From 44c2e1a9ae7111790b74f885a956d2120903f4a5 Mon Sep 17 00:00:00 2001 From: toonn Date: Mon, 28 Feb 2022 11:47:10 +0100 Subject: [PATCH 01/17] Provide explanation for invalid license identifier (#6200) After discussion in #hackage it seemed prudent to add some minimal explanation of what a valid SPDX identifier might look like in the error message. --- .../src/Distribution/Client/Init/Interactive/Command.hs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs index 10c758cc213..6223a8c3cd3 100644 --- a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs @@ -328,7 +328,11 @@ licensePrompt flags = getLicense flags $ do case simpleParsec l of Nothing -> do - putStrLn "The license must be a valid SPDX expression." + putStrLn ( "The license must be a valid SPDX expression:" + ++ "\n - On the SPDX License List: https://spdx.org/licenses/" + ++ "\n - NONE, if you do not want to grant any license" + ++ "\n - LicenseRef-( alphanumeric | - | . )+" + ) licensePrompt flags Just l' -> return l' where From 477696ed6d330d24007d0552bc90374a50dfbc85 Mon Sep 17 00:00:00 2001 From: Javier Neira Date: Mon, 28 Feb 2022 10:07:38 +0100 Subject: [PATCH 02/17] Remove unnecessary if As github already is not triggering workflows for commits with skip ci --- .github/workflows/users-guide.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/users-guide.yml b/.github/workflows/users-guide.yml index 48e2171233c..29483a564ed 100644 --- a/.github/workflows/users-guide.yml +++ b/.github/workflows/users-guide.yml @@ -42,10 +42,6 @@ defaults: jobs: build: - if: | - !contains(github.event.head_commit.message, '[skip ci]') - && !contains(github.event.head_commit.message, '[ci skip]') - runs-on: ubuntu-latest strategy: matrix: From aebe39a19309e8b350aabaa0416f01f8c18caecd Mon Sep 17 00:00:00 2001 From: Mel Zuser Date: Sat, 19 Feb 2022 17:40:22 -0500 Subject: [PATCH 03/17] Add support for cabal.project fields to scripts Closes #5698 --- .../src/Distribution/Client/ProjectConfig.hs | 2 + .../src/Distribution/Client/ScriptUtils.hs | 72 ++++++++++++------- 2 files changed, 50 insertions(+), 24 deletions(-) diff --git a/cabal-install/src/Distribution/Client/ProjectConfig.hs b/cabal-install/src/Distribution/Client/ProjectConfig.hs index 2b78c16449d..eb87215bd7b 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig.hs @@ -29,6 +29,8 @@ module Distribution.Client.ProjectConfig ( readGlobalConfig, readProjectLocalExtraConfig, readProjectLocalFreezeConfig, + parseProjectConfig, + reportParseResult, showProjectConfig, withProjectOrGlobalConfig, writeProjectLocalExtraConfig, diff --git a/cabal-install/src/Distribution/Client/ScriptUtils.hs b/cabal-install/src/Distribution/Client/ScriptUtils.hs index 7215ac3d330..9f012380256 100644 --- a/cabal-install/src/Distribution/Client/ScriptUtils.hs +++ b/cabal-install/src/Distribution/Client/ScriptUtils.hs @@ -30,7 +30,8 @@ import Distribution.Client.HashValue import Distribution.Client.NixStyleOptions ( NixStyleFlags (..) ) import Distribution.Client.ProjectConfig - ( ProjectConfig(..), ProjectConfigShared(..), withProjectOrGlobalConfig ) + ( ProjectConfig(..), ProjectConfigShared(..) + , parseProjectConfig, reportParseResult, withProjectOrGlobalConfig ) import Distribution.Client.ProjectFlags ( flagIgnoreProject ) import Distribution.Client.Setup @@ -46,7 +47,7 @@ import Distribution.Fields import Distribution.PackageDescription.FieldGrammar ( executableFieldGrammar ) import Distribution.PackageDescription.PrettyPrint - ( showGenericPackageDescription, writeGenericPackageDescription ) + ( showGenericPackageDescription ) import Distribution.Parsec ( Position(..) ) import Distribution.Simple.Flag @@ -56,7 +57,7 @@ import Distribution.Simple.PackageDescription import Distribution.Simple.Setup ( Flag(..) ) import Distribution.Simple.Utils - ( createDirectoryIfMissingVerbose, createTempDirectory, die', handleDoesNotExist, readUTF8File, warn ) + ( createDirectoryIfMissingVerbose, createTempDirectory, die', handleDoesNotExist, readUTF8File, warn, writeUTF8File ) import qualified Distribution.SPDX.License as SPDX import Distribution.Solver.Types.SourcePackage as SP ( SourcePackage(..) ) @@ -214,10 +215,13 @@ withContextAndSelectors noTargets kind flags@NixStyleFlags {..} targetStrings gl let projectRoot = distProjectRootDirectory $ distDirLayout ctx writeFile (projectRoot "scriptlocation") =<< canonicalizePath script - executable <- readScriptBlockFromScript verbosity =<< BS.readFile script + scriptContents <- BS.readFile script + executable <- readExecutableBlockFromScript verbosity scriptContents + projectCfg <- readProjectBlockFromScript verbosity (takeFileName script) scriptContents let executable' = executable & L.buildInfo . L.defaultLanguage %~ maybe (Just Haskell2010) Just - return (ScriptContext script executable', ctx, defaultTarget) + ctx' = ctx & lProjectConfig %~ (<> projectCfg) + return (ScriptContext script executable', ctx', defaultTarget) else reportTargetSelectorProblems verbosity err withTemporaryTempDirectory :: (IO FilePath -> IO a) -> IO a @@ -236,17 +240,18 @@ withTemporaryTempDirectory act = newEmptyMVar >>= \m -> bracket (getMkTmp m) (rm -- | Add the 'SourcePackage' to the context and use it to write a .cabal file. updateContextAndWriteProjectFile' :: ProjectBaseContext -> SourcePackage (PackageLocation (Maybe FilePath)) -> IO ProjectBaseContext updateContextAndWriteProjectFile' ctx srcPkg = do - let projectRoot = distProjectRootDirectory $ distDirLayout ctx - projectFile = projectRoot fakePackageCabalFileName - writeProjectFile = writeGenericPackageDescription (projectRoot fakePackageCabalFileName) (srcpkgDescription srcPkg) - projectFileExists <- doesFileExist projectFile + let projectRoot = distProjectRootDirectory $ distDirLayout ctx + packageFile = projectRoot fakePackageCabalFileName + contents = showGenericPackageDescription (srcpkgDescription srcPkg) + writePackageFile = writeUTF8File packageFile contents -- TODO This is here to prevent reconfiguration of cached repl packages. -- It's worth investigating why it's needed in the first place. - if projectFileExists then do - contents <- force <$> readUTF8File projectFile - when (contents /= showGenericPackageDescription (srcpkgDescription srcPkg)) - writeProjectFile - else writeProjectFile + packageFileExists <- doesFileExist packageFile + if packageFileExists then do + cached <- force <$> readUTF8File packageFile + when (cached /= contents) + writePackageFile + else writePackageFile return (ctx & lLocalPackages %~ (++ [SpecificSourcePackage srcPkg])) -- | Add add the executable metadata to the context and write a .cabal file. @@ -283,26 +288,41 @@ parseScriptBlock str = readScriptBlock :: Verbosity -> BS.ByteString -> IO Executable readScriptBlock verbosity = parseString parseScriptBlock verbosity "script block" --- | Extract the first encountered script metadata block started end --- terminated by the bellow tokens or die. +-- | Extract the first encountered executable metadata block started and +-- terminated by the below tokens or die. -- -- * @{- cabal:@ -- -- * @-}@ -- -- Return the metadata. -readScriptBlockFromScript :: Verbosity -> BS.ByteString -> IO Executable -readScriptBlockFromScript verbosity str = do - str' <- case extractScriptBlock str of +readExecutableBlockFromScript :: Verbosity -> BS.ByteString -> IO Executable +readExecutableBlockFromScript verbosity str = do + str' <- case extractScriptBlock "cabal" str of Left e -> die' verbosity $ "Failed extracting script block: " ++ e Right x -> return x when (BS.all isSpace str') $ warn verbosity "Empty script block" readScriptBlock verbosity str' +-- | Extract the first encountered project metadata block started and +-- terminated by the below tokens. +-- +-- * @{- project:@ +-- +-- * @-}@ +-- +-- Return the metadata. +readProjectBlockFromScript :: Verbosity -> String -> BS.ByteString -> IO ProjectConfig +readProjectBlockFromScript verbosity scriptName str = do + case extractScriptBlock "project" str of + Left _ -> return mempty + Right x -> reportParseResult verbosity "script" scriptName + $ parseProjectConfig scriptName x + -- | Extract the first encountered script metadata block started end -- terminated by the tokens -- --- * @{- cabal:@ +-- * @{-
:@ -- -- * @-}@ -- @@ -311,8 +331,8 @@ readScriptBlockFromScript verbosity str = do -- -- In case of missing or unterminated blocks a 'Left'-error is -- returned. -extractScriptBlock :: BS.ByteString -> Either String BS.ByteString -extractScriptBlock str = goPre (BS.lines str) +extractScriptBlock :: BS.ByteString -> BS.ByteString -> Either String BS.ByteString +extractScriptBlock header str = goPre (BS.lines str) where isStartMarker = (== startMarker) . stripTrailSpace isEndMarker = (== endMarker) . stripTrailSpace @@ -330,8 +350,8 @@ extractScriptBlock str = goPre (BS.lines str) | otherwise = goBody (l:acc) ls startMarker, endMarker :: BS.ByteString - startMarker = fromString "{- cabal:" - endMarker = fromString "-}" + startMarker = "{- " <> header <> ":" + endMarker = "-}" -- | The base for making a 'SourcePackage' for a fake project. -- It needs a 'Distribution.Types.Library.Library' or 'Executable' depending on the command. @@ -362,6 +382,10 @@ lLocalPackages :: Lens' ProjectBaseContext [PackageSpecifier UnresolvedSourcePac lLocalPackages f s = fmap (\x -> s { localPackages = x }) (f (localPackages s)) {-# inline lLocalPackages #-} +lProjectConfig :: Lens' ProjectBaseContext ProjectConfig +lProjectConfig f s = fmap (\x -> s { projectConfig = x }) (f (projectConfig s)) +{-# inline lProjectConfig #-} + -- Character classes -- Transcribed from "templates/Lexer.x" ccSpace, ccCtrlchar, ccPrintable, ccSymbol', ccParen, ccNamecore :: Set Char From 2910b62b6561952689a3d0b231e83838c83f3726 Mon Sep 17 00:00:00 2001 From: Mel Zuser Date: Sun, 20 Feb 2022 12:18:03 -0500 Subject: [PATCH 04/17] add docs and changelog entry --- changelog.d/pr-7851 | 6 ++++-- doc/cabal-commands.rst | 11 +++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/changelog.d/pr-7851 b/changelog.d/pr-7851 index ecc0769349a..6f251064fcd 100644 --- a/changelog.d/pr-7851 +++ b/changelog.d/pr-7851 @@ -1,7 +1,7 @@ synopsis: Better support for scripts packages: cabal-install -prs: #7851 #7925 #7938 #7990 -issues: #7842 #7073 #6354 #6149 #5508 +prs: #7851 #7925 #7938 #7990 #7997 +issues: #7842 #7073 #6354 #6149 #5508 #5698 description: { @@ -15,5 +15,7 @@ description: { - The name of the generated script executable has been changed from "script" to "cabal-script-" for easier process management. - Reduce the default verbosity of scripts, so that the build output doesn't interfere with the script output. +- Scripts now support a project metadata block that allows them to use options + that would normally be set in a cabal.project file. } diff --git a/doc/cabal-commands.rst b/doc/cabal-commands.rst index f347b120183..654c2a38016 100644 --- a/doc/cabal-commands.rst +++ b/doc/cabal-commands.rst @@ -465,14 +465,21 @@ a script that looks like: #!/usr/bin/env cabal {- cabal: - build-depends: base ^>= 4.11 - , shelly ^>= 1.8.1 + build-depends: base ^>= 4.14 + , shelly ^>= 1.10 + -} + {- project: + with-compiler: ghc-8.10.7 -} main :: IO () main = do ... +Where there cabal metadata block is mandatory and contains fields from a +package executable block, and the project metadata block is optional and +contains fields that would be in the cabal.project file in a regular project. + It can either be executed like any other script, using ``cabal`` as an interpreter, or through this command: From 389ee6294ea5210ed407e087968e4b68d6b343fa Mon Sep 17 00:00:00 2001 From: Mel Zuser Date: Sat, 26 Feb 2022 22:04:25 -0500 Subject: [PATCH 05/17] add test --- .../NewBuild/CmdRun/ScriptWithProjectBlock/cabal.out | 7 +++++++ .../CmdRun/ScriptWithProjectBlock/cabal.test.hs | 6 ++++++ .../NewBuild/CmdRun/ScriptWithProjectBlock/s.hs | 10 ++++++++++ 3 files changed, 23 insertions(+) create mode 100644 cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/cabal.out create mode 100644 cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/cabal.test.hs create mode 100644 cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/s.hs diff --git a/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/cabal.out b/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/cabal.out new file mode 100644 index 00000000000..ec27da9398e --- /dev/null +++ b/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/cabal.out @@ -0,0 +1,7 @@ +# cabal v2-run +Resolving dependencies... +Build profile: -w ghc- -O2 +In order, the following will be built: + - fake-package-0 (exe:cabal-script-s.hs) (first run) +Configuring executable 'cabal-script-s.hs' for fake-package-0.. +Building executable 'cabal-script-s.hs' for fake-package-0.. diff --git a/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/cabal.test.hs b/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/cabal.test.hs new file mode 100644 index 00000000000..8c92079136b --- /dev/null +++ b/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/cabal.test.hs @@ -0,0 +1,6 @@ +import Test.Cabal.Prelude + +main = cabalTest $ do + -- script is called "s.hs" to avoid Windows long path issue in CI + res <- cabal' "v2-run" ["s.hs"] + assertOutputContains "Hello World" res diff --git a/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/s.hs b/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/s.hs new file mode 100644 index 00000000000..1b5685ea8b7 --- /dev/null +++ b/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/s.hs @@ -0,0 +1,10 @@ +#!/usr/bin/env cabal +{- cabal: +build-depends: base +-} +{- project: +optimization: 2 +-} + +main :: IO () +main = putStrLn "Hello World" From a2580fa680ab0e0a6dfd6e01c7413f23cb96f57f Mon Sep 17 00:00:00 2001 From: Mel Zuser Date: Wed, 2 Mar 2022 09:42:44 -0500 Subject: [PATCH 06/17] add doc entry on script metadata field validation --- doc/cabal-commands.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/cabal-commands.rst b/doc/cabal-commands.rst index 654c2a38016..3292cd5c785 100644 --- a/doc/cabal-commands.rst +++ b/doc/cabal-commands.rst @@ -480,6 +480,10 @@ Where there cabal metadata block is mandatory and contains fields from a package executable block, and the project metadata block is optional and contains fields that would be in the cabal.project file in a regular project. +Only some fields are supported in the metadata blocks, and these fields are +currently not validated. See +`#8024 `__ for details. + It can either be executed like any other script, using ``cabal`` as an interpreter, or through this command: From f94ff6f35e5afec4f3201e18ae91389eeab9ae65 Mon Sep 17 00:00:00 2001 From: Mel Zuser Date: Wed, 2 Mar 2022 14:18:18 -0500 Subject: [PATCH 07/17] update docs for clarity --- doc/cabal-commands.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/doc/cabal-commands.rst b/doc/cabal-commands.rst index 3292cd5c785..27cc5426376 100644 --- a/doc/cabal-commands.rst +++ b/doc/cabal-commands.rst @@ -436,13 +436,15 @@ See `the v2-build section <#cabal-v2-build>`__ for the target syntax. When ``TARGET`` is one of the following: -- A component target: execute the specified executable, benchmark or test suite +- A component target: execute the specified executable, benchmark or test suite. - A package target: 1. If the package has exactly one executable component, it will be selected. 2. If the package has multiple executable components, an error is raised. 3. If the package has exactly one test or benchmark component, it will be selected. - 4. Otherwise an issue is raised + 4. Otherwise an issue is raised. + +- The path to a script: execute the script at the path. - Empty target: Same as package target, implicitly using the package from the current working directory. @@ -458,8 +460,8 @@ have to separate them with ``--``. $ cabal v2-run target -- -a -bcd --argument -``v2-run`` also supports running script files that use a certain format. With -a script that looks like: +``v2-run`` supports running script files that use a certain format. +Scripts look like: :: @@ -484,13 +486,12 @@ Only some fields are supported in the metadata blocks, and these fields are currently not validated. See `#8024 `__ for details. -It can either be executed like any other script, using ``cabal`` as an -interpreter, or through this command: +A script can either be executed directly using `cabal` as an interpreter or +with the command: :: $ cabal v2-run path/to/script - $ cabal v2-run path/to/script -- --arg1 # args are passed like this The executable is cached under the cabal directory, and can be pre-built with ``cabal v2-build path/to/script`` and the cache can be removed with From b427b0012c16e8e2618b1696146464e32a7a3d46 Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Mon, 28 Feb 2022 19:12:42 +0100 Subject: [PATCH 08/17] Remove outdated skip of test CustomPlain on macOS It's travis specific, and the related ticket #3938 has been resolved in the meantime. --- cabal-testsuite/PackageTests/CustomPlain/setup.test.hs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cabal-testsuite/PackageTests/CustomPlain/setup.test.hs b/cabal-testsuite/PackageTests/CustomPlain/setup.test.hs index 6016b2c4f9b..2b4a27b1388 100644 --- a/cabal-testsuite/PackageTests/CustomPlain/setup.test.hs +++ b/cabal-testsuite/PackageTests/CustomPlain/setup.test.hs @@ -1,10 +1,5 @@ import Test.Cabal.Prelude main = setupTest $ do skipUnless "no Cabal for GHC" =<< hasCabalForGhc - -- On Travis OSX, Cabal shipped with GHC 7.8 does not work - -- with error "setup: /usr/bin/ar: permission denied"; see - -- also https://github.com/haskell/cabal/issues/3938 - -- This is a hack to make the test not run in this case. - skipIf "osx and ghc < 7.10" =<< liftM2 (&&) isOSX (ghcVersionIs (< mkVersion [7,10])) setup' "configure" [] >>= assertOutputContains "ThisIsCustomYeah" setup' "build" [] >>= assertOutputContains "ThisIsCustomYeah" From 7cea19ab1b18803b615b9c1ac2faebeb57485177 Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Thu, 3 Mar 2022 20:08:41 +0100 Subject: [PATCH 09/17] Note that cabal-with-hpc test skip is not travis-specific --- .../TestSuiteTests/ExeV10/cabal-with-hpc.multitest.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/cabal-with-hpc.multitest.hs b/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/cabal-with-hpc.multitest.hs index e093d559b9f..14f12247548 100644 --- a/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/cabal-with-hpc.multitest.hs +++ b/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/cabal-with-hpc.multitest.hs @@ -9,7 +9,7 @@ import qualified Distribution.Verbosity as Verbosity import Test.Cabal.Prelude main = cabalTest $ do - skipIf "osx" =<< isOSX -- TODO: re-enable this once the macOS Travis + skipIf "osx" =<< isOSX -- TODO: re-enable this once the macOS CI -- issues are resolved, see discussion in #4902. hasShared <- hasSharedLibraries From 6b36f3f987b491486dbe24eaafc3d13fabc83568 Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Mon, 28 Feb 2022 19:49:15 +0100 Subject: [PATCH 10/17] Replace ghcVersionIs by isGhcVersion, consistent with isWindows, etc. --- .../PackageTests/CmmSourcesDyn/setup.test.hs | 2 +- .../PackageTests/SPDX/cabal-old-build.test.hs | 2 +- cabal-testsuite/README.md | 2 +- cabal-testsuite/src/Test/Cabal/Prelude.hs | 30 +++++++++---------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/cabal-testsuite/PackageTests/CmmSourcesDyn/setup.test.hs b/cabal-testsuite/PackageTests/CmmSourcesDyn/setup.test.hs index 072977fdee3..800a540696a 100644 --- a/cabal-testsuite/PackageTests/CmmSourcesDyn/setup.test.hs +++ b/cabal-testsuite/PackageTests/CmmSourcesDyn/setup.test.hs @@ -1,7 +1,7 @@ import Test.Cabal.Prelude main = setupTest $ do - skipIf "ghc < 7.8" =<< ghcVersionIs (< mkVersion [7,8]) + skipIf "ghc < 7.8" =<< isGhcVersion "< 7.8" setup "configure" [] res <- setup' "build" [] assertOutputContains "= Post common block elimination =" res diff --git a/cabal-testsuite/PackageTests/SPDX/cabal-old-build.test.hs b/cabal-testsuite/PackageTests/SPDX/cabal-old-build.test.hs index 98def645f5e..f88f6249197 100644 --- a/cabal-testsuite/PackageTests/SPDX/cabal-old-build.test.hs +++ b/cabal-testsuite/PackageTests/SPDX/cabal-old-build.test.hs @@ -2,6 +2,6 @@ import Test.Cabal.Prelude main = setupAndCabalTest $ withPackageDb $ do setup_install [] recordMode DoNotRecord $ do - ghc84 <- ghcVersionIs (>= mkVersion [8,4]) + ghc84 <- isGhcVersion ">= 8.4" let lic = if ghc84 then "BSD-3-Clause" else "BSD3" ghcPkg' "field" ["my", "license"] >>= assertOutputContains lic diff --git a/cabal-testsuite/README.md b/cabal-testsuite/README.md index 23af47be95f..afb072d7d5c 100644 --- a/cabal-testsuite/README.md +++ b/cabal-testsuite/README.md @@ -135,7 +135,7 @@ and stderr. **How do I skip running a test in some environments?** Use the `skipIf` and `skipUnless` combinators. Useful parameters to test these with include `hasSharedLibraries`, `hasProfiledLibraries`, -`hasCabalShared`, `ghcVersionIs`, `isWindows`, `isLinux`, `isOSX` +`hasCabalShared`, `isGhcVersion`, `isWindows`, `isLinux`, `isOSX` and `hasCabalForGhc`. **I programatically modified a file in my test suite, but Cabal/GHC diff --git a/cabal-testsuite/src/Test/Cabal/Prelude.hs b/cabal-testsuite/src/Test/Cabal/Prelude.hs index 2e728a07866..3e09c709762 100644 --- a/cabal-testsuite/src/Test/Cabal/Prelude.hs +++ b/cabal-testsuite/src/Test/Cabal/Prelude.hs @@ -36,7 +36,6 @@ import Distribution.Simple.Configure import Distribution.Version import Distribution.Package import Distribution.Parsec (eitherParsec) -import Distribution.Pretty (prettyShow) import Distribution.Types.UnqualComponentName import Distribution.Types.LocalBuildInfo import Distribution.PackageDescription @@ -765,7 +764,7 @@ getScriptCacheDirectory script = do hasSharedLibraries :: TestM Bool hasSharedLibraries = do - shared_libs_were_removed <- ghcVersionIs (>= mkVersion [7,8]) + shared_libs_were_removed <- isGhcVersion ">= 7.8" return (not (buildOS == Windows && shared_libs_were_removed)) hasProfiledLibraries :: TestM Bool @@ -789,13 +788,20 @@ hasCabalShared = do env <- getTestEnv return (testHaveCabalShared env) -ghcVersionIs :: WithCallStack ((Version -> Bool) -> TestM Bool) -ghcVersionIs f = do +isGhcVersion :: WithCallStack (String -> TestM Bool) +isGhcVersion range = do ghc_program <- requireProgramM ghcProgram - case programVersion ghc_program of - Nothing -> error $ "ghcVersionIs: no ghc version for " + v <- case programVersion ghc_program of + Nothing -> error $ "isGhcVersion: no ghc version for " ++ show (programLocation ghc_program) - Just v -> return (f v) + Just v -> return v + vr <- case eitherParsec range of + Left err -> fail err + Right vr -> return vr + return (v `withinRange` vr) + +skipUnlessGhcVersion :: String -> TestM () +skipUnlessGhcVersion range = skipUnless ("needs ghc " ++ range) =<< isGhcVersion range isWindows :: TestM Bool isWindows = return (buildOS == Windows) @@ -809,12 +815,6 @@ isLinux = return (buildOS == Linux) skipIfWindows :: TestM () skipIfWindows = skipIf "Windows" =<< isWindows -skipUnlessGhcVersion :: String -> TestM () -skipUnlessGhcVersion str = - case eitherParsec str of - Right vr -> skipUnless ("needs ghc" ++ prettyShow vr) =<< ghcVersionIs (`withinRange` vr) - Left err -> fail err - getOpenFilesLimit :: TestM (Maybe Integer) #ifdef mingw32_HOST_OS -- No MS-specified limit, was determined experimentally on Windows 10 Pro x64, @@ -855,7 +855,7 @@ hasCabalForGhc = do -- You'll want to exclude them in that case. -- hasNewBuildCompatBootCabal :: TestM Bool -hasNewBuildCompatBootCabal = ghcVersionIs (>= mkVersion [7,9]) +hasNewBuildCompatBootCabal = isGhcVersion ">= 7.9" ------------------------------------------------------------------------ -- * Broken tests @@ -959,7 +959,7 @@ getIPID pn = do delay :: TestM () delay = do env <- getTestEnv - is_old_ghc <- ghcVersionIs (< mkVersion [7,7]) + is_old_ghc <- isGhcVersion "< 7.7" -- For old versions of GHC, we only had second-level precision, -- so we need to sleep a full second. Newer versions use -- millisecond level precision, so we only have to wait From 7dba4e5666b198704819c59f6f7bb678d8d6f6a3 Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Mon, 28 Feb 2022 19:50:26 +0100 Subject: [PATCH 11/17] Add skipIfGhcVersion --- cabal-testsuite/src/Test/Cabal/Prelude.hs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cabal-testsuite/src/Test/Cabal/Prelude.hs b/cabal-testsuite/src/Test/Cabal/Prelude.hs index 3e09c709762..fc17d964f8e 100644 --- a/cabal-testsuite/src/Test/Cabal/Prelude.hs +++ b/cabal-testsuite/src/Test/Cabal/Prelude.hs @@ -803,6 +803,9 @@ isGhcVersion range = do skipUnlessGhcVersion :: String -> TestM () skipUnlessGhcVersion range = skipUnless ("needs ghc " ++ range) =<< isGhcVersion range +skipIfGhcVersion :: String -> TestM () +skipIfGhcVersion range = skipUnless ("incompatible with ghc " ++ range) =<< isGhcVersion range + isWindows :: TestM Bool isWindows = return (buildOS == Windows) From b0caddc9504020539abc00d46d822183a31759cc Mon Sep 17 00:00:00 2001 From: SEKUN Date: Fri, 4 Mar 2022 03:42:10 +0800 Subject: [PATCH 12/17] Update most examples to `cabal` 3.0 (#7942) The main issue being: current examples contain pre-SPDX identifiers which causes `cabal check` to warn about it being an unknown SPDX license identifier. Although there is an example that demonstrates `cabal` 2.0 specifically, hence why I left that one out. The remaining examples I have bumped up to `3.0`, and have updated the license field to an SPDX compliant identifier. * Fix ordering of `cabal-version` since newer versions required it to be at the top, as well as changed `Extensions` to `Default-Extensions`. * Fix missing `default-language` fields * Fix missing `license-field` * `Extensions` -> `Default-Extensions` --- doc/cabal-package.rst | 180 ++++++++++++++++++++++-------------------- 1 file changed, 93 insertions(+), 87 deletions(-) diff --git a/doc/cabal-package.rst b/doc/cabal-package.rst index 819d146dc11..8a96ac96d8b 100644 --- a/doc/cabal-package.rst +++ b/doc/cabal-package.rst @@ -87,10 +87,11 @@ computer architecture and user-specified configuration flags. version: 1.0 library - build-depends: base >= 4 && < 5 - exposed-modules: Foo - extensions: ForeignFunctionInterface - ghc-options: -Wall + default-language: Haskell2010 + build-depends: base >= 4 && < 5 + exposed-modules: Foo + extensions: ForeignFunctionInterface + ghc-options: -Wall if os(windows) build-depends: Win32 >= 2.1 && < 2.6 @@ -101,15 +102,15 @@ The HUnit package contains a file ``HUnit.cabal`` containing: :: + cabal-version: 3.0 name: HUnit version: 1.1.1 synopsis: A unit testing framework for Haskell homepage: http://hunit.sourceforge.net/ category: Testing author: Dean Herington - license: BSD3 + license: BSD-3-Clause license-file: LICENSE - cabal-version: 1.12 build-type: Simple library @@ -117,6 +118,7 @@ The HUnit package contains a file ``HUnit.cabal`` containing: exposed-modules: Test.HUnit.Base, Test.HUnit.Lang, Test.HUnit.Terminal, Test.HUnit.Text, Test.HUnit default-extensions: CPP + default-language: Haskell2010 and the following ``Setup.hs``: @@ -130,25 +132,27 @@ Example: A package containing executable programs :: + cabal-version: 3.0 name: TestPackage version: 0.0 synopsis: Small package with two programs author: Angela Author - license: BSD3 + license: BSD-3-Clause build-type: Simple - cabal-version: >= 1.8 executable program1 - build-depends: HUnit >= 1.1.1 && < 1.2 - main-is: main.hs - hs-source-dirs: prog1 + build-depends: HUnit >= 1.1.1 && < 1.2 + main-is: main.hs + hs-source-dirs: prog1 + default-language: Haskell2010 executable program2 -- A different main.hs because of hs-source-dirs. - main-is: main.hs - build-depends: HUnit >= 1.1.1 && < 1.2 - hs-source-dirs: prog2 - other-modules: Utils + main-is: main.hs + build-depends: HUnit >= 1.1.1 && < 1.2 + hs-source-dirs: prog2 + other-modules: Utils + default-language: Haskell2010 with ``Setup.hs`` the same as above. @@ -157,31 +161,34 @@ Example: A package containing a library and executable programs :: + cabal-version: 3.0 name: TestPackage version: 0.0 synopsis: Package with library and two programs - license: BSD3 + license: BSD-3-Clause author: Angela Author build-type: Simple - cabal-version: >= 1.8 library - build-depends: HUnit >= 1.1.1 && < 1.2 - hs-source-dirs: lib - exposed-modules: A, B, C + build-depends: HUnit >= 1.1.1 && < 1.2 + hs-source-dirs: lib + exposed-modules: A, B, C + default-language: Haskell2010 executable program1 - main-is: main.hs - hs-source-dirs: prog1 - other-modules: D, E + main-is: main.hs + hs-source-dirs: prog1 + other-modules: D, E + default-language: Haskell2010 executable program2 -- A different main.hs because of hs-source-dirs. - main-is: main.hs + main-is: main.hs -- No bound on internal libraries. - build-depends: TestPackage - hs-source-dirs: prog2 - other-modules: Utils + build-depends: TestPackage + hs-source-dirs: prog2 + other-modules: Utils + default-language: Haskell2010 with ``Setup.hs`` the same as above. Note that any library modules required (directly or indirectly) by an executable must be listed again. @@ -900,24 +907,28 @@ look something like this: name: foo version: 0.1.0.0 license: BSD3 + license-file: LICENSE build-type: Simple library foo-internal - exposed-modules: Foo.Internal + exposed-modules: Foo.Internal -- NOTE: no explicit constraints on base needed -- as they're inherited from the 'library' stanza - build-depends: base + build-depends: base + default-language: Haskell2010 library - exposed-modules: Foo.Public - build-depends: foo-internal, base >= 4.3 && < 5 + exposed-modules: Foo.Public + build-depends: foo-internal, base >= 4.3 && < 5 + default-language: Haskell2010 test-suite test-foo - type: exitcode-stdio-1.0 - main-is: test-foo.hs + 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 - build-depends: foo-internal, base + build-depends: foo-internal, base + default-language: Haskell2010 Internal libraries are also useful for packages that define multiple executables, but do not define a publicly accessible library. Internal @@ -935,9 +946,10 @@ a real-world use case: :: - cabal-version: 2.2 + cabal-version: 3.0 name: haddock-library version: 1.6.0 + license: BSD-3-Clause library build-depends: @@ -954,6 +966,8 @@ a real-world use case: exposed-modules: Documentation.Haddock + default-language: Haskell2010 + library attoparsec build-depends: , base ^>= 4.11.1.0 @@ -973,6 +987,8 @@ a real-world use case: ghc-options: -funbox-strict-fields -Wall -fwarn-tabs -O2 + default-language: Haskell2010 + Opening an interpreter session ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1245,24 +1261,6 @@ the :pkg-field:`test-module` field. The module exporting the ``tests`` symbol. -.. pkg-field:: code-generators - - An optional list of preprocessors which can generate new modules - for use in the test-suite. - - A list of executabes (possibly brought into scope by :pkg-field:`build-tool-depends`) that are run after all other - preprocessors. These executables are invoked as so: ``exe-name - TARGETDIR [SOURCEDIRS] -- [GHCOPTIONS]``. The arguments are, in order a target dir for - output, a sequence of all source directories with source files of - local lib components that the given test stanza dependens on, and - following a double dash, all options cabal would pass to ghc for a - build. They are expected to output a newline-seperated list of - generated modules which have been written to the targetdir - (excepting, if written, the main module). This can - be used for driving doctests and other discover-style tests generated - from source code. - - Example: Package using ``exitcode-stdio-1.0`` interface """"""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -1272,16 +1270,17 @@ demonstrate the use of the ``exitcode-stdio-1.0`` interface. .. code-block:: cabal :caption: foo.cabal + Cabal-Version: 3.0 Name: foo Version: 1.0 - License: BSD3 - Cabal-Version: >= 1.9.2 + License: BSD-3-Clause Build-Type: Simple Test-Suite test-foo - type: exitcode-stdio-1.0 - main-is: test-foo.hs - build-depends: base >= 4 && < 5 + type: exitcode-stdio-1.0 + main-is: test-foo.hs + build-depends: base >= 4 && < 5 + default-language: Haskell2010 .. code-block:: haskell :caption: test-foo.hs @@ -1306,16 +1305,17 @@ be provided by the library that provides the testing facility. .. code-block:: cabal :caption: bar.cabal + Cabal-Version: 3.0 Name: bar Version: 1.0 - License: BSD3 - Cabal-Version: >= 1.9.2 + License: BSD-3-Clause Build-Type: Simple Test-Suite test-bar - type: detailed-0.9 - test-module: Bar - build-depends: base >= 4 && < 5, Cabal >= 1.9.2 && < 2 + type: detailed-0.9 + test-module: Bar + build-depends: base >= 4 && < 5, Cabal >= 1.9.2 && < 2 + default-language: Haskell2010 .. code-block:: haskell @@ -1407,16 +1407,17 @@ demonstrate the use of the ``exitcode-stdio-1.0`` interface. :caption: foo.cabal :name: foo-bench.cabal + Cabal-Version: 3.0 Name: foo Version: 1.0 - License: BSD3 - Cabal-Version: >= 1.9.2 + License: BSD-3-Clause 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 + type: exitcode-stdio-1.0 + main-is: bench-foo.hs + build-depends: base >= 4 && < 5, time >= 1.1 && < 1.7 + default-language: Haskell2010 .. code-block:: haskell :caption: bench-foo.hs @@ -2385,10 +2386,10 @@ Example: A package containing a library and executable programs :: + Cabal-Version: 3.0 Name: Test1 Version: 0.0.1 - Cabal-Version: >= 1.8 - License: BSD3 + License: BSD-3-Clause Author: Jane Doe Synopsis: Test package to test configurations Category: Example @@ -2410,9 +2411,10 @@ Example: A package containing a library and executable programs -- assign automatically while searching for a solution Library - Build-Depends: base >= 4.2 && < 4.9 - Exposed-Modules: Testing.Test1 - Extensions: CPP + Build-Depends: base >= 4.2 && < 4.9 + Exposed-Modules: Testing.Test1 + Default-Extensions: CPP + Default-Language: Haskell2010 GHC-Options: -Wall if flag(Debug) @@ -2435,9 +2437,10 @@ Example: A package containing a library and executable programs Build-Depends: old-time >= 1.0 && < 1.2 Executable test1 - Main-is: T1.hs - Other-Modules: Testing.Test1 - Build-Depends: base >= 4.2 && < 4.9 + Main-is: T1.hs + Other-Modules: Testing.Test1 + Build-Depends: base >= 4.2 && < 4.9 + Default-Language: Haskell2010 if flag(debug) CC-Options: "-DDEBUG" @@ -2462,10 +2465,10 @@ Example: Using explicit braces rather than indentation for layout :: + Cabal-Version: 3.0 Name: Test1 Version: 0.0.1 - Cabal-Version: >= 1.8 - License: BSD3 + License: BSD-3-Clause Author: Jane Doe Synopsis: Test package to test configurations Category: Example @@ -2478,9 +2481,10 @@ Example: Using explicit braces rather than indentation for layout } Library { - Build-Depends: base >= 4.2 && < 4.9 - Exposed-Modules: Testing.Test1 - Extensions: CPP + Build-Depends: base >= 4.2 && < 4.9 + Exposed-Modules: Testing.Test1 + Default-Extensions: CPP + Default-language: Haskell2010 if flag(debug) { CPP-Options: -DDEBUG if !os(windows) { @@ -2737,14 +2741,16 @@ Starting with Cabal-2.2 it's possible to use common build info stanzas. build-depends: tasty ^>= 0.12.0.1 library - import: deps - exposed-modules: Foo + import: deps + exposed-modules: Foo + default-language: Haskell2010 test-suite tests - import: deps, test-deps - type: exitcode-stdio-1.0 - main-is: Tests.hs - build-depends: foo + import: deps, test-deps + type: exitcode-stdio-1.0 + main-is: Tests.hs + build-depends: foo + default-language: Haskell2010 - You can use `build information`_ fields in common stanzas. From 28d85cd9be7a3526a460771ccbedf1b03a8ce3ef Mon Sep 17 00:00:00 2001 From: Don Stewart Date: Tue, 1 Mar 2022 05:31:44 +0000 Subject: [PATCH 13/17] Flatten duplicate warnings about experimental features For some projects (e.g. glean) that make wide use of colon specifiers or visibility, we get hundreds (thousands) of duplicating warnings about these language features, spamming our builds. Flatten this warning into a single instance per parse, and a count of others. Example: ``` Warning: glean.cabal:1674:15: colon specifier is experimental feature (issue Warning: glean.cabal:1625:24: visibility is experimental feature (issue #5660) (and 32 more occurrences) ``` With -v1 (or below), flattening occurs. At -v2 or above, all instances are shown. Test plan: - try on glean.cabal from https://github.com/facebookincubator/Glean and see it working as above - cabal test all --- .../Distribution/Simple/PackageDescription.hs | 41 ++++++++++++++++--- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/Cabal/src/Distribution/Simple/PackageDescription.hs b/Cabal/src/Distribution/Simple/PackageDescription.hs index 4c64aedf767..bb7e54550c3 100644 --- a/Cabal/src/Distribution/Simple/PackageDescription.hs +++ b/Cabal/src/Distribution/Simple/PackageDescription.hs @@ -24,12 +24,16 @@ import Distribution.Compat.Prelude import Distribution.Fields.ParseResult import Distribution.PackageDescription import Distribution.PackageDescription.Parsec -import Distribution.Parsec.Error (showPError) -import Distribution.Parsec.Warning (showPWarning) -import Distribution.Simple.Utils -import Distribution.Verbosity + ( parseGenericPackageDescription, parseHookedBuildInfo ) +import Distribution.Parsec.Error ( showPError ) +import Distribution.Parsec.Warning + ( PWarning(..), PWarnType(PWTExperimental), showPWarning ) +import Distribution.Simple.Utils ( equating, die', warn ) +import Distribution.Verbosity ( normal, Verbosity ) -import qualified Data.ByteString as BS +import Data.List ( groupBy ) +import Text.Printf ( printf ) +import qualified Data.ByteString as BS import System.Directory (doesFileExist) readGenericPackageDescription :: Verbosity -> FilePath -> IO GenericPackageDescription @@ -65,10 +69,35 @@ parseString -> IO a parseString parser verbosity name bs = do let (warnings, result) = runParseResult (parser bs) - traverse_ (warn verbosity . showPWarning name) warnings + traverse_ (warn verbosity . showPWarning name) (flattenDups verbosity warnings) case result of Right x -> return x Left (_, errors) -> do traverse_ (warn verbosity . showPError name) errors die' verbosity $ "Failed parsing \"" ++ name ++ "\"." +-- Collapse duplicate experimental feature warnings into single warning, with +-- a count of further sites +flattenDups :: Verbosity -> [PWarning] -> [PWarning] +flattenDups verbosity ws + | verbosity <= normal = rest ++ experimentals + | otherwise = ws -- show all instances + where + (exps, rest) = partition (\(PWarning w _ _) -> w == PWTExperimental) ws + experimentals = + concatMap flatCount + . groupBy (equating warningStr) + . sortBy (comparing warningStr) + $ exps + + warningStr (PWarning _ _ w) = w + + -- flatten if we have 3 or more examples + flatCount :: [PWarning] -> [PWarning] + flatCount w@[] = w + flatCount w@[_] = w + flatCount w@[_,_] = w + flatCount (PWarning t pos w:xs) = + [PWarning t pos + (w <> printf " (and %d more occurrences)" (length xs)) + ] \ No newline at end of file From 8bb18a052fa16714cb3ce4dda999afa14daa50a7 Mon Sep 17 00:00:00 2001 From: Don Stewart Date: Thu, 3 Mar 2022 02:08:09 +0000 Subject: [PATCH 14/17] Add mini changelog and regression test Since the warning summarizer runs _after_ parsing, we need to check the warn output as a regression test, not a unit test. test plan: cabal-tests PackageTests/DuplicateExperimental/setup.test.hs --with-cabal `which cabal` ; echo $? --- .../DuplicateExperimental/Four.hs | 1 + .../DuplicateExperimental/Main.hs | 6 ++++ .../PackageTests/DuplicateExperimental/One.hs | 1 + .../DuplicateExperimental/Three.hs | 1 + .../PackageTests/DuplicateExperimental/Two.hs | 1 + .../DuplicateExperimental/cabal.project | 2 ++ .../DuplicateExperimental/duplicate.cabal | 35 +++++++++++++++++++ .../DuplicateExperimental/setup.out | 2 ++ .../DuplicateExperimental/setup.test.hs | 9 +++++ changelog.d/pr-8023 | 11 ++++++ 10 files changed, 69 insertions(+) create mode 100644 cabal-testsuite/PackageTests/DuplicateExperimental/Four.hs create mode 100644 cabal-testsuite/PackageTests/DuplicateExperimental/Main.hs create mode 100644 cabal-testsuite/PackageTests/DuplicateExperimental/One.hs create mode 100644 cabal-testsuite/PackageTests/DuplicateExperimental/Three.hs create mode 100644 cabal-testsuite/PackageTests/DuplicateExperimental/Two.hs create mode 100644 cabal-testsuite/PackageTests/DuplicateExperimental/cabal.project create mode 100644 cabal-testsuite/PackageTests/DuplicateExperimental/duplicate.cabal create mode 100644 cabal-testsuite/PackageTests/DuplicateExperimental/setup.out create mode 100644 cabal-testsuite/PackageTests/DuplicateExperimental/setup.test.hs create mode 100644 changelog.d/pr-8023 diff --git a/cabal-testsuite/PackageTests/DuplicateExperimental/Four.hs b/cabal-testsuite/PackageTests/DuplicateExperimental/Four.hs new file mode 100644 index 00000000000..eae11859189 --- /dev/null +++ b/cabal-testsuite/PackageTests/DuplicateExperimental/Four.hs @@ -0,0 +1 @@ +module Four where diff --git a/cabal-testsuite/PackageTests/DuplicateExperimental/Main.hs b/cabal-testsuite/PackageTests/DuplicateExperimental/Main.hs new file mode 100644 index 00000000000..75684e917e3 --- /dev/null +++ b/cabal-testsuite/PackageTests/DuplicateExperimental/Main.hs @@ -0,0 +1,6 @@ +module Main where + +import One +import Two +import Three +import Four diff --git a/cabal-testsuite/PackageTests/DuplicateExperimental/One.hs b/cabal-testsuite/PackageTests/DuplicateExperimental/One.hs new file mode 100644 index 00000000000..db76b316e19 --- /dev/null +++ b/cabal-testsuite/PackageTests/DuplicateExperimental/One.hs @@ -0,0 +1 @@ +module One where diff --git a/cabal-testsuite/PackageTests/DuplicateExperimental/Three.hs b/cabal-testsuite/PackageTests/DuplicateExperimental/Three.hs new file mode 100644 index 00000000000..efaea8d41a8 --- /dev/null +++ b/cabal-testsuite/PackageTests/DuplicateExperimental/Three.hs @@ -0,0 +1 @@ +module Three where diff --git a/cabal-testsuite/PackageTests/DuplicateExperimental/Two.hs b/cabal-testsuite/PackageTests/DuplicateExperimental/Two.hs new file mode 100644 index 00000000000..4738ff7fc49 --- /dev/null +++ b/cabal-testsuite/PackageTests/DuplicateExperimental/Two.hs @@ -0,0 +1 @@ +module Two where diff --git a/cabal-testsuite/PackageTests/DuplicateExperimental/cabal.project b/cabal-testsuite/PackageTests/DuplicateExperimental/cabal.project new file mode 100644 index 00000000000..8834d04402a --- /dev/null +++ b/cabal-testsuite/PackageTests/DuplicateExperimental/cabal.project @@ -0,0 +1,2 @@ +packages: + ./ diff --git a/cabal-testsuite/PackageTests/DuplicateExperimental/duplicate.cabal b/cabal-testsuite/PackageTests/DuplicateExperimental/duplicate.cabal new file mode 100644 index 00000000000..1b00acbf04b --- /dev/null +++ b/cabal-testsuite/PackageTests/DuplicateExperimental/duplicate.cabal @@ -0,0 +1,35 @@ +cabal-version: 3.0 +name: duplicate +version: 0 +synopsis: Test of de-duping multiple warnings for experimental features +category: Tests +license: MIT + +library + build-depends: base, one, two, three, four + exposed-modules: Main + default-language: Haskell2010 + +library one + visibility: public + exposed-modules: One + build-depends: base + default-language: Haskell2010 + +library two + visibility: public + exposed-modules: Two + build-depends: base + default-language: Haskell2010 + +library three + visibility: public + exposed-modules: Three + build-depends: base + default-language: Haskell2010 + +library four + visibility: public + exposed-modules: Four + build-depends: base + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/DuplicateExperimental/setup.out b/cabal-testsuite/PackageTests/DuplicateExperimental/setup.out new file mode 100644 index 00000000000..65f17dd1e53 --- /dev/null +++ b/cabal-testsuite/PackageTests/DuplicateExperimental/setup.out @@ -0,0 +1,2 @@ +# cabal build +# cabal build diff --git a/cabal-testsuite/PackageTests/DuplicateExperimental/setup.test.hs b/cabal-testsuite/PackageTests/DuplicateExperimental/setup.test.hs new file mode 100644 index 00000000000..3074e5ac50a --- /dev/null +++ b/cabal-testsuite/PackageTests/DuplicateExperimental/setup.test.hs @@ -0,0 +1,9 @@ +import Test.Cabal.Prelude +main = cabalTest $ do + -- check output is summarized in -v1 (-v normal) + res <- cabal' "build" ["--only-configure","duplicate","-vnormal"] + assertOutputContains "(and 3 more occurrences)" res + + -- check output is _not_ summarized in -v2 (verbose) + res <- cabal' "build" ["--only-configure","duplicate","-vverbose"] + assertOutputDoesNotContain "(and 3 more occurrences)" res diff --git a/changelog.d/pr-8023 b/changelog.d/pr-8023 new file mode 100644 index 00000000000..b19f81ae1df --- /dev/null +++ b/changelog.d/pr-8023 @@ -0,0 +1,11 @@ +synopsis: Flatten duplicate warnings about experimental features +packages: Cabal +prs: #8023 +issues: +description: { + +- Make builds that use experimental Cabal language features less noisy. At -v1 + (normal) we show just first instance of use of experimental cabal language +features, along with count of further occurences in the same file. + +} From b213816cef30b48327ea6a59d97a70791ef349d5 Mon Sep 17 00:00:00 2001 From: Don Stewart Date: Thu, 3 Mar 2022 22:51:30 +0000 Subject: [PATCH 15/17] Small nits --- Cabal/src/Distribution/Simple/PackageDescription.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cabal/src/Distribution/Simple/PackageDescription.hs b/Cabal/src/Distribution/Simple/PackageDescription.hs index bb7e54550c3..6bf11413930 100644 --- a/Cabal/src/Distribution/Simple/PackageDescription.hs +++ b/Cabal/src/Distribution/Simple/PackageDescription.hs @@ -76,7 +76,7 @@ parseString parser verbosity name bs = do traverse_ (warn verbosity . showPError name) errors die' verbosity $ "Failed parsing \"" ++ name ++ "\"." --- Collapse duplicate experimental feature warnings into single warning, with +-- | Collapse duplicate experimental feature warnings into single warning, with -- a count of further sites flattenDups :: Verbosity -> [PWarning] -> [PWarning] flattenDups verbosity ws @@ -100,4 +100,4 @@ flattenDups verbosity ws flatCount (PWarning t pos w:xs) = [PWarning t pos (w <> printf " (and %d more occurrences)" (length xs)) - ] \ No newline at end of file + ] From fbeb0a1894adf05bb11ce6f57b3405e9b046c8c1 Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Mon, 28 Feb 2022 19:50:44 +0100 Subject: [PATCH 16/17] Mark several failing test cases as "expected broken" Failures are tracked in issues https://github.com/haskell/cabal/issues/7610 https://github.com/haskell/cabal/issues/7987 https://github.com/haskell/cabal/issues/7989 https://github.com/haskell/cabal/issues/8028 https://github.com/haskell/cabal/issues/8032 --- .../PackageTests/Backpack/Includes2/setup-external.test.hs | 4 +++- .../Backpack/Includes2/setup-per-component.test.hs | 6 ++++-- .../Backpack/Includes3/setup-external-ok.test.hs | 4 +++- cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs | 7 +++++-- cabal-testsuite/PackageTests/NewBuild/T3827/cabal.test.hs | 4 ++++ .../PackageTests/Regression/T4025/setup.test.hs | 5 ++++- .../PackageTests/Regression/T4270/setup.test.hs | 7 +++++-- 7 files changed, 28 insertions(+), 9 deletions(-) diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.test.hs index 33f813a5eef..217aa2340d7 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.test.hs @@ -1,6 +1,8 @@ import Test.Cabal.Prelude main = setupAndCabalTest $ do - skipUnlessGhcVersion ">= 8.1" + skipUnlessGhcVersion ">= 8.1" + ghc <- isGhcVersion "== 9.0.2 || == 9.2.1" + expectBrokenIf ghc 7987 $ do withPackageDb $ do withDirectory "mylib" $ setup_install_with_docs ["--ipid", "mylib-0.1.0.0"] withDirectory "mysql" $ setup_install_with_docs ["--ipid", "mysql-0.1.0.0"] diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs index cfb08f33ed1..a3809d70fc0 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs @@ -1,7 +1,9 @@ import Test.Cabal.Prelude main = setupTest $ do - -- No cabal test because per-component is broken with it - skipUnlessGhcVersion ">= 8.1" + -- No cabal test because per-component is broken with it + skipUnlessGhcVersion ">= 8.1" + ghc <- isGhcVersion "== 9.0.2 || == 9.2.1" + expectBrokenIf ghc 7987 $ withPackageDb $ do let setup_install' args = setup_install_with_docs (["--cabal-file", "Includes2.cabal"] ++ args) setup_install' ["mylib", "--cid", "mylib-0.1.0.0"] diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.test.hs index 82cb49643a3..8760bb6b35a 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.test.hs @@ -2,7 +2,9 @@ import Test.Cabal.Prelude import Data.List import qualified Data.Char as Char main = setupAndCabalTest $ do - skipUnlessGhcVersion ">= 8.1" + skipUnlessGhcVersion ">= 8.1" + ghc <- isGhcVersion "== 9.0.2 || == 9.2.1" + expectBrokenIf ghc 7987 $ withPackageDb $ do containers_id <- getIPID "containers" withDirectory "repo/sigs-0.1.0.0" $ setup_install_with_docs ["--ipid", "sigs-0.1.0.0"] diff --git a/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs b/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs index 7b7bae851bf..108219f29f2 100644 --- a/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs +++ b/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs @@ -24,8 +24,11 @@ import Test.Cabal.Prelude -- Recording is turned off because versionedlib will or will not -- be installed depending on if we're on Linux or not. main = setupAndCabalTest . recordMode DoNotRecord $ do - -- Foreign libraries don't work with GHC 7.6 and earlier - skipUnlessGhcVersion ">= 7.8" + -- Foreign libraries don't work with GHC 7.6 and earlier + skipUnlessGhcVersion ">= 7.8" + osx <- isOSX + ghc <- isGhcVersion "== 8.0.2" + expectBrokenIf (osx && ghc) 7989 $ withPackageDb $ do setup_install [] setup "copy" [] -- regression test #4156 diff --git a/cabal-testsuite/PackageTests/NewBuild/T3827/cabal.test.hs b/cabal-testsuite/PackageTests/NewBuild/T3827/cabal.test.hs index a591492b2d9..c1287f9bb2a 100644 --- a/cabal-testsuite/PackageTests/NewBuild/T3827/cabal.test.hs +++ b/cabal-testsuite/PackageTests/NewBuild/T3827/cabal.test.hs @@ -1,3 +1,7 @@ import Test.Cabal.Prelude main = cabalTest $ do + missesProfiling <- isGhcVersion ">= 9.2.1" + osx <- isOSX + missesProfilingOsx <- isGhcVersion ">= 8.10.7" + expectBrokenIf (missesProfiling || osx && missesProfilingOsx) 8032 $ cabal "v2-build" ["exe:q"] diff --git a/cabal-testsuite/PackageTests/Regression/T4025/setup.test.hs b/cabal-testsuite/PackageTests/Regression/T4025/setup.test.hs index 9f38351758f..0ec5d068147 100644 --- a/cabal-testsuite/PackageTests/Regression/T4025/setup.test.hs +++ b/cabal-testsuite/PackageTests/Regression/T4025/setup.test.hs @@ -3,7 +3,10 @@ import Test.Cabal.Prelude -- an executable RPATH. Don't test on Windows, which doesn't -- support RPATH. main = setupAndCabalTest $ do - skipIfWindows + skipIfWindows + osx <- isOSX + ghc <- isGhcVersion ">= 8.10.7" + expectBrokenIf (osx && ghc) 7610 $ do -- see also issue #7988 setup "configure" ["--enable-executable-dynamic"] setup "build" [] -- This should fail as it we should NOT be able to find the diff --git a/cabal-testsuite/PackageTests/Regression/T4270/setup.test.hs b/cabal-testsuite/PackageTests/Regression/T4270/setup.test.hs index a62eef8bfd5..cf3d7afbdfb 100644 --- a/cabal-testsuite/PackageTests/Regression/T4270/setup.test.hs +++ b/cabal-testsuite/PackageTests/Regression/T4270/setup.test.hs @@ -6,5 +6,8 @@ main = setupAndCabalTest $ do skipUnless "no shared libs" =<< hasSharedLibraries skipUnless "no shared Cabal" =<< hasCabalShared skipUnless "no Cabal for GHC" =<< hasCabalForGhc - setup_build ["--enable-tests", "--enable-executable-dynamic"] - setup "test" [] + ghc <- isGhcVersion "== 8.0.2" + osx <- isOSX + expectBrokenIf (osx && ghc) 8028 $ do + setup_build ["--enable-tests", "--enable-executable-dynamic"] + setup "test" [] From 8c09118f4c1585f4fa07d9c244ef363b8d4c409f Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Thu, 3 Mar 2022 23:36:37 +0100 Subject: [PATCH 17/17] Raise heap size of memory tests from 8M to 16M (fixes #8029) There appears to be a small regression in heap usage with GHC 9.2.1. This raises the limit to accommodate that, and give a bit of a buffer. Compare analysis at https://github.com/haskell/cabal/issues/8029. --- cabal-install/cabal-install.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cabal-install/cabal-install.cabal b/cabal-install/cabal-install.cabal index 9f68b0137b1..216588ade87 100644 --- a/cabal-install/cabal-install.cabal +++ b/cabal-install/cabal-install.cabal @@ -339,7 +339,7 @@ Test-Suite memory-usage-tests hs-source-dirs: tests default-language: Haskell2010 - ghc-options: -threaded -rtsopts "-with-rtsopts=-M8M -K1K" + ghc-options: -threaded -rtsopts "-with-rtsopts=-M16M -K1K" other-modules: UnitTests.Distribution.Solver.Modular.DSL