fourmolu 0.8.0.0 → 0.8.1.0
raw patch · 11 files changed
+156/−70 lines, 11 filesdep ~directory
Dependency ranges changed: directory
Files
- CHANGELOG.md +5/−0
- README.md +1/−1
- app/Main.hs +18/−11
- fixity-tests/Main.hs +4/−21
- fourmolu.cabal +20/−12
- region-tests/Main.hs +3/−21
- src/Ormolu/Config.hs +12/−1
- src/Ormolu/Config/TH.hs +2/−2
- tests/Ormolu/CabalInfoSpec.hs +1/−1
- tests/Ormolu/Config/OptionsSpec.hs +60/−0
- tests/utils/IntegrationUtils.hs +30/−0
CHANGELOG.md view
@@ -1,3 +1,8 @@+## Fourmolu 0.8.1.0++* Add `emptyConfig` ([#221](https://github.com/fourmolu/fourmolu/pull/221))+* Fixed CLI options not overriding config file options, broken in 0.7.0.0 ([#225](https://github.com/fourmolu/fourmolu/pull/225))+ ## Fourmolu 0.8.0.0 * Consolidate `import-export-comma-style` and `diff-friendly-import-export` into a new option `import-export-style` ([#201](https://github.com/fourmolu/fourmolu/pull/207))
README.md view
@@ -53,7 +53,7 @@ | `newlines-between-decls` | any integer | number of newlines between top-level declarations | | `fixities` | A list of strings for defining fixities; see the "Language extensions, dependencies, and fixities" section below | -For examples of each of these options, see the [test files](https://github.com/fourmolu/fourmolu/tree/master/data/fourmolu/).+For examples of each of these options, see the [test files](https://github.com/fourmolu/fourmolu/tree/main/data/fourmolu/). ### Specifying configuration
app/Main.hs view
@@ -13,7 +13,6 @@ import Control.Exception (throwIO) import Control.Monad import Data.Bool (bool)-import Data.Functor.Identity (Identity (..)) import Data.List (intercalate, isSuffixOf, sort) import qualified Data.Map as Map import Data.Maybe (fromMaybe, mapMaybe)@@ -99,7 +98,7 @@ -- | Build the full config, by adding 'PrinterOpts' from a file, if found. mkConfig :: FilePath -> Opts -> IO (Config RegionIndices)-mkConfig path Opts {..} = do+mkConfig path Opts {optQuiet, optConfig, optPrinterOpts = cliPrinterOpts} = do mFourmoluConfig <- loadConfigFile path >>= \case ConfigLoaded f cfg -> do@@ -121,16 +120,17 @@ $ ("No " ++ show configFileName ++ " found in any of:") : map (" " ++) searchDirs return Nothing+ let resolve f = maybe mempty f mFourmoluConfig return $ optConfig { cfgPrinterOpts =- fillMissingPrinterOpts- (maybe mempty cfgFilePrinterOpts mFourmoluConfig)- (cfgPrinterOpts optConfig),+ fillMissingPrinterOpts cliPrinterOpts+ . fillMissingPrinterOpts (resolve cfgFilePrinterOpts)+ $ defaultPrinterOpts, cfgFixityOverrides = -- cfgFileFixities should go on the right so that command line -- fixity overrides takes precedence.- cfgFixityOverrides optConfig <> maybe mempty cfgFileFixities mFourmoluConfig+ cfgFixityOverrides optConfig <> resolve cfgFileFixities } where printDebug = when (cfgDebug optConfig) . hPutStrLn stderr@@ -248,6 +248,8 @@ optQuiet :: !Bool, -- | Ormolu 'Config' optConfig :: !(Config RegionIndices),+ -- | Fourmolu 'PrinterOpts',+ optPrinterOpts :: PrinterOptsPartial, -- | Options related to info extracted from .cabal files optCabal :: CabalOpts, -- | Source type option, where 'Nothing' means autodetection@@ -329,6 +331,7 @@ help "Make output quieter" ] <*> configParser+ <*> printerOptsParser <*> cabalOptsParser <*> sourceTypeParser <*> (many . strArgument . mconcat)@@ -410,7 +413,7 @@ help "End line of the region to format (inclusive)" ] )- <*> printerOptsParser+ <*> pure defaultPrinterOpts -- unused; overwritten in mkConfig sourceTypeParser :: Parser (Maybe SourceType) sourceTypeParser =@@ -422,16 +425,20 @@ help "Set the type of source; TYPE can be 'module', 'sig', or 'auto' (the default)" ] -printerOptsParser :: Parser PrinterOptsTotal+printerOptsParser :: Parser PrinterOptsPartial printerOptsParser = overFieldsM mkOption printerOptsMeta where+ mkOption :: PrinterOptsFieldMeta a -> Parser (Maybe a) mkOption PrinterOptsFieldMeta {..} =- option (Identity <$> eitherReader parseText) . mconcat $+ option (Just <$> eitherReader parseText) . mconcat $ [ long metaName, metavar metaPlaceholder, help metaHelp,- showDefaultWith (showText . runIdentity),- value $ Identity metaDefault+ -- the CLI flag itself should default to Nothing, but we'll show+ -- the default of the option as-if it weren't set in the config+ -- file in the help text.+ showDefaultWith (\_ -> showText metaDefault),+ value Nothing ] ----------------------------------------------------------------------------
fixity-tests/Main.hs view
@@ -1,15 +1,14 @@ {-# LANGUAGE RecordWildCards #-} -import Control.Monad (forM_, when)-import System.Directory (copyFile, findExecutable)-import System.Exit (ExitCode (..))+import Control.Monad (forM_)+import IntegrationUtils (getFourmoluExe, readProcess)+import System.Directory (copyFile) import System.IO.Temp (withSystemTempDirectory)-import System.Process (readProcessWithExitCode) import Test.Hspec main :: IO () main = hspec $- describe "fixity-tests" . beforeAll getExe $+ describe "fixity-tests" . beforeAll getFourmoluExe $ forM_ tests $ \Test {..} -> specify testLabel $ \fourmoluExe -> withSystemTempDirectory "fixity-test-dir" $ \tmpdir -> do@@ -93,19 +92,3 @@ testExpectedFileName = "test-1-with-fixity-info-expected.hs" } ]---- | Find a `fourmolu` executable on PATH.-getExe :: IO FilePath-getExe = findExecutable "fourmolu" >>= maybe (fail "Could not find fourmolu executable") return--readProcess :: FilePath -> [String] -> IO String-readProcess cmd args = do- (code, stdout, stderr) <- readProcessWithExitCode cmd args ""- when (code /= ExitSuccess) $ do- putStrLn $ "Command failed: " ++ (unwords . map (\s -> "\"" ++ s ++ "\"")) (cmd : args)- putStrLn "========== stdout =========="- putStrLn stdout- putStrLn "========== stderr =========="- putStrLn stderr- fail "Command failed. See output for more details."- return stdout
fourmolu.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: fourmolu-version: 0.8.0.0+version: 0.8.1.0 license: BSD-3-Clause license-file: LICENSE.md maintainer:@@ -168,7 +168,16 @@ else ghc-options: -O2 -Wall -rtsopts +common integration-test-utils+ build-tool-depends: fourmolu:fourmolu+ hs-source-dirs: tests/utils/+ other-modules: IntegrationUtils+ build-depends:+ directory >=1.3 && <1.4,+ process >=1.6 && <2.0+ test-suite tests+ import: integration-test-utils type: exitcode-stdio-1.0 main-is: Spec.hs build-tool-depends: hspec-discover:hspec-discover >=2.0 && <3.0@@ -184,8 +193,6 @@ Ormolu.Parser.ParseFailureSpec Ormolu.Parser.PragmaSpec Ormolu.PrinterSpec- -- fourmolu tests- Ormolu.Config.PrinterOptsSpec default-language: Haskell2010 build-depends:@@ -201,8 +208,13 @@ path >=0.6 && <0.10, path-io >=1.4.2 && <2.0, temporary ^>=1.3,- text >=0.2 && <3.0,- -- fourmolu-only deps+ text >=0.2 && <3.0++ -- specific to fourmolu tests+ other-modules:+ Ormolu.Config.OptionsSpec+ Ormolu.Config.PrinterOptsSpec+ build-depends: Diff >=0.3 && <0.5, pretty >=1.0 && <2.0, fourmolu@@ -214,16 +226,14 @@ ghc-options: -O2 -Wall test-suite region-tests+ import: integration-test-utils type: exitcode-stdio-1.0 main-is: Main.hs hs-source-dirs: region-tests default-language: Haskell2010- build-tool-depends: fourmolu:fourmolu build-depends: base >=4.14 && <5.0,- directory >=1.3 && <1.4,- hspec >=2.0 && <3.0,- process >=1.6 && <2.0+ hspec >=2.0 && <3.0 if flag(dev) ghc-options: -Wall -Werror@@ -231,16 +241,14 @@ ghc-options: -O2 -Wall test-suite fixity-tests+ import: integration-test-utils type: exitcode-stdio-1.0 main-is: Main.hs hs-source-dirs: fixity-tests default-language: Haskell2010- build-tool-depends: fourmolu:fourmolu build-depends: base >=4.14 && <5.0,- directory >=1.3 && <1.4, hspec >=2.0 && <3.0,- process >=1.6 && <2.0, temporary >=1.3 && <1.4 if flag(dev)
region-tests/Main.hs view
@@ -1,14 +1,12 @@ {-# LANGUAGE RecordWildCards #-} -import Control.Monad (forM_, when)-import System.Directory (findExecutable)-import System.Exit (ExitCode (..))-import System.Process (readProcessWithExitCode)+import Control.Monad (forM_)+import IntegrationUtils (getFourmoluExe, readProcess) import Test.Hspec main :: IO () main = hspec $- describe "region-tests" . beforeAll getExe $+ describe "region-tests" . beforeAll getFourmoluExe $ forM_ tests $ \Test {..} -> specify testLabel $ \fourmoluExe -> do actual <-@@ -66,19 +64,3 @@ testExpectedFileName = "expected-result-17-18.hs" } ]---- | Find a `fourmolu` executable on PATH.-getExe :: IO FilePath-getExe = findExecutable "fourmolu" >>= maybe (fail "Could not find fourmolu executable") return--readProcess :: FilePath -> [String] -> IO String-readProcess cmd args = do- (code, stdout, stderr) <- readProcessWithExitCode cmd args ""- when (code /= ExitSuccess) $ do- putStrLn $ "Command failed: " ++ (unwords . map (\s -> "\"" ++ s ++ "\"")) (cmd : args)- putStrLn "========== stdout =========="- putStrLn stdout- putStrLn "========== stderr =========="- putStrLn stderr- fail "Command failed. See output for more details."- return stdout
src/Ormolu/Config.hs view
@@ -40,6 +40,7 @@ loadConfigFile, configFileName, FourmoluConfig (..),+ emptyConfig, ConfigFileLoadResult (..), -- ** Utilities@@ -284,7 +285,10 @@ { metaName = "import-export-style", metaGetField = poImportExportStyle, metaPlaceholder = "STYLE",- metaHelp = "Styling of import/export lists",+ metaHelp =+ printf+ "Styling of import/export lists (choices: %s)"+ (showAllValues importExportStyleMap), metaDefault = ImportExportDiffFriendly }, poIndentWheres =@@ -428,6 +432,13 @@ Right fixities -> return . Map.fromList . concat $ fixities Left e -> fail $ errorBundlePretty e return FourmoluConfig {..}++emptyConfig :: FourmoluConfig+emptyConfig =+ FourmoluConfig+ { cfgFilePrinterOpts = mempty,+ cfgFileFixities = mempty+ } -- | Read options from a config file, if found. -- Looks recursively in parent folders, then in 'XdgConfig',
src/Ormolu/Config/TH.hs view
@@ -17,7 +17,7 @@ import Control.Monad (forM, when, (>=>)) import Data.Containers.ListUtils (nubOrd)-import Data.List (intercalate, nub)+import Data.List (nub) import Language.Haskell.TH import Language.Haskell.TH.Syntax (lift) import Text.Printf (printf)@@ -182,4 +182,4 @@ uncommas ss = let pre = init ss end = last ss- in intercalate ", " pre <> "or " <> end+ in concatMap (<> ", ") pre <> "or " <> end
tests/Ormolu/CabalInfoSpec.hs view
@@ -41,7 +41,7 @@ ciDependencies `shouldBe` Set.fromList ["Cabal", "Diff", "MemoTrie", "aeson", "ansi-terminal", "array", "base", "bytestring", "containers", "directory", "dlist", "exceptions", "file-embed", "filepath", "ghc-lib-parser", "megaparsec", "mtl", "syb", "template-haskell", "text", "th-lift-instances", "yaml"] it "extracts correct dependencies from fourmolu.cabal (tests/Ormolu/PrinterSpec.hs)" $ do CabalInfo {..} <- parseCabalInfo "fourmolu.cabal" "tests/Ormolu/PrinterSpec.hs"- ciDependencies `shouldBe` Set.fromList ["Diff", "QuickCheck", "base", "containers", "directory", "filepath", "ghc-lib-parser", "hspec", "hspec-megaparsec", "megaparsec", "fourmolu", "path", "path-io", "pretty", "temporary", "text"]+ ciDependencies `shouldBe` Set.fromList ["Diff", "QuickCheck", "base", "containers", "directory", "filepath", "ghc-lib-parser", "hspec", "hspec-megaparsec", "megaparsec", "fourmolu", "path", "path-io", "pretty", "process", "temporary", "text"] it "handles `hs-source-dirs: .`" $ do CabalInfo {..} <- parseTestCabalInfo "Foo.hs"
+ tests/Ormolu/Config/OptionsSpec.hs view
@@ -0,0 +1,60 @@+module Ormolu.Config.OptionsSpec (spec) where++import IntegrationUtils (getFourmoluExe, readProcess)+import System.FilePath ((</>))+import System.IO.Temp (withSystemTempDirectory)+import Test.Hspec++spec :: Spec+spec =+ describe "Fourmolu configuration via CLI" . beforeAll getFourmoluExe $ do+ it "CLI options override default" $ \fourmoluExe -> do+ withTempDir $ \tmpdir -> do+ let hsFile = tmpdir </> "test.hs"+ writeFile hsFile indented2++ withoutCLI <- readProcess fourmoluExe [hsFile]+ withoutCLI `shouldBe` indented4++ withCLI <- readProcess fourmoluExe ["--indentation=2", hsFile]+ withCLI `shouldBe` indented2++ it "CLI options used when config file lacks option" $ \fourmoluExe -> do+ withTempDir $ \tmpdir -> do+ let hsFile = tmpdir </> "test.hs"+ writeFile hsFile indented2+ let configFile = tmpdir </> "fourmolu.yaml"+ writeFile configFile "comma-style: trailing"++ withoutCLI <- readProcess fourmoluExe [hsFile]+ withoutCLI `shouldBe` indented4++ withCLI <- readProcess fourmoluExe ["--indentation=2", hsFile]+ withCLI `shouldBe` indented2++ it "CLI options override config file option" $ \fourmoluExe -> do+ withTempDir $ \tmpdir -> do+ let hsFile = tmpdir </> "test.hs"+ writeFile hsFile indented2+ let configFile = tmpdir </> "fourmolu.yaml"+ writeFile configFile "indentation: 2"++ withoutCLI <- readProcess fourmoluExe [hsFile]+ withoutCLI `shouldBe` indented2++ withCLI <- readProcess fourmoluExe ["--indentation=4", hsFile]+ withCLI `shouldBe` indented4+ where+ withTempDir = withSystemTempDirectory "fourmolu-cli-options-test"+ indented2 =+ unlines+ [ "main :: IO ()",+ "main =",+ " print 10"+ ]+ indented4 =+ unlines+ [ "main :: IO ()",+ "main =",+ " print 10"+ ]
+ tests/utils/IntegrationUtils.hs view
@@ -0,0 +1,30 @@+module IntegrationUtils+ ( getFourmoluExe,+ readProcess,+ )+where++import Control.Monad (when)+import System.Directory (findExecutable)+import System.Exit (ExitCode (..))+import System.Process (readProcessWithExitCode)++-- | Find a `fourmolu` executable on PATH.+getFourmoluExe :: IO FilePath+getFourmoluExe = findExecutable "fourmolu" >>= maybe (fail "Could not find fourmolu executable") return++-- | Like 'System.Process.readProcess', except without specifying stdin and showing stdout/stderr+-- on failure.+readProcess :: FilePath -> [String] -> IO String+readProcess cmd args = do+ (code, stdout, stderr) <- readProcessWithExitCode cmd args ""++ when (code /= ExitSuccess) $ do+ putStrLn $ "Command failed: " ++ (unwords . map (\s -> "\"" ++ s ++ "\"")) (cmd : args)+ putStrLn "========== stdout =========="+ putStrLn stdout+ putStrLn "========== stderr =========="+ putStrLn stderr+ fail "Command failed. See output for more details."++ return stdout