Skip to content

Commit c5d4b7c

Browse files
authored
Merge pull request #6666 from phadej/fix-sdist-permissions
Fix sdist permissions
2 parents 95a6ee3 + b2ee5e6 commit c5d4b7c

File tree

21 files changed

+260
-253
lines changed

21 files changed

+260
-253
lines changed

Cabal/Distribution/Simple.hs

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -413,31 +413,12 @@ installAction hooks flags args = do
413413
(getBuildConfig hooks verbosity distPref)
414414
hooks flags' args
415415

416+
-- Since Cabal-3.4 UserHooks are completely ignored
416417
sdistAction :: UserHooks -> SDistFlags -> Args -> IO ()
417-
sdistAction hooks flags _args = do
418-
distPref <- findDistPrefOrDefault (sDistDistPref flags)
419-
let pbi = emptyHookedBuildInfo
420-
421-
mlbi <- maybeGetPersistBuildConfig distPref
422-
423-
-- NB: It would be TOTALLY WRONG to use the 'PackageDescription'
424-
-- store in the 'LocalBuildInfo' for the rest of @sdist@, because
425-
-- that would result in only the files that would be built
426-
-- according to the user's configure being packaged up.
427-
-- In fact, it is not obvious why we need to read the
428-
-- 'LocalBuildInfo' in the first place, except that we want
429-
-- to do some architecture-independent preprocessing which
430-
-- needs to be configured. This is totally awful, see
431-
-- GH#130.
432-
433-
(_, ppd) <- confPkgDescr hooks verbosity Nothing
434-
435-
let pkg_descr0 = flattenPackageDescription ppd
436-
sanityCheckHookedBuildInfo verbosity pkg_descr0 pbi
437-
let pkg_descr = updatePackageDescription pbi pkg_descr0
438-
mlbi' = fmap (\lbi -> lbi { localPkgDescr = pkg_descr }) mlbi
439-
440-
sdist pkg_descr mlbi' flags srcPref (allSuffixHandlers hooks)
418+
sdistAction _hooks flags _args = do
419+
(_, ppd) <- confPkgDescr emptyUserHooks verbosity Nothing
420+
let pkg_descr = flattenPackageDescription ppd
421+
sdist pkg_descr flags srcPref knownSuffixHandlers
441422
where
442423
verbosity = fromFlag (sDistVerbosity flags)
443424

Cabal/Distribution/Simple/SrcDist.hs

Lines changed: 131 additions & 125 deletions
Large diffs are not rendered by default.

Cabal/Distribution/Simple/Utils.hs

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,13 @@ module Distribution.Simple.Utils (
9393

9494
-- * finding files
9595
findFileEx,
96+
findFileCwd,
9697
findFirstFile,
9798
findFileWithExtension,
99+
findFileCwdWithExtension,
98100
findFileWithExtension',
99101
findAllFilesWithExtension,
102+
findAllFilesCwdWithExtension,
100103
findModuleFileEx,
101104
findModuleFilesEx,
102105
getDirectoryContentsRecursive,
@@ -118,7 +121,9 @@ module Distribution.Simple.Utils (
118121
-- * .cabal and .buildinfo files
119122
defaultPackageDesc,
120123
findPackageDesc,
124+
findPackageDescCwd,
121125
tryFindPackageDesc,
126+
tryFindPackageDescCwd,
122127
findHookedPackageDesc,
123128

124129
-- * reading and writing files safely
@@ -942,6 +947,21 @@ findFile :: [FilePath] -- ^search locations
942947
-> IO FilePath
943948
findFile = findFileEx normal
944949

950+
-- | Find a file by looking in a search path. The file path must match exactly.
951+
--
952+
-- @since 3.4.0.0
953+
findFileCwd
954+
:: Verbosity
955+
-> FilePath -- ^ cwd
956+
-> [FilePath] -- ^ relative search location
957+
-> FilePath -- ^ File Name
958+
-> IO FilePath
959+
findFileCwd verbosity cwd searchPath fileName =
960+
findFirstFile (cwd </>)
961+
[ path </> fileName
962+
| path <- nub searchPath]
963+
>>= maybe (die' verbosity $ fileName ++ " doesn't exist") return
964+
945965
-- | Find a file by looking in a search path. The file path must match exactly.
946966
--
947967
findFileEx :: Verbosity
@@ -968,6 +988,32 @@ findFileWithExtension extensions searchPath baseName =
968988
| path <- nub searchPath
969989
, ext <- nub extensions ]
970990

991+
-- | @since 3.4.0.0
992+
findFileCwdWithExtension
993+
:: FilePath
994+
-> [String]
995+
-> [FilePath]
996+
-> FilePath
997+
-> IO (Maybe FilePath)
998+
findFileCwdWithExtension cwd extensions searchPath baseName =
999+
findFirstFile (cwd </>)
1000+
[ path </> baseName <.> ext
1001+
| path <- nub searchPath
1002+
, ext <- nub extensions ]
1003+
1004+
-- | @since 3.4.0.0
1005+
findAllFilesCwdWithExtension
1006+
:: FilePath -- ^ cwd
1007+
-> [String] -- ^ extensions
1008+
-> [FilePath] -- ^ relative search locations
1009+
-> FilePath -- ^ basename
1010+
-> IO [FilePath]
1011+
findAllFilesCwdWithExtension cwd extensions searchPath basename =
1012+
findAllFiles (cwd </>)
1013+
[ path </> basename <.> ext
1014+
| path <- nub searchPath
1015+
, ext <- nub extensions ]
1016+
9711017
findAllFilesWithExtension :: [String]
9721018
-> [FilePath]
9731019
-> FilePath
@@ -1460,16 +1506,23 @@ defaultPackageDesc verbosity = tryFindPackageDesc verbosity currentDir
14601506
-- @.cabal@ files.
14611507
findPackageDesc :: FilePath -- ^Where to look
14621508
-> IO (Either String FilePath) -- ^<pkgname>.cabal
1463-
findPackageDesc dir
1464-
= do files <- getDirectoryContents dir
1509+
findPackageDesc = findPackageDescCwd "."
1510+
1511+
-- | @since 3.4.0.0
1512+
findPackageDescCwd
1513+
:: FilePath -- ^ project root
1514+
-> FilePath -- ^ relative directory
1515+
-> IO (Either String FilePath) -- ^ <pkgname>.cabal relative to the project root
1516+
findPackageDescCwd cwd dir
1517+
= do files <- getDirectoryContents (cwd </> dir)
14651518
-- to make sure we do not mistake a ~/.cabal/ dir for a <pkgname>.cabal
14661519
-- file we filter to exclude dirs and null base file names:
1467-
cabalFiles <- filterM doesFileExist
1468-
[ dir </> file
1520+
cabalFiles <- filterM (doesFileExist . snd)
1521+
[ (dir </> file, cwd </> dir </> file)
14691522
| file <- files
14701523
, let (name, ext) = splitExtension file
14711524
, not (null name) && ext == ".cabal" ]
1472-
case cabalFiles of
1525+
case map fst cabalFiles of
14731526
[] -> return (Left noDesc)
14741527
[cabalFile] -> return (Right cabalFile)
14751528
multiple -> return (Left $ multiDesc multiple)
@@ -1489,6 +1542,13 @@ tryFindPackageDesc :: Verbosity -> FilePath -> IO FilePath
14891542
tryFindPackageDesc verbosity dir =
14901543
either (die' verbosity) return =<< findPackageDesc dir
14911544

1545+
-- | Like 'findPackageDescCwd', but calls 'die' in case of error.
1546+
--
1547+
-- @since 3.4.0.0
1548+
tryFindPackageDescCwd :: Verbosity -> FilePath -> FilePath -> IO FilePath
1549+
tryFindPackageDescCwd verbosity cwd dir =
1550+
either (die' verbosity) return =<< findPackageDescCwd cwd dir
1551+
14921552
-- |Find auxiliary package information in the given directory.
14931553
-- Looks for @.buildinfo@ files.
14941554
findHookedPackageDesc

Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ cabal-install-test:
133133
rm -rf .ghc.environment.*
134134
cd cabal-testsuite && `cabal-plan list-bin cabal-tests` --with-cabal=`cabal-plan list-bin cabal` --hide-successes -j3 ${TEST}
135135

136+
# This doesn't run build, as you first need to test with cabal-install-test :)
137+
cabal-install-test-accept:
138+
@which cabal-plan
139+
rm -rf .ghc.environment.*
140+
cd cabal-testsuite && `cabal-plan list-bin cabal-tests` --with-cabal=`cabal-plan list-bin cabal` --hide-successes -j3 --accept ${TEST}
141+
136142
# Docker validation
137143

138144
# Use this carefully, on big machine you can say
@@ -178,3 +184,8 @@ validate-via-docker-8.10.1:
178184

179185
validate-via-docker-old:
180186
docker build -t cabal-validate -f .docker/validate-old.dockerfile .
187+
188+
# tags
189+
.PHONY : tags
190+
tags :
191+
hasktags -c Cabal/Distribution Cabal/Language cabal-install/Distribution

cabal-install/Distribution/Client/CmdSdist.hs

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,11 @@ import qualified Data.ByteString.Char8 as BS
7070
import qualified Data.ByteString.Lazy.Char8 as BSL
7171
import Data.Either
7272
( partitionEithers )
73-
import Data.List
74-
( sortOn )
7573
import qualified Data.Set as Set
7674
import System.Directory
77-
( getCurrentDirectory, setCurrentDirectory
78-
, createDirectoryIfMissing, makeAbsolute )
75+
( getCurrentDirectory
76+
, createDirectoryIfMissing, makeAbsolute
77+
)
7978
import System.FilePath
8079
( (</>), (<.>), makeRelative, normalise, takeDirectory )
8180

@@ -218,9 +217,6 @@ sdistAction SdistFlags{..} targetStrings globalFlags = do
218217
baseCtx <- establishProjectBaseContextWithRoot verbosity (config <> prjConfig) (ProjectRootImplicit cwd) OtherCommand
219218
return (baseCtx, distDirLayout baseCtx)
220219

221-
data IsExec = Exec | NoExec
222-
deriving (Show, Eq)
223-
224220
data OutputFormat = SourceList Char
225221
| TarGzArchive
226222
deriving (Show, Eq)
@@ -256,19 +252,13 @@ packageToSdist verbosity projectRootDir format outputFile pkg = do
256252
_ -> die' verbosity ("cannot convert tarball package to " ++ show format)
257253

258254
Right dir -> do
259-
oldPwd <- getCurrentDirectory
260-
setCurrentDirectory dir
261-
262-
let norm flag = fmap ((flag, ) . normalise)
263-
(norm NoExec -> nonexec, norm Exec -> exec) <-
264-
listPackageSources verbosity (flattenPackageDescription $ packageDescription pkg) knownSuffixHandlers
265-
266-
let files = nub . sortOn snd $ nonexec ++ exec
255+
files' <- listPackageSources verbosity dir (flattenPackageDescription $ packageDescription pkg) knownSuffixHandlers
256+
let files = nub $ sort $ map normalise files'
267257

268258
case format of
269259
SourceList nulSep -> do
270260
let prefix = makeRelative projectRootDir dir
271-
write $ concat [prefix </> i ++ [nulSep] | (_, i) <- files]
261+
write $ concat [prefix </> i ++ [nulSep] | i <- files]
272262
when (outputFile /= "-") $
273263
notice verbosity $ "Wrote source list to " ++ outputFile ++ "\n"
274264
TarGzArchive -> do
@@ -280,11 +270,8 @@ packageToSdist verbosity projectRootDir format outputFile pkg = do
280270
Left err -> liftIO $ die' verbosity ("Error packing sdist: " ++ err)
281271
Right path -> tell [Tar.directoryEntry path]
282272

283-
for_ files $ \(perm, file) -> do
273+
for_ files $ \file -> do
284274
let fileDir = takeDirectory (prefix </> file)
285-
perm' = case perm of
286-
Exec -> Tar.executableFilePermissions
287-
NoExec -> Tar.ordinaryFilePermissions
288275
needsEntry <- gets (Set.notMember fileDir)
289276

290277
when needsEntry $ do
@@ -293,10 +280,10 @@ packageToSdist verbosity projectRootDir format outputFile pkg = do
293280
Left err -> liftIO $ die' verbosity ("Error packing sdist: " ++ err)
294281
Right path -> tell [Tar.directoryEntry path]
295282

296-
contents <- liftIO . fmap BSL.fromStrict . BS.readFile $ file
283+
contents <- liftIO . fmap BSL.fromStrict . BS.readFile $ dir </> file
297284
case Tar.toTarPath False (prefix </> file) of
298285
Left err -> liftIO $ die' verbosity ("Error packing sdist: " ++ err)
299-
Right path -> tell [(Tar.fileEntry path contents) { Tar.entryPermissions = perm' }]
286+
Right path -> tell [(Tar.fileEntry path contents) { Tar.entryPermissions = Tar.ordinaryFilePermissions }]
300287

301288
entries <- execWriterT (evalStateT entriesM mempty)
302289
let -- Pretend our GZip file is made on Unix.
@@ -314,8 +301,6 @@ packageToSdist verbosity projectRootDir format outputFile pkg = do
314301
when (outputFile /= "-") $
315302
notice verbosity $ "Wrote tarball sdist to " ++ outputFile ++ "\n"
316303

317-
setCurrentDirectory oldPwd
318-
319304
--
320305

321306
reifyTargetSelectors :: [PackageSpecifier UnresolvedSourcePackage] -> [TargetSelector] -> Either [TargetProblem] [UnresolvedSourcePackage]

cabal-install/Distribution/Client/ProjectBuilding.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1226,7 +1226,7 @@ buildInplaceUnpackedPackage verbosity
12261226
execRebuild srcdir (needElaboratedConfiguredPackage pkg)
12271227
listSdist =
12281228
fmap (map monitorFileHashed) $
1229-
allPackageSourceFiles verbosity scriptOptions srcdir
1229+
allPackageSourceFiles verbosity srcdir
12301230
ifNullThen m m' = do xs <- m
12311231
if null xs then m' else return xs
12321232
monitors <- case PD.buildType (elabPkgDescription pkg) of

cabal-install/Distribution/Client/Sandbox.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ sandboxAddSourceSnapshot verbosity buildTreeRefs sandboxDir pkgEnv = do
453453
when dirExists $
454454
removeDirectoryRecursive targetDir
455455
createDirectory targetTmpDir
456-
prepareTree verbosity pkg Nothing targetTmpDir knownSuffixHandlers
456+
prepareTree verbosity pkg targetTmpDir knownSuffixHandlers
457457
return (targetTmpDir, targetDir)
458458

459459
-- Now rename the "snapshots/$PKGNAME-$VERSION-tmp" dirs to

cabal-install/Distribution/Client/Sandbox/Timestamp.hs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import Distribution.Client.SrcDist (allPackageSourceFiles)
3838
import Distribution.Client.Sandbox.Index
3939
(ListIgnoredBuildTreeRefs (ListIgnored), RefTypesToList(OnlyLinks)
4040
,listBuildTreeRefs)
41-
import Distribution.Client.SetupWrapper
4241

4342
import Distribution.Compat.Exception (catchIO)
4443
import Distribution.Compat.Time (ModTime, getCurTime,
@@ -232,7 +231,7 @@ isDepModified verbosity now (packageDir, timestamp) = do
232231
debug verbosity ("Checking whether the dependency is modified: " ++ packageDir)
233232
-- TODO: we should properly plumb the correct options through
234233
-- instead of using defaultSetupScriptOptions
235-
depSources <- allPackageSourceFiles verbosity defaultSetupScriptOptions packageDir
234+
depSources <- allPackageSourceFiles verbosity packageDir
236235
go depSources
237236

238237
where

cabal-install/Distribution/Client/SrcDist.hs

Lines changed: 12 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3,66 +3,26 @@ module Distribution.Client.SrcDist (
33
allPackageSourceFiles,
44
) where
55

6-
7-
import Control.Exception (IOException, evaluate)
8-
import System.Directory (getTemporaryDirectory)
9-
import System.FilePath ((</>))
10-
11-
import Distribution.Compat.Exception (catchIO)
12-
import Distribution.Package (packageName)
136
import Distribution.PackageDescription.Configuration (flattenPackageDescription)
147
import Distribution.PackageDescription.Parsec (readGenericPackageDescription)
15-
import Distribution.Pretty (prettyShow)
16-
import Distribution.Simple.Setup (Flag (..), defaultSDistFlags, sdistCommand)
17-
import Distribution.Simple.Utils (warn, withTempDirectory)
18-
import Distribution.Verbosity (Verbosity, lessVerbose, normal)
19-
import Distribution.Version (intersectVersionRanges, mkVersion, orLaterVersion)
8+
import Distribution.Simple.PreProcess (knownSuffixHandlers)
9+
import Distribution.Simple.SrcDist (listPackageSourcesWithDie)
10+
import Distribution.Verbosity (Verbosity)
2011

21-
import Distribution.Client.Setup (SDistFlags (..))
22-
import Distribution.Client.SetupWrapper (SetupScriptOptions (..), setupWrapper)
23-
import Distribution.Client.Utils (tryFindAddSourcePackageDesc)
12+
import Distribution.Client.Utils (tryFindAddSourcePackageDesc)
2413

2514
-- | List all source files of a given add-source dependency. Exits with error if
2615
-- something is wrong (e.g. there is no .cabal file in the given directory).
27-
allPackageSourceFiles :: Verbosity -> SetupScriptOptions -> FilePath
28-
-> IO [FilePath]
29-
allPackageSourceFiles verbosity setupOpts0 packageDir = do
30-
pkg <- do
16+
--
17+
-- Used in sandbox and projectbuilding.
18+
-- TODO: when sandboxes are removed, move to ProjectBuilding.
19+
--
20+
allPackageSourceFiles :: Verbosity -> FilePath -> IO [FilePath]
21+
allPackageSourceFiles verbosity packageDir = do
22+
pd <- do
3123
let err = "Error reading source files of package."
3224
desc <- tryFindAddSourcePackageDesc verbosity packageDir err
3325
flattenPackageDescription `fmap` readGenericPackageDescription verbosity desc
34-
globalTmp <- getTemporaryDirectory
35-
withTempDirectory verbosity globalTmp "cabal-list-sources." $ \tempDir -> do
36-
let file = tempDir </> "cabal-sdist-list-sources"
37-
flags = defaultSDistFlags {
38-
sDistVerbosity = Flag $ if verbosity == normal
39-
then lessVerbose verbosity else verbosity,
40-
sDistListSources = Flag file
41-
}
42-
setupOpts = setupOpts0 {
43-
-- 'sdist --list-sources' was introduced in Cabal 1.18.
44-
useCabalVersion = intersectVersionRanges
45-
(orLaterVersion $ mkVersion [1,18,0])
46-
(useCabalVersion setupOpts0),
47-
useWorkingDir = Just packageDir
48-
}
49-
50-
doListSources :: IO [FilePath]
51-
doListSources = do
52-
setupWrapper verbosity setupOpts (Just pkg) sdistCommand (const flags) (const [])
53-
fmap lines . readFile $ file
5426

55-
onFailedListSources :: IOException -> IO ()
56-
onFailedListSources e = do
57-
warn verbosity $
58-
"Could not list sources of the package '"
59-
++ prettyShow (packageName pkg) ++ "'."
60-
warn verbosity $
61-
"Exception was: " ++ show e
27+
listPackageSourcesWithDie verbosity (\_ _ -> return []) packageDir pd knownSuffixHandlers
6228

63-
-- Run setup sdist --list-sources=TMPFILE
64-
r <- doListSources `catchIO` (\e -> onFailedListSources e >> return [])
65-
-- Ensure that we've closed the 'readFile' handle before we exit the
66-
-- temporary directory.
67-
_ <- evaluate (length r)
68-
return r

cabal-testsuite/PackageTests/AutogenModules/Package/setup.cabal.out

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,5 @@ On benchmark 'Bench' an 'autogen-module' is not on 'other-modules'
1616
Packages using 'cabal-version: 2.0' and the autogenerated module Paths_* must include it also on the 'autogen-modules' field besides 'exposed-modules' and 'other-modules'. This specifies that the module does not come with the package and is generated on setup. Modules built with a custom Setup.hs script also go here to ensure that commands like sdist don't fail.
1717
The filename ./my.cabal does not match package name (expected: AutogenModules.cabal)
1818
Note: the public hackage server would reject this package.
19-
Warning: Cannot run preprocessors. Run 'configure' command first.
2019
Building source dist for AutogenModules-0.1...
2120
cabal: Error: Could not find module: MyLibHelperModule with any suffix: ["gc","chs","hsc","x","y","ly","cpphs","hs","lhs","hsig","lhsig"]. If the module is autogenerated it should be added to 'autogen-modules'.

cabal-testsuite/PackageTests/AutogenModules/Package/setup.out

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,5 @@ On benchmark 'Bench' an 'autogen-module' is not on 'other-modules'
1616
Packages using 'cabal-version: 2.0' and the autogenerated module Paths_* must include it also on the 'autogen-modules' field besides 'exposed-modules' and 'other-modules'. This specifies that the module does not come with the package and is generated on setup. Modules built with a custom Setup.hs script also go here to ensure that commands like sdist don't fail.
1717
The filename ./my.cabal does not match package name (expected: AutogenModules.cabal)
1818
Note: the public hackage server would reject this package.
19-
Warning: Cannot run preprocessors. Run 'configure' command first.
2019
Building source dist for AutogenModules-0.1...
2120
setup: Error: Could not find module: MyLibHelperModule with any suffix: ["gc","chs","hsc","x","y","ly","cpphs","hs","lhs","hsig","lhsig"]. If the module is autogenerated it should be added to 'autogen-modules'.

0 commit comments

Comments
 (0)