diff --git a/cabal-install/src/Distribution/Client/CmdSdist.hs b/cabal-install/src/Distribution/Client/CmdSdist.hs index 6ac25d527c1..07707d6362e 100644 --- a/cabal-install/src/Distribution/Client/CmdSdist.hs +++ b/cabal-install/src/Distribution/Client/CmdSdist.hs @@ -115,13 +115,10 @@ import Distribution.Simple.Utils ( dieWithException , notice , ordNub + , ordNubBy , withOutputMarker , wrapText ) -import Distribution.Types.ComponentName - ( ComponentName - , showComponentName - ) import Distribution.Types.GenericPackageDescription (GenericPackageDescription) import Distribution.Types.PackageName ( PackageName @@ -376,7 +373,7 @@ packageToSdist verbosity projectRootDir format outputFile pkg = do reifyTargetSelectors :: [PackageSpecifier UnresolvedSourcePackage] -> [TargetSelector] -> Either [TargetProblem] [UnresolvedSourcePackage] reifyTargetSelectors pkgs sels = case partitionEithers (foldMap go sels) of - ([], sels') -> Right sels' + ([], sels') -> Right (ordNubBy packageId sels') (errs, _) -> Left errs where -- there can be pkgs which are in extra-packages: @@ -401,12 +398,15 @@ reifyTargetSelectors pkgs sels = go (TargetAllPackages (Just kind)) = [Left (AllComponentsOnly kind)] go (TargetPackageNamed pname _) = [Left (NonlocalPackageNotAllowed pname)] go (TargetComponentUnknown pname _ _) = [Left (NonlocalPackageNotAllowed pname)] - go (TargetComponent _ cname _) = [Left (ComponentsNotAllowed cname)] + -- sdist only packages whole packages, so any target selector referring to a + -- component (or a module/file within a component) of a local package selects + -- that package. (#11385: a bare package name typed inside the package directory + -- resolves to its primary library component, which shadowed the package match.) + go (TargetComponent pid _ _) = [getPkg pid] data TargetProblem = AllComponentsOnly ComponentKind | NonlocalPackageNotAllowed PackageName - | ComponentsNotAllowed ComponentName renderTargetProblem :: TargetProblem -> String renderTargetProblem (AllComponentsOnly kind) = @@ -414,11 +414,6 @@ renderTargetProblem (AllComponentsOnly kind) = ++ renderComponentKind Plural kind ++ " from a package " ++ "for distribution. Only entire packages may be packaged for distribution." -renderTargetProblem (ComponentsNotAllowed cname) = - "The component " - ++ showComponentName cname - ++ " cannot be packaged for distribution on its own. " - ++ "Only entire packages may be packaged for distribution." renderTargetProblem (NonlocalPackageNotAllowed pname) = "The package " ++ unPackageName pname diff --git a/cabal-testsuite/PackageTests/NewSdist/MultiTarget/valid-and-test-suite.out b/cabal-testsuite/PackageTests/NewSdist/MultiTarget/valid-and-test-suite.out index 6c1e881f806..a8c658cf147 100644 --- a/cabal-testsuite/PackageTests/NewSdist/MultiTarget/valid-and-test-suite.out +++ b/cabal-testsuite/PackageTests/NewSdist/MultiTarget/valid-and-test-suite.out @@ -1,3 +1,5 @@ # cabal v2-sdist -Error: [Cabal-7151] -The component test suite 'a-tests' cannot be packaged for distribution on its own. Only entire packages may be packaged for distribution. +Wrote tarball sdist to /dist-newstyle/sdist/a-0.1.tar.gz +Wrote tarball sdist to /dist-newstyle/sdist/b-0.1.tar.gz +# cabal v2-sdist +Wrote source list to /lists/a-0.1.list diff --git a/cabal-testsuite/PackageTests/NewSdist/MultiTarget/valid-and-test-suite.test.hs b/cabal-testsuite/PackageTests/NewSdist/MultiTarget/valid-and-test-suite.test.hs index 4950fde708a..e5d37479aa8 100644 --- a/cabal-testsuite/PackageTests/NewSdist/MultiTarget/valid-and-test-suite.test.hs +++ b/cabal-testsuite/PackageTests/NewSdist/MultiTarget/valid-and-test-suite.test.hs @@ -1,6 +1,15 @@ import Test.Cabal.Prelude +import System.Directory (createDirectoryIfMissing) +import System.FilePath (normalise) main = cabalTest $ do cwd <- fmap testCurrentDir getTestEnv - fails $ cabal "v2-sdist" ["a", "b", "a-tests"] - shouldNotExist $ cwd "dist-newstyle/sdist/a-0.1.tar.gz" - shouldNotExist $ cwd "dist-newstyle/sdist/b-0.1.tar.gz" + liftIO $ createDirectoryIfMissing False $ cwd "lists" + cabal "v2-sdist" ["a", "b", "a-tests"] + shouldExist $ cwd "dist-newstyle/sdist/a-0.1.tar.gz" + shouldExist $ cwd "dist-newstyle/sdist/b-0.1.tar.gz" + + -- Duplicate selectors resolving to the same package must yield a single + -- package, not two copies of the archive (#11385). With --list-only the + -- deduped package is written to a single .list file. + cabal "v2-sdist" ["a", "a-tests", "--list-only", "--output-dir", "lists"] + assertFindInFile (normalise "a/a.cabal") (cwd "lists/a-0.1.list") diff --git a/cabal-testsuite/PackageTests/NewSdist/SubDirPackageTarget/cabal.project b/cabal-testsuite/PackageTests/NewSdist/SubDirPackageTarget/cabal.project new file mode 100644 index 00000000000..a61b094f388 --- /dev/null +++ b/cabal-testsuite/PackageTests/NewSdist/SubDirPackageTarget/cabal.project @@ -0,0 +1 @@ +packages: p/ diff --git a/cabal-testsuite/PackageTests/NewSdist/SubDirPackageTarget/p/P.hs b/cabal-testsuite/PackageTests/NewSdist/SubDirPackageTarget/p/P.hs new file mode 100644 index 00000000000..fc4877ad85e --- /dev/null +++ b/cabal-testsuite/PackageTests/NewSdist/SubDirPackageTarget/p/P.hs @@ -0,0 +1 @@ +module P where diff --git a/cabal-testsuite/PackageTests/NewSdist/SubDirPackageTarget/p/p.cabal b/cabal-testsuite/PackageTests/NewSdist/SubDirPackageTarget/p/p.cabal new file mode 100644 index 00000000000..ed1f50f41a7 --- /dev/null +++ b/cabal-testsuite/PackageTests/NewSdist/SubDirPackageTarget/p/p.cabal @@ -0,0 +1,7 @@ +cabal-version: 2.2 +name: p +version: 0.1 + +library + default-language: Haskell2010 + exposed-modules: P diff --git a/cabal-testsuite/PackageTests/NewSdist/SubDirPackageTarget/subdir-target.out b/cabal-testsuite/PackageTests/NewSdist/SubDirPackageTarget/subdir-target.out new file mode 100644 index 00000000000..e1f64f03707 --- /dev/null +++ b/cabal-testsuite/PackageTests/NewSdist/SubDirPackageTarget/subdir-target.out @@ -0,0 +1,8 @@ +# cabal v2-sdist +Configuration is affected by cabal.project at ''. +Wrote tarball sdist to /dist-newstyle/sdist/p-0.1.tar.gz +# cabal v2-sdist +Configuration is affected by cabal.project at ''. +Wrote tarball sdist to /dist-newstyle/sdist/p-0.1.tar.gz +# cabal v2-sdist +Wrote tarball sdist to /dist-newstyle/sdist/p-0.1.tar.gz diff --git a/cabal-testsuite/PackageTests/NewSdist/SubDirPackageTarget/subdir-target.test.hs b/cabal-testsuite/PackageTests/NewSdist/SubDirPackageTarget/subdir-target.test.hs new file mode 100644 index 00000000000..b1816f9ae1f --- /dev/null +++ b/cabal-testsuite/PackageTests/NewSdist/SubDirPackageTarget/subdir-target.test.hs @@ -0,0 +1,10 @@ +import Test.Cabal.Prelude +main = cabalTest $ do + cwd <- fmap testCurrentDir getTestEnv + -- #11385: bare package name typed inside the package directory + withDirectory "p" $ cabal "v2-sdist" ["p"] + -- explicit component form selects the containing package + withDirectory "p" $ cabal "v2-sdist" ["p:lib:p"] + -- package name from the project root keeps working + cabal "v2-sdist" ["p"] + shouldExist $ cwd "dist-newstyle/sdist/p-0.1.tar.gz" diff --git a/changelog.d/11385.md b/changelog.d/11385.md new file mode 100644 index 00000000000..d17549685b0 --- /dev/null +++ b/changelog.d/11385.md @@ -0,0 +1,18 @@ +--- +synopsis: "`cabal sdist ` works when run inside the package directory" +packages: [cabal-install] +prs: 12440 +issues: 11385 +--- + +`cabal sdist ` failed with `[Cabal-7151] The component library cannot be +packaged for distribution on its own` when run inside the package directory, +because a bare package name resolves to the package's primary library component. +Any target selector referring to a component (or a module or file within a +component) of a local package now selects that package, so `cabal sdist `, +`cabal sdist :lib:` and similar forms package the containing package. +Explicit component-kind filters such as `cabal sdist tests` still fail with +`[Cabal-7151]`. Multiple selectors resolving to the same package (e.g. +`cabal sdist a a-tests`) now produce a single archive per package instead of +duplicates, and `cabal sdist a a-tests --output-dir -` writes one tarball to +standard output rather than failing with `[Cabal-7152]`.