Skip to content

Commit 572626b

Browse files
committed
cabal sdist: Rename Cabal file to match the package name
Before, if the name of the Cabal file did not match the acutual package name, then `cabal sdist` would include the Cabal file as-is in the source distribution, causing a subsequent `cabal check` to issue a warning and the failure of a Hackage upload. This commit changes that behaviour: The name of the Cabal file in the source distribution always matches the package name, regardless what it was named in the filesystem. Related issue: #6299
1 parent 6953972 commit 572626b

File tree

2 files changed

+66
-15
lines changed

2 files changed

+66
-15
lines changed

cabal-install/src/Distribution/Client/SrcDist.hs

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE DataKinds #-}
12
{-# LANGUAGE OverloadedStrings #-}
23
{-# LANGUAGE RankNTypes #-}
34

@@ -16,14 +17,17 @@ import Control.Monad.Writer.Lazy (WriterT, execWriterT, tell)
1617

1718
import Distribution.Client.Errors
1819
import Distribution.Client.Utils (tryReadAddSourcePackageDesc)
19-
import Distribution.Package (Package (packageId))
20+
import Distribution.Package (Package (packageId), packageName, unPackageName)
2021
import Distribution.PackageDescription.Configuration (flattenPackageDescription)
2122
import Distribution.Simple.PreProcess (knownSuffixHandlers)
22-
import Distribution.Simple.SrcDist (listPackageSourcesWithDie)
23-
import Distribution.Simple.Utils (dieWithException)
23+
import Distribution.Simple.SrcDist (listPackageSources, listPackageSourcesWithDie)
24+
import Distribution.Simple.Utils (dieWithException, tryFindPackageDesc)
2425
import Distribution.Types.GenericPackageDescription (GenericPackageDescription)
2526
import Distribution.Utils.Path
26-
( getSymbolicPath
27+
( FileOrDir (File)
28+
, Pkg
29+
, SymbolicPath
30+
, getSymbolicPath
2731
, makeSymbolicPath
2832
)
2933

@@ -32,6 +36,7 @@ import qualified Codec.Archive.Tar.Entry as Tar
3236
import qualified Codec.Compression.GZip as GZip
3337
import qualified Data.ByteString as BS
3438
import qualified Data.ByteString.Lazy as BSL
39+
import qualified Data.Map.Strict as Map
3540
import qualified Data.Set as Set
3641
import System.Directory (canonicalizePath)
3742
import System.FilePath
@@ -65,23 +70,45 @@ packageDirToSdist
6570
-> IO BSL.ByteString
6671
-- ^ resulting sdist tarball
6772
packageDirToSdist verbosity gpd dir = do
68-
-- let thisDie :: Verbosity -> String -> IO a
69-
-- thisDie v s = die' v $ "sdist of " <> prettyShow (packageId gpd) ++ ": " ++ s
70-
absDir <- canonicalizePath dir
71-
files' <- listPackageSourcesWithDie verbosity dieWithException (Just $ makeSymbolicPath absDir) (flattenPackageDescription gpd) knownSuffixHandlers
72-
let files :: [FilePath]
73-
files = nub $ sort $ map (normalise . getSymbolicPath) files'
73+
let prefix = prettyShow (packageId gpd)
74+
75+
mbWorkDir <- Just . makeSymbolicPath <$> canonicalizePath dir
76+
cabalFilePath <-
77+
getSymbolicPath
78+
<$> tryFindPackageDesc verbosity mbWorkDir
79+
files' <- listPackageSources verbosity mbWorkDir (flattenPackageDescription gpd) knownSuffixHandlers
80+
81+
let insertMapping
82+
:: SymbolicPath Pkg File
83+
-> Map FilePath FilePath
84+
-> Map FilePath FilePath
85+
insertMapping file =
86+
let
87+
value = normalise (getSymbolicPath file)
88+
89+
-- Replace the file name of the package description with one that
90+
-- matches the actual package name.
91+
-- See related issue #6299.
92+
key =
93+
prefix
94+
</> if value == cabalFilePath
95+
then unPackageName (packageName gpd) <.> "cabal"
96+
else value
97+
in
98+
Map.insert key value
99+
100+
let files :: Map FilePath FilePath
101+
files = foldr insertMapping Map.empty files'
74102

75103
let entriesM :: StateT (Set.Set FilePath) (WriterT [Tar.Entry] IO) ()
76104
entriesM = do
77-
let prefix = prettyShow (packageId gpd)
78105
modify (Set.insert prefix)
79106
case Tar.toTarPath True prefix of
80107
Left err -> liftIO $ dieWithException verbosity $ ErrorPackingSdist err
81108
Right path -> tell [Tar.directoryEntry path]
82109

83-
for_ files $ \file -> do
84-
let fileDir = takeDirectory (prefix </> file)
110+
for_ (Map.toAscList files) $ \(tarFile, srcFile) -> do
111+
let fileDir = takeDirectory tarFile
85112
needsEntry <- gets (Set.notMember fileDir)
86113

87114
when needsEntry $ do
@@ -90,8 +117,8 @@ packageDirToSdist verbosity gpd dir = do
90117
Left err -> liftIO $ dieWithException verbosity $ ErrorPackingSdist err
91118
Right path -> tell [Tar.directoryEntry path]
92119

93-
contents <- liftIO . fmap BSL.fromStrict . BS.readFile $ dir </> file
94-
case Tar.toTarPath False (prefix </> file) of
120+
contents <- liftIO . fmap BSL.fromStrict . BS.readFile $ dir </> srcFile
121+
case Tar.toTarPath False tarFile of
95122
Left err -> liftIO $ dieWithException verbosity $ ErrorPackingSdist err
96123
Right path -> tell [(Tar.fileEntry path contents){Tar.entryPermissions = Tar.ordinaryFilePermissions}]
97124

changelog.d/pr-10947.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
synopsis: "Rename the Cabal file to match the package name in source distribution archives"
3+
packages: ["cabal-install"]
4+
issues: ["#6299", "#7322"]
5+
prs: ["#10947"]
6+
---
7+
8+
The `cabal` program has no problem building packages where the name of the Cabal
9+
file is different from the package name. The same was not true when it came to
10+
installing such a package or uploading it to Hackage, since the Cabal file was
11+
be added to the source distribution archive as-is.
12+
13+
Now, `cabal sdist` adds the Cabal file named as `PACKAGE_NAME.cabal` to the
14+
source distribution archive. This has the following consequences:
15+
16+
* If you use for example a canonical name for your Cabal files like
17+
`package.cabal`, then you are now able to use `cabal install` or upload it
18+
to Hackage.
19+
20+
* If you relied on the fact that the name of the Cabal file in the created
21+
source distribution archive matches the one in the filesystem, then this is
22+
not true anymore.
23+
24+
TODO: Explain how/if it is possible to restore the old behaviour!

0 commit comments

Comments
 (0)