Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render project configs as clean list in provenance message (backport #9985) #10084

Merged
merged 2 commits into from
Jun 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE LambdaCase #-}

module Distribution.Solver.Types.ProjectConfigPath
(
Expand All @@ -11,6 +10,7 @@ module Distribution.Solver.Types.ProjectConfigPath

-- * Messages
, docProjectConfigPath
, docProjectConfigPaths
, cyclicalImportMsg
, docProjectConfigPathFailReason

Expand Down Expand Up @@ -56,13 +56,51 @@ instance Structured ProjectConfigPath
-- imported by: B.config
-- imported by: A.project
-- @
-- >>> render . docProjectConfigPath $ ProjectConfigPath $ "D.config" :| ["C.config", "B.config", "A.project" ]
-- >>> render . docProjectConfigPath $ ProjectConfigPath $ "D.config" :| ["C.config", "B.config", "A.project"]
-- "D.config\n imported by: C.config\n imported by: B.config\n imported by: A.project"
docProjectConfigPath :: ProjectConfigPath -> Doc
docProjectConfigPath (ProjectConfigPath (p :| [])) = text p
docProjectConfigPath (ProjectConfigPath (p :| ps)) = vcat $
text p : [ text " " <+> text "imported by:" <+> text l | l <- ps ]

-- | Renders the paths as a list without showing which path imports another,
-- like this;
-- @
-- - cabal.project
-- - project-cabal/constraints.config
-- - project-cabal/ghc-latest.config
-- - project-cabal/ghc-options.config
-- - project-cabal/pkgs.config
-- - project-cabal/pkgs/benchmarks.config
-- - project-cabal/pkgs/buildinfo.config
-- - project-cabal/pkgs/cabal.config
-- - project-cabal/pkgs/install.config
-- - project-cabal/pkgs/integration-tests.config
-- - project-cabal/pkgs/tests.config
-- @
--
-- >>> :{
-- do
-- let ps =
-- [ ProjectConfigPath ("cabal.project" :| [])
-- , ProjectConfigPath ("project-cabal/constraints.config" :| ["cabal.project"])
-- , ProjectConfigPath ("project-cabal/ghc-latest.config" :| ["cabal.project"])
-- , ProjectConfigPath ("project-cabal/ghc-options.config" :| ["cabal.project"])
-- , ProjectConfigPath ("project-cabal/pkgs.config" :| ["cabal.project"])
-- , ProjectConfigPath ("project-cabal/pkgs/benchmarks.config" :| ["project-cabal/pkgs.config","cabal.project"])
-- , ProjectConfigPath ("project-cabal/pkgs/buildinfo.config" :| ["project-cabal/pkgs.config","cabal.project"])
-- , ProjectConfigPath ("project-cabal/pkgs/cabal.config" :| ["project-cabal/pkgs.config","cabal.project"])
-- , ProjectConfigPath ("project-cabal/pkgs/install.config" :| ["project-cabal/pkgs.config","cabal.project"])
-- , 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
-- :}
-- "- 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 ]

-- | A message for a cyclical import, assuming the head of the path is the
-- duplicate.
cyclicalImportMsg :: ProjectConfigPath -> Doc
Expand Down
10 changes: 5 additions & 5 deletions cabal-install/src/Distribution/Client/ProjectConfig.hs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ module Distribution.Client.ProjectConfig
) where

import Distribution.Client.Compat.Prelude
import Text.PrettyPrint (render)
import Text.PrettyPrint (nest, render, text, vcat)
import Prelude ()

import Distribution.Client.Glob
Expand Down Expand Up @@ -875,10 +875,10 @@ renderBadPackageLocations (BadPackageLocations provenance bpls)
renderErrors f = unlines (map f bpls)

renderExplicit =
"When using configuration(s) from "
++ intercalate ", " (render . docProjectConfigPath <$> mapMaybe getExplicit (Set.toList provenance))
++ ", the following errors occurred:\n"
++ renderErrors renderBadPackageLocation
"When using configuration from:\n"
++ render (nest 2 . docProjectConfigPaths $ mapMaybe getExplicit (Set.toList provenance))
++ "\nThe following errors occurred:\n"
++ render (nest 2 $ vcat ((text "-" <+>) . text <$> map renderBadPackageLocation bpls))

getExplicit (Explicit path) = Just path
getExplicit Implicit = Nothing
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import: missing/pkgs.config
2 changes: 2 additions & 0 deletions cabal-testsuite/PackageTests/ConditionalAndImport/cabal.out
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,5 @@ After searching the rest of the dependency tree exhaustively, these were the goa
Error: [Cabal-7090]
Error parsing project file <ROOT>/bad-conditional.project:
Cannot set compiler in a conditional clause of a cabal project file
# checking that missing package message lists configuration provenance
# cabal v2-build
11 changes: 11 additions & 0 deletions cabal-testsuite/PackageTests/ConditionalAndImport/cabal.test.hs
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,15 @@ main = cabalTest . withRepo "repo" . recordMode RecordMarked $ do
badIf <- fails $ cabal' "v2-build" [ "--project-file=bad-conditional.project" ]
assertOutputContains "Cannot set compiler in a conditional clause of a cabal project file" badIf

log "checking that missing package message lists configuration provenance"
missing <- fails $ cabal' "v2-build" [ "--project-file=cabal-missing-package.project" ]
assertOutputContains
"When using configuration from: \
\ - cabal-missing-package.project \
\ - missing/pkgs.config \
\ - missing/pkgs/default.config \
\The following errors occurred: \
\ - The package location 'pkg-doesnt-exist' does not exist."
missing

return ()
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import: pkgs/default.config
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
packages: pkg-doesnt-exist
6 changes: 6 additions & 0 deletions changelog.d/issue-9971
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
synopsis: Renders project configuration provenance as a list of canonical paths
packages: cabal-install cabal-install-solver
prs: #9985
issues: #9971

description: Removes interleaved rendering of project imports.
Loading