Skip to content

Commit 31eb97a

Browse files
authored
Merge pull request #9895 from haskell/mergify/bp/3.12/pr-9705
Add a warning when an env file is created (backport #9705)
2 parents 017ed01 + 4852cf0 commit 31eb97a

File tree

1 file changed

+47
-17
lines changed

1 file changed

+47
-17
lines changed

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

+47-17
Original file line numberDiff line numberDiff line change
@@ -441,8 +441,8 @@ installAction flags@NixStyleFlags{extraFlags, configFlags, installFlags, project
441441
let
442442
GhcImplInfo{supportsPkgEnvFiles} = getImplInfo compiler
443443

444-
envFile <- getEnvFile clientInstallFlags platform compilerVersion
445-
existingEnvEntries <-
444+
(usedPackageEnvFlag, envFile) <- getEnvFile clientInstallFlags platform compilerVersion
445+
(usedExistingPkgEnvFile, existingEnvEntries) <-
446446
getExistingEnvEntries verbosity compilerFlavor supportsPkgEnvFiles envFile
447447
packageDbs <- getPackageDbStack compiler projectConfigStoreDir projectConfigLogsDir projectConfigPackageDBs
448448
installedIndex <- getInstalledPackages verbosity compiler packageDbs progDb
@@ -533,6 +533,7 @@ installAction flags@NixStyleFlags{extraFlags, configFlags, installFlags, project
533533
packageDbs
534534
envFile
535535
nonGlobalEnvEntries'
536+
(not usedExistingPkgEnvFile && not usedPackageEnvFlag)
536537
else -- Install any built exe by symlinking or copying it we don't use
537538
-- BuildOutcomes because we also need the component names
538539
traverseInstall (installCheckUnitExes InstallCheckInstall) installCfg
@@ -959,6 +960,9 @@ installLibraries
959960
-> FilePath
960961
-- ^ Environment file
961962
-> [GhcEnvironmentFileEntry]
963+
-> Bool
964+
-- ^ Whether we need to show a warning (i.e. we created a new environment
965+
-- file, and the user did not use --package-env)
962966
-> IO ()
963967
installLibraries
964968
verbosity
@@ -967,7 +971,8 @@ installLibraries
967971
compiler
968972
packageDbs'
969973
envFile
970-
envEntries = do
974+
envEntries
975+
showWarning = do
971976
if supportsPkgEnvFiles $ getImplInfo compiler
972977
then do
973978
let validDb (SpecificPackageDB fp) = doesPathExist fp
@@ -993,6 +998,27 @@ installLibraries
993998
contents' = renderGhcEnvironmentFile (baseEntries ++ pkgEntries)
994999
createDirectoryIfMissing True (takeDirectory envFile)
9951000
writeFileAtomic envFile (BS.pack contents')
1001+
when showWarning $
1002+
warn verbosity $
1003+
"The libraries were installed by creating a global GHC environment file at:\n"
1004+
++ envFile
1005+
++ "\n"
1006+
++ "\n"
1007+
++ "The presence of such an environment file is likely to confuse or break other "
1008+
++ "tools because it changes GHC's behaviour: it changes the default package set in "
1009+
++ "ghc and ghci from its normal value (which is \"all boot libraries\"). GHC "
1010+
++ "environment files are little-used and often not tested for.\n"
1011+
++ "\n"
1012+
++ "Furthermore, management of these environment files is still more difficult than "
1013+
++ "it could be; see e.g. https://github.com/haskell/cabal/issues/6481 .\n"
1014+
++ "\n"
1015+
++ "Double-check that creating a global GHC environment file is really what you "
1016+
++ "wanted! You can limit the effects of the environment file by creating it in a "
1017+
++ "specific directory using the --package-env flag. For example, use:\n"
1018+
++ "\n"
1019+
++ "cabal install --lib <packages...> --package-env .\n"
1020+
++ "\n"
1021+
++ "to create the file in the current directory."
9961022
else
9971023
warn verbosity $
9981024
"The current compiler doesn't support safely installing libraries, "
@@ -1223,46 +1249,50 @@ entriesForLibraryComponents = Map.foldrWithKey' (\k v -> mappend (go k v)) []
12231249
| any hasLib targets = [GhcEnvFilePackageId unitId]
12241250
| otherwise = []
12251251

1226-
-- | Gets the file path to the request environment file.
1227-
getEnvFile :: ClientInstallFlags -> Platform -> Version -> IO FilePath
1252+
-- | Gets the file path to the request environment file. The @Bool@ is @True@
1253+
-- if we got an explicit instruction using @--package-env@, @False@ if we used
1254+
-- the default.
1255+
getEnvFile :: ClientInstallFlags -> Platform -> Version -> IO (Bool, FilePath)
12281256
getEnvFile clientInstallFlags platform compilerVersion = do
12291257
appDir <- getGhcAppDir
12301258
case flagToMaybe (cinstEnvironmentPath clientInstallFlags) of
12311259
Just spec
12321260
-- Is spec a bare word without any "pathy" content, then it refers to
12331261
-- a named global environment.
12341262
| takeBaseName spec == spec ->
1235-
return (getGlobalEnv appDir platform compilerVersion spec)
1263+
return (True, getGlobalEnv appDir platform compilerVersion spec)
12361264
| otherwise -> do
12371265
spec' <- makeAbsolute spec
12381266
isDir <- doesDirectoryExist spec'
12391267
if isDir
12401268
then -- If spec is a directory, then make an ambient environment inside
12411269
-- that directory.
1242-
return (getLocalEnv spec' platform compilerVersion)
1270+
return (True, getLocalEnv spec' platform compilerVersion)
12431271
else -- Otherwise, treat it like a literal file path.
1244-
return spec'
1272+
return (True, spec')
12451273
Nothing ->
1246-
return (getGlobalEnv appDir platform compilerVersion "default")
1274+
return (False, getGlobalEnv appDir platform compilerVersion "default")
12471275

1248-
-- | Returns the list of @GhcEnvFilePackageIj@ values already existing in the
1249-
-- environment being operated on.
1250-
getExistingEnvEntries :: Verbosity -> CompilerFlavor -> Bool -> FilePath -> IO [GhcEnvironmentFileEntry]
1276+
-- | Returns the list of @GhcEnvFilePackageId@ values already existing in the
1277+
-- environment being operated on. The @Bool@ is @True@ if we took settings
1278+
-- from an existing file, @False@ otherwise.
1279+
getExistingEnvEntries :: Verbosity -> CompilerFlavor -> Bool -> FilePath -> IO (Bool, [GhcEnvironmentFileEntry])
12511280
getExistingEnvEntries verbosity compilerFlavor supportsPkgEnvFiles envFile = do
12521281
envFileExists <- doesFileExist envFile
1253-
filterEnvEntries
1254-
<$> if (compilerFlavor == GHC || compilerFlavor == GHCJS)
1282+
(usedExisting, allEntries) <-
1283+
if (compilerFlavor == GHC || compilerFlavor == GHCJS)
12551284
&& supportsPkgEnvFiles
12561285
&& envFileExists
1257-
then catch (readGhcEnvironmentFile envFile) $ \(_ :: ParseErrorExc) ->
1286+
then catch ((True,) <$> readGhcEnvironmentFile envFile) $ \(_ :: ParseErrorExc) ->
12581287
warn
12591288
verbosity
12601289
( "The environment file "
12611290
++ envFile
12621291
++ " is unparsable. Libraries cannot be installed."
12631292
)
1264-
>> return []
1265-
else return []
1293+
>> return (False, [])
1294+
else return (False, [])
1295+
return (usedExisting, filterEnvEntries allEntries)
12661296
where
12671297
-- Why? We know what the first part will be, we only care about the packages.
12681298
filterEnvEntries = filter $ \case

0 commit comments

Comments
 (0)