Skip to content

Commit 00ce024

Browse files
authored
Add a warning when an env file is created (#9705)
* Add a warning when an env file is created #6481 (comment) * Formatting * Improve wording of warning message * Only show warning if --package-env not given * Improve message and its formatting * Formatting
1 parent b216b99 commit 00ce024

File tree

1 file changed

+47
-17
lines changed

1 file changed

+47
-17
lines changed

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

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,8 @@ installAction flags@NixStyleFlags{extraFlags, configFlags, installFlags, project
442442
let
443443
GhcImplInfo{supportsPkgEnvFiles} = getImplInfo compiler
444444

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

1227-
-- | Gets the file path to the request environment file.
1228-
getEnvFile :: ClientInstallFlags -> Platform -> Version -> IO FilePath
1253+
-- | Gets the file path to the request environment file. The @Bool@ is @True@
1254+
-- if we got an explicit instruction using @--package-env@, @False@ if we used
1255+
-- the default.
1256+
getEnvFile :: ClientInstallFlags -> Platform -> Version -> IO (Bool, FilePath)
12291257
getEnvFile clientInstallFlags platform compilerVersion = do
12301258
appDir <- getGhcAppDir
12311259
case flagToMaybe (cinstEnvironmentPath clientInstallFlags) of
12321260
Just spec
12331261
-- Is spec a bare word without any "pathy" content, then it refers to
12341262
-- a named global environment.
12351263
| takeBaseName spec == spec ->
1236-
return (getGlobalEnv appDir platform compilerVersion spec)
1264+
return (True, getGlobalEnv appDir platform compilerVersion spec)
12371265
| otherwise -> do
12381266
spec' <- makeAbsolute spec
12391267
isDir <- doesDirectoryExist spec'
12401268
if isDir
12411269
then -- If spec is a directory, then make an ambient environment inside
12421270
-- that directory.
1243-
return (getLocalEnv spec' platform compilerVersion)
1271+
return (True, getLocalEnv spec' platform compilerVersion)
12441272
else -- Otherwise, treat it like a literal file path.
1245-
return spec'
1273+
return (True, spec')
12461274
Nothing ->
1247-
return (getGlobalEnv appDir platform compilerVersion "default")
1275+
return (False, getGlobalEnv appDir platform compilerVersion "default")
12481276

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

0 commit comments

Comments
 (0)