Skip to content

Commit 97090cc

Browse files
committed
Fix #3708 By default, don't overwrite a Stack executable not named stack
1 parent 04ac7b0 commit 97090cc

File tree

5 files changed

+69
-29
lines changed

5 files changed

+69
-29
lines changed

ChangeLog.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ Major changes:
1010

1111
Behavior changes:
1212

13+
* Add flag `--[no-]-only-local-bin` to Stack's `upgrade` command for a binary
14+
upgrade. If the Stack executable is `my-stack`, the default is
15+
`my-stack upgrade --only-local-bin` where previously it was, effectively,
16+
`my-stack upgrade --no-only-local-bin`. If the Stack executable is `stack`,
17+
the default is `stack upgrade --no-only-local-bin`, the same behaviour as
18+
previously.
19+
1320
* Use `$XDG_CACHE_HOME/stack/ghci-script`, rather than `<temp>/haskell-stack-ghci`
1421
(where `<temp>` is the directory yielded by the `temporary` package's
1522
`System.IO.Temp.getCanonicalTemporaryDirectory`), as the base location for

doc/upgrade_command.md

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ Either:
66

77
~~~text
88
stack upgrade [--binary-only] [--binary-platform ARG] [--force-download]
9-
[--binary-version ARG] [--github-org ARG] [--github-repo ARG]
9+
[--[no-]only-local-bin] [--binary-version ARG] [--github-org ARG]
10+
[--github-repo ARG]
1011
~~~
1112

1213
or:
@@ -26,6 +27,20 @@ By default:
2627
* the new version will not overwrite the existing version unless it is newer.
2728
Pass the `--force-download` flag to force a download;
2829

30+
* when an existing binary distribution is applicable, it will be put in Stack's
31+
local binary directory (see `stack path --local-bin`) and named `stack`
32+
(replacing any existing executable named `stack` there);
33+
34+
* if the current running Stack executable is named `stack` (or, on Windows,
35+
`stack.exe`) (this is case insensitive), an existing binary distribution will
36+
replace it. If the executable is located outside of Stack's local binary
37+
directory, pass the `--only-local-bin` flag to skip that step;
38+
39+
* if the current running Stack executable is named other than `stack` (and, on
40+
Windows, `stack.exe`), an existing binary distribution will only be put in
41+
Stack's local binary directory and named `stack`. Pass the
42+
`--no-only-local-bin` flag to replace also the current running executable;
43+
2944
* the new version will be the latest available. Pass the
3045
`--binary-version <version>` option to specify the version (this implies
3146
`--force-download`);
@@ -39,15 +54,8 @@ By default:
3954
repository; and
4055

4156
* the binary distribution will be sought for the current platform. Pass the
42-
`--binary-platform <platform>` option to specify a different platform (`<operating_system>-<architecture>-<suffix>`).
43-
44-
When applicable, an existing binary distribution will be:
45-
46-
* put in Stack's local binary directory (see `stack path --local-bin`) and named
47-
`stack` (replacing any existing executable there named `stack`); and
48-
49-
* (if different) named the same as, and replace, the current running Stack
50-
executable.
57+
`--binary-platform <platform>` option to specify a different platform
58+
(`<operating_system>-<architecture>-<suffix>`).
5159

5260
When compiling from source code, by default:
5361

@@ -65,13 +73,19 @@ When compiling from source code, by default:
6573
* `stack upgrade --force-download` seeks an upgrade to the latest version of
6674
Stack available as a binary distribution for the platform, even if not newer.
6775

76+
* If the Stack executable is named `my-stack`, `my-stack upgrade` seeks only to
77+
put the latest version of Stack available as a binary distribution for the
78+
platform, if newer, in Stack's local binary directory and name it `stack`.
79+
`my-stack upgrade --no-only-local-bin` seeks also to upgrade `my-stack` to the
80+
latest version of Stack available.
81+
6882
* `stack upgrade --binary-version 2.11.1` seeks an upgrade to Stack 2.11.1 if
6983
available as a binary distribution for the platform, even if not newer.
7084

7185
* `stack upgrade --source-only` seeks an upgrade by building Stack with
72-
Stack from the latest version of the source code in the package index
73-
(i.e. Hackage).
86+
Stack from the latest version of the source code in the package index
87+
(i.e. Hackage).
7488

7589
* `stack upgrade --source-only --git` seeks an upgrade by building Stack with
76-
Stack from the latest version of the source code in the `master` branch of
77-
Stack's repository.
90+
Stack from the latest version of the source code in the `master` branch of
91+
Stack's repository.

src/Stack/Options/UpgradeParser.hs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,20 @@ module Stack.Options.UpgradeParser
66
) where
77

88
import Options.Applicative
9-
( Parser, flag', help, long, metavar, showDefault, strOption
10-
, switch, value
9+
( Parser, flag', help, idm, long, metavar, showDefault
10+
, strOption, switch, value
1111
)
12+
import Options.Applicative.Builder.Extra ( boolFlags )
1213
import Stack.Prelude
1314
import Stack.Upgrade
1415
( BinaryOpts (..), SourceOpts (..), UpgradeOpts (..) )
1516

1617
-- | Parse command line arguments for Stack's @upgrade@ command.
17-
upgradeOptsParser :: Parser UpgradeOpts
18-
upgradeOptsParser = UpgradeOpts
18+
upgradeOptsParser ::
19+
Bool
20+
-- ^ The default for --[no]-only-local-bin
21+
-> Parser UpgradeOpts
22+
upgradeOptsParser onlyLocalBin = UpgradeOpts
1923
<$> (sourceOnly <|> optional binaryOpts)
2024
<*> (binaryOnly <|> optional sourceOpts)
2125
where
@@ -39,6 +43,10 @@ upgradeOptsParser = UpgradeOpts
3943
<> help "Download the latest available Stack executable, even if not \
4044
\newer."
4145
)
46+
<*> boolFlags onlyLocalBin
47+
"only-local-bin"
48+
"downloading only to Stack's local binary directory"
49+
idm
4250
<*> optional (strOption
4351
( long "binary-version"
4452
<> help "Download a specific Stack version, even if already \

src/Stack/Upgrade.hs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,12 @@ instance Exception UpgradePrettyException
9292
data BinaryOpts = BinaryOpts
9393
{ _boPlatform :: !(Maybe String)
9494
, _boForce :: !Bool
95-
-- ^ force a download, even if the downloaded version is older than what we
96-
-- are
95+
-- ^ Force a download, even if the downloaded version is older than what we
96+
-- are.
97+
, _boOnlyLocalBin :: !Bool
98+
-- ^ Only download to Stack's local binary directory.
9799
, _boVersion :: !(Maybe String)
98-
-- ^ specific version to download
100+
-- ^ Specific version to download
99101
, _boGitHubOrg :: !(Maybe String)
100102
, _boGitHubRepo :: !(Maybe String)
101103
}
@@ -146,7 +148,7 @@ upgrade builtHash (UpgradeOpts mbo mso) = case (mbo, mso) of
146148
source = sourceUpgrade builtHash
147149

148150
binaryUpgrade :: BinaryOpts -> RIO Runner ()
149-
binaryUpgrade (BinaryOpts mplatform force' mver morg mrepo) =
151+
binaryUpgrade (BinaryOpts mplatform force' onlyLocalBin mver morg mrepo) =
150152
withConfig NoReexec $ do
151153
platforms0 <-
152154
case mplatform of
@@ -194,11 +196,12 @@ binaryUpgrade (BinaryOpts mplatform force' mver morg mrepo) =
194196
pure True
195197
when toUpgrade $ do
196198
config <- view configL
197-
downloadStackExe platforms0 archiveInfo (configLocalBin config) True $
198-
\tmpFile -> do
199-
-- Sanity check!
200-
ec <- rawSystem (toFilePath tmpFile) ["--version"]
201-
unless (ec == ExitSuccess) (prettyThrowIO ExecutableFailure)
199+
downloadStackExe
200+
platforms0 archiveInfo (configLocalBin config) (not onlyLocalBin) $
201+
\tmpFile -> do
202+
-- Sanity check!
203+
ec <- rawSystem (toFilePath tmpFile) ["--version"]
204+
unless (ec == ExitSuccess) (prettyThrowIO ExecutableFailure)
202205

203206
sourceUpgrade ::
204207
Maybe String

src/main/Stack/CLI.hs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module Stack.CLI
66

77
import BuildInfo ( hpackVersion, versionString' )
88
import Data.Attoparsec.Interpreter ( getInterpreterArgs )
9+
import Data.Char ( toLower )
910
import qualified Data.List as L
1011
import Options.Applicative
1112
( Parser, ParserFailure, ParserHelp, ParserResult (..), flag
@@ -21,7 +22,7 @@ import RIO.Process ( withProcessContextNoLogging )
2122
import Stack.Build ( buildCmd )
2223
import Stack.Clean ( CleanCommand (..), cleanCmd )
2324
import Stack.ConfigCmd as ConfigCmd
24-
import Stack.Constants ( globalFooter, stackProgName )
25+
import Stack.Constants ( globalFooter, osIsWindows, stackProgName )
2526
import Stack.Coverage ( hpcReportCmd )
2627
import Stack.Docker
2728
( dockerCmdName, dockerHelpOptName, dockerPullCmdName )
@@ -483,7 +484,14 @@ commandLineHandler currentDir progName isInterpreter =
483484
upgradeCmd
484485
"Warning: if you use GHCup to install Stack, use only GHCup to \
485486
\upgrade Stack."
486-
upgradeOptsParser
487+
(upgradeOptsParser onlyLocalBins)
488+
where
489+
onlyLocalBins =
490+
(lowercase progName /= lowercase stackProgName)
491+
&& not ( osIsWindows
492+
&& lowercase progName == lowercase (stackProgName <> ".EXE")
493+
)
494+
lowercase = map toLower
487495

488496
upload = addCommand'
489497
"upload"

0 commit comments

Comments
 (0)