Skip to content

Commit

Permalink
Merge pull request #6273 from commercialhaskell/fix6269
Browse files Browse the repository at this point in the history
Fix #6269 Implement notify-if-nix-on-path
  • Loading branch information
mpilgrem authored Oct 5, 2023
2 parents 5aa561b + 1ea602c commit 1528fd3
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 2 deletions.
4 changes: 4 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ Behavior changes:
the Stack root, and deletes any corresponding to a `setup-<hash>.hs` or
`setup-shim-<hash>.hs` file, to avoid GHC issue
[#21250](https://gitlab.haskell.org/ghc/ghc/-/issues/21250).
* If Stack's Nix integration is not enabled, Stack will notify the user if a
`nix` executable is on the PATH. This usually indicates the Nix package
manager is available. In YAML configuration files, the `notify-if-nix-on-path`
key is introduced, to allow the notification to be muted if unwanted.

Other enhancements:

Expand Down
6 changes: 6 additions & 0 deletions doc/nix_integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ nix:
The equivalent command line flag (which will prevail) is `--[no-]nix`. Passing
any `--nix-*` option on the command line will imply the `--nix` option.

If Nix integration is not enabled, Stack will notify the user if a `nix`
executable is on the PATH. If that notification is unwanted, it can be muted by
setting Stack's configuration option
[`notify-if-nix-on-path`](yaml_configuration.md#notify-if-nix-on-path) to
`false`.

With Nix integration enabled, `stack build` and `stack exec` will automatically
launch themselves in a local build environment (using `nix-shell` behind the
scenes). It is not necessary to run `stack setup`, unless you want to cache a
Expand Down
9 changes: 9 additions & 0 deletions doc/yaml_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,15 @@ for details).
For further information, see the
[Nix integration](nix_integration.md#configuration) documentation.

### notify-if-nix-on-path

:octicons-tag-24: UNRELEASED

Default: `true`

If Stack's integration with the Nix package manager is not enabled, should Stack
notify the user if a `nix` executable is on the PATH?

### package-index

[:octicons-tag-24: 2.9.3](https://github.com/commercialhaskell/stack/releases/tag/v2.9.3)
Expand Down
1 change: 1 addition & 0 deletions src/Stack/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ configFromConfigMonoid
fromFirst "https://hackage.haskell.org/" configMonoidHackageBaseUrl
configHideSourcePaths = fromFirstTrue configMonoidHideSourcePaths
configRecommendUpgrade = fromFirstTrue configMonoidRecommendUpgrade
configNotifyIfNixOnPath = fromFirstTrue configMonoidNotifyIfNixOnPath
configNoRunCompile = fromFirstFalse configMonoidNoRunCompile
configAllowDifferentUser <-
case getFirst configMonoidAllowDifferentUser of
Expand Down
5 changes: 5 additions & 0 deletions src/Stack/Constants.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module Stack.Constants
, haskellDefaultPreprocessorExts
, stackProgName
, stackProgName'
, nixProgName
, stackDotYaml
, stackWorkEnvVar
, stackRootEnvVar
Expand Down Expand Up @@ -173,6 +174,10 @@ instance Exception ConstantsException where
stackProgName' :: Text
stackProgName' = T.pack stackProgName

-- | Name of the Nix package manager command
nixProgName :: String
nixProgName = "nix"

-- | Extensions used for Haskell modules. Excludes preprocessor ones.
haskellFileExts :: [Text]
haskellFileExts = ["hs", "hsc", "lhs"]
Expand Down
53 changes: 51 additions & 2 deletions src/Stack/Runners.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,21 @@ module Stack.Runners
, ShouldReexec (..)
) where

import RIO.Process ( mkDefaultProcessContext )
import qualified Data.ByteString.Lazy.Char8 as L8
import RIO.Process
( findExecutable, mkDefaultProcessContext, proc
, readProcess
)
import RIO.Time ( addUTCTime, getCurrentTime )
import Stack.Build.Target ( NeedTargets (..) )
import Stack.Config
( getInContainer, getInNixShell, loadConfig, withBuildConfig
, withNewLogFunc
)
import Stack.Constants
( defaultTerminalWidth, maxTerminalWidth, minTerminalWidth )
( defaultTerminalWidth, maxTerminalWidth, minTerminalWidth
, nixProgName
)
import Stack.DefaultColorWhen ( defaultColorWhen )
import qualified Stack.Docker as Docker
import qualified Stack.Nix as Nix
Expand Down Expand Up @@ -140,6 +146,49 @@ withConfig shouldReexec inner =
reexec :: RIO Config a -> RIO Config a
reexec inner = do
nixEnable' <- asks $ nixEnable . configNix
notifyIfNixOnPath <- asks configNotifyIfNixOnPath
when (not nixEnable' && notifyIfNixOnPath) $ do
eNix <- findExecutable nixProgName
case eNix of
Left _ -> pure ()
Right nix -> proc nix ["--version"] $ \pc -> do
let nixProgName' = style Shell (fromString nixProgName)
muteMsg = fillSep
[ flow "To mute this message in future, set"
, style Shell (flow "notify-if-nix-on-path: false")
, flow "in Stack's configuration."
]
reportErr errMsg = prettyWarn $
fillSep
[ nixProgName'
, flow "is on the PATH"
, parens (fillSep ["at", style File (fromString nix)])
, flow "but Stack encountered the following error with"
, nixProgName'
, style Shell "--version" <> ":"
]
<> blankLine
<> errMsg
<> blankLine
<> muteMsg
<> line
res <- tryAny (readProcess pc)
case res of
Left e -> reportErr (ppException e)
Right (ec, out, err) -> case ec of
ExitFailure _ -> reportErr $ string (L8.unpack err)
ExitSuccess -> do
let trimFinalNewline str = case reverse str of
'\n' : rest -> reverse rest
_ -> str
prettyWarn $ fillSep
[ fromString (trimFinalNewline $ L8.unpack out)
, flow "is on the PATH"
, parens (fillSep ["at", style File (fromString nix)])
, flow "but Stack's Nix integration is disabled."
, muteMsg
]
<> line
dockerEnable' <- asks $ dockerEnable . configDocker
case (nixEnable', dockerEnable') of
(True, True) -> throwIO DockerAndNixInvalid
Expand Down
3 changes: 3 additions & 0 deletions src/Stack/Types/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ data Config = Config
-- ^ Enable GHC hiding source paths?
, configRecommendUpgrade :: !Bool
-- ^ Recommend a Stack upgrade?
, configNotifyIfNixOnPath :: !Bool
-- ^ Notify if the Nix package manager (nix) is on the PATH, but
-- Stack's Nix integration is not enabled?
, configNoRunCompile :: !Bool
-- ^ Use --no-run and --compile options when using `stack script`
, configStackDeveloperMode :: !Bool
Expand Down
7 changes: 7 additions & 0 deletions src/Stack/Types/ConfigMonoid.hs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ data ConfigMonoid = ConfigMonoid
-- ^ See 'configHideSourcePaths'
, configMonoidRecommendUpgrade :: !FirstTrue
-- ^ See 'configRecommendUpgrade'
, configMonoidNotifyIfNixOnPath :: !FirstTrue
-- ^ See 'configNotifyIfNixOnPath'
, configMonoidCasaOpts :: !CasaOptsMonoid
-- ^ Casa configuration options.
, configMonoidCasaRepoPrefix :: !(First CasaRepoPrefix)
Expand Down Expand Up @@ -338,6 +340,8 @@ parseConfigMonoidObject rootDir obj = do
FirstTrue <$> obj ..:? configMonoidHideSourcePathsName
configMonoidRecommendUpgrade <-
FirstTrue <$> obj ..:? configMonoidRecommendUpgradeName
configMonoidNotifyIfNixOnPath <-
FirstTrue <$> obj ..:? configMonoidNotifyIfNixOnPathName
configMonoidCasaOpts <-
jsonSubWarnings (obj ..:? configMonoidCasaOptsName ..!= mempty)
configMonoidCasaRepoPrefix <-
Expand Down Expand Up @@ -515,6 +519,9 @@ configMonoidHideSourcePathsName = "hide-source-paths"
configMonoidRecommendUpgradeName :: Text
configMonoidRecommendUpgradeName = "recommend-stack-upgrade"

configMonoidNotifyIfNixOnPathName :: Text
configMonoidNotifyIfNixOnPathName = "notify-if-nix-on-path"

configMonoidCasaOptsName :: Text
configMonoidCasaOptsName = "casa"

Expand Down

0 comments on commit 1528fd3

Please sign in to comment.