diff --git a/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs b/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs index 2976d34b557..e5b5077d414 100644 --- a/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs +++ b/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs @@ -3,7 +3,9 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} module Test.QuickCheck.Instances.Cabal () where +#if !MIN_VERSION_base(4,18,0) import Control.Applicative (liftA2) +#endif import Data.Bits (shiftR) import Data.Char (isAlphaNum, isDigit, toLower) import Data.List (intercalate, (\\)) diff --git a/Cabal-tests/tests/CheckTests.hs b/Cabal-tests/tests/CheckTests.hs index 220cc7d1458..aa2f1e9b041 100644 --- a/Cabal-tests/tests/CheckTests.hs +++ b/Cabal-tests/tests/CheckTests.hs @@ -3,7 +3,6 @@ module Main ) where import Test.Tasty -import Test.Tasty.ExpectedFailure import Test.Tasty.Golden.Advanced (goldenTest) import Data.Algorithm.Diff (PolyDiff (..), getGroupedDiff) diff --git a/Cabal-tests/tests/UnitTests/Distribution/PackageDescription/Check.hs b/Cabal-tests/tests/UnitTests/Distribution/PackageDescription/Check.hs index 2665b49a6de..58f75602644 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/PackageDescription/Check.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/PackageDescription/Check.hs @@ -1,3 +1,6 @@ +-- For the deprecated import of Distribution.Compat.Prelude.Internal +{-# OPTIONS_GHC -Wwarn=deprecations #-} + module UnitTests.Distribution.PackageDescription.Check (tests) where import Distribution.Compat.Prelude.Internal diff --git a/Makefile b/Makefile index 7adb96d3bc5..18c92c30a6f 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,13 @@ CABALBUILD := cabal build CABALRUN := cabal run -DOCTEST := cabal repl --with-ghc=doctest --repl-options="-w" --project-file=cabal.project.doctest + +# The newer and prefered way to call the doctest tool is: +# $ cabal repl --with-ghc=doctest +# SEE: https://github.com/haskell/cabal/issues/8504 +# There is but one caveat, we have to avoid allow-newer. +# SEE: https://github.com/haskell/cabal/issues/6859 +DOCTEST := cabal repl --with-ghc=doctest --repl-options="-w" --ghc-options="-Wwarn" --allow-newer=False # default rules @@ -65,8 +71,8 @@ doc/buildinfo-fields-reference.rst : \ $(wildcard Cabal-described/src/Distribution/Described.hs Cabal-described/src/Distribution/Utils/*.hs) \ buildinfo-reference-generator/src/Main.hs \ buildinfo-reference-generator/template.zinza - cabal build --project-file=cabal.project.buildinfo buildinfo-reference-generator - cabal run --project-file=cabal.project.buildinfo buildinfo-reference-generator buildinfo-reference-generator/template.zinza | tee $@ + cabal build buildinfo-reference-generator + cabal run buildinfo-reference-generator buildinfo-reference-generator/template.zinza | tee $@ git diff --exit-code $@ # analyse-imports @@ -81,15 +87,6 @@ ghcid-lib : ghcid-cli : ghcid -c 'cabal repl cabal-install' -# Artem, 2023-02-03, https://github.com/haskell/cabal/issues/8504 -# The new and prefered way to call the doctest tool (as of now) is based on cabal repl --with-ghc=doctest. -# The call below reflects the current documentation of the doctest tool except one caveat, -# which is https://github.com/haskell/cabal/issues/6859, i.e. we have to hide allow-newer in our project -# file from cabal/doctest. This is easy: we just select a project file with no allow-newer (e.g. cabal.project.libonly). -# -# TODO: Cabal-described should be added here but its doctests currently broken, see: -# https://github.com/haskell/cabal/issues/8734 -# Just as well, cabal-install(-solver) doctests (the target below) bitrotted and need some care. doctest : $(DOCTEST) Cabal-syntax $(DOCTEST) Cabal-described @@ -185,11 +182,6 @@ validate-via-docker-8.10.4: validate-via-docker-old: docker build $(DOCKERARGS) -t cabal-validate:older -f .docker/validate-old.dockerfile . -# Weeder -weeder : - cabal build all --project-file=cabal.project.weeder - weeder | less - # tags .PHONY : tags tags : diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Configure.hs b/cabal-install/tests/UnitTests/Distribution/Client/Configure.hs index c570d7a738a..52a23a80ef2 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Configure.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Configure.hs @@ -23,13 +23,22 @@ tests = [ configureTests ] +defaultTestFlags :: NixStyleFlags () +defaultTestFlags = + (defaultNixStyleFlags ()) + { projectFlags = + mempty + { flagProjectDir = Flag projectDir + } + } + configureTests :: TestTree configureTests = testGroup "Configure tests" [ testCase "New config" $ do let flags = - (defaultNixStyleFlags ()) + defaultTestFlags { configFlags = mempty { configOptimization = Flag MaximumOptimisation @@ -42,7 +51,7 @@ configureTests = @=? (packageConfigOptimization . projectConfigLocalPackages $ snd projConfig) , testCase "Replacement + new config" $ do let flags = - (defaultNixStyleFlags ()) + defaultTestFlags { configExFlags = mempty { configAppend = Flag True @@ -52,10 +61,6 @@ configureTests = { configOptimization = Flag NoOptimisation , configVerbosity = Flag silent } - , projectFlags = - mempty - { flagProjectDir = Flag projectDir - } } (_, ProjectConfig{..}) <- configureAction' flags [] defaultGlobalFlags @@ -63,7 +68,7 @@ configureTests = Flag silent @=? projectConfigVerbosity projectConfigBuildOnly , testCase "Old + new config" $ do let flags = - (defaultNixStyleFlags ()) + defaultTestFlags { configExFlags = mempty { configAppend = Flag True @@ -72,10 +77,6 @@ configureTests = mempty { configVerbosity = Flag silent } - , projectFlags = - mempty - { flagProjectDir = Flag projectDir - } } (_, ProjectConfig{..}) <- configureAction' flags [] defaultGlobalFlags @@ -83,15 +84,11 @@ configureTests = Flag silent @=? projectConfigVerbosity projectConfigBuildOnly , testCase "Old + new config, no appending" $ do let flags = - (defaultNixStyleFlags ()) + defaultTestFlags { configFlags = mempty { configVerbosity = Flag silent } - , projectFlags = - mempty - { flagProjectDir = Flag projectDir - } } (_, ProjectConfig{..}) <- configureAction' flags [] defaultGlobalFlags @@ -99,15 +96,11 @@ configureTests = Flag silent @=? projectConfigVerbosity projectConfigBuildOnly , testCase "Old + new config, backup check" $ do let flags = - (defaultNixStyleFlags ()) + defaultTestFlags { configFlags = mempty { configVerbosity = Flag silent } - , projectFlags = - mempty - { flagProjectDir = Flag projectDir - } } backup = projectDir "cabal.project.local~" @@ -122,16 +115,12 @@ configureTests = , testCase "Local program options" $ do let ghcFlags = ["-fno-full-laziness"] flags = - (defaultNixStyleFlags ()) + defaultTestFlags { configFlags = mempty { configVerbosity = Flag silent , configProgramArgs = [("ghc", ghcFlags)] } - , projectFlags = - mempty - { flagProjectDir = Flag projectDir - } } (_, ProjectConfig{..}) <- configureAction' flags [] defaultGlobalFlags diff --git a/cabal-testsuite/cabal.project b/cabal-testsuite/cabal.project new file mode 100644 index 00000000000..17b04a2b56f --- /dev/null +++ b/cabal-testsuite/cabal.project @@ -0,0 +1,6 @@ +-- This intercepting project is here to avoid tests picking up a cabal.project +-- from a parent directory, such as the one in the root of the `haskell/cabal` +-- project itself. Having `optional-packages: .` avoids the folowing warning +-- being added to the `.out` file: +-- Warning: There are no packages or optional-packages in the project +optional-packages: . diff --git a/cabal-testsuite/static/Main.hs b/cabal-testsuite/static/Main.hs index de106fe48f9..d82a4bd93b7 100644 --- a/cabal-testsuite/static/Main.hs +++ b/cabal-testsuite/static/Main.hs @@ -1,3 +1,4 @@ module Main where +main :: IO () main = return () diff --git a/cabal.project b/cabal.project index d506fe9b117..e368c280c99 100644 --- a/cabal.project +++ b/cabal.project @@ -1,25 +1,6 @@ -import: cabal.project.latest-ghc - -packages: Cabal/ -packages: cabal-testsuite/ -packages: Cabal-syntax/ -packages: cabal-install/ -packages: cabal-install-solver/ -packages: solver-benchmarks/ +import: project-cabal/ghc-options.config +import: project-cabal/ghc-latest.config +import: project-cabal/pkgs.config +import: project-cabal/constraints.config tests: True - -packages: Cabal-QuickCheck/ -packages: Cabal-tree-diff/ -packages: Cabal-described -packages: Cabal-tests/ -packages: cabal-benchmarks/ - -optional-packages: ./vendored/*/*.cabal - --- avoiding extra dependencies -constraints: rere -rere-cfg -constraints: these -assoc - -program-options - ghc-options: -fno-ignore-asserts diff --git a/cabal.project.buildinfo b/cabal.project.buildinfo deleted file mode 100644 index 839f35c5805..00000000000 --- a/cabal.project.buildinfo +++ /dev/null @@ -1,10 +0,0 @@ -packages: Cabal-syntax/ -packages: Cabal/ -packages: Cabal-described -packages: buildinfo-reference-generator/ -tests: False -optimization: False - --- avoiding extra dependencies -constraints: rere -rere-cfg -constraints: these -assoc diff --git a/cabal.project.doctest b/cabal.project.doctest deleted file mode 100644 index dac9b0d88a9..00000000000 --- a/cabal.project.doctest +++ /dev/null @@ -1,24 +0,0 @@ -packages: Cabal-syntax/ -packages: Cabal/ -packages: cabal-testsuite/ -packages: cabal-install/ -packages: solver-benchmarks/ - -packages: cabal-install-solver/ -packages: Cabal-QuickCheck/ -packages: Cabal-tree-diff -packages: Cabal-described -packages: Cabal-tests -packages: cabal-benchmarks - -tests: True - --- avoiding extra dependencies -constraints: rere -rere-cfg -constraints: these -assoc - -write-ghc-environment-files: never - -program-options - ghc-options: -fno-ignore-asserts - diff --git a/cabal.project.libonly b/cabal.project.libonly deleted file mode 100644 index 59873fd4ad1..00000000000 --- a/cabal.project.libonly +++ /dev/null @@ -1,14 +0,0 @@ -packages: Cabal-syntax/ Cabal/ cabal-testsuite/ - -packages: Cabal-QuickCheck/ -packages: Cabal-tree-diff -packages: Cabal-described -packages: Cabal-tests - -tests: True - --- Uncomment to allow picking up extra local unpacked deps: ---optional-packages: */ - -program-options - ghc-options: -fno-ignore-asserts diff --git a/cabal.project.meta b/cabal.project.meta index 304b2a50e58..99eaaa54359 100644 --- a/cabal.project.meta +++ b/cabal.project.meta @@ -1,2 +1 @@ packages: cabal-dev-scripts -optional-packages: diff --git a/cabal.project.release b/cabal.project.release index 07eb4b50d41..fd4b5c333e0 100644 --- a/cabal.project.release +++ b/cabal.project.release @@ -1,8 +1,5 @@ -packages: Cabal-syntax/ -packages: Cabal/ -packages: cabal-install-solver/ -packages: cabal-install/ -tests: False -benchmarks: False -optimization: True -index-state: hackage.haskell.org 2024-03-20T08:02:24Z +import: project-cabal/pkgs/cabal.config +import: project-cabal/pkgs/install.config +import: project-cabal/pkgs/tests.config + +index-state: hackage.haskell.org 2024-02-13T10:16:13Z diff --git a/cabal.project.validate b/cabal.project.validate index d3583c31b0e..aae9375fb34 100644 --- a/cabal.project.validate +++ b/cabal.project.validate @@ -1,34 +1,7 @@ -import: cabal.project.latest-ghc - -packages: Cabal-syntax/ -packages: Cabal/ -packages: cabal-testsuite/ -packages: cabal-install/ -packages: solver-benchmarks/ - -packages: cabal-install-solver/ -packages: Cabal-QuickCheck/ -packages: Cabal-tree-diff -packages: Cabal-described -packages: Cabal-tests -packages: cabal-benchmarks +import: project-cabal/ghc-options.config +import: project-cabal/ghc-latest.config +import: project-cabal/pkgs.config +import: project-cabal/constraints.config tests: True - --- avoiding extra dependencies -constraints: rere -rere-cfg -constraints: these -assoc - write-ghc-environment-files: never - -program-options - ghc-options: -fno-ignore-asserts - -package Cabal-syntax - ghc-options: -Werror -package Cabal - ghc-options: -Werror -package cabal-testsuite - ghc-options: -Werror -package cabal-install - ghc-options: -Werror diff --git a/cabal.project.validate.libonly b/cabal.project.validate.libonly index 3baafa1661a..7c5bd38ab6b 100644 --- a/cabal.project.validate.libonly +++ b/cabal.project.validate.libonly @@ -1,28 +1,8 @@ -packages: Cabal-syntax/ -packages: Cabal/ -packages: cabal-testsuite/ -packages: Cabal-QuickCheck/ -packages: Cabal-tree-diff -packages: Cabal-described -packages: Cabal-tests +import: project-cabal/ghc-options.config +import: project-cabal/pkgs/cabal.config +import: project-cabal/pkgs/tests.config +import: project-cabal/pkgs/integration-tests.config +import: project-cabal/constraints.config tests: True - write-ghc-environment-files: never - --- avoiding extra dependencies -constraints: rere -rere-cfg -constraints: these -assoc - -program-options - ghc-options: -fno-ignore-asserts - -package Cabal-syntax - ghc-options: -Werror -package Cabal - ghc-options: -Werror -package cabal-testsuite - ghc-options: -Werror - --- https://github.com/haskell-hvr/cryptohash-sha256/issues/12 -allow-newer: cryptohash-sha256:base diff --git a/cabal.project.weeder b/cabal.project.weeder deleted file mode 100644 index 5fa8357bd6a..00000000000 --- a/cabal.project.weeder +++ /dev/null @@ -1,15 +0,0 @@ --- project file for weeder. Only Cabal and cabal install --- install weeder with --- --- cabal install -w ghc-8.8.3 weeder --- - -packages: Cabal-syntax/ -packages: Cabal/ -packages: cabal-install/ -tests: False - -with-compiler: ghc-8.8.3 - -package * - ghc-options: -fwrite-ide-info diff --git a/project-cabal/README.md b/project-cabal/README.md new file mode 100644 index 00000000000..03f3dbdaf02 --- /dev/null +++ b/project-cabal/README.md @@ -0,0 +1,102 @@ +# Cabal Projects + +We have these projects, all in the root: + +``` +$ tree -P 'cabal.project*' --prune -L 1 +. +├── cabal.project +├── cabal.project.libonly +├── cabal.project.meta +├── cabal.project.release +├── cabal.project.validate +└── cabal.project.validate.libonly +``` + +Projects are expected to pass a `build --dry-run` standalone test, +substituting the actual project filename for `cabal.project` in +`--project-file=cabal.project`: + +``` +$ cabal build all --enable-tests --enable-benchmarks --dry-run \ + --project-file=cabal.project +``` + +The `release` project might fail to resolve dependencies with the latest GHC +compiler with its `index-state` pinned but it should build if unpinned, by +removing `index-state` from the project or setting it to `HEAD`: + +``` +$ cabal build all --enable-tests --enable-benchmarks \ + --project-file=cabal.project.release \ + --index-state="hackage.haskell.org HEAD" +``` + +## Configuration + +Any project configuration that is not itself a project should use a `.config` +extension and be put into the `project-cabal` folder: + +``` +$ tree -P '*.config' project-cabal +project-cabal +├── constraints.config +├── ghc-latest.config +├── ghc-options.config +├── pkgs +│   ├── benchmarks.config +│   ├── buildinfo.config +│   ├── cabal.config +│   ├── install.config +│   ├── integration-tests.config +│   └── tests.config +└── pkgs.config + +2 directories, 10 files +``` + +## Package Groups + +We have one `project-cabal/pkgs.config` that includes all package groups. + +``` +$ cat project-cabal/pkgs.config +import: pkgs/cabal.config +import: pkgs/install.config +import: pkgs/buildinfo.config +import: pkgs/tests.config +import: pkgs/integration-tests.config +import: pkgs/benchmarks.config +``` + +The default and `validate` projects get their packages this way. The `libonly`, +and `validate.libonly` projects import packages from `cabal` and `tests` package +groups. The `release` project also does this but also imports the `install` +package group. + +| Project | pkgs | cabal | tests | install | +|------------------|:---: |:---: |:---: |:---: | +| default | ✓ | | | | +| libonly | | ✓ | ✓ | | +| release | | ✓ | ✓ | ✓ | +| validate | ✓ | | | | +| validate.libonly | | ✓ | ✓ | | + +The `meta` project is a one-liner: + +``` +$ cat cabal.project.meta +packages: cabal-dev-scripts +``` + +## Extra Config + +Additional configuration is imported: + +| Project | ghc-options | ghc-latest | constraints | +|------------------|:---: |:---: |:---: | +| default | ✓ | ✓ | ✓ | +| libonly | ✓ | | | +| release | | | | +| validate | ✓ | ✓ | ✓ | +| validate.libonly | ✓ | | ✓ | diff --git a/project-cabal/constraints.config b/project-cabal/constraints.config new file mode 100644 index 00000000000..aba937cb9f1 --- /dev/null +++ b/project-cabal/constraints.config @@ -0,0 +1,3 @@ +-- avoiding extra dependencies +constraints: rere -rere-cfg +constraints: these -assoc diff --git a/cabal.project.latest-ghc b/project-cabal/ghc-latest.config similarity index 100% rename from cabal.project.latest-ghc rename to project-cabal/ghc-latest.config diff --git a/project-cabal/ghc-options.config b/project-cabal/ghc-options.config new file mode 100644 index 00000000000..e3ece385c5c --- /dev/null +++ b/project-cabal/ghc-options.config @@ -0,0 +1,2 @@ +program-options + ghc-options: -fno-ignore-asserts -Werror diff --git a/project-cabal/pkgs.config b/project-cabal/pkgs.config new file mode 100644 index 00000000000..5f12a02754a --- /dev/null +++ b/project-cabal/pkgs.config @@ -0,0 +1,6 @@ +import: pkgs/cabal.config +import: pkgs/install.config +import: pkgs/buildinfo.config +import: pkgs/tests.config +import: pkgs/integration-tests.config +import: pkgs/benchmarks.config diff --git a/project-cabal/pkgs/benchmarks.config b/project-cabal/pkgs/benchmarks.config new file mode 100644 index 00000000000..22941678058 --- /dev/null +++ b/project-cabal/pkgs/benchmarks.config @@ -0,0 +1,3 @@ +packages: + cabal-benchmarks + , solver-benchmarks diff --git a/project-cabal/pkgs/buildinfo.config b/project-cabal/pkgs/buildinfo.config new file mode 100644 index 00000000000..aec4e483443 --- /dev/null +++ b/project-cabal/pkgs/buildinfo.config @@ -0,0 +1 @@ +packages: buildinfo-reference-generator diff --git a/project-cabal/pkgs/cabal.config b/project-cabal/pkgs/cabal.config new file mode 100644 index 00000000000..2500cad5ecf --- /dev/null +++ b/project-cabal/pkgs/cabal.config @@ -0,0 +1,4 @@ +packages: + Cabal + , Cabal-described + , Cabal-syntax diff --git a/project-cabal/pkgs/install.config b/project-cabal/pkgs/install.config new file mode 100644 index 00000000000..9010d1f332b --- /dev/null +++ b/project-cabal/pkgs/install.config @@ -0,0 +1,3 @@ +packages: + cabal-install + , cabal-install-solver diff --git a/project-cabal/pkgs/integration-tests.config b/project-cabal/pkgs/integration-tests.config new file mode 100644 index 00000000000..00fc56f4467 --- /dev/null +++ b/project-cabal/pkgs/integration-tests.config @@ -0,0 +1 @@ +packages: cabal-testsuite diff --git a/project-cabal/pkgs/tests.config b/project-cabal/pkgs/tests.config new file mode 100644 index 00000000000..a9cec9c596f --- /dev/null +++ b/project-cabal/pkgs/tests.config @@ -0,0 +1,4 @@ +packages: + Cabal-QuickCheck + , Cabal-tests + , Cabal-tree-diff diff --git a/solver-benchmarks/HackageBenchmark.hs b/solver-benchmarks/HackageBenchmark.hs index d70c25feebc..37996dbfc63 100644 --- a/solver-benchmarks/HackageBenchmark.hs +++ b/solver-benchmarks/HackageBenchmark.hs @@ -1,4 +1,3 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -19,7 +18,6 @@ import Control.Monad (forM, replicateM, unless, when) import qualified Data.ByteString as BS import Data.List (nub, unzip4) import Data.Maybe (isJust, catMaybes) -import Data.Monoid ((<>)) import Data.String (fromString) import Data.Function ((&)) import Data.Time (NominalDiffTime, diffUTCTime, getCurrentTime) @@ -187,7 +185,7 @@ hackageBenchmarkMain = do then do putStrLn $ "Obtaining the package list (using " ++ argCabal1 ++ ") ..." list <- readProcess argCabal1 ["list", "--simple-output"] "" - return $ nub [mkPackageName $ head (words line) | line <- lines list] + return $ nub [mkPackageName n | n : _ <- words <$> lines list] else do putStrLn "Using given package list ..." return argPackages @@ -345,7 +343,8 @@ isExpectedResult Unknown = False -- should be the same. If they aren't the same, we returns Unknown. combineTrialResults :: [CabalResult] -> CabalResult combineTrialResults rs - | allEqual rs = head rs + | r:_ <- rs + , allEqual rs = r | allEqual [r | r <- rs, r /= Timeout] = Timeout | otherwise = Unknown where diff --git a/weeder.dhall b/weeder.dhall deleted file mode 100644 index ff28bf5c995..00000000000 --- a/weeder.dhall +++ /dev/null @@ -1,9 +0,0 @@ -{ roots = - [ "^Main\\.main$" - , "^Hackage\\.Security\\." - , "^Text\\.JSON\\.Canonical\\." - , "Paths_Cabal\\." - , "Paths_cabal_install\\." - ] -, type-class-roots = True -}