From af7a5e96f0d93e3b5f9db01146550df3800d0c06 Mon Sep 17 00:00:00 2001 From: Bodigrim Date: Sat, 16 May 2026 00:45:06 +0100 Subject: [PATCH] Decommission v1-register --gen-script and v1-unregister --gen-script The v1 commands `v1-register` and `v1-unregister` are obsolete by now, but even in their prime time - as witnessed by comments - their usage with `--gen-script` was not well attested or understood. Pruning this mode leads to surprising reduction of rather hairy code. By default `v1-register` just goes ahead and registers a package. It also has a mode `--gen-pkg-config` to generate a `.conf` file, which a user can manually register by running `ghc-pkg register`. Now `--gen-script` mode used to generate a shell script, which would run `ghc-pkg register` on the same `.conf` file (embedded). Why would anyone really want that? I have no idea and the comment quietly recognises that "In practice this aspect was not especially popular" and "The script generation [is] not well used or tested". The v2 commands never use `--gen-script` feature. The documentation (unchanged since 1658ad8bc0 in 2005) used to claim that package distributors should be using `register --gen-script` and `unregister --gen-script` to generate `register.sh` and `unregister.sh` to be included in their packages. This does not seem to reflect the reality. E. g., https://packages.debian.org/trixie/amd64/libghc-tasty-dev/filelist does not contain any shell scripts, only `tasty-*.conf` file. Same on Fedora: https://packages.fedoraproject.org/pkgs/ghc-tasty/ghc-tasty-devel/fedora-rawhide.html#files Indeed inspecting build logs such as https://kojipkgs.fedoraproject.org//packages/ghc-tasty/1.5.3/28.fc44/data/logs/x86_64/build.log confirms that package distributors use `v1-register --gen-pkg-config` and don't use `--gen-script`. --- Cabal/Cabal.cabal | 1 - .../src/Distribution/Simple/Program/Script.hs | 114 ------------------ Cabal/src/Distribution/Simple/Register.hs | 74 +----------- .../src/Distribution/Simple/Setup/Register.hs | 16 --- .../Distribution/Client/ProjectPlanning.hs | 1 - .../setup-gen-script.test.hs | 14 --- changelog.d/pr-11834.md | 8 ++ doc/setup-commands.rst | 30 +---- 8 files changed, 18 insertions(+), 240 deletions(-) delete mode 100644 Cabal/src/Distribution/Simple/Program/Script.hs delete mode 100644 cabal-testsuite/PackageTests/InternalLibraries/setup-gen-script.test.hs create mode 100644 changelog.d/pr-11834.md diff --git a/Cabal/Cabal.cabal b/Cabal/Cabal.cabal index c91d2c11d89..122e7282b4c 100644 --- a/Cabal/Cabal.cabal +++ b/Cabal/Cabal.cabal @@ -150,7 +150,6 @@ library Distribution.Simple.Program.Ld Distribution.Simple.Program.ResponseFile Distribution.Simple.Program.Run - Distribution.Simple.Program.Script Distribution.Simple.Program.Strip Distribution.Simple.Program.Types Distribution.Simple.Register diff --git a/Cabal/src/Distribution/Simple/Program/Script.hs b/Cabal/src/Distribution/Simple/Program/Script.hs deleted file mode 100644 index a967e656e5a..00000000000 --- a/Cabal/src/Distribution/Simple/Program/Script.hs +++ /dev/null @@ -1,114 +0,0 @@ -{-# LANGUAGE GADTs #-} - ------------------------------------------------------------------------------ - --- | --- Module : Distribution.Simple.Program.Script --- Copyright : Duncan Coutts 2009 --- --- Maintainer : cabal-devel@haskell.org --- Portability : portable --- --- This module provides an library interface to the @hc-pkg@ program. --- Currently only GHC and LHC have hc-pkg programs. -module Distribution.Simple.Program.Script - ( invocationAsSystemScript - , invocationAsShellScript - , invocationAsBatchFile - ) where - -import Distribution.Compat.Prelude -import Prelude () - -import Distribution.Simple.Program.Run -import Distribution.Simple.Utils -import Distribution.System - --- | Generate a system script, either POSIX shell script or Windows batch file --- as appropriate for the given system. -invocationAsSystemScript :: OS -> ProgramInvocation -> String -invocationAsSystemScript Windows = invocationAsBatchFile -invocationAsSystemScript _ = invocationAsShellScript - --- | Generate a POSIX shell script that invokes a program. -invocationAsShellScript :: ProgramInvocation -> String -invocationAsShellScript - ProgramInvocation - { progInvokePath = path - , progInvokeArgs = args - , progInvokeEnv = envExtra - , progInvokeCwd = mcwd - , progInvokeInput = minput - } = - unlines $ - ["#!/bin/sh"] - ++ concatMap setEnv envExtra - ++ ["cd " ++ quote cwd | cwd <- maybeToList mcwd] - ++ [ ( case minput of - Nothing -> "" - Just input -> "printf '%s' " ++ quote (iodataToText input) ++ " | " - ) - ++ unwords (map quote $ path : args) - ++ " \"$@\"" - ] - where - setEnv (var, Nothing) = ["unset " ++ var, "export " ++ var] - setEnv (var, Just val) = ["export " ++ var ++ "=" ++ quote val] - - quote :: String -> String - quote s = "'" ++ escape s ++ "'" - - escape [] = [] - escape ('\'' : cs) = "'\\''" ++ escape cs - escape (c : cs) = c : escape cs - -iodataToText :: IOData -> String -iodataToText (IODataText str) = str -iodataToText (IODataBinary lbs) = fromUTF8LBS lbs - --- | Generate a Windows batch file that invokes a program. -invocationAsBatchFile :: ProgramInvocation -> String -invocationAsBatchFile - ProgramInvocation - { progInvokePath = path - , progInvokeArgs = args - , progInvokeEnv = envExtra - , progInvokeCwd = mcwd - , progInvokeInput = minput - } = - unlines $ - ["@echo off"] - ++ map setEnv envExtra - ++ ["cd \"" ++ cwd ++ "\"" | cwd <- maybeToList mcwd] - ++ case minput of - Nothing -> - [unwords (path : args)] - Just input -> - ["("] - ++ ["echo " ++ escape line | line <- lines $ iodataToText input] - ++ [ ") | " - ++ "\"" - ++ path - ++ "\"" - ++ concatMap (\arg -> ' ' : quote arg) args - ] - where - setEnv (var, Nothing) = "set " ++ var ++ "=" - setEnv (var, Just val) = "set " ++ var ++ "=" ++ escape val - - quote :: String -> String - quote s = "\"" ++ escapeQ s ++ "\"" - - escapeQ [] = [] - escapeQ ('"' : cs) = "\"\"\"" ++ escapeQ cs - escapeQ (c : cs) = c : escapeQ cs - - escape [] = [] - escape ('|' : cs) = "^|" ++ escape cs - escape ('<' : cs) = "^<" ++ escape cs - escape ('>' : cs) = "^>" ++ escape cs - escape ('&' : cs) = "^&" ++ escape cs - escape ('(' : cs) = "^(" ++ escape cs - escape (')' : cs) = "^)" ++ escape cs - escape ('^' : cs) = "^^" ++ escape cs - escape (c : cs) = c : escape cs diff --git a/Cabal/src/Distribution/Simple/Register.hs b/Cabal/src/Distribution/Simple/Register.hs index 3e603a14d6a..b17fc1ba2ba 100644 --- a/Cabal/src/Distribution/Simple/Register.hs +++ b/Cabal/src/Distribution/Simple/Register.hs @@ -2,8 +2,6 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE RankNTypes #-} ------------------------------------------------------------------------------ - -- | -- Module : Distribution.Simple.Register -- Copyright : Isaac Jones 2003-2004 @@ -14,10 +12,7 @@ -- -- This module deals with registering and unregistering packages. There are a -- couple ways it can do this, one is to do it directly. Another is to generate --- a script that can be run later to do it. The idea here being that the user --- is shielded from the details of what command to use for package registration --- for a particular compiler. In practice this aspect was not especially --- popular so we also provide a way to simply generate the package registration +-- the package registration -- file which then must be manually passed to @ghc-pkg@. It is possible to -- generate registration information for where the package is to be installed, -- or alternatively to register the package in place in the build tree. The @@ -25,8 +20,8 @@ -- build multi-package systems. -- -- This module does not delegate anything to the per-compiler modules but just --- mixes it all in this module, which is rather unsatisfactory. The script --- generation and the unregister feature are not well used or tested. +-- mixes it all in this module, which is rather unsatisfactory. The +-- unregister feature is not well used or tested. module Distribution.Simple.Register ( register , registerWithHandles @@ -77,7 +72,6 @@ import Distribution.Simple.Errors import Distribution.Simple.Flag import Distribution.Simple.Program import qualified Distribution.Simple.Program.HcPkg as HcPkg -import Distribution.Simple.Program.Script import Distribution.Simple.Setup.Common import Distribution.Simple.Setup.Haddock (HaddockTarget (ForDevelopment)) import Distribution.Simple.Setup.Register @@ -90,8 +84,6 @@ import Distribution.Version import System.Directory import System.FilePath (isAbsolute) -import qualified Data.ByteString.Lazy.Char8 as BS.Char8 - -- ----------------------------------------------------------------------------- -- Registration @@ -197,7 +189,6 @@ registerAll verbHandles pkg lbi regFlags ipis = case () of _ | modeGenerateRegFile -> writeRegistrationFileOrDirectory - | modeGenerateRegScript -> writeRegisterScript | otherwise -> do for_ ipis $ \ipi -> do setupMessage' @@ -222,8 +213,6 @@ registerAll verbHandles pkg lbi regFlags ipis = (makeSymbolicPath (prettyShow (packageId pkg) <.> "conf")) (fromFlag (regGenPkgConf regFlags)) - modeGenerateRegScript = fromFlag (regGenScript regFlags) - -- FIXME: there's really no guarantee this will work. -- registering into a totally different db stack can -- fail if dependencies cannot be satisfied. @@ -233,7 +222,6 @@ registerAll verbHandles pkg lbi regFlags ipis = ++ maybeToList (flagToMaybe (regPackageDB regFlags)) common = registerCommonFlags regFlags verbosity = mkVerbosity verbHandles (fromFlag (setupVerbosity common)) - mbWorkDir = mbWorkDirLBI lbi writeRegistrationFileOrDirectory = do -- Handles overwriting both directory and file @@ -255,17 +243,6 @@ registerAll verbHandles pkg lbi regFlags ipis = (regFile (number i ++ "-" ++ prettyShow (IPI.installedUnitId installedPkgInfo))) (IPI.showInstalledPackageInfo installedPkgInfo) - writeRegisterScript = - case compilerFlavor (compiler lbi) of - UHC -> notice verbosity "Registration scripts not needed for uhc" - _ -> - withHcPkg - verbosity - "Registration scripts are not implemented for this compiler" - (compiler lbi) - (withPrograms lbi) - (writeHcPkgRegisterScript verbosity mbWorkDir ipis packageDbs) - generateRegistrationInfo :: Verbosity -> PackageDescription @@ -449,38 +426,6 @@ registerPackage verbosity comp progdb mbWorkDir packageDbs installedPkgInfo regi UHC -> UHC.registerPackage verbosity mbWorkDir comp progdb packageDbs installedPkgInfo _ -> dieWithException verbosity RegisteringNotImplemented -writeHcPkgRegisterScript - :: Verbosity - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> [InstalledPackageInfo] - -> PackageDBStack - -> HcPkg.ConfiguredProgram - -> IO () -writeHcPkgRegisterScript verbosity mbWorkDir ipis packageDbs hpi = do - let genScript installedPkgInfo = - let invocation = - HcPkg.registerInvocation - hpi - Verbosity.Normal - mbWorkDir - packageDbs - installedPkgInfo - HcPkg.defaultRegisterOptions - in invocationAsSystemScript buildOS invocation - scripts = map genScript ipis - -- TODO: Do something more robust here - regScript = unlines scripts - - let out_file = interpretSymbolicPath mbWorkDir regScriptFileName - info verbosity ("Creating package registration script: " ++ out_file) - writeUTF8File out_file regScript - setFileExecutable out_file - -regScriptFileName :: SymbolicPath Pkg File -regScriptFileName = case buildOS of - Windows -> makeSymbolicPath "register.bat" - _ -> makeSymbolicPath "register.sh" - -- ----------------------------------------------------------------------------- -- Making the InstalledPackageInfo @@ -730,7 +675,6 @@ unregisterWithHandles :: VerbosityHandles -> PackageDescription -> LocalBuildInf unregisterWithHandles verbHandles pkg lbi regFlags = do let pkgid = packageId pkg common = registerCommonFlags regFlags - genScript = fromFlag (regGenScript regFlags) verbosity = mkVerbosity verbHandles (fromFlag (setupVerbosity common)) packageDb = fromFlagOrDefault @@ -745,12 +689,7 @@ unregisterWithHandles verbHandles pkg lbi regFlags = do mbWorkDir packageDb pkgid - in if genScript - then - writeFileAtomic - unregScriptFileName - (BS.Char8.pack $ invocationAsSystemScript buildOS invocation) - else runProgramInvocation verbosity invocation + in runProgramInvocation verbosity invocation setupMessage verbosity "Unregistering" pkgid withHcPkg verbosity @@ -759,11 +698,6 @@ unregisterWithHandles verbHandles pkg lbi regFlags = do (withPrograms lbi) unreg -unregScriptFileName :: FilePath -unregScriptFileName = case buildOS of - Windows -> "unregister.bat" - _ -> "unregister.sh" - internalPackageDBPath :: LocalBuildInfo -> SymbolicPath Pkg (Dir Dist) -> SymbolicPath Pkg (Dir PkgDB) internalPackageDBPath lbi distPref = case compilerFlavor (compiler lbi) of diff --git a/Cabal/src/Distribution/Simple/Setup/Register.hs b/Cabal/src/Distribution/Simple/Setup/Register.hs index 9a6b839594d..7fff42de784 100644 --- a/Cabal/src/Distribution/Simple/Setup/Register.hs +++ b/Cabal/src/Distribution/Simple/Setup/Register.hs @@ -53,7 +53,6 @@ import Distribution.Verbosity data RegisterFlags = RegisterFlags { registerCommonFlags :: !CommonSetupFlags , regPackageDB :: Flag PackageDB - , regGenScript :: Flag Bool , regGenPkgConf :: Flag (Maybe (SymbolicPath Pkg (Dir PkgConf))) , regInPlace :: Flag Bool , regPrintId :: Flag Bool @@ -89,7 +88,6 @@ defaultRegisterFlags = RegisterFlags { registerCommonFlags = defaultCommonSetupFlags , regPackageDB = NoFlag - , regGenScript = Flag False , regGenPkgConf = NoFlag , regInPlace = Flag False , regPrintId = Flag False @@ -137,13 +135,6 @@ registerCommand = regInPlace (\v flags -> flags{regInPlace = v}) trueArg - , option - "" - ["gen-script"] - "instead of registering, generate a script to register later" - regGenScript - (\v flags -> flags{regGenScript = v}) - trueArg , option "" ["gen-pkg-config"] @@ -196,13 +187,6 @@ unregisterCommand = ) ] ) - , option - "" - ["gen-script"] - "Instead of performing the unregister command, generate a script to unregister later" - regGenScript - (\v flags -> flags{regGenScript = v}) - trueArg ] } diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 5be55634324..8ba32c9323f 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -4343,7 +4343,6 @@ setupHsRegisterFlags Cabal.RegisterFlags { registerCommonFlags = common , regPackageDB = mempty -- misfeature - , regGenScript = mempty -- never use , regGenPkgConf = toFlag (Just (makeSymbolicPath pkgConfFile)) , regInPlace = case elabBuildStyle of BuildInplaceOnly{} -> toFlag True diff --git a/cabal-testsuite/PackageTests/InternalLibraries/setup-gen-script.test.hs b/cabal-testsuite/PackageTests/InternalLibraries/setup-gen-script.test.hs deleted file mode 100644 index ada96fc159a..00000000000 --- a/cabal-testsuite/PackageTests/InternalLibraries/setup-gen-script.test.hs +++ /dev/null @@ -1,14 +0,0 @@ -import Test.Cabal.Prelude --- Test to see if --gen-script -main = setupAndCabalTest $ do - withPackageDb $ do - withDirectory "p" $ do - setup_build [] - setup "copy" [] - setup "register" ["--gen-script"] - _ <- if isWindows - then shell "cmd" ["/C", "register.bat"] - else shell "sh" ["register.sh"] - return () - -- Make sure we can see p - withDirectory "r" $ setup_install [] diff --git a/changelog.d/pr-11834.md b/changelog.d/pr-11834.md new file mode 100644 index 00000000000..f0b6f01922a --- /dev/null +++ b/changelog.d/pr-11834.md @@ -0,0 +1,8 @@ +--- +synopsis: Decommission `v1-register --gen-script` and `v1-unregister --gen-script` +packages: [Cabal,cabal-install] +prs: 11834 +significance: significant +--- + +Command line interface `cabal v1-register --gen-script` and `cabal v1-unregister --gen-script` as well as corresponding `./Setup register --gen-script` and `./Setup unregister --gen-script` are decommissioned. Instead of `cabal v1-register --gen-script` one can generate a package config file with `register --gen-pkg-config` and register it with `ghc-pkg register`. Instead of `cabal v1-unregister --gen-script` just run `ghc-pkg unregister`. diff --git a/doc/setup-commands.rst b/doc/setup-commands.rst index 3873fb5f613..fef82de2a96 100644 --- a/doc/setup-commands.rst +++ b/doc/setup-commands.rst @@ -57,18 +57,16 @@ root directory: $ runhaskell Setup.hs copy --destdir=/tmp/mypkg $ tar -czf mypkg.tar.gz /tmp/mypkg/ -If the package contains a library, you need two additional steps: +If the package contains a library, you need an additional step: :: - $ runhaskell Setup.hs register --gen-script - $ runhaskell Setup.hs unregister --gen-script + $ runhaskell Setup.hs register --gen-pkg-config -This creates shell scripts ``register.sh`` and ``unregister.sh``, which +This creates a configuration file ``mypkg.conf`` which must also be sent to the target system. After unpacking there, the -package must be registered by running the ``register.sh`` script. The -``unregister.sh`` script would be used in the uninstall procedure of the -package. Similar steps may be used for creating binary packages for +package must be registered by running the ``ghc-pkg register mypkg.conf``. +Similar steps may be used for creating binary packages for Windows. The following options are understood by all commands: @@ -1292,14 +1290,6 @@ This command takes the following options: Register this package in the user's local package database. -.. option:: --gen-script - - Instead of registering the package, generate a script containing - commands to perform the registration. On Unix, this file is called - ``register.sh``, on Windows, ``register.bat``. This script might be - included in a binary bundle, to be run after the bundle is unpacked - on the target system. - .. option:: --gen-pkg-config[=path] Instead of registering the package, generate a package registration @@ -1307,8 +1297,7 @@ This command takes the following options: compilers that support package registration files which at the moment is only GHC. The file should be used with the compiler's mechanism for registering packages. This option is mainly intended - for packaging systems. If possible use the :option:`--gen-script` option - instead since it is more portable across Haskell implementations. + for packaging systems. The *path* is optional and can be used to specify a particular output file to generate. Otherwise, by default the file is the package name and version with a ``.conf`` extension. @@ -1353,13 +1342,6 @@ This command takes the following options: Deregister this package in the user's local package database. -.. option:: --gen-script - - Instead of deregistering the package, generate a script containing - commands to perform the deregistration. On Unix, this file is called - ``unregister.sh``, on Windows, ``unregister.bat``. This script might - be included in a binary bundle, to be run on the target system. - .. _setup-clean: runhaskell Setup.hs clean