Skip to content

Commit 639928f

Browse files
mergify[bot]wismillulysses4ever
authored
Fix --program-suffix resulting in invalid symlink (backport #10056) (#10079)
* 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. (cherry picked from commit 8593474) # Conflicts: # cabal-install/src/Distribution/Client/CmdInstall.hs * fixup! resolve conflicts --------- Co-authored-by: Pierre Le Marre <[email protected]> Co-authored-by: Artem Pelenitsyn <[email protected]> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent 42b93b7 commit 639928f

File tree

6 files changed

+54
-1
lines changed

6 files changed

+54
-1
lines changed

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

+13-1
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ installAction flags@NixStyleFlags{extraFlags, configFlags, installFlags, project
538538
-- BuildOutcomes because we also need the component names
539539
traverseInstall (installCheckUnitExes InstallCheckInstall) installCfg
540540
where
541-
configFlags' = disableTestsBenchsByDefault configFlags
541+
configFlags' = disableTestsBenchsByDefault . ignoreProgramAffixes $ configFlags
542542
verbosity = fromFlagOrDefault normal (configVerbosity configFlags')
543543
ignoreProject = flagIgnoreProject projectFlags
544544
cliConfig =
@@ -1099,6 +1099,18 @@ disableTestsBenchsByDefault configFlags =
10991099
, configBenchmarks = Flag False <> configBenchmarks configFlags
11001100
}
11011101

1102+
-- | Disables program prefix and suffix, in order to get the /canonical/
1103+
-- executable name in the store and thus:
1104+
--
1105+
-- * avoid making the package hash depend on these options and needless rebuild;
1106+
-- * provide the correct executable path to the install methods (copy, symlink).
1107+
ignoreProgramAffixes :: ConfigFlags -> ConfigFlags
1108+
ignoreProgramAffixes configFlags =
1109+
configFlags
1110+
{ configProgPrefix = NoFlag
1111+
, configProgSuffix = NoFlag
1112+
}
1113+
11021114
-- | Prepares a record containing the information needed to either symlink or
11031115
-- copy an executable.
11041116
symlink :: OverwritePolicy -> InstallExe -> UnitId -> UnqualComponentName -> Symlink
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
main = pure ()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
packages: .
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) []
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

+4
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)