Skip to content

Commit 8593474

Browse files
wismillMikolaj
authored andcommitted
Fix --program-{prefix,suffix} resulting in invalid installation
Currently the options `--program-{prefix,suffix}` for cabal install affects the name of the file in the install directory *and* the executable name in the store. The installation fails: - If using `--install-method=symlink`, the *target* of the symlink is not affected by the affix options and it results in an invalid symlink. - If using `--install-method=copy`, the copy fails because the source is not found. Another issue is that it affects the computation of the hash of the build directory in the store, resulting in needless rebuild when using successively different affix options. Fixed by making the name of the executable in the store canonical, i.e. always ignoring the program affix options. Added a test for all the combinations of `--install-method` and program affixes options.
1 parent 6f1329b commit 8593474

File tree

6 files changed

+54
-1
lines changed

6 files changed

+54
-1
lines changed

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ installAction flags@NixStyleFlags{extraFlags, configFlags, installFlags, project
540540
-- BuildOutcomes because we also need the component names
541541
traverseInstall (installCheckUnitExes InstallCheckInstall) installCfg
542542
where
543-
configFlags' = disableTestsBenchsByDefault configFlags
543+
configFlags' = disableTestsBenchsByDefault . ignoreProgramAffixes $ configFlags
544544
verbosity = fromFlagOrDefault normal (setupVerbosity $ configCommonFlags configFlags')
545545
ignoreProject = flagIgnoreProject projectFlags
546546
cliConfig =
@@ -1101,6 +1101,18 @@ disableTestsBenchsByDefault configFlags =
11011101
, configBenchmarks = Flag False <> configBenchmarks configFlags
11021102
}
11031103

1104+
-- | Disables program prefix and suffix, in order to get the /canonical/
1105+
-- executable name in the store and thus:
1106+
--
1107+
-- * avoid making the package hash depend on these options and needless rebuild;
1108+
-- * provide the correct executable path to the install methods (copy, symlink).
1109+
ignoreProgramAffixes :: ConfigFlags -> ConfigFlags
1110+
ignoreProgramAffixes configFlags =
1111+
configFlags
1112+
{ configProgPrefix = NoFlag
1113+
, configProgSuffix = NoFlag
1114+
}
1115+
11041116
-- | Prepares a record containing the information needed to either symlink or
11051117
-- copy an executable.
11061118
symlink :: OverwritePolicy -> InstallExe -> UnitId -> UnqualComponentName -> Symlink
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
main = pure ()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
packages: .
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import Test.Cabal.Prelude
2+
import Data.Foldable (traverse_)
3+
4+
-- Test that program affixes options result in successful installation:
5+
-- • Valid symlinks (--install-method=symlink)
6+
-- • Valid copy of executables (--install-method=copy)
7+
main = cabalTest $ do
8+
env <- getTestEnv
9+
recordMode DoNotRecord $ do
10+
let installdir = testPrefixDir env </> "bin"
11+
commonOpts = ["p", "--installdir", installdir, "--overwrite-policy=always"]
12+
testAllAffixes installMethod = do
13+
let testAffixes' = testAffixes
14+
(commonOpts ++ ["--install-method", installMethod])
15+
testAffixes' Nothing Nothing
16+
testAffixes' (Just "a-") Nothing
17+
testAffixes' Nothing (Just "-z")
18+
testAffixes' (Just "a-") (Just "-z")
19+
traverse_ testAllAffixes ["symlink", "copy"]
20+
where
21+
mkAffixOption option = maybe [] (\a -> ["--program-" ++ option, a])
22+
mkProgramName p s = maybe [] id p ++ "p" ++ maybe [] id s
23+
testAffixes commonOpts prefix suffix = do
24+
cabal "install" ( commonOpts
25+
++ mkAffixOption "prefix" prefix
26+
++ mkAffixOption "suffix" suffix)
27+
runInstalledExe (mkProgramName prefix suffix) []
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name: p
2+
version: 1.0
3+
build-type: Simple
4+
cabal-version: >= 1.2
5+
6+
executable p
7+
main-is: Main.hs
8+
build-depends: base

changelog.d/issue-9919

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
synopsis: Fix --program-suffix resulting in invalid installation
2+
packages: cabal-install
3+
issues: #8823 #9919
4+
prs: #10056

0 commit comments

Comments
 (0)