diff --git a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs index ea077bbee22..35948233ae7 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs @@ -325,7 +325,7 @@ testSuiteFieldGrammar = TestSuiteStanza ^^^ availableSince CabalSpecV3_6 [] -- TODO 3_8 validateTestSuite :: Position -> TestSuiteStanza -> ParseResult TestSuite -validateTestSuite pos stanza = case _testStanzaTestType stanza of +validateTestSuite pos stanza = case testSuiteType of Nothing -> pure basicTestSuite Just tt@(TestTypeUnknown _ _) -> @@ -357,6 +357,11 @@ validateTestSuite pos stanza = case _testStanzaTestType stanza of { testInterface = TestSuiteLibV09 ver module_ } where + testSuiteType = + _testStanzaTestType stanza + <|> testTypeExe <$ _testStanzaMainIs stanza + <|> testTypeLib <$ _testStanzaTestModule stanza + missingField name tt = "The '" ++ name ++ "' field is required for the " ++ prettyShow tt ++ " test suite type." @@ -442,7 +447,7 @@ benchmarkFieldGrammar = BenchmarkStanza <*> blurFieldGrammar benchmarkStanzaBuildInfo buildInfoFieldGrammar validateBenchmark :: Position -> BenchmarkStanza -> ParseResult Benchmark -validateBenchmark pos stanza = case _benchmarkStanzaBenchmarkType stanza of +validateBenchmark pos stanza = case benchmarkStanzaType of Nothing -> pure emptyBenchmark { benchmarkBuildInfo = _benchmarkStanzaBuildInfo stanza } @@ -469,6 +474,10 @@ validateBenchmark pos stanza = case _benchmarkStanzaBenchmarkType stanza of } where + benchmarkStanzaType = + _benchmarkStanzaBenchmarkType stanza + <|> benchmarkTypeExe <$ _benchmarkStanzaMainIs stanza + missingField name tt = "The '" ++ name ++ "' field is required for the " ++ prettyShow tt ++ " benchmark type." diff --git a/Cabal-syntax/src/Distribution/PackageDescription/Parsec.hs b/Cabal-syntax/src/Distribution/PackageDescription/Parsec.hs index 5f19e740e75..1e38664f413 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/Parsec.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/Parsec.hs @@ -319,10 +319,8 @@ goSections specVer = traverse_ process let hasType ts = testInterface ts /= testInterface mempty unless (onAllBranches hasType testSuite) $ lift $ parseFailure pos $ concat [ "Test suite " ++ show (prettyShow name') - , " is missing required field \"type\" or the field " - , "is not present in all conditional branches. The " - , "available test types are: " - , intercalate ", " (map prettyShow knownTestTypes) + , " is missing required field \"main-is\" or the field " + , "is not present in all conditional branches." ] -- TODO check duplicate name here? @@ -337,10 +335,8 @@ goSections specVer = traverse_ process let hasType ts = benchmarkInterface ts /= benchmarkInterface mempty unless (onAllBranches hasType bench) $ lift $ parseFailure pos $ concat [ "Benchmark " ++ show (prettyShow name') - , " is missing required field \"type\" or the field " - , "is not present in all conditional branches. The " - , "available benchmark types are: " - , intercalate ", " (map prettyShow knownBenchmarkTypes) + , " is missing required field \"main-is\" or the field " + , "is not present in all conditional branches." ] -- TODO check duplicate name here? diff --git a/Cabal-syntax/src/Distribution/Types/BenchmarkInterface.hs b/Cabal-syntax/src/Distribution/Types/BenchmarkInterface.hs index ddf04e3fa5f..867d36db804 100644 --- a/Cabal-syntax/src/Distribution/Types/BenchmarkInterface.hs +++ b/Cabal-syntax/src/Distribution/Types/BenchmarkInterface.hs @@ -11,8 +11,7 @@ import Distribution.Compat.Prelude import Distribution.Types.BenchmarkType import Distribution.Version --- | The benchmark interfaces that are currently defined. Each --- benchmark must specify which interface it supports. +-- | The benchmark interfaces that are currently defined. -- -- More interfaces may be defined in future, either new revisions or -- totally new interfaces. diff --git a/Cabal-syntax/src/Distribution/Types/BenchmarkType.hs b/Cabal-syntax/src/Distribution/Types/BenchmarkType.hs index d991fbccae2..cd17b2e5456 100644 --- a/Cabal-syntax/src/Distribution/Types/BenchmarkType.hs +++ b/Cabal-syntax/src/Distribution/Types/BenchmarkType.hs @@ -5,6 +5,7 @@ module Distribution.Types.BenchmarkType ( BenchmarkType(..), knownBenchmarkTypes, + benchmarkTypeExe, ) where import Distribution.Compat.Prelude @@ -28,7 +29,10 @@ instance Structured BenchmarkType instance NFData BenchmarkType where rnf = genericRnf knownBenchmarkTypes :: [BenchmarkType] -knownBenchmarkTypes = [ BenchmarkTypeExe (mkVersion [1,0]) ] +knownBenchmarkTypes = [ benchmarkTypeExe ] + +benchmarkTypeExe :: BenchmarkType +benchmarkTypeExe = BenchmarkTypeExe (mkVersion [1,0]) instance Pretty BenchmarkType where pretty (BenchmarkTypeExe ver) = text "exitcode-stdio-" <<>> pretty ver diff --git a/Cabal-syntax/src/Distribution/Types/TestSuiteInterface.hs b/Cabal-syntax/src/Distribution/Types/TestSuiteInterface.hs index 330e9bc6dcb..61916cd9695 100644 --- a/Cabal-syntax/src/Distribution/Types/TestSuiteInterface.hs +++ b/Cabal-syntax/src/Distribution/Types/TestSuiteInterface.hs @@ -12,8 +12,7 @@ import Distribution.Types.TestType import Distribution.ModuleName import Distribution.Version --- | The test suite interfaces that are currently defined. Each test suite must --- specify which interface it supports. +-- | The test suite interfaces that are currently defined. -- -- More interfaces may be defined in future, either new revisions or totally -- new interfaces. diff --git a/Cabal-syntax/src/Distribution/Types/TestType.hs b/Cabal-syntax/src/Distribution/Types/TestType.hs index b81d3043fba..983ded6fb38 100644 --- a/Cabal-syntax/src/Distribution/Types/TestType.hs +++ b/Cabal-syntax/src/Distribution/Types/TestType.hs @@ -5,6 +5,8 @@ module Distribution.Types.TestType ( TestType(..), knownTestTypes, + testTypeExe, + testTypeLib, ) where import Distribution.Compat.Prelude @@ -28,8 +30,15 @@ instance Structured TestType instance NFData TestType where rnf = genericRnf knownTestTypes :: [TestType] -knownTestTypes = [ TestTypeExe (mkVersion [1,0]) - , TestTypeLib (mkVersion [0,9]) ] +knownTestTypes = [ testTypeExe + , testTypeLib + ] + +testTypeExe :: TestType +testTypeExe = TestTypeExe (mkVersion [1,0]) + +testTypeLib :: TestType +testTypeLib = TestTypeLib (mkVersion [0,9]) instance Pretty TestType where pretty (TestTypeExe ver) = text "exitcode-stdio-" <<>> pretty ver diff --git a/Cabal-tests/tests/ParserTests/errors/issue-5055-2.errors b/Cabal-tests/tests/ParserTests/errors/issue-5055-2.errors index fa30b4ad99b..ef5374ee35c 100644 --- a/Cabal-tests/tests/ParserTests/errors/issue-5055-2.errors +++ b/Cabal-tests/tests/ParserTests/errors/issue-5055-2.errors @@ -1,2 +1,2 @@ VERSION: Just (mkVersion [2,0]) -issue-5055-2.cabal:15:1: Test suite "flag-cabal-test" is missing required field "type" or the field is not present in all conditional branches. The available test types are: exitcode-stdio-1.0, detailed-0.9 +issue-5055-2.cabal:15:1: Test suite "flag-cabal-test" is missing required field "main-is" or the field is not present in all conditional branches. diff --git a/Cabal-tests/tests/ParserTests/errors/issue-5055.errors b/Cabal-tests/tests/ParserTests/errors/issue-5055.errors index 650ac0d89c5..60056dae7fc 100644 --- a/Cabal-tests/tests/ParserTests/errors/issue-5055.errors +++ b/Cabal-tests/tests/ParserTests/errors/issue-5055.errors @@ -1,2 +1,2 @@ VERSION: Just (mkVersion [2,0]) -issue-5055.cabal:15:1: Test suite "flag-cabal-test" is missing required field "type" or the field is not present in all conditional branches. The available test types are: exitcode-stdio-1.0, detailed-0.9 +issue-5055.cabal:15:1: Test suite "flag-cabal-test" is missing required field "main-is" or the field is not present in all conditional branches. diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr b/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr index be5e955442b..648ee1f4f76 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr @@ -213,11 +213,9 @@ GenericPackageDescription { condTreeData = TestSuite { testName = UnqualComponentName "", - testInterface = - TestSuiteUnsupported - (TestTypeUnknown - "" - (mkVersion [])), + testInterface = TestSuiteExeV10 + (mkVersion [1, 0]) + "FirstMain.hs", testBuildInfo = BuildInfo { buildable = True, buildTools = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-5055.format b/Cabal-tests/tests/ParserTests/regressions/issue-5055.format index 5aa4a1288f6..3e186e2391d 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-5055.format +++ b/Cabal-tests/tests/ParserTests/regressions/issue-5055.format @@ -19,3 +19,5 @@ test-suite flag-cabal-test build-depends: base >=4.8 && <5 if os(windows) + type: exitcode-stdio-1.0 + main-is: FirstMain.hs diff --git a/Cabal/src/Distribution/PackageDescription/Check.hs b/Cabal/src/Distribution/PackageDescription/Check.hs index 8c48d923271..0a33d4ac735 100644 --- a/Cabal/src/Distribution/PackageDescription/Check.hs +++ b/Cabal/src/Distribution/PackageDescription/Check.hs @@ -322,12 +322,14 @@ checkTestSuite pkg test = TestSuiteUnsupported tt@(TestTypeUnknown _ _) -> Just $ PackageBuildWarning $ quote (prettyShow tt) ++ " is not a known type of test suite. " + ++ "Either remove the 'type' field or use a known type. " ++ "The known test suite types are: " ++ commaSep (map prettyShow knownTestTypes) TestSuiteUnsupported tt -> Just $ PackageBuildWarning $ quote (prettyShow tt) ++ " is not a supported test suite version. " + ++ "Either remove the 'type' field or use a known type. " ++ "The known test suite types are: " ++ commaSep (map prettyShow knownTestTypes) _ -> Nothing @@ -372,12 +374,14 @@ checkBenchmark _pkg bm = BenchmarkUnsupported tt@(BenchmarkTypeUnknown _ _) -> Just $ PackageBuildWarning $ quote (prettyShow tt) ++ " is not a known type of benchmark. " + ++ "Either remove the 'type' field or use a known type. " ++ "The known benchmark types are: " ++ commaSep (map prettyShow knownBenchmarkTypes) BenchmarkUnsupported tt -> Just $ PackageBuildWarning $ quote (prettyShow tt) ++ " is not a supported benchmark version. " + ++ "Either remove the 'type' field or use a known type. " ++ "The known benchmark types are: " ++ commaSep (map prettyShow knownBenchmarkTypes) _ -> Nothing diff --git a/cabal-install/tests/IntegrationTests2/targets/benchmarks-disabled/p.cabal b/cabal-install/tests/IntegrationTests2/targets/benchmarks-disabled/p.cabal index c3f2b537f9e..c20518f8579 100644 --- a/cabal-install/tests/IntegrationTests2/targets/benchmarks-disabled/p.cabal +++ b/cabal-install/tests/IntegrationTests2/targets/benchmarks-disabled/p.cabal @@ -9,7 +9,6 @@ benchmark solver-disabled build-depends: a-package-that-does-not-exist benchmark user-disabled - type: exitcode-stdio-1.0 main-is: Test.hs build-depends: base diff --git a/cabal-install/tests/IntegrationTests2/targets/multiple-tests/p.cabal b/cabal-install/tests/IntegrationTests2/targets/multiple-tests/p.cabal index 2816cf2d814..9d444f9e25d 100644 --- a/cabal-install/tests/IntegrationTests2/targets/multiple-tests/p.cabal +++ b/cabal-install/tests/IntegrationTests2/targets/multiple-tests/p.cabal @@ -4,7 +4,6 @@ build-type: Simple cabal-version: >= 1.10 test-suite p1 - type: exitcode-stdio-1.0 main-is: P1.hs build-depends: base diff --git a/cabal-install/tests/IntegrationTests2/targets/variety/p.cabal b/cabal-install/tests/IntegrationTests2/targets/variety/p.cabal index d00e3a5ab3e..2eb084fc274 100644 --- a/cabal-install/tests/IntegrationTests2/targets/variety/p.cabal +++ b/cabal-install/tests/IntegrationTests2/targets/variety/p.cabal @@ -16,7 +16,6 @@ executable an-exe other-modules: AModule test-suite a-testsuite - type: exitcode-stdio-1.0 main-is: Test.hs other-modules: AModule diff --git a/cabal-testsuite/PackageTests/DuplicateModuleName/DuplicateModuleName.cabal b/cabal-testsuite/PackageTests/DuplicateModuleName/DuplicateModuleName.cabal index bff80d26a46..63cfe4b4a25 100644 --- a/cabal-testsuite/PackageTests/DuplicateModuleName/DuplicateModuleName.cabal +++ b/cabal-testsuite/PackageTests/DuplicateModuleName/DuplicateModuleName.cabal @@ -13,7 +13,6 @@ library default-language: Haskell2010 test-suite foo - type: detailed-0.9 test-module: Foo hs-source-dirs: tests build-depends: base, Cabal, DuplicateModuleName diff --git a/cabal-testsuite/PackageTests/NewBuild/CmdBench/MultipleBenchmarks/MultipleBenchmarks.cabal b/cabal-testsuite/PackageTests/NewBuild/CmdBench/MultipleBenchmarks/MultipleBenchmarks.cabal index 426a3f9c469..1c2112d783e 100644 --- a/cabal-testsuite/PackageTests/NewBuild/CmdBench/MultipleBenchmarks/MultipleBenchmarks.cabal +++ b/cabal-testsuite/PackageTests/NewBuild/CmdBench/MultipleBenchmarks/MultipleBenchmarks.cabal @@ -4,7 +4,6 @@ build-type: Simple cabal-version: >= 1.10 benchmark foo - type: exitcode-stdio-1.0 main-is: Foo.hs build-depends: base default-language: Haskell2010 diff --git a/changelog.d/pr-8115 b/changelog.d/pr-8115 new file mode 100644 index 00000000000..24ebd1b0cf3 --- /dev/null +++ b/changelog.d/pr-8115 @@ -0,0 +1,10 @@ +synopsis: Make type field optional for tests and benchmarks +packages: Cabal, Cabal-syntax +prs: #8115 +issues: #7459 +description: { + +Allow the ommission of the `type` field in `test-suite` and `benchmark` stanzas +when the type can be inferred by the presence of `main-is` or `test-module`. + +} diff --git a/doc/cabal-package.rst b/doc/cabal-package.rst index 355fef84ba1..19074207cd0 100644 --- a/doc/cabal-package.rst +++ b/doc/cabal-package.rst @@ -926,7 +926,6 @@ look something like this: default-language: Haskell2010 test-suite test-foo - type: exitcode-stdio-1.0 main-is: test-foo.hs -- NOTE: no constraints on 'foo-internal' as same-package -- dependencies implicitly refer to the same package instance @@ -1188,14 +1187,14 @@ Test suites The test suite may be described using the following fields, as well as build information fields (see the section on `build information`_). -.. pkg-field:: type: interface (required) +.. pkg-field:: type: interface The interface type and version of the test suite. Cabal supports two - test suite interfaces, called ``exitcode-stdio-1.0`` and + test suite interfaces, called ``exitcode-stdio-1.0`` (default) and ``detailed-0.9``. Each of these types may require or disallow other fields as described below. -Test suites using the ``exitcode-stdio-1.0`` interface are executables +Test suites using the ``exitcode-stdio-1.0`` (default) interface are executables that indicate test failure with a non-zero exit code when run; they may provide human-readable log information through the standard output and error channels. The ``exitcode-stdio-1.0`` type requires the ``main-is`` @@ -1204,7 +1203,6 @@ field. .. pkg-field:: main-is: filename :synopsis: Module containing tests main function. - :required: ``exitcode-stdio-1.0`` :disallowed: ``detailed-0.9`` The name of the ``.hs`` or ``.lhs`` file containing the ``Main`` @@ -1226,7 +1224,6 @@ the :pkg-field:`test-module` field. .. pkg-field:: test-module: identifier - :required: ``detailed-0.9`` :disallowed: ``exitcode-stdio-1.0`` The module exporting the ``tests`` symbol. @@ -1247,7 +1244,6 @@ demonstrate the use of the ``exitcode-stdio-1.0`` interface. Build-Type: Simple Test-Suite test-foo - type: exitcode-stdio-1.0 main-is: test-foo.hs build-depends: base >= 4 && < 5 default-language: Haskell2010 @@ -1282,7 +1278,6 @@ be provided by the library that provides the testing facility. Build-Type: Simple Test-Suite test-bar - type: detailed-0.9 test-module: Bar build-depends: base >= 4 && < 5, Cabal >= 1.9.2 && < 2 default-language: Haskell2010 @@ -1345,20 +1340,8 @@ Benchmarks The benchmark may be described using the following fields, as well as build information fields (see the section on `build information`_). -.. pkg-field:: type: interface (required) - - The interface type and version of the benchmark. At the moment Cabal - only support one benchmark interface, called ``exitcode-stdio-1.0``. - -Benchmarks using the ``exitcode-stdio-1.0`` interface are executables -that indicate failure to run the benchmark with a non-zero exit code -when run; they may provide human-readable information through the -standard output and error channels. - .. pkg-field:: main-is: filename - :required: ``exitcode-stdio-1.0`` - The name of the ``.hs`` or ``.lhs`` file containing the ``Main`` module. Note that it is the ``.hs`` filename that must be listed, even if that file is generated using a preprocessor. The source file @@ -1367,12 +1350,9 @@ standard output and error channels. field of an executable section. Further, while the name of the file may vary, the module itself must be named ``Main``. -Example: Package using ``exitcode-stdio-1.0`` interface +Example: """"""""""""""""""""""""""""""""""""""""""""""""""""""" -The example package description and executable source file below -demonstrate the use of the ``exitcode-stdio-1.0`` interface. - .. code-block:: cabal :caption: foo.cabal :name: foo-bench.cabal @@ -1384,7 +1364,6 @@ demonstrate the use of the ``exitcode-stdio-1.0`` interface. Build-Type: Simple Benchmark bench-foo - type: exitcode-stdio-1.0 main-is: bench-foo.hs build-depends: base >= 4 && < 5, time >= 1.1 && < 1.7 default-language: Haskell2010 @@ -2719,7 +2698,6 @@ Starting with Cabal-2.2 it's possible to use common build info stanzas. test-suite tests import: deps, test-deps - type: exitcode-stdio-1.0 main-is: Tests.hs build-depends: foo default-language: Haskell2010