Skip to content

Commit

Permalink
Fix --program-{prefix,suffix} resulting in invalid installation
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
wismill authored and Mikolaj committed Jun 2, 2024
1 parent 6f1329b commit 8593474
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 1 deletion.
14 changes: 13 additions & 1 deletion cabal-install/src/Distribution/Client/CmdInstall.hs
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ installAction flags@NixStyleFlags{extraFlags, configFlags, installFlags, project
-- BuildOutcomes because we also need the component names
traverseInstall (installCheckUnitExes InstallCheckInstall) installCfg
where
configFlags' = disableTestsBenchsByDefault configFlags
configFlags' = disableTestsBenchsByDefault . ignoreProgramAffixes $ configFlags
verbosity = fromFlagOrDefault normal (setupVerbosity $ configCommonFlags configFlags')
ignoreProject = flagIgnoreProject projectFlags
cliConfig =
Expand Down Expand Up @@ -1101,6 +1101,18 @@ disableTestsBenchsByDefault configFlags =
, configBenchmarks = Flag False <> configBenchmarks configFlags
}

-- | Disables program prefix and suffix, in order to get the /canonical/
-- executable name in the store and thus:
--
-- * avoid making the package hash depend on these options and needless rebuild;
-- * provide the correct executable path to the install methods (copy, symlink).
ignoreProgramAffixes :: ConfigFlags -> ConfigFlags
ignoreProgramAffixes configFlags =
configFlags
{ configProgPrefix = NoFlag
, configProgSuffix = NoFlag
}

-- | Prepares a record containing the information needed to either symlink or
-- copy an executable.
symlink :: OverwritePolicy -> InstallExe -> UnitId -> UnqualComponentName -> Symlink
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
main = pure ()
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
packages: .
27 changes: 27 additions & 0 deletions cabal-testsuite/PackageTests/Install/ProgramAffixes/cabal.test.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Test.Cabal.Prelude
import Data.Foldable (traverse_)

-- Test that program affixes options result in successful installation:
-- • Valid symlinks (--install-method=symlink)
-- • Valid copy of executables (--install-method=copy)
main = cabalTest $ do
env <- getTestEnv
recordMode DoNotRecord $ do
let installdir = testPrefixDir env </> "bin"
commonOpts = ["p", "--installdir", installdir, "--overwrite-policy=always"]
testAllAffixes installMethod = do
let testAffixes' = testAffixes
(commonOpts ++ ["--install-method", installMethod])
testAffixes' Nothing Nothing
testAffixes' (Just "a-") Nothing
testAffixes' Nothing (Just "-z")
testAffixes' (Just "a-") (Just "-z")
traverse_ testAllAffixes ["symlink", "copy"]
where
mkAffixOption option = maybe [] (\a -> ["--program-" ++ option, a])
mkProgramName p s = maybe [] id p ++ "p" ++ maybe [] id s
testAffixes commonOpts prefix suffix = do
cabal "install" ( commonOpts
++ mkAffixOption "prefix" prefix
++ mkAffixOption "suffix" suffix)
runInstalledExe (mkProgramName prefix suffix) []
8 changes: 8 additions & 0 deletions cabal-testsuite/PackageTests/Install/ProgramAffixes/p.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: p
version: 1.0
build-type: Simple
cabal-version: >= 1.2

executable p
main-is: Main.hs
build-depends: base
4 changes: 4 additions & 0 deletions changelog.d/issue-9919
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
synopsis: Fix --program-suffix resulting in invalid installation
packages: cabal-install
issues: #8823 #9919
prs: #10056

0 comments on commit 8593474

Please sign in to comment.