From d32505a467524101a1633a2ea37a7d11213609c3 Mon Sep 17 00:00:00 2001 From: Mike Pilgrem Date: Fri, 9 Aug 2024 22:05:31 +0100 Subject: [PATCH] Re #6636 Add `--run-tests` and `--run-benchmarks` Also documents flags in online documentation. Also conforms test-suite and benchmark in-app documentation. Also updates related FAQ. Also conforms `benchmarkOptsFromMonoid` to `testOptsFromMonoid`. --- .stan.toml | 27 +++++++++++++++++++-------- ChangeLog.md | 4 ++++ doc/commands/bench_command.md | 4 ++-- doc/commands/build_command.md | 23 +++++++++++++++++++++-- doc/commands/haddock_command.md | 4 ++-- doc/commands/install_command.md | 4 ++-- doc/commands/test_command.md | 4 ++-- doc/faq.md | 14 +++++++++++++- src/Stack/Build/ExecutePackage.hs | 16 ++++++++-------- src/Stack/BuildOpts.hs | 11 +++++++---- src/Stack/Config/Build.hs | 17 +++++++---------- src/Stack/Ghci.hs | 4 ++-- src/Stack/Options/BenchParser.hs | 20 +++++++++----------- src/Stack/Options/TestParser.hs | 15 +++++++-------- src/Stack/Types/BuildOpts.hs | 6 +++--- src/Stack/Types/BuildOptsMonoid.hs | 20 ++++++++++---------- tests/unit/Stack/ConfigSpec.hs | 4 ++-- 17 files changed, 120 insertions(+), 77 deletions(-) diff --git a/.stan.toml b/.stan.toml index 7748787399..1fe60ac52d 100644 --- a/.stan.toml +++ b/.stan.toml @@ -190,25 +190,36 @@ # Anti-pattern: unsafe functions [[ignore]] - id = "OBS-STAN-0212-FNS1cF-59:17" + id = "OBS-STAN-0212-FNS1cF-60:17" # ✦ Description: Usage of unsafe functions breaks referential transparency # ✦ Category: #Unsafe #AntiPattern # ✦ File: src\Stack\BuildOpts.hs # -# 58 ┃ -# 59 ┃ buildMonoid = undefined :: BuildOptsMonoid -# 60 ┃ ^^^^^^^^^ +# 59 ┃ +# 60 ┃ buildMonoid = undefined :: BuildOptsMonoid +# 61 ┃ ^^^^^^^^^ # Anti-pattern: unsafe functions [[ignore]] - id = "OBS-STAN-0212-FNS1cF-71:14" + id = "OBS-STAN-0212-FNS1cF-72:14" # ✦ Description: Usage of unsafe functions breaks referential transparency # ✦ Category: #Unsafe #AntiPattern # ✦ File: src\Stack\BuildOpts.hs # -# 70 ┃ -# 71 ┃ toMonoid = undefined :: TestOptsMonoid -# 72 ┃ ^^^^^^^^^ +# 71 ┃ +# 72 ┃ toMonoid = undefined :: TestOptsMonoid +# 73 ┃ ^^^^^^^^^ + +# Anti-pattern: unsafe functions +[[ignore]] + id = "OBS-STAN-0212-FNS1cF-83:15" +# ✦ Description: Usage of unsafe functions breaks referential transparency +# ✦ Category: #Unsafe #AntiPattern +# ✦ File: src/Stack/BuildOpts.hs +# +# 82 ┃ +# 83 ┃ beoMonoid = undefined :: BenchmarkOptsMonoid +# 84 ┃ ^^^^^^^^^ # Anti-pattern: Pattern matching on '_' # Pattern matching on '_' for sum types can create maintainability issues diff --git a/ChangeLog.md b/ChangeLog.md index 05b2738870..02274d7d50 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -20,6 +20,10 @@ Behavior changes: Other enhancements: +* Add flags `--run-tests` and `--run-benchmarks` (the existing defaults) to + Stack's `build` command, which take precedence over the existing + `no-run-tests` and `no-run-benchmarks` configuration options, respectively. + Bug fixes: * Stack's in-app messages refer to https://haskellstack.org as currently diff --git a/doc/commands/bench_command.md b/doc/commands/bench_command.md index ef7d11abc9..52ff529810 100644 --- a/doc/commands/bench_command.md +++ b/doc/commands/bench_command.md @@ -16,9 +16,9 @@ stack bench [TARGET] [--dry-run] [--pedantic] [--fast] [--ghc-options OPTIONS] [--[no-]copy-bins] [--[no-]copy-compiler-tool] [--[no-]prefetch] [--[no-]keep-going] [--[no-]keep-tmp-files] [--[no-]force-dirty] [--[no-]test] [--[no-]rerun-tests] [--ta|--test-arguments TEST_ARGS] - [--coverage] [--no-run-tests] [--test-suite-timeout ARG] + [--coverage] [--[no-]run-tests] [--test-suite-timeout ARG] [--[no-]tests-allow-stdin] [--[no-]bench] - [--ba|--benchmark-arguments BENCH_ARGS] [--no-run-benchmarks] + [--ba|--benchmark-arguments BENCH_ARGS] [--[no-]run-benchmarks] [--[no-]reconfigure] [--cabal-verbosity VERBOSITY | --[no-]cabal-verbose] [--[no-]split-objs] [--skip ARG] [--[no-]interleaved-output] [--ddump-dir ARG] diff --git a/doc/commands/build_command.md b/doc/commands/build_command.md index f472f84b62..510d6c67ac 100644 --- a/doc/commands/build_command.md +++ b/doc/commands/build_command.md @@ -16,9 +16,9 @@ stack build [TARGET] [--dry-run] [--pedantic] [--fast] [--ghc-options OPTIONS] [--[no-]copy-bins] [--[no-]copy-compiler-tool] [--[no-]prefetch] [--[no-]keep-going] [--[no-]keep-tmp-files] [--[no-]force-dirty] [--[no-]test] [--[no-]rerun-tests] [--ta|--test-arguments TEST_ARGS] - [--coverage] [--no-run-tests] [--test-suite-timeout ARG] + [--coverage] [--[no-]run-tests] [--test-suite-timeout ARG] [--[no-]tests-allow-stdin] [--[no-]bench] - [--ba|--benchmark-arguments BENCH_ARGS] [--no-run-benchmarks] + [--ba|--benchmark-arguments BENCH_ARGS] [--[no-]run-benchmarks] [--[no-]reconfigure] [--cabal-verbosity VERBOSITY | --[no-]cabal-verbose] [--[no-]split-objs] [--skip ARG] [--[no-]interleaved-output] [--ddump-dir ARG] @@ -661,6 +661,25 @@ command line arguments. For example, to pass `'a single quoted string'`: The content of single quotes is taken literally. Within single quotes, `''` escapes a single quote. +### `--[no-]rerun-tests` flag + +Default: Enabled + +Unset the flag to disable the automatic running of targeted test-suites that +have already been successful. + +### `--[no-]run-benchmarks` flag + +Default: Enabled + +Unset the flag to disable the automatic running of targeted benchmarks. + +### `--[no-]run-tests` flag + +Default: Enabled + +Unset the flag to disable the automatic running of targeted test suites. + ### `--test-arguments`, `--ta` option `stack build --test --test-arguments=` will pass the specified diff --git a/doc/commands/haddock_command.md b/doc/commands/haddock_command.md index 70227278d5..33bbe41be2 100644 --- a/doc/commands/haddock_command.md +++ b/doc/commands/haddock_command.md @@ -16,10 +16,10 @@ stack haddock [TARGET] [--dry-run] [--pedantic] [--fast] [--ghc-options OPTIONS] [--[no-]copy-bins] [--[no-]copy-compiler-tool] [--[no-]prefetch] [--[no-]keep-going] [--[no-]keep-tmp-files] [--[no-]force-dirty] [--[no-]test] [--[no-]rerun-tests] - [--ta|--test-arguments TEST_ARGS] [--coverage] [--no-run-tests] + [--ta|--test-arguments TEST_ARGS] [--coverage] [--[no-]run-tests] [--test-suite-timeout ARG] [--[no-]tests-allow-stdin] [--[no-]bench] [--ba|--benchmark-arguments BENCH_ARGS] - [--no-run-benchmarks] [--[no-]reconfigure] + [--[no-]run-benchmarks] [--[no-]reconfigure] [--cabal-verbosity VERBOSITY | --[no-]cabal-verbose] [--[no-]split-objs] [--skip ARG] [--[no-]interleaved-output] [--ddump-dir ARG] diff --git a/doc/commands/install_command.md b/doc/commands/install_command.md index 74cd45e55f..653981a2d4 100644 --- a/doc/commands/install_command.md +++ b/doc/commands/install_command.md @@ -16,10 +16,10 @@ stack install [TARGET] [--dry-run] [--pedantic] [--fast] [--ghc-options OPTIONS] [--[no-]copy-bins] [--[no-]copy-compiler-tool] [--[no-]prefetch] [--[no-]keep-going] [--[no-]keep-tmp-files] [--[no-]force-dirty] [--[no-]test] [--[no-]rerun-tests] - [--ta|--test-arguments TEST_ARGS] [--coverage] [--no-run-tests] + [--ta|--test-arguments TEST_ARGS] [--coverage] [--[no-]run-tests] [--test-suite-timeout ARG] [--[no-]tests-allow-stdin] [--[no-]bench] [--ba|--benchmark-arguments BENCH_ARGS] - [--no-run-benchmarks] [--[no-]reconfigure] + [--[no-]run-benchmarks] [--[no-]reconfigure] [--cabal-verbosity VERBOSITY | --[no-]cabal-verbose] [--[no-]split-objs] [--skip ARG] [--[no-]interleaved-output] [--ddump-dir ARG] diff --git a/doc/commands/test_command.md b/doc/commands/test_command.md index b9d7dddb5d..cb0f2cb9c9 100644 --- a/doc/commands/test_command.md +++ b/doc/commands/test_command.md @@ -16,9 +16,9 @@ stack test [TARGET] [--dry-run] [--pedantic] [--fast] [--ghc-options OPTIONS] [--[no-]copy-bins] [--[no-]copy-compiler-tool] [--[no-]prefetch] [--[no-]keep-going] [--[no-]keep-tmp-files] [--[no-]force-dirty] [--[no-]test] [--[no-]rerun-tests] [--ta|--test-arguments TEST_ARGS] - [--coverage] [--no-run-tests] [--test-suite-timeout ARG] + [--coverage] [--[no-]run-tests] [--test-suite-timeout ARG] [--[no-]tests-allow-stdin] [--[no-]bench] - [--ba|--benchmark-arguments BENCH_ARGS] [--no-run-benchmarks] + [--ba|--benchmark-arguments BENCH_ARGS] [--[no-]run-benchmarks] [--[no-]reconfigure] [--cabal-verbosity VERBOSITY | --[no-]cabal-verbose] [--[no-]split-objs] [--skip ARG] [--[no-]interleaved-output] [--ddump-dir ARG] diff --git a/doc/faq.md b/doc/faq.md index 6d40651e55..b3c6a17af9 100644 --- a/doc/faq.md +++ b/doc/faq.md @@ -366,7 +366,19 @@ top-level `dependencies` key. Alternatively, build all components of project packages without running - tests or benchmarks once built. Command: + tests or benchmarks once built. Add the following to a configuration file: + + ~~~yaml + build: + test: true + test-arguments: + no-run-tests: true + bench: true + benchmark-opts: + no-run-benchmarks: true + ~~~ + + or command: ~~~text stack build --test --no-run-tests --bench --no-run-benchmarks diff --git a/src/Stack/Build/ExecutePackage.hs b/src/Stack/Build/ExecutePackage.hs index 140970cf9f..59fd0d8b2b 100644 --- a/src/Stack/Build/ExecutePackage.hs +++ b/src/Stack/Build/ExecutePackage.hs @@ -978,11 +978,8 @@ singleTest topts testsToRun ac ee task installedMap = do config <- view configL let needHpc = topts.coverage toRun <- - if topts.disableRun - then do - announce "Test running disabled by --no-run-tests flag." - pure False - else if topts.rerunTests + if topts.runTests + then if topts.rerunTests then pure True else do status <- getTestStatus pkgDir @@ -999,6 +996,9 @@ singleTest topts testsToRun ac ee task installedMap = do announce "rerunning previously failed test" pure True TSUnknown -> pure True + else do + announce "Test running disabled by --no-run-tests flag." + pure False when toRun $ do buildDir <- distDirFromDir pkgDir @@ -1262,11 +1262,11 @@ singleBench beopts benchesToRun ac ee task installedMap = do beopts.additionalArgs toRun <- - if beopts.disableRun - then do + if beopts.runBenchmarks + then pure True + else do announce "Benchmark running disabled by --no-run-benchmarks flag." pure False - else pure True when toRun $ do announce "benchmarks" diff --git a/src/Stack/BuildOpts.hs b/src/Stack/BuildOpts.hs index e71a604721..75d5623691 100644 --- a/src/Stack/BuildOpts.hs +++ b/src/Stack/BuildOpts.hs @@ -17,8 +17,9 @@ import Stack.Types.BuildOpts , TestOpts (..) ) import Stack.Types.BuildOptsMonoid - ( BuildOptsMonoid (..), CabalVerbosity (..) - , ProgressBarFormat (..), TestOptsMonoid (..) + ( BenchmarkOptsMonoid (..), BuildOptsMonoid (..) + , CabalVerbosity (..), ProgressBarFormat (..) + , TestOptsMonoid (..) ) defaultBuildOpts :: BuildOpts @@ -63,7 +64,7 @@ defaultTestOpts = TestOpts { rerunTests = defaultFirstTrue toMonoid.rerunTests , additionalArgs = [] , coverage = defaultFirstFalse toMonoid.coverage - , disableRun = defaultFirstFalse toMonoid.disableRun + , runTests = defaultFirstTrue toMonoid.runTests , maximumTimeSeconds = Nothing , allowStdin = defaultFirstTrue toMonoid.allowStdin } @@ -76,5 +77,7 @@ defaultHaddockOpts = HaddockOpts { additionalArgs = [] } defaultBenchmarkOpts :: BenchmarkOpts defaultBenchmarkOpts = BenchmarkOpts { additionalArgs = Nothing - , disableRun = False + , runBenchmarks = defaultFirstTrue beoMonoid.runBenchmarks } + where + beoMonoid = undefined :: BenchmarkOptsMonoid diff --git a/src/Stack/Config/Build.hs b/src/Stack/Config/Build.hs index 54c977c213..89d1e1f44b 100644 --- a/src/Stack/Config/Build.hs +++ b/src/Stack/Config/Build.hs @@ -122,7 +122,7 @@ testOptsFromMonoid toMonoid madditional = defaultTestOpts , TestOpts.additionalArgs = fromMaybe [] madditional <> toMonoid.additionalArgs , TestOpts.coverage = fromFirstFalse toMonoid.coverage - , TestOpts.disableRun = fromFirstFalse toMonoid.disableRun + , TestOpts.runTests = fromFirstTrue toMonoid.runTests , TestOpts.maximumTimeSeconds = fromFirst defaultTestOpts.maximumTimeSeconds @@ -135,12 +135,9 @@ benchmarkOptsFromMonoid :: BenchmarkOptsMonoid -> Maybe [String] -> BenchmarkOpts -benchmarkOptsFromMonoid beoMonoid madditional = - defaultBenchmarkOpts - { BenchmarkOpts.additionalArgs = - fmap (\args -> unwords args <> " ") madditional <> - getFirst beoMonoid.additionalArgs - , BenchmarkOpts.disableRun = fromFirst - defaultBenchmarkOpts.disableRun - beoMonoid.disableRun - } +benchmarkOptsFromMonoid beoMonoid madditional = defaultBenchmarkOpts + { BenchmarkOpts.additionalArgs = + fmap (\args -> unwords args <> " ") madditional <> + getFirst beoMonoid.additionalArgs + , BenchmarkOpts.runBenchmarks = fromFirstTrue beoMonoid.runBenchmarks + } diff --git a/src/Stack/Ghci.hs b/src/Stack/Ghci.hs index cfdd365756..b7cb3af0fc 100644 --- a/src/Stack/Ghci.hs +++ b/src/Stack/Ghci.hs @@ -213,9 +213,9 @@ ghciCmd ghciOpts = bopts <- view buildOptsL -- override env so running of tests and benchmarks is disabled let boptsLocal = bopts - { testOpts = bopts.testOpts { TestOpts.disableRun = True } + { testOpts = bopts.testOpts { TestOpts.runTests = False } , benchmarkOpts = - bopts.benchmarkOpts { BenchmarkOpts.disableRun = True } + bopts.benchmarkOpts { BenchmarkOpts.runBenchmarks = False } } local (set buildOptsL boptsLocal) (ghci ghciOpts) diff --git a/src/Stack/Options/BenchParser.hs b/src/Stack/Options/BenchParser.hs index 28c6dc84bf..d5aa763571 100644 --- a/src/Stack/Options/BenchParser.hs +++ b/src/Stack/Options/BenchParser.hs @@ -5,9 +5,9 @@ module Stack.Options.BenchParser ( benchOptsParser ) where -import Options.Applicative - ( Parser, flag', help, long, metavar, strOption ) -import Options.Applicative.Builder.Extra ( optionalFirst ) +import Options.Applicative ( Parser, help, long, metavar, strOption ) +import Options.Applicative.Builder.Extra + ( firstBoolFlagsTrue, optionalFirst ) import Stack.Prelude import Stack.Options.Utils ( hideMods ) import Stack.Types.BuildOptsMonoid ( BenchmarkOptsMonoid (..) ) @@ -20,15 +20,13 @@ benchOptsParser hide0 = BenchmarkOptsMonoid ( long "benchmark-arguments" <> long "ba" <> metavar "BENCH_ARGS" - <> help "Forward BENCH_ARGS to the benchmark suite. Supports templates \ - \from 'cabal bench'." - <> hide - )) - <*> optionalFirst (flag' True - ( long "no-run-benchmarks" - <> help "Disable running of benchmarks. (Benchmarks will still be \ - \built.)" + <> help "Arguments passed to the benchmarks. Supports path variables \ + \provided by the Cabal build system." <> hide )) + <*> firstBoolFlagsTrue + "run-benchmarks" + "running of targeted benchmarks." + hide where hide = hideMods hide0 diff --git a/src/Stack/Options/TestParser.hs b/src/Stack/Options/TestParser.hs index c8955fff6f..f6d90c1dd7 100644 --- a/src/Stack/Options/TestParser.hs +++ b/src/Stack/Options/TestParser.hs @@ -19,13 +19,13 @@ testOptsParser :: Bool -> Parser TestOptsMonoid testOptsParser hide0 = TestOptsMonoid <$> firstBoolFlagsTrue "rerun-tests" - "running already successful tests." + "running already successful test suites." hide <*> fmap concat (many (argsOption ( long "test-arguments" <> long "ta" <> metavar "TEST_ARGS" - <> help "Arguments passed in to the test suite program." + <> help "Arguments passed to the test suites." <> hide ))) <*> optionalFirstFalse (flag' True @@ -33,11 +33,10 @@ testOptsParser hide0 = TestOptsMonoid <> help "Generate a code coverage report." <> hide )) - <*> optionalFirstFalse (flag' True - ( long "no-run-tests" - <> help "Disable running of tests. (Tests will still be built.)" - <> hide - )) + <*> firstBoolFlagsTrue + "run-tests" + "running of targeted test suites." + hide <*> optionalFirst (option (fmap Just auto) ( long "test-suite-timeout" <> help "Maximum test suite run time in seconds." @@ -45,7 +44,7 @@ testOptsParser hide0 = TestOptsMonoid )) <*> firstBoolFlagsTrue "tests-allow-stdin" - "allow standard input in test executables." + "allow standard input in test suites." hide where hide = hideMods hide0 diff --git a/src/Stack/Types/BuildOpts.hs b/src/Stack/Types/BuildOpts.hs index d65b661698..50df365b92 100644 --- a/src/Stack/Types/BuildOpts.hs +++ b/src/Stack/Types/BuildOpts.hs @@ -102,7 +102,7 @@ data TestOpts = TestOpts { rerunTests :: !Bool -- ^ Whether successful tests will be run gain , additionalArgs :: ![String] -- ^ Arguments passed to the test program , coverage :: !Bool -- ^ Generate a code coverage report - , disableRun :: !Bool -- ^ Disable running of tests + , runTests :: !Bool -- ^ Enable running of tests , maximumTimeSeconds :: !(Maybe Int) -- ^ test suite timeout in seconds , allowStdin :: !Bool -- ^ Whether to allow standard input } @@ -112,8 +112,8 @@ data TestOpts = TestOpts data BenchmarkOpts = BenchmarkOpts { additionalArgs :: !(Maybe String) -- ^ Arguments passed to the benchmark program - , disableRun :: !Bool - -- ^ Disable running of benchmarks + , runBenchmarks :: !Bool + -- ^ Enable running of benchmarks } deriving (Eq, Show) diff --git a/src/Stack/Types/BuildOptsMonoid.hs b/src/Stack/Types/BuildOptsMonoid.hs index 6ddfcc3c2c..626414c9da 100644 --- a/src/Stack/Types/BuildOptsMonoid.hs +++ b/src/Stack/Types/BuildOptsMonoid.hs @@ -258,7 +258,7 @@ data TestOptsMonoid = TestOptsMonoid { rerunTests :: !FirstTrue , additionalArgs :: ![String] , coverage :: !FirstFalse - , disableRun :: !FirstFalse + , runTests :: !FirstTrue , maximumTimeSeconds :: !(First (Maybe Int)) , allowStdin :: !FirstTrue } @@ -269,14 +269,14 @@ instance FromJSON (WithJSONWarnings TestOptsMonoid) where rerunTests <- FirstTrue <$> o ..:? rerunTestsArgName additionalArgs <- o ..:? testAdditionalArgsName ..!= [] coverage <- FirstFalse <$> o ..:? coverageArgName - disableRun <- FirstFalse <$> o ..:? testDisableRunArgName + runTests <- FirstTrue . (not <$>) <$> o ..:? noRunTestsArgName maximumTimeSeconds <- First <$> o ..:? maximumTimeSecondsArgName allowStdin <- FirstTrue <$> o ..:? testsAllowStdinName pure TestOptsMonoid { rerunTests , additionalArgs , coverage - , disableRun + , runTests , maximumTimeSeconds , allowStdin } @@ -290,8 +290,8 @@ testAdditionalArgsName = "additional-args" coverageArgName :: Text coverageArgName = "coverage" -testDisableRunArgName :: Text -testDisableRunArgName = "no-run-tests" +noRunTestsArgName :: Text +noRunTestsArgName = "no-run-tests" maximumTimeSecondsArgName :: Text maximumTimeSecondsArgName = "test-suite-timeout" @@ -328,24 +328,24 @@ haddockAdditionalArgsName = "haddock-args" data BenchmarkOptsMonoid = BenchmarkOptsMonoid { additionalArgs :: !(First String) - , disableRun :: !(First Bool) + , runBenchmarks :: !FirstTrue } deriving (Generic, Show) instance FromJSON (WithJSONWarnings BenchmarkOptsMonoid) where parseJSON = withObjectWarnings "BenchmarkOptsMonoid" $ \o -> do additionalArgs <- First <$> o ..:? benchmarkAdditionalArgsName - disableRun <- First <$> o ..:? benchmarkDisableRunArgName + runBenchmarks <- FirstTrue . (not <$>) <$> o ..:? noRunBenchmarksArgName pure BenchmarkOptsMonoid { additionalArgs - , disableRun + , runBenchmarks } benchmarkAdditionalArgsName :: Text benchmarkAdditionalArgsName = "benchmark-arguments" -benchmarkDisableRunArgName :: Text -benchmarkDisableRunArgName = "no-run-benchmarks" +noRunBenchmarksArgName :: Text +noRunBenchmarksArgName = "no-run-benchmarks" instance Semigroup BenchmarkOptsMonoid where (<>) = mappenddefault diff --git a/tests/unit/Stack/ConfigSpec.hs b/tests/unit/Stack/ConfigSpec.hs index 5b2cd0cf31..30037c22a0 100644 --- a/tests/unit/Stack/ConfigSpec.hs +++ b/tests/unit/Stack/ConfigSpec.hs @@ -255,14 +255,14 @@ spec = beforeAll setup $ do { rerunTests = True , additionalArgs = ["-fprof"] , coverage = True - , disableRun = True + , runTests = False , maximumTimeSeconds = Nothing , allowStdin = True } bopts.benchmarks `shouldBe` True bopts.benchmarkOpts `shouldBe` BenchmarkOpts { additionalArgs = Just "-O2" - , disableRun = True + , runBenchmarks = False } bopts.reconfigure `shouldBe` True bopts.cabalVerbose `shouldBe` CabalVerbosity verbose