diff --git a/package.yaml b/package.yaml index eeffdb0b..ef815764 100644 --- a/package.yaml +++ b/package.yaml @@ -100,5 +100,7 @@ tests: - hspec-expectations-lifted - lens-aeson - load-env + - opt-env-conf - restyler - text + - unliftio diff --git a/restyler.cabal b/restyler.cabal index 3a3c3a28..fc889d34 100644 --- a/restyler.cabal +++ b/restyler.cabal @@ -146,6 +146,7 @@ test-suite test Restyler.Config.CommitTemplateSpec Restyler.Config.IncludeSpec Restyler.Config.InterpreterSpec + Restyler.ConfigSpec Restyler.DelimitedSpec Restyler.IgnoreSpec Restyler.RestrictionsSpec @@ -187,6 +188,8 @@ test-suite test , hspec-expectations-lifted , lens-aeson , load-env + , opt-env-conf , restyler , text + , unliftio default-language: GHC2021 diff --git a/src/Restyler/Config.hs b/src/Restyler/Config.hs index d41545b8..a9fa89f9 100644 --- a/src/Restyler/Config.hs +++ b/src/Restyler/Config.hs @@ -10,6 +10,7 @@ -- Portability : POSIX module Restyler.Config ( Config (..) + , configParser , parseConfig -- * Individual configuration points @@ -74,16 +75,23 @@ instance HasRestylerOverrides Config where parseConfig :: IO Config parseConfig = do - withSystemTempFile "restyler-default-config.yaml" $ \tmp h -> do + withSystemTempFile "restyler-default-config.yaml" $ \defaults h -> do BS.hPutStr h defaultConfigContent >> hClose h - runParser Pkg.version "Restyle local file" $ configParser tmp + runParser Pkg.version "Restyle local file" + $ configParser + [ ".github/restyled.yml" + , ".github/restyled.yaml" + , ".restyled.yml" + , ".restyled.yaml" + , defaults + ] defaultConfigContent :: ByteString defaultConfigContent = $(embedFile "config/default.yaml") -configParser :: FilePath -> Parser Config -configParser defaults = - withCombinedYamlConfigs (configSources defaults) +configParser :: [FilePath] -> Parser Config +configParser paths = + withCombinedYamlConfigs (traverse hiddenPath paths) $ Config <$> setting [ help "Do anything at all" @@ -105,16 +113,6 @@ configParser defaults = <*> restylerOverridesParser <*> subConfig_ "cli" optionsParser -configSources :: FilePath -> Parser [Path Abs File] -configSources defaults = - sequenceA - [ hiddenPath ".github/restyled.yml" - , hiddenPath ".github/restyled.yaml" - , hiddenPath ".restyled.yml" - , hiddenPath ".restyled.yaml" - , hiddenPath defaults - ] - hiddenPath :: FilePath -> Parser (Path Abs File) hiddenPath x = filePathSetting [value x, hidden] diff --git a/test/Restyler/ConfigSpec.hs b/test/Restyler/ConfigSpec.hs new file mode 100644 index 00000000..17f12c92 --- /dev/null +++ b/test/Restyler/ConfigSpec.hs @@ -0,0 +1,52 @@ +module Restyler.ConfigSpec + ( spec + ) where + +import Restyler.Prelude + +import Data.Text.IO (hPutStr) +import OptEnvConf.Args (parseArgs) +import OptEnvConf.EnvMap qualified as EnvMap +import OptEnvConf.Run (runParserOn) +import Restyler.Config +import System.IO (hClose) +import Test.Hspec +import UnliftIO.Temporary (withSystemTempFile) + +spec :: Spec +spec = do + it "uses defined defaults" $ do + config <- loadTestConfig [] [] ["Foo.hs"] + config.enabled `shouldBe` True + +loadTestConfig + :: HasCallStack + => [Text] + -- ^ Lines of Yaml + -- + -- Empty means to behave as if no file at all. + -> [(String, String)] + -- ^ ENV + -> [String] + -- ^ Args + -> IO Config +loadTestConfig yaml env args = do + result <- case yaml of + [] -> runParser ["config/default.yaml"] + ls -> withSystemTempFile "restyler-test-config.yaml" $ \path h -> do + hPutStr h (unlines ls) >> hClose h + runParser [path, "config/default.yaml"] + + case result of + Left errs -> do + expectationFailure $ show errs + error "unreachable" + Right config -> pure config + where + runParser paths = + runParserOn + Nothing + (configParser paths) + (parseArgs args) + (EnvMap.parse env) + Nothing