diff --git a/cabal-install-solver/src/Distribution/Solver/Types/ProjectConfigPath.hs b/cabal-install-solver/src/Distribution/Solver/Types/ProjectConfigPath.hs index bb1a81bc1b5..84375b0f4de 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/ProjectConfigPath.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/ProjectConfigPath.hs @@ -1,4 +1,5 @@ {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE ViewPatterns #-} module Distribution.Solver.Types.ProjectConfigPath ( @@ -7,10 +8,11 @@ module Distribution.Solver.Types.ProjectConfigPath , projectConfigPathRoot , nullProjectConfigPath , consProjectConfigPath + , unconsProjectConfigPath -- * Messages , docProjectConfigPath - , docProjectConfigPaths + , docProjectConfigFiles , cyclicalImportMsg , docProjectConfigPathFailReason @@ -21,17 +23,19 @@ module Distribution.Solver.Types.ProjectConfigPath ) where import Distribution.Solver.Compat.Prelude hiding (toList, (<>)) +import qualified Distribution.Solver.Compat.Prelude as P ((<>)) import Prelude (sequence) import Data.Coerce (coerce) import Data.List.NonEmpty ((<|)) -import Network.URI (parseURI) +import Network.URI (parseURI, parseAbsoluteURI) import System.Directory import System.FilePath import qualified Data.List.NonEmpty as NE import Distribution.Solver.Modular.Version (VR) import Distribution.Pretty (prettyShow) import Text.PrettyPrint +import Distribution.Simple.Utils (ordNub) -- | Path to a configuration file, either a singleton project root, or a longer -- list representing a path to an import. The path is a non-empty list that we @@ -45,7 +49,41 @@ import Text.PrettyPrint -- List elements are relative to each other but once canonicalized, elements are -- relative to the directory of the project root. newtype ProjectConfigPath = ProjectConfigPath (NonEmpty FilePath) - deriving (Eq, Ord, Show, Generic) + deriving (Eq, Show, Generic) + +-- | Sorts URIs after local file paths and longer file paths after shorter ones +-- as measured by the number of path segments. If still equal, then sorting is +-- lexical. +-- +-- The project itself, a single element root path, compared to any of the +-- configuration paths it imports, should always sort first. Comparing one +-- project root path against another is done lexically. +instance Ord ProjectConfigPath where + compare pa@(ProjectConfigPath (NE.toList -> as)) pb@(ProjectConfigPath (NE.toList -> bs)) = + case (as, bs) of + -- There should only ever be one root project path, only one path + -- with length 1. Comparing it to itself should be EQ. Don't assume + -- this though, do a comparison anyway when both sides have length + -- 1. The root path, the project itself, should always be the first + -- path in a sorted listing. + ([a], [b]) -> compare a b + ([_], _) -> LT + (_, [_]) -> GT + + (a:_, b:_) -> case (parseAbsoluteURI a, parseAbsoluteURI b) of + (Just ua, Just ub) -> compare ua ub P.<> compare aImporters bImporters + (Just _, Nothing) -> GT + (Nothing, Just _) -> LT + (Nothing, Nothing) -> compare (splitPath a) (splitPath b) P.<> compare aImporters bImporters + _ -> + compare (length as) (length bs) + P.<> compare (length aPaths) (length bPaths) + P.<> compare aPaths bPaths + where + aPaths = splitPath <$> as + bPaths = splitPath <$> bs + aImporters = snd $ unconsProjectConfigPath pa + bImporters = snd $ unconsProjectConfigPath pb instance Binary ProjectConfigPath instance Structured ProjectConfigPath @@ -95,15 +133,16 @@ docProjectConfigPath (ProjectConfigPath (p :| ps)) = vcat $ -- , ProjectConfigPath ("project-cabal/pkgs/integration-tests.config" :| ["project-cabal/pkgs.config","cabal.project"]) -- , ProjectConfigPath ("project-cabal/pkgs/tests.config" :| ["project-cabal/pkgs.config","cabal.project"]) -- ] --- return . render $ docProjectConfigPaths ps +-- return . render $ docProjectConfigFiles ps -- :} -- "- cabal.project\n- project-cabal/constraints.config\n- project-cabal/ghc-latest.config\n- project-cabal/ghc-options.config\n- project-cabal/pkgs.config\n- project-cabal/pkgs/benchmarks.config\n- project-cabal/pkgs/buildinfo.config\n- project-cabal/pkgs/cabal.config\n- project-cabal/pkgs/install.config\n- project-cabal/pkgs/integration-tests.config\n- project-cabal/pkgs/tests.config" -docProjectConfigPaths :: [ProjectConfigPath] -> Doc -docProjectConfigPaths ps = vcat - [ text "-" <+> text p | ProjectConfigPath (p :| _) <- ps ] +docProjectConfigFiles :: [ProjectConfigPath] -> Doc +docProjectConfigFiles ps = vcat + [ text "-" <+> text p + | p <- ordNub [ p | ProjectConfigPath (p :| _) <- ps ] + ] --- | A message for a cyclical import, assuming the head of the path is the --- duplicate. +-- | A message for a cyclical import, a "cyclical import of". cyclicalImportMsg :: ProjectConfigPath -> Doc cyclicalImportMsg path@(ProjectConfigPath (duplicate :| _)) = vcat @@ -148,6 +187,10 @@ isTopLevelConfigPath (ProjectConfigPath p) = NE.length p == 1 consProjectConfigPath :: FilePath -> ProjectConfigPath -> ProjectConfigPath consProjectConfigPath p ps = ProjectConfigPath (p <| coerce ps) +-- | Split the path into the importee and the importer path. +unconsProjectConfigPath :: ProjectConfigPath -> (FilePath, Maybe ProjectConfigPath) +unconsProjectConfigPath ps = fmap ProjectConfigPath <$> NE.uncons (coerce ps) + -- | Make paths relative to the directory of the root of the project, not -- relative to the file they were imported from. makeRelativeConfigPath :: FilePath -> ProjectConfigPath -> ProjectConfigPath diff --git a/cabal-install/src/Distribution/Client/ProjectConfig.hs b/cabal-install/src/Distribution/Client/ProjectConfig.hs index eea6b958b70..5f31dc0fab5 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig.hs @@ -951,7 +951,7 @@ renderBadPackageLocations (BadPackageLocations provenance bpls) renderExplicit = "When using configuration from:\n" - ++ render (nest 2 . docProjectConfigPaths $ mapMaybe getExplicit (Set.toList provenance)) + ++ render (nest 2 . docProjectConfigFiles $ mapMaybe getExplicit (Set.toList provenance)) ++ "\nThe following errors occurred:\n" ++ render (nest 2 $ vcat ((text "-" <+>) . text <$> map renderBadPackageLocation bpls)) diff --git a/cabal-testsuite/PackageTests/ConditionalAndImport/cabal.out b/cabal-testsuite/PackageTests/ConditionalAndImport/cabal.out index c2690ee4366..fd408a95505 100644 --- a/cabal-testsuite/PackageTests/ConditionalAndImport/cabal.out +++ b/cabal-testsuite/PackageTests/ConditionalAndImport/cabal.out @@ -67,9 +67,9 @@ cyclical import of cyclical-2-out-out-self-b.config; # checking that cyclical check doesn't false-positive on same file names in different folders; hoping within a folder and then into a subfolder # cabal v2-build Configuration is affected by the following files: +- noncyclical-same-filename-a.project - noncyclical-same-filename-a.config imported by: noncyclical-same-filename-a.project -- noncyclical-same-filename-a.project - same-filename/noncyclical-same-filename-a.config imported by: noncyclical-same-filename-a.config imported by: noncyclical-same-filename-a.project @@ -83,10 +83,10 @@ Building library for my-0.1... # checking that cyclical check doesn't false-positive on same file names in different folders; hoping into a subfolder and then back out again # cabal v2-build Configuration is affected by the following files: +- noncyclical-same-filename-b.project - noncyclical-same-filename-b.config imported by: same-filename/noncyclical-same-filename-b.config imported by: noncyclical-same-filename-b.project -- noncyclical-same-filename-b.project - same-filename/noncyclical-same-filename-b.config imported by: noncyclical-same-filename-b.project Up to date diff --git a/cabal-testsuite/PackageTests/ConditionalAndImport/with-ghc.config b/cabal-testsuite/PackageTests/ConditionalAndImport/with-ghc.config new file mode 100644 index 00000000000..140a00be1b9 --- /dev/null +++ b/cabal-testsuite/PackageTests/ConditionalAndImport/with-ghc.config @@ -0,0 +1,7 @@ +-- WARNING: Override the `with-compiler: ghc-x.y.z` of the stackage import, of +-- https://www.stackage.org/nightly-yyyy-mm-dd/cabal.config. Otherwise tests +-- will fail with: +-- -Error: [Cabal-5490] +-- -Cannot find the program 'ghc'. User-specified path 'ghc-x.y.z' does not +-- refer to an executable and the program is not on the system path. +with-compiler: ghc diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/0.config b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/0.config new file mode 100644 index 00000000000..05195095cb0 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/0.config @@ -0,0 +1,7 @@ +import: cfg/1.config +import: cfg/3.config +import: cfg/5.config +import: cfg/7.config +import: cfg/9.config + +import: with-ghc.config diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/2.config b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/2.config new file mode 100644 index 00000000000..80143e396c8 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/2.config @@ -0,0 +1,2 @@ +import: cfg/3.config +import: https://www.stackage.org/lts-21.25/cabal.config diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/4.config b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/4.config new file mode 100644 index 00000000000..8b84982cc3e --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/4.config @@ -0,0 +1,2 @@ +import: cfg/5.config +import: https://www.stackage.org/lts-21.25/cabal.config diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/6.config b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/6.config new file mode 100644 index 00000000000..43ce76e8766 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/6.config @@ -0,0 +1,2 @@ +import: cfg/7.config +import: https://www.stackage.org/lts-21.25/cabal.config diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/8.config b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/8.config new file mode 100644 index 00000000000..28d0551160f --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/8.config @@ -0,0 +1,2 @@ +import: cfg/9.config +import: https://www.stackage.org/lts-21.25/cabal.config diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cabal.out b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cabal.out new file mode 100644 index 00000000000..437612a2eca --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cabal.out @@ -0,0 +1,3 @@ +# checking "using config from message" with URI imports +# cabal v2-build +# checking that package directories and locations are reported in order diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cabal.test.hs b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cabal.test.hs new file mode 100644 index 00000000000..e354b356d7f --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cabal.test.hs @@ -0,0 +1,42 @@ +import Test.Cabal.Prelude + +main = cabalTest . recordMode RecordMarked $ do + let log = recordHeader . pure + + log "checking \"using config from message\" with URI imports" + out <- fails $ cabal' "v2-build" [ "all", "--dry-run", "--project-file=no-pkgs.project" ] + + -- Use assertRegex when the output is tainted by the temp directory, like + -- this: + -- + -- When using configuration from: + -- - /tmp/cabal-testsuite-282695/cabal.project + -- - /tmp/cabal-testsuite-282695/2.config etc + assertRegex + "Project configuration with URI imports is listed in full" + "When using configuration from:(\n|\r\n) \ + \ .*no-pkgs\\.project(\n|\r\n) \ + \ .*0\\.config(\n|\r\n) \ + \ .*2\\.config(\n|\r\n) \ + \ .*4\\.config(\n|\r\n) \ + \ .*6\\.config(\n|\r\n) \ + \ .*8\\.config(\n|\r\n) \ + \ .*1\\.config(\n|\r\n) \ + \ .*3\\.config(\n|\r\n) \ + \ .*5\\.config(\n|\r\n) \ + \ .*7\\.config(\n|\r\n) \ + \ .*9\\.config(\n|\r\n) \ + \ .*with-ghc\\.config(\n|\r\n) \ + \ .*https://www.stackage.org/lts-21.25/cabal.config(\n|\r\n)" + out + + log "checking that package directories and locations are reported in order" + assertOutputContains + "The following errors occurred: \ + \ - The package directory 'no-pkg-1' does not contain any .cabal file. \ + \ - The package location 'no-pkg-2-dir' does not exist. \ + \ - The package directory 'no-pkg-3' does not contain any .cabal file. \ + \ - The package location 'no-pkg-4-dir' does not exist." + out + + return () diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cfg/1.config b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cfg/1.config new file mode 100644 index 00000000000..126a94da61d --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cfg/1.config @@ -0,0 +1,2 @@ +import: ../2.config +import: https://www.stackage.org/lts-21.25/cabal.config diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cfg/3.config b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cfg/3.config new file mode 100644 index 00000000000..f40b183e472 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cfg/3.config @@ -0,0 +1,2 @@ +import: ../4.config +import: https://www.stackage.org/lts-21.25/cabal.config diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cfg/5.config b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cfg/5.config new file mode 100644 index 00000000000..7f579a54345 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cfg/5.config @@ -0,0 +1,2 @@ +import: ../6.config +import: https://www.stackage.org/lts-21.25/cabal.config diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cfg/7.config b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cfg/7.config new file mode 100644 index 00000000000..7cd98c9c244 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cfg/7.config @@ -0,0 +1,2 @@ +import: ../8.config +import: https://www.stackage.org/lts-21.25/cabal.config diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cfg/9.config b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cfg/9.config new file mode 100644 index 00000000000..44d1cc5e562 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/cfg/9.config @@ -0,0 +1,2 @@ +-- No imports here +import: https://www.stackage.org/lts-21.25/cabal.config diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/no-pkg-1/README.md b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/no-pkg-1/README.md new file mode 100644 index 00000000000..ba73c42531f --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/no-pkg-1/README.md @@ -0,0 +1,2 @@ +There's intentionally no package here but the directory for the package exists +so that the project can find it. diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/no-pkg-3/README.md b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/no-pkg-3/README.md new file mode 100644 index 00000000000..ba73c42531f --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/no-pkg-3/README.md @@ -0,0 +1,2 @@ +There's intentionally no package here but the directory for the package exists +so that the project can find it. diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/no-pkgs.project b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/no-pkgs.project new file mode 100644 index 00000000000..0d723a9e298 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/no-pkgs.project @@ -0,0 +1,7 @@ +packages: + no-pkg-1 + no-pkg-2-dir + no-pkg-3 + no-pkg-4-dir + +import: 0.config diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/with-ghc.config b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/with-ghc.config new file mode 100644 index 00000000000..140a00be1b9 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromComplex/with-ghc.config @@ -0,0 +1,7 @@ +-- WARNING: Override the `with-compiler: ghc-x.y.z` of the stackage import, of +-- https://www.stackage.org/nightly-yyyy-mm-dd/cabal.config. Otherwise tests +-- will fail with: +-- -Error: [Cabal-5490] +-- -Cannot find the program 'ghc'. User-specified path 'ghc-x.y.z' does not +-- refer to an executable and the program is not on the system path. +with-compiler: ghc diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/a-very-extra.config b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/a-very-extra.config new file mode 100644 index 00000000000..c0f8dc3cc73 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/a-very-extra.config @@ -0,0 +1,2 @@ +import: https://www.stackage.org/lts-21.25/cabal.config +import: https://www.stackage.org/lts-21.25/cabal.config diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/an-extra.config b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/an-extra.config new file mode 100644 index 00000000000..c0f8dc3cc73 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/an-extra.config @@ -0,0 +1,2 @@ +import: https://www.stackage.org/lts-21.25/cabal.config +import: https://www.stackage.org/lts-21.25/cabal.config diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/cabal.out b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/cabal.out new file mode 100644 index 00000000000..92fd8204a40 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/cabal.out @@ -0,0 +1 @@ +# cabal v2-build diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/cabal.project b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/cabal.project new file mode 100644 index 00000000000..32308f3491f --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/cabal.project @@ -0,0 +1,9 @@ +packages: no-pkg-dir +import: z-empty.config +import: an-extra.config +import: an-extra.config +import: a-very-extra.config +import: a-very-extra.config +import: https://www.stackage.org/lts-21.25/cabal.config +import: https://www.stackage.org/lts-21.25/cabal.config +import: with-ghc.config diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/cabal.test.hs b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/cabal.test.hs new file mode 100644 index 00000000000..cf37d1621a6 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/cabal.test.hs @@ -0,0 +1,24 @@ +import Test.Cabal.Prelude + +main = cabalTest . recordMode RecordMarked $ do + let log = recordHeader . pure + + out <- fails $ cabal' "v2-build" [ "all", "--dry-run" ] + + -- Use assertRegex when the output is tainted by the temp directory, like + -- this: + -- + -- When using configuration from: + -- - /tmp/cabal-testsuite-282695/cabal.project + assertRegex + "Project configuration is listed in full and deduplicated" + "When using configuration from:(\n|\r\n) \ + \ .*cabal\\.project(\n|\r\n) \ + \ .*a-very-extra\\.config(\n|\r\n) \ + \ .*an-extra\\.config(\n|\r\n) \ + \ .*with-ghc\\.config(\n|\r\n) \ + \ .*z-empty\\.config(\n|\r\n) \ + \ .*https://www.stackage.org/lts-21.25/cabal.config(\n|\r\n)" + out + + return () diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/with-ghc.config b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/with-ghc.config new file mode 100644 index 00000000000..140a00be1b9 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/with-ghc.config @@ -0,0 +1,7 @@ +-- WARNING: Override the `with-compiler: ghc-x.y.z` of the stackage import, of +-- https://www.stackage.org/nightly-yyyy-mm-dd/cabal.config. Otherwise tests +-- will fail with: +-- -Error: [Cabal-5490] +-- -Cannot find the program 'ghc'. User-specified path 'ghc-x.y.z' does not +-- refer to an executable and the program is not on the system path. +with-compiler: ghc diff --git a/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/z-empty.config b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/z-empty.config new file mode 100644 index 00000000000..771bb389fde --- /dev/null +++ b/cabal-testsuite/PackageTests/ProjectImport/DedupUsingConfigFromSimple/z-empty.config @@ -0,0 +1 @@ +-- This file is intentionally empty, just this comment. diff --git a/changelog.d/pr-10546 b/changelog.d/pr-10546 new file mode 100644 index 00000000000..db0951505f0 --- /dev/null +++ b/changelog.d/pr-10546 @@ -0,0 +1,82 @@ +--- +synopsis: Deduplicate "using configuration from" message +packages: [cabal-install-solver] +prs: 10546 +--- + +## Using Configuration From Message Changes + +Deduplicates and sorts the list of configuration files and URIs printed with the +"using configuration from" message. This message is shown when there's a build +failure. We can trigger that message by using a non-existant package in the +project, "no-pkg-dir". + +If an import is repeated in a `.project` or `.config` file it only imported once +but if the same import is made from an imported file then it was being repeated +in the message. Additional problems were not showing the project first and +mixing configuration files and URIs together. + +* The test set up: + + ``` + $ cat cabal.project + cat cabal.project + packages: no-pkg-dir + import: z-empty.config + import: an-extra.config + import: an-extra.config + import: a-very-extra.config + import: a-very-extra.config + import: https://www.stackage.org/lts-21.25/cabal.config + import: https://www.stackage.org/lts-21.25/cabal.config + + $ cat an-extra.config + import: https://www.stackage.org/lts-21.25/cabal.config + import: https://www.stackage.org/lts-21.25/cabal.config + + $ cat a-very-extra.config + import: https://www.stackage.org/lts-21.25/cabal.config + import: https://www.stackage.org/lts-21.25/cabal.config + + $ cat z-empty.config + - This file is intentionally empty, just this comment. + ``` + +* Before the fix: + + ``` + $ ~/.ghcup/bin/cabal-3.12.1.0 build all --dry-run + When using configuration from: + - a-very-extra.config + - an-extra.config + - cabal.project + - https://www.stackage.org/lts-21.25/cabal.config + - https://www.stackage.org/lts-21.25/cabal.config + - https://www.stackage.org/lts-21.25/cabal.config + - z-empty.config + The following errors occurred: + - The package location 'no-pkg-dir' does not exist. + ``` + +* After the fix: + + ``` + $ cabal build all --dry-run + When using configuration from: + - cabal.project + - a-very-extra.config + - an-extra.config + - z-empty.config + - https://www.stackage.org/lts-21.25/cabal.config + The following errors occurred: + - The package location 'no-pkg-dir' does not exist. + ``` + +## Ord ProjectConfigPath Instance Changes + +Adds a custom `Ord` instance for `ProjectConfigPath` that sorts URIs after local +file paths and longer file paths after shorter ones as measured by the number of +path segments. If still equal, then sorting is lexical. The project itself, a +single element root path, compared to any of the configuration paths it imports, +should always sort first. Comparing one project root path against another is +done lexically.