Skip to content

Commit

Permalink
priv deps: Don't component qualify private scopes
Browse files Browse the repository at this point in the history
Originally, we were qualifying a private dependency with the component
with that private dep. Now, we qualify a private dependency without the
component, i.e. only with the package name and the scope name.

However, we want the same private scope name to be shared across all
components of a package (and, if different dependencies are desired
across components, different scope names should be used). For example,
the following package should not be possible to solve (and does not with
this commit):

    cabal-version:   3.0
    name:            pkgC
    version:         0.1.0.0
    build-type:      Simple

    library
        private-build-depends: SameName with (libA == 0.1.0.0)
        build-depends:    base

    executable myexe
        private-build-depends: SameName with (libA == 0.2.0.0)
        build-depends: base

See the second case of the `same-scope-name` test.
  • Loading branch information
alt-romes committed Apr 26, 2024
1 parent a811ad2 commit cc97c7e
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ convConfId parent (PI (Q (PackagePath ns qn) pn) (I v loc)) =
-- As below, we need to identify where `AliasPkg` applies. This is
-- needed to qualify `solverPkgLibDeps` since we may have multiple
-- instances of the same package qualified.
| QualAlias pn' _ alias <- qn
| QualAlias pn' alias <- qn
, parent == Just pn' -> AliasPkg (PreExistingId sourceId pi) alias

| otherwise
Expand All @@ -84,7 +84,7 @@ convConfId parent (PI (Q (PackagePath ns qn) pn) (I v loc)) =
-- Same reasoning as for exes, the "top" qualified goal is the one
-- which is private and needs to be aliased, but there might be other goals underneath which
-- are solved in the same scope (but are not private)
| QualAlias pn' _ alias <- qn
| QualAlias pn' alias <- qn
, parent == Just pn' -> AliasPkg (PlannedId sourceId) alias

| IndependentBuildTool _ pn' <- ns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ qualifyDeps QO{..} rdm (Q pp@(PackagePath ns q) pn) = go
goD (Dep dep@(PkgComponent qpn (ExposedExe _)) is_private ci) _ =
Dep (Q (PackagePath (IndependentBuildTool pn qpn) QualToplevel) <$> dep) is_private ci
goD (Dep dep@(PkgComponent qpn (ExposedLib _)) is_private ci) comp
| Private pq <- is_private = Dep (Q (PackagePath ns (QualAlias pn comp pq)) <$> dep) is_private ci
| Private pq <- is_private = Dep (Q (PackagePath ns (QualAlias pn pq)) <$> dep) is_private ci
| qBase qpn = Dep (Q (PackagePath ns (QualBase pn)) <$> dep) is_private ci
| qSetup comp = Dep (Q (PackagePath (IndependentComponent pn ComponentSetup) QualToplevel) <$> dep) is_private ci
| otherwise = Dep (Q (PackagePath ns (inheritedQ qpn) ) <$> dep) is_private ci
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ findBadPrivClosures pkg rdm =
--
-- * If it is not the same private scope, but in one nonetheless,
-- we've reached an end and none of the packages accumulated.
| Q (PackagePath _ ps@(QualAlias _ _ _)) _ <- next
| Q (PackagePath _ ps@(QualAlias _ _)) _ <- next
= if ps == bad_scope_qual
then assert (not $ null acc) acc
else []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ constraintScopeMatches (ScopeTarget pn) (Q (PackagePath ns q) pn') =
namespaceMatches (IndependentBuildTool {}) = False
in namespaceMatches ns && q == QualToplevel && pn == pn'
constraintScopeMatches (ScopePrivate spn alias c_pn) (Q (PackagePath _qual_ns q) c_pn') =
let qualMatches (QualAlias qual_pn _ qual_alias) = spn == qual_pn && alias == qual_alias
let qualMatches (QualAlias qual_pn qual_alias) = spn == qual_pn && alias == qual_alias
qualMatches _ = False
-- TODO: Check whether any ns should subsume qual_ns (if private constraint scopes grow namespaces...)
in qualMatches q && c_pn == c_pn'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ data Qualifier =
| QualBase PackageName

-- A goal which is solved per-component
| QualAlias PackageName Component PrivateAlias
| QualAlias PackageName PrivateAlias

deriving (Eq, Ord, Show)

Expand All @@ -75,7 +75,7 @@ data Qualifier =
dispQualifier :: Qualifier -> Disp.Doc
dispQualifier QualToplevel = Disp.empty
dispQualifier (QualBase pn) = pretty pn <<>> Disp.text ".bb."
dispQualifier (QualAlias pn c alias) = pretty pn <<>> Disp.text ":" <<>> pretty c <<>> Disp.text ":" <<>> pretty alias <<>> Disp.text "."
dispQualifier (QualAlias pn alias) = pretty pn <<>> Disp.text ":" <<>> pretty alias <<>> Disp.text "."

instance Pretty Qualifier where
pretty = dispQualifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,21 @@ because of the conflict too
main =
cabalTest $ recordMode DoNotRecord $ do
-- withProjectFile "cabal.project.scenea" $ -- For some reason this doesn't work...

withRepo "repo" $ do
-- Succeeds because SameName from pkgA and SameName from pkgB do not collide.
cabal "build" ["pkgA", "--project-file=cabal.project.scenea"]
out <- cabal' "build" ["pkgA", "--project-file=cabal.project.scenea"]
-- We build the two versions, one for each package's private deps.
assertOutputContains "- libA-0.1.0.0 (lib) (requires build)" out
assertOutputContains "- libA-0.2.0.0 (lib) (requires build)" out

withRepo "repo" $ do
-- Fails because SameName from pkgC in its two separate components
cabal "build" ["pkgC", "--project-file=cabal.project.sceneb"]
fails (cabal' "build" ["pkgC", "--project-file=cabal.project.sceneb"])
>>= assertOutputContains "rejecting: pkgC:SameName.libA-0.2.0.0 (conflict: pkgC => pkgC:SameName.libA==0.1.0.0)"

withRepo "repo" $ do
-- Fails because SameName from pkgD in the same component
cabal "build" ["pkgD", "--project-file=cabal.project.scenec"]
fails (cabal' "build" ["pkgD", "--project-file=cabal.project.scenec"])
>>= assertOutputContains "rejecting: pkgD:SameName.libA-0.2.0.0 (conflict: pkgD => pkgD:SameName.libA==0.1.0.0)"

0 comments on commit cc97c7e

Please sign in to comment.