Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions cabal-install/src/Distribution/Client/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -372,17 +372,20 @@ mainWorker args = do
-> [String]
-> IO (CommandParse Action)
delegateToExternal commands' name cmdArgs = do
-- we rely on cabal's implementation of findProgramOnSearchPath not following
-- symlinks here. If that ever happens, then the argv[0] of the called executable
-- will be different to the intended one and will break tools that work by reading it.
mCommand <- findProgramOnSearchPath normal defaultProgramSearchPath ("cabal-" <> name)
case mCommand of
Just (exec, _) -> return (CommandReadyToGo $ \_ -> callExternal exec name cmdArgs)
Just (exec, _) -> return (CommandReadyToGo $ \_ -> callExternal exec cmdArgs)
Nothing -> defaultCommandFallback commands' name cmdArgs

callExternal :: String -> String -> [String] -> IO ()
callExternal exec name cmdArgs = do
callExternal :: String -> [String] -> IO ()
callExternal exec cmdArgs = do
cur_env <- getEnvironment
cabal_exe <- getExecutablePath
let new_env = ("CABAL", cabal_exe) : cur_env
result <- try $ createProcess ((proc exec (name : cmdArgs)){env = Just new_env})
result <- try $ createProcess ((proc exec cmdArgs){env = Just new_env})
case result of
Left ex -> printErrors ["Error executing external command: " ++ show (ex :: SomeException)]
Right (_, _, _, ph) -> waitForProcess ph >>= exitWith
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ import System.Environment
main = do
args <- getArgs
case args of
["aaaa" , "--help"] -> putStrLn "I am helping with the aaaa command"
["--help"] -> putStrLn "I am helping with the aaaa command"
_ -> putStrLn "aaaa"
19 changes: 19 additions & 0 deletions changelog.d/pr-11232.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
synopsis: don't pass exe name to external commands
packages: [cabal-install]
prs: 11232
issues: [10275]
significance: significant
---

Previously the executable name of the external command was passed to external commands as the first argument.

This behaviour was adapted from cargo which does this because of reasons that are internal to rust that do not affect GHC Haskell, and are even orthogonal to patterns that see common use in Haskell.

Additionally, it complicates the 'simple' case which is what we should optimize for when building such a feature - with this change, for any executable `cabal-foo` in your search-path, `cabal foo` will be a valid invocation of that command.

The previous use case (one executable that serves multiple external subcommands) is still possible by the following means:

- using a wrapper around the executable
- using a symlink and check argv\[0\] in the executable

Loading