From 23c078516c3774ecddc50496fabd3009ad540c1e Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Thu, 14 Aug 2025 20:06:23 +0200 Subject: [PATCH 1/2] Update Cabal logo --- Cabal-light.png | Bin 0 -> 11776 bytes README.md | 2 +- doc/images/Cabal-dark.png | Bin 7086 -> 12032 bytes 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 Cabal-light.png diff --git a/Cabal-light.png b/Cabal-light.png new file mode 100644 index 0000000000000000000000000000000000000000..4563a65a7869a72d4930fe78d0c08ca3bc001566 GIT binary patch literal 11776 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 fytE0s!QjvR< + This Cabal Git repository contains the following main packages: diff --git a/doc/images/Cabal-dark.png b/doc/images/Cabal-dark.png index aa599f84bb5ae3d44cf5f3701c0d9209cc5a71a1..2e0a105c5be84c992aba649ecc0f2bedce5865be 100644 GIT binary patch literal 12032 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 S0CcwBl9g0?Q!f7Q^Zy53mDoZ6 literal 7086 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 Y|MpC<4~P}i^8f$<07*qoM6N<$g3s8U?EnA( From 72c1ee4974491b17e83fa50289bbfff70d2b8d2f Mon Sep 17 00:00:00 2001 From: mangoiv Date: Wed, 1 Oct 2025 18:16:40 +0200 Subject: [PATCH 2/2] cabal-install: don't pass exe name to external commands Previously the executable name of the external command was passed to external commands as the first argument. This behaviour was adapated 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. 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 Additionally, the variable `$CABAL` that was set by `cabal-install` was renamed to `CABAL_EXTERNAL_CABAL_PATH`. This has two reasons: 1. it makes migration easier for users of the external command feature that were previously expecting the name of the executable to appear in `argv[1]` 2. it does not unnecessarily pollute the environment variable namespace as it turns out some other tools have been and are already using this name, historically Resolves #10275 --- cabal-install/src/Distribution/Client/Main.hs | 13 ++++++---- .../ExternalCommand/cabal.test.hs | 1 - .../ExternalCommandEnv/setup-test/AAAA.hs | 2 +- .../ExternalCommandExitCode/cabal.test.hs | 1 - .../ExternalCommandHelp/setup-test/AAAA.hs | 2 +- changelog.d/pr-11232.md | 24 +++++++++++++++++++ doc/external-commands.rst | 16 +++++++++---- 7 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 changelog.d/pr-11232.md diff --git a/cabal-install/src/Distribution/Client/Main.hs b/cabal-install/src/Distribution/Client/Main.hs index 01dd3edaa23..be0ab581c00 100644 --- a/cabal-install/src/Distribution/Client/Main.hs +++ b/cabal-install/src/Distribution/Client/Main.hs @@ -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 from 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}) + let new_env = ("CABAL_EXTERNAL_CABAL_PATH", cabal_exe) : cur_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 diff --git a/cabal-testsuite/PackageTests/ExternalCommand/cabal.test.hs b/cabal-testsuite/PackageTests/ExternalCommand/cabal.test.hs index b6a06678990..69319db30ca 100644 --- a/cabal-testsuite/PackageTests/ExternalCommand/cabal.test.hs +++ b/cabal-testsuite/PackageTests/ExternalCommand/cabal.test.hs @@ -17,7 +17,6 @@ main = do addToPath (takeDirectory exe_path) $ do -- Test that the thing works at all res <- cabal_raw_action ["aaaa"] (\h -> () <$ Process.waitForProcess h) - assertOutputContains "aaaa" res -- Test that the extra arguments are passed on res <- cabal_raw_action ["aaaa", "--foobaz"] (\h -> () <$ Process.waitForProcess h) diff --git a/cabal-testsuite/PackageTests/ExternalCommandEnv/setup-test/AAAA.hs b/cabal-testsuite/PackageTests/ExternalCommandEnv/setup-test/AAAA.hs index 99af61e9c03..2bb2cea11f3 100644 --- a/cabal-testsuite/PackageTests/ExternalCommandEnv/setup-test/AAAA.hs +++ b/cabal-testsuite/PackageTests/ExternalCommandEnv/setup-test/AAAA.hs @@ -4,7 +4,7 @@ import System.Environment import System.Process main = do - cabal_proc <- getEnv "CABAL" + cabal_proc <- getEnv "CABAL_EXTERNAL_CABAL_PATH" other_var <- getEnv "OTHER_VAR" putStrLn ("OTHER_VAR is set to: " ++ other_var) callProcess cabal_proc ["--version"] diff --git a/cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.test.hs b/cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.test.hs index 7fc79d75815..a9ba8972e3f 100644 --- a/cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.test.hs +++ b/cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.test.hs @@ -18,7 +18,6 @@ main = do addToPath (takeDirectory exe_path) $ do -- Test that the thing works at all res <- fails $ cabal_raw_action ["aaaa"] (\h -> () <$ Process.waitForProcess h) - assertOutputContains "aaaa" res -- Check the exit code is the one returned by subcommand unless (resultExitCode res == ExitFailure 99) (assertFailure $ "Incorrect exit code: " ++ show (resultExitCode res)) diff --git a/cabal-testsuite/PackageTests/ExternalCommandHelp/setup-test/AAAA.hs b/cabal-testsuite/PackageTests/ExternalCommandHelp/setup-test/AAAA.hs index dd139b905da..10fe05988d8 100644 --- a/cabal-testsuite/PackageTests/ExternalCommandHelp/setup-test/AAAA.hs +++ b/cabal-testsuite/PackageTests/ExternalCommandHelp/setup-test/AAAA.hs @@ -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" diff --git a/changelog.d/pr-11232.md b/changelog.d/pr-11232.md new file mode 100644 index 00000000000..4d65d82ecd5 --- /dev/null +++ b/changelog.d/pr-11232.md @@ -0,0 +1,24 @@ +--- +synopsis: Don't pass the executable 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 + +Additionally, the variable `$CABAL` that was set by `cabal-install` was renamed to `CABAL_EXTERNAL_CABAL_PATH`. This has two reasons: +1. it makes migration easier for users of the external command feature that were previously expecting the name of the executable + to appear in `argv[1]` +2. it does not unnecessarily pollute the environment variable namespace as it turns out some other tools have been and are already + using this name, historically diff --git a/doc/external-commands.rst b/doc/external-commands.rst index eca76483cc1..9ca74dcbb15 100644 --- a/doc/external-commands.rst +++ b/doc/external-commands.rst @@ -3,19 +3,27 @@ External Commands ``cabal-install`` provides a system for external commands, akin to the ones used by tools like ``git`` or ``cargo``. -If you execute ``cabal ``, ``cabal-install`` will search the path for an executable named ``cabal-`` and execute it. The name of the command is passed as the first argument and -the remaining arguments are passed afterwards. An error will be thrown in case the custom command is not found. The exit code of cabal when calling an external command is the same as the exit code +If you execute ``cabal ``, ``cabal-install`` will search the path for an executable named ``cabal-`` and execute it. An error will be thrown in case the custom command is not found. The exit code of cabal when calling an external command is the same as the exit code of the command. -The ``$CABAL`` environment variable is set to the path of the ``cabal-install`` executable +The name of the command is *not* passed as the first argument as is done in ``cargo``, instead you will have to figure out the name via `argv[0]` as +is the case in e.g. `git`. + +The ``$CABAL_EXTERNAL_CABAL_PATH`` environment variable is set to the path of the ``cabal-install`` executable which invoked the subcommand. It is strongly recommended that you implement your custom commands by calling the -CLI via the ``$CABAL`` variable rather than linking against the ``Cabal`` library. +CLI via the ``$CABAL_EXTERNAL_CABAL_PATH`` variable rather than linking against the ``Cabal`` library. There is no guarantee that the subcommand will link against the same version of the ``Cabal`` library as ``cabal-install`` so it would lead to unexpected results and incompatibilities. +Historically, the `cabal-install` binary would pass the name of the executable which it is trying to invoke via the external command feature as +the first argument to the executable itself. The main difference was that ``$CABAL_EXTERNAL_CABAL_PATH`` was called ``$CABAL``, which means that +you can stay compatible with both versions, depending on which variable is set. + +Mind that if you were implementing external commands previously, you will not need to skip the first argument (the executable name) anymore. + ``cabal-install`` can also display the help message of the external command. When ``cabal help `` is invoked, then ``cabal- --help`` will be called so your external command can display a help message.