From 8fe6122df565497d56df58187ca05c24c263339a Mon Sep 17 00:00:00 2001 From: Artem Pelenitsyn Date: Mon, 10 Jun 2024 16:09:18 -0400 Subject: [PATCH 001/207] CI: dogfooding should run on the same Mac runner as validate (#10101) --- .github/workflows/validate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 71c0246b6fc..a34023d2d9e 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -343,7 +343,7 @@ jobs: needs: validate strategy: matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-13, windows-latest] # We only use one ghc version the used one for the next release (defined at top of the workflow) # We need to build an array dynamically to inject the appropiate env var in a previous job, # see https://docs.github.com/en/actions/learn-github-actions/expressions#fromjson From 9af466dd55390cebdf48eae5bbfdfd6464ff9591 Mon Sep 17 00:00:00 2001 From: Mango The Fourth <40720523+MangoIV@users.noreply.github.com> Date: Wed, 12 Jun 2024 23:16:42 +0200 Subject: [PATCH 002/207] add the applicable new (version 9.10) GHC flags to normaliseGhcArgs (#10014) * add the applicable new (versions 9.2 - 9.10) GHC flags to normaliseGhcArgs Actionable flags are: - fdiagnostics-as-json (changes the format GHC outputs its diagnostics) - fprint-error-index-lists (changes the way GHC displays compile time) - fbreak-points (enables/disables break-points in GHCi) - dipe-stats (dumps information about which info tables have IPE information) - ffamily-application-cache (only changes the speed of the compiler) - fprint-redundant-promotion-ticks - show-error-context - unoptimized-core-for-interpreter (only applies to GHCi) * [chore] correct the flag names and add a FUTUREWORK --- Cabal/src/Distribution/Simple/Program.hs | 7 +++++ Cabal/src/Distribution/Simple/Program/GHC.hs | 31 +++++++++++++++++--- changelog.d/pr-10014 | 11 +++++++ 3 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 changelog.d/pr-10014 diff --git a/Cabal/src/Distribution/Simple/Program.hs b/Cabal/src/Distribution/Simple/Program.hs index f5a609f3b7e..e81501d2c39 100644 --- a/Cabal/src/Distribution/Simple/Program.hs +++ b/Cabal/src/Distribution/Simple/Program.hs @@ -1,3 +1,10 @@ +{- FUTUREWORK: + - + - Currently the logic in this module is not tested. + - + - Ideally, a set of unit tests that check whether certain + - flags trigger recompilation should be added. + - -} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE RankNTypes #-} diff --git a/Cabal/src/Distribution/Simple/Program/GHC.hs b/Cabal/src/Distribution/Simple/Program/GHC.hs index 84d6b0ccfaa..c42eb18e3b1 100644 --- a/Cabal/src/Distribution/Simple/Program/GHC.hs +++ b/Cabal/src/Distribution/Simple/Program/GHC.hs @@ -1,6 +1,7 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE MultiWayIf #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -227,8 +228,27 @@ normaliseGhcArgs (Just ghcVersion) PackageDescription{..} ghcArgs , "keep-going" -- try harder, the build will still fail if it's erroneous , "print-axiom-incomps" -- print more debug info for closed type families ] + , from + [9, 2] + [ "family-application-cache" + ] + , from + [9, 6] + [ "print-redundant-promotion-ticks" + , "show-error-context" + ] + , from + [9, 8] + [ "unoptimized-core-for-interpreter" + ] + , from + [9, 10] + [ "diagnostics-as-json" + , "print-error-index-links" + , "break-points" + ] ] - , flagIn . invertibleFlagSet "-d" $ ["ppr-case-as-let", "ppr-ticks"] + , flagIn $ invertibleFlagSet "-d" ["ppr-case-as-let", "ppr-ticks"] , isOptIntFlag , isIntFlag , if safeToFilterWarnings @@ -289,6 +309,7 @@ normaliseGhcArgs (Just ghcVersion) PackageDescription{..} ghcArgs , from [8, 6] ["-dhex-word-literals"] , from [8, 8] ["-fshow-docs-of-hole-fits", "-fno-show-docs-of-hole-fits"] , from [9, 0] ["-dlinear-core-lint"] + , from [9, 10] ["-dipe-stats"] ] isOptIntFlag :: String -> Any @@ -709,7 +730,10 @@ renderGhcOptions comp _platform@(Platform _arch os) opts | flagProfAuto implInfo -> ["-fprof-auto-exported"] | otherwise -> ["-auto"] , ["-split-sections" | flagBool ghcOptSplitSections] - , ["-split-objs" | flagBool ghcOptSplitObjs] + , case compilerCompatVersion GHC comp of + -- the -split-objs flag was removed in GHC 9.8 + Just ver | ver >= mkVersion [9, 8] -> [] + _ -> ["-split-objs" | flagBool ghcOptSplitObjs] , case flagToMaybe (ghcOptHPCDir opts) of Nothing -> [] Just hpcdir -> ["-fhpc", "-hpcdir", u hpcdir] @@ -799,8 +823,7 @@ renderGhcOptions comp _platform@(Platform _arch os) opts -- Packages concat - [ [ case () of - _ + [ [ if | unitIdSupported comp -> "-this-unit-id" | packageKeySupported comp -> "-this-package-key" | otherwise -> "-package-name" diff --git a/changelog.d/pr-10014 b/changelog.d/pr-10014 new file mode 100644 index 00000000000..541b4c72d18 --- /dev/null +++ b/changelog.d/pr-10014 @@ -0,0 +1,11 @@ +synopsis: Update ghc args normalization and ghc option rendering +packages: Cabal +issues: #9729 +prs: #10014 + +description: { + +The flags -fdiagnostics-as-json, -fprint-error-index-lists, -fbreak-points, -dipe-stats, -ffamily-application-cache, -fprint-redundant-promotion-ticks, -fshow-error-context and -funoptimized-core-for-interpreter have been added to the flags that do not cause recompilation. + +--{enable,disable}-split-objs is not shown on in the helper for GHC >= 9.8 +} From 7e47c6d76143a290d9ddce0c06dcaed35d40d012 Mon Sep 17 00:00:00 2001 From: Adam Gundry Date: Thu, 13 Jun 2024 02:52:12 +0100 Subject: [PATCH 003/207] solver: Prevent ghc-internal from being reinstalled (see #10087) (#10093) GHC 9.10 ships with a new wired-in package, ghc-internal, which cannot be reinstalled. This commit prevents cabal-install from attempting it. Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- cabal-install/src/Distribution/Client/Dependency.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index 66a0a103c23..3f6a7fea32a 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -463,6 +463,7 @@ nonReinstallablePackages :: [PackageName] nonReinstallablePackages = [ mkPackageName "base" , mkPackageName "ghc-bignum" + , mkPackageName "ghc-internal" , mkPackageName "ghc-prim" , mkPackageName "ghc" , mkPackageName "integer-gmp" From a26db4ff5ae9ecdfe259a570f76176bb690a2786 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Tue, 21 May 2024 11:55:22 -0400 Subject: [PATCH 004/207] update requests per CVE-2024-35195 --- doc/requirements.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/requirements.in b/doc/requirements.in index 1c3ee5b9fd9..f0514fb5581 100644 --- a/doc/requirements.in +++ b/doc/requirements.in @@ -12,3 +12,5 @@ urllib3 >= 2.0.7 jinja2 >= 3.1.4 # CVE-2024-3651 idna >= 3.7 +# CVE-2024-35195 +requests >= 2.32.0 From da53b525a3b0d38e12f88e5f5e3836465a42e724 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Fri, 14 Jun 2024 15:56:21 +0100 Subject: [PATCH 005/207] external commands: Wait for process to finish before exiting (#10100) Issue #10063 points out that cabal exits before the external command has finished executing. This was a simple oversight to not waitForProcess on the result of calling createProcess. This also points out the flaw that there isn't a way for external commands to signal failure, so we now also propagate the exit code from the external process. Fixes #10063 --- cabal-install/src/Distribution/Client/Main.hs | 4 +- .../ExternalCommandExitCode/cabal.out | 8 ++++ .../ExternalCommandExitCode/cabal.project | 1 + .../ExternalCommandExitCode/cabal.test.hs | 38 +++++++++++++++++++ .../setup-test/AAAA.hs | 8 ++++ .../setup-test/CHANGELOG.md | 5 +++ .../setup-test/LICENSE | 30 +++++++++++++++ .../setup-test/setup-test.cabal | 25 ++++++++++++ changelog.d/issue-10063 | 14 +++++++ doc/external-commands.rst | 3 +- 10 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.out create mode 100644 cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.project create mode 100644 cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.test.hs create mode 100644 cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/AAAA.hs create mode 100644 cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/CHANGELOG.md create mode 100644 cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/LICENSE create mode 100644 cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/setup-test.cabal create mode 100644 changelog.d/issue-10063 diff --git a/cabal-install/src/Distribution/Client/Main.hs b/cabal-install/src/Distribution/Client/Main.hs index de14fc129c9..c1975e83094 100644 --- a/cabal-install/src/Distribution/Client/Main.hs +++ b/cabal-install/src/Distribution/Client/Main.hs @@ -275,7 +275,7 @@ import System.IO , stderr , stdout ) -import System.Process (createProcess, env, proc) +import System.Process (createProcess, env, proc, waitForProcess) -- | Entry point -- @@ -383,7 +383,7 @@ mainWorker args = do result <- try $ createProcess ((proc exec (name : cmdArgs)){env = Just new_env}) case result of Left ex -> printErrors ["Error executing external command: " ++ show (ex :: SomeException)] - Right _ -> return () + Right (_, _, _, ph) -> waitForProcess ph >>= exitWith printCommandHelp help = do pname <- getProgName diff --git a/cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.out b/cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.out new file mode 100644 index 00000000000..1c4c24db55c --- /dev/null +++ b/cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.out @@ -0,0 +1,8 @@ +# cabal v2-build +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - setup-test-0.1.0.0 (exe:cabal-aaaa) (first run) +Configuring executable 'cabal-aaaa' for setup-test-0.1.0.0... +Preprocessing executable 'cabal-aaaa' for setup-test-0.1.0.0... +Building executable 'cabal-aaaa' for setup-test-0.1.0.0... diff --git a/cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.project b/cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.project new file mode 100644 index 00000000000..1a33bb5a25e --- /dev/null +++ b/cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.project @@ -0,0 +1 @@ +packages: setup-test/ diff --git a/cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.test.hs b/cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.test.hs new file mode 100644 index 00000000000..7fc79d75815 --- /dev/null +++ b/cabal-testsuite/PackageTests/ExternalCommandExitCode/cabal.test.hs @@ -0,0 +1,38 @@ +import Test.Cabal.Prelude +import qualified System.Process as Process +import Control.Concurrent (threadDelay) +import System.Directory (removeFile) +import Control.Exception (catch, throwIO) +import System.IO.Error (isDoesNotExistError) +import qualified Data.Time.Clock as Time +import qualified Data.Time.Format as Time +import Data.Maybe +import System.Environment +import System.FilePath +import System.Exit + +main = do + cabalTest $ do + res <- cabalWithStdin "v2-build" ["all"] "" + exe_path <- withPlan $ planExePath "setup-test" "cabal-aaaa" + 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)) + + +cabal_raw_action :: [String] -> (Process.ProcessHandle -> IO ()) -> TestM Result +cabal_raw_action args action = do + configured_prog <- requireProgramM cabalProgram + env <- getTestEnv + r <- liftIO $ runAction (testVerbosity env) + (Just $ testCurrentDir env) + (testEnvironment env) + (programPath configured_prog) + args + Nothing + action + recordLog r + requireSuccess r diff --git a/cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/AAAA.hs b/cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/AAAA.hs new file mode 100644 index 00000000000..b9d4e99c553 --- /dev/null +++ b/cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/AAAA.hs @@ -0,0 +1,8 @@ +module Main where + +import System.Environment +import System.Exit + +main = do + getArgs >>= print + exitWith (ExitFailure 99) diff --git a/cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/CHANGELOG.md b/cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/CHANGELOG.md new file mode 100644 index 00000000000..7ae8ff6113d --- /dev/null +++ b/cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for setup-test + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/LICENSE b/cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/LICENSE new file mode 100644 index 00000000000..cd8ad2ac8ae --- /dev/null +++ b/cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/LICENSE @@ -0,0 +1,30 @@ +Copyright (c) 2023, Matthew Pickering + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Matthew Pickering nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/setup-test.cabal b/cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/setup-test.cabal new file mode 100644 index 00000000000..8deb0577a16 --- /dev/null +++ b/cabal-testsuite/PackageTests/ExternalCommandExitCode/setup-test/setup-test.cabal @@ -0,0 +1,25 @@ +cabal-version: 3.0 +name: setup-test +version: 0.1.0.0 +-- synopsis: +-- description: +license: BSD-3-Clause +license-file: LICENSE +author: Matthew Pickering +maintainer: matthewtpickering@gmail.com +-- copyright: +build-type: Simple +extra-doc-files: CHANGELOG.md +-- extra-source-files: + +common warnings + ghc-options: -Wall + +executable cabal-aaaa + import: warnings + main-is: AAAA.hs + -- other-modules: + -- other-extensions: + build-depends: base + hs-source-dirs: . + default-language: Haskell2010 diff --git a/changelog.d/issue-10063 b/changelog.d/issue-10063 new file mode 100644 index 00000000000..568ffe68a9b --- /dev/null +++ b/changelog.d/issue-10063 @@ -0,0 +1,14 @@ +synopsis: External commands now propagate exit code from child process +packages: cabal-install +prs: #10100 +issues: #10063 + +description: { + The exit code from an external command is now propagated as the exit code of + cabal-install when invoked by calling an external command. + + For example, if your external command exits with code 1, then cabal-install will + also exit with code 1. + + This mechanism can be used by an external command to signal failure. +} diff --git a/doc/external-commands.rst b/doc/external-commands.rst index e72495aa160..eca76483cc1 100644 --- a/doc/external-commands.rst +++ b/doc/external-commands.rst @@ -4,7 +4,8 @@ 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 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 +of the command. The ``$CABAL`` environment variable is set to the path of the ``cabal-install`` executable which invoked the subcommand. From a72bea0deec829c28b4810c7a8304f230f1ae814 Mon Sep 17 00:00:00 2001 From: sheaf Date: Fri, 3 May 2024 15:07:31 +0200 Subject: [PATCH 006/207] Use SetupHooks for Configure build-type This commit implements the Configure build-type in terms of Hooks, when build-type: Hooks is available (for Cabal >= 3.13). This moves Configure away from an implementation in terms of UserHooks, i.e. away from the Custom build-type. --- Cabal/src/Distribution/Simple.hs | 76 ++++++++++++++++--- .../Distribution/Simple/ConfigureScript.hs | 49 +++++++----- Cabal/src/Distribution/Simple/Errors.hs | 4 +- cabal-install/src/Distribution/Client/Main.hs | 4 +- .../src/Distribution/Client/SetupWrapper.hs | 18 +++-- changelog.d/pr-9969 | 18 +++++ 6 files changed, 132 insertions(+), 37 deletions(-) create mode 100644 changelog.d/pr-9969 diff --git a/Cabal/src/Distribution/Simple.hs b/Cabal/src/Distribution/Simple.hs index 85eabcbe93c..1423ed8f992 100644 --- a/Cabal/src/Distribution/Simple.hs +++ b/Cabal/src/Distribution/Simple.hs @@ -67,6 +67,7 @@ module Distribution.Simple -- ** Standard sets of hooks , simpleUserHooks , autoconfUserHooks + , autoconfSetupHooks , emptyUserHooks ) where @@ -110,6 +111,7 @@ import Distribution.Simple.SetupHooks.Internal ) import Distribution.Simple.Test import Distribution.Simple.Utils +import qualified Distribution.Types.LocalBuildConfig as LBC import Distribution.Utils.Path import Distribution.Verbosity import Distribution.Version @@ -935,16 +937,11 @@ autoconfUserHooks = let common = configCommonFlags flags verbosity = fromFlag $ setupVerbosity common mbWorkDir = flagToMaybe $ setupWorkingDir common - baseDir = packageRoot common - confExists <- doesFileExist $ baseDir "configure" - if confExists - then - runConfigureScript - verbosity - flags - lbi - else dieWithException verbosity ConfigureScriptNotFound - + runConfigureScript + flags + (flagAssignment lbi) + (withPrograms lbi) + (hostPlatform lbi) pbi <- getHookedBuildInfo verbosity mbWorkDir (buildDir lbi) sanityCheckHookedBuildInfo verbosity pkg_descr pbi let pkg_descr' = updatePackageDescription pbi pkg_descr @@ -991,6 +988,65 @@ getHookedBuildInfo verbosity mbWorkDir build_dir = do info verbosity $ "Reading parameters from " ++ getSymbolicPath infoFile readHookedBuildInfo verbosity mbWorkDir infoFile +autoconfSetupHooks :: SetupHooks +autoconfSetupHooks = + SetupHooks.noSetupHooks + { SetupHooks.configureHooks = + SetupHooks.noConfigureHooks + { SetupHooks.postConfPackageHook = Just post_conf_pkg + , SetupHooks.preConfComponentHook = Just pre_conf_comp + } + } + where + post_conf_pkg + :: SetupHooks.PostConfPackageInputs + -> IO () + post_conf_pkg + ( SetupHooks.PostConfPackageInputs + { SetupHooks.localBuildConfig = + LBC.LocalBuildConfig{LBC.withPrograms = progs} + , SetupHooks.packageBuildDescr = + LBC.PackageBuildDescr + { LBC.configFlags = cfg + , LBC.flagAssignment = flags + , LBC.hostPlatform = plat + } + } + ) = runConfigureScript cfg flags progs plat + + pre_conf_comp + :: SetupHooks.PreConfComponentInputs + -> IO SetupHooks.PreConfComponentOutputs + pre_conf_comp + ( SetupHooks.PreConfComponentInputs + { SetupHooks.packageBuildDescr = + LBC.PackageBuildDescr + { LBC.configFlags = cfg + , localPkgDescr = pkg_descr + } + , SetupHooks.component = component + } + ) = do + let verbosity = fromFlag $ configVerbosity cfg + mbWorkDir = flagToMaybe $ configWorkingDir cfg + distPref = configDistPref cfg + dist_dir <- findDistPrefOrDefault distPref + -- Read the ".buildinfo" file and use that to update + -- the components (main library + executables only). + hbi <- getHookedBuildInfo verbosity mbWorkDir (dist_dir makeRelativePathEx "build") + sanityCheckHookedBuildInfo verbosity pkg_descr hbi + -- SetupHooks TODO: we are reading getHookedBuildInfo once + -- for each component. I think this is inherent to the SetupHooks + -- approach. + let comp_name = componentName component + diff <- case SetupHooks.hookedBuildInfoComponentDiff_maybe hbi comp_name of + Nothing -> return $ SetupHooks.emptyComponentDiff comp_name + Just do_diff -> do_diff + return $ + SetupHooks.PreConfComponentOutputs + { SetupHooks.componentDiff = diff + } + defaultTestHook :: Args -> PackageDescription diff --git a/Cabal/src/Distribution/Simple/ConfigureScript.hs b/Cabal/src/Distribution/Simple/ConfigureScript.hs index 3661c683ceb..cf2a18297ee 100644 --- a/Cabal/src/Distribution/Simple/ConfigureScript.hs +++ b/Cabal/src/Distribution/Simple/ConfigureScript.hs @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE RankNTypes #-} @@ -23,6 +24,7 @@ import Prelude () -- local import Distribution.PackageDescription import Distribution.Pretty +import Distribution.Simple.Configure (findDistPrefOrDefault) import Distribution.Simple.Errors import Distribution.Simple.LocalBuildInfo import Distribution.Simple.Program @@ -30,12 +32,12 @@ import Distribution.Simple.Program.Db import Distribution.Simple.Setup.Common import Distribution.Simple.Setup.Config import Distribution.Simple.Utils -import Distribution.System (buildPlatform) +import Distribution.System (Platform, buildPlatform) import Distribution.Utils.NubList import Distribution.Utils.Path -import Distribution.Verbosity -- Base +import System.Directory (createDirectoryIfMissing, doesFileExist) import qualified System.FilePath as FilePath #ifdef mingw32_HOST_OS import System.FilePath (normalise, splitDrive) @@ -48,14 +50,25 @@ import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Map as Map runConfigureScript - :: Verbosity - -> ConfigFlags - -> LocalBuildInfo + :: ConfigFlags + -> FlagAssignment + -> ProgramDb + -> Platform + -- ^ host platform -> IO () -runConfigureScript verbosity flags lbi = do +runConfigureScript cfg flags programDb hp = do + let commonCfg = configCommonFlags cfg + verbosity = fromFlag $ setupVerbosity commonCfg + dist_dir <- findDistPrefOrDefault $ setupDistPref commonCfg + let build_dir = dist_dir makeRelativePathEx "build" + mbWorkDir = flagToMaybe $ setupWorkingDir commonCfg + configureScriptPath = packageRoot commonCfg "configure" + confExists <- doesFileExist configureScriptPath + unless confExists $ + dieWithException verbosity (ConfigureScriptNotFound configureScriptPath) + configureFile <- + makeAbsolute $ configureScriptPath env <- getEnvironment - let commonFlags = configCommonFlags flags - programDb = withPrograms lbi (ccProg, ccFlags) <- configureCCompiler verbosity programDb ccProgShort <- getShortPathName ccProg -- The C compiler's compilation and linker flags (e.g. @@ -64,8 +77,8 @@ runConfigureScript verbosity flags lbi = do -- to ccFlags -- We don't try and tell configure which ld to use, as we don't have -- a way to pass its flags too - configureFile <- - makeAbsolute $ packageRoot commonFlags "configure" + + let configureFile' = toUnix configureFile -- autoconf is fussy about filenames, and has a set of forbidden -- characters that can't appear in the build directory, etc: -- https://www.gnu.org/software/autoconf/manual/autoconf.html#File-System-Conventions @@ -79,7 +92,6 @@ runConfigureScript verbosity flags lbi = do -- TODO: We don't check for colons, tildes or leading dashes. We -- also should check the builddir's path, destdir, and all other -- paths as well. - let configureFile' = toUnix configureFile for_ badAutoconfCharacters $ \(c, cname) -> when (c `elem` FilePath.dropDrive configureFile') $ warn verbosity $ @@ -111,7 +123,7 @@ runConfigureScript verbosity flags lbi = do Map.fromListWith (<>) [ (flagEnvVar flag, (flag, bool) :| []) - | (flag, bool) <- unFlagAssignment $ flagAssignment lbi + | (flag, bool) <- unFlagAssignment flags ] -- A map from env vars to flag names to the single flag we will go with cabalFlagMapDeconflicted :: Map String (FlagName, Bool) <- @@ -143,10 +155,10 @@ runConfigureScript verbosity flags lbi = do ] ++ [ ( "CABAL_FLAGS" - , Just $ unwords [showFlagValue fv | fv <- unFlagAssignment $ flagAssignment lbi] + , Just $ unwords [showFlagValue fv | fv <- unFlagAssignment flags] ) ] - let extraPath = fromNubList $ configProgramPathExtra flags + let extraPath = fromNubList $ configProgramPathExtra cfg let cflagsEnv = maybe (unwords ccFlags) (++ (" " ++ unwords ccFlags)) $ lookup "CFLAGS" env @@ -160,7 +172,6 @@ runConfigureScript verbosity flags lbi = do ("CFLAGS", Just cflagsEnv) : [("PATH", Just pathEnv) | not (null extraPath)] ++ cabalFlagEnv - hp = hostPlatform lbi maybeHostFlag = if hp == buildPlatform then [] else ["--host=" ++ show (pretty hp)] args' = configureFile' : args ++ ["CC=" ++ ccProgShort] ++ maybeHostFlag shProg = simpleProgram "sh" @@ -169,14 +180,16 @@ runConfigureScript verbosity flags lbi = do lookupProgram shProg `fmap` configureProgram verbosity shProg progDb case shConfiguredProg of - Just sh -> + Just sh -> do + let build_in = interpretSymbolicPath mbWorkDir build_dir + createDirectoryIfMissing True build_in runProgramInvocation verbosity $ (programInvocation (sh{programOverrideEnv = overEnv}) args') - { progInvokeCwd = Just (interpretSymbolicPathLBI lbi $ buildDir lbi) + { progInvokeCwd = Just build_in } Nothing -> dieWithException verbosity NotFoundMsg where - args = configureArgs backwardsCompatHack flags + args = configureArgs backwardsCompatHack cfg backwardsCompatHack = False -- | Convert Windows path to Unix ones diff --git a/Cabal/src/Distribution/Simple/Errors.hs b/Cabal/src/Distribution/Simple/Errors.hs index 8513f92c7b9..67f97a7f889 100644 --- a/Cabal/src/Distribution/Simple/Errors.hs +++ b/Cabal/src/Distribution/Simple/Errors.hs @@ -115,7 +115,7 @@ data CabalException | CheckSemaphoreSupport | NoLibraryForPackage | SanityCheckHookedBuildInfo UnqualComponentName - | ConfigureScriptNotFound + | ConfigureScriptNotFound FilePath | NoValidComponent | ConfigureEitherSingleOrAll | ConfigCIDValidForPreComponent @@ -513,7 +513,7 @@ exceptionMessage e = case e of ++ prettyShow exe1 ++ "' but the package does not have a " ++ "executable with that name." - ConfigureScriptNotFound -> "configure script not found." + ConfigureScriptNotFound fp -> "configure script not found at " ++ fp ++ "." NoValidComponent -> "No valid component targets found" ConfigureEitherSingleOrAll -> "Can only configure either single component or all of them" ConfigCIDValidForPreComponent -> "--cid is only supported for per-component configure" diff --git a/cabal-install/src/Distribution/Client/Main.hs b/cabal-install/src/Distribution/Client/Main.hs index c1975e83094..46a653b8bf7 100644 --- a/cabal-install/src/Distribution/Client/Main.hs +++ b/cabal-install/src/Distribution/Client/Main.hs @@ -1470,8 +1470,8 @@ actAsSetupAction actAsSetupFlags args _globalFlags = in case bt of Simple -> Simple.defaultMainArgs args Configure -> - Simple.defaultMainWithHooksArgs - Simple.autoconfUserHooks + Simple.defaultMainWithSetupHooksArgs + Simple.autoconfSetupHooks args Make -> Make.defaultMainArgs args Hooks -> error "actAsSetupAction Hooks" diff --git a/cabal-install/src/Distribution/Client/SetupWrapper.hs b/cabal-install/src/Distribution/Client/SetupWrapper.hs index 4040c26bcea..b214cabfc23 100644 --- a/cabal-install/src/Distribution/Client/SetupWrapper.hs +++ b/cabal-install/src/Distribution/Client/SetupWrapper.hs @@ -557,8 +557,8 @@ internalSetupMethod verbosity options bt args = do buildTypeAction :: BuildType -> ([String] -> IO ()) buildTypeAction Simple = Simple.defaultMainArgs buildTypeAction Configure = - Simple.defaultMainWithHooksArgs - Simple.autoconfUserHooks + Simple.defaultMainWithSetupHooksArgs + Simple.autoconfSetupHooks buildTypeAction Make = Make.defaultMainArgs buildTypeAction Hooks = error "buildTypeAction Hooks" buildTypeAction Custom = error "buildTypeAction Custom" @@ -862,10 +862,18 @@ getExternalSetupMethod verbosity options pkg bt = do buildTypeScript cabalLibVersion = "{-# LANGUAGE NoImplicitPrelude #-}\n" <> case bt of Simple -> "import Distribution.Simple; main = defaultMain\n" Configure - | cabalLibVersion >= mkVersion [1, 3, 10] -> "import Distribution.Simple; main = defaultMainWithHooks autoconfUserHooks\n" - | otherwise -> "import Distribution.Simple; main = defaultMainWithHooks defaultUserHooks\n" + | cabalLibVersion >= mkVersion [3, 13, 0] + -> "import Distribution.Simple; main = defaultMainWithSetupHooks autoconfSetupHooks\n" + | cabalLibVersion >= mkVersion [1, 3, 10] + -> "import Distribution.Simple; main = defaultMainWithHooks autoconfUserHooks\n" + | otherwise + -> "import Distribution.Simple; main = defaultMainWithHooks defaultUserHooks\n" Make -> "import Distribution.Make; main = defaultMain\n" - Hooks -> "import Distribution.Simple; import SetupHooks; main = defaultMainWithSetupHooks setupHooks\n" + Hooks + | cabalLibVersion >= mkVersion [3, 13, 0] + -> "import Distribution.Simple; import SetupHooks; main = defaultMainWithSetupHooks setupHooks\n" + | otherwise + -> error "buildTypeScript Hooks with Cabal < 3.13" Custom -> error "buildTypeScript Custom" installedCabalVersion diff --git a/changelog.d/pr-9969 b/changelog.d/pr-9969 new file mode 100644 index 00000000000..17a60b88e99 --- /dev/null +++ b/changelog.d/pr-9969 @@ -0,0 +1,18 @@ +synopsis: Configure build-type in terms of Hooks +packages: Cabal cabal-install +prs: #9969 + +description: { + +The `build-type: Configure` is now implemented in terms of `build-type: Hooks` +rather than in terms of `build-type: Custom`. This moves the `Configure` +build-type away from the `Custom` issues. Eventually, `build-type: Hooks` will +no longer imply packages are built in legacy-fallback mode. Now, when that +happens, `Configure` will also stop implying `legacy-fallback`. + +The observable aspect of this change is `runConfigureScript` now having a +different type, and `autoconfSetupHooks` being exposed `Distribution.Simple`. +The former is motivated by internal implementation details, while the latter +provides the `SetupHooks` value for the `Configure` build type, which can be +consumed by other `Hooks` clients (e.g. eventually HLS). +} From 6f1ff97a504253a392473c1b32a2cb44de01607e Mon Sep 17 00:00:00 2001 From: Rodrigo Mesquita Date: Wed, 12 Jun 2024 11:51:12 +0100 Subject: [PATCH 007/207] Fix recomp bug by invalidating cache on build exception Be sure to invalidate the cache if building throws an exception! If not, we'll abort execution with a stale recompilation cache. See ghc#24926 for an example of how this can go wrong. --- .../Client/ProjectBuilding/UnpackedPackage.hs | 6 +++- .../Recompilation/GHC24926/Repro.hs | 6 ++++ .../Recompilation/GHC24926/cabal.test.hs | 36 +++++++++++++++++++ .../Recompilation/GHC24926/repro.cabal | 19 ++++++++++ .../Recompilation/GHC24926/src/Process.hs | 7 ++++ 5 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 cabal-testsuite/PackageTests/Recompilation/GHC24926/Repro.hs create mode 100644 cabal-testsuite/PackageTests/Recompilation/GHC24926/cabal.test.hs create mode 100644 cabal-testsuite/PackageTests/Recompilation/GHC24926/repro.cabal create mode 100644 cabal-testsuite/PackageTests/Recompilation/GHC24926/src/Process.hs diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs index 7d9f34a8e8b..23dff3ff3ab 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs @@ -99,7 +99,7 @@ import qualified Data.ByteString.Lazy as LBS import qualified Data.ByteString.Lazy.Char8 as LBS.Char8 import qualified Data.List.NonEmpty as NE -import Control.Exception (ErrorCall, Handler (..), SomeAsyncException, assert, catches) +import Control.Exception (ErrorCall, Handler (..), SomeAsyncException, assert, catches, onException) import System.Directory (canonicalizePath, createDirectoryIfMissing, doesDirectoryExist, doesFileExist, removeFile) import System.FilePath (dropDrive, normalise, takeDirectory, (<.>), ()) import System.IO (Handle, IOMode (AppendMode), withFile) @@ -480,6 +480,10 @@ buildInplaceUnpackedPackage whenRebuild $ do timestamp <- beginUpdateFileMonitor runBuild + -- Be sure to invalidate the cache if building throws an exception! + -- If not, we'll abort execution with a stale recompilation cache. + -- See ghc#24926 for an example of how this can go wrong. + `onException` invalidatePackageRegFileMonitor packageFileMonitor let listSimple = execRebuild (getSymbolicPath srcdir) (needElaboratedConfiguredPackage pkg) diff --git a/cabal-testsuite/PackageTests/Recompilation/GHC24926/Repro.hs b/cabal-testsuite/PackageTests/Recompilation/GHC24926/Repro.hs new file mode 100644 index 00000000000..204872538ea --- /dev/null +++ b/cabal-testsuite/PackageTests/Recompilation/GHC24926/Repro.hs @@ -0,0 +1,6 @@ +import Process (a) +import Internal (Unused) + +main :: IO () +main = a + diff --git a/cabal-testsuite/PackageTests/Recompilation/GHC24926/cabal.test.hs b/cabal-testsuite/PackageTests/Recompilation/GHC24926/cabal.test.hs new file mode 100644 index 00000000000..607426f381c --- /dev/null +++ b/cabal-testsuite/PackageTests/Recompilation/GHC24926/cabal.test.hs @@ -0,0 +1,36 @@ +import Test.Cabal.Prelude + +-- See ghc#24926 +main = cabalTest $ do + recordMode DoNotRecord $ do + + root <- testTmpDir <$> getTestEnv + + writeInternalOrig root + cabal "test" [] + + liftIO $ writeFile (root ++ "/src/Internal.hs") + " module Internal where;\ + + \ data Unused = Unused;" + fails $ cabal "test" [] -- broken module on purpose + + writeInternalOrig root + out <- cabal' "test" [] -- shouldn't fail! + + assertOutputDoesNotContain + ": error:" out + assertOutputDoesNotContain + "Cannot continue after interface file error" out + + where + + writeInternalOrig r = liftIO $ do + writeFile (r ++ "/src/Internal.hs") + " module Internal where;\ + + \ data Unused = Unused;\ + + \ b :: IO (); \ + \ b = pure ();" + diff --git a/cabal-testsuite/PackageTests/Recompilation/GHC24926/repro.cabal b/cabal-testsuite/PackageTests/Recompilation/GHC24926/repro.cabal new file mode 100644 index 00000000000..30ad3d92d13 --- /dev/null +++ b/cabal-testsuite/PackageTests/Recompilation/GHC24926/repro.cabal @@ -0,0 +1,19 @@ +cabal-version: 3.0 +name: repro +version: 0.1.0.0 +build-type: Simple + +library + default-language: Haskell2010 + exposed-modules: + Internal + Process + build-depends: base + hs-source-dirs: src + +test-suite repro + default-language: Haskell2010 + type: exitcode-stdio-1.0 + main-is: Repro.hs + build-depends: base, repro + diff --git a/cabal-testsuite/PackageTests/Recompilation/GHC24926/src/Process.hs b/cabal-testsuite/PackageTests/Recompilation/GHC24926/src/Process.hs new file mode 100644 index 00000000000..919c5d46df5 --- /dev/null +++ b/cabal-testsuite/PackageTests/Recompilation/GHC24926/src/Process.hs @@ -0,0 +1,7 @@ +module Process where + +import Internal + +a :: IO () +a = b + From 413d2fdb1525ae7e42061a533f9ad864266c761a Mon Sep 17 00:00:00 2001 From: Rodrigo Mesquita Date: Fri, 3 May 2024 14:51:31 +0200 Subject: [PATCH 008/207] testsuite: Pass pkgdb of store used for intree Cabal --- .../PackageTests/BuildToolPaths/cabal.test.hs | 13 +++++--- cabal-testsuite/main/cabal-tests.hs | 33 ++++++++++++------- cabal-testsuite/src/Test/Cabal/Monad.hs | 10 +++--- cabal-testsuite/src/Test/Cabal/Prelude.hs | 7 ++-- 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/cabal-testsuite/PackageTests/BuildToolPaths/cabal.test.hs b/cabal-testsuite/PackageTests/BuildToolPaths/cabal.test.hs index 60df6ca1ac2..dc2559eb12f 100644 --- a/cabal-testsuite/PackageTests/BuildToolPaths/cabal.test.hs +++ b/cabal-testsuite/PackageTests/BuildToolPaths/cabal.test.hs @@ -10,16 +10,19 @@ main = cabalTest $ do -- shipped with a version of Cabal with SetupHooks). -- Ever since 716b109c4ae908458b16af5d75c233c7d9fdfc06, we use --intree-cabal-lib in -- CI, so we should always take the "Just" case which actually runs the test. + -- + -- NB: be sure to use v2 commands, as otherwise the testsuite driver will not + -- pass --package-db flags. Nothing -> skip "Cabal-hooks library unavailable." - Just pkgdb -> recordMode DoNotRecord $ do + Just _pkgdb -> recordMode DoNotRecord $ do -- At build-time: -- -- - in a pre-build hook -- - in a Template Haskell splice - cabal "build" [ "all", "--enable-tests", "--enable-benchmarks", "--package-db=" ++ pkgdb ] + cabal "v2-build" [ "all", "--enable-tests", "--enable-benchmarks"] -- At runtime of a test-suite - cabal "test" [ "pbts", "--package-db=" ++ pkgdb ] + cabal "v2-test" [ "pbts" ] -- At runtime of a benchmark - cabal "bench" [ "pbts", "--package-db=" ++ pkgdb ] + cabal "v2-bench" [ "pbts" ] -- At runtime of an executable - cabal "run" [ "pbts-exe", "--package-db=" ++ pkgdb ] + cabal "v2-run" [ "pbts-exe" ] diff --git a/cabal-testsuite/main/cabal-tests.hs b/cabal-testsuite/main/cabal-tests.hs index c3d167e3b8c..f27ea9b6094 100644 --- a/cabal-testsuite/main/cabal-tests.hs +++ b/cabal-testsuite/main/cabal-tests.hs @@ -125,12 +125,13 @@ mainArgParser = MainArgs <*> commonArgParser -- Unpack and build a specific released version of Cabal and Cabal-syntax libraries -buildCabalLibsProject :: String -> Verbosity -> Maybe FilePath -> FilePath -> IO FilePath +buildCabalLibsProject :: String -> Verbosity -> Maybe FilePath -> FilePath -> IO [FilePath] buildCabalLibsProject projString verb mbGhc dir = do let prog_db = userSpecifyPaths [("ghc", path) | Just path <- [mbGhc] ] defaultProgramDb (cabal, _) <- requireProgram verb (simpleProgram "cabal") prog_db (ghc, _) <- requireProgram verb ghcProgram prog_db + let storeRoot = dir "store" let pv = fromMaybe (error "no ghc version") (programVersion ghc) let final_package_db = dir "dist-newstyle" "packagedb" "ghc-" ++ prettyShow pv createDirectoryIfMissing True dir @@ -138,16 +139,24 @@ buildCabalLibsProject projString verb mbGhc dir = do runProgramInvocation verb ((programInvocation cabal - ["--store-dir", dir "store" + ["--store-dir", storeRoot , "--project-file=" ++ dir "cabal.project-test" , "build" , "-w", programPath ghc , "Cabal", "Cabal-syntax", "Cabal-hooks" ] ) { progInvokeCwd = Just dir }) - return final_package_db + -- Determine the path to the packagedb in the store for this ghc version + storesByGhc <- getDirectoryContents storeRoot + case filter (prettyShow pv `isInfixOf`) storesByGhc of + [] -> return [final_package_db] + storeForGhc:_ -> do + let storePackageDB = (storeRoot storeForGhc "package.db") + return [storePackageDB, final_package_db] -buildCabalLibsSpecific :: String -> Verbosity -> Maybe FilePath -> FilePath -> IO FilePath + + +buildCabalLibsSpecific :: String -> Verbosity -> Maybe FilePath -> FilePath -> IO [FilePath] buildCabalLibsSpecific ver verb mbGhc builddir_rel = do let prog_db = userSpecifyPaths [("ghc", path) | Just path <- [mbGhc] ] defaultProgramDb (cabal, _) <- requireProgram verb (simpleProgram "cabal") prog_db @@ -166,7 +175,7 @@ buildCabalLibsSpecific ver verb mbGhc builddir_rel = do buildCabalLibsProject ("packages: Cabal-" ++ ver ++ " Cabal-syntax-" ++ ver ++ " Cabal-hooks-" ++ hooksVer) verb mbGhc dir -buildCabalLibsIntree :: String -> Verbosity -> Maybe FilePath -> FilePath -> IO FilePath +buildCabalLibsIntree :: String -> Verbosity -> Maybe FilePath -> FilePath -> IO [FilePath] buildCabalLibsIntree root verb mbGhc builddir_rel = do dir <- canonicalizePath (builddir_rel "intree") buildCabalLibsProject ("packages: " ++ root "Cabal" ++ " " ++ root "Cabal-syntax" ++ " " ++ root "Cabal-hooks") verb mbGhc dir @@ -182,26 +191,26 @@ main = do args <- execParser $ info (mainArgParser <**> helper) mempty let verbosity = if mainArgVerbose args then verbose else normal - mpkg_db <- + pkg_dbs <- -- Not path to cabal-install so we're not going to run cabal-install tests so we -- can skip setting up a Cabal library to use with cabal-install. case argCabalInstallPath (mainCommonArgs args) of Nothing -> do when (isJust $ mainArgCabalSpec args) (putStrLn "Ignoring Cabal library specification as cabal-install tests are not running") - return Nothing + return [] -- Path to cabal-install is passed, so need to install the requested relevant version of Cabal -- library. Just {} -> case mainArgCabalSpec args of Nothing -> do putStrLn "No Cabal library specified, using boot Cabal library with cabal-install tests" - return Nothing - Just BootCabalLib -> return Nothing + return [] + Just BootCabalLib -> return [] Just (InTreeCabalLib root build_dir) -> - Just <$> buildCabalLibsIntree root verbosity (argGhcPath (mainCommonArgs args)) build_dir + buildCabalLibsIntree root verbosity (argGhcPath (mainCommonArgs args)) build_dir Just (SpecificCabalLib ver build_dir) -> - Just <$> buildCabalLibsSpecific ver verbosity (argGhcPath (mainCommonArgs args)) build_dir + buildCabalLibsSpecific ver verbosity (argGhcPath (mainCommonArgs args)) build_dir -- To run our test scripts, we need to be able to run Haskell code -- linked against the Cabal library under test. The most efficient @@ -228,7 +237,7 @@ main = do -> IO result runTest runner path = runner Nothing [] path $ - ["--builddir", dist_dir, path] ++ ["--extra-package-db=" ++ pkg_db | Just pkg_db <- [mpkg_db]] ++ renderCommonArgs (mainCommonArgs args) + ["--builddir", dist_dir, path] ++ ["--extra-package-db=" ++ pkg_db | pkg_db <- pkg_dbs] ++ renderCommonArgs (mainCommonArgs args) case mainArgTestPaths args of [path] -> do diff --git a/cabal-testsuite/src/Test/Cabal/Monad.hs b/cabal-testsuite/src/Test/Cabal/Monad.hs index e817a89c282..861538692aa 100644 --- a/cabal-testsuite/src/Test/Cabal/Monad.hs +++ b/cabal-testsuite/src/Test/Cabal/Monad.hs @@ -158,7 +158,7 @@ renderCommonArgs args = data TestArgs = TestArgs { testArgDistDir :: FilePath, - testArgPackageDb :: Maybe FilePath, + testArgPackageDb :: [FilePath], testArgScriptPath :: FilePath, testCommonArgs :: CommonArgs } @@ -169,7 +169,7 @@ testArgParser = TestArgs ( help "Build directory of cabal-testsuite" <> long "builddir" <> metavar "DIR") - <*> optional (option str + <*> many (option str ( help "Package DB which contains Cabal and Cabal-syntax" <> long "extra-package-db" <> metavar "DIR")) @@ -333,7 +333,7 @@ runTestM mode m = testMtimeChangeDelay = Nothing, testScriptEnv = senv, testSetupPath = dist_dir "build" "setup" "setup", - testPackageDbPath = testArgPackageDb args, + testPackageDbPath = case testArgPackageDb args of [] -> Nothing; xs -> Just xs, testSkipSetupTests = argSkipSetupTests (testCommonArgs args), testHaveCabalShared = runnerWithSharedLib senv, testEnvironment = @@ -649,8 +649,8 @@ data TestEnv = TestEnv -- | Setup script path , testSetupPath :: FilePath -- | Setup package-db path which contains Cabal and Cabal-syntax for cabal-install to - -- use when compiling custom setups. - , testPackageDbPath :: Maybe FilePath + -- use when compiling custom setups, plus the store with possible dependencies of those setup packages. + , testPackageDbPath :: Maybe [FilePath] -- | Skip Setup tests? , testSkipSetupTests :: Bool -- | Do we have shared libraries for the Cabal-under-tests? diff --git a/cabal-testsuite/src/Test/Cabal/Prelude.hs b/cabal-testsuite/src/Test/Cabal/Prelude.hs index 8a0aaff928b..b72e427c91b 100644 --- a/cabal-testsuite/src/Test/Cabal/Prelude.hs +++ b/cabal-testsuite/src/Test/Cabal/Prelude.hs @@ -324,14 +324,13 @@ cabalGArgs global_args cmd args input = do = [ "--builddir", testDistDir env , "-j1" ] ++ [ "--project-file=" ++ fp | Just fp <- [testCabalProjectFile env] ] - ++ ["--package-db=" ++ db | Just db <- [testPackageDbPath env]] + ++ ["--package-db=" ++ db | Just dbs <- [testPackageDbPath env], db <- dbs] | "v1-" `isPrefixOf` cmd = [ "--builddir", testDistDir env ] ++ install_args - | otherwise = [ "--builddir", testDistDir env ] - ++ ["--package-db=" ++ db | Just db <- [testPackageDbPath env]] + ++ ["--package-db=" ++ db | Just dbs <- [testPackageDbPath env], db <- dbs] ++ install_args install_args @@ -875,7 +874,7 @@ allCabalVersion = isCabalVersion all isCabalVersion :: WithCallStack (((Version -> Bool) -> [Version] -> Bool) -> String -> TestM Bool) isCabalVersion decide range = do env <- getTestEnv - cabal_pkgs <- ghcPkg_raw' $ ["--global", "list", "Cabal", "--simple"] ++ ["--package-db=" ++ db | Just db <- [testPackageDbPath env]] + cabal_pkgs <- ghcPkg_raw' $ ["--global", "list", "Cabal", "--simple"] ++ ["--package-db=" ++ db | Just dbs <- [testPackageDbPath env], db <- dbs] let pkg_versions :: [PackageIdentifier] = mapMaybe simpleParsec (words (resultOutput cabal_pkgs)) vr <- case eitherParsec range of Left err -> fail err From 12c8d198ac97c59d35a4fb9f3581fa13b0c861fd Mon Sep 17 00:00:00 2001 From: Phil de Joux Date: Mon, 10 Jun 2024 10:59:24 -0400 Subject: [PATCH 009/207] Change packages default to empty --- doc/cabal-project-description-file.rst | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/doc/cabal-project-description-file.rst b/doc/cabal-project-description-file.rst index c1f29bfc052..cd80cd3ab72 100644 --- a/doc/cabal-project-description-file.rst +++ b/doc/cabal-project-description-file.rst @@ -86,19 +86,25 @@ would not be necessitated. Specifying the local packages ----------------------------- +You *must* provide a non-empty list of local packages in your project, filling +out either a ``packages`` field or an ``optional-packages`` field or both to +satisfy this requirement. + +When ``cabal.project`` doesn't exist, ``cabal-install`` fabricates an ephemeral +project for its own use with this simple content, a glob that will find any (but +expects to find one) package in the current directory: + +.. code-block:: cabal + + packages: ./*.cabal + The following top-level options specify what the local packages of a project are: .. cfg-field:: packages: package location list (space or comma separated) :synopsis: Project packages. - :default: ``./*.cabal`` - - .. warning:: - - The default value ``./*.cabal`` only takes effect if there is no explicit - ``cabal.project`` file. - If you use such explicit file you *must* fill the field. + :default: empty Specifies the list of package locations which contain the local packages to be built by this project. Package locations can take the From 010eca90d38a0fa46f9f54f1a2397b6f6b4afcd1 Mon Sep 17 00:00:00 2001 From: sheaf Date: Mon, 25 Mar 2024 13:05:05 +0100 Subject: [PATCH 010/207] cabal-install configureCompiler: configure progdb We should configure unconfigured programs before serialising them (using the Binary ProgramDb instance) in Distribution.Client.ProjectPlanning.configureCompiler, as otherwise we can accidentally discard information. This isn't currently a live bug, because in practice we end up re-running configuration steps when interfacing with the Cabal library. However, in the bright future in which we avoid re-configuring things when building a Cabal package that we already determined when invoking cabal-install, this starts causing problems. --- cabal-install/src/Distribution/Client/ProjectPlanning.hs | 9 +++++++-- cabal-testsuite/PackageTests/ExtraProgPath/setup.out | 2 -- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 43c835f7a0d..6b77531b8a5 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -483,7 +483,7 @@ configureCompiler let extraPath = fromNubList packageConfigProgramPathExtra progdb <- liftIO $ prependProgramSearchPath verbosity extraPath [] defaultProgramDb let progdb' = userSpecifyPaths (Map.toList (getMapLast packageConfigProgramPaths)) progdb - result@(_, _, progdb'') <- + (comp, plat, progdb'') <- liftIO $ Cabal.configCompilerEx hcFlavor @@ -500,7 +500,12 @@ configureCompiler -- programs it cares about, and those are the ones we monitor here. monitorFiles (programsMonitorFiles progdb'') - return result + -- Configure the unconfigured programs in the program database, + -- as we can't serialise unconfigured programs. + -- See also #2241 and #9840. + finalProgDb <- liftIO $ configureAllKnownPrograms verbosity progdb'' + + return (comp, plat, finalProgDb) where hcFlavor = flagToMaybe projectConfigHcFlavor hcPath = flagToMaybe projectConfigHcPath diff --git a/cabal-testsuite/PackageTests/ExtraProgPath/setup.out b/cabal-testsuite/PackageTests/ExtraProgPath/setup.out index 1011c8899ed..c3755d7e8c7 100644 --- a/cabal-testsuite/PackageTests/ExtraProgPath/setup.out +++ b/cabal-testsuite/PackageTests/ExtraProgPath/setup.out @@ -1,8 +1,6 @@ # cabal v2-build Warning: cannot determine version of /pkg-config : "" -Warning: cannot determine version of /pkg-config : -"" Resolving dependencies... Error: [Cabal-7107] Could not resolve dependencies: From 5442cd933c474b8bbcc9ea9dd64ccae8d07eecbb Mon Sep 17 00:00:00 2001 From: sheaf Date: Fri, 3 May 2024 12:21:13 +0200 Subject: [PATCH 011/207] configureRequiredProgram: take care if program already configured In configureRequiredProgram, we would unconditionally configure the program, even if it was configured already. To explain why this is problematic: - The programs we try to configure in this function are those that arise from a "build-tool-depends" field of a package. - If the program is not in the "unconfigured" state, we would unconditionally treat it as a simpleProgram. This means that if such a program is builtin but is not a simpleProgram, we might fail to configure it properly. This problem arises when we configure programs more eagerly: when, in the past, we might have gone looking up an unconfigured program and successfully configured it, now we might find the program is already configured. One example in which this would cause an issue is when we have build-tool-depends: hsc2hs If we end up re-configuring hsc2hs in configureRequiredProgram, we would treat it as a simple program, which would cause us to be unable to determine its version. --- Cabal/src/Distribution/Simple/Configure.hs | 118 ++++++++++++--------- 1 file changed, 70 insertions(+), 48 deletions(-) diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index 9e561e791c6..8d90b0d8822 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -2210,55 +2210,77 @@ configureRequiredProgram verbosity progdb (LegacyExeDependency progName verRange) = - case lookupKnownProgram progName progdb of - Nothing -> - -- Try to configure it as a 'simpleProgram' automatically - -- - -- There's a bit of a story behind this line. In old versions - -- of Cabal, there were only internal build-tools dependencies. So the - -- behavior in this case was: - -- - -- - If a build-tool dependency was internal, don't do - -- any checking. - -- - -- - If it was external, call 'configureRequiredProgram' to - -- "configure" the executable. In particular, if - -- the program was not "known" (present in 'ProgramDb'), - -- then we would just error. This was fine, because - -- the only way a program could be executed from 'ProgramDb' - -- is if some library code from Cabal actually called it, - -- and the pre-existing Cabal code only calls known - -- programs from 'defaultProgramDb', and so if it - -- is calling something else, you have a Custom setup - -- script, and in that case you are expected to register - -- the program you want to call in the ProgramDb. - -- - -- OK, so that was fine, until I (ezyang, in 2016) refactored - -- Cabal to support per-component builds. In this case, what - -- was previously an internal build-tool dependency now became - -- an external one, and now previously "internal" dependencies - -- are now external. But these are permitted to exist even - -- when they are not previously configured (something that - -- can only occur by a Custom script.) + case lookupProgramByName progName progdb of + Just prog -> + -- If the program has already been configured, use it + -- (as long as the version is compatible). -- - -- So, I decided, "Fine, let's just accept these in any - -- case." Thus this line. The alternative would have been to - -- somehow detect when a build-tools dependency was "internal" (by - -- looking at the unflattened package description) but this - -- would also be incompatible with future work to support - -- external executable dependencies: we definitely cannot - -- assume they will be preinitialized in the 'ProgramDb'. - configureProgram verbosity (simpleProgram progName) progdb - Just prog - -- requireProgramVersion always requires the program have a version - -- but if the user says "build-depends: foo" ie no version constraint - -- then we should not fail if we cannot discover the program version. - | verRange == anyVersion -> do - (_, progdb') <- requireProgram verbosity prog progdb - return progdb' - | otherwise -> do - (_, _, progdb') <- requireProgramVersion verbosity prog verRange progdb - return progdb' + -- Not doing so means falling back to the "simpleProgram" path below, + -- which might fail if the program has custom logic to find a version + -- (such as hsc2hs). + let loc = locationPath $ programLocation prog + in case programVersion prog of + Nothing + | verRange == anyVersion -> + return progdb + | otherwise -> + dieWithException verbosity $! + UnknownVersionDb (programId prog) verRange loc + Just version + | withinRange version verRange -> + return progdb + | otherwise -> + dieWithException verbosity $! + BadVersionDb (programId prog) version verRange loc + Nothing -> + -- Otherwise, try to configure it as a 'simpleProgram' automatically + case lookupKnownProgram progName progdb of + Nothing -> + -- There's a bit of a story behind this line. In old versions + -- of Cabal, there were only internal build-tools dependencies. So the + -- behavior in this case was: + -- + -- - If a build-tool dependency was internal, don't do + -- any checking. + -- + -- - If it was external, call 'configureRequiredProgram' to + -- "configure" the executable. In particular, if + -- the program was not "known" (present in 'ProgramDb'), + -- then we would just error. This was fine, because + -- the only way a program could be executed from 'ProgramDb' + -- is if some library code from Cabal actually called it, + -- and the pre-existing Cabal code only calls known + -- programs from 'defaultProgramDb', and so if it + -- is calling something else, you have a Custom setup + -- script, and in that case you are expected to register + -- the program you want to call in the ProgramDb. + -- + -- OK, so that was fine, until I (ezyang, in 2016) refactored + -- Cabal to support per-component builds. In this case, what + -- was previously an internal build-tool dependency now became + -- an external one, and now previously "internal" dependencies + -- are now external. But these are permitted to exist even + -- when they are not previously configured (something that + -- can only occur by a Custom script.) + -- + -- So, I decided, "Fine, let's just accept these in any + -- case." Thus this line. The alternative would have been to + -- somehow detect when a build-tools dependency was "internal" (by + -- looking at the unflattened package description) but this + -- would also be incompatible with future work to support + -- external executable dependencies: we definitely cannot + -- assume they will be preinitialized in the 'ProgramDb'. + configureProgram verbosity (simpleProgram progName) progdb + Just prog + -- requireProgramVersion always requires the program have a version + -- but if the user says "build-depends: foo" ie no version constraint + -- then we should not fail if we cannot discover the program version. + | verRange == anyVersion -> do + (_, progdb') <- requireProgram verbosity prog progdb + return progdb' + | otherwise -> do + (_, _, progdb') <- requireProgramVersion verbosity prog verRange progdb + return progdb' -- ----------------------------------------------------------------------------- -- Configuring pkg-config package dependencies From bebf1fdc4d9a62416f3798f86c513d35968ff1e6 Mon Sep 17 00:00:00 2001 From: sheaf Date: Fri, 3 May 2024 14:27:46 +0200 Subject: [PATCH 012/207] SetupWrapper: configure progs when building Setup This commit configures the unconfigured programs in the program database when we are building a custom Setup script. This ensures that we can find the "strip" program which might otherwise still be unconfigured. --- .../src/Distribution/Client/SetupWrapper.hs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/cabal-install/src/Distribution/Client/SetupWrapper.hs b/cabal-install/src/Distribution/Client/SetupWrapper.hs index b214cabfc23..936412cf4fb 100644 --- a/cabal-install/src/Distribution/Client/SetupWrapper.hs +++ b/cabal-install/src/Distribution/Client/SetupWrapper.hs @@ -90,7 +90,8 @@ import Distribution.Simple.Program , runDbProgramCwd ) import Distribution.Simple.Program.Db - ( prependProgramSearchPath + ( configureAllKnownPrograms + , prependProgramSearchPath , progOverrideEnv ) import Distribution.Simple.Program.Find @@ -1035,11 +1036,19 @@ getExternalSetupMethod verbosity options pkg bt = do createDirectoryIfMissingVerbose verbosity True setupCacheDir installExecutableFile verbosity src cachedSetupProgFile -- Do not strip if we're using GHCJS, since the result may be a script - when (maybe True ((/= GHCJS) . compilerFlavor) $ useCompiler options') $ + when (maybe True ((/= GHCJS) . compilerFlavor) $ useCompiler options') $ do + -- Add the relevant PATH overrides for the package to the + -- program database. + setupProgDb + <- prependProgramSearchPath verbosity + (useExtraPathEnv options) + (useExtraEnvOverrides options) + (useProgramDb options') + >>= configureAllKnownPrograms verbosity Strip.stripExe verbosity platform - (useProgramDb options') + setupProgDb cachedSetupProgFile return cachedSetupProgFile where From 53e41933d7396976b4e1a008b11178fa43fb2b1e Mon Sep 17 00:00:00 2001 From: sheaf Date: Fri, 3 May 2024 15:00:44 +0200 Subject: [PATCH 013/207] Remove haskell-suite-dummy-program hack There was some hacky logic in place to give a "haskell-suite" compiler a dummy location so that we would attempt to configure it. This logic is no longer necessary since 'configureRequiredProgram' was changed to accomodate the situation in which 'lookupKnownProgram' fails. In fact, it is downright harmful, as this dummy location will trigger errors when we attempt to configure all known programs, which is a necessary step before attempting to serialise a program database. --- Cabal/src/Distribution/Simple/Program/Builtin.hs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Cabal/src/Distribution/Simple/Program/Builtin.hs b/Cabal/src/Distribution/Simple/Program/Builtin.hs index e79e676d8cc..65501111a7e 100644 --- a/Cabal/src/Distribution/Simple/Program/Builtin.hs +++ b/Cabal/src/Distribution/Simple/Program/Builtin.hs @@ -226,21 +226,13 @@ hpcProgram = -- during the configure phase. haskellSuiteProgram :: Program haskellSuiteProgram = - (simpleProgram "haskell-suite") - { -- pretend that the program exists, otherwise it won't be in the - -- "configured" state - programFindLocation = \_verbosity _searchPath -> - return $ Just ("haskell-suite-dummy-location", []) - } + simpleProgram "haskell-suite" -- This represent a haskell-suite package manager. See the comments for -- haskellSuiteProgram. haskellSuitePkgProgram :: Program haskellSuitePkgProgram = - (simpleProgram "haskell-suite-pkg") - { programFindLocation = \_verbosity _searchPath -> - return $ Just ("haskell-suite-pkg-dummy-location", []) - } + simpleProgram "haskell-suite-pkg" happyProgram :: Program happyProgram = From 6c5e096e881984a914eeff83a808e08fb47db304 Mon Sep 17 00:00:00 2001 From: Lennart Augustsson Date: Sun, 16 Jun 2024 00:01:44 +0200 Subject: [PATCH 014/207] Add MHS as a recognized compiler. (#9878) * Add MHS as a recognized compiler. * Add Changelog entry * Add comment. * Update checksums. * Update more checksums. --------- Co-authored-by: Lennart Augustsson --- Cabal-syntax/src/Distribution/Compiler.hs | 3 ++- .../tests/UnitTests/Distribution/Utils/Structured.hs | 8 ++++---- changelog.d/pr-9878 | 8 ++++++++ 3 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 changelog.d/pr-9878 diff --git a/Cabal-syntax/src/Distribution/Compiler.hs b/Cabal-syntax/src/Distribution/Compiler.hs index 8fb3f88851e..d715efbf951 100644 --- a/Cabal-syntax/src/Distribution/Compiler.hs +++ b/Cabal-syntax/src/Distribution/Compiler.hs @@ -75,6 +75,7 @@ data CompilerFlavor | LHC | UHC | Eta + | MHS -- MicroHS, see https://github.com/augustss/MicroHs | HaskellSuite String -- string is the id of the actual compiler | OtherCompiler String deriving (Generic, Show, Read, Eq, Ord, Typeable, Data) @@ -85,7 +86,7 @@ instance NFData CompilerFlavor where rnf = genericRnf knownCompilerFlavors :: [CompilerFlavor] knownCompilerFlavors = - [GHC, GHCJS, NHC, YHC, Hugs, HBC, Helium, JHC, LHC, UHC, Eta] + [GHC, GHCJS, NHC, YHC, Hugs, HBC, Helium, JHC, LHC, UHC, Eta, MHS] instance Pretty CompilerFlavor where pretty (OtherCompiler name) = Disp.text name diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs index 641551473e8..54624a617c3 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs @@ -33,15 +33,15 @@ md5Check proxy md5Int = structureHash proxy @?= md5FromInteger md5Int md5CheckGenericPackageDescription :: Proxy GenericPackageDescription -> Assertion md5CheckGenericPackageDescription proxy = md5Check proxy #if MIN_VERSION_base(4,19,0) - 0x4acd7857947385180d814f36dc1a759e + 0x44f8430d7366cf849e09669627573040 #else - 0x3ff3fa6c3c570bcafa10b457b1208cc8 + 0x8ed837568017bde3abb4fcee244b9c9f #endif md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion md5CheckLocalBuildInfo proxy = md5Check proxy #if MIN_VERSION_base(4,19,0) - 0x552eca9ce2e4a34e74deff571f279fc4 + 0xdff58fe5e7f9568c67cd982eaba7edc2 #else - 0x48497d6b3f15df06f1107b81b98febe1 + 0x4e50a4a95779b862edde3d6696797251 #endif diff --git a/changelog.d/pr-9878 b/changelog.d/pr-9878 new file mode 100644 index 00000000000..c4c5de13f61 --- /dev/null +++ b/changelog.d/pr-9878 @@ -0,0 +1,8 @@ +synopsis: Add mhs as a known Haskell compiler +packages: Cabal +issues: +prs: #9878 + +description: { +This simply add MHS to the enumeration of known Haskell compilers. +} From e478f12b66b408962f37f065a6488536b87b6ebc Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Fri, 14 Jun 2024 10:43:15 +0100 Subject: [PATCH 015/207] perf: Group together packages by repo when verifying tarballs verifyFetchedTarball has the effect of deserialising the index tarball (see call to Sec.withIndex). verifyFetchedTarball is called individually for each package in the build plan (see ProjectPlanning.hs). Not once per repo. The hackage tarball is now 880mb so it takes a non significant amount of time to deserialise this (much better after haskell/tar#95). This code path is important as it can add 1s with these 38 calls on to the initial load of a project and scales linearly with the size of your build tree. Reproducer: Simple project with "lens" dependency deserialises the index tarball 38 times. Solution: Refactor verifyFetchedTarball to run once per repo rather than once per package. In future it would be much better to refactor this function so that the items are not immediately grouped and ungrouped but I didn't want to take that on immediately. Fixes #10110 --- .hlint.yaml | 1 + .../src/Distribution/Client/FetchUtils.hs | 97 ++++++++++++------- .../Distribution/Client/ProjectPlanning.hs | 38 ++++---- .../src/Distribution/Client/Utils.hs | 1 + 4 files changed, 85 insertions(+), 52 deletions(-) diff --git a/.hlint.yaml b/.hlint.yaml index 6266b76964f..0170ee22ebd 100644 --- a/.hlint.yaml +++ b/.hlint.yaml @@ -92,6 +92,7 @@ - ignore: {name: "Use unwords"} # 8 hints - ignore: {name: "Use void"} # 22 hints - ignore: {name: "Use when"} # 1 hint +- ignore: {name: "Use uncurry"} # 1 hint - arguments: - --ignore-glob=Cabal-syntax/src/Distribution/Fields/Lexer.hs diff --git a/cabal-install/src/Distribution/Client/FetchUtils.hs b/cabal-install/src/Distribution/Client/FetchUtils.hs index c804040cab7..62da386573d 100644 --- a/cabal-install/src/Distribution/Client/FetchUtils.hs +++ b/cabal-install/src/Distribution/Client/FetchUtils.hs @@ -25,7 +25,7 @@ module Distribution.Client.FetchUtils -- ** specifically for repo packages , checkRepoTarballFetched , fetchRepoTarball - , verifyFetchedTarball + , verifyFetchedTarballs -- ** fetching packages asynchronously , asyncFetchPackages @@ -98,6 +98,7 @@ import System.IO , openTempFile ) +import Control.Monad (forM) import Distribution.Client.Errors import qualified Hackage.Security.Client as Sec import qualified Hackage.Security.Util.Checked as Sec @@ -152,40 +153,66 @@ checkRepoTarballFetched repo pkgid = do then return (Just file) else return Nothing -verifyFetchedTarball :: Verbosity -> RepoContext -> Repo -> PackageId -> IO Bool -verifyFetchedTarball verbosity repoCtxt repo pkgid = - let file = packageFile repo pkgid - handleError :: IO Bool -> IO Bool - handleError act = do - res <- Safe.try act - case res of - Left e -> warn verbosity ("Error verifying fetched tarball " ++ file ++ ", will redownload: " ++ show (e :: SomeException)) >> pure False - Right b -> pure b - in handleError $ do - exists <- doesFileExist file - if not exists - then return True -- if the file does not exist, it vacuously passes validation, since it will be downloaded as necessary with what we will then check is a valid hash. - else case repo of - -- a secure repo has hashes we can compare against to confirm this is the correct file. - RepoSecure{} -> - repoContextWithSecureRepo repoCtxt repo $ \repoSecure -> - Sec.withIndex repoSecure $ \callbacks -> - let warnAndFail s = warn verbosity ("Fetched tarball " ++ file ++ " does not match server, will redownload: " ++ s) >> return False - in -- the do block in parens is due to dealing with the checked exceptions mechanism. - ( do - fileInfo <- Sec.indexLookupFileInfo callbacks pkgid - sz <- Sec.FileLength . fromInteger <$> getFileSize file - if sz /= Sec.fileInfoLength (Sec.trusted fileInfo) - then warnAndFail "file length mismatch" - else do - res <- Sec.compareTrustedFileInfo (Sec.trusted fileInfo) <$> Sec.computeFileInfo (Sec.Path file :: Sec.Path Sec.Absolute) - if res - then pure True - else warnAndFail "file hash mismatch" - ) - `Sec.catchChecked` (\(e :: Sec.InvalidPackageException) -> warnAndFail (show e)) - `Sec.catchChecked` (\(e :: Sec.VerificationError) -> warnAndFail (show e)) - _ -> pure True +verifyFetchedTarballs + :: Verbosity + -> RepoContext + -> Repo + -> [PackageId] + -> IO + ( [ Either + (Repo, PackageId) -- Verified + (Repo, PackageId) -- unverified) + ] + ) +verifyFetchedTarballs verbosity repoCtxt repo pkgids = + -- Establish the context once per repo (see #10110), this codepath is important + -- to be fast as it can happen when no other building happens. + let establishContext k = + case repo of + RepoSecure{} -> + repoContextWithSecureRepo repoCtxt repo $ \repoSecure -> + Sec.withIndex repoSecure $ \callbacks -> k (Just callbacks) + _ -> k Nothing + in do + establishContext $ \mCallbacks -> + forM pkgids $ \pkgid -> do + let file = packageFile repo pkgid + res <- verifyFetchedTarball verbosity file mCallbacks pkgid + return $ if res then Left (repo, pkgid) else Right (repo, pkgid) + +verifyFetchedTarball :: Verbosity -> FilePath -> Maybe Sec.IndexCallbacks -> PackageId -> IO Bool +verifyFetchedTarball verbosity file mCallbacks pkgid = + let + handleError :: IO Bool -> IO Bool + handleError act = do + res <- Safe.try act + case res of + Left e -> warn verbosity ("Error verifying fetched tarball " ++ file ++ ", will redownload: " ++ show (e :: SomeException)) >> pure False + Right b -> pure b + in + handleError $ do + exists <- doesFileExist file + if not exists + then return True -- if the file does not exist, it vacuously passes validation, since it will be downloaded as necessary with what we will then check is a valid hash. + else case mCallbacks of + -- a secure repo has hashes we can compare against to confirm this is the correct file. + Just callbacks -> + let warnAndFail s = warn verbosity ("Fetched tarball " ++ file ++ " does not match server, will redownload: " ++ s) >> return False + in -- the do block in parens is due to dealing with the checked exceptions mechanism. + ( do + fileInfo <- Sec.indexLookupFileInfo callbacks pkgid + sz <- Sec.FileLength . fromInteger <$> getFileSize file + if sz /= Sec.fileInfoLength (Sec.trusted fileInfo) + then warnAndFail "file length mismatch" + else do + res <- Sec.compareTrustedFileInfo (Sec.trusted fileInfo) <$> Sec.computeFileInfo (Sec.Path file :: Sec.Path Sec.Absolute) + if res + then pure True + else warnAndFail "file hash mismatch" + ) + `Sec.catchChecked` (\(e :: Sec.InvalidPackageException) -> warnAndFail (show e)) + `Sec.catchChecked` (\(e :: Sec.VerificationError) -> warnAndFail (show e)) + _ -> pure True -- | Fetch a package if we don't have it already. fetchPackage diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 6b77531b8a5..efc4ebbd1e4 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -127,7 +127,7 @@ import Distribution.Client.SetupWrapper import Distribution.Client.Store import Distribution.Client.Targets (userToPackageConstraint) import Distribution.Client.Types -import Distribution.Client.Utils (incVersion) +import Distribution.Client.Utils (concatMapM, incVersion) import qualified Distribution.Client.BuildReports.Storage as BuildReports import qualified Distribution.Client.IndexUtils as IndexUtils @@ -206,7 +206,7 @@ import qualified Distribution.Solver.Types.ComponentDeps as CD import qualified Distribution.Compat.Graph as Graph import Control.Exception (assert) -import Control.Monad (forM, sequence) +import Control.Monad (sequence) import Control.Monad.IO.Class (liftIO) import Control.Monad.State as State (State, execState, runState, state) import Data.Foldable (fold) @@ -1069,25 +1069,29 @@ getPackageSourceHashes verbosity withRepoCtx solverPlan = do -- Tarballs from repositories, either where the repository provides -- hashes as part of the repo metadata, or where we will have to -- download and hash the tarball. - repoTarballPkgsWithMetadataUnvalidated :: [(PackageId, Repo)] - repoTarballPkgsWithoutMetadata :: [(PackageId, Repo)] + repoTarballPkgsWithMetadataUnvalidated :: [(Repo, [PackageId])] + repoTarballPkgsWithoutMetadata :: [(Repo, PackageId)] ( repoTarballPkgsWithMetadataUnvalidated , repoTarballPkgsWithoutMetadata ) = partitionEithers [ case repo of - RepoSecure{} -> Left (pkgid, repo) - _ -> Right (pkgid, repo) + RepoSecure{} -> Left (repo, [pkgid]) + _ -> Right (repo, pkgid) | (pkgid, RepoTarballPackage repo _ _) <- allPkgLocations ] + -- Group up the unvalidated packages by repo so we only read the remote + -- index once per repo (see #10110). The packages are ungrouped here and then regrouped + -- below, it would be better in future to refactor this whole code path so that we don't + -- repeatedly group and ungroup. + repoTarballPkgsWithMetadataUnvalidatedMap = Map.fromListWith (++) repoTarballPkgsWithMetadataUnvalidated + (repoTarballPkgsWithMetadata, repoTarballPkgsToDownloadWithMeta) <- fmap partitionEithers $ liftIO $ - withRepoCtx $ \repoctx -> forM repoTarballPkgsWithMetadataUnvalidated $ - \x@(pkg, repo) -> - verifyFetchedTarball verbosity repoctx repo pkg >>= \b -> case b of - True -> return $ Left x - False -> return $ Right x + withRepoCtx $ \repoctx -> flip concatMapM (Map.toList repoTarballPkgsWithMetadataUnvalidatedMap) $ + \(repo, pkgids) -> + verifyFetchedTarballs verbosity repoctx repo pkgids -- For tarballs from repos that do not have hashes available we now have -- to check if the packages were downloaded already. @@ -1101,9 +1105,9 @@ getPackageSourceHashes verbosity withRepoCtx solverPlan = do [ do mtarball <- checkRepoTarballFetched repo pkgid case mtarball of - Nothing -> return (Left (pkgid, repo)) + Nothing -> return (Left (repo, pkgid)) Just tarball -> return (Right (pkgid, tarball)) - | (pkgid, repo) <- repoTarballPkgsWithoutMetadata + | (repo, pkgid) <- repoTarballPkgsWithoutMetadata ] let repoTarballPkgsToDownload = repoTarballPkgsToDownloadWithMeta ++ repoTarballPkgsToDownloadWithNoMeta @@ -1139,9 +1143,9 @@ getPackageSourceHashes verbosity withRepoCtx solverPlan = do | pkgid <- pkgids ] | (repo, pkgids) <- - map (\grp@((_, repo) :| _) -> (repo, map fst (NE.toList grp))) - . NE.groupBy ((==) `on` (remoteRepoName . repoRemote . snd)) - . sortBy (compare `on` (remoteRepoName . repoRemote . snd)) + map (\grp@((repo, _) :| _) -> (repo, map snd (NE.toList grp))) + . NE.groupBy ((==) `on` (remoteRepoName . repoRemote . fst)) + . sortBy (compare `on` (remoteRepoName . repoRemote . fst)) $ repoTarballPkgsWithMetadata ] @@ -1153,7 +1157,7 @@ getPackageSourceHashes verbosity withRepoCtx solverPlan = do [ do tarball <- fetchRepoTarball verbosity repoctx repo pkgid return (pkgid, tarball) - | (pkgid, repo) <- repoTarballPkgsToDownload + | (repo, pkgid) <- repoTarballPkgsToDownload ] return diff --git a/cabal-install/src/Distribution/Client/Utils.hs b/cabal-install/src/Distribution/Client/Utils.hs index 87378da7f10..69d46f8a473 100644 --- a/cabal-install/src/Distribution/Client/Utils.hs +++ b/cabal-install/src/Distribution/Client/Utils.hs @@ -38,6 +38,7 @@ module Distribution.Client.Utils , listFilesInside , safeRead , hasElem + , concatMapM , occursOnlyOrBefore , giveRTSWarning ) where From d780adc134e3ce4a462d7f093adb69be895be1df Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Mon, 17 Jun 2024 16:45:05 +0100 Subject: [PATCH 016/207] Bump index state to allow tar-0.6.3.0 tar-0.6.3.0 has much improved performance of deserialising .tar index which has significant ramifications for the start-up time of cabal-install. See #10110 --- cabal.release.project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cabal.release.project b/cabal.release.project index 3d73d2f19a1..5ce38e721a5 100644 --- a/cabal.release.project +++ b/cabal.release.project @@ -2,4 +2,4 @@ import: project-cabal/pkgs/cabal.config import: project-cabal/pkgs/install.config import: project-cabal/pkgs/tests.config -index-state: hackage.haskell.org 2024-04-22T06:16:57Z +index-state: hackage.haskell.org 2024-06-17T00:00:01Z From 9b44f122313788f5fd9908155d47e8e302c450ae Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Mon, 17 Jun 2024 18:15:42 +0100 Subject: [PATCH 017/207] Update bootstrap plans to include tar-0.6.3 Using the updated version of this library improves performance of cabal-install so it's worthwhile to make sure the bootstrap plans use this version. --- bootstrap/generate_bootstrap_plans | 2 +- bootstrap/linux-8.10.7.json | 1145 ++++++++++++++-------------- bootstrap/linux-9.0.2.json | 1145 ++++++++++++++-------------- bootstrap/linux-9.2.8.json | 1065 +++++++++++++------------- bootstrap/linux-9.4.8.json | 1045 ++++++++++++------------- bootstrap/linux-9.6.4.json | 985 ++++++++++++------------ bootstrap/linux-9.8.2.json | 973 +++++++++++------------ cabal.bootstrap.project | 2 +- 8 files changed, 3184 insertions(+), 3178 deletions(-) diff --git a/bootstrap/generate_bootstrap_plans b/bootstrap/generate_bootstrap_plans index d10b958deb5..de77e9944dd 100755 --- a/bootstrap/generate_bootstrap_plans +++ b/bootstrap/generate_bootstrap_plans @@ -3,7 +3,7 @@ PATH+=:$PWD/jq-bin/bin ghcs_nix="https://gitlab.haskell.org/bgamari/ghcs-nix/-/archive/master/ghcs-nix-master.tar.gz" -nix build -f "$ghcs_nix" ghc-8_10_7 -o boot_ghc +nix build -f "$ghcs_nix" ghc-9_6_5 -o boot_ghc run() { local ver="$1" diff --git a/bootstrap/linux-8.10.7.json b/bootstrap/linux-8.10.7.json index 64f1d42ec7c..b1a2eef78f4 100644 --- a/bootstrap/linux-8.10.7.json +++ b/bootstrap/linux-8.10.7.json @@ -1,574 +1,575 @@ { - "builtin": [ - { - "package": "rts", - "version": "1.0.1" - }, - { - "package": "ghc-prim", - "version": "0.6.1" - }, - { - "package": "integer-gmp", - "version": "1.0.3.0" - }, - { - "package": "base", - "version": "4.14.3.0" - }, - { - "package": "array", - "version": "0.5.4.0" - }, - { - "package": "deepseq", - "version": "1.4.4.0" - }, - { - "package": "containers", - "version": "0.6.5.1" - }, - { - "package": "ghc-boot-th", - "version": "8.10.7" - }, - { - "package": "pretty", - "version": "1.1.3.6" - }, - { - "package": "template-haskell", - "version": "2.16.0.0" - }, - { - "package": "transformers", - "version": "0.5.6.2" - }, - { - "package": "mtl", - "version": "2.2.2" - }, - { - "package": "stm", - "version": "2.5.0.1" - }, - { - "package": "exceptions", - "version": "0.10.4" - }, - { - "package": "time", - "version": "1.9.3" - } - ], - "dependencies": [ - { - "cabal_sha256": "a4a1975fde77e289b605c45a3ef78d731d8c1834e4cef311152d910a1e94d98c", - "component": "lib:data-array-byte", - "flags": [], - "package": "data-array-byte", - "revision": 3, - "source": "hackage", - "src_sha256": "1bb6eca0b3e02d057fe7f4e14c81ef395216f421ab30fdaa1b18017c9c025600", - "version": "0.1.0.1" - }, - { - "cabal_sha256": "98e79e1c97117143e4012983509ec95f7e5e4f6adff6914d07812a39f83404b9", - "component": "lib:bytestring", - "flags": [ - "-pure-haskell" - ], - "package": "bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "ebc3b8a6ef74a5cd6ddbb8d447d1c9a5fd4964c7975ebcae0b8ab0bcc406cc8c", - "version": "0.12.1.0" - }, - { - "cabal_sha256": "d9e181e1acae0ac505d8b217dec3805c68554878f1e32b3d8351b9ce17061623", - "component": "lib:filepath", - "flags": [ - "-cpphs" - ], - "package": "filepath", - "revision": 0, - "source": "hackage", - "src_sha256": "337a0b5bcf0898cb7f51ff327528cf26f4ac38baed7b66b28fbdea334699d8ed", - "version": "1.4.300.1" - }, - { - "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", - "component": "lib:unix", - "flags": [ - "-os-string" - ], - "package": "unix", - "revision": 0, - "source": "hackage", - "src_sha256": "5ab6c346aef2eb9bf80b4d29ca7e22063fc23e52fd69fbc4d18a9f98b154e424", - "version": "2.8.5.1" - }, - { - "cabal_sha256": "ae1730011f547153bb52139f217d1d524202b3da730a369660fc539e5dcfff31", - "component": "lib:directory", - "flags": [ - "-os-string" - ], - "package": "directory", - "revision": 0, - "source": "hackage", - "src_sha256": "a4e798a4e5339a7aa9577515886271386280bfbc1fe4a29fd4aa6464d4792064", - "version": "1.3.8.4" - }, - { - "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", - "component": "exe:alex", - "flags": [], - "package": "alex", - "revision": 0, - "source": "hackage", - "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", - "version": "3.5.1.0" - }, - { - "cabal_sha256": "03381e511429c44d13990c6d76281c4fc2468371cede4fe684b0c98d9b7d5f5a", - "component": "lib:binary", - "flags": [], - "package": "binary", - "revision": 0, - "source": "hackage", - "src_sha256": "8437116b4eccdba13cb9badb62331c0d4598c3f0252a587e37d8f5990d9bf74c", - "version": "0.8.9.2" - }, - { - "cabal_sha256": "aa7a5a92fe430a34d24d33878323c8a010021e05e410fe98b7fac3015c88dc74", - "component": "lib:text", - "flags": [ - "-developer", - "-pure-haskell", - "+simdutf" - ], - "package": "text", - "revision": 0, - "source": "hackage", - "src_sha256": "e40cdda8b285f4d72476ed35dc2f5f167d524e6b38bb5ec964d00ee1ff24feab", - "version": "2.1.1" - }, - { - "cabal_sha256": "8407cbd428d7f640a0fff8891bd2f7aca13cebe70a5e654856f8abec9a648b56", - "component": "lib:parsec", - "flags": [], - "package": "parsec", - "revision": 1, - "source": "hackage", - "src_sha256": "58c500bec1ec3c849c8243ddfd675a5983b17a8e5da55acea6adade5ae179d36", - "version": "3.1.17.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-syntax", - "flags": [], - "package": "Cabal-syntax", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "7785a72bc140ae5a9ef2439f10637b5fd104999832f1d93328d4973f37cb8469", - "component": "lib:process", - "flags": [], - "package": "process", - "revision": 0, - "source": "hackage", - "src_sha256": "b468355ab46966537eb171ed5593a0a1facc8d2eefc38659e43768f68f5dcb96", - "version": "1.6.19.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal", - "flags": [], - "package": "Cabal", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-hooks", - "flags": [], - "package": "Cabal-hooks", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "0.1" - }, - { - "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", - "component": "exe:hsc2hs", - "flags": [ - "-in-ghc-tree" - ], - "package": "hsc2hs", - "revision": 2, - "source": "hackage", - "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", - "version": "0.68.10" - }, - { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", - "component": "lib:network", - "flags": [ - "-devel" - ], - "package": "network", - "revision": 0, - "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" - }, - { - "cabal_sha256": "0a6ee328b71119d7dfcd004f0ec8feb77e6e78d8f6de1a281568edd3d3b6d83f", - "component": "lib:th-compat", - "flags": [], - "package": "th-compat", - "revision": 1, - "source": "hackage", - "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", - "version": "0.1.5" - }, - { - "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", - "component": "lib:network-uri", - "flags": [], - "package": "network-uri", - "revision": 1, - "source": "hackage", - "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", - "version": "2.6.4.2" - }, - { - "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", - "component": "lib:HTTP", - "flags": [ - "-conduit10", - "+network-uri", - "-warn-as-error", - "-warp-tests" - ], - "package": "HTTP", - "revision": 4, - "source": "hackage", - "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", - "version": "4000.4.1" - }, - { - "cabal_sha256": "c4733d09f798fc4304e936924a1a7d9fc2425aefad6c46ad4592035254b46051", - "component": "lib:base-orphans", - "flags": [], - "package": "base-orphans", - "revision": 0, - "source": "hackage", - "src_sha256": "5bbf2da382c5b212d6a8be2f8c49edee0eba30f272a15fd32c13e6e4091ef172", - "version": "0.9.1" - }, - { - "cabal_sha256": "ae22238274c572aa91e90c6c353e7206386708912ac5e6dc40ac61d1dcc553db", - "component": "lib:hashable", - "flags": [ - "+integer-gmp", - "-random-initial-seed" - ], - "package": "hashable", - "revision": 1, - "source": "hackage", - "src_sha256": "1fa3d64548440942b2b38b99c76d8dcaa94fa2ea3912cd7a6354ea4ec4af4758", - "version": "1.4.4.0" - }, - { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", - "component": "lib:async", - "flags": [ - "-bench" - ], - "package": "async", - "revision": 1, - "source": "hackage", - "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", - "version": "2.2.5" - }, - { - "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", - "component": "lib:base16-bytestring", - "flags": [], - "package": "base16-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", - "version": "1.0.2.0" - }, - { - "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", - "component": "lib:base64-bytestring", - "flags": [], - "package": "base64-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", - "version": "1.2.1.0" - }, - { - "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", - "component": "lib:splitmix", - "flags": [ - "-optimised-mixer" - ], - "package": "splitmix", - "revision": 1, - "source": "hackage", - "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", - "version": "0.1.0.5" - }, - { - "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", - "component": "lib:random", - "flags": [], - "package": "random", - "revision": 0, - "source": "hackage", - "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", - "version": "1.2.1.2" - }, - { - "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", - "component": "lib:edit-distance", - "flags": [], - "package": "edit-distance", - "revision": 1, - "source": "hackage", - "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", - "version": "0.2.2.1" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install-solver", - "flags": [ - "-debug-expensive-assertions", - "-debug-tracetree" - ], - "package": "cabal-install-solver", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", - "component": "lib:cryptohash-sha256", - "flags": [ - "-exe", - "+use-cbits" - ], - "package": "cryptohash-sha256", - "revision": 4, - "source": "hackage", - "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", - "version": "0.11.102.1" - }, - { - "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", - "component": "lib:echo", - "flags": [ - "-example" - ], - "package": "echo", - "revision": 0, - "source": "hackage", - "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", - "version": "0.1.4" - }, - { - "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", - "component": "lib:ed25519", - "flags": [ - "+no-donna", - "+test-doctests", - "+test-hlint", - "+test-properties" - ], - "package": "ed25519", - "revision": 8, - "source": "hackage", - "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", - "version": "0.0.5.0" - }, - { - "cabal_sha256": "17786545dce60c4d5783ba6125c0a6499a1abddd3d7417b15500ccd767c35f07", - "component": "lib:lukko", - "flags": [ - "+ofd-locking" - ], - "package": "lukko", - "revision": 5, - "source": "hackage", - "src_sha256": "a80efb60cfa3dae18682c01980d76d5f7e413e191cd186992e1bf7388d48ab1f", - "version": "0.1.1.3" - }, - { - "cabal_sha256": "32fa47f8345a2c0662fb602fc42e4b674e41ec48079b68bdecb4b6f68032c24e", - "component": "lib:os-string", - "flags": [], - "package": "os-string", - "revision": 0, - "source": "hackage", - "src_sha256": "0953126e962966719753c98d71f596f5fea07e100bce191b7453735a1ff2caa1", - "version": "2.0.2" - }, - { - "cabal_sha256": "619828cae098a7b6deeb0316e12f55011101d88f756787ed024ceedb81cf1eba", - "component": "lib:tar-internal", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "08c61e82b59ed6fe7e85e9fe7cceaaf853ba54511d1ec57efa511ddc55ef1998", - "version": "0.6.2.0" - }, - { - "cabal_sha256": "619828cae098a7b6deeb0316e12f55011101d88f756787ed024ceedb81cf1eba", - "component": "lib:tar", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "08c61e82b59ed6fe7e85e9fe7cceaaf853ba54511d1ec57efa511ddc55ef1998", - "version": "0.6.2.0" - }, - { - "cabal_sha256": "64a1925c93e9a26cd4c40c470736950c4b5ea7bae68418cb996c5c7df4873cba", - "component": "lib:zlib", - "flags": [ - "-bundled-c-zlib", - "+non-blocking-ffi", - "-pkg-config" - ], - "package": "zlib", - "revision": 1, - "source": "hackage", - "src_sha256": "7e43c205e1e1ff5a4b033086ec8cce82ab658879e977c8ba02a6701946ff7a47", - "version": "0.7.0.0" - }, - { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", - "component": "lib:hackage-security", - "flags": [ - "+cabal-syntax", - "+lukko" - ], - "package": "hackage-security", - "revision": 1, - "source": "hackage", - "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", - "version": "0.6.2.6" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "lib:open-browser", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - }, - { - "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", - "component": "lib:regex-base", - "flags": [], - "package": "regex-base", - "revision": 4, - "source": "hackage", - "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", - "version": "0.94.0.2" - }, - { - "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", - "component": "lib:regex-posix", - "flags": [ - "-_regex-posix-clib" - ], - "package": "regex-posix", - "revision": 3, - "source": "hackage", - "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", - "version": "0.96.0.1" - }, - { - "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", - "component": "lib:resolv", - "flags": [], - "package": "resolv", - "revision": 3, - "source": "hackage", - "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", - "version": "0.2.0.2" - }, - { - "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", - "component": "lib:safe-exceptions", - "flags": [], - "package": "safe-exceptions", - "revision": 1, - "source": "hackage", - "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", - "version": "0.1.7.4" - }, - { - "cabal_sha256": "a8f76076a40409a36ee975970c53273c2089aec9d9ece8168dfc736dfec24b9d", - "component": "lib:semaphore-compat", - "flags": [], - "package": "semaphore-compat", - "revision": 2, - "source": "hackage", - "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", - "version": "1.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "exe:cabal", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "exe:example", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - } - ] + "builtin": [ + { + "package": "rts", + "version": "1.0.1" + }, + { + "package": "ghc-prim", + "version": "0.6.1" + }, + { + "package": "integer-gmp", + "version": "1.0.3.0" + }, + { + "package": "base", + "version": "4.14.3.0" + }, + { + "package": "array", + "version": "0.5.4.0" + }, + { + "package": "deepseq", + "version": "1.4.4.0" + }, + { + "package": "containers", + "version": "0.6.5.1" + }, + { + "package": "ghc-boot-th", + "version": "8.10.7" + }, + { + "package": "pretty", + "version": "1.1.3.6" + }, + { + "package": "template-haskell", + "version": "2.16.0.0" + }, + { + "package": "transformers", + "version": "0.5.6.2" + }, + { + "package": "mtl", + "version": "2.2.2" + }, + { + "package": "stm", + "version": "2.5.0.1" + }, + { + "package": "exceptions", + "version": "0.10.4" + }, + { + "package": "time", + "version": "1.9.3" + } + ], + "dependencies": [ + { + "cabal_sha256": "a4a1975fde77e289b605c45a3ef78d731d8c1834e4cef311152d910a1e94d98c", + "component": "lib:data-array-byte", + "flags": [], + "package": "data-array-byte", + "revision": 3, + "source": "hackage", + "src_sha256": "1bb6eca0b3e02d057fe7f4e14c81ef395216f421ab30fdaa1b18017c9c025600", + "version": "0.1.0.1" + }, + { + "cabal_sha256": "98e79e1c97117143e4012983509ec95f7e5e4f6adff6914d07812a39f83404b9", + "component": "lib:bytestring", + "flags": [ + "-pure-haskell" + ], + "package": "bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "ebc3b8a6ef74a5cd6ddbb8d447d1c9a5fd4964c7975ebcae0b8ab0bcc406cc8c", + "version": "0.12.1.0" + }, + { + "cabal_sha256": "345cbb1afe414a09e47737e4d14cbd51891a734e67c0ef3d77a1439518bb81e8", + "component": "lib:filepath", + "flags": [ + "-cpphs" + ], + "package": "filepath", + "revision": 0, + "source": "hackage", + "src_sha256": "88d6452fd199e333e66e68d2dc5d715f5c6d361661a4a8add88320a82864b788", + "version": "1.4.300.2" + }, + { + "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", + "component": "lib:unix", + "flags": [ + "-os-string" + ], + "package": "unix", + "revision": 0, + "source": "hackage", + "src_sha256": "5ab6c346aef2eb9bf80b4d29ca7e22063fc23e52fd69fbc4d18a9f98b154e424", + "version": "2.8.5.1" + }, + { + "cabal_sha256": "fbeec9ec346e5272167f63dcb86af513b457a7b9fc36dc818e4c7b81608d612b", + "component": "lib:directory", + "flags": [ + "-os-string" + ], + "package": "directory", + "revision": 0, + "source": "hackage", + "src_sha256": "e864ed54ddfc6e15d2eb02c87f4be8edd7719e1f9cea13e0f86909400b6ea768", + "version": "1.3.8.5" + }, + { + "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", + "component": "exe:alex", + "flags": [], + "package": "alex", + "revision": 0, + "source": "hackage", + "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", + "version": "3.5.1.0" + }, + { + "cabal_sha256": "03381e511429c44d13990c6d76281c4fc2468371cede4fe684b0c98d9b7d5f5a", + "component": "lib:binary", + "flags": [], + "package": "binary", + "revision": 0, + "source": "hackage", + "src_sha256": "8437116b4eccdba13cb9badb62331c0d4598c3f0252a587e37d8f5990d9bf74c", + "version": "0.8.9.2" + }, + { + "cabal_sha256": "78c3fb91055d0607a80453327f087b9dc82168d41d0dca3ff410d21033b5e87d", + "component": "lib:text", + "flags": [ + "-developer", + "-pure-haskell", + "+simdutf" + ], + "package": "text", + "revision": 1, + "source": "hackage", + "src_sha256": "e40cdda8b285f4d72476ed35dc2f5f167d524e6b38bb5ec964d00ee1ff24feab", + "version": "2.1.1" + }, + { + "cabal_sha256": "8407cbd428d7f640a0fff8891bd2f7aca13cebe70a5e654856f8abec9a648b56", + "component": "lib:parsec", + "flags": [], + "package": "parsec", + "revision": 1, + "source": "hackage", + "src_sha256": "58c500bec1ec3c849c8243ddfd675a5983b17a8e5da55acea6adade5ae179d36", + "version": "3.1.17.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-syntax", + "flags": [], + "package": "Cabal-syntax", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "2a9393de33f18415fb8f4826957a87a94ffe8840ca8472a9b69dca6de45aca03", + "component": "lib:process", + "flags": [], + "package": "process", + "revision": 1, + "source": "hackage", + "src_sha256": "cefda221c3009fa2316b5cf148215cb340dad7eb8503f22e49e33722559df99a", + "version": "1.6.20.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal", + "flags": [], + "package": "Cabal", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-hooks", + "flags": [], + "package": "Cabal-hooks", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "0.1" + }, + { + "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", + "component": "exe:hsc2hs", + "flags": [ + "-in-ghc-tree" + ], + "package": "hsc2hs", + "revision": 2, + "source": "hackage", + "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", + "version": "0.68.10" + }, + { + "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", + "component": "lib:network", + "flags": [ + "-devel" + ], + "package": "network", + "revision": 0, + "source": "hackage", + "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", + "version": "3.2.0.0" + }, + { + "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", + "component": "lib:th-compat", + "flags": [], + "package": "th-compat", + "revision": 2, + "source": "hackage", + "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", + "version": "0.1.5" + }, + { + "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", + "component": "lib:network-uri", + "flags": [], + "package": "network-uri", + "revision": 1, + "source": "hackage", + "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", + "version": "2.6.4.2" + }, + { + "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", + "component": "lib:HTTP", + "flags": [ + "-conduit10", + "+network-uri", + "-warn-as-error", + "-warp-tests" + ], + "package": "HTTP", + "revision": 4, + "source": "hackage", + "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", + "version": "4000.4.1" + }, + { + "cabal_sha256": "455d863c96cf4b1804772c630a235f535fdb52ca9137a4150967b521ee4734ab", + "component": "lib:base-orphans", + "flags": [], + "package": "base-orphans", + "revision": 0, + "source": "hackage", + "src_sha256": "6211900916955b84687c61b5e4fa98ce110e511a96086b7a93f06dd63c97ba93", + "version": "0.9.2" + }, + { + "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", + "component": "lib:hashable", + "flags": [ + "+arch-native", + "+integer-gmp", + "-random-initial-seed" + ], + "package": "hashable", + "revision": 0, + "source": "hackage", + "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", + "version": "1.4.6.0" + }, + { + "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", + "component": "lib:async", + "flags": [ + "-bench" + ], + "package": "async", + "revision": 1, + "source": "hackage", + "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", + "version": "2.2.5" + }, + { + "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", + "component": "lib:base16-bytestring", + "flags": [], + "package": "base16-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", + "version": "1.0.2.0" + }, + { + "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", + "component": "lib:base64-bytestring", + "flags": [], + "package": "base64-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", + "version": "1.2.1.0" + }, + { + "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", + "component": "lib:splitmix", + "flags": [ + "-optimised-mixer" + ], + "package": "splitmix", + "revision": 1, + "source": "hackage", + "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", + "version": "0.1.0.5" + }, + { + "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", + "component": "lib:random", + "flags": [], + "package": "random", + "revision": 0, + "source": "hackage", + "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", + "version": "1.2.1.2" + }, + { + "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", + "component": "lib:edit-distance", + "flags": [], + "package": "edit-distance", + "revision": 1, + "source": "hackage", + "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", + "version": "0.2.2.1" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install-solver", + "flags": [ + "-debug-expensive-assertions", + "-debug-tracetree" + ], + "package": "cabal-install-solver", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", + "component": "lib:cryptohash-sha256", + "flags": [ + "-exe", + "+use-cbits" + ], + "package": "cryptohash-sha256", + "revision": 4, + "source": "hackage", + "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", + "version": "0.11.102.1" + }, + { + "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", + "component": "lib:echo", + "flags": [ + "-example" + ], + "package": "echo", + "revision": 0, + "source": "hackage", + "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", + "version": "0.1.4" + }, + { + "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", + "component": "lib:ed25519", + "flags": [ + "+no-donna", + "+test-doctests", + "+test-hlint", + "+test-properties" + ], + "package": "ed25519", + "revision": 8, + "source": "hackage", + "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", + "version": "0.0.5.0" + }, + { + "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", + "component": "lib:lukko", + "flags": [ + "+ofd-locking" + ], + "package": "lukko", + "revision": 0, + "source": "hackage", + "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", + "version": "0.1.2" + }, + { + "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", + "component": "lib:os-string", + "flags": [], + "package": "os-string", + "revision": 0, + "source": "hackage", + "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", + "version": "2.0.3" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar-internal", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", + "component": "lib:zlib", + "flags": [ + "-bundled-c-zlib", + "+non-blocking-ffi", + "-pkg-config" + ], + "package": "zlib", + "revision": 0, + "source": "hackage", + "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", + "version": "0.7.1.0" + }, + { + "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", + "component": "lib:hackage-security", + "flags": [ + "+cabal-syntax", + "+lukko" + ], + "package": "hackage-security", + "revision": 1, + "source": "hackage", + "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", + "version": "0.6.2.6" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "lib:open-browser", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + }, + { + "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", + "component": "lib:regex-base", + "flags": [], + "package": "regex-base", + "revision": 4, + "source": "hackage", + "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", + "version": "0.94.0.2" + }, + { + "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", + "component": "lib:regex-posix", + "flags": [ + "-_regex-posix-clib" + ], + "package": "regex-posix", + "revision": 3, + "source": "hackage", + "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", + "version": "0.96.0.1" + }, + { + "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", + "component": "lib:resolv", + "flags": [], + "package": "resolv", + "revision": 3, + "source": "hackage", + "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", + "version": "0.2.0.2" + }, + { + "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", + "component": "lib:safe-exceptions", + "flags": [], + "package": "safe-exceptions", + "revision": 1, + "source": "hackage", + "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", + "version": "0.1.7.4" + }, + { + "cabal_sha256": "2de5218cef72b8ef090bd7d0fd930ffa143242a120c62e013b5cf039858f1855", + "component": "lib:semaphore-compat", + "flags": [], + "package": "semaphore-compat", + "revision": 3, + "source": "hackage", + "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", + "version": "1.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "exe:cabal", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "exe:example", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + } + ] } diff --git a/bootstrap/linux-9.0.2.json b/bootstrap/linux-9.0.2.json index 8db81ee3aa1..eb885f6b305 100644 --- a/bootstrap/linux-9.0.2.json +++ b/bootstrap/linux-9.0.2.json @@ -1,574 +1,575 @@ { - "builtin": [ - { - "package": "rts", - "version": "1.0.2" - }, - { - "package": "ghc-prim", - "version": "0.7.0" - }, - { - "package": "ghc-bignum", - "version": "1.1" - }, - { - "package": "base", - "version": "4.15.1.0" - }, - { - "package": "array", - "version": "0.5.4.0" - }, - { - "package": "deepseq", - "version": "1.4.5.0" - }, - { - "package": "containers", - "version": "0.6.4.1" - }, - { - "package": "ghc-boot-th", - "version": "9.0.2" - }, - { - "package": "pretty", - "version": "1.1.3.6" - }, - { - "package": "template-haskell", - "version": "2.17.0.0" - }, - { - "package": "transformers", - "version": "0.5.6.2" - }, - { - "package": "mtl", - "version": "2.2.2" - }, - { - "package": "stm", - "version": "2.5.0.0" - }, - { - "package": "exceptions", - "version": "0.10.4" - }, - { - "package": "time", - "version": "1.9.3" - } - ], - "dependencies": [ - { - "cabal_sha256": "a4a1975fde77e289b605c45a3ef78d731d8c1834e4cef311152d910a1e94d98c", - "component": "lib:data-array-byte", - "flags": [], - "package": "data-array-byte", - "revision": 3, - "source": "hackage", - "src_sha256": "1bb6eca0b3e02d057fe7f4e14c81ef395216f421ab30fdaa1b18017c9c025600", - "version": "0.1.0.1" - }, - { - "cabal_sha256": "98e79e1c97117143e4012983509ec95f7e5e4f6adff6914d07812a39f83404b9", - "component": "lib:bytestring", - "flags": [ - "-pure-haskell" - ], - "package": "bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "ebc3b8a6ef74a5cd6ddbb8d447d1c9a5fd4964c7975ebcae0b8ab0bcc406cc8c", - "version": "0.12.1.0" - }, - { - "cabal_sha256": "d9e181e1acae0ac505d8b217dec3805c68554878f1e32b3d8351b9ce17061623", - "component": "lib:filepath", - "flags": [ - "-cpphs" - ], - "package": "filepath", - "revision": 0, - "source": "hackage", - "src_sha256": "337a0b5bcf0898cb7f51ff327528cf26f4ac38baed7b66b28fbdea334699d8ed", - "version": "1.4.300.1" - }, - { - "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", - "component": "lib:unix", - "flags": [ - "-os-string" - ], - "package": "unix", - "revision": 0, - "source": "hackage", - "src_sha256": "5ab6c346aef2eb9bf80b4d29ca7e22063fc23e52fd69fbc4d18a9f98b154e424", - "version": "2.8.5.1" - }, - { - "cabal_sha256": "ae1730011f547153bb52139f217d1d524202b3da730a369660fc539e5dcfff31", - "component": "lib:directory", - "flags": [ - "-os-string" - ], - "package": "directory", - "revision": 0, - "source": "hackage", - "src_sha256": "a4e798a4e5339a7aa9577515886271386280bfbc1fe4a29fd4aa6464d4792064", - "version": "1.3.8.4" - }, - { - "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", - "component": "exe:alex", - "flags": [], - "package": "alex", - "revision": 0, - "source": "hackage", - "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", - "version": "3.5.1.0" - }, - { - "cabal_sha256": "03381e511429c44d13990c6d76281c4fc2468371cede4fe684b0c98d9b7d5f5a", - "component": "lib:binary", - "flags": [], - "package": "binary", - "revision": 0, - "source": "hackage", - "src_sha256": "8437116b4eccdba13cb9badb62331c0d4598c3f0252a587e37d8f5990d9bf74c", - "version": "0.8.9.2" - }, - { - "cabal_sha256": "aa7a5a92fe430a34d24d33878323c8a010021e05e410fe98b7fac3015c88dc74", - "component": "lib:text", - "flags": [ - "-developer", - "-pure-haskell", - "+simdutf" - ], - "package": "text", - "revision": 0, - "source": "hackage", - "src_sha256": "e40cdda8b285f4d72476ed35dc2f5f167d524e6b38bb5ec964d00ee1ff24feab", - "version": "2.1.1" - }, - { - "cabal_sha256": "8407cbd428d7f640a0fff8891bd2f7aca13cebe70a5e654856f8abec9a648b56", - "component": "lib:parsec", - "flags": [], - "package": "parsec", - "revision": 1, - "source": "hackage", - "src_sha256": "58c500bec1ec3c849c8243ddfd675a5983b17a8e5da55acea6adade5ae179d36", - "version": "3.1.17.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-syntax", - "flags": [], - "package": "Cabal-syntax", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "7785a72bc140ae5a9ef2439f10637b5fd104999832f1d93328d4973f37cb8469", - "component": "lib:process", - "flags": [], - "package": "process", - "revision": 0, - "source": "hackage", - "src_sha256": "b468355ab46966537eb171ed5593a0a1facc8d2eefc38659e43768f68f5dcb96", - "version": "1.6.19.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal", - "flags": [], - "package": "Cabal", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-hooks", - "flags": [], - "package": "Cabal-hooks", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "0.1" - }, - { - "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", - "component": "exe:hsc2hs", - "flags": [ - "-in-ghc-tree" - ], - "package": "hsc2hs", - "revision": 2, - "source": "hackage", - "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", - "version": "0.68.10" - }, - { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", - "component": "lib:network", - "flags": [ - "-devel" - ], - "package": "network", - "revision": 0, - "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" - }, - { - "cabal_sha256": "0a6ee328b71119d7dfcd004f0ec8feb77e6e78d8f6de1a281568edd3d3b6d83f", - "component": "lib:th-compat", - "flags": [], - "package": "th-compat", - "revision": 1, - "source": "hackage", - "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", - "version": "0.1.5" - }, - { - "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", - "component": "lib:network-uri", - "flags": [], - "package": "network-uri", - "revision": 1, - "source": "hackage", - "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", - "version": "2.6.4.2" - }, - { - "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", - "component": "lib:HTTP", - "flags": [ - "-conduit10", - "+network-uri", - "-warn-as-error", - "-warp-tests" - ], - "package": "HTTP", - "revision": 4, - "source": "hackage", - "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", - "version": "4000.4.1" - }, - { - "cabal_sha256": "c4733d09f798fc4304e936924a1a7d9fc2425aefad6c46ad4592035254b46051", - "component": "lib:base-orphans", - "flags": [], - "package": "base-orphans", - "revision": 0, - "source": "hackage", - "src_sha256": "5bbf2da382c5b212d6a8be2f8c49edee0eba30f272a15fd32c13e6e4091ef172", - "version": "0.9.1" - }, - { - "cabal_sha256": "ae22238274c572aa91e90c6c353e7206386708912ac5e6dc40ac61d1dcc553db", - "component": "lib:hashable", - "flags": [ - "+integer-gmp", - "-random-initial-seed" - ], - "package": "hashable", - "revision": 1, - "source": "hackage", - "src_sha256": "1fa3d64548440942b2b38b99c76d8dcaa94fa2ea3912cd7a6354ea4ec4af4758", - "version": "1.4.4.0" - }, - { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", - "component": "lib:async", - "flags": [ - "-bench" - ], - "package": "async", - "revision": 1, - "source": "hackage", - "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", - "version": "2.2.5" - }, - { - "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", - "component": "lib:base16-bytestring", - "flags": [], - "package": "base16-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", - "version": "1.0.2.0" - }, - { - "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", - "component": "lib:base64-bytestring", - "flags": [], - "package": "base64-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", - "version": "1.2.1.0" - }, - { - "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", - "component": "lib:splitmix", - "flags": [ - "-optimised-mixer" - ], - "package": "splitmix", - "revision": 1, - "source": "hackage", - "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", - "version": "0.1.0.5" - }, - { - "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", - "component": "lib:random", - "flags": [], - "package": "random", - "revision": 0, - "source": "hackage", - "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", - "version": "1.2.1.2" - }, - { - "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", - "component": "lib:edit-distance", - "flags": [], - "package": "edit-distance", - "revision": 1, - "source": "hackage", - "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", - "version": "0.2.2.1" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install-solver", - "flags": [ - "-debug-expensive-assertions", - "-debug-tracetree" - ], - "package": "cabal-install-solver", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", - "component": "lib:cryptohash-sha256", - "flags": [ - "-exe", - "+use-cbits" - ], - "package": "cryptohash-sha256", - "revision": 4, - "source": "hackage", - "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", - "version": "0.11.102.1" - }, - { - "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", - "component": "lib:echo", - "flags": [ - "-example" - ], - "package": "echo", - "revision": 0, - "source": "hackage", - "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", - "version": "0.1.4" - }, - { - "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", - "component": "lib:ed25519", - "flags": [ - "+no-donna", - "+test-doctests", - "+test-hlint", - "+test-properties" - ], - "package": "ed25519", - "revision": 8, - "source": "hackage", - "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", - "version": "0.0.5.0" - }, - { - "cabal_sha256": "17786545dce60c4d5783ba6125c0a6499a1abddd3d7417b15500ccd767c35f07", - "component": "lib:lukko", - "flags": [ - "+ofd-locking" - ], - "package": "lukko", - "revision": 5, - "source": "hackage", - "src_sha256": "a80efb60cfa3dae18682c01980d76d5f7e413e191cd186992e1bf7388d48ab1f", - "version": "0.1.1.3" - }, - { - "cabal_sha256": "32fa47f8345a2c0662fb602fc42e4b674e41ec48079b68bdecb4b6f68032c24e", - "component": "lib:os-string", - "flags": [], - "package": "os-string", - "revision": 0, - "source": "hackage", - "src_sha256": "0953126e962966719753c98d71f596f5fea07e100bce191b7453735a1ff2caa1", - "version": "2.0.2" - }, - { - "cabal_sha256": "619828cae098a7b6deeb0316e12f55011101d88f756787ed024ceedb81cf1eba", - "component": "lib:tar-internal", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "08c61e82b59ed6fe7e85e9fe7cceaaf853ba54511d1ec57efa511ddc55ef1998", - "version": "0.6.2.0" - }, - { - "cabal_sha256": "619828cae098a7b6deeb0316e12f55011101d88f756787ed024ceedb81cf1eba", - "component": "lib:tar", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "08c61e82b59ed6fe7e85e9fe7cceaaf853ba54511d1ec57efa511ddc55ef1998", - "version": "0.6.2.0" - }, - { - "cabal_sha256": "64a1925c93e9a26cd4c40c470736950c4b5ea7bae68418cb996c5c7df4873cba", - "component": "lib:zlib", - "flags": [ - "-bundled-c-zlib", - "+non-blocking-ffi", - "-pkg-config" - ], - "package": "zlib", - "revision": 1, - "source": "hackage", - "src_sha256": "7e43c205e1e1ff5a4b033086ec8cce82ab658879e977c8ba02a6701946ff7a47", - "version": "0.7.0.0" - }, - { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", - "component": "lib:hackage-security", - "flags": [ - "+cabal-syntax", - "+lukko" - ], - "package": "hackage-security", - "revision": 1, - "source": "hackage", - "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", - "version": "0.6.2.6" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "lib:open-browser", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - }, - { - "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", - "component": "lib:regex-base", - "flags": [], - "package": "regex-base", - "revision": 4, - "source": "hackage", - "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", - "version": "0.94.0.2" - }, - { - "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", - "component": "lib:regex-posix", - "flags": [ - "-_regex-posix-clib" - ], - "package": "regex-posix", - "revision": 3, - "source": "hackage", - "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", - "version": "0.96.0.1" - }, - { - "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", - "component": "lib:resolv", - "flags": [], - "package": "resolv", - "revision": 3, - "source": "hackage", - "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", - "version": "0.2.0.2" - }, - { - "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", - "component": "lib:safe-exceptions", - "flags": [], - "package": "safe-exceptions", - "revision": 1, - "source": "hackage", - "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", - "version": "0.1.7.4" - }, - { - "cabal_sha256": "a8f76076a40409a36ee975970c53273c2089aec9d9ece8168dfc736dfec24b9d", - "component": "lib:semaphore-compat", - "flags": [], - "package": "semaphore-compat", - "revision": 2, - "source": "hackage", - "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", - "version": "1.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "exe:cabal", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "exe:example", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - } - ] + "builtin": [ + { + "package": "rts", + "version": "1.0.2" + }, + { + "package": "ghc-prim", + "version": "0.7.0" + }, + { + "package": "ghc-bignum", + "version": "1.1" + }, + { + "package": "base", + "version": "4.15.1.0" + }, + { + "package": "array", + "version": "0.5.4.0" + }, + { + "package": "deepseq", + "version": "1.4.5.0" + }, + { + "package": "containers", + "version": "0.6.4.1" + }, + { + "package": "ghc-boot-th", + "version": "9.0.2" + }, + { + "package": "pretty", + "version": "1.1.3.6" + }, + { + "package": "template-haskell", + "version": "2.17.0.0" + }, + { + "package": "transformers", + "version": "0.5.6.2" + }, + { + "package": "mtl", + "version": "2.2.2" + }, + { + "package": "stm", + "version": "2.5.0.0" + }, + { + "package": "exceptions", + "version": "0.10.4" + }, + { + "package": "time", + "version": "1.9.3" + } + ], + "dependencies": [ + { + "cabal_sha256": "a4a1975fde77e289b605c45a3ef78d731d8c1834e4cef311152d910a1e94d98c", + "component": "lib:data-array-byte", + "flags": [], + "package": "data-array-byte", + "revision": 3, + "source": "hackage", + "src_sha256": "1bb6eca0b3e02d057fe7f4e14c81ef395216f421ab30fdaa1b18017c9c025600", + "version": "0.1.0.1" + }, + { + "cabal_sha256": "98e79e1c97117143e4012983509ec95f7e5e4f6adff6914d07812a39f83404b9", + "component": "lib:bytestring", + "flags": [ + "-pure-haskell" + ], + "package": "bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "ebc3b8a6ef74a5cd6ddbb8d447d1c9a5fd4964c7975ebcae0b8ab0bcc406cc8c", + "version": "0.12.1.0" + }, + { + "cabal_sha256": "345cbb1afe414a09e47737e4d14cbd51891a734e67c0ef3d77a1439518bb81e8", + "component": "lib:filepath", + "flags": [ + "-cpphs" + ], + "package": "filepath", + "revision": 0, + "source": "hackage", + "src_sha256": "88d6452fd199e333e66e68d2dc5d715f5c6d361661a4a8add88320a82864b788", + "version": "1.4.300.2" + }, + { + "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", + "component": "lib:unix", + "flags": [ + "-os-string" + ], + "package": "unix", + "revision": 0, + "source": "hackage", + "src_sha256": "5ab6c346aef2eb9bf80b4d29ca7e22063fc23e52fd69fbc4d18a9f98b154e424", + "version": "2.8.5.1" + }, + { + "cabal_sha256": "fbeec9ec346e5272167f63dcb86af513b457a7b9fc36dc818e4c7b81608d612b", + "component": "lib:directory", + "flags": [ + "-os-string" + ], + "package": "directory", + "revision": 0, + "source": "hackage", + "src_sha256": "e864ed54ddfc6e15d2eb02c87f4be8edd7719e1f9cea13e0f86909400b6ea768", + "version": "1.3.8.5" + }, + { + "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", + "component": "exe:alex", + "flags": [], + "package": "alex", + "revision": 0, + "source": "hackage", + "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", + "version": "3.5.1.0" + }, + { + "cabal_sha256": "03381e511429c44d13990c6d76281c4fc2468371cede4fe684b0c98d9b7d5f5a", + "component": "lib:binary", + "flags": [], + "package": "binary", + "revision": 0, + "source": "hackage", + "src_sha256": "8437116b4eccdba13cb9badb62331c0d4598c3f0252a587e37d8f5990d9bf74c", + "version": "0.8.9.2" + }, + { + "cabal_sha256": "78c3fb91055d0607a80453327f087b9dc82168d41d0dca3ff410d21033b5e87d", + "component": "lib:text", + "flags": [ + "-developer", + "-pure-haskell", + "+simdutf" + ], + "package": "text", + "revision": 1, + "source": "hackage", + "src_sha256": "e40cdda8b285f4d72476ed35dc2f5f167d524e6b38bb5ec964d00ee1ff24feab", + "version": "2.1.1" + }, + { + "cabal_sha256": "8407cbd428d7f640a0fff8891bd2f7aca13cebe70a5e654856f8abec9a648b56", + "component": "lib:parsec", + "flags": [], + "package": "parsec", + "revision": 1, + "source": "hackage", + "src_sha256": "58c500bec1ec3c849c8243ddfd675a5983b17a8e5da55acea6adade5ae179d36", + "version": "3.1.17.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-syntax", + "flags": [], + "package": "Cabal-syntax", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "2a9393de33f18415fb8f4826957a87a94ffe8840ca8472a9b69dca6de45aca03", + "component": "lib:process", + "flags": [], + "package": "process", + "revision": 1, + "source": "hackage", + "src_sha256": "cefda221c3009fa2316b5cf148215cb340dad7eb8503f22e49e33722559df99a", + "version": "1.6.20.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal", + "flags": [], + "package": "Cabal", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-hooks", + "flags": [], + "package": "Cabal-hooks", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "0.1" + }, + { + "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", + "component": "exe:hsc2hs", + "flags": [ + "-in-ghc-tree" + ], + "package": "hsc2hs", + "revision": 2, + "source": "hackage", + "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", + "version": "0.68.10" + }, + { + "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", + "component": "lib:network", + "flags": [ + "-devel" + ], + "package": "network", + "revision": 0, + "source": "hackage", + "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", + "version": "3.2.0.0" + }, + { + "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", + "component": "lib:th-compat", + "flags": [], + "package": "th-compat", + "revision": 2, + "source": "hackage", + "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", + "version": "0.1.5" + }, + { + "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", + "component": "lib:network-uri", + "flags": [], + "package": "network-uri", + "revision": 1, + "source": "hackage", + "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", + "version": "2.6.4.2" + }, + { + "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", + "component": "lib:HTTP", + "flags": [ + "-conduit10", + "+network-uri", + "-warn-as-error", + "-warp-tests" + ], + "package": "HTTP", + "revision": 4, + "source": "hackage", + "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", + "version": "4000.4.1" + }, + { + "cabal_sha256": "455d863c96cf4b1804772c630a235f535fdb52ca9137a4150967b521ee4734ab", + "component": "lib:base-orphans", + "flags": [], + "package": "base-orphans", + "revision": 0, + "source": "hackage", + "src_sha256": "6211900916955b84687c61b5e4fa98ce110e511a96086b7a93f06dd63c97ba93", + "version": "0.9.2" + }, + { + "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", + "component": "lib:hashable", + "flags": [ + "+arch-native", + "+integer-gmp", + "-random-initial-seed" + ], + "package": "hashable", + "revision": 0, + "source": "hackage", + "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", + "version": "1.4.6.0" + }, + { + "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", + "component": "lib:async", + "flags": [ + "-bench" + ], + "package": "async", + "revision": 1, + "source": "hackage", + "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", + "version": "2.2.5" + }, + { + "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", + "component": "lib:base16-bytestring", + "flags": [], + "package": "base16-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", + "version": "1.0.2.0" + }, + { + "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", + "component": "lib:base64-bytestring", + "flags": [], + "package": "base64-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", + "version": "1.2.1.0" + }, + { + "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", + "component": "lib:splitmix", + "flags": [ + "-optimised-mixer" + ], + "package": "splitmix", + "revision": 1, + "source": "hackage", + "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", + "version": "0.1.0.5" + }, + { + "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", + "component": "lib:random", + "flags": [], + "package": "random", + "revision": 0, + "source": "hackage", + "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", + "version": "1.2.1.2" + }, + { + "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", + "component": "lib:edit-distance", + "flags": [], + "package": "edit-distance", + "revision": 1, + "source": "hackage", + "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", + "version": "0.2.2.1" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install-solver", + "flags": [ + "-debug-expensive-assertions", + "-debug-tracetree" + ], + "package": "cabal-install-solver", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", + "component": "lib:cryptohash-sha256", + "flags": [ + "-exe", + "+use-cbits" + ], + "package": "cryptohash-sha256", + "revision": 4, + "source": "hackage", + "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", + "version": "0.11.102.1" + }, + { + "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", + "component": "lib:echo", + "flags": [ + "-example" + ], + "package": "echo", + "revision": 0, + "source": "hackage", + "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", + "version": "0.1.4" + }, + { + "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", + "component": "lib:ed25519", + "flags": [ + "+no-donna", + "+test-doctests", + "+test-hlint", + "+test-properties" + ], + "package": "ed25519", + "revision": 8, + "source": "hackage", + "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", + "version": "0.0.5.0" + }, + { + "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", + "component": "lib:lukko", + "flags": [ + "+ofd-locking" + ], + "package": "lukko", + "revision": 0, + "source": "hackage", + "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", + "version": "0.1.2" + }, + { + "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", + "component": "lib:os-string", + "flags": [], + "package": "os-string", + "revision": 0, + "source": "hackage", + "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", + "version": "2.0.3" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar-internal", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", + "component": "lib:zlib", + "flags": [ + "-bundled-c-zlib", + "+non-blocking-ffi", + "-pkg-config" + ], + "package": "zlib", + "revision": 0, + "source": "hackage", + "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", + "version": "0.7.1.0" + }, + { + "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", + "component": "lib:hackage-security", + "flags": [ + "+cabal-syntax", + "+lukko" + ], + "package": "hackage-security", + "revision": 1, + "source": "hackage", + "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", + "version": "0.6.2.6" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "lib:open-browser", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + }, + { + "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", + "component": "lib:regex-base", + "flags": [], + "package": "regex-base", + "revision": 4, + "source": "hackage", + "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", + "version": "0.94.0.2" + }, + { + "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", + "component": "lib:regex-posix", + "flags": [ + "-_regex-posix-clib" + ], + "package": "regex-posix", + "revision": 3, + "source": "hackage", + "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", + "version": "0.96.0.1" + }, + { + "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", + "component": "lib:resolv", + "flags": [], + "package": "resolv", + "revision": 3, + "source": "hackage", + "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", + "version": "0.2.0.2" + }, + { + "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", + "component": "lib:safe-exceptions", + "flags": [], + "package": "safe-exceptions", + "revision": 1, + "source": "hackage", + "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", + "version": "0.1.7.4" + }, + { + "cabal_sha256": "2de5218cef72b8ef090bd7d0fd930ffa143242a120c62e013b5cf039858f1855", + "component": "lib:semaphore-compat", + "flags": [], + "package": "semaphore-compat", + "revision": 3, + "source": "hackage", + "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", + "version": "1.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "exe:cabal", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "exe:example", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + } + ] } diff --git a/bootstrap/linux-9.2.8.json b/bootstrap/linux-9.2.8.json index 17293e6b197..c004593615b 100644 --- a/bootstrap/linux-9.2.8.json +++ b/bootstrap/linux-9.2.8.json @@ -1,534 +1,535 @@ { - "builtin": [ - { - "package": "rts", - "version": "1.0.2" - }, - { - "package": "ghc-prim", - "version": "0.8.0" - }, - { - "package": "ghc-bignum", - "version": "1.2" - }, - { - "package": "base", - "version": "4.16.4.0" - }, - { - "package": "array", - "version": "0.5.4.0" - }, - { - "package": "deepseq", - "version": "1.4.6.1" - }, - { - "package": "containers", - "version": "0.6.5.1" - }, - { - "package": "ghc-boot-th", - "version": "9.2.8" - }, - { - "package": "pretty", - "version": "1.1.3.6" - }, - { - "package": "template-haskell", - "version": "2.18.0.0" - }, - { - "package": "bytestring", - "version": "0.11.4.0" - }, - { - "package": "transformers", - "version": "0.5.6.2" - }, - { - "package": "mtl", - "version": "2.2.2" - }, - { - "package": "stm", - "version": "2.5.0.2" - }, - { - "package": "exceptions", - "version": "0.10.4" - }, - { - "package": "time", - "version": "1.11.1.1" - }, - { - "package": "binary", - "version": "0.8.9.0" - }, - { - "package": "text", - "version": "1.2.5.0" - }, - { - "package": "parsec", - "version": "3.1.15.0" - } - ], - "dependencies": [ - { - "cabal_sha256": "d9e181e1acae0ac505d8b217dec3805c68554878f1e32b3d8351b9ce17061623", - "component": "lib:filepath", - "flags": [ - "-cpphs" - ], - "package": "filepath", - "revision": 0, - "source": "hackage", - "src_sha256": "337a0b5bcf0898cb7f51ff327528cf26f4ac38baed7b66b28fbdea334699d8ed", - "version": "1.4.300.1" - }, - { - "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", - "component": "lib:unix", - "flags": [ - "-os-string" - ], - "package": "unix", - "revision": 0, - "source": "hackage", - "src_sha256": "5ab6c346aef2eb9bf80b4d29ca7e22063fc23e52fd69fbc4d18a9f98b154e424", - "version": "2.8.5.1" - }, - { - "cabal_sha256": "ae1730011f547153bb52139f217d1d524202b3da730a369660fc539e5dcfff31", - "component": "lib:directory", - "flags": [ - "-os-string" - ], - "package": "directory", - "revision": 0, - "source": "hackage", - "src_sha256": "a4e798a4e5339a7aa9577515886271386280bfbc1fe4a29fd4aa6464d4792064", - "version": "1.3.8.4" - }, - { - "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", - "component": "exe:alex", - "flags": [], - "package": "alex", - "revision": 0, - "source": "hackage", - "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", - "version": "3.5.1.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-syntax", - "flags": [], - "package": "Cabal-syntax", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "7785a72bc140ae5a9ef2439f10637b5fd104999832f1d93328d4973f37cb8469", - "component": "lib:process", - "flags": [], - "package": "process", - "revision": 0, - "source": "hackage", - "src_sha256": "b468355ab46966537eb171ed5593a0a1facc8d2eefc38659e43768f68f5dcb96", - "version": "1.6.19.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal", - "flags": [], - "package": "Cabal", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-hooks", - "flags": [], - "package": "Cabal-hooks", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "0.1" - }, - { - "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", - "component": "exe:hsc2hs", - "flags": [ - "-in-ghc-tree" - ], - "package": "hsc2hs", - "revision": 2, - "source": "hackage", - "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", - "version": "0.68.10" - }, - { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", - "component": "lib:network", - "flags": [ - "-devel" - ], - "package": "network", - "revision": 0, - "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" - }, - { - "cabal_sha256": "0a6ee328b71119d7dfcd004f0ec8feb77e6e78d8f6de1a281568edd3d3b6d83f", - "component": "lib:th-compat", - "flags": [], - "package": "th-compat", - "revision": 1, - "source": "hackage", - "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", - "version": "0.1.5" - }, - { - "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", - "component": "lib:network-uri", - "flags": [], - "package": "network-uri", - "revision": 1, - "source": "hackage", - "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", - "version": "2.6.4.2" - }, - { - "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", - "component": "lib:HTTP", - "flags": [ - "-conduit10", - "+network-uri", - "-warn-as-error", - "-warp-tests" - ], - "package": "HTTP", - "revision": 4, - "source": "hackage", - "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", - "version": "4000.4.1" - }, - { - "cabal_sha256": "a4a1975fde77e289b605c45a3ef78d731d8c1834e4cef311152d910a1e94d98c", - "component": "lib:data-array-byte", - "flags": [], - "package": "data-array-byte", - "revision": 3, - "source": "hackage", - "src_sha256": "1bb6eca0b3e02d057fe7f4e14c81ef395216f421ab30fdaa1b18017c9c025600", - "version": "0.1.0.1" - }, - { - "cabal_sha256": "32fa47f8345a2c0662fb602fc42e4b674e41ec48079b68bdecb4b6f68032c24e", - "component": "lib:os-string", - "flags": [], - "package": "os-string", - "revision": 0, - "source": "hackage", - "src_sha256": "0953126e962966719753c98d71f596f5fea07e100bce191b7453735a1ff2caa1", - "version": "2.0.2" - }, - { - "cabal_sha256": "ae22238274c572aa91e90c6c353e7206386708912ac5e6dc40ac61d1dcc553db", - "component": "lib:hashable", - "flags": [ - "+integer-gmp", - "-random-initial-seed" - ], - "package": "hashable", - "revision": 1, - "source": "hackage", - "src_sha256": "1fa3d64548440942b2b38b99c76d8dcaa94fa2ea3912cd7a6354ea4ec4af4758", - "version": "1.4.4.0" - }, - { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", - "component": "lib:async", - "flags": [ - "-bench" - ], - "package": "async", - "revision": 1, - "source": "hackage", - "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", - "version": "2.2.5" - }, - { - "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", - "component": "lib:base16-bytestring", - "flags": [], - "package": "base16-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", - "version": "1.0.2.0" - }, - { - "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", - "component": "lib:base64-bytestring", - "flags": [], - "package": "base64-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", - "version": "1.2.1.0" - }, - { - "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", - "component": "lib:splitmix", - "flags": [ - "-optimised-mixer" - ], - "package": "splitmix", - "revision": 1, - "source": "hackage", - "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", - "version": "0.1.0.5" - }, - { - "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", - "component": "lib:random", - "flags": [], - "package": "random", - "revision": 0, - "source": "hackage", - "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", - "version": "1.2.1.2" - }, - { - "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", - "component": "lib:edit-distance", - "flags": [], - "package": "edit-distance", - "revision": 1, - "source": "hackage", - "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", - "version": "0.2.2.1" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install-solver", - "flags": [ - "-debug-expensive-assertions", - "-debug-tracetree" - ], - "package": "cabal-install-solver", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", - "component": "lib:cryptohash-sha256", - "flags": [ - "-exe", - "+use-cbits" - ], - "package": "cryptohash-sha256", - "revision": 4, - "source": "hackage", - "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", - "version": "0.11.102.1" - }, - { - "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", - "component": "lib:echo", - "flags": [ - "-example" - ], - "package": "echo", - "revision": 0, - "source": "hackage", - "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", - "version": "0.1.4" - }, - { - "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", - "component": "lib:ed25519", - "flags": [ - "+no-donna", - "+test-doctests", - "+test-hlint", - "+test-properties" - ], - "package": "ed25519", - "revision": 8, - "source": "hackage", - "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", - "version": "0.0.5.0" - }, - { - "cabal_sha256": "17786545dce60c4d5783ba6125c0a6499a1abddd3d7417b15500ccd767c35f07", - "component": "lib:lukko", - "flags": [ - "+ofd-locking" - ], - "package": "lukko", - "revision": 5, - "source": "hackage", - "src_sha256": "a80efb60cfa3dae18682c01980d76d5f7e413e191cd186992e1bf7388d48ab1f", - "version": "0.1.1.3" - }, - { - "cabal_sha256": "619828cae098a7b6deeb0316e12f55011101d88f756787ed024ceedb81cf1eba", - "component": "lib:tar-internal", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "08c61e82b59ed6fe7e85e9fe7cceaaf853ba54511d1ec57efa511ddc55ef1998", - "version": "0.6.2.0" - }, - { - "cabal_sha256": "619828cae098a7b6deeb0316e12f55011101d88f756787ed024ceedb81cf1eba", - "component": "lib:tar", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "08c61e82b59ed6fe7e85e9fe7cceaaf853ba54511d1ec57efa511ddc55ef1998", - "version": "0.6.2.0" - }, - { - "cabal_sha256": "64a1925c93e9a26cd4c40c470736950c4b5ea7bae68418cb996c5c7df4873cba", - "component": "lib:zlib", - "flags": [ - "-bundled-c-zlib", - "+non-blocking-ffi", - "-pkg-config" - ], - "package": "zlib", - "revision": 1, - "source": "hackage", - "src_sha256": "7e43c205e1e1ff5a4b033086ec8cce82ab658879e977c8ba02a6701946ff7a47", - "version": "0.7.0.0" - }, - { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", - "component": "lib:hackage-security", - "flags": [ - "+cabal-syntax", - "+lukko" - ], - "package": "hackage-security", - "revision": 1, - "source": "hackage", - "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", - "version": "0.6.2.6" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "lib:open-browser", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - }, - { - "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", - "component": "lib:regex-base", - "flags": [], - "package": "regex-base", - "revision": 4, - "source": "hackage", - "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", - "version": "0.94.0.2" - }, - { - "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", - "component": "lib:regex-posix", - "flags": [ - "-_regex-posix-clib" - ], - "package": "regex-posix", - "revision": 3, - "source": "hackage", - "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", - "version": "0.96.0.1" - }, - { - "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", - "component": "lib:resolv", - "flags": [], - "package": "resolv", - "revision": 3, - "source": "hackage", - "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", - "version": "0.2.0.2" - }, - { - "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", - "component": "lib:safe-exceptions", - "flags": [], - "package": "safe-exceptions", - "revision": 1, - "source": "hackage", - "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", - "version": "0.1.7.4" - }, - { - "cabal_sha256": "a8f76076a40409a36ee975970c53273c2089aec9d9ece8168dfc736dfec24b9d", - "component": "lib:semaphore-compat", - "flags": [], - "package": "semaphore-compat", - "revision": 2, - "source": "hackage", - "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", - "version": "1.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "exe:cabal", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "exe:example", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - } - ] + "builtin": [ + { + "package": "rts", + "version": "1.0.2" + }, + { + "package": "ghc-prim", + "version": "0.8.0" + }, + { + "package": "ghc-bignum", + "version": "1.2" + }, + { + "package": "base", + "version": "4.16.4.0" + }, + { + "package": "array", + "version": "0.5.4.0" + }, + { + "package": "deepseq", + "version": "1.4.6.1" + }, + { + "package": "containers", + "version": "0.6.5.1" + }, + { + "package": "ghc-boot-th", + "version": "9.2.8" + }, + { + "package": "pretty", + "version": "1.1.3.6" + }, + { + "package": "template-haskell", + "version": "2.18.0.0" + }, + { + "package": "bytestring", + "version": "0.11.4.0" + }, + { + "package": "transformers", + "version": "0.5.6.2" + }, + { + "package": "mtl", + "version": "2.2.2" + }, + { + "package": "stm", + "version": "2.5.0.2" + }, + { + "package": "exceptions", + "version": "0.10.4" + }, + { + "package": "time", + "version": "1.11.1.1" + }, + { + "package": "binary", + "version": "0.8.9.0" + }, + { + "package": "text", + "version": "1.2.5.0" + }, + { + "package": "parsec", + "version": "3.1.15.0" + } + ], + "dependencies": [ + { + "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", + "component": "lib:os-string", + "flags": [], + "package": "os-string", + "revision": 0, + "source": "hackage", + "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", + "version": "2.0.3" + }, + { + "cabal_sha256": "8af7a843cba7eddc8d44ae94002b766ee8c23cbcd3ecdb2cc79ee6e0a694419a", + "component": "lib:filepath", + "flags": [ + "-cpphs" + ], + "package": "filepath", + "revision": 1, + "source": "hackage", + "src_sha256": "d2606db4fa8517932a2d9ea6415c365da4d1794afcb264a5b3c10110123978a7", + "version": "1.5.2.0" + }, + { + "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", + "component": "lib:unix", + "flags": [ + "+os-string" + ], + "package": "unix", + "revision": 0, + "source": "hackage", + "src_sha256": "5ab6c346aef2eb9bf80b4d29ca7e22063fc23e52fd69fbc4d18a9f98b154e424", + "version": "2.8.5.1" + }, + { + "cabal_sha256": "fbeec9ec346e5272167f63dcb86af513b457a7b9fc36dc818e4c7b81608d612b", + "component": "lib:directory", + "flags": [ + "+os-string" + ], + "package": "directory", + "revision": 0, + "source": "hackage", + "src_sha256": "e864ed54ddfc6e15d2eb02c87f4be8edd7719e1f9cea13e0f86909400b6ea768", + "version": "1.3.8.5" + }, + { + "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", + "component": "exe:alex", + "flags": [], + "package": "alex", + "revision": 0, + "source": "hackage", + "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", + "version": "3.5.1.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-syntax", + "flags": [], + "package": "Cabal-syntax", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "2a9393de33f18415fb8f4826957a87a94ffe8840ca8472a9b69dca6de45aca03", + "component": "lib:process", + "flags": [], + "package": "process", + "revision": 1, + "source": "hackage", + "src_sha256": "cefda221c3009fa2316b5cf148215cb340dad7eb8503f22e49e33722559df99a", + "version": "1.6.20.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal", + "flags": [], + "package": "Cabal", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-hooks", + "flags": [], + "package": "Cabal-hooks", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "0.1" + }, + { + "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", + "component": "exe:hsc2hs", + "flags": [ + "-in-ghc-tree" + ], + "package": "hsc2hs", + "revision": 2, + "source": "hackage", + "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", + "version": "0.68.10" + }, + { + "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", + "component": "lib:network", + "flags": [ + "-devel" + ], + "package": "network", + "revision": 0, + "source": "hackage", + "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", + "version": "3.2.0.0" + }, + { + "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", + "component": "lib:th-compat", + "flags": [], + "package": "th-compat", + "revision": 2, + "source": "hackage", + "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", + "version": "0.1.5" + }, + { + "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", + "component": "lib:network-uri", + "flags": [], + "package": "network-uri", + "revision": 1, + "source": "hackage", + "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", + "version": "2.6.4.2" + }, + { + "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", + "component": "lib:HTTP", + "flags": [ + "-conduit10", + "+network-uri", + "-warn-as-error", + "-warp-tests" + ], + "package": "HTTP", + "revision": 4, + "source": "hackage", + "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", + "version": "4000.4.1" + }, + { + "cabal_sha256": "a4a1975fde77e289b605c45a3ef78d731d8c1834e4cef311152d910a1e94d98c", + "component": "lib:data-array-byte", + "flags": [], + "package": "data-array-byte", + "revision": 3, + "source": "hackage", + "src_sha256": "1bb6eca0b3e02d057fe7f4e14c81ef395216f421ab30fdaa1b18017c9c025600", + "version": "0.1.0.1" + }, + { + "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", + "component": "lib:hashable", + "flags": [ + "+arch-native", + "+integer-gmp", + "-random-initial-seed" + ], + "package": "hashable", + "revision": 0, + "source": "hackage", + "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", + "version": "1.4.6.0" + }, + { + "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", + "component": "lib:async", + "flags": [ + "-bench" + ], + "package": "async", + "revision": 1, + "source": "hackage", + "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", + "version": "2.2.5" + }, + { + "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", + "component": "lib:base16-bytestring", + "flags": [], + "package": "base16-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", + "version": "1.0.2.0" + }, + { + "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", + "component": "lib:base64-bytestring", + "flags": [], + "package": "base64-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", + "version": "1.2.1.0" + }, + { + "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", + "component": "lib:splitmix", + "flags": [ + "-optimised-mixer" + ], + "package": "splitmix", + "revision": 1, + "source": "hackage", + "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", + "version": "0.1.0.5" + }, + { + "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", + "component": "lib:random", + "flags": [], + "package": "random", + "revision": 0, + "source": "hackage", + "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", + "version": "1.2.1.2" + }, + { + "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", + "component": "lib:edit-distance", + "flags": [], + "package": "edit-distance", + "revision": 1, + "source": "hackage", + "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", + "version": "0.2.2.1" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install-solver", + "flags": [ + "-debug-expensive-assertions", + "-debug-tracetree" + ], + "package": "cabal-install-solver", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", + "component": "lib:cryptohash-sha256", + "flags": [ + "-exe", + "+use-cbits" + ], + "package": "cryptohash-sha256", + "revision": 4, + "source": "hackage", + "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", + "version": "0.11.102.1" + }, + { + "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", + "component": "lib:echo", + "flags": [ + "-example" + ], + "package": "echo", + "revision": 0, + "source": "hackage", + "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", + "version": "0.1.4" + }, + { + "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", + "component": "lib:ed25519", + "flags": [ + "+no-donna", + "+test-doctests", + "+test-hlint", + "+test-properties" + ], + "package": "ed25519", + "revision": 8, + "source": "hackage", + "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", + "version": "0.0.5.0" + }, + { + "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", + "component": "lib:lukko", + "flags": [ + "+ofd-locking" + ], + "package": "lukko", + "revision": 0, + "source": "hackage", + "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", + "version": "0.1.2" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar-internal", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", + "component": "lib:zlib", + "flags": [ + "-bundled-c-zlib", + "+non-blocking-ffi", + "-pkg-config" + ], + "package": "zlib", + "revision": 0, + "source": "hackage", + "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", + "version": "0.7.1.0" + }, + { + "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", + "component": "lib:hackage-security", + "flags": [ + "+cabal-syntax", + "+lukko" + ], + "package": "hackage-security", + "revision": 1, + "source": "hackage", + "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", + "version": "0.6.2.6" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "lib:open-browser", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + }, + { + "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", + "component": "lib:regex-base", + "flags": [], + "package": "regex-base", + "revision": 4, + "source": "hackage", + "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", + "version": "0.94.0.2" + }, + { + "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", + "component": "lib:regex-posix", + "flags": [ + "-_regex-posix-clib" + ], + "package": "regex-posix", + "revision": 3, + "source": "hackage", + "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", + "version": "0.96.0.1" + }, + { + "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", + "component": "lib:resolv", + "flags": [], + "package": "resolv", + "revision": 3, + "source": "hackage", + "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", + "version": "0.2.0.2" + }, + { + "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", + "component": "lib:safe-exceptions", + "flags": [], + "package": "safe-exceptions", + "revision": 1, + "source": "hackage", + "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", + "version": "0.1.7.4" + }, + { + "cabal_sha256": "2de5218cef72b8ef090bd7d0fd930ffa143242a120c62e013b5cf039858f1855", + "component": "lib:semaphore-compat", + "flags": [], + "package": "semaphore-compat", + "revision": 3, + "source": "hackage", + "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", + "version": "1.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "exe:cabal", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "exe:example", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + } + ] } diff --git a/bootstrap/linux-9.4.8.json b/bootstrap/linux-9.4.8.json index 8a721f76be7..901a3071b55 100644 --- a/bootstrap/linux-9.4.8.json +++ b/bootstrap/linux-9.4.8.json @@ -1,524 +1,525 @@ { - "builtin": [ - { - "package": "rts", - "version": "1.0.2" - }, - { - "package": "ghc-prim", - "version": "0.9.1" - }, - { - "package": "ghc-bignum", - "version": "1.3" - }, - { - "package": "base", - "version": "4.17.2.1" - }, - { - "package": "array", - "version": "0.5.4.0" - }, - { - "package": "deepseq", - "version": "1.4.8.0" - }, - { - "package": "ghc-boot-th", - "version": "9.4.8" - }, - { - "package": "pretty", - "version": "1.1.3.6" - }, - { - "package": "template-haskell", - "version": "2.19.0.0" - }, - { - "package": "containers", - "version": "0.6.7" - }, - { - "package": "bytestring", - "version": "0.11.5.3" - }, - { - "package": "transformers", - "version": "0.5.6.2" - }, - { - "package": "mtl", - "version": "2.2.2" - }, - { - "package": "stm", - "version": "2.5.1.0" - }, - { - "package": "exceptions", - "version": "0.10.5" - }, - { - "package": "time", - "version": "1.12.2" - }, - { - "package": "binary", - "version": "0.8.9.1" - }, - { - "package": "text", - "version": "2.0.2" - }, - { - "package": "parsec", - "version": "3.1.16.1" - } - ], - "dependencies": [ - { - "cabal_sha256": "d9e181e1acae0ac505d8b217dec3805c68554878f1e32b3d8351b9ce17061623", - "component": "lib:filepath", - "flags": [ - "-cpphs" - ], - "package": "filepath", - "revision": 0, - "source": "hackage", - "src_sha256": "337a0b5bcf0898cb7f51ff327528cf26f4ac38baed7b66b28fbdea334699d8ed", - "version": "1.4.300.1" - }, - { - "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", - "component": "lib:unix", - "flags": [ - "-os-string" - ], - "package": "unix", - "revision": 0, - "source": "hackage", - "src_sha256": "5ab6c346aef2eb9bf80b4d29ca7e22063fc23e52fd69fbc4d18a9f98b154e424", - "version": "2.8.5.1" - }, - { - "cabal_sha256": "ae1730011f547153bb52139f217d1d524202b3da730a369660fc539e5dcfff31", - "component": "lib:directory", - "flags": [ - "-os-string" - ], - "package": "directory", - "revision": 0, - "source": "hackage", - "src_sha256": "a4e798a4e5339a7aa9577515886271386280bfbc1fe4a29fd4aa6464d4792064", - "version": "1.3.8.4" - }, - { - "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", - "component": "exe:alex", - "flags": [], - "package": "alex", - "revision": 0, - "source": "hackage", - "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", - "version": "3.5.1.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-syntax", - "flags": [], - "package": "Cabal-syntax", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "7785a72bc140ae5a9ef2439f10637b5fd104999832f1d93328d4973f37cb8469", - "component": "lib:process", - "flags": [], - "package": "process", - "revision": 0, - "source": "hackage", - "src_sha256": "b468355ab46966537eb171ed5593a0a1facc8d2eefc38659e43768f68f5dcb96", - "version": "1.6.19.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal", - "flags": [], - "package": "Cabal", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-hooks", - "flags": [], - "package": "Cabal-hooks", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "0.1" - }, - { - "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", - "component": "exe:hsc2hs", - "flags": [ - "-in-ghc-tree" - ], - "package": "hsc2hs", - "revision": 2, - "source": "hackage", - "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", - "version": "0.68.10" - }, - { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", - "component": "lib:network", - "flags": [ - "-devel" - ], - "package": "network", - "revision": 0, - "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" - }, - { - "cabal_sha256": "0a6ee328b71119d7dfcd004f0ec8feb77e6e78d8f6de1a281568edd3d3b6d83f", - "component": "lib:th-compat", - "flags": [], - "package": "th-compat", - "revision": 1, - "source": "hackage", - "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", - "version": "0.1.5" - }, - { - "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", - "component": "lib:network-uri", - "flags": [], - "package": "network-uri", - "revision": 1, - "source": "hackage", - "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", - "version": "2.6.4.2" - }, - { - "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", - "component": "lib:HTTP", - "flags": [ - "-conduit10", - "+network-uri", - "-warn-as-error", - "-warp-tests" - ], - "package": "HTTP", - "revision": 4, - "source": "hackage", - "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", - "version": "4000.4.1" - }, - { - "cabal_sha256": "32fa47f8345a2c0662fb602fc42e4b674e41ec48079b68bdecb4b6f68032c24e", - "component": "lib:os-string", - "flags": [], - "package": "os-string", - "revision": 0, - "source": "hackage", - "src_sha256": "0953126e962966719753c98d71f596f5fea07e100bce191b7453735a1ff2caa1", - "version": "2.0.2" - }, - { - "cabal_sha256": "ae22238274c572aa91e90c6c353e7206386708912ac5e6dc40ac61d1dcc553db", - "component": "lib:hashable", - "flags": [ - "+integer-gmp", - "-random-initial-seed" - ], - "package": "hashable", - "revision": 1, - "source": "hackage", - "src_sha256": "1fa3d64548440942b2b38b99c76d8dcaa94fa2ea3912cd7a6354ea4ec4af4758", - "version": "1.4.4.0" - }, - { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", - "component": "lib:async", - "flags": [ - "-bench" - ], - "package": "async", - "revision": 1, - "source": "hackage", - "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", - "version": "2.2.5" - }, - { - "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", - "component": "lib:base16-bytestring", - "flags": [], - "package": "base16-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", - "version": "1.0.2.0" - }, - { - "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", - "component": "lib:base64-bytestring", - "flags": [], - "package": "base64-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", - "version": "1.2.1.0" - }, - { - "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", - "component": "lib:splitmix", - "flags": [ - "-optimised-mixer" - ], - "package": "splitmix", - "revision": 1, - "source": "hackage", - "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", - "version": "0.1.0.5" - }, - { - "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", - "component": "lib:random", - "flags": [], - "package": "random", - "revision": 0, - "source": "hackage", - "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", - "version": "1.2.1.2" - }, - { - "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", - "component": "lib:edit-distance", - "flags": [], - "package": "edit-distance", - "revision": 1, - "source": "hackage", - "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", - "version": "0.2.2.1" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install-solver", - "flags": [ - "-debug-expensive-assertions", - "-debug-tracetree" - ], - "package": "cabal-install-solver", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", - "component": "lib:cryptohash-sha256", - "flags": [ - "-exe", - "+use-cbits" - ], - "package": "cryptohash-sha256", - "revision": 4, - "source": "hackage", - "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", - "version": "0.11.102.1" - }, - { - "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", - "component": "lib:echo", - "flags": [ - "-example" - ], - "package": "echo", - "revision": 0, - "source": "hackage", - "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", - "version": "0.1.4" - }, - { - "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", - "component": "lib:ed25519", - "flags": [ - "+no-donna", - "+test-doctests", - "+test-hlint", - "+test-properties" - ], - "package": "ed25519", - "revision": 8, - "source": "hackage", - "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", - "version": "0.0.5.0" - }, - { - "cabal_sha256": "17786545dce60c4d5783ba6125c0a6499a1abddd3d7417b15500ccd767c35f07", - "component": "lib:lukko", - "flags": [ - "+ofd-locking" - ], - "package": "lukko", - "revision": 5, - "source": "hackage", - "src_sha256": "a80efb60cfa3dae18682c01980d76d5f7e413e191cd186992e1bf7388d48ab1f", - "version": "0.1.1.3" - }, - { - "cabal_sha256": "619828cae098a7b6deeb0316e12f55011101d88f756787ed024ceedb81cf1eba", - "component": "lib:tar-internal", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "08c61e82b59ed6fe7e85e9fe7cceaaf853ba54511d1ec57efa511ddc55ef1998", - "version": "0.6.2.0" - }, - { - "cabal_sha256": "619828cae098a7b6deeb0316e12f55011101d88f756787ed024ceedb81cf1eba", - "component": "lib:tar", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "08c61e82b59ed6fe7e85e9fe7cceaaf853ba54511d1ec57efa511ddc55ef1998", - "version": "0.6.2.0" - }, - { - "cabal_sha256": "64a1925c93e9a26cd4c40c470736950c4b5ea7bae68418cb996c5c7df4873cba", - "component": "lib:zlib", - "flags": [ - "-bundled-c-zlib", - "+non-blocking-ffi", - "-pkg-config" - ], - "package": "zlib", - "revision": 1, - "source": "hackage", - "src_sha256": "7e43c205e1e1ff5a4b033086ec8cce82ab658879e977c8ba02a6701946ff7a47", - "version": "0.7.0.0" - }, - { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", - "component": "lib:hackage-security", - "flags": [ - "+cabal-syntax", - "+lukko" - ], - "package": "hackage-security", - "revision": 1, - "source": "hackage", - "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", - "version": "0.6.2.6" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "lib:open-browser", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - }, - { - "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", - "component": "lib:regex-base", - "flags": [], - "package": "regex-base", - "revision": 4, - "source": "hackage", - "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", - "version": "0.94.0.2" - }, - { - "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", - "component": "lib:regex-posix", - "flags": [ - "-_regex-posix-clib" - ], - "package": "regex-posix", - "revision": 3, - "source": "hackage", - "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", - "version": "0.96.0.1" - }, - { - "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", - "component": "lib:resolv", - "flags": [], - "package": "resolv", - "revision": 3, - "source": "hackage", - "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", - "version": "0.2.0.2" - }, - { - "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", - "component": "lib:safe-exceptions", - "flags": [], - "package": "safe-exceptions", - "revision": 1, - "source": "hackage", - "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", - "version": "0.1.7.4" - }, - { - "cabal_sha256": "a8f76076a40409a36ee975970c53273c2089aec9d9ece8168dfc736dfec24b9d", - "component": "lib:semaphore-compat", - "flags": [], - "package": "semaphore-compat", - "revision": 2, - "source": "hackage", - "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", - "version": "1.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "exe:cabal", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "exe:example", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - } - ] + "builtin": [ + { + "package": "rts", + "version": "1.0.2" + }, + { + "package": "ghc-prim", + "version": "0.9.1" + }, + { + "package": "ghc-bignum", + "version": "1.3" + }, + { + "package": "base", + "version": "4.17.2.1" + }, + { + "package": "array", + "version": "0.5.4.0" + }, + { + "package": "deepseq", + "version": "1.4.8.0" + }, + { + "package": "ghc-boot-th", + "version": "9.4.8" + }, + { + "package": "pretty", + "version": "1.1.3.6" + }, + { + "package": "template-haskell", + "version": "2.19.0.0" + }, + { + "package": "containers", + "version": "0.6.7" + }, + { + "package": "bytestring", + "version": "0.11.5.3" + }, + { + "package": "transformers", + "version": "0.5.6.2" + }, + { + "package": "mtl", + "version": "2.2.2" + }, + { + "package": "stm", + "version": "2.5.1.0" + }, + { + "package": "exceptions", + "version": "0.10.5" + }, + { + "package": "time", + "version": "1.12.2" + }, + { + "package": "binary", + "version": "0.8.9.1" + }, + { + "package": "text", + "version": "2.0.2" + }, + { + "package": "parsec", + "version": "3.1.16.1" + } + ], + "dependencies": [ + { + "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", + "component": "lib:os-string", + "flags": [], + "package": "os-string", + "revision": 0, + "source": "hackage", + "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", + "version": "2.0.3" + }, + { + "cabal_sha256": "8af7a843cba7eddc8d44ae94002b766ee8c23cbcd3ecdb2cc79ee6e0a694419a", + "component": "lib:filepath", + "flags": [ + "-cpphs" + ], + "package": "filepath", + "revision": 1, + "source": "hackage", + "src_sha256": "d2606db4fa8517932a2d9ea6415c365da4d1794afcb264a5b3c10110123978a7", + "version": "1.5.2.0" + }, + { + "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", + "component": "lib:unix", + "flags": [ + "+os-string" + ], + "package": "unix", + "revision": 0, + "source": "hackage", + "src_sha256": "5ab6c346aef2eb9bf80b4d29ca7e22063fc23e52fd69fbc4d18a9f98b154e424", + "version": "2.8.5.1" + }, + { + "cabal_sha256": "fbeec9ec346e5272167f63dcb86af513b457a7b9fc36dc818e4c7b81608d612b", + "component": "lib:directory", + "flags": [ + "+os-string" + ], + "package": "directory", + "revision": 0, + "source": "hackage", + "src_sha256": "e864ed54ddfc6e15d2eb02c87f4be8edd7719e1f9cea13e0f86909400b6ea768", + "version": "1.3.8.5" + }, + { + "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", + "component": "exe:alex", + "flags": [], + "package": "alex", + "revision": 0, + "source": "hackage", + "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", + "version": "3.5.1.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-syntax", + "flags": [], + "package": "Cabal-syntax", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "2a9393de33f18415fb8f4826957a87a94ffe8840ca8472a9b69dca6de45aca03", + "component": "lib:process", + "flags": [], + "package": "process", + "revision": 1, + "source": "hackage", + "src_sha256": "cefda221c3009fa2316b5cf148215cb340dad7eb8503f22e49e33722559df99a", + "version": "1.6.20.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal", + "flags": [], + "package": "Cabal", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-hooks", + "flags": [], + "package": "Cabal-hooks", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "0.1" + }, + { + "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", + "component": "exe:hsc2hs", + "flags": [ + "-in-ghc-tree" + ], + "package": "hsc2hs", + "revision": 2, + "source": "hackage", + "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", + "version": "0.68.10" + }, + { + "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", + "component": "lib:network", + "flags": [ + "-devel" + ], + "package": "network", + "revision": 0, + "source": "hackage", + "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", + "version": "3.2.0.0" + }, + { + "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", + "component": "lib:th-compat", + "flags": [], + "package": "th-compat", + "revision": 2, + "source": "hackage", + "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", + "version": "0.1.5" + }, + { + "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", + "component": "lib:network-uri", + "flags": [], + "package": "network-uri", + "revision": 1, + "source": "hackage", + "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", + "version": "2.6.4.2" + }, + { + "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", + "component": "lib:HTTP", + "flags": [ + "-conduit10", + "+network-uri", + "-warn-as-error", + "-warp-tests" + ], + "package": "HTTP", + "revision": 4, + "source": "hackage", + "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", + "version": "4000.4.1" + }, + { + "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", + "component": "lib:hashable", + "flags": [ + "+arch-native", + "+integer-gmp", + "-random-initial-seed" + ], + "package": "hashable", + "revision": 0, + "source": "hackage", + "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", + "version": "1.4.6.0" + }, + { + "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", + "component": "lib:async", + "flags": [ + "-bench" + ], + "package": "async", + "revision": 1, + "source": "hackage", + "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", + "version": "2.2.5" + }, + { + "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", + "component": "lib:base16-bytestring", + "flags": [], + "package": "base16-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", + "version": "1.0.2.0" + }, + { + "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", + "component": "lib:base64-bytestring", + "flags": [], + "package": "base64-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", + "version": "1.2.1.0" + }, + { + "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", + "component": "lib:splitmix", + "flags": [ + "-optimised-mixer" + ], + "package": "splitmix", + "revision": 1, + "source": "hackage", + "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", + "version": "0.1.0.5" + }, + { + "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", + "component": "lib:random", + "flags": [], + "package": "random", + "revision": 0, + "source": "hackage", + "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", + "version": "1.2.1.2" + }, + { + "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", + "component": "lib:edit-distance", + "flags": [], + "package": "edit-distance", + "revision": 1, + "source": "hackage", + "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", + "version": "0.2.2.1" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install-solver", + "flags": [ + "-debug-expensive-assertions", + "-debug-tracetree" + ], + "package": "cabal-install-solver", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", + "component": "lib:cryptohash-sha256", + "flags": [ + "-exe", + "+use-cbits" + ], + "package": "cryptohash-sha256", + "revision": 4, + "source": "hackage", + "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", + "version": "0.11.102.1" + }, + { + "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", + "component": "lib:echo", + "flags": [ + "-example" + ], + "package": "echo", + "revision": 0, + "source": "hackage", + "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", + "version": "0.1.4" + }, + { + "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", + "component": "lib:ed25519", + "flags": [ + "+no-donna", + "+test-doctests", + "+test-hlint", + "+test-properties" + ], + "package": "ed25519", + "revision": 8, + "source": "hackage", + "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", + "version": "0.0.5.0" + }, + { + "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", + "component": "lib:lukko", + "flags": [ + "+ofd-locking" + ], + "package": "lukko", + "revision": 0, + "source": "hackage", + "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", + "version": "0.1.2" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar-internal", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", + "component": "lib:zlib", + "flags": [ + "-bundled-c-zlib", + "+non-blocking-ffi", + "-pkg-config" + ], + "package": "zlib", + "revision": 0, + "source": "hackage", + "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", + "version": "0.7.1.0" + }, + { + "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", + "component": "lib:hackage-security", + "flags": [ + "+cabal-syntax", + "+lukko" + ], + "package": "hackage-security", + "revision": 1, + "source": "hackage", + "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", + "version": "0.6.2.6" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "lib:open-browser", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + }, + { + "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", + "component": "lib:regex-base", + "flags": [], + "package": "regex-base", + "revision": 4, + "source": "hackage", + "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", + "version": "0.94.0.2" + }, + { + "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", + "component": "lib:regex-posix", + "flags": [ + "-_regex-posix-clib" + ], + "package": "regex-posix", + "revision": 3, + "source": "hackage", + "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", + "version": "0.96.0.1" + }, + { + "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", + "component": "lib:resolv", + "flags": [], + "package": "resolv", + "revision": 3, + "source": "hackage", + "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", + "version": "0.2.0.2" + }, + { + "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", + "component": "lib:safe-exceptions", + "flags": [], + "package": "safe-exceptions", + "revision": 1, + "source": "hackage", + "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", + "version": "0.1.7.4" + }, + { + "cabal_sha256": "2de5218cef72b8ef090bd7d0fd930ffa143242a120c62e013b5cf039858f1855", + "component": "lib:semaphore-compat", + "flags": [], + "package": "semaphore-compat", + "revision": 3, + "source": "hackage", + "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", + "version": "1.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "exe:cabal", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "exe:example", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + } + ] } diff --git a/bootstrap/linux-9.6.4.json b/bootstrap/linux-9.6.4.json index 7e04a3fd91a..8edfb255f49 100644 --- a/bootstrap/linux-9.6.4.json +++ b/bootstrap/linux-9.6.4.json @@ -1,494 +1,495 @@ { - "builtin": [ - { - "package": "rts", - "version": "1.0.2" - }, - { - "package": "ghc-prim", - "version": "0.10.0" - }, - { - "package": "ghc-bignum", - "version": "1.3" - }, - { - "package": "base", - "version": "4.18.2.0" - }, - { - "package": "array", - "version": "0.5.6.0" - }, - { - "package": "deepseq", - "version": "1.4.8.1" - }, - { - "package": "ghc-boot-th", - "version": "9.6.4" - }, - { - "package": "pretty", - "version": "1.1.3.6" - }, - { - "package": "template-haskell", - "version": "2.20.0.0" - }, - { - "package": "containers", - "version": "0.6.7" - }, - { - "package": "bytestring", - "version": "0.11.5.3" - }, - { - "package": "transformers", - "version": "0.6.1.0" - }, - { - "package": "mtl", - "version": "2.3.1" - }, - { - "package": "stm", - "version": "2.5.1.0" - }, - { - "package": "exceptions", - "version": "0.10.7" - }, - { - "package": "filepath", - "version": "1.4.200.1" - }, - { - "package": "time", - "version": "1.12.2" - }, - { - "package": "unix", - "version": "2.8.4.0" - }, - { - "package": "directory", - "version": "1.3.8.1" - }, - { - "package": "binary", - "version": "0.8.9.1" - }, - { - "package": "text", - "version": "2.0.2" - }, - { - "package": "parsec", - "version": "3.1.16.1" - }, - { - "package": "process", - "version": "1.6.17.0" - } - ], - "dependencies": [ - { - "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", - "component": "exe:alex", - "flags": [], - "package": "alex", - "revision": 0, - "source": "hackage", - "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", - "version": "3.5.1.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-syntax", - "flags": [], - "package": "Cabal-syntax", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal", - "flags": [], - "package": "Cabal", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-hooks", - "flags": [], - "package": "Cabal-hooks", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "0.1" - }, - { - "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", - "component": "exe:hsc2hs", - "flags": [ - "-in-ghc-tree" - ], - "package": "hsc2hs", - "revision": 2, - "source": "hackage", - "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", - "version": "0.68.10" - }, - { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", - "component": "lib:network", - "flags": [ - "-devel" - ], - "package": "network", - "revision": 0, - "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" - }, - { - "cabal_sha256": "0a6ee328b71119d7dfcd004f0ec8feb77e6e78d8f6de1a281568edd3d3b6d83f", - "component": "lib:th-compat", - "flags": [], - "package": "th-compat", - "revision": 1, - "source": "hackage", - "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", - "version": "0.1.5" - }, - { - "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", - "component": "lib:network-uri", - "flags": [], - "package": "network-uri", - "revision": 1, - "source": "hackage", - "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", - "version": "2.6.4.2" - }, - { - "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", - "component": "lib:HTTP", - "flags": [ - "-conduit10", - "+network-uri", - "-warn-as-error", - "-warp-tests" - ], - "package": "HTTP", - "revision": 4, - "source": "hackage", - "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", - "version": "4000.4.1" - }, - { - "cabal_sha256": "32fa47f8345a2c0662fb602fc42e4b674e41ec48079b68bdecb4b6f68032c24e", - "component": "lib:os-string", - "flags": [], - "package": "os-string", - "revision": 0, - "source": "hackage", - "src_sha256": "0953126e962966719753c98d71f596f5fea07e100bce191b7453735a1ff2caa1", - "version": "2.0.2" - }, - { - "cabal_sha256": "ae22238274c572aa91e90c6c353e7206386708912ac5e6dc40ac61d1dcc553db", - "component": "lib:hashable", - "flags": [ - "+integer-gmp", - "-random-initial-seed" - ], - "package": "hashable", - "revision": 1, - "source": "hackage", - "src_sha256": "1fa3d64548440942b2b38b99c76d8dcaa94fa2ea3912cd7a6354ea4ec4af4758", - "version": "1.4.4.0" - }, - { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", - "component": "lib:async", - "flags": [ - "-bench" - ], - "package": "async", - "revision": 1, - "source": "hackage", - "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", - "version": "2.2.5" - }, - { - "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", - "component": "lib:base16-bytestring", - "flags": [], - "package": "base16-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", - "version": "1.0.2.0" - }, - { - "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", - "component": "lib:base64-bytestring", - "flags": [], - "package": "base64-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", - "version": "1.2.1.0" - }, - { - "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", - "component": "lib:splitmix", - "flags": [ - "-optimised-mixer" - ], - "package": "splitmix", - "revision": 1, - "source": "hackage", - "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", - "version": "0.1.0.5" - }, - { - "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", - "component": "lib:random", - "flags": [], - "package": "random", - "revision": 0, - "source": "hackage", - "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", - "version": "1.2.1.2" - }, - { - "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", - "component": "lib:edit-distance", - "flags": [], - "package": "edit-distance", - "revision": 1, - "source": "hackage", - "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", - "version": "0.2.2.1" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install-solver", - "flags": [ - "-debug-expensive-assertions", - "-debug-tracetree" - ], - "package": "cabal-install-solver", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", - "component": "lib:cryptohash-sha256", - "flags": [ - "-exe", - "+use-cbits" - ], - "package": "cryptohash-sha256", - "revision": 4, - "source": "hackage", - "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", - "version": "0.11.102.1" - }, - { - "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", - "component": "lib:echo", - "flags": [ - "-example" - ], - "package": "echo", - "revision": 0, - "source": "hackage", - "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", - "version": "0.1.4" - }, - { - "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", - "component": "lib:ed25519", - "flags": [ - "+no-donna", - "+test-doctests", - "+test-hlint", - "+test-properties" - ], - "package": "ed25519", - "revision": 8, - "source": "hackage", - "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", - "version": "0.0.5.0" - }, - { - "cabal_sha256": "17786545dce60c4d5783ba6125c0a6499a1abddd3d7417b15500ccd767c35f07", - "component": "lib:lukko", - "flags": [ - "+ofd-locking" - ], - "package": "lukko", - "revision": 5, - "source": "hackage", - "src_sha256": "a80efb60cfa3dae18682c01980d76d5f7e413e191cd186992e1bf7388d48ab1f", - "version": "0.1.1.3" - }, - { - "cabal_sha256": "619828cae098a7b6deeb0316e12f55011101d88f756787ed024ceedb81cf1eba", - "component": "lib:tar-internal", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "08c61e82b59ed6fe7e85e9fe7cceaaf853ba54511d1ec57efa511ddc55ef1998", - "version": "0.6.2.0" - }, - { - "cabal_sha256": "619828cae098a7b6deeb0316e12f55011101d88f756787ed024ceedb81cf1eba", - "component": "lib:tar", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "08c61e82b59ed6fe7e85e9fe7cceaaf853ba54511d1ec57efa511ddc55ef1998", - "version": "0.6.2.0" - }, - { - "cabal_sha256": "64a1925c93e9a26cd4c40c470736950c4b5ea7bae68418cb996c5c7df4873cba", - "component": "lib:zlib", - "flags": [ - "-bundled-c-zlib", - "+non-blocking-ffi", - "-pkg-config" - ], - "package": "zlib", - "revision": 1, - "source": "hackage", - "src_sha256": "7e43c205e1e1ff5a4b033086ec8cce82ab658879e977c8ba02a6701946ff7a47", - "version": "0.7.0.0" - }, - { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", - "component": "lib:hackage-security", - "flags": [ - "+cabal-syntax", - "+lukko" - ], - "package": "hackage-security", - "revision": 1, - "source": "hackage", - "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", - "version": "0.6.2.6" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "lib:open-browser", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - }, - { - "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", - "component": "lib:regex-base", - "flags": [], - "package": "regex-base", - "revision": 4, - "source": "hackage", - "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", - "version": "0.94.0.2" - }, - { - "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", - "component": "lib:regex-posix", - "flags": [ - "-_regex-posix-clib" - ], - "package": "regex-posix", - "revision": 3, - "source": "hackage", - "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", - "version": "0.96.0.1" - }, - { - "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", - "component": "lib:resolv", - "flags": [], - "package": "resolv", - "revision": 3, - "source": "hackage", - "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", - "version": "0.2.0.2" - }, - { - "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", - "component": "lib:safe-exceptions", - "flags": [], - "package": "safe-exceptions", - "revision": 1, - "source": "hackage", - "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", - "version": "0.1.7.4" - }, - { - "cabal_sha256": "a8f76076a40409a36ee975970c53273c2089aec9d9ece8168dfc736dfec24b9d", - "component": "lib:semaphore-compat", - "flags": [], - "package": "semaphore-compat", - "revision": 2, - "source": "hackage", - "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", - "version": "1.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "exe:cabal", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "exe:example", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - } - ] + "builtin": [ + { + "package": "rts", + "version": "1.0.2" + }, + { + "package": "ghc-prim", + "version": "0.10.0" + }, + { + "package": "ghc-bignum", + "version": "1.3" + }, + { + "package": "base", + "version": "4.18.2.0" + }, + { + "package": "array", + "version": "0.5.6.0" + }, + { + "package": "deepseq", + "version": "1.4.8.1" + }, + { + "package": "ghc-boot-th", + "version": "9.6.4" + }, + { + "package": "pretty", + "version": "1.1.3.6" + }, + { + "package": "template-haskell", + "version": "2.20.0.0" + }, + { + "package": "containers", + "version": "0.6.7" + }, + { + "package": "bytestring", + "version": "0.11.5.3" + }, + { + "package": "transformers", + "version": "0.6.1.0" + }, + { + "package": "mtl", + "version": "2.3.1" + }, + { + "package": "stm", + "version": "2.5.1.0" + }, + { + "package": "exceptions", + "version": "0.10.7" + }, + { + "package": "filepath", + "version": "1.4.200.1" + }, + { + "package": "time", + "version": "1.12.2" + }, + { + "package": "unix", + "version": "2.8.4.0" + }, + { + "package": "directory", + "version": "1.3.8.1" + }, + { + "package": "binary", + "version": "0.8.9.1" + }, + { + "package": "text", + "version": "2.0.2" + }, + { + "package": "parsec", + "version": "3.1.16.1" + }, + { + "package": "process", + "version": "1.6.17.0" + } + ], + "dependencies": [ + { + "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", + "component": "exe:alex", + "flags": [], + "package": "alex", + "revision": 0, + "source": "hackage", + "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", + "version": "3.5.1.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-syntax", + "flags": [], + "package": "Cabal-syntax", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal", + "flags": [], + "package": "Cabal", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-hooks", + "flags": [], + "package": "Cabal-hooks", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "0.1" + }, + { + "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", + "component": "exe:hsc2hs", + "flags": [ + "-in-ghc-tree" + ], + "package": "hsc2hs", + "revision": 2, + "source": "hackage", + "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", + "version": "0.68.10" + }, + { + "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", + "component": "lib:network", + "flags": [ + "-devel" + ], + "package": "network", + "revision": 0, + "source": "hackage", + "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", + "version": "3.2.0.0" + }, + { + "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", + "component": "lib:th-compat", + "flags": [], + "package": "th-compat", + "revision": 2, + "source": "hackage", + "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", + "version": "0.1.5" + }, + { + "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", + "component": "lib:network-uri", + "flags": [], + "package": "network-uri", + "revision": 1, + "source": "hackage", + "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", + "version": "2.6.4.2" + }, + { + "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", + "component": "lib:HTTP", + "flags": [ + "-conduit10", + "+network-uri", + "-warn-as-error", + "-warp-tests" + ], + "package": "HTTP", + "revision": 4, + "source": "hackage", + "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", + "version": "4000.4.1" + }, + { + "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", + "component": "lib:os-string", + "flags": [], + "package": "os-string", + "revision": 0, + "source": "hackage", + "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", + "version": "2.0.3" + }, + { + "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", + "component": "lib:hashable", + "flags": [ + "+arch-native", + "+integer-gmp", + "-random-initial-seed" + ], + "package": "hashable", + "revision": 0, + "source": "hackage", + "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", + "version": "1.4.6.0" + }, + { + "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", + "component": "lib:async", + "flags": [ + "-bench" + ], + "package": "async", + "revision": 1, + "source": "hackage", + "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", + "version": "2.2.5" + }, + { + "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", + "component": "lib:base16-bytestring", + "flags": [], + "package": "base16-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", + "version": "1.0.2.0" + }, + { + "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", + "component": "lib:base64-bytestring", + "flags": [], + "package": "base64-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", + "version": "1.2.1.0" + }, + { + "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", + "component": "lib:splitmix", + "flags": [ + "-optimised-mixer" + ], + "package": "splitmix", + "revision": 1, + "source": "hackage", + "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", + "version": "0.1.0.5" + }, + { + "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", + "component": "lib:random", + "flags": [], + "package": "random", + "revision": 0, + "source": "hackage", + "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", + "version": "1.2.1.2" + }, + { + "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", + "component": "lib:edit-distance", + "flags": [], + "package": "edit-distance", + "revision": 1, + "source": "hackage", + "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", + "version": "0.2.2.1" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install-solver", + "flags": [ + "-debug-expensive-assertions", + "-debug-tracetree" + ], + "package": "cabal-install-solver", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", + "component": "lib:cryptohash-sha256", + "flags": [ + "-exe", + "+use-cbits" + ], + "package": "cryptohash-sha256", + "revision": 4, + "source": "hackage", + "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", + "version": "0.11.102.1" + }, + { + "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", + "component": "lib:echo", + "flags": [ + "-example" + ], + "package": "echo", + "revision": 0, + "source": "hackage", + "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", + "version": "0.1.4" + }, + { + "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", + "component": "lib:ed25519", + "flags": [ + "+no-donna", + "+test-doctests", + "+test-hlint", + "+test-properties" + ], + "package": "ed25519", + "revision": 8, + "source": "hackage", + "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", + "version": "0.0.5.0" + }, + { + "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", + "component": "lib:lukko", + "flags": [ + "+ofd-locking" + ], + "package": "lukko", + "revision": 0, + "source": "hackage", + "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", + "version": "0.1.2" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar-internal", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", + "component": "lib:zlib", + "flags": [ + "-bundled-c-zlib", + "+non-blocking-ffi", + "-pkg-config" + ], + "package": "zlib", + "revision": 0, + "source": "hackage", + "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", + "version": "0.7.1.0" + }, + { + "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", + "component": "lib:hackage-security", + "flags": [ + "+cabal-syntax", + "+lukko" + ], + "package": "hackage-security", + "revision": 1, + "source": "hackage", + "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", + "version": "0.6.2.6" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "lib:open-browser", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + }, + { + "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", + "component": "lib:regex-base", + "flags": [], + "package": "regex-base", + "revision": 4, + "source": "hackage", + "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", + "version": "0.94.0.2" + }, + { + "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", + "component": "lib:regex-posix", + "flags": [ + "-_regex-posix-clib" + ], + "package": "regex-posix", + "revision": 3, + "source": "hackage", + "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", + "version": "0.96.0.1" + }, + { + "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", + "component": "lib:resolv", + "flags": [], + "package": "resolv", + "revision": 3, + "source": "hackage", + "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", + "version": "0.2.0.2" + }, + { + "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", + "component": "lib:safe-exceptions", + "flags": [], + "package": "safe-exceptions", + "revision": 1, + "source": "hackage", + "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", + "version": "0.1.7.4" + }, + { + "cabal_sha256": "2de5218cef72b8ef090bd7d0fd930ffa143242a120c62e013b5cf039858f1855", + "component": "lib:semaphore-compat", + "flags": [], + "package": "semaphore-compat", + "revision": 3, + "source": "hackage", + "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", + "version": "1.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "exe:cabal", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "exe:example", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + } + ] } diff --git a/bootstrap/linux-9.8.2.json b/bootstrap/linux-9.8.2.json index 9876089e798..c1cc7a760b0 100644 --- a/bootstrap/linux-9.8.2.json +++ b/bootstrap/linux-9.8.2.json @@ -1,488 +1,489 @@ { - "builtin": [ - { - "package": "rts", - "version": "1.0.2" - }, - { - "package": "ghc-prim", - "version": "0.11.0" - }, - { - "package": "ghc-bignum", - "version": "1.3" - }, - { - "package": "base", - "version": "4.19.1.0" - }, - { - "package": "array", - "version": "0.5.6.0" - }, - { - "package": "deepseq", - "version": "1.5.0.0" - }, - { - "package": "ghc-boot-th", - "version": "9.8.2" - }, - { - "package": "pretty", - "version": "1.1.3.6" - }, - { - "package": "template-haskell", - "version": "2.21.0.0" - }, - { - "package": "containers", - "version": "0.6.8" - }, - { - "package": "bytestring", - "version": "0.12.1.0" - }, - { - "package": "transformers", - "version": "0.6.1.0" - }, - { - "package": "mtl", - "version": "2.3.1" - }, - { - "package": "stm", - "version": "2.5.2.1" - }, - { - "package": "exceptions", - "version": "0.10.7" - }, - { - "package": "filepath", - "version": "1.4.200.1" - }, - { - "package": "time", - "version": "1.12.2" - }, - { - "package": "unix", - "version": "2.8.4.0" - }, - { - "package": "directory", - "version": "1.3.8.1" - }, - { - "package": "binary", - "version": "0.8.9.1" - }, - { - "package": "text", - "version": "2.1.1" - }, - { - "package": "parsec", - "version": "3.1.17.0" - }, - { - "package": "process", - "version": "1.6.18.0" - }, - { - "package": "semaphore-compat", - "version": "1.0.0" - } - ], - "dependencies": [ - { - "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", - "component": "exe:alex", - "flags": [], - "package": "alex", - "revision": 0, - "source": "hackage", - "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", - "version": "3.5.1.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-syntax", - "flags": [], - "package": "Cabal-syntax", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal", - "flags": [], - "package": "Cabal", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-hooks", - "flags": [], - "package": "Cabal-hooks", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "0.1" - }, - { - "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", - "component": "exe:hsc2hs", - "flags": [ - "-in-ghc-tree" - ], - "package": "hsc2hs", - "revision": 2, - "source": "hackage", - "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", - "version": "0.68.10" - }, - { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", - "component": "lib:network", - "flags": [ - "-devel" - ], - "package": "network", - "revision": 0, - "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" - }, - { - "cabal_sha256": "0a6ee328b71119d7dfcd004f0ec8feb77e6e78d8f6de1a281568edd3d3b6d83f", - "component": "lib:th-compat", - "flags": [], - "package": "th-compat", - "revision": 1, - "source": "hackage", - "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", - "version": "0.1.5" - }, - { - "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", - "component": "lib:network-uri", - "flags": [], - "package": "network-uri", - "revision": 1, - "source": "hackage", - "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", - "version": "2.6.4.2" - }, - { - "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", - "component": "lib:HTTP", - "flags": [ - "-conduit10", - "+network-uri", - "-warn-as-error", - "-warp-tests" - ], - "package": "HTTP", - "revision": 4, - "source": "hackage", - "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", - "version": "4000.4.1" - }, - { - "cabal_sha256": "32fa47f8345a2c0662fb602fc42e4b674e41ec48079b68bdecb4b6f68032c24e", - "component": "lib:os-string", - "flags": [], - "package": "os-string", - "revision": 0, - "source": "hackage", - "src_sha256": "0953126e962966719753c98d71f596f5fea07e100bce191b7453735a1ff2caa1", - "version": "2.0.2" - }, - { - "cabal_sha256": "ae22238274c572aa91e90c6c353e7206386708912ac5e6dc40ac61d1dcc553db", - "component": "lib:hashable", - "flags": [ - "+integer-gmp", - "-random-initial-seed" - ], - "package": "hashable", - "revision": 1, - "source": "hackage", - "src_sha256": "1fa3d64548440942b2b38b99c76d8dcaa94fa2ea3912cd7a6354ea4ec4af4758", - "version": "1.4.4.0" - }, - { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", - "component": "lib:async", - "flags": [ - "-bench" - ], - "package": "async", - "revision": 1, - "source": "hackage", - "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", - "version": "2.2.5" - }, - { - "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", - "component": "lib:base16-bytestring", - "flags": [], - "package": "base16-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", - "version": "1.0.2.0" - }, - { - "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", - "component": "lib:base64-bytestring", - "flags": [], - "package": "base64-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", - "version": "1.2.1.0" - }, - { - "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", - "component": "lib:splitmix", - "flags": [ - "-optimised-mixer" - ], - "package": "splitmix", - "revision": 1, - "source": "hackage", - "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", - "version": "0.1.0.5" - }, - { - "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", - "component": "lib:random", - "flags": [], - "package": "random", - "revision": 0, - "source": "hackage", - "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", - "version": "1.2.1.2" - }, - { - "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", - "component": "lib:edit-distance", - "flags": [], - "package": "edit-distance", - "revision": 1, - "source": "hackage", - "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", - "version": "0.2.2.1" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install-solver", - "flags": [ - "-debug-expensive-assertions", - "-debug-tracetree" - ], - "package": "cabal-install-solver", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", - "component": "lib:cryptohash-sha256", - "flags": [ - "-exe", - "+use-cbits" - ], - "package": "cryptohash-sha256", - "revision": 4, - "source": "hackage", - "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", - "version": "0.11.102.1" - }, - { - "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", - "component": "lib:echo", - "flags": [ - "-example" - ], - "package": "echo", - "revision": 0, - "source": "hackage", - "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", - "version": "0.1.4" - }, - { - "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", - "component": "lib:ed25519", - "flags": [ - "+no-donna", - "+test-doctests", - "+test-hlint", - "+test-properties" - ], - "package": "ed25519", - "revision": 8, - "source": "hackage", - "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", - "version": "0.0.5.0" - }, - { - "cabal_sha256": "17786545dce60c4d5783ba6125c0a6499a1abddd3d7417b15500ccd767c35f07", - "component": "lib:lukko", - "flags": [ - "+ofd-locking" - ], - "package": "lukko", - "revision": 5, - "source": "hackage", - "src_sha256": "a80efb60cfa3dae18682c01980d76d5f7e413e191cd186992e1bf7388d48ab1f", - "version": "0.1.1.3" - }, - { - "cabal_sha256": "619828cae098a7b6deeb0316e12f55011101d88f756787ed024ceedb81cf1eba", - "component": "lib:tar-internal", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "08c61e82b59ed6fe7e85e9fe7cceaaf853ba54511d1ec57efa511ddc55ef1998", - "version": "0.6.2.0" - }, - { - "cabal_sha256": "619828cae098a7b6deeb0316e12f55011101d88f756787ed024ceedb81cf1eba", - "component": "lib:tar", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "08c61e82b59ed6fe7e85e9fe7cceaaf853ba54511d1ec57efa511ddc55ef1998", - "version": "0.6.2.0" - }, - { - "cabal_sha256": "64a1925c93e9a26cd4c40c470736950c4b5ea7bae68418cb996c5c7df4873cba", - "component": "lib:zlib", - "flags": [ - "-bundled-c-zlib", - "+non-blocking-ffi", - "-pkg-config" - ], - "package": "zlib", - "revision": 1, - "source": "hackage", - "src_sha256": "7e43c205e1e1ff5a4b033086ec8cce82ab658879e977c8ba02a6701946ff7a47", - "version": "0.7.0.0" - }, - { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", - "component": "lib:hackage-security", - "flags": [ - "+cabal-syntax", - "+lukko" - ], - "package": "hackage-security", - "revision": 1, - "source": "hackage", - "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", - "version": "0.6.2.6" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "lib:open-browser", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - }, - { - "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", - "component": "lib:regex-base", - "flags": [], - "package": "regex-base", - "revision": 4, - "source": "hackage", - "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", - "version": "0.94.0.2" - }, - { - "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", - "component": "lib:regex-posix", - "flags": [ - "-_regex-posix-clib" - ], - "package": "regex-posix", - "revision": 3, - "source": "hackage", - "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", - "version": "0.96.0.1" - }, - { - "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", - "component": "lib:resolv", - "flags": [], - "package": "resolv", - "revision": 3, - "source": "hackage", - "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", - "version": "0.2.0.2" - }, - { - "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", - "component": "lib:safe-exceptions", - "flags": [], - "package": "safe-exceptions", - "revision": 1, - "source": "hackage", - "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", - "version": "0.1.7.4" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "exe:cabal", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "exe:example", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - } - ] + "builtin": [ + { + "package": "rts", + "version": "1.0.2" + }, + { + "package": "ghc-prim", + "version": "0.11.0" + }, + { + "package": "ghc-bignum", + "version": "1.3" + }, + { + "package": "base", + "version": "4.19.1.0" + }, + { + "package": "array", + "version": "0.5.6.0" + }, + { + "package": "deepseq", + "version": "1.5.0.0" + }, + { + "package": "ghc-boot-th", + "version": "9.8.2" + }, + { + "package": "pretty", + "version": "1.1.3.6" + }, + { + "package": "template-haskell", + "version": "2.21.0.0" + }, + { + "package": "containers", + "version": "0.6.8" + }, + { + "package": "bytestring", + "version": "0.12.1.0" + }, + { + "package": "transformers", + "version": "0.6.1.0" + }, + { + "package": "mtl", + "version": "2.3.1" + }, + { + "package": "stm", + "version": "2.5.2.1" + }, + { + "package": "exceptions", + "version": "0.10.7" + }, + { + "package": "filepath", + "version": "1.4.200.1" + }, + { + "package": "time", + "version": "1.12.2" + }, + { + "package": "unix", + "version": "2.8.4.0" + }, + { + "package": "directory", + "version": "1.3.8.1" + }, + { + "package": "binary", + "version": "0.8.9.1" + }, + { + "package": "text", + "version": "2.1.1" + }, + { + "package": "parsec", + "version": "3.1.17.0" + }, + { + "package": "process", + "version": "1.6.18.0" + }, + { + "package": "semaphore-compat", + "version": "1.0.0" + } + ], + "dependencies": [ + { + "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", + "component": "exe:alex", + "flags": [], + "package": "alex", + "revision": 0, + "source": "hackage", + "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", + "version": "3.5.1.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-syntax", + "flags": [], + "package": "Cabal-syntax", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal", + "flags": [], + "package": "Cabal", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-hooks", + "flags": [], + "package": "Cabal-hooks", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "0.1" + }, + { + "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", + "component": "exe:hsc2hs", + "flags": [ + "-in-ghc-tree" + ], + "package": "hsc2hs", + "revision": 2, + "source": "hackage", + "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", + "version": "0.68.10" + }, + { + "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", + "component": "lib:network", + "flags": [ + "-devel" + ], + "package": "network", + "revision": 0, + "source": "hackage", + "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", + "version": "3.2.0.0" + }, + { + "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", + "component": "lib:th-compat", + "flags": [], + "package": "th-compat", + "revision": 2, + "source": "hackage", + "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", + "version": "0.1.5" + }, + { + "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", + "component": "lib:network-uri", + "flags": [], + "package": "network-uri", + "revision": 1, + "source": "hackage", + "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", + "version": "2.6.4.2" + }, + { + "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", + "component": "lib:HTTP", + "flags": [ + "-conduit10", + "+network-uri", + "-warn-as-error", + "-warp-tests" + ], + "package": "HTTP", + "revision": 4, + "source": "hackage", + "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", + "version": "4000.4.1" + }, + { + "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", + "component": "lib:os-string", + "flags": [], + "package": "os-string", + "revision": 0, + "source": "hackage", + "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", + "version": "2.0.3" + }, + { + "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", + "component": "lib:hashable", + "flags": [ + "+arch-native", + "+integer-gmp", + "-random-initial-seed" + ], + "package": "hashable", + "revision": 0, + "source": "hackage", + "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", + "version": "1.4.6.0" + }, + { + "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", + "component": "lib:async", + "flags": [ + "-bench" + ], + "package": "async", + "revision": 1, + "source": "hackage", + "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", + "version": "2.2.5" + }, + { + "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", + "component": "lib:base16-bytestring", + "flags": [], + "package": "base16-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", + "version": "1.0.2.0" + }, + { + "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", + "component": "lib:base64-bytestring", + "flags": [], + "package": "base64-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", + "version": "1.2.1.0" + }, + { + "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", + "component": "lib:splitmix", + "flags": [ + "-optimised-mixer" + ], + "package": "splitmix", + "revision": 1, + "source": "hackage", + "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", + "version": "0.1.0.5" + }, + { + "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", + "component": "lib:random", + "flags": [], + "package": "random", + "revision": 0, + "source": "hackage", + "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", + "version": "1.2.1.2" + }, + { + "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", + "component": "lib:edit-distance", + "flags": [], + "package": "edit-distance", + "revision": 1, + "source": "hackage", + "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", + "version": "0.2.2.1" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install-solver", + "flags": [ + "-debug-expensive-assertions", + "-debug-tracetree" + ], + "package": "cabal-install-solver", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", + "component": "lib:cryptohash-sha256", + "flags": [ + "-exe", + "+use-cbits" + ], + "package": "cryptohash-sha256", + "revision": 4, + "source": "hackage", + "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", + "version": "0.11.102.1" + }, + { + "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", + "component": "lib:echo", + "flags": [ + "-example" + ], + "package": "echo", + "revision": 0, + "source": "hackage", + "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", + "version": "0.1.4" + }, + { + "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", + "component": "lib:ed25519", + "flags": [ + "+no-donna", + "+test-doctests", + "+test-hlint", + "+test-properties" + ], + "package": "ed25519", + "revision": 8, + "source": "hackage", + "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", + "version": "0.0.5.0" + }, + { + "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", + "component": "lib:lukko", + "flags": [ + "+ofd-locking" + ], + "package": "lukko", + "revision": 0, + "source": "hackage", + "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", + "version": "0.1.2" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar-internal", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", + "component": "lib:zlib", + "flags": [ + "-bundled-c-zlib", + "+non-blocking-ffi", + "-pkg-config" + ], + "package": "zlib", + "revision": 0, + "source": "hackage", + "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", + "version": "0.7.1.0" + }, + { + "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", + "component": "lib:hackage-security", + "flags": [ + "+cabal-syntax", + "+lukko" + ], + "package": "hackage-security", + "revision": 1, + "source": "hackage", + "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", + "version": "0.6.2.6" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "lib:open-browser", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + }, + { + "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", + "component": "lib:regex-base", + "flags": [], + "package": "regex-base", + "revision": 4, + "source": "hackage", + "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", + "version": "0.94.0.2" + }, + { + "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", + "component": "lib:regex-posix", + "flags": [ + "-_regex-posix-clib" + ], + "package": "regex-posix", + "revision": 3, + "source": "hackage", + "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", + "version": "0.96.0.1" + }, + { + "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", + "component": "lib:resolv", + "flags": [], + "package": "resolv", + "revision": 3, + "source": "hackage", + "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", + "version": "0.2.0.2" + }, + { + "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", + "component": "lib:safe-exceptions", + "flags": [], + "package": "safe-exceptions", + "revision": 1, + "source": "hackage", + "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", + "version": "0.1.7.4" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "exe:cabal", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "exe:example", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + } + ] } diff --git a/cabal.bootstrap.project b/cabal.bootstrap.project index 845a3fca7fd..74c8ca5e47a 100644 --- a/cabal.bootstrap.project +++ b/cabal.bootstrap.project @@ -9,4 +9,4 @@ packages: tests: False benchmarks: False -index-state: hackage.haskell.org 2024-04-22T06:16:57Z +index-state: hackage.haskell.org 2024-06-17T00:00:01Z From 08adfc9c338ea8408c5a2b5baaf4232fe452ee5a Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Wed, 19 Jun 2024 11:52:31 +0200 Subject: [PATCH 018/207] Use `msys2` shell on Windows GHA runners --- .github/workflows/validate.yml | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index a34023d2d9e..600e8e982bb 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -1,11 +1,5 @@ name: Validate -# We use bash as default even in windows -# to try keep the workflow as uniform as possible -defaults: - run: - shell: bash - # See: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#concurrency. concurrency: group: ${{ github.ref }}-${{ github.workflow }} @@ -60,28 +54,33 @@ env: jobs: validate: - name: Validate ${{ matrix.os }} ghc-${{ matrix.ghc }} - runs-on: ${{ matrix.os }} + name: Validate ${{ matrix.sys.os }} ghc-${{ matrix.ghc }} + runs-on: ${{ matrix.sys.os }} outputs: GHC_FOR_RELEASE: ${{ format('["{0}"]', env.GHC_FOR_RELEASE) }} strategy: matrix: - os: [ubuntu-latest, macos-13, windows-latest] + sys: + - { os: windows-latest, shell: 'C:/msys64/usr/bin/bash.exe -e {0}' } + - { os: ubuntu-latest, shell: bash } + - { os: macos-13, shell: bash} # If you remove something from here, then add it to the old-ghcs job. # Also a removed GHC from here means that we are actually dropping # support, so the PR *must* have a changelog entry. ghc: ['9.10.1', '9.8.2', '9.6.4', '9.4.8', '9.2.8', '9.0.2', '8.10.7', '8.8.4', '8.6.5'] exclude: # corrupts GHA cache or the fabric of reality itself, see https://github.com/haskell/cabal/issues/8356 - - os: windows-latest + - sys: { os: windows-latest, shell: 'C:/msys64/usr/bin/bash.exe -e {0}' } ghc: '8.10.7' # lot of segfaults caused by ghc bugs - - os: windows-latest + - sys: { os: windows-latest, shell: 'C:/msys64/usr/bin/bash.exe -e {0}' } ghc: '8.8.4' # it often randomly does "C:\Users\RUNNER~1\AppData\Local\Temp\ghcFEDE.c: DeleteFile "\\\\?\\C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\ghcFEDE.c": permission denied (Access is denied.)" - - os: windows-latest + - sys: { os: windows-latest, shell: 'C:/msys64/usr/bin/bash.exe -e {0}' } ghc: '8.6.5' - + defaults: + run: + shell: ${{ matrix.sys.shell }} steps: - name: Work around XDG directories existence (haskell-actions/setup#62) From 2018e30b11d8678c7291b61d9e9987fc952db586 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Sat, 22 Jun 2024 20:45:33 -0400 Subject: [PATCH 019/207] Don't use tasty-quickcheck 0.11 API incompatible with our test suites --- Cabal-described/Cabal-described.cabal | 4 ++-- Cabal-tests/Cabal-tests.cabal | 4 ++-- cabal-install-solver/cabal-install-solver.cabal | 2 +- cabal-install/cabal-install.cabal | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cabal-described/Cabal-described.cabal b/Cabal-described/Cabal-described.cabal index 8f7f9c66750..d8471940cea 100644 --- a/Cabal-described/Cabal-described.cabal +++ b/Cabal-described/Cabal-described.cabal @@ -18,8 +18,8 @@ library , pretty , QuickCheck , rere >=0.1 && <0.3 - , tasty - , tasty-quickcheck + , tasty <1.6 + , tasty-quickcheck <0.11 exposed-modules: Distribution.Described diff --git a/Cabal-tests/Cabal-tests.cabal b/Cabal-tests/Cabal-tests.cabal index f48222332f4..dd443d1fc21 100644 --- a/Cabal-tests/Cabal-tests.cabal +++ b/Cabal-tests/Cabal-tests.cabal @@ -71,7 +71,7 @@ test-suite unit-tests , QuickCheck >=2.14 && <2.15 , tasty >=1.2.3 && <1.6 , tasty-hunit - , tasty-quickcheck + , tasty-quickcheck <0.11 , temporary , text @@ -176,7 +176,7 @@ test-suite rpmvercmp QuickCheck , tasty >=1.2.3 && <1.6 , tasty-hunit - , tasty-quickcheck + , tasty-quickcheck <0.11 c-sources: tests/cbits/rpmvercmp.c cc-options: -Wall diff --git a/cabal-install-solver/cabal-install-solver.cabal b/cabal-install-solver/cabal-install-solver.cabal index 6918f739b88..b2b2b12b7af 100644 --- a/cabal-install-solver/cabal-install-solver.cabal +++ b/cabal-install-solver/cabal-install-solver.cabal @@ -135,5 +135,5 @@ Test-Suite unit-tests , Cabal-syntax , cabal-install-solver , tasty >= 1.2.3 && <1.6 - , tasty-quickcheck + , tasty-quickcheck <0.11 , tasty-hunit >= 0.10 diff --git a/cabal-install/cabal-install.cabal b/cabal-install/cabal-install.cabal index f00041aa9e3..5f20b3db947 100644 --- a/cabal-install/cabal-install.cabal +++ b/cabal-install/cabal-install.cabal @@ -350,7 +350,7 @@ test-suite unit-tests zlib, tasty >= 1.2.3 && <1.6, tasty-golden >=2.3.1.1 && <2.4, - tasty-quickcheck, + tasty-quickcheck <0.11, tasty-expected-failure, tasty-hunit >= 0.10, tree-diff, @@ -438,6 +438,6 @@ test-suite long-tests tasty >= 1.2.3 && <1.6, tasty-expected-failure, tasty-hunit >= 0.10, - tasty-quickcheck, + tasty-quickcheck <0.11, QuickCheck >= 2.14 && <2.16, pretty-show >= 1.6.15 From e6362e6882036a1340b871ed54b0ac972fef14ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9cate?= Date: Mon, 24 Jun 2024 20:12:53 +0200 Subject: [PATCH 020/207] Disable arch-native flag when building releases that we distribute (#10142) * Disable arch-native flag when building releases that we distribute * Use the constraints stanza * Also disable the flag in cabal.validate.project --- cabal.release.project | 3 +++ cabal.validate.project | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/cabal.release.project b/cabal.release.project index 5ce38e721a5..ffd7c18adc1 100644 --- a/cabal.release.project +++ b/cabal.release.project @@ -2,4 +2,7 @@ import: project-cabal/pkgs/cabal.config import: project-cabal/pkgs/install.config import: project-cabal/pkgs/tests.config +constraints: + hashable -arch-native + index-state: hackage.haskell.org 2024-06-17T00:00:01Z diff --git a/cabal.validate.project b/cabal.validate.project index 52c78411107..2e3084cccf0 100644 --- a/cabal.validate.project +++ b/cabal.validate.project @@ -7,3 +7,8 @@ tests: True write-ghc-environment-files: never program-options ghc-options: -Werror + +-- This project file is used to distribute the cabal-head binary, +-- as such we cannot enable "-march=native". +constraints: + hashable -arch-native From c932a1cfcbdf6eeaebef48642011177e4e100597 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Fri, 12 Apr 2024 11:43:17 +0100 Subject: [PATCH 021/207] Add support for profiled dynamic way New options for cabal.project and ./Setup interface: * `profiling-shared`: Enable building profiling dynamic way * Passing `--enable-profiling` and `--enable-executable-dynamic` builds profiled dynamic executables. Support for using `profiling-shared` is guarded behind a constraint which ensures you are using `Cabal >= 3.13`. In the cabal file: * `ghc-prof-shared-options`, for passing options when building in profiling dynamic way Other miscellenious fixes and improvements * Some refactoring around ways so that which ways we should build for a library, foreign library and executable is computed by the `buildWays` function (rather than ad-hoc in three different places). * Improved logic for detecting whether a compiler supports compiling a specific way. See functions `profilingVanillaSupported`, `dynamicSupported`, `profilingDynamicSupported` etc These functions report accurate infomation after ghc-9.10.1. * Fixed logic for determining whether to build shared libraries. (see #10050) Now, if you explicitly enable `--*-shared`, then that will always take effect. If it's not specified then `--enable-executable-dynamic` will turn on shared libraries IF `--enable-profiling` is not enabled. * Remove assumption that dynamically linked compilers can build dynamic libraries (they might be cross compilers. * Query the build compiler to determine which library way is necessary to be built for TH support to work. (rather than assume all compilers are dynamically linked) * An extensive test which checks how options for `./Setup` and `cabal-install` are translated into build ways. Fixes #4816, #10049, #10050 --- .../PackageDescription/FieldGrammar.hs | 14 + .../src/Distribution/Types/BuildInfo.hs | 7 + .../src/Distribution/Types/BuildInfo/Lens.hs | 7 + .../ParserTests/regressions/Octree-0.5.expr | 6 + .../ParserTests/regressions/anynone.expr | 2 + .../ParserTests/regressions/big-version.expr | 2 + .../regressions/common-conditional.expr | 16 + .../tests/ParserTests/regressions/common.expr | 4 + .../ParserTests/regressions/common2.expr | 16 + .../ParserTests/regressions/common3.expr | 4 + .../tests/ParserTests/regressions/elif.expr | 4 + .../tests/ParserTests/regressions/elif2.expr | 10 + .../ParserTests/regressions/encoding-0.8.expr | 2 + .../ParserTests/regressions/generics-sop.expr | 14 + .../ParserTests/regressions/hasktorch.expr | 36 ++ .../regressions/hidden-main-lib.expr | 2 + .../ParserTests/regressions/indentation.expr | 2 + .../ParserTests/regressions/indentation2.expr | 2 + .../ParserTests/regressions/indentation3.expr | 2 + .../ParserTests/regressions/issue-5055.expr | 6 + .../ParserTests/regressions/issue-5846.expr | 2 + .../ParserTests/regressions/issue-6083-a.expr | 8 + .../ParserTests/regressions/issue-6083-b.expr | 8 + .../ParserTests/regressions/issue-6083-c.expr | 4 + .../regressions/issue-6083-pkg-pkg.expr | 2 + .../ParserTests/regressions/issue-774.expr | 2 + .../regressions/jaeger-flamegraph.expr | 6 + .../regressions/leading-comma-2.expr | 2 + .../regressions/leading-comma.expr | 2 + .../tests/ParserTests/regressions/libpq1.expr | 16 + .../tests/ParserTests/regressions/libpq2.expr | 16 + .../ParserTests/regressions/mixin-1.expr | 2 + .../ParserTests/regressions/mixin-2.expr | 2 + .../ParserTests/regressions/mixin-3.expr | 2 + .../ParserTests/regressions/monad-param.expr | 2 + .../regressions/multiple-libs-2.expr | 4 + .../ParserTests/regressions/noVersion.expr | 2 + .../regressions/nothing-unicode.expr | 4 + .../tests/ParserTests/regressions/shake.expr | 42 +++ .../tests/ParserTests/regressions/spdx-1.expr | 2 + .../tests/ParserTests/regressions/spdx-2.expr | 2 + .../tests/ParserTests/regressions/spdx-3.expr | 2 + .../regressions/th-lift-instances.expr | 8 + .../ParserTests/regressions/version-sets.expr | 2 + .../regressions/wl-pprint-indef.expr | 4 + .../Distribution/Utils/Structured.hs | 8 +- Cabal/Cabal.cabal | 1 + Cabal/src/Distribution/Simple/BuildPaths.hs | 5 + Cabal/src/Distribution/Simple/BuildWay.hs | 14 + Cabal/src/Distribution/Simple/Compiler.hs | 48 +++ Cabal/src/Distribution/Simple/Configure.hs | 94 +++-- Cabal/src/Distribution/Simple/GHC.hs | 173 +++++---- Cabal/src/Distribution/Simple/GHC/Build.hs | 41 +-- .../Simple/GHC/Build/ExtraSources.hs | 212 ++++++----- .../src/Distribution/Simple/GHC/Build/Link.hs | 343 ++++++++++-------- .../Distribution/Simple/GHC/Build/Modules.hs | 118 ++++-- .../Distribution/Simple/GHC/Build/Utils.hs | 12 + Cabal/src/Distribution/Simple/Hpc.hs | 3 +- .../src/Distribution/Simple/LocalBuildInfo.hs | 1 + Cabal/src/Distribution/Simple/Setup/Config.hs | 10 + .../Distribution/Types/LocalBuildConfig.hs | 3 + .../src/Distribution/Types/LocalBuildInfo.hs | 53 ++- .../Solver/Types/ConstraintSource.hs | 6 + .../src/Distribution/Client/Config.hs | 1 + .../src/Distribution/Client/Dependency.hs | 17 + .../src/Distribution/Client/ProjectConfig.hs | 38 +- .../Client/ProjectConfig/Legacy.hs | 5 + .../Client/ProjectConfig/Types.hs | 1 + .../Client/ProjectOrchestration.hs | 5 +- .../Distribution/Client/ProjectPlanning.hs | 149 ++++++-- .../src/Distribution/Client/Setup.hs | 14 +- .../Distribution/Client/ProjectConfig.hs | 7 +- .../PackageTests/ProfShared/Lib.hs | 3 + .../PackageTests/ProfShared/exe/Prof.hs | 5 + .../PackageTests/ProfShared/profShared.cabal | 13 + .../PackageTests/ProfShared/setup.test.hs | 145 ++++++++ .../PackageTests/ProfSharedWarning/Lib.hs | 3 + .../ProfSharedWarning/cabal.project | 1 + .../ProfSharedWarning/exe/Prof.hs | 5 + .../ProfSharedWarning/profShared.cabal | 13 + .../PackageTests/ProfSharedWarning/setup.out | 3 + .../ProfSharedWarning/setup_prof.out | 4 + cabal-testsuite/src/Test/Cabal/Prelude.hs | 16 +- changelog.d/issue-4816 | 23 ++ changelog.d/issue-4816-2 | 26 ++ doc/buildinfo-fields-reference.rst | 16 + doc/cabal-package-description-file.rst | 11 + doc/setup-commands.rst | 11 + 88 files changed, 1503 insertions(+), 483 deletions(-) create mode 100644 Cabal/src/Distribution/Simple/BuildWay.hs create mode 100644 cabal-testsuite/PackageTests/ProfShared/Lib.hs create mode 100644 cabal-testsuite/PackageTests/ProfShared/exe/Prof.hs create mode 100644 cabal-testsuite/PackageTests/ProfShared/profShared.cabal create mode 100644 cabal-testsuite/PackageTests/ProfShared/setup.test.hs create mode 100644 cabal-testsuite/PackageTests/ProfSharedWarning/Lib.hs create mode 100644 cabal-testsuite/PackageTests/ProfSharedWarning/cabal.project create mode 100644 cabal-testsuite/PackageTests/ProfSharedWarning/exe/Prof.hs create mode 100644 cabal-testsuite/PackageTests/ProfSharedWarning/profShared.cabal create mode 100644 cabal-testsuite/PackageTests/ProfSharedWarning/setup.out create mode 100644 cabal-testsuite/PackageTests/ProfSharedWarning/setup_prof.out create mode 100644 changelog.d/issue-4816 create mode 100644 changelog.d/issue-4816-2 diff --git a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs index db6b7f7607b..4d9ada935af 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs @@ -673,6 +673,7 @@ buildInfoFieldGrammar = <*> optionsFieldGrammar <*> profOptionsFieldGrammar <*> sharedOptionsFieldGrammar + <*> profSharedOptionsFieldGrammar <*> pure mempty -- static-options ??? <*> prefixedFields "x-" L.customFieldsBI <*> monoidalFieldAla "build-depends" formatDependencyList L.targetBuildDepends @@ -738,6 +739,19 @@ sharedOptionsFieldGrammar = extract :: CompilerFlavor -> ALens' BuildInfo [String] extract flavor = L.sharedOptions . lookupLens flavor +profSharedOptionsFieldGrammar + :: (FieldGrammar c g, Applicative (g BuildInfo), c (List NoCommaFSep Token' String)) + => g BuildInfo (PerCompilerFlavor [String]) +profSharedOptionsFieldGrammar = + PerCompilerFlavor + <$> monoidalFieldAla "ghc-prof-shared-options" (alaList' NoCommaFSep Token') (extract GHC) + ^^^ availableSince CabalSpecV3_14 [] + <*> monoidalFieldAla "ghcjs-prof-shared-options" (alaList' NoCommaFSep Token') (extract GHCJS) + ^^^ availableSince CabalSpecV3_14 [] + where + extract :: CompilerFlavor -> ALens' BuildInfo [String] + extract flavor = L.profSharedOptions . lookupLens flavor + lookupLens :: (Functor f, Monoid v) => CompilerFlavor -> LensLike' f (PerCompilerFlavor v) v lookupLens k f p@(PerCompilerFlavor ghc ghcjs) | k == GHC = (\n -> PerCompilerFlavor n ghcjs) <$> f ghc diff --git a/Cabal-syntax/src/Distribution/Types/BuildInfo.hs b/Cabal-syntax/src/Distribution/Types/BuildInfo.hs index da1f8aea88f..680b9bf49db 100644 --- a/Cabal-syntax/src/Distribution/Types/BuildInfo.hs +++ b/Cabal-syntax/src/Distribution/Types/BuildInfo.hs @@ -12,6 +12,7 @@ module Distribution.Types.BuildInfo , hcOptions , hcProfOptions , hcSharedOptions + , hcProfSharedOptions , hcStaticOptions ) where @@ -133,6 +134,7 @@ data BuildInfo = BuildInfo , options :: PerCompilerFlavor [String] , profOptions :: PerCompilerFlavor [String] , sharedOptions :: PerCompilerFlavor [String] + , profSharedOptions :: PerCompilerFlavor [String] , staticOptions :: PerCompilerFlavor [String] , customFieldsBI :: [(String, String)] -- ^ Custom fields starting @@ -193,6 +195,7 @@ instance Monoid BuildInfo where , options = mempty , profOptions = mempty , sharedOptions = mempty + , profSharedOptions = mempty , staticOptions = mempty , customFieldsBI = [] , targetBuildDepends = [] @@ -245,6 +248,7 @@ instance Semigroup BuildInfo where , options = combine options , profOptions = combine profOptions , sharedOptions = combine sharedOptions + , profSharedOptions = combine profSharedOptions , staticOptions = combine staticOptions , customFieldsBI = combine customFieldsBI , targetBuildDepends = combineNub targetBuildDepends @@ -295,6 +299,9 @@ hcProfOptions = lookupHcOptions profOptions hcSharedOptions :: CompilerFlavor -> BuildInfo -> [String] hcSharedOptions = lookupHcOptions sharedOptions +hcProfSharedOptions :: CompilerFlavor -> BuildInfo -> [String] +hcProfSharedOptions = lookupHcOptions profSharedOptions + hcStaticOptions :: CompilerFlavor -> BuildInfo -> [String] hcStaticOptions = lookupHcOptions staticOptions diff --git a/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs b/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs index 19453a671b9..ac99f3c65a5 100644 --- a/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs +++ b/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs @@ -195,6 +195,10 @@ class HasBuildInfo a where sharedOptions = buildInfo . sharedOptions {-# INLINE sharedOptions #-} + profSharedOptions :: Lens' a (PerCompilerFlavor [String]) + profSharedOptions = buildInfo . profSharedOptions + {-# INLINE profSharedOptions #-} + staticOptions :: Lens' a (PerCompilerFlavor [String]) staticOptions = buildInfo . staticOptions {-# INLINE staticOptions #-} @@ -341,6 +345,9 @@ instance HasBuildInfo BuildInfo where sharedOptions f s = fmap (\x -> s{T.sharedOptions = x}) (f (T.sharedOptions s)) {-# INLINE sharedOptions #-} + profSharedOptions f s = fmap (\x -> s{T.profSharedOptions = x}) (f (T.profSharedOptions s)) + {-# INLINE profSharedOptions #-} + staticOptions f s = fmap (\x -> s{T.staticOptions = x}) (f (T.staticOptions s)) {-# INLINE staticOptions #-} diff --git a/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.expr b/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.expr index 3d03421210b..b3494104aed 100644 --- a/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.expr +++ b/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.expr @@ -132,6 +132,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -238,6 +240,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -339,6 +343,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/anynone.expr b/Cabal-tests/tests/ParserTests/regressions/anynone.expr index 3191425d609..8c9c8879ab4 100644 --- a/Cabal-tests/tests/ParserTests/regressions/anynone.expr +++ b/Cabal-tests/tests/ParserTests/regressions/anynone.expr @@ -95,6 +95,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/big-version.expr b/Cabal-tests/tests/ParserTests/regressions/big-version.expr index e677de20626..d4ef82adf52 100644 --- a/Cabal-tests/tests/ParserTests/regressions/big-version.expr +++ b/Cabal-tests/tests/ParserTests/regressions/big-version.expr @@ -96,6 +96,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/common-conditional.expr b/Cabal-tests/tests/ParserTests/regressions/common-conditional.expr index f6ffe291e59..9cacba2b770 100644 --- a/Cabal-tests/tests/ParserTests/regressions/common-conditional.expr +++ b/Cabal-tests/tests/ParserTests/regressions/common-conditional.expr @@ -112,6 +112,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -187,6 +189,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -278,6 +282,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -356,6 +362,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -432,6 +440,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -501,6 +511,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -593,6 +605,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -670,6 +684,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/common.expr b/Cabal-tests/tests/ParserTests/regressions/common.expr index e0eb4a1dde7..25abadef9e7 100644 --- a/Cabal-tests/tests/ParserTests/regressions/common.expr +++ b/Cabal-tests/tests/ParserTests/regressions/common.expr @@ -110,6 +110,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -186,6 +188,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/common2.expr b/Cabal-tests/tests/ParserTests/regressions/common2.expr index b3cb004eecb..cd501d11cf2 100644 --- a/Cabal-tests/tests/ParserTests/regressions/common2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/common2.expr @@ -106,6 +106,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -205,6 +207,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -285,6 +289,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -386,6 +392,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -462,6 +470,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -562,6 +572,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -639,6 +651,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -716,6 +730,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/common3.expr b/Cabal-tests/tests/ParserTests/regressions/common3.expr index 21b200baa7b..fc1fc155c09 100644 --- a/Cabal-tests/tests/ParserTests/regressions/common3.expr +++ b/Cabal-tests/tests/ParserTests/regressions/common3.expr @@ -110,6 +110,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -186,6 +188,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/elif.expr b/Cabal-tests/tests/ParserTests/regressions/elif.expr index 1315d689467..f17c1e17b88 100644 --- a/Cabal-tests/tests/ParserTests/regressions/elif.expr +++ b/Cabal-tests/tests/ParserTests/regressions/elif.expr @@ -105,6 +105,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -172,6 +174,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/elif2.expr b/Cabal-tests/tests/ParserTests/regressions/elif2.expr index 61f2177cbaa..ec01a92a79d 100644 --- a/Cabal-tests/tests/ParserTests/regressions/elif2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/elif2.expr @@ -105,6 +105,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -172,6 +174,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -245,6 +249,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -312,6 +318,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -385,6 +393,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/encoding-0.8.expr b/Cabal-tests/tests/ParserTests/regressions/encoding-0.8.expr index e1b125e7a32..0d248029a31 100644 --- a/Cabal-tests/tests/ParserTests/regressions/encoding-0.8.expr +++ b/Cabal-tests/tests/ParserTests/regressions/encoding-0.8.expr @@ -114,6 +114,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/generics-sop.expr b/Cabal-tests/tests/ParserTests/regressions/generics-sop.expr index 9084371a614..25786cdfad5 100644 --- a/Cabal-tests/tests/ParserTests/regressions/generics-sop.expr +++ b/Cabal-tests/tests/ParserTests/regressions/generics-sop.expr @@ -242,6 +242,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -373,6 +375,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -457,6 +461,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -561,6 +567,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -631,6 +639,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -702,6 +712,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [ @@ -798,6 +810,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/hasktorch.expr b/Cabal-tests/tests/ParserTests/regressions/hasktorch.expr index 346af927d1b..c68fac467e1 100644 --- a/Cabal-tests/tests/ParserTests/regressions/hasktorch.expr +++ b/Cabal-tests/tests/ParserTests/regressions/hasktorch.expr @@ -322,6 +322,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -642,6 +644,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -884,6 +888,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -1084,6 +1090,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -1438,6 +1446,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -2740,6 +2750,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -2829,6 +2841,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -5072,6 +5086,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -6424,6 +6440,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -6514,6 +6532,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -8182,6 +8202,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -8670,6 +8692,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -9433,6 +9457,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -9554,6 +9580,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -9659,6 +9687,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -9764,6 +9794,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -9858,6 +9890,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -9978,6 +10012,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/hidden-main-lib.expr b/Cabal-tests/tests/ParserTests/regressions/hidden-main-lib.expr index fba99528b53..b51b4adacb2 100644 --- a/Cabal-tests/tests/ParserTests/regressions/hidden-main-lib.expr +++ b/Cabal-tests/tests/ParserTests/regressions/hidden-main-lib.expr @@ -97,6 +97,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/indentation.expr b/Cabal-tests/tests/ParserTests/regressions/indentation.expr index e5b106dc5cd..c97630ddb00 100644 --- a/Cabal-tests/tests/ParserTests/regressions/indentation.expr +++ b/Cabal-tests/tests/ParserTests/regressions/indentation.expr @@ -106,6 +106,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/indentation2.expr b/Cabal-tests/tests/ParserTests/regressions/indentation2.expr index 46f24105f0f..605cba525d1 100644 --- a/Cabal-tests/tests/ParserTests/regressions/indentation2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/indentation2.expr @@ -99,6 +99,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/indentation3.expr b/Cabal-tests/tests/ParserTests/regressions/indentation3.expr index 0191d063f6e..55d0533c3fe 100644 --- a/Cabal-tests/tests/ParserTests/regressions/indentation3.expr +++ b/Cabal-tests/tests/ParserTests/regressions/indentation3.expr @@ -101,6 +101,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr b/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr index 07c04ec6cb9..3b5092639e4 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr @@ -100,6 +100,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -183,6 +185,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -267,6 +271,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-5846.expr b/Cabal-tests/tests/ParserTests/regressions/issue-5846.expr index 2ff7de7917e..61a7b7d2ca1 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-5846.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-5846.expr @@ -94,6 +94,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-6083-a.expr b/Cabal-tests/tests/ParserTests/regressions/issue-6083-a.expr index 43c345dd170..c9c57785ac6 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-6083-a.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-6083-a.expr @@ -94,6 +94,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -189,6 +191,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -255,6 +259,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -335,6 +341,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-6083-b.expr b/Cabal-tests/tests/ParserTests/regressions/issue-6083-b.expr index e6606851627..b0ed19062fc 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-6083-b.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-6083-b.expr @@ -94,6 +94,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -189,6 +191,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -255,6 +259,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -345,6 +351,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-6083-c.expr b/Cabal-tests/tests/ParserTests/regressions/issue-6083-c.expr index 7435b0d59b4..c901eebc8ce 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-6083-c.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-6083-c.expr @@ -94,6 +94,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -189,6 +191,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-6083-pkg-pkg.expr b/Cabal-tests/tests/ParserTests/regressions/issue-6083-pkg-pkg.expr index a221632efa4..62ed5fd2fb9 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-6083-pkg-pkg.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-6083-pkg-pkg.expr @@ -94,6 +94,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-774.expr b/Cabal-tests/tests/ParserTests/regressions/issue-774.expr index e1ffb85dceb..2f58de4eb00 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-774.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-774.expr @@ -108,6 +108,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/jaeger-flamegraph.expr b/Cabal-tests/tests/ParserTests/regressions/jaeger-flamegraph.expr index c9e675ceb76..9994c9b72c1 100644 --- a/Cabal-tests/tests/ParserTests/regressions/jaeger-flamegraph.expr +++ b/Cabal-tests/tests/ParserTests/regressions/jaeger-flamegraph.expr @@ -139,6 +139,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -238,6 +240,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -403,6 +407,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/leading-comma-2.expr b/Cabal-tests/tests/ParserTests/regressions/leading-comma-2.expr index 0bb5556b2f4..99f7cddf881 100644 --- a/Cabal-tests/tests/ParserTests/regressions/leading-comma-2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/leading-comma-2.expr @@ -104,6 +104,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/leading-comma.expr b/Cabal-tests/tests/ParserTests/regressions/leading-comma.expr index b1ba1b282f4..441fe75261d 100644 --- a/Cabal-tests/tests/ParserTests/regressions/leading-comma.expr +++ b/Cabal-tests/tests/ParserTests/regressions/leading-comma.expr @@ -97,6 +97,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/libpq1.expr b/Cabal-tests/tests/ParserTests/regressions/libpq1.expr index 8906a91f63b..2e0bc309f9f 100644 --- a/Cabal-tests/tests/ParserTests/regressions/libpq1.expr +++ b/Cabal-tests/tests/ParserTests/regressions/libpq1.expr @@ -190,6 +190,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -289,6 +291,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -373,6 +377,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -464,6 +470,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -529,6 +537,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -596,6 +606,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -661,6 +673,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -728,6 +742,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/libpq2.expr b/Cabal-tests/tests/ParserTests/regressions/libpq2.expr index 3c26ece45ad..b74143af0b9 100644 --- a/Cabal-tests/tests/ParserTests/regressions/libpq2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/libpq2.expr @@ -195,6 +195,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -294,6 +296,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -378,6 +382,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -466,6 +472,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -531,6 +539,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -598,6 +608,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -663,6 +675,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -730,6 +744,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/mixin-1.expr b/Cabal-tests/tests/ParserTests/regressions/mixin-1.expr index de8a15f04c0..77821302ddf 100644 --- a/Cabal-tests/tests/ParserTests/regressions/mixin-1.expr +++ b/Cabal-tests/tests/ParserTests/regressions/mixin-1.expr @@ -98,6 +98,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/mixin-2.expr b/Cabal-tests/tests/ParserTests/regressions/mixin-2.expr index 3bf06bc9c3b..d8b58ff5a0b 100644 --- a/Cabal-tests/tests/ParserTests/regressions/mixin-2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/mixin-2.expr @@ -98,6 +98,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/mixin-3.expr b/Cabal-tests/tests/ParserTests/regressions/mixin-3.expr index 0c0fc57a8b8..c0cbfe921ad 100644 --- a/Cabal-tests/tests/ParserTests/regressions/mixin-3.expr +++ b/Cabal-tests/tests/ParserTests/regressions/mixin-3.expr @@ -98,6 +98,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/monad-param.expr b/Cabal-tests/tests/ParserTests/regressions/monad-param.expr index 28d57c1e3b0..e450672e868 100644 --- a/Cabal-tests/tests/ParserTests/regressions/monad-param.expr +++ b/Cabal-tests/tests/ParserTests/regressions/monad-param.expr @@ -120,6 +120,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/multiple-libs-2.expr b/Cabal-tests/tests/ParserTests/regressions/multiple-libs-2.expr index a8c6b0c0c4a..aa7d6954637 100644 --- a/Cabal-tests/tests/ParserTests/regressions/multiple-libs-2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/multiple-libs-2.expr @@ -97,6 +97,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -175,6 +177,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/noVersion.expr b/Cabal-tests/tests/ParserTests/regressions/noVersion.expr index 8187272c2c0..dfe79d768fb 100644 --- a/Cabal-tests/tests/ParserTests/regressions/noVersion.expr +++ b/Cabal-tests/tests/ParserTests/regressions/noVersion.expr @@ -97,6 +97,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/nothing-unicode.expr b/Cabal-tests/tests/ParserTests/regressions/nothing-unicode.expr index 2f2663733c6..2ed17f6d557 100644 --- a/Cabal-tests/tests/ParserTests/regressions/nothing-unicode.expr +++ b/Cabal-tests/tests/ParserTests/regressions/nothing-unicode.expr @@ -112,6 +112,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -179,6 +181,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/shake.expr b/Cabal-tests/tests/ParserTests/regressions/shake.expr index 8dd849d75bd..4dd37e84de0 100644 --- a/Cabal-tests/tests/ParserTests/regressions/shake.expr +++ b/Cabal-tests/tests/ParserTests/regressions/shake.expr @@ -306,6 +306,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -519,6 +521,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -586,6 +590,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -660,6 +666,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -727,6 +735,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -805,6 +815,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -982,6 +994,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -1206,6 +1220,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -1271,6 +1287,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -1335,6 +1353,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -1406,6 +1426,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -1470,6 +1492,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -1545,6 +1569,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -1764,6 +1790,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -1992,6 +2020,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -2061,6 +2091,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -2130,6 +2162,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -2198,6 +2232,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -2273,6 +2309,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -2341,6 +2379,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -2420,6 +2460,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/spdx-1.expr b/Cabal-tests/tests/ParserTests/regressions/spdx-1.expr index 2ca07bf2322..ddeaf37cbe4 100644 --- a/Cabal-tests/tests/ParserTests/regressions/spdx-1.expr +++ b/Cabal-tests/tests/ParserTests/regressions/spdx-1.expr @@ -95,6 +95,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/spdx-2.expr b/Cabal-tests/tests/ParserTests/regressions/spdx-2.expr index 9c50edd4864..b865b1f31db 100644 --- a/Cabal-tests/tests/ParserTests/regressions/spdx-2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/spdx-2.expr @@ -99,6 +99,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/spdx-3.expr b/Cabal-tests/tests/ParserTests/regressions/spdx-3.expr index 944faa4c0c0..dc8f3f922b9 100644 --- a/Cabal-tests/tests/ParserTests/regressions/spdx-3.expr +++ b/Cabal-tests/tests/ParserTests/regressions/spdx-3.expr @@ -99,6 +99,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.expr b/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.expr index 8f2edf09a36..5e781597f30 100644 --- a/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.expr +++ b/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.expr @@ -127,6 +127,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -298,6 +300,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -473,6 +477,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -577,6 +583,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/version-sets.expr b/Cabal-tests/tests/ParserTests/regressions/version-sets.expr index b134e4584ad..3244bc1cc45 100644 --- a/Cabal-tests/tests/ParserTests/regressions/version-sets.expr +++ b/Cabal-tests/tests/ParserTests/regressions/version-sets.expr @@ -121,6 +121,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/wl-pprint-indef.expr b/Cabal-tests/tests/ParserTests/regressions/wl-pprint-indef.expr index 03959b195c0..6e718e3e685 100644 --- a/Cabal-tests/tests/ParserTests/regressions/wl-pprint-indef.expr +++ b/Cabal-tests/tests/ParserTests/regressions/wl-pprint-indef.expr @@ -114,6 +114,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], @@ -202,6 +204,8 @@ GenericPackageDescription { [], sharedOptions = PerCompilerFlavor [] [], + profSharedOptions = + PerCompilerFlavor [] [], staticOptions = PerCompilerFlavor [] [], customFieldsBI = [], diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs index 54624a617c3..d600a51fa05 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs @@ -33,15 +33,15 @@ md5Check proxy md5Int = structureHash proxy @?= md5FromInteger md5Int md5CheckGenericPackageDescription :: Proxy GenericPackageDescription -> Assertion md5CheckGenericPackageDescription proxy = md5Check proxy #if MIN_VERSION_base(4,19,0) - 0x44f8430d7366cf849e09669627573040 + 0xe28f08e7ac644f836d8b3fe7f9428dcf #else - 0x8ed837568017bde3abb4fcee244b9c9f + 0x3442058190aa48c2f795b83ee995f702 #endif md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion md5CheckLocalBuildInfo proxy = md5Check proxy #if MIN_VERSION_base(4,19,0) - 0xdff58fe5e7f9568c67cd982eaba7edc2 + 0x31b94dc3e61eb01fea1a1c3c73d984ee #else - 0x4e50a4a95779b862edde3d6696797251 + 0xdc2f5e7a9c696a4e0bd64f02a0140b74 #endif diff --git a/Cabal/Cabal.cabal b/Cabal/Cabal.cabal index e6a978234c2..deaad72cef1 100644 --- a/Cabal/Cabal.cabal +++ b/Cabal/Cabal.cabal @@ -101,6 +101,7 @@ library Distribution.Simple.BuildPaths Distribution.Simple.BuildTarget Distribution.Simple.BuildToolDepends + Distribution.Simple.BuildWay Distribution.Simple.CCompiler Distribution.Simple.Command Distribution.Simple.Compiler diff --git a/Cabal/src/Distribution/Simple/BuildPaths.hs b/Cabal/src/Distribution/Simple/BuildPaths.hs index 4c44bd380f2..05a9c6c190f 100644 --- a/Cabal/src/Distribution/Simple/BuildPaths.hs +++ b/Cabal/src/Distribution/Simple/BuildPaths.hs @@ -32,6 +32,7 @@ module Distribution.Simple.BuildPaths , mkProfLibName , mkGenericSharedLibName , mkSharedLibName + , mkProfSharedLibName , mkStaticLibName , mkGenericSharedBundledLibName , exeExtension @@ -283,6 +284,10 @@ mkSharedLibName :: Platform -> CompilerId -> UnitId -> String mkSharedLibName platform comp lib = mkGenericSharedLibName platform comp (getHSLibraryName lib) +mkProfSharedLibName :: Platform -> CompilerId -> UnitId -> String +mkProfSharedLibName platform comp lib = + mkGenericSharedLibName platform comp (getHSLibraryName lib ++ "_p") + -- Static libs are named the same as shared libraries, only with -- a different extension. mkStaticLibName :: Platform -> CompilerId -> UnitId -> String diff --git a/Cabal/src/Distribution/Simple/BuildWay.hs b/Cabal/src/Distribution/Simple/BuildWay.hs new file mode 100644 index 00000000000..614c229d462 --- /dev/null +++ b/Cabal/src/Distribution/Simple/BuildWay.hs @@ -0,0 +1,14 @@ +{-# LANGUAGE LambdaCase #-} + +module Distribution.Simple.BuildWay where + +data BuildWay = StaticWay | DynWay | ProfWay | ProfDynWay + deriving (Eq, Ord, Show, Read, Enum) + +-- | Returns the object/interface extension prefix for the given build way (e.g. "dyn_" for 'DynWay') +buildWayPrefix :: BuildWay -> String +buildWayPrefix = \case + StaticWay -> "" + ProfWay -> "p_" + DynWay -> "dyn_" + ProfDynWay -> "p_dyn_" diff --git a/Cabal/src/Distribution/Simple/Compiler.hs b/Cabal/src/Distribution/Simple/Compiler.hs index ae8d1c05136..7b9f2ac8059 100644 --- a/Cabal/src/Distribution/Simple/Compiler.hs +++ b/Cabal/src/Distribution/Simple/Compiler.hs @@ -63,6 +63,11 @@ module Distribution.Simple.Compiler , unitIdSupported , coverageSupported , profilingSupported + , profilingDynamicSupported + , profilingDynamicSupportedOrUnknown + , profilingVanillaSupported + , profilingVanillaSupportedOrUnknown + , dynamicSupported , backpackSupported , arResponseFilesSupported , arDashLSupported @@ -428,6 +433,49 @@ profilingSupported comp = GHCJS -> True _ -> False +-- | Returns Just if we can certainly determine whether a way is supported +-- if we don't know, return Nothing +waySupported :: String -> Compiler -> Maybe Bool +waySupported way comp = + case compilerFlavor comp of + GHC -> + -- Infomation about compiler ways is only accurately reported after + -- 9.10.1. Which is useful as this is before profiling dynamic support + -- was introduced. (See GHC #24881) + if compilerVersion comp >= mkVersion [9, 10, 1] + then case Map.lookup "RTS ways" (compilerProperties comp) of + Just ways -> Just (way `elem` words ways) + Nothing -> Just False + else Nothing + _ -> Nothing + +-- | Either profiling is definitely supported or we don't know (so assume +-- it is) +profilingVanillaSupportedOrUnknown :: Compiler -> Bool +profilingVanillaSupportedOrUnknown comp = profilingVanillaSupported comp `elem` [Just True, Nothing] + +-- | Is the compiler distributed with profiling libraries +profilingVanillaSupported :: Compiler -> Maybe Bool +profilingVanillaSupported comp = waySupported "p" comp + +-- | Is the compiler distributed with profiling dynamic libraries +profilingDynamicSupported :: Compiler -> Maybe Bool +profilingDynamicSupported comp = + -- Certainly not before this version, as it was not implemented yet. + if compilerVersion comp <= mkVersion [9, 11, 0] + then Just False + else waySupported "p_dyn" comp + +-- | Either profiling dynamic is definitely supported or we don't know (so assume +-- it is) +profilingDynamicSupportedOrUnknown :: Compiler -> Bool +profilingDynamicSupportedOrUnknown comp = + profilingDynamicSupported comp `elem` [Just True, Nothing] + +-- | Is the compiler distributed with dynamic libraries +dynamicSupported :: Compiler -> Maybe Bool +dynamicSupported comp = waySupported "dyn" comp + -- | Does this compiler support a package database entry with: -- "visibility"? libraryVisibilitySupported :: Compiler -> Bool diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index 8d90b0d8822..aa0e2a3a438 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -81,6 +81,7 @@ import Distribution.PackageDescription.Configuration import Distribution.PackageDescription.PrettyPrint import Distribution.Simple.BuildTarget import Distribution.Simple.BuildToolDepends +import Distribution.Simple.BuildWay import Distribution.Simple.Compiler import Distribution.Simple.LocalBuildInfo import Distribution.Simple.PackageIndex (InstalledPackageIndex, lookupUnitId) @@ -709,7 +710,7 @@ computeLocalBuildConfig cfg comp programDb = do -- rely on them. By the time that bug was fixed, ghci had -- been changed to read shared libraries instead of archive -- files (see next code block). - not (GHC.isDynamic comp) + not (GHC.compilerBuildWay comp `elem` [DynWay, ProfDynWay]) CompilerId GHCJS _ -> not (GHCJS.isDynamic comp) _ -> False @@ -734,7 +735,7 @@ computeLocalBuildConfig cfg comp programDb = do CompilerId GHC _ -> -- if ghc is dynamic, then ghci needs a shared -- library, so we build one by default. - GHC.isDynamic comp + GHC.compilerBuildWay comp == DynWay CompilerId GHCJS _ -> GHCJS.isDynamic comp _ -> False @@ -754,12 +755,6 @@ computeLocalBuildConfig cfg comp programDb = do withFullyStaticExe_ = fromFlag $ configFullyStaticExe cfg - when (withDynExe_ && not withSharedLib_) $ - warn verbosity $ - "Executables will use dynamic linking, but a shared library " - ++ "is not being built. Linking will fail if any executables " - ++ "depend on the library." - setProfiling <- configureProfiling verbosity cfg comp setCoverage <- configureCoverage verbosity cfg comp @@ -792,6 +787,7 @@ computeLocalBuildConfig cfg comp programDb = do , withDynExe = withDynExe_ , withFullyStaticExe = withFullyStaticExe_ , withProfLib = False + , withProfLibShared = False , withProfLibDetail = ProfDetailNone , withProfExe = False , withProfExeDetail = ProfDetailNone @@ -807,6 +803,20 @@ computeLocalBuildConfig cfg comp programDb = do , relocatable = fromFlagOrDefault False $ configRelocatable cfg } + -- Dynamic executable, but no shared vanilla libraries + when (LBC.withDynExe buildOptions && not (LBC.withProfExe buildOptions) && not (LBC.withSharedLib buildOptions)) $ + warn verbosity $ + "Executables will use dynamic linking, but a shared library " + ++ "is not being built. Linking will fail if any executables " + ++ "depend on the library." + + -- Profiled dynamic executable, but no shared profiling libraries + when (LBC.withDynExe buildOptions && LBC.withProfExe buildOptions && not (LBC.withProfLibShared buildOptions)) $ + warn verbosity $ + "Executables will use profiled dynamic linking, but a profiled shared library " + ++ "is not being built. Linking will fail if any executables " + ++ "depend on the library." + return $ LBC.LocalBuildConfig { extraConfigArgs = [] -- Currently configure does not @@ -1732,7 +1742,7 @@ configureCoverage verbosity cfg comp = do -- -- Note that @--enable-executable-profiling@ also affects profiling -- of benchmarks and (non-detailed) test suites. -computeEffectiveProfiling :: ConfigFlags -> (Bool {- lib -}, Bool {- exe -}) +computeEffectiveProfiling :: ConfigFlags -> (Bool {- lib vanilla-}, Bool {- lib shared -}, Bool {- exe -}) computeEffectiveProfiling cfg = -- The --profiling flag sets the default for both libs and exes, -- but can be overridden by --library-profiling, or the old deprecated @@ -1740,15 +1750,20 @@ computeEffectiveProfiling cfg = -- -- The --profiling-detail and --library-profiling-detail flags behave -- similarly - let tryExeProfiling = + let dynamicExe = fromFlagOrDefault False (configDynExe cfg) + tryExeProfiling = fromFlagOrDefault False (mappend (configProf cfg) (configProfExe cfg)) tryLibProfiling = fromFlagOrDefault - tryExeProfiling - (mappend (configProf cfg) (configProfLib cfg)) - in (tryLibProfiling, tryExeProfiling) + (tryExeProfiling && not dynamicExe) + (configProfLib cfg) + tryLibProfilingShared = + fromFlagOrDefault + (tryExeProfiling && dynamicExe) + (configProfShared cfg) + in (tryLibProfiling, tryLibProfilingShared, tryExeProfiling) -- | Select and apply profiling settings for the build based on the -- 'ConfigFlags' and 'Compiler'. @@ -1758,7 +1773,7 @@ configureProfiling -> Compiler -> IO (LBC.BuildOptions -> LBC.BuildOptions) configureProfiling verbosity cfg comp = do - let (tryLibProfiling, tryExeProfiling) = computeEffectiveProfiling cfg + let (tryLibProfiling, tryLibProfilingShared, tryExeProfiling) = computeEffectiveProfiling cfg tryExeProfileLevel = fromFlagOrDefault @@ -1785,8 +1800,8 @@ configureProfiling verbosity cfg comp = do return ProfDetailDefault checkProfileLevel other = return other - (exeProfWithoutLibProf, applyProfiling) <- - if profilingSupported comp + applyProfiling <- + if profilingSupported comp && (profilingVanillaSupportedOrUnknown comp || profilingDynamicSupportedOrUnknown comp) then do exeLevel <- checkProfileLevel tryExeProfileLevel libLevel <- checkProfileLevel tryLibProfileLevel @@ -1797,11 +1812,46 @@ configureProfiling verbosity cfg comp = do , LBC.withProfExe = tryExeProfiling , LBC.withProfExeDetail = exeLevel } - return (tryExeProfiling && not tryLibProfiling, apply) + let compilerSupportsProfilingDynamic = profilingDynamicSupportedOrUnknown comp + apply2 <- + if compilerSupportsProfilingDynamic + then -- Case 1: We support profiled shared libraries so turn on shared profiling + -- libraries if the user asked for it. + return $ \buildOptions -> apply buildOptions{LBC.withProfLibShared = tryLibProfilingShared} + else -- Case 2: Compiler doesn't support profiling shared so turn them off + do + -- If we wanted to enable profiling shared libraries.. tell the + -- user we couldn't. + when (profilingVanillaSupportedOrUnknown comp && tryLibProfilingShared) $ + warn + verbosity + ( "The compiler " + ++ showCompilerId comp + ++ " does not support " + ++ "profiling shared objects. Static profiled objects " + ++ "will be built." + ) + return $ \buildOptions -> + let original_options = apply buildOptions + in original_options + { LBC.withProfLibShared = False + , LBC.withProfLib = profilingVanillaSupportedOrUnknown comp && (tryLibProfilingShared || LBC.withProfLib original_options) + , LBC.withDynExe = if LBC.withProfExe original_options then False else LBC.withDynExe original_options + } + + when (tryExeProfiling && not (tryLibProfiling || tryLibProfilingShared)) $ do + warn + verbosity + ( "Executables will be built with profiling, but library " + ++ "profiling is disabled. Linking will fail if any executables " + ++ "depend on the library." + ) + return apply2 else do let apply buildOptions = buildOptions { LBC.withProfLib = False + , LBC.withProfLibShared = False , LBC.withProfLibDetail = ProfDetailNone , LBC.withProfExe = False , LBC.withProfExeDetail = ProfDetailNone @@ -1814,15 +1864,7 @@ configureProfiling verbosity cfg comp = do ++ " does not support " ++ "profiling. Profiling has been disabled." ) - return (False, apply) - - when exeProfWithoutLibProf $ - warn - verbosity - ( "Executables will be built with profiling, but library " - ++ "profiling is disabled. Linking will fail if any executables " - ++ "depend on the library." - ) + return apply return applyProfiling diff --git a/Cabal/src/Distribution/Simple/GHC.hs b/Cabal/src/Distribution/Simple/GHC.hs index 095e657264e..8d7dda4de34 100644 --- a/Cabal/src/Distribution/Simple/GHC.hs +++ b/Cabal/src/Distribution/Simple/GHC.hs @@ -61,7 +61,7 @@ module Distribution.Simple.GHC , Internal.componentCcGhcOptions , getGhcAppDir , getLibDir - , isDynamic + , compilerBuildWay , getGlobalPackageDB , pkgRoot @@ -98,6 +98,7 @@ import Distribution.Simple.BuildPaths import Distribution.Simple.Compiler import Distribution.Simple.Errors import qualified Distribution.Simple.GHC.Build as GHC +import Distribution.Simple.GHC.Build.Modules (BuildWay (..)) import Distribution.Simple.GHC.Build.Utils import Distribution.Simple.GHC.EnvironmentParser import Distribution.Simple.GHC.ImplInfo @@ -747,11 +748,28 @@ libAbiHash verbosity _pkg_descr lbi lib clbi = do , ghcOptObjSuffix = toFlag "p_o" , ghcOptExtra = hcProfOptions GHC libBi } - ghcArgs - | withVanillaLib lbi = vanillaArgs - | withSharedLib lbi = sharedArgs - | withProfLib lbi = profArgs - | otherwise = error "libAbiHash: Can't find an enabled library way" + profDynArgs = + vanillaArgs + `mappend` mempty + { ghcOptProfilingMode = toFlag True + , ghcOptProfilingAuto = + Internal.profDetailLevelFlag + True + (withProfLibDetail lbi) + , ghcOptDynLinkMode = toFlag GhcDynamicOnly + , ghcOptFPic = toFlag True + , ghcOptHiSuffix = toFlag "p_dyn_hi" + , ghcOptObjSuffix = toFlag "p_dyn_o" + , ghcOptExtra = hcProfSharedOptions GHC libBi + } + ghcArgs = + let (libWays, _, _) = buildWays lbi + in case libWays (componentIsIndefinite clbi) of + (ProfDynWay : _) -> profDynArgs + (ProfWay : _) -> profArgs + (StaticWay : _) -> vanillaArgs + (DynWay : _) -> sharedArgs + _ -> error "libAbiHash: Can't find an enabled library way" (ghcProg, _) <- requireProgram verbosity ghcProgram (withPrograms lbi) @@ -870,75 +888,90 @@ installLib -> ComponentLocalBuildInfo -> IO () installLib verbosity lbi targetDir dynlibTargetDir _builtDir pkg lib clbi = do + let + (wantedLibWays, _, _) = buildWays lbi + isIndef = componentIsIndefinite clbi + libWays = wantedLibWays isIndef + + info verbosity ("Wanted install ways: " ++ show libWays) + -- copy .hi files over: - whenVanilla $ copyModuleFiles $ Suffix "hi" - whenProf $ copyModuleFiles $ Suffix "p_hi" - whenShared $ copyModuleFiles $ Suffix "dyn_hi" + forM_ (wantedLibWays isIndef) $ \w -> case w of + StaticWay -> copyModuleFiles (Suffix "hi") + DynWay -> copyModuleFiles (Suffix "dyn_hi") + ProfWay -> copyModuleFiles (Suffix "p_hi") + ProfDynWay -> copyModuleFiles (Suffix "p_dyn_hi") -- copy extra compilation artifacts that ghc plugins may produce copyDirectoryIfExists extraCompilationArtifacts -- copy the built library files over: - whenHasCode $ do - whenVanilla $ do - sequence_ - [ installOrdinary + when (has_code && hasLib) $ do + forM_ libWays $ \w -> case w of + StaticWay -> do + sequence_ + [ installOrdinary + builtDir + targetDir + (mkGenericStaticLibName (l ++ f)) + | l <- + getHSLibraryName + (componentUnitId clbi) + : (extraBundledLibs (libBuildInfo lib)) + , f <- "" : extraLibFlavours (libBuildInfo lib) + ] + whenGHCi $ installOrdinary builtDir targetDir ghciLibName + ProfWay -> do + installOrdinary builtDir targetDir profileLibName + whenGHCi $ installOrdinary builtDir targetDir ghciProfLibName + ProfDynWay -> do + installShared builtDir - targetDir - (mkGenericStaticLibName (l ++ f)) - | l <- - getHSLibraryName - (componentUnitId clbi) - : (extraBundledLibs (libBuildInfo lib)) - , f <- "" : extraLibFlavours (libBuildInfo lib) - ] - whenGHCi $ installOrdinary builtDir targetDir ghciLibName - whenProf $ do - installOrdinary builtDir targetDir profileLibName - whenGHCi $ installOrdinary builtDir targetDir ghciProfLibName - whenShared $ - if - -- The behavior for "extra-bundled-libraries" changed in version 2.5.0. - -- See ghc issue #15837 and Cabal PR #5855. - | specVersion pkg < CabalSpecV3_0 -> do - sequence_ - [ installShared - builtDir - dynlibTargetDir - (mkGenericSharedLibName platform compiler_id (l ++ f)) - | l <- getHSLibraryName uid : extraBundledLibs (libBuildInfo lib) - , f <- "" : extraDynLibFlavours (libBuildInfo lib) - ] - | otherwise -> do - sequence_ - [ installShared - builtDir - dynlibTargetDir - ( mkGenericSharedLibName - platform - compiler_id - (getHSLibraryName uid ++ f) - ) - | f <- "" : extraDynLibFlavours (libBuildInfo lib) - ] - sequence_ - [ do - files <- getDirectoryContents (i builtDir) - let l' = - mkGenericSharedBundledLibName - platform - compiler_id - l - forM_ files $ \file -> - when (l' `isPrefixOf` file) $ do - isFile <- doesFileExist (i $ builtDir makeRelativePathEx file) - when isFile $ do - installShared - builtDir - dynlibTargetDir - file - | l <- extraBundledLibs (libBuildInfo lib) - ] + dynlibTargetDir + (mkProfSharedLibName platform compiler_id uid) + DynWay -> do + if + -- The behavior for "extra-bundled-libraries" changed in version 2.5.0. + -- See ghc issue #15837 and Cabal PR #5855. + | specVersion pkg < CabalSpecV3_0 -> do + sequence_ + [ installShared + builtDir + dynlibTargetDir + (mkGenericSharedLibName platform compiler_id (l ++ f)) + | l <- getHSLibraryName uid : extraBundledLibs (libBuildInfo lib) + , f <- "" : extraDynLibFlavours (libBuildInfo lib) + ] + | otherwise -> do + sequence_ + [ installShared + builtDir + dynlibTargetDir + ( mkGenericSharedLibName + platform + compiler_id + (getHSLibraryName uid ++ f) + ) + | f <- "" : extraDynLibFlavours (libBuildInfo lib) + ] + sequence_ + [ do + files <- getDirectoryContents (i builtDir) + let l' = + mkGenericSharedBundledLibName + platform + compiler_id + l + forM_ files $ \file -> + when (l' `isPrefixOf` file) $ do + isFile <- doesFileExist (i $ builtDir makeRelativePathEx file) + when isFile $ do + installShared + builtDir + dynlibTargetDir + file + | l <- extraBundledLibs (libBuildInfo lib) + ] where -- See Note [Symbolic paths] in Distribution.Utils.Path i = interpretSymbolicPathLBI lbi @@ -997,11 +1030,7 @@ installLib verbosity lbi targetDir dynlibTargetDir _builtDir pkg lib clbi = do Platform JavaScript _ -> True _ -> False has_code = not (componentIsIndefinite clbi) - whenHasCode = when has_code - whenVanilla = when (hasLib && withVanillaLib lbi) - whenProf = when (hasLib && withProfLib lbi && has_code) whenGHCi = when (hasLib && withGHCiLib lbi && has_code) - whenShared = when (hasLib && withSharedLib lbi && has_code) -- ----------------------------------------------------------------------------- -- Registering diff --git a/Cabal/src/Distribution/Simple/GHC/Build.hs b/Cabal/src/Distribution/Simple/GHC/Build.hs index 51f7d650338..1f88f07552b 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build.hs @@ -6,19 +6,17 @@ import Distribution.Compat.Prelude import Prelude () import Control.Monad.IO.Class -import qualified Data.Set as Set import Distribution.PackageDescription as PD hiding (buildInfo) import Distribution.Simple.Build.Inputs import Distribution.Simple.Flag (Flag) import Distribution.Simple.GHC.Build.ExtraSources import Distribution.Simple.GHC.Build.Link import Distribution.Simple.GHC.Build.Modules -import Distribution.Simple.GHC.Build.Utils (withDynFLib) import Distribution.Simple.LocalBuildInfo import Distribution.Simple.Program.Builtin (ghcProgram) import Distribution.Simple.Program.Db (requireProgram) import Distribution.Simple.Utils -import Distribution.Types.ComponentLocalBuildInfo (componentIsIndefinite) +import Distribution.Types.ComponentLocalBuildInfo import Distribution.Types.ParStrat import Distribution.Utils.NubList (fromNubListR) import Distribution.Utils.Path @@ -70,10 +68,10 @@ build build numJobs pkg_descr pbci = do let verbosity = buildVerbosity pbci - component = buildComponent pbci isLib = buildIsLib pbci lbi = localBuildInfo pbci clbi = buildCLBI pbci + isIndef = componentIsIndefinite clbi mbWorkDir = mbWorkDirLBI lbi i = interpretSymbolicPathLBI lbi -- See Note [Symbolic paths] in Distribution.Utils.Path @@ -110,41 +108,14 @@ build numJobs pkg_descr pbci = do (ghcProg, _) <- liftIO $ requireProgram verbosity ghcProgram (withPrograms lbi) - -- Determine in which ways we want to build the component - let - wantVanilla = if isLib then withVanillaLib lbi else False - -- Arguably, wantStatic should be "withFullyStaticExe lbi" for executables, - -- but it was not before the refactor. - wantStatic = if isLib then withStaticLib lbi else not (wantDynamic || wantProf) - wantDynamic = case component of - CLib{} -> withSharedLib lbi - CFLib flib -> withDynFLib flib - CExe{} -> withDynExe lbi - CTest{} -> withDynExe lbi - CBench{} -> withDynExe lbi - wantProf = if isLib then withProfLib lbi else withProfExe lbi - - -- See also Note [Building Haskell Modules accounting for TH] in Distribution.Simple.GHC.Build.Modules - -- We build static by default if no other way is wanted. - -- For executables and foreign libraries, there should only be one wanted way. - wantedWays = - Set.fromList $ - -- If building a library, we accumulate all the ways, - -- otherwise, we take just one. - (if isLib then id else take 1) $ - [ProfWay | wantProf] - -- I don't see why we shouldn't build with dynamic - -- indefinite components. - <> [DynWay | wantDynamic && not (componentIsIndefinite clbi)] - <> [StaticWay | wantStatic || wantVanilla || not (wantDynamic || wantProf)] - - liftIO $ info verbosity ("Wanted build ways: " ++ show (Set.toList wantedWays)) + let wantedWays@(wantedLibWays, _, wantedExeWay) = buildWays lbi + liftIO $ info verbosity ("Wanted build ways(" ++ show isLib ++ "): " ++ show (if isLib then wantedLibWays isIndef else [wantedExeWay])) -- We need a separate build and link phase, and C sources must be compiled -- after Haskell modules, because C sources may depend on stub headers -- generated from compiling Haskell modules (#842, #3294). - buildOpts <- buildHaskellModules numJobs ghcProg pkg_descr buildTargetDir wantedWays pbci - extraSources <- buildAllExtraSources ghcProg buildTargetDir pbci + buildOpts <- buildHaskellModules numJobs ghcProg pkg_descr buildTargetDir (wantedLibWays isIndef) pbci + extraSources <- buildAllExtraSources ghcProg buildTargetDir wantedWays pbci linkOrLoadComponent ghcProg pkg_descr diff --git a/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs b/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs index fc204cda30a..83bcf9a6bca 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs @@ -19,6 +19,7 @@ import Distribution.Types.Component import Distribution.Types.TargetInfo import Distribution.Simple.Build.Inputs +import Distribution.Simple.GHC.Build.Modules import Distribution.Simple.GHC.Build.Utils import Distribution.Simple.LocalBuildInfo import Distribution.Simple.Program.Types @@ -35,6 +36,8 @@ buildAllExtraSources -- ^ The GHC configured program -> SymbolicPath Pkg (Dir Artifacts) -- ^ The build directory for this target + -> (Bool -> [BuildWay], Bool -> BuildWay, BuildWay) + -- ^ Needed build ways -> PreBuildComponentInputs -- ^ The context and component being built in it. -> IO (NubListR (SymbolicPath Pkg File)) @@ -57,6 +60,8 @@ buildCSources -- ^ The GHC configured program -> SymbolicPath Pkg (Dir Artifacts) -- ^ The build directory for this target + -> (Bool -> [BuildWay], Bool -> BuildWay, BuildWay) + -- ^ Needed build ways -> PreBuildComponentInputs -- ^ The context and component being built in it. -> IO (NubListR (SymbolicPath Pkg File)) @@ -65,7 +70,6 @@ buildCSources = buildExtraSources "C Sources" Internal.componentCcGhcOptions - True ( \c -> do let cFiles = cSources (componentBuildInfo c) case c of @@ -81,7 +85,6 @@ buildCxxSources = buildExtraSources "C++ Sources" Internal.componentCxxGhcOptions - True ( \c -> do let cxxFiles = cxxSources (componentBuildInfo c) case c of @@ -93,13 +96,12 @@ buildCxxSources = -- is relative to the package. _otherwise -> cxxFiles ) -buildJsSources ghcProg buildTargetDir = do +buildJsSources ghcProg buildTargetDir neededWays = do Platform hostArch _ <- hostPlatform <$> localBuildInfo let hasJsSupport = hostArch == JavaScript buildExtraSources "JS Sources" Internal.componentJsGhcOptions - False ( \c -> if hasJsSupport then -- JS files are C-like with GHC's JS backend: they are @@ -111,17 +113,16 @@ buildJsSources ghcProg buildTargetDir = do ) ghcProg buildTargetDir + neededWays buildAsmSources = buildExtraSources "Assembler Sources" Internal.componentAsmGhcOptions - True (asmSources . componentBuildInfo) buildCmmSources = buildExtraSources "C-- Sources" Internal.componentCmmGhcOptions - True (cmmSources . componentBuildInfo) -- | Create 'PreBuildComponentRules' for a given type of extra build sources @@ -142,10 +143,6 @@ buildExtraSources -- invocation of GHC when compiling these extra sources (e.g. -- @'Internal.componentCxxGhcOptions'@, -- @'Internal.componentCmmGhcOptions'@) - -> Bool - -- ^ Some types of build sources should not be built in the dynamic way, namely, JS sources. - -- I'm not entirely sure this remains true after we migrate to supporting GHC's JS backend rather than GHCJS. - -- Boolean for "do we allow building these sources the dynamic way?" -> (Component -> [SymbolicPath Pkg File]) -- ^ View the extra sources of a component, typically from -- the build info (e.g. @'asmSources'@, @'cSources'@). @@ -156,108 +153,109 @@ buildExtraSources -- ^ The GHC configured program -> SymbolicPath Pkg (Dir Artifacts) -- ^ The build directory for this target + -> (Bool -> [BuildWay], Bool -> BuildWay, BuildWay) + -- ^ Needed build ways -> PreBuildComponentInputs -- ^ The context and component being built in it. -> IO (NubListR (SymbolicPath Pkg File)) -- ^ Returns the list of extra sources that were built -buildExtraSources description componentSourceGhcOptions wantDyn viewSources ghcProg buildTargetDir = - \PreBuildComponentInputs{buildingWhat, localBuildInfo = lbi, targetInfo} -> do - let - bi = componentBuildInfo (targetComponent targetInfo) - verbosity = buildingWhatVerbosity buildingWhat - clbi = targetCLBI targetInfo - mbWorkDir = mbWorkDirLBI lbi - i = interpretSymbolicPath mbWorkDir - sources = viewSources (targetComponent targetInfo) - comp = compiler lbi - platform = hostPlatform lbi - -- Instead of keeping this logic here, we really just want to - -- receive as an input the `neededWays` from GHC/Build.build and build - -- accordingly, since we've already determined the extra needed ways - -- needed for e.g. template haskell. Although we'd have to account for 'wantDyn'. - isGhcDynamic = isDynamic comp - doingTH = usesTemplateHaskellOrQQ bi - forceSharedLib = doingTH && isGhcDynamic - runGhcProg = runGHC verbosity ghcProg comp platform +buildExtraSources + description + componentSourceGhcOptions + viewSources + ghcProg + buildTargetDir + (neededLibWays, neededFLibWay, neededExeWay) = + \PreBuildComponentInputs{buildingWhat, localBuildInfo = lbi, targetInfo} -> do + let + bi = componentBuildInfo (targetComponent targetInfo) + verbosity = buildingWhatVerbosity buildingWhat + clbi = targetCLBI targetInfo + isIndef = componentIsIndefinite clbi + mbWorkDir = mbWorkDirLBI lbi + i = interpretSymbolicPath mbWorkDir + sources = viewSources (targetComponent targetInfo) + comp = compiler lbi + platform = hostPlatform lbi + runGhcProg = runGHC verbosity ghcProg comp platform - buildAction :: SymbolicPath Pkg File -> IO () - buildAction sourceFile = do - let baseSrcOpts = - componentSourceGhcOptions - verbosity - lbi - bi - clbi - buildTargetDir - sourceFile - vanillaSrcOpts - -- Dynamic GHC requires C sources to be built - -- with -fPIC for REPL to work. See #2207. - | isGhcDynamic && wantDyn = baseSrcOpts{ghcOptFPic = toFlag True} - | otherwise = baseSrcOpts - profSrcOpts = - vanillaSrcOpts - `mappend` mempty - { ghcOptProfilingMode = toFlag True - } - sharedSrcOpts = - vanillaSrcOpts - `mappend` mempty - { ghcOptFPic = toFlag True - , ghcOptDynLinkMode = toFlag GhcDynamicOnly - } - -- TODO: Placing all Haskell, C, & C++ objects in a single directory - -- Has the potential for file collisions. In general we would - -- consider this a user error. However, we should strive to - -- add a warning if this occurs. - odir = fromFlag (ghcOptObjDir vanillaSrcOpts) + buildAction :: SymbolicPath Pkg File -> IO () + buildAction sourceFile = do + let baseSrcOpts = + componentSourceGhcOptions + verbosity + lbi + bi + clbi + buildTargetDir + sourceFile + vanillaSrcOpts = + -- -fPIC is used in case you are using the repl + -- of a dynamically linked GHC + baseSrcOpts{ghcOptFPic = toFlag True} + profSrcOpts = + vanillaSrcOpts + `mappend` mempty + { ghcOptProfilingMode = toFlag True + } + sharedSrcOpts = + vanillaSrcOpts + `mappend` mempty + { ghcOptFPic = toFlag True + , ghcOptDynLinkMode = toFlag GhcDynamicOnly + } + profSharedSrcOpts = + vanillaSrcOpts + `mappend` mempty + { ghcOptProfilingMode = toFlag True + , ghcOptFPic = toFlag True + , ghcOptDynLinkMode = toFlag GhcDynamicOnly + } + -- TODO: Placing all Haskell, C, & C++ objects in a single directory + -- Has the potential for file collisions. In general we would + -- consider this a user error. However, we should strive to + -- add a warning if this occurs. + odir = fromFlag (ghcOptObjDir vanillaSrcOpts) - compileIfNeeded :: GhcOptions -> IO () - compileIfNeeded opts = do - needsRecomp <- checkNeedsRecompilation mbWorkDir sourceFile opts - when needsRecomp $ runGhcProg mbWorkDir opts + compileIfNeeded :: GhcOptions -> IO () + compileIfNeeded opts = do + needsRecomp <- checkNeedsRecompilation mbWorkDir sourceFile opts + when needsRecomp $ runGhcProg mbWorkDir opts - -- TODO: This whole section can be streamlined to the - -- wantedWays+neededWays logic used in Build/Modules.hs - createDirectoryIfMissingVerbose verbosity True (i odir) - case targetComponent targetInfo of - -- For libraries, we compile extra objects in the three ways: vanilla, shared, and profiled. - -- We suffix shared objects with .dyn_o and profiled ones with .p_o. - CLib _lib - -- Unless for repl, in which case we only need the vanilla way - | BuildRepl _ <- buildingWhat -> - compileIfNeeded vanillaSrcOpts - | otherwise -> - do + createDirectoryIfMissingVerbose verbosity True (i odir) + case targetComponent targetInfo of + -- For libraries, we compile extra objects in the four ways: vanilla, shared, profiled and profiled shared. + -- We suffix shared objects with `.dyn_o`, profiled ones with `.p_o` and profiled shared ones with `.p_dyn_o`. + CLib _lib + -- Unless for repl, in which case we only need the vanilla way + | BuildRepl _ <- buildingWhat -> compileIfNeeded vanillaSrcOpts - when (wantDyn && (forceSharedLib || withSharedLib lbi)) $ - compileIfNeeded sharedSrcOpts{ghcOptObjSuffix = toFlag "dyn_o"} - when (withProfLib lbi) $ - compileIfNeeded profSrcOpts{ghcOptObjSuffix = toFlag "p_o"} - - -- For foreign libraries, we determine with which options to build the - -- objects (vanilla vs shared vs profiled) - CFLib flib - | withProfExe lbi -> -- It doesn't sound right to query "ProfExe" for a foreign library... - compileIfNeeded profSrcOpts - | withDynFLib flib && wantDyn -> - compileIfNeeded sharedSrcOpts - | otherwise -> - compileIfNeeded vanillaSrcOpts - -- For the remaining component types (Exec, Test, Bench), we also - -- determine with which options to build the objects (vanilla vs shared vs - -- profiled), but predicate is the same for the three kinds. - _exeLike - | withProfExe lbi -> - compileIfNeeded profSrcOpts - | withDynExe lbi && wantDyn -> - compileIfNeeded sharedSrcOpts - | otherwise -> - compileIfNeeded vanillaSrcOpts - -- build any sources - if (null sources || componentIsIndefinite clbi) - then return mempty - else do - info verbosity ("Building " ++ description ++ "...") - traverse_ buildAction sources - return (toNubListR sources) + | otherwise -> + do + forM_ (neededLibWays isIndef) $ \case + StaticWay -> compileIfNeeded vanillaSrcOpts + DynWay -> compileIfNeeded sharedSrcOpts{ghcOptObjSuffix = toFlag "dyn_o"} + ProfWay -> compileIfNeeded profSrcOpts{ghcOptObjSuffix = toFlag "p_o"} + ProfDynWay -> compileIfNeeded profSharedSrcOpts{ghcOptObjSuffix = toFlag "p_dyn_o"} + CFLib flib -> + case neededFLibWay (withDynFLib flib) of + StaticWay -> compileIfNeeded vanillaSrcOpts + DynWay -> compileIfNeeded sharedSrcOpts + ProfWay -> compileIfNeeded profSrcOpts + ProfDynWay -> compileIfNeeded profSharedSrcOpts + -- For the remaining component types (Exec, Test, Bench), we also + -- determine with which options to build the objects (vanilla vs shared vs + -- profiled), but predicate is the same for the three kinds. + _exeLike -> + case neededExeWay of + StaticWay -> compileIfNeeded vanillaSrcOpts + DynWay -> compileIfNeeded sharedSrcOpts + ProfWay -> compileIfNeeded profSrcOpts + ProfDynWay -> compileIfNeeded profSharedSrcOpts + -- build any sources + if (null sources || componentIsIndefinite clbi) + then return mempty + else do + info verbosity ("Building " ++ description ++ "...") + traverse_ buildAction sources + return (toNubListR sources) diff --git a/Cabal/src/Distribution/Simple/GHC/Build/Link.hs b/Cabal/src/Distribution/Simple/GHC/Build/Link.hs index ee0f21ffa6d..3f9f00c9d28 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build/Link.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build/Link.hs @@ -8,8 +8,6 @@ module Distribution.Simple.GHC.Build.Link where import Distribution.Compat.Prelude import Prelude () -import Control.Exception (assert) -import Control.Monad (forM_) import Control.Monad.IO.Class import qualified Data.ByteString.Lazy.Char8 as BS import qualified Data.Set as Set @@ -76,128 +74,148 @@ linkOrLoadComponent -> (SymbolicPath Pkg (Dir Artifacts), SymbolicPath Pkg (Dir Build)) -- ^ The build target dir, and the target dir. -- See Note [Build Target Dir vs Target Dir] in Distribution.Simple.GHC.Build - -> (Set.Set BuildWay, BuildWay -> GhcOptions) + -> ((Bool -> [BuildWay], Bool -> BuildWay, BuildWay), BuildWay -> GhcOptions) -- ^ The set of build ways wanted based on the user opts, and a function to -- convert a build way into the set of ghc options that were used to build -- that way. -> PreBuildComponentInputs -- ^ The context and component being built in it. -> IO () -linkOrLoadComponent ghcProg pkg_descr extraSources (buildTargetDir, targetDir) (wantedWays, buildOpts) pbci = do - let - verbosity = buildVerbosity pbci - target = targetInfo pbci - component = buildComponent pbci - what = buildingWhat pbci - lbi = localBuildInfo pbci - bi = buildBI pbci - clbi = buildCLBI pbci - mbWorkDir = mbWorkDirLBI lbi +linkOrLoadComponent + ghcProg + pkg_descr + extraSources + (buildTargetDir, targetDir) + ((wantedLibWays, wantedFLibWay, wantedExeWay), buildOpts) + pbci = do + let + verbosity = buildVerbosity pbci + target = targetInfo pbci + component = buildComponent pbci + what = buildingWhat pbci + lbi = localBuildInfo pbci + bi = buildBI pbci + clbi = buildCLBI pbci + isIndef = componentIsIndefinite clbi + mbWorkDir = mbWorkDirLBI lbi - -- See Note [Symbolic paths] in Distribution.Utils.Path - i = interpretSymbolicPathLBI lbi + -- See Note [Symbolic paths] in Distribution.Utils.Path + i = interpretSymbolicPathLBI lbi - -- ensure extra lib dirs exist before passing to ghc - cleanedExtraLibDirs <- liftIO $ filterM (doesDirectoryExist . i) (extraLibDirs bi) - cleanedExtraLibDirsStatic <- liftIO $ filterM (doesDirectoryExist . i) (extraLibDirsStatic bi) + -- ensure extra lib dirs exist before passing to ghc + cleanedExtraLibDirs <- liftIO $ filterM (doesDirectoryExist . i) (extraLibDirs bi) + cleanedExtraLibDirsStatic <- liftIO $ filterM (doesDirectoryExist . i) (extraLibDirsStatic bi) - let - extraSourcesObjs :: [RelativePath Artifacts File] - extraSourcesObjs = - [ makeRelativePathEx $ getSymbolicPath src `replaceExtension` objExtension - | src <- extraSources - ] - - -- TODO: Shouldn't we use withStaticLib for libraries and something else - -- for foreign libs in the three cases where we use `withFullyStaticExe` below? - linkerOpts rpaths = - mempty - { ghcOptLinkOptions = - PD.ldOptions bi - ++ [ "-static" - | withFullyStaticExe lbi - ] - -- Pass extra `ld-options` given - -- through to GHC's linker. - ++ maybe - [] - programOverrideArgs - (lookupProgram ldProgram (withPrograms lbi)) - , ghcOptLinkLibs = - if withFullyStaticExe lbi - then extraLibsStatic bi - else extraLibs bi - , ghcOptLinkLibPath = - toNubListR $ + let + extraSourcesObjs :: [RelativePath Artifacts File] + extraSourcesObjs = + [ makeRelativePathEx $ getSymbolicPath src `replaceExtension` objExtension + | src <- extraSources + ] + + -- TODO: Shouldn't we use withStaticLib for libraries and something else + -- for foreign libs in the three cases where we use `withFullyStaticExe` below? + linkerOpts rpaths = + mempty + { ghcOptLinkOptions = + PD.ldOptions bi + ++ [ "-static" + | withFullyStaticExe lbi + ] + -- Pass extra `ld-options` given + -- through to GHC's linker. + ++ maybe + [] + programOverrideArgs + (lookupProgram ldProgram (withPrograms lbi)) + , ghcOptLinkLibs = if withFullyStaticExe lbi - then cleanedExtraLibDirsStatic - else cleanedExtraLibDirs - , ghcOptLinkFrameworks = toNubListR $ map getSymbolicPath $ PD.frameworks bi - , ghcOptLinkFrameworkDirs = toNubListR $ PD.extraFrameworkDirs bi - , ghcOptInputFiles = - toNubListR - [ coerceSymbolicPath $ buildTargetDir obj - | obj <- extraSourcesObjs - ] - , ghcOptNoLink = Flag False - , ghcOptRPaths = rpaths - } - case what of - BuildRepl replFlags -> liftIO $ do - let - -- For repl we use the vanilla (static) ghc options - staticOpts = buildOpts StaticWay - replOpts = - staticOpts - { -- Repl options use Static as the base, but doesn't need to pass -static. - -- However, it maybe should, for uniformity. - ghcOptDynLinkMode = NoFlag - , ghcOptExtra = - Internal.filterGhciFlags - (ghcOptExtra staticOpts) - <> replOptionsFlags (replReplOptions replFlags) - , ghcOptInputModules = replNoLoad (replReplOptions replFlags) (ghcOptInputModules staticOpts) - , ghcOptInputFiles = replNoLoad (replReplOptions replFlags) (ghcOptInputFiles staticOpts) - } - -- For a normal compile we do separate invocations of ghc for - -- compiling as for linking. But for repl we have to do just - -- the one invocation, so that one has to include all the - -- linker stuff too, like -l flags and any .o files from C - -- files etc. - -- - -- TODO: The repl doesn't use the runtime paths from linkerOpts - -- (ghcOptRPaths), which looks like a bug. After the refactor we - -- can fix this. - `mappend` linkerOpts mempty - `mappend` mempty - { ghcOptMode = toFlag GhcModeInteractive - , ghcOptOptimisation = toFlag GhcNoOptimisation + then extraLibsStatic bi + else extraLibs bi + , ghcOptLinkLibPath = + toNubListR $ + if withFullyStaticExe lbi + then cleanedExtraLibDirsStatic + else cleanedExtraLibDirs + , ghcOptLinkFrameworks = toNubListR $ map getSymbolicPath $ PD.frameworks bi + , ghcOptLinkFrameworkDirs = toNubListR $ PD.extraFrameworkDirs bi + , ghcOptInputFiles = + toNubListR + [ coerceSymbolicPath $ buildTargetDir obj + | obj <- extraSourcesObjs + ] + , ghcOptNoLink = Flag False + , ghcOptRPaths = rpaths + } + + case what of + BuildRepl replFlags -> liftIO $ do + let + -- For repl we use the vanilla (static) ghc options + staticOpts = buildOpts StaticWay + replOpts = + staticOpts + { -- Repl options use Static as the base, but doesn't need to pass -static. + -- However, it maybe should, for uniformity. + ghcOptDynLinkMode = NoFlag + , ghcOptExtra = + Internal.filterGhciFlags + (ghcOptExtra staticOpts) + <> replOptionsFlags (replReplOptions replFlags) + } + -- For a normal compile we do separate invocations of ghc for + -- compiling as for linking. But for repl we have to do just + -- the one invocation, so that one has to include all the + -- linker stuff too, like -l flags and any .o files from C + -- files etc. + -- + -- TODO: The repl doesn't use the runtime paths from linkerOpts + -- (ghcOptRPaths), which looks like a bug. After the refactor we + -- can fix this. + `mappend` linkerOpts mempty + `mappend` mempty + { ghcOptMode = toFlag GhcModeInteractive + , ghcOptOptimisation = toFlag GhcNoOptimisation + } + replOpts_final = + replOpts + { ghcOptInputModules = replNoLoad (replReplOptions replFlags) (ghcOptInputModules replOpts) + , ghcOptInputFiles = replNoLoad (replReplOptions replFlags) (ghcOptInputFiles replOpts) } - -- TODO: problem here is we need the .c files built first, so we can load them - -- with ghci, but .c files can depend on .h files generated by ghc by ffi - -- exports. - when (case component of CLib lib -> null (allLibModules lib clbi); _ -> False) $ - warn verbosity "No exposed modules" - runReplOrWriteFlags ghcProg lbi replFlags replOpts (pkgName (PD.package pkg_descr)) target - _otherwise -> - let - runGhcProg = runGHC verbosity ghcProg comp platform mbWorkDir - platform = hostPlatform lbi - comp = compiler lbi - in - when (not $ componentIsIndefinite clbi) $ do - -- If not building dynamically, we don't pass any runtime paths. - rpaths <- if DynWay `Set.member` wantedWays then getRPaths pbci else return (toNubListR []) - liftIO $ do - info verbosity "Linking..." - let linkExeLike name = linkExecutable (linkerOpts rpaths) (wantedWays, buildOpts) targetDir name runGhcProg lbi - case component of - CLib lib -> linkLibrary buildTargetDir cleanedExtraLibDirs pkg_descr verbosity runGhcProg lib lbi clbi extraSources rpaths wantedWays - CFLib flib -> linkFLib flib bi lbi (linkerOpts rpaths) (wantedWays, buildOpts) targetDir runGhcProg - CExe exe -> linkExeLike (exeName exe) - CTest test -> linkExeLike (testName test) - CBench bench -> linkExeLike (benchmarkName bench) + -- TODO: problem here is we need the .c files built first, so we can load them + -- with ghci, but .c files can depend on .h files generated by ghc by ffi + -- exports. + when (case component of CLib lib -> null (allLibModules lib clbi); _ -> False) $ + warn verbosity "No exposed modules" + runReplOrWriteFlags ghcProg lbi replFlags replOpts_final (pkgName (PD.package pkg_descr)) target + _otherwise -> + let + runGhcProg = runGHC verbosity ghcProg comp platform mbWorkDir + platform = hostPlatform lbi + comp = compiler lbi + get_rpaths ways = + if DynWay `Set.member` ways then getRPaths pbci else return (toNubListR []) + in + when (not $ componentIsIndefinite clbi) $ do + -- If not building dynamically, we don't pass any runtime paths. + liftIO $ do + info verbosity "Linking..." + let linkExeLike name = do + rpaths <- get_rpaths (Set.singleton wantedExeWay) + linkExecutable (linkerOpts rpaths) (wantedExeWay, buildOpts) targetDir name runGhcProg lbi + case component of + CLib lib -> do + let libWays = wantedLibWays isIndef + rpaths <- get_rpaths (Set.fromList libWays) + linkLibrary buildTargetDir cleanedExtraLibDirs pkg_descr verbosity runGhcProg lib lbi clbi extraSources rpaths libWays + CFLib flib -> do + let flib_way = wantedFLibWay (withDynFLib flib) + rpaths <- get_rpaths (Set.singleton flib_way) + linkFLib flib bi lbi (linkerOpts rpaths) (flib_way, buildOpts) targetDir runGhcProg + CExe exe -> linkExeLike (exeName exe) + CTest test -> linkExeLike (testName test) + CBench bench -> linkExeLike (benchmarkName bench) -- | Link a library component linkLibrary @@ -217,7 +235,7 @@ linkLibrary -- ^ Extra build sources (that were compiled to objects) -> NubListR FilePath -- ^ A list with the runtime-paths (rpaths), or empty if not linking dynamically - -> Set.Set BuildWay + -> [BuildWay] -- ^ Wanted build ways and corresponding build options -> IO () linkLibrary buildTargetDir cleanedExtraLibDirs pkg_descr verbosity runGhcProg lib lbi clbi extraSources rpaths wantedWays = do @@ -237,6 +255,9 @@ linkLibrary buildTargetDir cleanedExtraLibDirs pkg_descr verbosity runGhcProg li sharedLibFilePath = buildTargetDir makeRelativePathEx (mkSharedLibName (hostPlatform lbi) compiler_id uid) + profSharedLibFilePath = + buildTargetDir + makeRelativePathEx (mkProfSharedLibName (hostPlatform lbi) compiler_id uid) staticLibFilePath = buildTargetDir makeRelativePathEx (mkStaticLibName (hostPlatform lbi) compiler_id uid) @@ -252,6 +273,9 @@ linkLibrary buildTargetDir cleanedExtraLibDirs pkg_descr verbosity runGhcProg li sharedLibInstallPath = libInstallPath mkSharedLibName (hostPlatform lbi) compiler_id uid + profSharedLibInstallPath = + libInstallPath + mkProfSharedLibName (hostPlatform lbi) compiler_id uid getObjFiles :: BuildWay -> IO [SymbolicPath Pkg File] getObjFiles way = @@ -358,6 +382,32 @@ linkLibrary buildTargetDir cleanedExtraLibDirs pkg_descr verbosity runGhcProg li toNubListR $ PD.extraFrameworkDirs libBi , ghcOptRPaths = rpaths } + ghcProfSharedLinkArgs pdynObjectFiles = + ghcBaseLinkArgs + { ghcOptShared = toFlag True + , ghcOptProfilingMode = toFlag True + , ghcOptProfilingAuto = + Internal.profDetailLevelFlag + True + (withProfLibDetail lbi) + , ghcOptDynLinkMode = toFlag GhcDynamicOnly + , ghcOptInputFiles = toNubListR pdynObjectFiles + , ghcOptOutputFile = toFlag profSharedLibFilePath + , -- For dynamic libs, Mac OS/X needs to know the install location + -- at build time. This only applies to GHC < 7.8 - see the + -- discussion in #1660. + ghcOptDylibName = + if hostOS == OSX + && ghcVersion < mkVersion [7, 8] + then toFlag profSharedLibInstallPath + else mempty + , ghcOptLinkLibs = extraLibs libBi + , ghcOptLinkLibPath = toNubListR $ cleanedExtraLibDirs + , ghcOptLinkFrameworks = toNubListR $ map getSymbolicPath $ PD.frameworks libBi + , ghcOptLinkFrameworkDirs = + toNubListR $ PD.extraFrameworkDirs libBi + , ghcOptRPaths = rpaths + } ghcStaticLinkArgs staticObjectFiles = ghcBaseLinkArgs { ghcOptStaticLib = toFlag True @@ -371,6 +421,7 @@ linkLibrary buildTargetDir cleanedExtraLibDirs pkg_descr verbosity runGhcProg li staticObjectFiles <- getObjFiles StaticWay profObjectFiles <- getObjFiles ProfWay dynamicObjectFiles <- getObjFiles DynWay + profDynamicObjectFiles <- getObjFiles ProfDynWay let linkWay = \case @@ -384,6 +435,8 @@ linkLibrary buildTargetDir cleanedExtraLibDirs pkg_descr verbosity runGhcProg li ldProg ghciProfLibFilePath profObjectFiles + ProfDynWay -> do + runGhcProg $ ghcProfSharedLinkArgs profDynamicObjectFiles DynWay -> do runGhcProg $ ghcSharedLinkArgs dynamicObjectFiles StaticWay -> do @@ -413,7 +466,7 @@ linkLibrary buildTargetDir cleanedExtraLibDirs pkg_descr verbosity runGhcProg li linkExecutable :: (GhcOptions) -- ^ The linker-specific GHC options - -> (Set.Set BuildWay, BuildWay -> GhcOptions) + -> (BuildWay, BuildWay -> GhcOptions) -- ^ The wanted build ways and corresponding GhcOptions that were -- used to compile the modules in that way. -> SymbolicPath Pkg (Dir Build) @@ -425,30 +478,27 @@ linkExecutable -- ^ Run the configured GHC program -> LocalBuildInfo -> IO () -linkExecutable linkerOpts (wantedWays, buildOpts) targetDir targetName runGhcProg lbi = do - -- When building an executable, we should only "want" one build way. - assert (Set.size wantedWays == 1) $ - forM_ wantedWays $ \way -> do - let baseOpts = buildOpts way - linkOpts = - baseOpts - `mappend` linkerOpts - `mappend` mempty - { -- If there are no input Haskell files we pass -no-hs-main, and - -- assume there is a main function in another non-haskell object - ghcOptLinkNoHsMain = toFlag (ghcOptInputFiles baseOpts == mempty && ghcOptInputScripts baseOpts == mempty) - } - comp = compiler lbi +linkExecutable linkerOpts (way, buildOpts) targetDir targetName runGhcProg lbi = do + let baseOpts = buildOpts way + linkOpts = + baseOpts + `mappend` linkerOpts + `mappend` mempty + { -- If there are no input Haskell files we pass -no-hs-main, and + -- assume there is a main function in another non-haskell object + ghcOptLinkNoHsMain = toFlag (ghcOptInputFiles baseOpts == mempty && ghcOptInputScripts baseOpts == mempty) + } + comp = compiler lbi - -- Work around old GHCs not relinking in this - -- situation, see #3294 - let target = - targetDir makeRelativePathEx (exeTargetName (hostPlatform lbi) targetName) - when (compilerVersion comp < mkVersion [7, 7]) $ do - let targetPath = interpretSymbolicPathLBI lbi target - e <- doesFileExist targetPath - when e (removeFile targetPath) - runGhcProg linkOpts{ghcOptOutputFile = toFlag target} + -- Work around old GHCs not relinking in this + -- situation, see #3294 + let target = + targetDir makeRelativePathEx (exeTargetName (hostPlatform lbi) targetName) + when (compilerVersion comp < mkVersion [7, 7]) $ do + let targetPath = interpretSymbolicPathLBI lbi target + e <- doesFileExist targetPath + when e (removeFile targetPath) + runGhcProg linkOpts{ghcOptOutputFile = toFlag target} -- | Link a foreign library component linkFLib @@ -457,7 +507,7 @@ linkFLib -> LocalBuildInfo -> (GhcOptions) -- ^ The linker-specific GHC options - -> (Set.Set BuildWay, BuildWay -> GhcOptions) + -> (BuildWay, BuildWay -> GhcOptions) -- ^ The wanted build ways and corresponding GhcOptions that were -- used to compile the modules in that way. -> SymbolicPath Pkg (Dir Build) @@ -466,7 +516,7 @@ linkFLib -> (GhcOptions -> IO ()) -- ^ Run the configured GHC program -> IO () -linkFLib flib bi lbi linkerOpts (wantedWays, buildOpts) targetDir runGhcProg = do +linkFLib flib bi lbi linkerOpts (way, buildOpts) targetDir runGhcProg = do let comp = compiler lbi @@ -498,8 +548,8 @@ linkFLib flib bi lbi linkerOpts (wantedWays, buildOpts) targetDir runGhcProg = d else statRtsVanillaLib (rtsStaticInfo rtsInfo) ] - linkOpts :: BuildWay -> GhcOptions - linkOpts way = case foreignLibType flib of + linkOpts :: GhcOptions + linkOpts = case foreignLibType flib of ForeignLibNativeShared -> (buildOpts way) `mappend` linkerOpts @@ -521,13 +571,10 @@ linkFLib flib bi lbi linkerOpts (wantedWays, buildOpts) targetDir runGhcProg = d -- soname on supported platforms. See also the note for -- @flibBuildName@. let buildName = flibBuildName lbi flib - -- There should not be more than one wanted way when building an flib - assert (Set.size wantedWays == 1) $ - forM_ wantedWays $ \way -> do - let outFile = targetDir makeRelativePathEx buildName - runGhcProg (linkOpts way){ghcOptOutputFile = toFlag outFile} - let i = interpretSymbolicPathLBI lbi - renameFile (i outFile) (i targetDir flibTargetName lbi flib) + let outFile = targetDir makeRelativePathEx buildName + runGhcProg linkOpts{ghcOptOutputFile = toFlag outFile} + let i = interpretSymbolicPathLBI lbi + renameFile (i outFile) (i targetDir flibTargetName lbi flib) -- | Calculate the RPATHs for the component we are building. -- diff --git a/Cabal/src/Distribution/Simple/GHC/Build/Modules.hs b/Cabal/src/Distribution/Simple/GHC/Build/Modules.hs index 9c9e55a03bf..0c89d860a1b 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build/Modules.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build/Modules.hs @@ -17,6 +17,7 @@ import Distribution.ModuleName (ModuleName) import qualified Distribution.PackageDescription as PD import Distribution.Pretty import Distribution.Simple.Build.Inputs +import Distribution.Simple.BuildWay import Distribution.Simple.Compiler import Distribution.Simple.GHC.Build.Utils import qualified Distribution.Simple.GHC.Internal as Internal @@ -102,8 +103,8 @@ buildHaskellModules -> SymbolicPath Pkg ('Dir Artifacts) -- ^ The path to the build directory for this target, which -- has already been created. - -> Set.Set BuildWay - -- ^ The set of wanted build ways according to user options + -> [BuildWay] + -- ^ The set of needed build ways according to user options -> PreBuildComponentInputs -- ^ The context and component being built in it. -> IO (BuildWay -> GhcOptions) @@ -111,7 +112,7 @@ buildHaskellModules -- invocation used to compile the component in that 'BuildWay'. -- This can be useful in, eg, a linker invocation, in which we want to use the -- same options and list the same inputs as those used for building. -buildHaskellModules numJobs ghcProg pkg_descr buildTargetDir wantedWays pbci = do +buildHaskellModules numJobs ghcProg pkg_descr buildTargetDir neededLibWays pbci = do -- See Note [Building Haskell Modules accounting for TH] let @@ -147,9 +148,6 @@ buildHaskellModules numJobs ghcProg pkg_descr buildTargetDir wantedWays pbci = d runGhcProg = runGHC verbosity ghcProg comp platform mbWorkDir platform = hostPlatform lbi - -- See Note [Building Haskell Modules accounting for TH] - doingTH = usesTemplateHaskellOrQQ bi - -- We define the base opts which are shared across different build ways in -- 'buildHaskellModules' baseOpts way = @@ -200,6 +198,18 @@ buildHaskellModules numJobs ghcProg pkg_descr buildTargetDir wantedWays pbci = d (if isLib then True else False) ((if isLib then withProfLibDetail else withProfExeDetail) lbi) } + profDynOpts = + (baseOpts ProfDynWay) + { ghcOptDynLinkMode = toFlag GhcDynamicOnly -- use -dynamic + , -- TODO: Does it hurt to set -fPIC for executables? + ghcOptFPic = toFlag True -- use -fPIC + , ghcOptProfilingMode = toFlag True + , ghcOptProfilingAuto = + Internal.profDetailLevelFlag + (if isLib then True else False) + ((if isLib then withProfLibDetail else withProfExeDetail) lbi) + } + -- Options for building both static and dynamic way at the same time, using -- the GHC flag -static and -dynamic-too dynTooOpts = @@ -212,45 +222,84 @@ buildHaskellModules numJobs ghcProg pkg_descr buildTargetDir wantedWays pbci = d -- (Note that `baseOtps StaticWay = hcStaticOptions`, not hcSharedOpts) } + profDynTooOpts = + (baseOpts ProfWay) + { ghcOptDynLinkMode = toFlag GhcStaticAndDynamic -- use -dynamic-too + , -- TODO: Does it hurt to set -fPIC for executables? + ghcOptFPic = toFlag True -- use -fPIC + , ghcOptProfilingMode = toFlag True + , ghcOptProfilingAuto = + Internal.profDetailLevelFlag + (if isLib then True else False) + ((if isLib then withProfLibDetail else withProfExeDetail) lbi) + , ghcOptDynHiSuffix = toFlag (buildWayPrefix ProfDynWay ++ "hi") + , ghcOptDynObjSuffix = toFlag (buildWayPrefix ProfDynWay ++ "o") + , ghcOptHPCDir = hpcdir Hpc.ProfDyn + -- Should we pass hcSharedOpts in the -dynamic-too ghc invocation? + -- (Note that `baseOtps StaticWay = hcStaticOptions`, not hcSharedOpts) + } + -- Determines how to build for each way, also serves as the base options -- for loading modules in 'linkOrLoadComponent' buildOpts way = case way of StaticWay -> staticOpts DynWay -> dynOpts ProfWay -> profOpts - - defaultGhcWay = if isDynamic comp then DynWay else StaticWay + ProfDynWay -> profDynOpts -- If there aren't modules, or if we're loading the modules in repl, don't build. unless (forRepl || (null inputFiles && null inputModules)) $ liftIO $ do -- See Note [Building Haskell Modules accounting for TH] let - neededWays = - wantedWays - <> Set.fromList - -- TODO: You also don't need to build the GHC way when doing TH if - -- you are using an external interpreter!! - [defaultGhcWay | doingTH && defaultGhcWay `Set.notMember` wantedWays] + neededLibWaysSet = Set.fromList neededLibWays -- If we need both static and dynamic, use dynamic-too instead of -- compiling twice (if we support it) useDynamicToo = - StaticWay `Set.member` neededWays - && DynWay `Set.member` neededWays + StaticWay `Set.member` neededLibWaysSet + && DynWay `Set.member` neededLibWaysSet + && supportsDynamicToo comp + && null (hcSharedOptions GHC bi) + + useProfDynamicToo = + ProfWay `Set.member` neededLibWaysSet + && ProfDynWay `Set.member` neededLibWaysSet && supportsDynamicToo comp && null (hcSharedOptions GHC bi) + defaultGhcWay = compilerBuildWay comp + + order w + | w == defaultGhcWay = 0 + | otherwise = fromEnum w + 1 + -- The ways we'll build, in order orderedBuilds - -- If we can use dynamic-too, do it first. The default GHC way can only - -- be static or dynamic, so, if we build both right away, any modules - -- possibly needed by TH later (e.g. if building profiled) are already built. + -- We need to make sure that the way which is the way the compiler is built + -- is built first so that Template Haskell works. + | useProfDynamicToo && useDynamicToo = + if defaultGhcWay `elem` [ProfDynWay, ProfWay] + then [buildProfAndProfDynamicToo, buildStaticAndDynamicToo] + else [buildStaticAndDynamicToo, buildProfAndProfDynamicToo] + | useProfDynamicToo && not useDynamicToo = + if defaultGhcWay `elem` [ProfDynWay, ProfWay] + then + [buildProfAndProfDynamicToo] + ++ (runGhcProg . buildOpts <$> neededLibWays \\ [ProfDynWay, ProfWay]) + else + (runGhcProg . buildOpts <$> neededLibWays \\ [ProfDynWay, ProfWay]) + ++ [buildProfAndProfDynamicToo] | useDynamicToo = - [buildStaticAndDynamicToo] - ++ (runGhcProg . buildOpts <$> Set.toList neededWays \\ [StaticWay, DynWay]) + if defaultGhcWay `elem` [StaticWay, DynWay] + then + [buildStaticAndDynamicToo] + ++ (runGhcProg . buildOpts <$> neededLibWays \\ [StaticWay, DynWay]) + else + (runGhcProg . buildOpts <$> neededLibWays \\ [StaticWay, DynWay]) + ++ [buildStaticAndDynamicToo] -- Otherwise, we need to ensure the defaultGhcWay is built first | otherwise = - runGhcProg . buildOpts <$> sortOn (\w -> if w == defaultGhcWay then 0 else fromEnum w + 1) (Set.toList neededWays) + runGhcProg . buildOpts <$> sortOn order neededLibWays buildStaticAndDynamicToo = do runGhcProg dynTooOpts @@ -264,27 +313,31 @@ buildHaskellModules numJobs ghcProg pkg_descr buildTargetDir wantedWays pbci = d -- both ways. copyDirectoryRecursive verbosity (i dynDir) (i vanillaDir) _ -> return () + + buildProfAndProfDynamicToo = do + runGhcProg profDynTooOpts + case (hpcdir Hpc.ProfDyn, hpcdir Hpc.Prof) of + (Flag profDynDir, Flag profDir) -> + -- When the vanilla and shared library builds are done + -- in one pass, only one set of HPC module interfaces + -- are generated. This set should suffice for both + -- static and dynamically linked executables. We copy + -- the modules interfaces so they are available under + -- both ways. + copyDirectoryRecursive verbosity (i profDynDir) (i profDir) + _ -> return () in -- REVIEW:ADD? info verbosity "Building Haskell Sources..." sequence_ orderedBuilds return buildOpts -data BuildWay = StaticWay | DynWay | ProfWay - deriving (Eq, Ord, Show, Enum) - --- | Returns the object/interface extension prefix for the given build way (e.g. "dyn_" for 'DynWay') -buildWayPrefix :: BuildWay -> String -buildWayPrefix = \case - StaticWay -> "" - ProfWay -> "p_" - DynWay -> "dyn_" - -- | Returns the corresponding 'Hpc.Way' for a 'BuildWay' buildWayHpcWay :: BuildWay -> Hpc.Way buildWayHpcWay = \case StaticWay -> Hpc.Vanilla ProfWay -> Hpc.Prof DynWay -> Hpc.Dyn + ProfDynWay -> Hpc.ProfDyn -- | Returns a function to extract the extra haskell compiler options from a -- 'BuildInfo' and 'CompilerFlavor' @@ -293,6 +346,7 @@ buildWayExtraHcOptions = \case StaticWay -> hcStaticOptions ProfWay -> hcProfOptions DynWay -> hcSharedOptions + ProfDynWay -> hcProfSharedOptions -- | Returns a pair of the Haskell input files and Haskell modules of the -- component being built. diff --git a/Cabal/src/Distribution/Simple/GHC/Build/Utils.hs b/Cabal/src/Distribution/Simple/GHC/Build/Utils.hs index fb8bd21351a..c87d074c202 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build/Utils.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build/Utils.hs @@ -13,6 +13,7 @@ import qualified Distribution.ModuleName as ModuleName import Distribution.PackageDescription as PD import Distribution.PackageDescription.Utils (cabalBug) import Distribution.Simple.BuildPaths +import Distribution.Simple.BuildWay import Distribution.Simple.Compiler import qualified Distribution.Simple.GHC.Internal as Internal import Distribution.Simple.Program.GHC @@ -47,10 +48,21 @@ findExecutableMain verbosity mbWorkDir buildDir (bnfo, modPath) = supportsDynamicToo :: Compiler -> Bool supportsDynamicToo = Internal.ghcLookupProperty "Support dynamic-too" +compilerBuildWay :: Compiler -> BuildWay +compilerBuildWay c = + case (isDynamic c, isProfiled c) of + (True, True) -> ProfDynWay + (True, False) -> DynWay + (False, True) -> ProfWay + (False, False) -> StaticWay + -- | Is this compiler's RTS dynamically linked? isDynamic :: Compiler -> Bool isDynamic = Internal.ghcLookupProperty "GHC Dynamic" +isProfiled :: Compiler -> Bool +isProfiled = Internal.ghcLookupProperty "GHC Profiled" + -- | Should we dynamically link the foreign library, based on its 'foreignLibType'? withDynFLib :: ForeignLib -> Bool withDynFLib flib = diff --git a/Cabal/src/Distribution/Simple/Hpc.hs b/Cabal/src/Distribution/Simple/Hpc.hs index ea1c1368057..4198d7a66ba 100644 --- a/Cabal/src/Distribution/Simple/Hpc.hs +++ b/Cabal/src/Distribution/Simple/Hpc.hs @@ -58,7 +58,7 @@ import System.Directory (createDirectoryIfMissing, doesFileExist) -- ------------------------------------------------------------------------- -- Haskell Program Coverage -data Way = Vanilla | Prof | Dyn +data Way = Vanilla | Prof | Dyn | ProfDyn deriving (Bounded, Enum, Eq, Read, Show) hpcDir @@ -73,6 +73,7 @@ hpcDir distPref way = distPref makeRelativePathEx ("hpc" wayDir) Vanilla -> "vanilla" Prof -> "prof" Dyn -> "dyn" + ProfDyn -> "prof_dyn" mixDir :: SymbolicPath Pkg (Dir Dist) diff --git a/Cabal/src/Distribution/Simple/LocalBuildInfo.hs b/Cabal/src/Distribution/Simple/LocalBuildInfo.hs index 35681ee5908..dce6ff0f8bb 100644 --- a/Cabal/src/Distribution/Simple/LocalBuildInfo.hs +++ b/Cabal/src/Distribution/Simple/LocalBuildInfo.hs @@ -36,6 +36,7 @@ module Distribution.Simple.LocalBuildInfo , interpretSymbolicPathLBI , mbWorkDirLBI , absoluteWorkingDirLBI + , buildWays -- * Buildable package components , Component (..) diff --git a/Cabal/src/Distribution/Simple/Setup/Config.hs b/Cabal/src/Distribution/Simple/Setup/Config.hs index 14e76c7d769..88c970e162f 100644 --- a/Cabal/src/Distribution/Simple/Setup/Config.hs +++ b/Cabal/src/Distribution/Simple/Setup/Config.hs @@ -127,6 +127,8 @@ data ConfigFlags = ConfigFlags , configProf :: Flag Bool -- ^ Enable profiling in the library -- and executables. + , configProfShared :: Flag Bool + -- ^ Enable shared profiling objects , configProfDetail :: Flag ProfDetailLevel -- ^ Profiling detail level -- in the library and executables. @@ -286,6 +288,7 @@ instance Eq ConfigFlags where && equal configProfExe && equal configProf && equal configProfDetail + && equal configProfShared && equal configProfLibDetail && equal configConfigureArgs && equal configOptimization @@ -518,6 +521,13 @@ configureOptions showOrParseArgs = configProf (\v flags -> flags{configProf = v}) (boolOpt [] []) + , option + "" + ["profiling-shared"] + "Build profiling shared libraries" + configProfShared + (\v flags -> flags{configProfShared = v}) + (boolOpt [] []) , option "" ["executable-profiling"] diff --git a/Cabal/src/Distribution/Types/LocalBuildConfig.hs b/Cabal/src/Distribution/Types/LocalBuildConfig.hs index 9126d92f1eb..ce9064b2f43 100644 --- a/Cabal/src/Distribution/Types/LocalBuildConfig.hs +++ b/Cabal/src/Distribution/Types/LocalBuildConfig.hs @@ -151,6 +151,8 @@ data BuildOptions = BuildOptions { withVanillaLib :: Bool -- ^ Whether to build normal libs. , withProfLib :: Bool + -- ^ Whether to build normal libs. + , withProfLibShared :: Bool -- ^ Whether to build profiling versions of libs. , withSharedLib :: Bool -- ^ Whether to build shared versions of libs. @@ -211,6 +213,7 @@ buildOptionsConfigFlags (BuildOptions{..}) = , configGHCiLib = toFlag $ withGHCiLib , configProfExe = toFlag $ withProfExe , configProfLib = toFlag $ withProfLib + , configProfShared = toFlag $ withProfLibShared , configProf = mempty , -- configProfDetail is for exe+lib, but overridden by configProfLibDetail -- so we specify both so we can specify independently diff --git a/Cabal/src/Distribution/Types/LocalBuildInfo.hs b/Cabal/src/Distribution/Types/LocalBuildInfo.hs index 3f9d8d74268..f6af8c29c77 100644 --- a/Cabal/src/Distribution/Types/LocalBuildInfo.hs +++ b/Cabal/src/Distribution/Types/LocalBuildInfo.hs @@ -28,11 +28,12 @@ module Distribution.Types.LocalBuildInfo , withPackageDB , withVanillaLib , withProfLib - , withSharedLib - , withStaticLib + , withProfLibShared , withDynExe , withFullyStaticExe , withProfExe + , withSharedLib + , withStaticLib , withProfLibDetail , withProfExeDetail , withOptimization @@ -82,6 +83,7 @@ module Distribution.Types.LocalBuildInfo , neededTargetsInBuildOrder' , withNeededTargetsInBuildOrder' , testCoverage + , buildWays -- * Functions you SHOULD NOT USE (yet), but are defined here to @@ -111,6 +113,7 @@ import Distribution.Utils.Path import Distribution.PackageDescription import Distribution.Pretty +import Distribution.Simple.BuildWay import Distribution.Simple.Compiler import Distribution.Simple.Flag import Distribution.Simple.InstallDirs hiding @@ -169,6 +172,7 @@ pattern LocalBuildInfo -> Bool -> Bool -> Bool + -> Bool -> ProfDetailLevel -> ProfDetailLevel -> OptimisationLevel @@ -201,6 +205,7 @@ pattern LocalBuildInfo , withPackageDB , withVanillaLib , withProfLib + , withProfLibShared , withSharedLib , withStaticLib , withDynExe @@ -252,6 +257,7 @@ pattern LocalBuildInfo LBC.BuildOptions { withVanillaLib , withProfLib + , withProfLibShared , withSharedLib , withStaticLib , withDynExe @@ -429,6 +435,49 @@ testCoverage :: LocalBuildInfo -> Bool testCoverage (LocalBuildInfo{exeCoverage = exes, libCoverage = libs}) = exes && libs +-- | Returns a list of ways, in the order which they should be built, and the +-- way we build executable and foreign library components. +-- +-- Ideally all this info should be fixed at configure time and not dependent on +-- additional info but `LocalBuildInfo` is per package (not per component) so it's +-- currently not possible to configure components to be built in certain ways. +buildWays :: LocalBuildInfo -> (Bool -> [BuildWay], Bool -> BuildWay, BuildWay) +buildWays lbi = + let + -- enable-library-profiling (enable (static profiling way)) .p_o + -- enable-shared (enabled dynamic way) .dyn_o + -- enable-profiling-shared (enable dyanmic profilng way) .p_dyn_o + -- enable-library-vanilla (enable vanilla way) .o + -- + -- enable-executable-dynamic => build dynamic executables + -- => --enable-profiling + --enable-executable-dynamic => build dynamic profiled executables + -- => --enable-profiling => build vanilla profiled executables + + wantedLibWays is_indef = + [ProfDynWay | withProfLibShared lbi && not is_indef] + <> [ProfWay | withProfLib lbi] + -- I don't see why we shouldn't build with dynamic-- indefinite components. + <> [DynWay | withSharedLib lbi && not is_indef] + -- MP: Ideally we should have `BuildOptions` on a per component basis, in + -- which case this `is_indef` check could be moved to configure time. + <> [StaticWay | withVanillaLib lbi || withStaticLib lbi] + + wantedFLibWay is_dyn_flib = + case (is_dyn_flib, withProfExe lbi) of + (True, True) -> ProfDynWay + (False, True) -> ProfWay + (True, False) -> DynWay + (False, False) -> StaticWay + + wantedExeWay = + case (withDynExe lbi, withProfExe lbi) of + (True, True) -> ProfDynWay + (True, False) -> DynWay + (False, True) -> ProfWay + (False, False) -> StaticWay + in + (wantedLibWays, wantedFLibWay, wantedExeWay) + ------------------------------------------------------------------------------- -- Stub functions to prevent someone from accidentally defining them diff --git a/cabal-install-solver/src/Distribution/Solver/Types/ConstraintSource.hs b/cabal-install-solver/src/Distribution/Solver/Types/ConstraintSource.hs index 3fdf64bde89..55b35212d3c 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/ConstraintSource.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/ConstraintSource.hs @@ -41,6 +41,10 @@ data ConstraintSource = -- from Cabal >= 3.11 | ConstraintSourceMultiRepl + | ConstraintSourceProfiledDynamic + -- | Constraint introduced by --enable-profiling-shared, which requires features + -- from Cabal >= 3.13 + -- | The source of the constraint is not specified. | ConstraintSourceUnknown @@ -72,6 +76,8 @@ showConstraintSource ConstraintSourceConfigFlagOrTarget = "config file, command line flag, or user target" showConstraintSource ConstraintSourceMultiRepl = "--enable-multi-repl" +showConstraintSource ConstraintSourceProfiledDynamic = + "--enable-profiling-shared" showConstraintSource ConstraintSourceUnknown = "unknown source" showConstraintSource ConstraintSetupCabalMinVersion = "minimum version of Cabal used by Setup.hs" diff --git a/cabal-install/src/Distribution/Client/Config.hs b/cabal-install/src/Distribution/Client/Config.hs index d9b91c959d0..5930ca98c13 100644 --- a/cabal-install/src/Distribution/Client/Config.hs +++ b/cabal-install/src/Distribution/Client/Config.hs @@ -490,6 +490,7 @@ instance Semigroup SavedConfig where , configVanillaLib = combine configVanillaLib , configProfLib = combine configProfLib , configProf = combine configProf + , configProfShared = combine configProfShared , configSharedLib = combine configSharedLib , configStaticLib = combine configStaticLib , configDynExe = combine configDynExe diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index 3f6a7fea32a..2949b4d21d1 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -64,6 +64,7 @@ module Distribution.Client.Dependency , addDefaultSetupDependencies , addSetupCabalMinVersionConstraint , addSetupCabalMaxVersionConstraint + , addSetupCabalProfiledDynamic ) where import Distribution.Client.Compat.Prelude @@ -671,6 +672,22 @@ addSetupCabalMaxVersionConstraint maxVersion = where cabalPkgname = mkPackageName "Cabal" +-- | Add an a lower bound @setup.Cabal >= 3.13@ labeled with 'ConstraintSourceProfiledDynamic' +addSetupCabalProfiledDynamic + :: DepResolverParams + -> DepResolverParams +addSetupCabalProfiledDynamic = + addConstraints + [ LabeledPackageConstraint + ( PackageConstraint + (ScopeAnySetupQualifier cabalPkgname) + (PackagePropertyVersion $ orLaterVersion (mkVersion [3, 13, 0])) + ) + ConstraintSourceProfiledDynamic + ] + where + cabalPkgname = mkPackageName "Cabal" + upgradeDependencies :: DepResolverParams -> DepResolverParams upgradeDependencies = setPreferenceDefault PreferAllLatest diff --git a/cabal-install/src/Distribution/Client/ProjectConfig.hs b/cabal-install/src/Distribution/Client/ProjectConfig.hs index 99dde932037..cec000b6a9b 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig.hs @@ -102,9 +102,8 @@ import Distribution.Client.HttpUtils import Distribution.Client.Types import Distribution.Client.Utils.Parsec (renderParseError) +import Distribution.Solver.Types.ConstraintSource import Distribution.Solver.Types.PackageConstraint - ( PackageProperty (..) - ) import Distribution.Solver.Types.Settings import Distribution.Solver.Types.SourcePackage @@ -116,6 +115,7 @@ import Distribution.Client.Setup import Distribution.Client.SrcDist ( packageDirToSdist ) +import Distribution.Client.Targets import Distribution.Client.Types.SourceRepo ( SourceRepoList , SourceRepositoryPackage (..) @@ -136,11 +136,6 @@ import Distribution.Fields , showPWarning ) import Distribution.Package - ( PackageId - , PackageName - , UnitId - , packageId - ) import Distribution.PackageDescription.Parsec ( parseGenericPackageDescription ) @@ -195,8 +190,6 @@ import Distribution.Verbosity , verbose ) import Distribution.Version - ( Version - ) import qualified Codec.Archive.Tar as Tar import qualified Codec.Archive.Tar.Entry as Tar @@ -317,9 +310,34 @@ resolveSolverSettings where -- TODO: [required eventually] some of these settings need validation, e.g. -- the flag assignments need checking. + cabalPkgname = mkPackageName "Cabal" + + profilingDynamicConstraint = + ( UserConstraint + (UserAnySetupQualifier cabalPkgname) + (PackagePropertyVersion $ orLaterVersion (mkVersion [3, 13, 0])) + , ConstraintSourceProfiledDynamic + ) + + profDynEnabledGlobally = fromFlagOrDefault False (packageConfigProfShared projectConfigLocalPackages) + + profDynEnabledAnyLocally = + or + [ fromFlagOrDefault False (packageConfigProfShared ppc) + | (_, ppc) <- Map.toList (getMapMappend projectConfigSpecificPackage) + ] + + -- Add a setup.Cabal >= 3.13 constraint if prof+dyn is enabled globally + -- or any package in the project enables it. + -- Ideally we'd apply this constraint only on the closure of packages requiring prof+dyn, + -- but that would require another solver run for marginal advantages that + -- will further shrink as 3.13 is adopted. + solverCabalLibConstraints = + [profilingDynamicConstraint | profDynEnabledGlobally || profDynEnabledAnyLocally] + solverSettingRemoteRepos = fromNubList projectConfigRemoteRepos solverSettingLocalNoIndexRepos = fromNubList projectConfigLocalNoIndexRepos - solverSettingConstraints = projectConfigConstraints + solverSettingConstraints = solverCabalLibConstraints ++ projectConfigConstraints solverSettingPreferences = projectConfigPreferences solverSettingFlagAssignment = packageConfigFlagAssignment projectConfigLocalPackages solverSettingFlagAssignments = diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs index ddb6f615264..3d4dc29d8a0 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs @@ -768,6 +768,7 @@ convertLegacyPerPackageFlags , configFullyStaticExe = packageConfigFullyStaticExe , configProfExe = packageConfigProfExe , configProf = packageConfigProf + , configProfShared = packageConfigProfShared , configProfDetail = packageConfigProfDetail , configProfLibDetail = packageConfigProfLibDetail , configConfigureArgs = packageConfigConfigureArgs @@ -1074,6 +1075,7 @@ convertToLegacyAllPackageConfig , configFullyStaticExe = mempty , configProfExe = mempty , configProf = mempty + , configProfShared = mempty , configProfDetail = mempty , configProfLibDetail = mempty , configConfigureArgs = mempty @@ -1150,6 +1152,7 @@ convertToLegacyPerPackageConfig PackageConfig{..} = , configFullyStaticExe = packageConfigFullyStaticExe , configProfExe = packageConfigProfExe , configProf = packageConfigProf + , configProfShared = packageConfigProfShared , configProfDetail = packageConfigProfDetail , configProfLibDetail = packageConfigProfLibDetail , configConfigureArgs = packageConfigConfigureArgs @@ -1545,11 +1548,13 @@ legacyPackageConfigFieldDescrs = , "program-suffix" , "library-vanilla" , "library-profiling" + , "library-vanilla" , "shared" , "static" , "executable-dynamic" , "executable-static" , "profiling" + , "profiling-shared" , "executable-profiling" , "profiling-detail" , "library-profiling-detail" diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs index 2a6f9589cbb..08c27b00a3d 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs @@ -265,6 +265,7 @@ data PackageConfig = PackageConfig , packageConfigFullyStaticExe :: Flag Bool , packageConfigProf :: Flag Bool -- TODO: [code cleanup] sort out , packageConfigProfLib :: Flag Bool -- this duplication + , packageConfigProfShared :: Flag Bool , packageConfigProfExe :: Flag Bool -- and consistency , packageConfigProfDetail :: Flag ProfDetailLevel , packageConfigProfLibDetail :: Flag ProfDetailLevel diff --git a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs index 2d963b0e07f..7f26ac12382 100644 --- a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs +++ b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs @@ -1061,7 +1061,7 @@ printPlan nubFlag x (Setup.Flag x') | x == x' = Setup.NoFlag nubFlag _ f = f - (tryLibProfiling, tryExeProfiling) = + (tryLibProfiling, tryLibProfilingShared, tryExeProfiling) = computeEffectiveProfiling fullConfigureFlags partialConfigureFlags = @@ -1072,7 +1072,8 @@ printPlan nubFlag tryExeProfiling (configProfExe fullConfigureFlags) , configProfLib = nubFlag tryLibProfiling (configProfLib fullConfigureFlags) - -- Maybe there are more we can add + , configProfShared = + nubFlag tryLibProfilingShared (configProfShared fullConfigureFlags) } in -- Not necessary to "escape" it, it's just for user output unwords . ("" :) $ diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index efc4ebbd1e4..d0f696be957 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -165,6 +165,8 @@ import Distribution.Simple.LocalBuildInfo , componentName , pkgComponents ) + +import Distribution.Simple.BuildWay import Distribution.Simple.PackageIndex (InstalledPackageIndex) import Distribution.Simple.Program import Distribution.Simple.Program.Db @@ -1627,13 +1629,18 @@ elaborateInstallPlan (map fst src_comps) let whyNotPerComp = why_not_per_component src_comps case NE.nonEmpty whyNotPerComp of - Nothing -> return comps + Nothing -> do + elaborationWarnings + return comps Just notPerCompReasons -> do checkPerPackageOk comps notPerCompReasons - return - [ elaborateSolverToPackage notPerCompReasons spkg g $ - comps ++ maybeToList setupComponent - ] + pkgComp <- + elaborateSolverToPackage + notPerCompReasons + spkg + g + (comps ++ maybeToList setupComponent) + return [pkgComp] Left cns -> dieProgress $ hang @@ -1696,7 +1703,7 @@ elaborateInstallPlan <+> fsep (punctuate comma $ map (text . whyNotPerComponent) $ toList reasons) -- TODO: Maybe exclude Backpack too - elab0 = elaborateSolverToCommon spkg + (elab0, elaborationWarnings) = elaborateSolverToCommon spkg pkgid = elabPkgSourceId elab0 pd = elabPkgDescription elab0 @@ -1992,7 +1999,7 @@ elaborateInstallPlan -> SolverPackage UnresolvedPkgLoc -> ComponentsGraph -> [ElaboratedConfiguredPackage] - -> ElaboratedConfiguredPackage + -> LogProgress ElaboratedConfiguredPackage elaborateSolverToPackage pkgWhyNotPerComponent pkg@( SolverPackage @@ -2003,13 +2010,14 @@ elaborateInstallPlan _exe_deps0 ) compGraph - comps = + comps = do -- Knot tying: the final elab includes the -- pkgInstalledId, which is calculated by hashing many -- of the other fields of the elaboratedPackage. - elab + elaborationWarnings + return elab where - elab0@ElaboratedConfiguredPackage{..} = + (elab0@ElaboratedConfiguredPackage{..}, elaborationWarnings) = elaborateSolverToCommon pkg elab1 = @@ -2095,7 +2103,7 @@ elaborateInstallPlan elaborateSolverToCommon :: SolverPackage UnresolvedPkgLoc - -> ElaboratedConfiguredPackage + -> (ElaboratedConfiguredPackage, LogProgress ()) elaborateSolverToCommon pkg@( SolverPackage (SourcePackage pkgid gdesc srcloc descOverride) @@ -2104,7 +2112,7 @@ elaborateInstallPlan deps0 _exe_deps0 ) = - elaboratedPackage + (elaboratedPackage, wayWarnings pkgid) where elaboratedPackage = ElaboratedConfiguredPackage{..} @@ -2212,13 +2220,14 @@ elaborateInstallPlan elabBuildOptions = LBC.BuildOptions { withVanillaLib = perPkgOptionFlag pkgid True packageConfigVanillaLib -- TODO: [required feature]: also needs to be handled recursively - , withSharedLib = pkgid `Set.member` pkgsUseSharedLibrary + , withSharedLib = canBuildSharedLibs && pkgid `Set.member` pkgsUseSharedLibrary , withStaticLib = perPkgOptionFlag pkgid False packageConfigStaticLib , withDynExe = perPkgOptionFlag pkgid False packageConfigDynExe , withFullyStaticExe = perPkgOptionFlag pkgid False packageConfigFullyStaticExe , withGHCiLib = perPkgOptionFlag pkgid False packageConfigGHCiLib -- TODO: [required feature] needs to default to enabled on windows still , withProfExe = perPkgOptionFlag pkgid False packageConfigProf - , withProfLib = pkgid `Set.member` pkgsUseProfilingLibrary + , withProfLib = canBuildProfilingLibs && pkgid `Set.member` pkgsUseProfilingLibrary + , withProfLibShared = canBuildProfilingSharedLibs && pkgid `Set.member` pkgsUseProfilingLibraryShared , exeCoverage = perPkgOptionFlag pkgid False packageConfigCoverage , libCoverage = perPkgOptionFlag pkgid False packageConfigCoverage , withOptimization = perPkgOptionFlag pkgid NormalOptimisation packageConfigOptimization @@ -2377,35 +2386,112 @@ elaborateInstallPlan pkgsUseSharedLibrary :: Set PackageId pkgsUseSharedLibrary = packagesWithLibDepsDownwardClosedProperty needsSharedLib + + needsSharedLib pkgid = + fromMaybe + compilerShouldUseSharedLibByDefault + -- Case 1: --enable-shared or --disable-shared is passed explicitly, honour that. + ( case pkgSharedLib of + Just v -> Just v + Nothing -> case pkgDynExe of + -- case 2: If --enable-executable-dynamic is passed then turn on + -- shared library generation. + Just True -> + -- Case 3: If --enable-profiling is passed, then we are going to + -- build profiled dynamic, so no need for shared libraries. + case pkgProf of + Just True -> if canBuildProfilingSharedLibs then Nothing else Just True + _ -> Just True + -- But don't necessarily turn off shared library generation if + -- --disable-executable-dynamic is passed. The shared objects might + -- be needed for something different. + _ -> Nothing + ) where - needsSharedLib pkg = - fromMaybe - compilerShouldUseSharedLibByDefault - (liftM2 (||) pkgSharedLib pkgDynExe) - where - pkgid = packageId pkg - pkgSharedLib = perPkgOptionMaybe pkgid packageConfigSharedLib - pkgDynExe = perPkgOptionMaybe pkgid packageConfigDynExe + pkgSharedLib = perPkgOptionMaybe pkgid packageConfigSharedLib + pkgDynExe = perPkgOptionMaybe pkgid packageConfigDynExe + pkgProf = perPkgOptionMaybe pkgid packageConfigProf -- TODO: [code cleanup] move this into the Cabal lib. It's currently open -- coded in Distribution.Simple.Configure, but should be made a proper -- function of the Compiler or CompilerInfo. compilerShouldUseSharedLibByDefault = case compilerFlavor compiler of - GHC -> GHC.isDynamic compiler + GHC -> GHC.compilerBuildWay compiler == DynWay && canBuildSharedLibs GHCJS -> GHCJS.isDynamic compiler _ -> False + compilerShouldUseProfilingLibByDefault = + case compilerFlavor compiler of + GHC -> GHC.compilerBuildWay compiler == ProfWay && canBuildProfilingLibs + _ -> False + + compilerShouldUseProfilingSharedLibByDefault = + case compilerFlavor compiler of + GHC -> GHC.compilerBuildWay compiler == ProfDynWay && canBuildProfilingSharedLibs + _ -> False + + -- Returns False if we definitely can't build shared libs + canBuildWayLibs predicate = case predicate compiler of + Just can_build -> can_build + -- If we don't know for certain, just assume we can + -- which matches behaviour in previous cabal releases + Nothing -> True + + canBuildSharedLibs = canBuildWayLibs dynamicSupported + canBuildProfilingLibs = canBuildWayLibs profilingVanillaSupported + canBuildProfilingSharedLibs = canBuildWayLibs profilingDynamicSupported + + wayWarnings pkg = do + when + (needsProfilingLib pkg && not canBuildProfilingLibs) + (warnProgress (text "Compiler does not support building p libraries, profiling is disabled")) + when + (needsSharedLib pkg && not canBuildSharedLibs) + (warnProgress (text "Compiler does not support building dyn libraries, dynamic libraries are disabled")) + when + (needsProfilingLibShared pkg && not canBuildProfilingSharedLibs) + (warnProgress (text "Compiler does not support building p_dyn libraries, profiling dynamic libraries are disabled.")) + pkgsUseProfilingLibrary :: Set PackageId pkgsUseProfilingLibrary = packagesWithLibDepsDownwardClosedProperty needsProfilingLib + + needsProfilingLib pkg = + fromFlagOrDefault compilerShouldUseProfilingLibByDefault (profBothFlag <> profLibFlag) where - needsProfilingLib pkg = - fromFlagOrDefault False (profBothFlag <> profLibFlag) - where - pkgid = packageId pkg - profBothFlag = lookupPerPkgOption pkgid packageConfigProf - profLibFlag = lookupPerPkgOption pkgid packageConfigProfLib + pkgid = packageId pkg + profBothFlag = lookupPerPkgOption pkgid packageConfigProf + profLibFlag = lookupPerPkgOption pkgid packageConfigProfLib + + pkgsUseProfilingLibraryShared :: Set PackageId + pkgsUseProfilingLibraryShared = + packagesWithLibDepsDownwardClosedProperty needsProfilingLibShared + + needsProfilingLibShared pkg = + fromMaybe + compilerShouldUseProfilingSharedLibByDefault + -- case 1: If --enable-profiling-shared is passed explicitly, honour that + ( case profLibSharedFlag of + Just v -> Just v + Nothing -> case pkgDynExe of + Just True -> + case pkgProf of + -- case 2: --enable-executable-dynamic + --enable-profiling + -- turn on shared profiling libraries + Just True -> if canBuildProfilingSharedLibs then Just True else Nothing + _ -> Nothing + -- But don't necessarily turn off shared library generation is + -- --disable-executable-dynamic is passed. The shared objects might + -- be needed for something different. + _ -> Nothing + ) + where + pkgid = packageId pkg + profLibSharedFlag = perPkgOptionMaybe pkgid packageConfigProfShared + pkgDynExe = perPkgOptionMaybe pkgid packageConfigDynExe + pkgProf = perPkgOptionMaybe pkgid packageConfigProf + -- TODO: [code cleanup] unused: the old deprecated packageConfigProfExe libDepGraph = @@ -2422,7 +2508,7 @@ elaborateInstallPlan libDepGraph [ Graph.nodeKey pkg | pkg <- SolverInstallPlan.toList solverPlan - , property pkg -- just the packages that satisfy the property + , property (packageId pkg) -- just the packages that satisfy the property -- TODO: [nice to have] this does not check the config consistency, -- e.g. a package explicitly turning off profiling, but something -- depending on it that needs profiling. This really needs a separate @@ -3837,7 +3923,7 @@ setupHsConfigureFlags sanityCheckElaboratedConfiguredPackage sharedConfig elab - (Cabal.ConfigFlags{..}) + Cabal.ConfigFlags{..} where Cabal.ConfigFlags { configVanillaLib @@ -3848,6 +3934,7 @@ setupHsConfigureFlags , configGHCiLib , -- , configProfExe -- overridden configProfLib + , configProfShared , -- , configProf -- overridden configProfDetail , configProfLibDetail diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index 8fea76bae3b..0df20fb4569 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -679,7 +679,7 @@ filterConfigureFlags' :: ConfigFlags -> Version -> ConfigFlags filterConfigureFlags' flags cabalLibVersion -- NB: we expect the latest version to be the most common case, -- so test it first. - | cabalLibVersion >= mkVersion [3, 11, 0] = flags_latest + | cabalLibVersion >= mkVersion [3, 13, 0] = flags_latest -- The naming convention is that flags_version gives flags with -- all flags *introduced* in version eliminated. -- It is NOT the latest version of Cabal library that @@ -701,6 +701,7 @@ filterConfigureFlags' flags cabalLibVersion | cabalLibVersion < mkVersion [2, 5, 0] = flags_2_5_0 | cabalLibVersion < mkVersion [3, 7, 0] = flags_3_7_0 | cabalLibVersion < mkVersion [3, 11, 0] = flags_3_11_0 + | cabalLibVersion < mkVersion [3, 13, 0] = flags_3_13_0 | otherwise = error "the impossible just happened" -- see first guard where flags_latest = @@ -712,8 +713,15 @@ filterConfigureFlags' flags cabalLibVersion configConstraints = [] } - flags_3_11_0 = + flags_3_13_0 = + -- Earlier Cabal versions don't understand about .. flags_latest + { -- Building profiled shared libraries + configProfShared = NoFlag + } + + flags_3_11_0 = + flags_3_13_0 { -- It's too late to convert configPromisedDependencies to anything -- meaningful, so we just assert that it's empty. -- We add a Cabal>=3.11 constraint before solving when multi-repl is @@ -783,7 +791,7 @@ filterConfigureFlags' flags cabalLibVersion -- Cabal < 1.23 doesn't know about '--profiling-detail'. -- Cabal < 1.23 has a hacked up version of 'enable-profiling' -- which we shouldn't use. - (tryLibProfiling, tryExeProfiling) = computeEffectiveProfiling flags + (tryLibProfiling, _tryLibProfilingShared, tryExeProfiling) = computeEffectiveProfiling flags flags_1_23_0 = flags_1_25_0 { configProfDetail = NoFlag diff --git a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs index 946e0bf48fd..2c4de05a9a2 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs @@ -683,6 +683,7 @@ instance Arbitrary PackageConfig where <*> arbitrary <*> arbitrary <*> arbitrary + <*> arbitrary <*> shortListOf 5 arbitraryShortToken <*> arbitrary <*> arbitrary @@ -751,6 +752,7 @@ instance Arbitrary PackageConfig where , packageConfigFullyStaticExe = x50 , packageConfigProf = x07 , packageConfigProfLib = x08 + , packageConfigProfShared = x08_1 , packageConfigProfExe = x09 , packageConfigProfDetail = x10 , packageConfigProfLibDetail = x11 @@ -814,6 +816,7 @@ instance Arbitrary PackageConfig where , packageConfigFullyStaticExe = x50' , packageConfigProf = x07' , packageConfigProfLib = x08' + , packageConfigProfShared = x08_1' , packageConfigProfExe = x09' , packageConfigProfDetail = x10' , packageConfigProfLibDetail = x11' @@ -866,7 +869,7 @@ instance Arbitrary PackageConfig where , packageConfigBenchmarkOptions = x52' } | ( ( (x00', x01', x02', x03', x04') - , (x05', x42', x06', x50', x07', x08', x09') + , (x05', x42', x06', x50', x07', x08', x08_1', x09') , (x10', x11', x12', x13', x14') , (x15', x16', x53', x17', x18', x19') ) @@ -883,7 +886,7 @@ instance Arbitrary PackageConfig where shrink ( ( (preShrink_Paths x00, preShrink_Args x01, x02, x03, x04) - , (x05, x42, x06, x50, x07, x08, x09) + , (x05, x42, x06, x50, x07, x08, x08_1, x09) , (x10, x11, map NonEmpty x12, x13, x14) , ( x15 diff --git a/cabal-testsuite/PackageTests/ProfShared/Lib.hs b/cabal-testsuite/PackageTests/ProfShared/Lib.hs new file mode 100644 index 00000000000..516d174a825 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProfShared/Lib.hs @@ -0,0 +1,3 @@ +module Lib where + +lib = 10 diff --git a/cabal-testsuite/PackageTests/ProfShared/exe/Prof.hs b/cabal-testsuite/PackageTests/ProfShared/exe/Prof.hs new file mode 100644 index 00000000000..200915ffefa --- /dev/null +++ b/cabal-testsuite/PackageTests/ProfShared/exe/Prof.hs @@ -0,0 +1,5 @@ +module Main where + +import Lib + +main = print lib diff --git a/cabal-testsuite/PackageTests/ProfShared/profShared.cabal b/cabal-testsuite/PackageTests/ProfShared/profShared.cabal new file mode 100644 index 00000000000..ef348cfecc6 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProfShared/profShared.cabal @@ -0,0 +1,13 @@ +Cabal-Version: 3.8 +Name: prof-shared +Version: 0.1 +Build-Type: Simple + +library + exposed-modules: Lib + Build-Depends: base + +executable Prof + main-is: Prof.hs + hs-source-dirs: exe + build-depends: base, prof-shared diff --git a/cabal-testsuite/PackageTests/ProfShared/setup.test.hs b/cabal-testsuite/PackageTests/ProfShared/setup.test.hs new file mode 100644 index 00000000000..754ff7a290d --- /dev/null +++ b/cabal-testsuite/PackageTests/ProfShared/setup.test.hs @@ -0,0 +1,145 @@ +import Test.Cabal.Prelude +import Data.List +import Data.Bifunctor + +data BuildWay = StaticWay | DynWay | ProfWay | ProfDynWay + deriving (Eq, Ord, Show, Read, Enum) + +-- Test building with profiling shared support +main = do + setupTest $ recordMode DoNotRecord $ do + has_prof_shared <- hasProfiledSharedLibraries + has_shared <- hasSharedLibraries + -- Tests are not robust against missing dynamic libraries yet. Would + -- be better to fix this. + skipUnless "Missing shared libraries" has_shared + + let analyse_result expected r = do + + let ls = lines (resultOutput r) + + library_prefix = "Wanted build ways(True): " + executable_prefix = "Wanted build ways(False): " + + get_ways prefix = map (drop (length prefix)) (filter (prefix `isPrefixOf`) ls) + library_ways = read_ways (get_ways library_prefix) + executable_ways = read_ways (get_ways executable_prefix) + + read_ways raw_ways = + case raw_ways of + -- There should only be one + [x] -> (read :: String -> [BuildWay]) x + -- Unless there are none, when we don't built the executable for example + [] -> [] + xs -> error "Unexpected number of log lines" + + way = (library_ways, executable_ways) + + unless (bimap (nub . sort) (nub . sort) expected == bimap (nub . sort) (nub . sort) way) $ + assertFailure $ "Expected:" ++ show expected ++ "\n" ++ "Got:" ++ show way + + requireSuccess r + setupTest $ recordMode DoNotRecord $ do + + has_prof_shared <- hasProfiledSharedLibraries + has_shared <- hasSharedLibraries + + let v = [ StaticWay ] + dyn = [ DynWay | has_shared ] + p_dyn = if has_prof_shared then [ProfDynWay] else p + p = [ ProfWay ] + none = [] + + let run_test args expected = do + setup "configure" args + res <- setup' "build" [] + analyse_result expected res + setup "clean" [] + + + run_test [] + (v <> dyn, v) + + + run_test ["--disable-library-vanilla", "--enable-executable-dynamic"] + (dyn, dyn) + + run_test ["--enable-profiling-shared"] + (v <> dyn <> p_dyn, v) + + run_test ["--enable-profiling-shared", "--enable-executable-dynamic"] + (v <> dyn <> p_dyn, dyn) + + run_test ["--enable-executable-dynamic", "--disable-library-vanilla"] + (dyn, dyn) + + run_test ["--enable-profiling"] + (v <> dyn <> p, p) + + run_test ["--enable-executable-profiling"] + (v <> dyn <> p, p) + + run_test ["--enable-executable-profiling", "--enable-executable-dynamic"] + (v <> dyn <> p_dyn, p_dyn) + + run_test ["--enable-profiling", "--enable-executable-dynamic"] + (v <> dyn <> p_dyn, p_dyn) + + --v dyn p (p exe) + run_test ["--enable-library-profiling", "--enable-executable-profiling"] + (v <> dyn <> p, p) + + run_test ["prof-shared", "--enable-profiling-shared", "--disable-library-vanilla", "--disable-shared"] + (p_dyn, none) + + -- p p_dyn + run_test ["prof-shared", "--enable-profiling-shared", "--enable-library-profiling", "--disable-library-vanilla", "--disable-shared"] + (p <> p_dyn, []) + + -- v p p_dyn + run_test ["prof-shared","--enable-profiling-shared", "--enable-library-profiling", "--enable-library-vanilla", "--disable-shared"] + (v <> p <> p_dyn, none) + + -- v dyn p p_dyn + run_test ["prof-shared", "--enable-profiling-shared", "--enable-library-profiling", "--enable-library-vanilla", "--enable-shared"] + (v <> dyn <> p <> p_dyn, none) + + let run_cabal_test args expected = cabalTest $ recordMode DoNotRecord $ do + has_prof_shared <- hasProfiledSharedLibraries + has_shared <- hasSharedLibraries + -- See GHC commit e400b9babdcf11669f963aeec20078fe7ccfca0d + -- Only installing profiled library is broken on very old ghc-pkg versions + broken_ghc_pkg <- isGhcVersion "<= 8.6.5" + + let cvt_l StaticWay = [ StaticWay ] + cvt_l DynWay = [ DynWay | has_shared ] + cvt_l ProfDynWay = [ProfDynWay | has_prof_shared ] + cvt_l ProfWay = [ ProfWay ] + + let cvt_e StaticWay = StaticWay + cvt_e DynWay = if has_shared then DynWay else error "DynWay" + cvt_e ProfDynWay = if has_prof_shared then ProfDynWay else ProfWay + cvt_e ProfWay = ProfWay + + unless (broken_ghc_pkg && (fst expected == [ProfWay])) $ do + res <- cabal' "v2-build" args + void $ analyse_result (bimap (concatMap cvt_l) (map cvt_e) expected) res + + run_cabal_test ["--disable-shared"] ([StaticWay], [StaticWay]) + run_cabal_test ["--disable-shared", "--disable-executable-dynamic"] ([StaticWay], [StaticWay]) + run_cabal_test ["--enable-shared"] ([DynWay, StaticWay], [StaticWay]) + run_cabal_test ["--enable-executable-dynamic"] ([DynWay, StaticWay], [DynWay]) + run_cabal_test ["--enable-shared", "--disable-library-vanilla", "--enable-executable-dynamic"] ([DynWay], [DynWay]) + + run_cabal_test ["--disable-shared", "--disable-library-vanilla", "--enable-profiling"] ([ProfWay], [ProfWay]) + + run_cabal_test ["--disable-shared", "--enable-profiling"] ([ProfWay, StaticWay], [ProfWay]) + + run_cabal_test ["--disable-shared", "--enable-profiling-shared", "--enable-profiling"] ([ProfDynWay, ProfWay, StaticWay], [ProfWay]) + + run_cabal_test ["--disable-shared", "--enable-profiling", "--enable-profiling-shared", "--enable-executable-dynamic"] ([ProfWay, ProfDynWay, StaticWay], [ProfDynWay]) + + run_cabal_test ["--enable-profiling", "--enable-executable-dynamic"] ([ProfDynWay, ProfWay, DynWay, StaticWay], [ProfDynWay]) + + run_cabal_test ["prof-shared", "--disable-library-profiling", "--enable-profiling", "--enable-executable-dynamic"] ([ProfDynWay, DynWay, StaticWay], []) + diff --git a/cabal-testsuite/PackageTests/ProfSharedWarning/Lib.hs b/cabal-testsuite/PackageTests/ProfSharedWarning/Lib.hs new file mode 100644 index 00000000000..516d174a825 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProfSharedWarning/Lib.hs @@ -0,0 +1,3 @@ +module Lib where + +lib = 10 diff --git a/cabal-testsuite/PackageTests/ProfSharedWarning/cabal.project b/cabal-testsuite/PackageTests/ProfSharedWarning/cabal.project new file mode 100644 index 00000000000..e6fdbadb439 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProfSharedWarning/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/cabal-testsuite/PackageTests/ProfSharedWarning/exe/Prof.hs b/cabal-testsuite/PackageTests/ProfSharedWarning/exe/Prof.hs new file mode 100644 index 00000000000..200915ffefa --- /dev/null +++ b/cabal-testsuite/PackageTests/ProfSharedWarning/exe/Prof.hs @@ -0,0 +1,5 @@ +module Main where + +import Lib + +main = print lib diff --git a/cabal-testsuite/PackageTests/ProfSharedWarning/profShared.cabal b/cabal-testsuite/PackageTests/ProfSharedWarning/profShared.cabal new file mode 100644 index 00000000000..ef348cfecc6 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProfSharedWarning/profShared.cabal @@ -0,0 +1,13 @@ +Cabal-Version: 3.8 +Name: prof-shared +Version: 0.1 +Build-Type: Simple + +library + exposed-modules: Lib + Build-Depends: base + +executable Prof + main-is: Prof.hs + hs-source-dirs: exe + build-depends: base, prof-shared diff --git a/cabal-testsuite/PackageTests/ProfSharedWarning/setup.out b/cabal-testsuite/PackageTests/ProfSharedWarning/setup.out new file mode 100644 index 00000000000..66512712837 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProfSharedWarning/setup.out @@ -0,0 +1,3 @@ +# Setup configure +Configuring prof-shared-0.1... +Warning: Executables will use dynamic linking, but a shared library is not being built. Linking will fail if any executables depend on the library. diff --git a/cabal-testsuite/PackageTests/ProfSharedWarning/setup_prof.out b/cabal-testsuite/PackageTests/ProfSharedWarning/setup_prof.out new file mode 100644 index 00000000000..ad201b3b391 --- /dev/null +++ b/cabal-testsuite/PackageTests/ProfSharedWarning/setup_prof.out @@ -0,0 +1,4 @@ +# Setup configure +Configuring prof-shared-0.1... +Warning: The flag --enable-executable-profiling is deprecated. Please use --enable-profiling instead. +Warning: Executables will use profiled dynamic linking, but a profiled shared library is not being built. Linking will fail if any executables depend on the library. diff --git a/cabal-testsuite/src/Test/Cabal/Prelude.hs b/cabal-testsuite/src/Test/Cabal/Prelude.hs index b72e427c91b..d110bd9f433 100644 --- a/cabal-testsuite/src/Test/Cabal/Prelude.hs +++ b/cabal-testsuite/src/Test/Cabal/Prelude.hs @@ -834,22 +834,22 @@ getScriptCacheDirectory script = do ------------------------------------------------------------------------ -- * Skipping tests -hasSharedLibraries :: TestM Bool -hasSharedLibraries = do - shared_libs_were_removed <- isGhcVersion ">= 7.8" - return (not (buildOS == Windows && shared_libs_were_removed)) - -hasProfiledLibraries :: TestM Bool -hasProfiledLibraries = do +testCompilerWithArgs :: [String] -> TestM Bool +testCompilerWithArgs args = do env <- getTestEnv ghc_path <- programPathM ghcProgram let prof_test_hs = testWorkDir env "Prof.hs" liftIO $ writeFile prof_test_hs "module Prof where" r <- liftIO $ run (testVerbosity env) (Just $ testCurrentDir env) - (testEnvironment env) ghc_path ["-prof", "-c", prof_test_hs] + (testEnvironment env) ghc_path (["-c", prof_test_hs] ++ args) Nothing return (resultExitCode r == ExitSuccess) +hasProfiledLibraries, hasProfiledSharedLibraries, hasSharedLibraries :: TestM Bool +hasProfiledLibraries = testCompilerWithArgs ["-prof"] +hasProfiledSharedLibraries = testCompilerWithArgs ["-prof", "-dynamic"] +hasSharedLibraries = testCompilerWithArgs ["-dynamic"] + -- | Check if the GHC that is used for compiling package tests has -- a shared library of the cabal library under test in its database. -- diff --git a/changelog.d/issue-4816 b/changelog.d/issue-4816 new file mode 100644 index 00000000000..e0ac7700b7e --- /dev/null +++ b/changelog.d/issue-4816 @@ -0,0 +1,23 @@ +synopsis: Add support for building profiled dynamic way +packages: Cabal Cabal-syntax cabal-install +prs: #9900 +issues: #4816 + +description: { +Add support for profiled dynamic way + +New options for cabal.project and ./Setup interface: + +* `profiling-shared`: Enable building profiling dynamic way +* Passing `--enable-profiling` and `--enable-executable-dynamic` builds + profiled dynamic executables. + +Support for using `profiling-shared` is guarded behind a constraint +which ensures you are using `Cabal >= 3.13`. + +In the cabal file: + +* `ghc-prof-shared-options`, for passing options when building in + profiling dynamic way + +} diff --git a/changelog.d/issue-4816-2 b/changelog.d/issue-4816-2 new file mode 100644 index 00000000000..96307c3f83e --- /dev/null +++ b/changelog.d/issue-4816-2 @@ -0,0 +1,26 @@ +synopsis: Fix interaction of `--*-shared` and `--*-executable-dynamic` options. +packages: cabal-install +prs: #9900 +issues: #10050 + +description: { + +If you explicitly request `--disable-shared` it should disable the building of +a shared library and override any automatic ways this option is turned on. + +Passing `--enable-executable-dynamic` turns on `--enable-shared` if the option is +not specified explicitly. + +Before this patch, writing `--disable-shared` on its own would not disable the building of shared libraries. Writing `--disable-shared` and `--disable-executable-dynamic` would disable shared library +creation (despite `--disable-executable-dynamic` being the default). + +Now: + +* If you specify `--enable-shared` then shared objects are built. +* If you specify `--disabled-shared` then shared objects are not built. +* If you don't explicitly specify whether you want to build shared libraries then + * `--enable-executable-dynamic` will automatically turn on building shared libraries + * `--enable-executable-dynamic --enable-profiling` will automatically turn on building + shared profiling libraries (if supported by your compiler). + +} diff --git a/doc/buildinfo-fields-reference.rst b/doc/buildinfo-fields-reference.rst index c1ccf418f81..cfabe5ee448 100644 --- a/doc/buildinfo-fields-reference.rst +++ b/doc/buildinfo-fields-reference.rst @@ -387,6 +387,14 @@ ghc-prof-options .. math:: {\left\{ \mathop{\mathit{hs\text{-}string}}\mid{{[\mathop{\mathord{``}\mathtt{\ }\mathord{"}}]^c}}^+_{} \right\}}^\ast_{\bullet} +ghc-prof-shared-options + * Monoidal field + * Available since ``cabal-version: 3.14``. + * Documentation of :pkg-field:`library:ghc-prof-shared-options` + + .. math:: + {\left\{ \mathop{\mathit{hs\text{-}string}}\mid{{[\mathop{\mathord{``}\mathtt{\ }\mathord{"}}]^c}}^+_{} \right\}}^\ast_{\bullet} + ghc-shared-options * Monoidal field * Documentation of :pkg-field:`library:ghc-shared-options` @@ -408,6 +416,14 @@ ghcjs-prof-options .. math:: {\left\{ \mathop{\mathit{hs\text{-}string}}\mid{{[\mathop{\mathord{``}\mathtt{\ }\mathord{"}}]^c}}^+_{} \right\}}^\ast_{\bullet} +ghcjs-prof-shared-options + * Monoidal field + * Available since ``cabal-version: 3.14``. + * Documentation of :pkg-field:`library:ghcjs-prof-shared-options` + + .. math:: + {\left\{ \mathop{\mathit{hs\text{-}string}}\mid{{[\mathop{\mathord{``}\mathtt{\ }\mathord{"}}]^c}}^+_{} \right\}}^\ast_{\bullet} + ghcjs-shared-options * Monoidal field * Documentation of :pkg-field:`library:ghcjs-shared-options` diff --git a/doc/cabal-package-description-file.rst b/doc/cabal-package-description-file.rst index 450ddc0c0d3..d560b69e05d 100644 --- a/doc/cabal-package-description-file.rst +++ b/doc/cabal-package-description-file.rst @@ -1930,6 +1930,13 @@ system-dependent values for these fields. ones specified via :pkg-field:`ghc-options`, and are passed to GHC during both the compile and link phases. +.. pkg-field:: ghc-prof-shared-options: token list + + Additional options for GHC when the package is built as shared profiling + library. The options specified via this field are combined with the + ones specified via :pkg-field:`ghc-options`, and are passed to GHC during + both the compile and link phases. + .. pkg-field:: ghcjs-options: token list Like :pkg-field:`ghc-options` but applies to GHCJS @@ -1942,6 +1949,10 @@ system-dependent values for these fields. Like :pkg-field:`ghc-shared-options` but applies to GHCJS +.. pkg-field:: ghcjs-prof-shared-options: token list + + Like :pkg-field:`ghc-prof-shared-options` but applies to GHCJS + .. pkg-field:: includes: filename list A list of header files to be included in any compilations via C. diff --git a/doc/setup-commands.rst b/doc/setup-commands.rst index 20bdafabfae..5ed8077f46b 100644 --- a/doc/setup-commands.rst +++ b/doc/setup-commands.rst @@ -795,10 +795,21 @@ Miscellaneous options Build shared library. This implies a separate compiler run to generate position independent code as required on most platforms. + ``--enable-shared`` is enabled automatically if GHC is dynamically linked or + you request to build dynamic executables. + .. option:: --disable-shared (default) Do not build shared library. +.. option:: --enable-profiling-shared + + Build a profiling shared library. + +.. option:: --disable-profiling-shared + + (default) Do not built a profiling shared library. + .. option:: --enable-static Build a static library. This passes ``-staticlib`` to GHC (available From 06a5280c8d47f16236a14813bbe32aaf0ffc2faa Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 10:28:04 +0000 Subject: [PATCH 022/207] Changelogs for 3.12.1.0 (backport #10124) (#10132) * Changelogs for 3.12.1.0 (#10124) * changelog for 3.12.1.0 * fixup! changelog for 3.12.1.0 * fixup! Changelogs for 3.12.1.0 Co-authored-by: Artem Pelenitsyn * fixup! changelog for 3.12.1.0 * fixup! changelog for 3.12.1.0 * fixup! Changelogs for 3.12.1.0 Co-authored-by: ffaf1 * fixup! Changelogs for 3.12.1.0 * fixup! Changelogs for 3.12.1.0 * fixup! Changelogs for 3.12.1.0 --------- Co-authored-by: Artem Pelenitsyn Co-authored-by: ffaf1 (cherry picked from commit 2067ed198d6def8feb7c41512aa99406ebb202e3) # Conflicts: # release-notes/Cabal-3.12.0.0.md * fixup! Changelogs for 3.12.1.0 (backport #10124) --------- Co-authored-by: brandon s allbery kf8nh Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- changelog.d/issue-10042 | 9 --- changelog.d/issue-10063 | 14 ----- changelog.d/issue-6750 | 13 ---- changelog.d/issue-8875 | 10 --- changelog.d/issue-9641 | 8 --- changelog.d/issue-9919 | 4 -- changelog.d/issue-9971 | 6 -- changelog.d/pr-10014 | 11 ---- changelog.d/pr-9766 | 11 ---- changelog.d/pr-9824 | 10 --- changelog.d/pr-9878 | 8 --- changelog.d/pr-9950 | 21 ------- release-notes/Cabal-3.12.0.0.md | 30 ++++----- release-notes/Cabal-3.12.1.0.md | 54 ++++++++++++++++ ...-3.12.x.0.md => cabal-install-3.12.1.0.md} | 62 +++++++++++++++---- 15 files changed, 118 insertions(+), 153 deletions(-) delete mode 100644 changelog.d/issue-10042 delete mode 100644 changelog.d/issue-10063 delete mode 100644 changelog.d/issue-6750 delete mode 100644 changelog.d/issue-8875 delete mode 100644 changelog.d/issue-9641 delete mode 100644 changelog.d/issue-9919 delete mode 100644 changelog.d/issue-9971 delete mode 100644 changelog.d/pr-10014 delete mode 100644 changelog.d/pr-9766 delete mode 100644 changelog.d/pr-9824 delete mode 100644 changelog.d/pr-9878 delete mode 100644 changelog.d/pr-9950 create mode 100644 release-notes/Cabal-3.12.1.0.md rename release-notes/{WIP-cabal-install-3.12.x.0.md => cabal-install-3.12.1.0.md} (83%) diff --git a/changelog.d/issue-10042 b/changelog.d/issue-10042 deleted file mode 100644 index e254210c028..00000000000 --- a/changelog.d/issue-10042 +++ /dev/null @@ -1,9 +0,0 @@ -synopsis: Don't recommend deprecated/removed 'extensions:' field -packages: Cabal -prs: #10044 -issues: #10042 - -description: { - When applicable, field 'default-extensions:' is recommended (rather than - deprecated/removed 'extensions:'). -} diff --git a/changelog.d/issue-10063 b/changelog.d/issue-10063 deleted file mode 100644 index 568ffe68a9b..00000000000 --- a/changelog.d/issue-10063 +++ /dev/null @@ -1,14 +0,0 @@ -synopsis: External commands now propagate exit code from child process -packages: cabal-install -prs: #10100 -issues: #10063 - -description: { - The exit code from an external command is now propagated as the exit code of - cabal-install when invoked by calling an external command. - - For example, if your external command exits with code 1, then cabal-install will - also exit with code 1. - - This mechanism can be used by an external command to signal failure. -} diff --git a/changelog.d/issue-6750 b/changelog.d/issue-6750 deleted file mode 100644 index e392258267b..00000000000 --- a/changelog.d/issue-6750 +++ /dev/null @@ -1,13 +0,0 @@ -synopsis: Make Setup copy/install succeed when there's no executable or library -packages: Cabal -prs: #9926 -issues: #6750 - -description: { - Historically the Setup copy and install steps would fail if the package didn't - contain an executable or library component. In this case there's nothing to do. - - This required workarounds for downstream users of Cabal to handle this edge case. - Now that this error has been downgraded to a warning, Cabal will succeed if - there's nothing to do. -} diff --git a/changelog.d/issue-8875 b/changelog.d/issue-8875 deleted file mode 100644 index 6642609a0e6..00000000000 --- a/changelog.d/issue-8875 +++ /dev/null @@ -1,10 +0,0 @@ -synopsis: Allow whitespace in targets -packages: cabal-install -prs: #10032 -issues: #8875 - -description: { -Allow spaces in the final component of target selectors. This resolves an issue -where using absolute paths in selectors can fail if there is whitespace in the -parent directories of the project. -} diff --git a/changelog.d/issue-9641 b/changelog.d/issue-9641 deleted file mode 100644 index 34666f0ad59..00000000000 --- a/changelog.d/issue-9641 +++ /dev/null @@ -1,8 +0,0 @@ -synopsis: offline flag applied to `source-repository-package`s -packages: Cabal-install -prs: #9771 -issues: #9641 - -description: { -`--offline` flag is already used to block access to Hackage. Now with this PR, this also applies to remote dependency `source-repository-package` in `cabal.project`. -} diff --git a/changelog.d/issue-9919 b/changelog.d/issue-9919 deleted file mode 100644 index a4fe32bbdef..00000000000 --- a/changelog.d/issue-9919 +++ /dev/null @@ -1,4 +0,0 @@ -synopsis: Fix --program-suffix resulting in invalid installation -packages: cabal-install -issues: #8823 #9919 -prs: #10056 diff --git a/changelog.d/issue-9971 b/changelog.d/issue-9971 deleted file mode 100644 index 9bfb2e4822f..00000000000 --- a/changelog.d/issue-9971 +++ /dev/null @@ -1,6 +0,0 @@ -synopsis: Renders project configuration provenance as a list of canonical paths -packages: cabal-install cabal-install-solver -prs: #9985 -issues: #9971 - -description: Removes interleaved rendering of project imports. diff --git a/changelog.d/pr-10014 b/changelog.d/pr-10014 deleted file mode 100644 index 541b4c72d18..00000000000 --- a/changelog.d/pr-10014 +++ /dev/null @@ -1,11 +0,0 @@ -synopsis: Update ghc args normalization and ghc option rendering -packages: Cabal -issues: #9729 -prs: #10014 - -description: { - -The flags -fdiagnostics-as-json, -fprint-error-index-lists, -fbreak-points, -dipe-stats, -ffamily-application-cache, -fprint-redundant-promotion-ticks, -fshow-error-context and -funoptimized-core-for-interpreter have been added to the flags that do not cause recompilation. - ---{enable,disable}-split-objs is not shown on in the helper for GHC >= 9.8 -} diff --git a/changelog.d/pr-9766 b/changelog.d/pr-9766 deleted file mode 100644 index 3d10abb659f..00000000000 --- a/changelog.d/pr-9766 +++ /dev/null @@ -1,11 +0,0 @@ -synopsis: Warn on missing `default-language` -packages: Cabalcabal-install -prs: #9766 -issues: #9620 - -description: { - -- To help the adoption of GHC language editions, `cabal check` will now - warn about missing `default-language`. - -} diff --git a/changelog.d/pr-9824 b/changelog.d/pr-9824 deleted file mode 100644 index 168b9c98e64..00000000000 --- a/changelog.d/pr-9824 +++ /dev/null @@ -1,10 +0,0 @@ -synopsis: Abbrevate solver rejection messages with installed versions -packages: cabal-install-solver -prs: #9824 -issues: #9823 - -description: { - -Abbreviate solver rejection messages even in the presence of installed versions. - -} diff --git a/changelog.d/pr-9878 b/changelog.d/pr-9878 deleted file mode 100644 index c4c5de13f61..00000000000 --- a/changelog.d/pr-9878 +++ /dev/null @@ -1,8 +0,0 @@ -synopsis: Add mhs as a known Haskell compiler -packages: Cabal -issues: -prs: #9878 - -description: { -This simply add MHS to the enumeration of known Haskell compilers. -} diff --git a/changelog.d/pr-9950 b/changelog.d/pr-9950 deleted file mode 100644 index a961c953639..00000000000 --- a/changelog.d/pr-9950 +++ /dev/null @@ -1,21 +0,0 @@ -synopsis: Re-instate `initialBuildSteps` -packages: Cabal -issues: #9856 -prs: #9950 - -description: { - -The `initialBuildSteps` function from `Distribution.Simple.Build`, which had -been hastily removed, has been reinstated. - -It now comes with a deprecation warning: calling that function does not suffice -to prepare the sources for a package, as there are other steps that one might -also need to perform: - - - running pre-processors (such as alex/happy) - - running pre-build hooks or custom logic - (in build-type: Hooks or build-type: Custom or Configure) - -Consumers wanting to prepare the sources of a package, e.g. in order to launch a -REPL session, are advised to run `setup repl --repl-multi-file=` instead. -} diff --git a/release-notes/Cabal-3.12.0.0.md b/release-notes/Cabal-3.12.0.0.md index f177338c6ec..4c4ff805ce9 100644 --- a/release-notes/Cabal-3.12.0.0.md +++ b/release-notes/Cabal-3.12.0.0.md @@ -55,7 +55,7 @@ Cabal and Cabal-syntax 3.12.0.0 changelog and release notes `filterPackageChecksById`, this can be used by third-party tools to filter warnings. -- Add support for `GHC2024` [#9736](https://github.com/haskell/cabal/issues/9736) +- Add support for `GHC2024` [#9736](https://github.com/haskell/cabal/issues/9736) [#9791](https://github.com/haskell/cabal/pull/9791) Support for the `GHC2024` language edition, introduced by GHC 9.10, has been added. It can now be used in the `default-language` and `other-languages` @@ -77,14 +77,18 @@ Cabal and Cabal-syntax 3.12.0.0 changelog and release notes Support for all previous GHC versions is deprecated. +- Label error messages with codes (following GHC, Stack) + + As with GHC and Stack, Cabal and cabal-install now generate warnings and errors prefixed with error codes of the form `[Cabal-xxxxx]`. These will be documented on https://errors.haskell.org, although very few are as yet. + ### Other changes -- `cabal init` should not suggest Cabal < 2.0 [#8680](https://github.com/haskell/cabal/issues/8680) +- `cabal init` should not suggest Cabal < 2.0 [#8680](https://github.com/haskell/cabal/issues/8680) [#8700](https://github.com/haskell/cabal/pull/8700) 'cabal init' no longer suggests users to set cabal-version to less than 2.0. -- Remove Distribution.Utils.TempTestDir module from Cabal library [#9453](https://github.com/haskell/cabal/issues/9453) [#9454](https://github.com/haskell/cabal/pull/9454) +- Remove `Distribution.Utils.TempTestDir` module from Cabal library [#9453](https://github.com/haskell/cabal/issues/9453) [#9454](https://github.com/haskell/cabal/pull/9454) This library was only used by internal tests, and now lives in the `Cabal-tests` library which is shared across test components. @@ -110,7 +114,7 @@ Cabal and Cabal-syntax 3.12.0.0 changelog and release notes - `checkPackage` signature has been simplified, you do not need to pass a specific configuration of the package, since - we do not flatten GenericPackageDescription any more. + we do not flatten `GenericPackageDescription` any more. - `checkPackageFileNames` has been removed, use `checkPackageFiles` instead. - `checkPackageFilesGPD` has been introduced, @@ -122,7 +126,7 @@ Cabal and Cabal-syntax 3.12.0.0 changelog and release notes GHC plugins now can store custom data in the 'extra-compilation-artifacts' directory which gets installed with the package. -- Add option to ./Setup repl to write repl arguments to file [#8726](https://github.com/haskell/cabal/pull/8726) +- Add option to `./Setup repl` to write repl arguments to file [#8726](https://github.com/haskell/cabal/pull/8726) The `./Setup repl` command is modified to allow a user to defer starting the repl and instead instruct the command to write the necessary build @@ -137,7 +141,7 @@ Cabal and Cabal-syntax 3.12.0.0 changelog and release notes Cabal: Distribution now recognises Haiku as a valid platform, and also implements Haiku's unique directory layout. -- Installation of .hie files [#8685](https://github.com/haskell/cabal/issues/8685) [#9019](https://github.com/haskell/cabal/pull/9019) +- Installation of `.hie` files [#8685](https://github.com/haskell/cabal/issues/8685) [#9019](https://github.com/haskell/cabal/pull/9019) Hie files generated by GHC are now stored in the `extra-compilation-artifacts` directory which gets installed with the @@ -180,7 +184,7 @@ Cabal and Cabal-syntax 3.12.0.0 changelog and release notes - Document `remote-repo-cache` as implemented. [#8737](https://github.com/haskell/cabal/issues/8737) [#8738](https://github.com/haskell/cabal/pull/8738) -- Deduplicate LD_LIBRARY_PATH when running tests [#8728](https://github.com/haskell/cabal/pull/8728) +- Deduplicate `LD_LIBRARY_PATH` when running tests [#8728](https://github.com/haskell/cabal/pull/8728) - Add support for a number of architectures: @@ -190,7 +194,7 @@ Cabal and Cabal-syntax 3.12.0.0 changelog and release notes - Don't report `index.html` file as created, if not created by Haddock [#5120](https://github.com/haskell/cabal/issues/5120) [#9332](https://github.com/haskell/cabal/pull/9332) -- Enable using $ORIGIN in RPATH on GNU/Hurd [#9441](https://github.com/haskell/cabal/pull/9441) +- Enable using `$ORIGIN` in `RPATH` on GNU/Hurd [#9441](https://github.com/haskell/cabal/pull/9441) - Make check comply with Hackage requirements [#8897](https://github.com/haskell/cabal/pull/8897) @@ -198,13 +202,11 @@ Cabal and Cabal-syntax 3.12.0.0 changelog and release notes - `cabal check` will only return exitcode 1 when the package is not fit for Hackage. E.g. it will not error anymore when your `synopsis:` is larger than `description:`, just emit a warning. - - Cabal: Distribution.Client.Check now exports `isHackageDistError`, for + - Cabal: `Distribution.Client.Check` now exports `isHackageDistError`, for third-party tools to know if a specific error will preclude a package from being uploaded to Hacakge. -- Add language extension `ExtendedLiterals` [#8992](https://github.com/haskell/cabal/pull/8992) - - Adds support for the `ExtendedLiterals` language extension (GHC proposal #451) +- Add language extension `ExtendedLiterals` (GHC proposal #451) [#8992](https://github.com/haskell/cabal/pull/8992) - Warn about inconsistent indentation [#8975](https://github.com/haskell/cabal/pull/8975) @@ -253,9 +255,7 @@ Cabal and Cabal-syntax 3.12.0.0 changelog and release notes `cabal` invokes `pkg-config` individually for each lib if querying for all doesn't return the expected result -- Add language extension `ListTuplePuns` [#8854](https://github.com/haskell/cabal/pull/8854) - - Adds support for the `ListTuplePuns` language extension (GHC proposal #475) +- Add language extension `ListTuplePuns` (GHC proposal #475) [#8854](https://github.com/haskell/cabal/pull/8854) - Add `mkVersionIntervals` for creating a `VersionIntervals` from a list [#9034](https://github.com/haskell/cabal/pull/9034) diff --git a/release-notes/Cabal-3.12.1.0.md b/release-notes/Cabal-3.12.1.0.md new file mode 100644 index 00000000000..8f37e2c0454 --- /dev/null +++ b/release-notes/Cabal-3.12.1.0.md @@ -0,0 +1,54 @@ +Cabal and Cabal-syntax 3.12.1.0 changelog and release notes +--- + + +### Significant changes + +- Update GHC arguments normalization and GHC options rendering [#9729](https://github.com/haskell/cabal/issues/9729) [#10014](https://github.com/haskell/cabal/pull/10014) + + The flags `-fdiagnostics-as-json`, `-fprint-error-index-lists`, `-fbreak-points`, `-dipe-stats`, `-ffamily-application-cache`, `-fprint-redundant-promotion-ticks`, `-fshow-error-context` and `-funoptimized-core-for-interpreter` have been added to the flags that do not cause recompilation. + +- Warn on missing `default-language` [#9620](https://github.com/haskell/cabal/issues/9620) [#9766](https://github.com/haskell/cabal/pull/9766) + + - To help the adoption of GHC language editions, `cabal check` will now + warn about missing `default-language`. + +- Add MHS ([MicroHS](https://github.com/augustss/MicroHs)) as a known Haskell compiler [#9878](https://github.com/haskell/cabal/pull/9878) + +- Re-instate `initialBuildSteps` [#9856](https://github.com/haskell/cabal/issues/9856) [#9950](https://github.com/haskell/cabal/pull/9950) + + The `initialBuildSteps` function from `Distribution.Simple.Build`, which had + been hastily removed, has been reinstated. + + It now comes with a deprecation warning: calling that function does not suffice + to prepare the sources for a package, as there are other steps that one might + also need to perform: + + - running pre-processors (such as alex/happy); + - running pre-build hooks or custom logic + (in build-type: Hooks or build-type: Custom or Configure). + + Consumers wanting to prepare the sources of a package, e.g. in order to launch a + REPL session, are advised to run `setup repl --repl-multi-file=` instead. + +- Label error messages with codes (following GHC, Stack) + + As with GHC and Stack, Cabal and cabal-install now generate warnings and errors prefixed with error codes of the form `[Cabal-xxxxx]`. These will be documented on https://errors.haskell.org, although very few are as yet. + + This change was actually present in Cabal-3.12.0.0, but was inadvertently omitted from the changelog. + +### Other changes + +- Don't recommend deprecated/removed `extensions` field [#10042](https://github.com/haskell/cabal/issues/10042) [#10044](https://github.com/haskell/cabal/pull/10044) + + When applicable, field `default-extensions` is recommended (rather than + deprecated/removed `extensions:`). + +- Make `Setup copy` and `Setup install` succeed when there's no executable or library [#6750](https://github.com/haskell/cabal/issues/6750) [#9926](https://github.com/haskell/cabal/pull/9926) + + Historically the Setup copy and install steps would fail if the package didn't + contain an executable or library component. In this case there's nothing to do. + + This required workarounds for downstream users of Cabal to handle this edge case. + Now that this error has been downgraded to a warning, Cabal will succeed if + there's nothing to do. diff --git a/release-notes/WIP-cabal-install-3.12.x.0.md b/release-notes/cabal-install-3.12.1.0.md similarity index 83% rename from release-notes/WIP-cabal-install-3.12.x.0.md rename to release-notes/cabal-install-3.12.1.0.md index 34d84982806..8d7055eb95b 100644 --- a/release-notes/WIP-cabal-install-3.12.x.0.md +++ b/release-notes/cabal-install-3.12.1.0.md @@ -1,12 +1,18 @@ -Pre-release cabal-install 3.12.0.0/3.11.0.0 changelog and release notes. - -This file will be edited and the changes incorprated into the official -3.12.1.0 cabal-install and cabal-install-solver release notes. - +cabal-install 3.12.1.0 changelog and release notes. --- ### Significant changes +- Cabal 3.12 support [#9917](https://github.com/haskell/cabal/issues/9917) + + This is the first release of `cabal-install` that is fully compatible with `Cabal` 3.12.0.0 as released with GHC 9.10.1. In particular, it means custom setup builds will work with GHC 9.10. + +- `cabal-install` has been built against `tar` 0.6.3.0 [#10123](https://github.com/haskell/cabal/pull/10123) + + The new release of `tar` has significant performance improvements, making `cabal update` in particular much faster. + + For anyone building from the source, we suggest making sure that the version of `tar` in your plan is at least 0.6.3.0. (For example, we bumped the `index-state` in our `cabal.project.release` in the `Cabal` repository.) + - Add support for asm, cmm, and js sources in executable components [#8639](https://github.com/haskell/cabal/issues/8639) [#9061](https://github.com/haskell/cabal/pull/9061) Executable components now support the inclusion of asm, cmm, and js source @@ -36,17 +42,14 @@ This file will be edited and the changes incorprated into the official a flag which specifies which libraries should be included in the coverage report for some testsuite. -- Add `cabal path` command [#8879](https://github.com/haskell/cabal/pull/8879) +- Add `cabal path` command [#8879](https://github.com/haskell/cabal/pull/8879) [#9673](https://github.com/haskell/cabal/pull/9673) The `cabal path` command prints the file system paths used by Cabal. It is intended for use by tooling that needs to read or modify Cabal data, such that it does not need to replicate the complicated logic for respecting `CABAL_DIR`, `CABAL_CONFIG`, etc. -- Redesign `cabal path` command to account for projects [#9673](https://github.com/haskell/cabal/pull/9673) - - Previously, `cabal path` was only able to query from the global configuration file, e.g., `~/.cabal/config` or the XDG equivalent. - We take the foundations and enhance `cabal path` to take project configuration, such as `cabal.project`, into account. + It will obey a `cabal.project` if present. Additionally, we add support for multiple output formats, such as key-value pairs and json. @@ -62,7 +65,7 @@ This file will be edited and the changes incorprated into the official The json output format is versioned by the cabal-install version, which is part of the json object. Thus, all result objects contain at least the key "cabal-install-version". - We expand the `cabal path` to also produce information of the compiler that is going to be used in a `cabal build` or `cabal repl` invocation. + It also produces information of the compiler that is going to be used in a `cabal build` or `cabal repl` invocation. To do that, we re-configure the compiler program, and outputs the location, version and compiler flavour. This is helpful for downstream tools, such as HLS, to figure out the GHC version required to compile a project with, without dependency solving. @@ -121,7 +124,7 @@ This file will be edited and the changes incorprated into the official name did not match exactly. Now they will be cached even if the header's capitalization is different. -- Clarify the semantics of the `--package-db` flag [#9678](https://github.com/haskell/cabal/issues/9678) +- Clarify the semantics of the `--package-db` flag [#9678](https://github.com/haskell/cabal/issues/9678) [#9683](https://github.com/haskell/cabal/pull/9683) The `--package-db` flag now only applies to the default immutable initial package stack rather than also applying to the store @@ -257,7 +260,7 @@ This file will be edited and the changes incorprated into the official This relies on the "Project Unit Id" which is available since GHC 9.8.1, older versions of GHC do not benefit from this change. -- Add support for `GHC2024` [#9736](https://github.com/haskell/cabal/issues/9736) +- Add support for `GHC2024` [#9736](https://github.com/haskell/cabal/issues/9736) [#9791](https://github.com/haskell/cabal/pull/9791) Support for the `GHC2024` language edition, introduced by GHC 9.10, has been added. It can now be used in the `default-language` and `other-languages` @@ -273,6 +276,23 @@ This file will be edited and the changes incorprated into the official - Add language extension `TypeAbstractions` [#9496](https://github.com/haskell/cabal/issues/9496) [#9502](https://github.com/haskell/cabal/pull/9502) +- Label error messages with codes (following GHC, Stack) + + As with GHC and Stack, Cabal and cabal-install now generate warnings and errors prefixed with error codes of the form `[Cabal-xxxxx]`. These will be documented on https://errors.haskell.org, although very few are as yet. + +- The `--offline` flag applied to `source-repository-package`s [#9641](https://github.com/haskell/cabal/issues/9641) [#9771](https://github.com/haskell/cabal/pull/9771) + + The `--offline` flag is already used to block access to Hackage. Now with this PR, this also applies to remote dependency `source-repository-package` in `cabal.project`. + +- Fix `--program-suffix` resulting in invalid installation [#8823](https://github.com/haskell/cabal/issues/8823) [#9919](https://github.com/haskell/cabal/issues/9919) [#10056](https://github.com/haskell/cabal/pull/10056) + + Formerly, using `--program-suffix` resulted in bad symlinks into the store. This has been corrected. + +- Warn on missing `default-language` [#9620](https://github.com/haskell/cabal/issues/9620) [#9766](https://github.com/haskell/cabal/pull/9766) + + - To help the adoption of GHC language editions, `cabal check` will now + warn about missing `default-language`. + ### Other changes - Script cache dir is the base16 hash of the canonical path of the script. [#9459](https://github.com/haskell/cabal/pull/9459) @@ -341,3 +361,19 @@ This file will be edited and the changes incorprated into the official The "Executing·install·plan··serially" and other similar "Executing install plan··..." outputs no longer contain double spaces. + +- Allow whitespace in targets [#8875](https://github.com/haskell/cabal/issues/8875) [#10032](https://github.com/haskell/cabal/pull/10032) + + Allow spaces in the final component of target selectors. This resolves an issue + where using absolute paths in selectors can fail if there is whitespace in the + parent directories of the project. + +- Renders project configuration provenance as a list of canonical paths [#9971](https://github.com/haskell/cabal/issues/9971) [#9985](https://github.com/haskell/cabal/pull/9985) + + Removes interleaved rendering of project imports. + +- Abbreviate solver rejection messages with installed versions [#9823](https://github.com/haskell/cabal/issues/9823) [#9824](https://github.com/haskell/cabal/pull/9824) + +- solver: Prevent `ghc-internal` from being reinstalled [#10108](https://github.com/haskell/cabal/pull/10108) + + GHC 9.10 ships with a new wired-in package, `ghc-internal`, which cannot be reinstalled. This commit prevents cabal-install from attempting it. From 7d3cfc5f1d27d2e072cc32bbcc1aafdab636fde5 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Fri, 14 Jun 2024 13:56:21 +0200 Subject: [PATCH 023/207] Use `--io-manager=native` in `lib-suite` on Windows --- cabal-testsuite/cabal-testsuite.cabal | 2 +- validate.sh | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/cabal-testsuite/cabal-testsuite.cabal b/cabal-testsuite/cabal-testsuite.cabal index 1a6ed19967c..1c27e40c23c 100644 --- a/cabal-testsuite/cabal-testsuite.cabal +++ b/cabal-testsuite/cabal-testsuite.cabal @@ -91,7 +91,7 @@ executable cabal-tests import: shared main-is: cabal-tests.hs hs-source-dirs: main - ghc-options: -threaded + ghc-options: -threaded -rtsopts -- Make sure these are built before the executable is run build-tool-depends: cabal-testsuite:test-runtime-deps build-depends: diff --git a/validate.sh b/validate.sh index 3b56a945c84..40ad0576b5f 100755 --- a/validate.sh +++ b/validate.sh @@ -324,6 +324,13 @@ CABAL_TESTSUITE_BDIR="$(pwd)/$BUILDDIR/build/$ARCH/$BASEHC/cabal-testsuite-3" CABALNEWBUILD="${CABAL} build $JOBS -w $HC --builddir=$BUILDDIR --project-file=$PROJECTFILE" CABALLISTBIN="${CABAL} list-bin --builddir=$BUILDDIR --project-file=$PROJECTFILE" +# This was needed in some local Windows MSYS2 environments +# but breaks CI for Windows + GHC 9.0.2, thus it is set only on non-CI executions +# of validate.sh +# https://github.com/haskell/cabal/issues/9571 +# https://github.com/haskell/cabal/pull/10114 +RTSOPTS="$([[ $ARCH = "x86_64-windows" && -z "$CI" ]] && echo "+RTS --io-manager=native" || echo "")" + # header ####################################################################### @@ -344,6 +351,7 @@ doctest: $DOCTEST benchmarks: $BENCHMARKS verbose: $VERBOSE extra compilers: $EXTRAHCS +extra RTS options: $RTSOPTS EOF } @@ -426,7 +434,7 @@ fi step_lib_suite() { print_header "Cabal: cabal-testsuite" -CMD="$($CABALLISTBIN cabal-testsuite:exe:cabal-tests) --builddir=$CABAL_TESTSUITE_BDIR $TESTSUITEJOBS --with-ghc=$HC --hide-successes" +CMD="$($CABALLISTBIN cabal-testsuite:exe:cabal-tests) --builddir=$CABAL_TESTSUITE_BDIR $TESTSUITEJOBS --with-ghc=$HC --hide-successes $RTSOPTS" (cd cabal-testsuite && timed $CMD) || exit 1 } @@ -468,7 +476,7 @@ CMD="$($CABALLISTBIN cabal-install:test:integration-tests2) -j1 --hide-successes step_cli_suite() { print_header "cabal-install: cabal-testsuite" -CMD="$($CABALLISTBIN cabal-testsuite:exe:cabal-tests) --builddir=$CABAL_TESTSUITE_BDIR --with-cabal=$($CABALLISTBIN cabal-install:exe:cabal) $TESTSUITEJOBS --with-ghc=$HC --hide-successes --intree-cabal-lib=$PWD --test-tmp=$PWD/testdb" +CMD="$($CABALLISTBIN cabal-testsuite:exe:cabal-tests) --builddir=$CABAL_TESTSUITE_BDIR --with-cabal=$($CABALLISTBIN cabal-install:exe:cabal) $TESTSUITEJOBS --with-ghc=$HC --hide-successes --intree-cabal-lib=$PWD --test-tmp=$PWD/testdb $RTSOPTS" (cd cabal-testsuite && timed $CMD) || exit 1 } From 437ef553fb35ed432a0d02f2113afd2cbe09a278 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Mon, 24 Jun 2024 18:42:00 -0400 Subject: [PATCH 024/207] Remove a stray line from cabal-install changelog See https://github.com/haskell/cabal/pull/9696#discussion_r1651689945 ff. --- cabal-install/changelog | 1 - 1 file changed, 1 deletion(-) diff --git a/cabal-install/changelog b/cabal-install/changelog index 3fe99c798e6..2d742052eeb 100644 --- a/cabal-install/changelog +++ b/cabal-install/changelog @@ -1,6 +1,5 @@ -*-change-log-*- -3.10.2.0 Hécate August 2023 3.10.3.0 Hécate January 2024 * See https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.10.3.0.md From e7d483dfb849c430977745af3ab663b636105810 Mon Sep 17 00:00:00 2001 From: Andrea Bedini Date: Thu, 20 Jun 2024 16:50:43 +0800 Subject: [PATCH 025/207] Return Maybe PkgConfigDb rather than PkgConfigDb --- .../src/Distribution/Solver/Modular.hs | 2 +- .../src/Distribution/Solver/Modular/Solver.hs | 2 +- .../Distribution/Solver/Modular/Validate.hs | 4 +- .../Solver/Types/DependencyResolver.hs | 2 +- .../Distribution/Solver/Types/PkgConfigDb.hs | 46 ++++++++----------- .../src/Distribution/Client/Configure.hs | 2 +- .../src/Distribution/Client/Dependency.hs | 2 +- .../src/Distribution/Client/Fetch.hs | 2 +- .../src/Distribution/Client/Freeze.hs | 2 +- .../src/Distribution/Client/Install.hs | 4 +- .../Distribution/Client/ProjectPlanning.hs | 12 ++--- .../Distribution/Solver/Modular/DSL.hs | 2 +- .../Solver/Modular/DSL/TestCaseUtils.hs | 4 +- .../Distribution/Solver/Modular/QuickCheck.hs | 2 +- 14 files changed, 39 insertions(+), 49 deletions(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular.hs b/cabal-install-solver/src/Distribution/Solver/Modular.hs index 2aac240318f..9111b2d78d0 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular.hs @@ -116,7 +116,7 @@ modularResolver sc (Platform arch os) cinfo iidx sidx pkgConfigDB pprefs pcs pns solve' :: SolverConfig -> CompilerInfo -> Index - -> PkgConfigDb + -> Maybe PkgConfigDb -> (PN -> PackagePreferences) -> Map PN [LabeledPackageConstraint] -> Set PN diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs index 39bd7bf4690..b57f55af1fc 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs @@ -91,7 +91,7 @@ newtype PruneAfterFirstSuccess = PruneAfterFirstSuccess Bool solve :: SolverConfig -- ^ solver parameters -> CompilerInfo -> Index -- ^ all available packages as an index - -> PkgConfigDb -- ^ available pkg-config pkgs + -> Maybe PkgConfigDb -- ^ available pkg-config pkgs -> (PN -> PackagePreferences) -- ^ preferences -> M.Map PN [LabeledPackageConstraint] -- ^ global constraints -> S.Set PN -- ^ global goals diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs index cbe6282b6d0..c757efe48e1 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs @@ -561,7 +561,7 @@ extendRequiredComponents eqpn available = foldM extendSingle -- | Interface. -validateTree :: CompilerInfo -> Index -> PkgConfigDb -> Tree d c -> Tree d c +validateTree :: CompilerInfo -> Index -> Maybe PkgConfigDb -> Tree d c -> Tree d c validateTree cinfo idx pkgConfigDb t = runValidate (validate t) VS { supportedExt = maybe (const True) -- if compiler has no list of extensions, we assume everything is supported (\ es -> let s = S.fromList es in \ x -> S.member x s) @@ -569,7 +569,7 @@ validateTree cinfo idx pkgConfigDb t = runValidate (validate t) VS { , supportedLang = maybe (const True) (flip L.elem) -- use list lookup because language list is small and no Ord instance (compilerInfoLanguages cinfo) - , presentPkgs = pkgConfigPkgIsPresent pkgConfigDb + , presentPkgs = maybe (\_pn _pvr -> False) pkgConfigPkgIsPresent pkgConfigDb , index = idx , saved = M.empty , pa = PA M.empty M.empty M.empty diff --git a/cabal-install-solver/src/Distribution/Solver/Types/DependencyResolver.hs b/cabal-install-solver/src/Distribution/Solver/Types/DependencyResolver.hs index e773492ae74..139a6d2b33d 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/DependencyResolver.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/DependencyResolver.hs @@ -30,7 +30,7 @@ type DependencyResolver loc = Platform -> CompilerInfo -> InstalledPackageIndex -> PackageIndex (SourcePackage loc) - -> PkgConfigDb + -> Maybe PkgConfigDb -> (PackageName -> PackagePreferences) -> [LabeledPackageConstraint] -> Set PackageName diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs index 21845eafdec..98ef5bcd0b0 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs @@ -46,25 +46,28 @@ import Distribution.Types.PkgconfigVersion import Distribution.Types.PkgconfigVersionRange import Distribution.Verbosity (Verbosity) --- | The list of packages installed in the system visible to --- @pkg-config@. This is an opaque datatype, to be constructed with --- `readPkgConfigDb` and queried with `pkgConfigPkgPresent`. -data PkgConfigDb = PkgConfigDb (M.Map PkgconfigName (Maybe PkgconfigVersion)) - -- ^ If an entry is `Nothing`, this means that the - -- package seems to be present, but we don't know the - -- exact version (because parsing of the version - -- number failed). - | NoPkgConfigDb - -- ^ For when we could not run pkg-config successfully. +newtype PkgConfigDb = PkgConfigDb (M.Map PkgconfigName (Maybe PkgconfigVersion)) deriving (Show, Generic, Typeable) +-- -- | The list of packages installed in the system visible to +-- -- @pkg-config@. This is an opaque datatype, to be constructed with +-- -- `readPkgConfigDb` and queried with `pkgConfigPkgPresent`. +-- data PkgConfigDb = PkgConfigDb (M.Map PkgconfigName (Maybe PkgconfigVersion)) +-- -- ^ If an entry is `Nothing`, this means that the +-- -- package seems to be present, but we don't know the +-- -- exact version (because parsing of the version +-- -- number failed). +-- | NoPkgConfigDb +-- -- ^ For when we could not run pkg-config successfully. +-- deriving (Show, Generic, Typeable) + instance Binary PkgConfigDb instance Structured PkgConfigDb -- | Query pkg-config for the list of installed packages, together -- with their versions. Return a `PkgConfigDb` encapsulating this -- information. -readPkgConfigDb :: Verbosity -> ProgramDb -> IO PkgConfigDb +readPkgConfigDb :: Verbosity -> ProgramDb -> IO (Maybe PkgConfigDb) readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do mpkgConfig <- needProgram verbosity pkgConfigProgram progdb case mpkgConfig of @@ -106,7 +109,7 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do (programInvocation pkgConfig ("--modversion" : pkgNames)) let pkgVersions = lines outs if exitCode == ExitSuccess && length pkgVersions == length pkgNames - then (return . pkgConfigDbFromList . zip pkgNames) pkgVersions + then (return . Just . pkgConfigDbFromList . zip pkgNames) pkgVersions else -- if there's a single broken pc file the above fails, so we fall back -- into calling it individually @@ -116,7 +119,7 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do -- requested one, we fall back to querying one by one. do info verbosity ("call to pkg-config --modversion on all packages failed. Falling back to querying pkg-config individually on each package") - pkgConfigDbFromList . catMaybes <$> mapM (getIndividualVersion pkgConfig) pkgNames + Just . pkgConfigDbFromList . catMaybes <$> mapM (getIndividualVersion pkgConfig) pkgNames where -- For when pkg-config invocation fails (possibly because of a -- too long command line). @@ -124,9 +127,9 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do info verbosity ("Failed to query pkg-config, Cabal will continue" ++ " without solving for pkg-config constraints: " ++ extra) - return NoPkgConfigDb + return Nothing - ioErrorHandler :: IOException -> IO PkgConfigDb + ioErrorHandler :: IOException -> IO (Maybe PkgConfigDb) ioErrorHandler e = noPkgConfig (show e) getIndividualVersion :: ConfiguredProgram -> String -> IO (Maybe (String, String)) @@ -162,13 +165,6 @@ pkgConfigPkgIsPresent (PkgConfigDb db) pn vr = Nothing -> False -- Package not present in the DB. Just Nothing -> True -- Package present, but version unknown. Just (Just v) -> withinPkgconfigVersionRange v vr --- If we could not read the pkg-config database successfully we fail. --- The plan found by the solver can't be executed later, because pkg-config itself --- is going to be called in the build phase to get the library location for linking --- so even if there is a library, it would need to be passed manual flags anyway. -pkgConfigPkgIsPresent NoPkgConfigDb _ _ = False - - -- | Query the version of a package in the @pkg-config@ database. -- @Nothing@ indicates the package is not in the database, while @@ -176,12 +172,6 @@ pkgConfigPkgIsPresent NoPkgConfigDb _ _ = False -- but its version is not known. pkgConfigDbPkgVersion :: PkgConfigDb -> PkgconfigName -> Maybe (Maybe PkgconfigVersion) pkgConfigDbPkgVersion (PkgConfigDb db) pn = M.lookup pn db --- NB: Since the solver allows solving to succeed if there is --- NoPkgConfigDb, we should report that we *guess* that there --- is a matching pkg-config configuration, but that we just --- don't know about it. -pkgConfigDbPkgVersion NoPkgConfigDb _ = Just Nothing - -- | Query pkg-config for the locations of pkg-config's package files. Use this -- to monitor for changes in the pkg-config DB. diff --git a/cabal-install/src/Distribution/Client/Configure.hs b/cabal-install/src/Distribution/Client/Configure.hs index fc7ea49fe31..0586a362dd2 100644 --- a/cabal-install/src/Distribution/Client/Configure.hs +++ b/cabal-install/src/Distribution/Client/Configure.hs @@ -390,7 +390,7 @@ planLocalPackage -> ConfigExFlags -> InstalledPackageIndex -> SourcePackageDb - -> PkgConfigDb + -> Maybe PkgConfigDb -> IO (Progress String String SolverInstallPlan) planLocalPackage verbosity diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index 2949b4d21d1..ae731cdc64b 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -781,7 +781,7 @@ runSolver = modularResolver resolveDependencies :: Platform -> CompilerInfo - -> PkgConfigDb + -> Maybe PkgConfigDb -> DepResolverParams -> Progress String String SolverInstallPlan resolveDependencies platform comp pkgConfigDB params = diff --git a/cabal-install/src/Distribution/Client/Fetch.hs b/cabal-install/src/Distribution/Client/Fetch.hs index 54db5ae607b..f09ae4d772e 100644 --- a/cabal-install/src/Distribution/Client/Fetch.hs +++ b/cabal-install/src/Distribution/Client/Fetch.hs @@ -161,7 +161,7 @@ planPackages -> FetchFlags -> InstalledPackageIndex -> SourcePackageDb - -> PkgConfigDb + -> Maybe PkgConfigDb -> [PackageSpecifier UnresolvedSourcePackage] -> IO [UnresolvedSourcePackage] planPackages diff --git a/cabal-install/src/Distribution/Client/Freeze.hs b/cabal-install/src/Distribution/Client/Freeze.hs index 9bc4e3234b5..92f590bb772 100644 --- a/cabal-install/src/Distribution/Client/Freeze.hs +++ b/cabal-install/src/Distribution/Client/Freeze.hs @@ -199,7 +199,7 @@ planPackages -> FreezeFlags -> InstalledPackageIndex -> SourcePackageDb - -> PkgConfigDb + -> Maybe PkgConfigDb -> [PackageSpecifier UnresolvedSourcePackage] -> IO [SolverPlanPackage] planPackages diff --git a/cabal-install/src/Distribution/Client/Install.hs b/cabal-install/src/Distribution/Client/Install.hs index a31e4d2ce62..9cf80d3858c 100644 --- a/cabal-install/src/Distribution/Client/Install.hs +++ b/cabal-install/src/Distribution/Client/Install.hs @@ -381,7 +381,7 @@ install type InstallContext = ( InstalledPackageIndex , SourcePackageDb - , PkgConfigDb + , Maybe PkgConfigDb , [UserTarget] , [PackageSpecifier UnresolvedSourcePackage] , HttpTransport @@ -567,7 +567,7 @@ planPackages -> InstallFlags -> InstalledPackageIndex -> SourcePackageDb - -> PkgConfigDb + -> Maybe PkgConfigDb -> [PackageSpecifier UnresolvedSourcePackage] -> Progress String String SolverInstallPlan planPackages diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index d0f696be957..0b099dac37c 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -664,7 +664,7 @@ rebuildInstallPlan -> (Compiler, Platform, ProgramDb) -> [PackageSpecifier UnresolvedSourcePackage] -> InstalledPackageIndex - -> Rebuild (SolverInstallPlan, PkgConfigDb, IndexUtils.TotalIndexState, IndexUtils.ActiveRepos) + -> Rebuild (SolverInstallPlan, Maybe PkgConfigDb, IndexUtils.TotalIndexState, IndexUtils.ActiveRepos) phaseRunSolver projectConfig@ProjectConfig { projectConfigShared @@ -776,7 +776,7 @@ rebuildInstallPlan phaseElaboratePlan :: ProjectConfig -> (Compiler, Platform, ProgramDb) - -> PkgConfigDb + -> Maybe PkgConfigDb -> SolverInstallPlan -> [PackageSpecifier (SourcePackage (PackageLocation loc))] -> Rebuild @@ -1010,7 +1010,7 @@ getSourcePackages verbosity withRepoCtx idxState activeRepos = do $ repos return sourcePkgDbWithTIS -getPkgConfigDb :: Verbosity -> ProgramDb -> Rebuild PkgConfigDb +getPkgConfigDb :: Verbosity -> ProgramDb -> Rebuild (Maybe PkgConfigDb) getPkgConfigDb verbosity progdb = do dirs <- liftIO $ getPkgConfigDbDirs verbosity progdb -- Just monitor the dirs so we'll notice new .pc files. @@ -1210,7 +1210,7 @@ planPackages -> SolverSettings -> InstalledPackageIndex -> SourcePackageDb - -> PkgConfigDb + -> Maybe PkgConfigDb -> [PackageSpecifier UnresolvedSourcePackage] -> Map PackageName (Map OptionalStanza Bool) -> Progress String String SolverInstallPlan @@ -1533,7 +1533,7 @@ elaborateInstallPlan -> Platform -> Compiler -> ProgramDb - -> PkgConfigDb + -> Maybe PkgConfigDb -> DistDirLayout -> StoreDirLayout -> SolverInstallPlan @@ -1937,7 +1937,7 @@ elaborateInstallPlan ++ " from " ++ prettyShow (elabPkgSourceId elab0) ) - (pkgConfigDbPkgVersion pkgConfigDB pn) + (pkgConfigDB >>= \db -> pkgConfigDbPkgVersion db pn) ) | PkgconfigDependency pn _ <- PD.pkgconfigDepends diff --git a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL.hs b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL.hs index 991c5cafa0e..08e1d7fb141 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL.hs @@ -783,7 +783,7 @@ exResolve -> Maybe [Extension] -- List of languages supported by the compiler, or Nothing if unknown. -> Maybe [Language] - -> PC.PkgConfigDb + -> Maybe PC.PkgConfigDb -> [ExamplePkgName] -> Maybe Int -> CountConflicts diff --git a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL/TestCaseUtils.hs b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL/TestCaseUtils.hs index 91ec541f976..afd1419d30c 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL/TestCaseUtils.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL/TestCaseUtils.hs @@ -130,7 +130,7 @@ data SolverTest = SolverTest , testDb :: ExampleDb , testSupportedExts :: Maybe [Extension] , testSupportedLangs :: Maybe [Language] - , testPkgConfigDb :: PkgConfigDb + , testPkgConfigDb :: Maybe PkgConfigDb , testEnableAllTests :: EnableAllTests } @@ -233,7 +233,7 @@ mkTestExtLangPC exts langs mPkgConfigDb db label targets result = , testDb = db , testSupportedExts = exts , testSupportedLangs = langs - , testPkgConfigDb = maybe NoPkgConfigDb pkgConfigDbFromList mPkgConfigDb + , testPkgConfigDb = pkgConfigDbFromList <$> mPkgConfigDb , testEnableAllTests = EnableAllTests False } diff --git a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs index 114db775f21..1a2bc97224f 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs @@ -227,7 +227,7 @@ solve enableBj fineGrainedConflicts reorder countConflicts indep prefOldest goal (unTestDb (testDb test)) Nothing Nothing - (pkgConfigDbFromList []) + (Just $ pkgConfigDbFromList []) (map unPN (testTargets test)) -- The backjump limit prevents individual tests from using -- too much time and memory. From 0b960d6f6e340a67eb7f54bae91bf529d3bc8692 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Tue, 18 Jun 2024 12:53:05 +0200 Subject: [PATCH 026/207] Make clear when pkg-config is not present When no pkg-config program was found, cabal would claim that the package is not in the db, instead of telling clearly that no pkg-config was found at all. --- .../Distribution/Solver/Modular/Message.hs | 1 + .../src/Distribution/Solver/Modular/Tree.hs | 1 + .../Distribution/Solver/Modular/Validate.hs | 12 ++++++---- .../Distribution/Solver/Types/PkgConfigDb.hs | 24 +++++++------------ .../PackageTests/ExtraProgPath/setup.out | 2 +- changelog.d/pr-10122 | 10 ++++++++ 6 files changed, 29 insertions(+), 21 deletions(-) create mode 100644 changelog.d/pr-10122 diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Message.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Message.hs index e097d3e081c..70b13cbec5c 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Message.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Message.hs @@ -279,6 +279,7 @@ showFR :: ConflictSet -> FailReason -> String showFR _ (UnsupportedExtension ext) = " (conflict: requires " ++ showUnsupportedExtension ext ++ ")" showFR _ (UnsupportedLanguage lang) = " (conflict: requires " ++ showUnsupportedLanguage lang ++ ")" showFR _ (MissingPkgconfigPackage pn vr) = " (conflict: pkg-config package " ++ prettyShow pn ++ prettyShow vr ++ ", not found in the pkg-config database)" +showFR _ (MissingPkgconfigProgram pn vr) = " (pkg-config package " ++ prettyShow pn ++ prettyShow vr ++ " is needed but no pkg-config executable was found or querying it failed)" showFR _ (NewPackageDoesNotMatchExistingConstraint d) = " (conflict: " ++ showConflictingDep d ++ ")" showFR _ (ConflictingConstraints d1 d2) = " (conflict: " ++ L.intercalate ", " (L.map showConflictingDep [d1, d2]) ++ ")" showFR _ (NewPackageIsMissingRequiredComponent comp dr) = " (does not contain " ++ showExposedComponent comp ++ ", which is required by " ++ showDependencyReason dr ++ ")" diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Tree.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Tree.hs index 10d372525b1..62eb964dc01 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Tree.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Tree.hs @@ -102,6 +102,7 @@ data POption = POption I (Maybe PackagePath) data FailReason = UnsupportedExtension Extension | UnsupportedLanguage Language | MissingPkgconfigPackage PkgconfigName PkgconfigVersionRange + | MissingPkgconfigProgram PkgconfigName PkgconfigVersionRange | NewPackageDoesNotMatchExistingConstraint ConflictingDep | ConflictingConstraints ConflictingDep ConflictingDep | NewPackageIsMissingRequiredComponent ExposedComponent (DependencyReason QPN) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs index c757efe48e1..4af149b31cf 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs @@ -90,7 +90,7 @@ import Distribution.Types.PkgconfigVersionRange data ValidateState = VS { supportedExt :: Extension -> Bool, supportedLang :: Language -> Bool, - presentPkgs :: PkgconfigName -> PkgconfigVersionRange -> Bool, + presentPkgs :: Maybe (PkgconfigName -> PkgconfigVersionRange -> Bool), index :: Index, -- Saved, scoped, dependencies. Every time 'validate' makes a package choice, @@ -383,7 +383,7 @@ extractNewDeps v b fa sa = go -- or the successfully extended assignment. extend :: (Extension -> Bool) -- ^ is a given extension supported -> (Language -> Bool) -- ^ is a given language supported - -> (PkgconfigName -> PkgconfigVersionRange -> Bool) -- ^ is a given pkg-config requirement satisfiable + -> Maybe (PkgconfigName -> PkgconfigVersionRange -> Bool) -- ^ is a given pkg-config requirement satisfiable -> [LDep QPN] -> PPreAssignment -> Either Conflict PPreAssignment @@ -398,8 +398,10 @@ extend extSupported langSupported pkgPresent newactives ppa = foldM extendSingle if langSupported lang then Right a else Left (dependencyReasonToConflictSet dr, UnsupportedLanguage lang) extendSingle a (LDep dr (Pkg pn vr)) = - if pkgPresent pn vr then Right a - else Left (dependencyReasonToConflictSet dr, MissingPkgconfigPackage pn vr) + case (\f -> f pn vr) <$> pkgPresent of + Just True -> Right a + Just False -> Left (dependencyReasonToConflictSet dr, MissingPkgconfigPackage pn vr) + Nothing -> Left (dependencyReasonToConflictSet dr, MissingPkgconfigProgram pn vr) extendSingle a (LDep dr (Dep dep@(PkgComponent qpn _) ci)) = let mergedDep = M.findWithDefault (MergedDepConstrained []) qpn a in case (\ x -> M.insert qpn x a) <$> merge mergedDep (PkgDep dr dep ci) of @@ -569,7 +571,7 @@ validateTree cinfo idx pkgConfigDb t = runValidate (validate t) VS { , supportedLang = maybe (const True) (flip L.elem) -- use list lookup because language list is small and no Ord instance (compilerInfoLanguages cinfo) - , presentPkgs = maybe (\_pn _pvr -> False) pkgConfigPkgIsPresent pkgConfigDb + , presentPkgs = pkgConfigPkgIsPresent <$> pkgConfigDb , index = idx , saved = M.empty , pa = PA M.empty M.empty M.empty diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs index 98ef5bcd0b0..ccf52ea2c8c 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs @@ -46,21 +46,15 @@ import Distribution.Types.PkgconfigVersion import Distribution.Types.PkgconfigVersionRange import Distribution.Verbosity (Verbosity) +-- | The list of packages installed in the system visible to +-- @pkg-config@. +-- +-- If an entry is `Nothing`, this means that the package seems to be present, +-- but we don't know the exact version (because parsing of the version number +-- failed). newtype PkgConfigDb = PkgConfigDb (M.Map PkgconfigName (Maybe PkgconfigVersion)) deriving (Show, Generic, Typeable) --- -- | The list of packages installed in the system visible to --- -- @pkg-config@. This is an opaque datatype, to be constructed with --- -- `readPkgConfigDb` and queried with `pkgConfigPkgPresent`. --- data PkgConfigDb = PkgConfigDb (M.Map PkgconfigName (Maybe PkgconfigVersion)) --- -- ^ If an entry is `Nothing`, this means that the --- -- package seems to be present, but we don't know the --- -- exact version (because parsing of the version --- -- number failed). --- | NoPkgConfigDb --- -- ^ For when we could not run pkg-config successfully. --- deriving (Show, Generic, Typeable) - instance Binary PkgConfigDb instance Structured PkgConfigDb @@ -71,7 +65,7 @@ readPkgConfigDb :: Verbosity -> ProgramDb -> IO (Maybe PkgConfigDb) readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do mpkgConfig <- needProgram verbosity pkgConfigProgram progdb case mpkgConfig of - Nothing -> noPkgConfig "Cannot find pkg-config program" + Nothing -> noPkgConfig "cannot find pkg-config program" Just (pkgConfig, _) -> do -- To prevent malformed Unicode in the descriptions from crashing cabal, -- read without interpreting any encoding first. (#9608) @@ -124,8 +118,8 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do -- For when pkg-config invocation fails (possibly because of a -- too long command line). noPkgConfig extra = do - info verbosity ("Failed to query pkg-config, Cabal will continue" - ++ " without solving for pkg-config constraints: " + info verbosity ("Warning: Failed to query pkg-config, Cabal will backtrack " + ++ "if a package from pkg-config is requested. Error message: " ++ extra) return Nothing diff --git a/cabal-testsuite/PackageTests/ExtraProgPath/setup.out b/cabal-testsuite/PackageTests/ExtraProgPath/setup.out index c3755d7e8c7..01fc2e5cfc0 100644 --- a/cabal-testsuite/PackageTests/ExtraProgPath/setup.out +++ b/cabal-testsuite/PackageTests/ExtraProgPath/setup.out @@ -5,6 +5,6 @@ Resolving dependencies... Error: [Cabal-7107] Could not resolve dependencies: [__0] next goal: CheckExtraProgPath (user goal) -[__0] rejecting: CheckExtraProgPath-0.1 (conflict: pkg-config package zlib-any, not found in the pkg-config database) +[__0] rejecting: CheckExtraProgPath-0.1 (pkg-config package zlib-any is needed but no pkg-config executable was found or querying it failed) [__0] fail (backjumping, conflict set: CheckExtraProgPath) After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: CheckExtraProgPath (2) diff --git a/changelog.d/pr-10122 b/changelog.d/pr-10122 new file mode 100644 index 00000000000..7e9fbe10d47 --- /dev/null +++ b/changelog.d/pr-10122 @@ -0,0 +1,10 @@ +synopsis: Clarify error message when pkg-config is not found +packages: cabal-install-solver +prs: #10122 + +description: { + +- The error message when pkg-config is not found or querying it fails will no +longer incorrectly claim that the package is missing in the database. + +} From 17890938db3c391ac7118362bd675d4ab94c03b7 Mon Sep 17 00:00:00 2001 From: Rodrigo Mesquita Date: Thu, 20 Jun 2024 10:52:50 +0100 Subject: [PATCH 027/207] Cabal: Add flag to ignore build tool dependencies Add a flag to disable the hard requirement on the build-tools-(depends) declared on the Cabal package. When this flag is enabled (--ignore-build-tools), a build-tool which can't be found does not block compilation. Fixes #10061 --- .../Distribution/Utils/Structured.hs | 4 +- Cabal/src/Distribution/Simple/Configure.hs | 50 ++++++++++--------- Cabal/src/Distribution/Simple/Setup/Config.hs | 15 ++++++ .../src/Distribution/Client/Config.hs | 1 + .../Client/ProjectConfig/Legacy.hs | 2 + .../Distribution/Client/ProjectPlanning.hs | 1 + .../src/Distribution/Client/Setup.hs | 1 + .../PackageTests/IgnoreBuildTools/Hello.hs | 7 +++ .../IgnoreBuildTools/client.cabal | 13 +++++ .../PackageTests/IgnoreBuildTools/setup.out | 5 ++ .../IgnoreBuildTools/setup.test.hs | 5 ++ changelog.d/pr-10128 | 12 +++++ 12 files changed, 91 insertions(+), 25 deletions(-) create mode 100644 cabal-testsuite/PackageTests/IgnoreBuildTools/Hello.hs create mode 100644 cabal-testsuite/PackageTests/IgnoreBuildTools/client.cabal create mode 100644 cabal-testsuite/PackageTests/IgnoreBuildTools/setup.out create mode 100644 cabal-testsuite/PackageTests/IgnoreBuildTools/setup.test.hs create mode 100644 changelog.d/pr-10128 diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs index d600a51fa05..63841cba729 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs @@ -41,7 +41,7 @@ md5CheckGenericPackageDescription proxy = md5Check proxy md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion md5CheckLocalBuildInfo proxy = md5Check proxy #if MIN_VERSION_base(4,19,0) - 0x31b94dc3e61eb01fea1a1c3c73d984ee + 0x6809d4d86ae1810f2a032bc90c952b76 #else - 0xdc2f5e7a9c696a4e0bd64f02a0140b74 + 0x9409dca80a2e1522b1c3a39356e9aaef #endif diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index aa0e2a3a438..cae6dd7d101 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -858,29 +858,33 @@ configurePackage cfg lbc0 pkg_descr00 flags enabled comp platform programDb0 pac -- right before calling configurePackage? -- Configure certain external build tools, see below for which ones. - let requiredBuildTools = do - bi <- enabledBuildInfos pkg_descr0 enabled - -- First, we collect any tool dep that we know is external. This is, - -- in practice: - -- - -- 1. `build-tools` entries on the whitelist - -- - -- 2. `build-tool-depends` that aren't from the current package. - let externBuildToolDeps = - [ LegacyExeDependency (unUnqualComponentName eName) versionRange - | buildTool@(ExeDependency _ eName versionRange) <- - getAllToolDependencies pkg_descr0 bi - , not $ isInternal pkg_descr0 buildTool - ] - -- Second, we collect any build-tools entry we don't know how to - -- desugar. We'll never have any idea how to build them, so we just - -- hope they are already on the PATH. - let unknownBuildTools = - [ buildTool - | buildTool <- buildTools bi - , Nothing == desugarBuildTool pkg_descr0 buildTool - ] - externBuildToolDeps ++ unknownBuildTools + let requiredBuildTools + -- If --ignore-build-tools is set, no build tool is required: + | fromFlagOrDefault False $ configIgnoreBuildTools cfg = + [] + | otherwise = do + bi <- enabledBuildInfos pkg_descr0 enabled + -- First, we collect any tool dep that we know is external. This is, + -- in practice: + -- + -- 1. `build-tools` entries on the whitelist + -- + -- 2. `build-tool-depends` that aren't from the current package. + let externBuildToolDeps = + [ LegacyExeDependency (unUnqualComponentName eName) versionRange + | buildTool@(ExeDependency _ eName versionRange) <- + getAllToolDependencies pkg_descr0 bi + , not $ isInternal pkg_descr0 buildTool + ] + -- Second, we collect any build-tools entry we don't know how to + -- desugar. We'll never have any idea how to build them, so we just + -- hope they are already on the PATH. + let unknownBuildTools = + [ buildTool + | buildTool <- buildTools bi + , Nothing == desugarBuildTool pkg_descr0 buildTool + ] + externBuildToolDeps ++ unknownBuildTools programDb1 <- configureAllKnownPrograms (lessVerbose verbosity) programDb0 diff --git a/Cabal/src/Distribution/Simple/Setup/Config.hs b/Cabal/src/Distribution/Simple/Setup/Config.hs index 88c970e162f..244f442af46 100644 --- a/Cabal/src/Distribution/Simple/Setup/Config.hs +++ b/Cabal/src/Distribution/Simple/Setup/Config.hs @@ -230,6 +230,10 @@ data ConfigFlags = ConfigFlags -- testsuites run with @--enable-coverage@. Notably, this list must exclude -- indefinite libraries and instantiations because HPC does not support -- backpack (Nov. 2023). + , configIgnoreBuildTools :: Flag Bool + -- ^ When this flag is set, all tools declared in `build-tool`s and + -- `build-tool-depends` will be ignored. This allows a Cabal package with + -- build-tool-dependencies to be built even if the tool is not found. } deriving (Generic, Read, Show, Typeable) @@ -322,7 +326,9 @@ instance Eq ConfigFlags where && equal configDebugInfo && equal configDumpBuildInfo && equal configUseResponseFiles + && equal configAllowDependingOnPrivateLibs && equal configCoverageFor + && equal configIgnoreBuildTools where equal f = on (==) f a b @@ -866,6 +872,15 @@ configureOptions showOrParseArgs = (Flag . (: []) . fromString) (fmap prettyShow . fromFlagOrDefault []) ) + , option + "" + ["ignore-build-tools"] + ( "Ignore build tool dependencies. " + ++ "If set, declared build tools needn't be found for compilation to proceed." + ) + configIgnoreBuildTools + (\v flags -> flags{configIgnoreBuildTools = v}) + trueArg ] where liftInstallDirs = diff --git a/cabal-install/src/Distribution/Client/Config.hs b/cabal-install/src/Distribution/Client/Config.hs index 5930ca98c13..951155d365b 100644 --- a/cabal-install/src/Distribution/Client/Config.hs +++ b/cabal-install/src/Distribution/Client/Config.hs @@ -546,6 +546,7 @@ instance Semigroup SavedConfig where , configAllowDependingOnPrivateLibs = combine configAllowDependingOnPrivateLibs , configCoverageFor = combine configCoverageFor + , configIgnoreBuildTools = combine configIgnoreBuildTools } where combine = combine' savedConfigureFlags diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs index 3d4dc29d8a0..0de745526c1 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs @@ -1114,6 +1114,7 @@ convertToLegacyAllPackageConfig , configDumpBuildInfo = mempty , configAllowDependingOnPrivateLibs = mempty , configCoverageFor = mempty + , configIgnoreBuildTools = mempty } haddockFlags = @@ -1191,6 +1192,7 @@ convertToLegacyPerPackageConfig PackageConfig{..} = , configDumpBuildInfo = packageConfigDumpBuildInfo , configAllowDependingOnPrivateLibs = mempty , configCoverageFor = mempty + , configIgnoreBuildTools = mempty } installFlags = diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 0b099dac37c..19f9907703c 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -4047,6 +4047,7 @@ setupHsConfigureFlags configPrograms_ = mempty -- never use, shouldn't exist configUseResponseFiles = mempty configAllowDependingOnPrivateLibs = Flag $ not $ libraryVisibilitySupported pkgConfigCompiler + configIgnoreBuildTools = mempty cidToGivenComponent :: ConfiguredId -> GivenComponent cidToGivenComponent (ConfiguredId srcid mb_cn cid) = GivenComponent (packageName srcid) ln cid diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index 0df20fb4569..a8db5c98106 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -718,6 +718,7 @@ filterConfigureFlags' flags cabalLibVersion flags_latest { -- Building profiled shared libraries configProfShared = NoFlag + , configIgnoreBuildTools = NoFlag } flags_3_11_0 = diff --git a/cabal-testsuite/PackageTests/IgnoreBuildTools/Hello.hs b/cabal-testsuite/PackageTests/IgnoreBuildTools/Hello.hs new file mode 100644 index 00000000000..4c2772407db --- /dev/null +++ b/cabal-testsuite/PackageTests/IgnoreBuildTools/Hello.hs @@ -0,0 +1,7 @@ +module Main where + +a :: String +a = "0000" + +main :: IO () +main = putStrLn a diff --git a/cabal-testsuite/PackageTests/IgnoreBuildTools/client.cabal b/cabal-testsuite/PackageTests/IgnoreBuildTools/client.cabal new file mode 100644 index 00000000000..fc69b378236 --- /dev/null +++ b/cabal-testsuite/PackageTests/IgnoreBuildTools/client.cabal @@ -0,0 +1,13 @@ +cabal-version: 3.0 +name: client +version: 0.1.0.0 +license: MIT +category: Testing +build-type: Simple + +executable hello-world + main-is: Hello.hs + build-depends: base + build-tool-depends: pre-proc:zero-to-one, another:non-existent + -- build-tools: somethingnonexists + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/IgnoreBuildTools/setup.out b/cabal-testsuite/PackageTests/IgnoreBuildTools/setup.out new file mode 100644 index 00000000000..de3c1b9d6bc --- /dev/null +++ b/cabal-testsuite/PackageTests/IgnoreBuildTools/setup.out @@ -0,0 +1,5 @@ +# Setup configure +Configuring client-0.1.0.0... +# Setup build +Preprocessing executable 'hello-world' for client-0.1.0.0... +Building executable 'hello-world' for client-0.1.0.0... diff --git a/cabal-testsuite/PackageTests/IgnoreBuildTools/setup.test.hs b/cabal-testsuite/PackageTests/IgnoreBuildTools/setup.test.hs new file mode 100644 index 00000000000..0a0297ad454 --- /dev/null +++ b/cabal-testsuite/PackageTests/IgnoreBuildTools/setup.test.hs @@ -0,0 +1,5 @@ +import Test.Cabal.Prelude +-- Test --ignore-build-tools ignores build-tools and build-tool-depends +main = setupTest $ do + setup "configure" ["--ignore-build-tools"] + setup "build" [] diff --git a/changelog.d/pr-10128 b/changelog.d/pr-10128 new file mode 100644 index 00000000000..8c7cc45d204 --- /dev/null +++ b/changelog.d/pr-10128 @@ -0,0 +1,12 @@ +synopsis: Add flag ignore-build-tools +packages: Cabal +prs: #10128 + +description: { + +- Adds flag --ignore-build-tools which allows a user to ignore the tool + dependencies declared in build-tool-depends. For general use, this flag + should never be needed, but it may be useful for packagers. + +} + From dc3ff8f682ff3093102068c35cb744aeb0968740 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Sat, 21 Oct 2023 19:51:51 +0200 Subject: [PATCH 028/207] haddock-project: fixed main library name The main library must use the package name rather than `UnitId`, otherwise the links from other sublibraries will not work. --- .../Distribution/Client/CmdHaddockProject.hs | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs index 8c0c21a5427..5da4e970b1c 100644 --- a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs +++ b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs @@ -284,27 +284,34 @@ haddockProjectAction flags _extraArgs globalFlags = do unitId = unUnitId (elabUnitId package) buildDir = distBuildDirectory distLayout distDirParams packageName = unPackageName (pkgName $ elabPkgSourceId package) + -- TODO: is there a better way to recognise if the library + -- is the main library? + mainLib = + prettyShow (elabPkgSourceId package) ++ "-inplace" + == prettyShow (elabUnitId package) + name = if mainLib then packageName else unitId + let docDir = buildDir "doc" "html" packageName - destDir = outputDir unitId + destDir = outputDir name interfacePath = destDir packageName <.> "haddock" a <- doesDirectoryExist docDir case a of - True -> + True -> do copyDirectoryRecursive verbosity docDir destDir - >> return - [ - ( unitId - , interfacePath - , Visible - ) - ] + return + [ + ( name + , interfacePath + , Visible + ) + ] False -> do warn verbosity From ed54689cedce5818a09624828d63b5aa0fdf825d Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 19 Mar 2024 20:13:32 +0100 Subject: [PATCH 029/207] haddock-project: support for sublibraries This commit makes haddock-project handle sublibraries. The commit changes how `cabal haddock` works, changing the layout in the `dist-newstyle` folder. With this change `haddock` subcommand will install `package:sublib` component in a directory `package-sublib` under `l/sublib/doc/html/`. --- Cabal/src/Distribution/Simple/BuildPaths.hs | 56 ++++++- Cabal/src/Distribution/Simple/Haddock.hs | 136 +++++++++++++--- Cabal/src/Distribution/Simple/Install.hs | 6 +- Cabal/src/Distribution/Simple/Register.hs | 2 +- .../src/Distribution/Simple/Setup/Haddock.hs | 9 -- .../Distribution/Client/CmdHaddockProject.hs | 149 +++++++++--------- .../Includes2/setup-external.cabal.out | 12 +- .../Backpack/Includes2/setup-external.out | 12 +- .../Includes2/setup-per-component.out | 12 +- .../Includes3/setup-external-explicit.out | 4 +- .../Includes3/setup-external-ok.cabal.out | 8 +- .../Backpack/Includes3/setup-external-ok.out | 8 +- .../Backpack/Reexport1/setup.cabal.out | 4 +- .../PackageTests/Backpack/Reexport1/setup.out | 4 +- .../PackageTests/Haddock/setup.cabal.out | 2 +- .../PackageTests/Haddock/setup.out | 2 +- .../PackageTests/HaddockArgs/quickjump.out | 6 +- .../HaddockBuildDepends/cabal.out | 4 +- .../HaddockNewline/setup.cabal.out | 2 +- .../PackageTests/HaddockNewline/setup.out | 2 +- .../HaddockProject/haddock-project.out | 8 +- .../Haddock/haddock.cabal.out | 6 +- .../InternalLibraries/Haddock/haddock.out | 6 +- .../NewHaddock/DisableDoc/cabal.out | 2 +- .../HaddockForHackageCmdOutput/cabal.out | 2 +- .../HaddockOutput/HaddockOutputCmd/cabal.out | 2 +- .../HaddockOutputCmd/cabal.test.hs | 2 +- .../HaddockOutputConfig/cabal.out | 2 +- .../HaddockOutputConfig/cabal.test.hs | 2 +- .../NewHaddock/ImplyDependencies/cabal.out | 4 +- 30 files changed, 302 insertions(+), 174 deletions(-) diff --git a/Cabal/src/Distribution/Simple/BuildPaths.hs b/Cabal/src/Distribution/Simple/BuildPaths.hs index 05a9c6c190f..c0305b7e9f0 100644 --- a/Cabal/src/Distribution/Simple/BuildPaths.hs +++ b/Cabal/src/Distribution/Simple/BuildPaths.hs @@ -19,6 +19,7 @@ module Distribution.Simple.BuildPaths , srcPref , buildInfoPref , haddockDirName + , haddockLibraryDirPath , hscolourPref , haddockPref , autogenPackageModulesDir @@ -26,7 +27,11 @@ module Distribution.Simple.BuildPaths , autogenPathsModuleName , autogenPackageInfoModuleName , cppHeaderName - , haddockName + , haddockPath + , haddockPackageLibraryName + , haddockPackageLibraryName' + , haddockLibraryName + , haddockLibraryPath , mkGenericStaticLibName , mkLibName , mkProfLibName @@ -92,10 +97,28 @@ buildInfoPref distPref = distPref makeRelativePathEx "build-info.json" -- | This is the name of the directory in which the generated haddocks -- should be stored. It does not include the @/doc/html@ prefix. +-- +-- It is also used by `haddock-project` when constructing its output directory. haddockDirName :: HaddockTarget -> PackageDescription -> FilePath haddockDirName ForDevelopment = prettyShow . packageName haddockDirName ForHackage = (++ "-docs") . prettyShow . packageId +-- | This is the name of the directory in which the generated haddocks for +-- a (sub)library should be stored. It does not include the @/doc/html@ +-- prefix. +-- +-- It is also used by `haddock-project` when constructing its output directory. +haddockLibraryDirPath + :: HaddockTarget + -> PackageDescription + -> Library + -> FilePath +haddockLibraryDirPath haddockTarget pkg_descr lib = + case libName lib of + LSubLibName sublib_name -> + haddockDirName haddockTarget pkg_descr prettyShow sublib_name + _ -> haddockDirName haddockTarget pkg_descr + -- | The directory to which generated haddock documentation should be written. haddockPref :: HaddockTarget @@ -139,8 +162,35 @@ autogenPackageInfoModuleName pkg_descr = fixchar '-' = '_' fixchar c = c -haddockName :: PackageDescription -> FilePath -haddockName pkg_descr = prettyShow (packageName pkg_descr) <.> "haddock" +haddockPath :: PackageDescription -> FilePath +haddockPath pkg_descr = prettyShow (packageName pkg_descr) <.> "haddock" + +-- | A name of a (sub)library used by haddock, in the form +-- `:` if it is a sublibrary, or `` if it is the +-- main library. +-- +-- Used by `haddock-project` and `Distribution.Simple.Haddock`. +haddockPackageLibraryName :: PackageDescription -> Library -> String +haddockPackageLibraryName pkg_descr lib = + haddockPackageLibraryName' (packageName pkg_descr) (libName lib) + +haddockPackageLibraryName' :: PackageName -> LibraryName -> String +haddockPackageLibraryName' pkg_name lib_name = + case lib_name of + LSubLibName sublib_name -> + prettyShow pkg_name ++ ":" ++ prettyShow sublib_name + LMainLibName -> prettyShow pkg_name + +-- | A name of a (sub)library used by haddock. +haddockLibraryName :: PackageDescription -> Library -> String +haddockLibraryName pkg_descr lib = + case libName lib of + LSubLibName sublib_name -> prettyShow sublib_name + LMainLibName -> prettyShow (packageName pkg_descr) + +-- | File path of the ".haddock" file. +haddockLibraryPath :: PackageDescription -> Library -> FilePath +haddockLibraryPath pkg_descr lib = haddockLibraryName pkg_descr lib <.> "haddock" -- ----------------------------------------------------------------------------- -- Source File helper diff --git a/Cabal/src/Distribution/Simple/Haddock.hs b/Cabal/src/Distribution/Simple/Haddock.hs index 657991e16b1..ab3c3fd1d8d 100644 --- a/Cabal/src/Distribution/Simple/Haddock.hs +++ b/Cabal/src/Distribution/Simple/Haddock.hs @@ -369,8 +369,10 @@ haddock_setupHooks lbi' clbi htmlTemplate + haddockTarget + pkg_descr exe - let exeArgs' = commonArgs `mappend` exeArgs + commonArgs runHaddock verbosity mbWorkDir @@ -379,7 +381,7 @@ haddock_setupHooks platform haddockProg True - exeArgs' + exeArgs Nothing -> do warn verbosity @@ -406,9 +408,19 @@ haddock_setupHooks lbi' clbi htmlTemplate + haddockTarget + pkg_descr lib - let libArgs' = commonArgs `mappend` libArgs - runHaddock verbosity mbWorkDir tmpFileOpts comp platform haddockProg True libArgs' + commonArgs + runHaddock + verbosity + mbWorkDir + tmpFileOpts + comp + platform + haddockProg + True + libArgs inplaceDir <- absoluteWorkingDirLBI lbi let @@ -450,9 +462,19 @@ haddock_setupHooks lbi' clbi htmlTemplate + haddockTarget + pkg_descr flib - let libArgs' = commonArgs `mappend` flibArgs - runHaddock verbosity mbWorkDir tmpFileOpts comp platform haddockProg True libArgs' + commonArgs + runHaddock + verbosity + mbWorkDir + tmpFileOpts + comp + platform + haddockProg + True + flibArgs ) >> return index CExe _ -> when (flag haddockExecutables) (smsg >> doExe component) >> return index @@ -547,13 +569,11 @@ fromHaddockProjectFlags flags = } fromPackageDescription :: HaddockTarget -> PackageDescription -> HaddockArgs -fromPackageDescription haddockTarget pkg_descr = +fromPackageDescription _haddockTarget pkg_descr = mempty - { argInterfaceFile = Flag $ haddockName pkg_descr + { argInterfaceFile = Flag $ haddockPath pkg_descr , argPackageName = Flag $ packageId $ pkg_descr - , argOutputDir = - Dir $ - "doc" "html" haddockDirName haddockTarget pkg_descr + , argOutputDir = Dir $ "doc" "html" , argPrologue = Flag $ ShortText.fromShortText $ @@ -674,9 +694,13 @@ fromLibrary -> ComponentLocalBuildInfo -> Maybe PathTemplate -- ^ template for HTML location + -> HaddockTarget + -> PackageDescription -> Library + -> HaddockArgs + -- ^ common args -> IO HaddockArgs -fromLibrary verbosity haddockArtifactsDirs lbi clbi htmlTemplate lib = do +fromLibrary verbosity haddockArtifactsDirs lbi clbi htmlTemplate haddockTarget pkg_descr lib commonArgs = do inFiles <- map snd `fmap` getLibSourceFiles verbosity lbi lib clbi args <- mkHaddockArgs @@ -687,10 +711,29 @@ fromLibrary verbosity haddockArtifactsDirs lbi clbi htmlTemplate lib = do htmlTemplate inFiles (libBuildInfo lib) - return - args - { argHideModules = (mempty, otherModules (libBuildInfo lib)) - } + let args' = + commonArgs + <> args + { argOutputDir = + Dir $ haddockLibraryDirPath haddockTarget pkg_descr lib + , argInterfaceFile = Flag $ haddockLibraryPath pkg_descr lib + } + args'' = + args' + { argHideModules = (mempty, otherModules (libBuildInfo lib)) + , argTitle = Flag $ haddockPackageLibraryName pkg_descr lib + , -- we need to accommodate for `argOutputDir`, see `haddockLibraryPath` + argBaseUrl = case (libName lib, argBaseUrl args') of + (LSubLibName _, Flag url) -> Flag $ ".." url + (_, a) -> a + , argContents = case (libName lib, argContents args') of + (LSubLibName _, Flag url) -> Flag $ ".." url + (_, a) -> a + , argIndex = case (libName lib, argIndex args') of + (LSubLibName _, Flag url) -> Flag $ ".." url + (_, a) -> a + } + return args'' fromExecutable :: Verbosity @@ -701,9 +744,13 @@ fromExecutable -> ComponentLocalBuildInfo -> Maybe PathTemplate -- ^ template for HTML location + -> HaddockTarget + -> PackageDescription -> Executable + -> HaddockArgs + -- ^ common args -> IO HaddockArgs -fromExecutable verbosity haddockArtifactsDirs lbi clbi htmlTemplate exe = do +fromExecutable verbosity haddockArtifactsDirs lbi clbi htmlTemplate haddockTarget pkg_descr exe commonArgs = do inFiles <- map snd `fmap` getExeSourceFiles verbosity lbi exe clbi args <- mkHaddockArgs @@ -714,10 +761,27 @@ fromExecutable verbosity haddockArtifactsDirs lbi clbi htmlTemplate exe = do htmlTemplate inFiles (buildInfo exe) + let args' = + commonArgs + <> args + { argOutputDir = + Dir $ + haddockDirName haddockTarget pkg_descr + unUnqualComponentName (exeName exe) + } return - args - { argOutputDir = Dir $ unUnqualComponentName $ exeName exe - , argTitle = Flag $ unUnqualComponentName $ exeName exe + args' + { argTitle = Flag $ unUnqualComponentName $ exeName exe + , -- we need to accommodate `argOutputDir` + argBaseUrl = case argBaseUrl args' of + Flag url -> Flag $ ".." url + NoFlag -> NoFlag + , argContents = case argContents args' of + Flag url -> Flag $ ".." url + NoFlag -> NoFlag + , argIndex = case argIndex args' of + Flag url -> Flag $ ".." url + NoFlag -> NoFlag } fromForeignLib @@ -729,9 +793,13 @@ fromForeignLib -> ComponentLocalBuildInfo -> Maybe PathTemplate -- ^ template for HTML location + -> HaddockTarget + -> PackageDescription -> ForeignLib + -> HaddockArgs + -- ^ common args -> IO HaddockArgs -fromForeignLib verbosity haddockArtifactsDirs lbi clbi htmlTemplate flib = do +fromForeignLib verbosity haddockArtifactsDirs lbi clbi htmlTemplate haddockTarget pkg_descr flib commonArgs = do inFiles <- map snd `fmap` getFLibSourceFiles verbosity lbi flib clbi args <- mkHaddockArgs @@ -742,10 +810,27 @@ fromForeignLib verbosity haddockArtifactsDirs lbi clbi htmlTemplate flib = do htmlTemplate inFiles (foreignLibBuildInfo flib) + let args' = + commonArgs + <> args + { argOutputDir = + Dir $ + haddockDirName haddockTarget pkg_descr + unUnqualComponentName (foreignLibName flib) + } return - args - { argOutputDir = Dir $ unUnqualComponentName $ foreignLibName flib - , argTitle = Flag $ unUnqualComponentName $ foreignLibName flib + args' + { argTitle = Flag $ unUnqualComponentName $ foreignLibName flib + , -- we need to accommodate `argOutputDir` + argBaseUrl = case argBaseUrl args' of + Flag url -> Flag $ ".." url + NoFlag -> NoFlag + , argContents = case argContents args' of + Flag url -> Flag $ ".." url + NoFlag -> NoFlag + , argIndex = case argIndex args' of + Flag url -> Flag $ ".." url + NoFlag -> NoFlag } compToExe :: Component -> Maybe Executable @@ -1117,7 +1202,8 @@ haddockPackagePaths ipkgs mkHtmlPath = do interfaces <- sequenceA [ case interfaceAndHtmlPath ipkg of - Nothing -> return (Left (packageId ipkg)) + Nothing -> do + return (Left (packageId ipkg)) Just (interface, html) -> do (html', hypsrc') <- case html of diff --git a/Cabal/src/Distribution/Simple/Install.hs b/Cabal/src/Distribution/Simple/Install.hs index c46f28b3529..435d3fbbebc 100644 --- a/Cabal/src/Distribution/Simple/Install.hs +++ b/Cabal/src/Distribution/Simple/Install.hs @@ -38,7 +38,7 @@ import Distribution.Types.UnqualComponentName import Distribution.Package import Distribution.PackageDescription -import Distribution.Simple.BuildPaths (haddockName, haddockPref) +import Distribution.Simple.BuildPaths (haddockPath, haddockPref) import Distribution.Simple.BuildTarget import Distribution.Simple.Compiler ( CompilerFlavor (..) @@ -199,8 +199,8 @@ copyPackage verbosity pkg_descr lbi distPref copydest = do -- copy in htmlPref first. let haddockInterfaceFileSrc = haddockPref ForDevelopment distPref pkg_descr - makeRelativePathEx (haddockName pkg_descr) - haddockInterfaceFileDest = interfacePref haddockName pkg_descr + makeRelativePathEx (haddockPath pkg_descr) + haddockInterfaceFileDest = interfacePref haddockPath pkg_descr -- We only generate the haddock interface file for libs, So if the -- package consists only of executables there will not be one: exists <- doesFileExist $ i haddockInterfaceFileSrc diff --git a/Cabal/src/Distribution/Simple/Register.hs b/Cabal/src/Distribution/Simple/Register.hs index 78053111a4a..7648c867f99 100644 --- a/Cabal/src/Distribution/Simple/Register.hs +++ b/Cabal/src/Distribution/Simple/Register.hs @@ -548,7 +548,7 @@ generalInstalledPackageInfo adjustRelIncDirs pkg abi_hash lib lbi clbi installDi , IPI.ldOptions = ldOptions bi , IPI.frameworks = map getSymbolicPath $ frameworks bi , IPI.frameworkDirs = map getSymbolicPath $ extraFrameworkDirs bi - , IPI.haddockInterfaces = [haddockdir installDirs haddockName pkg] + , IPI.haddockInterfaces = [haddockdir installDirs haddockLibraryPath pkg lib] , IPI.haddockHTMLs = [htmldir installDirs] , IPI.pkgRoot = Nothing , IPI.libVisibility = libVisibility lib diff --git a/Cabal/src/Distribution/Simple/Setup/Haddock.hs b/Cabal/src/Distribution/Simple/Setup/Haddock.hs index 402544ce511..c896288b431 100644 --- a/Cabal/src/Distribution/Simple/Setup/Haddock.hs +++ b/Cabal/src/Distribution/Simple/Setup/Haddock.hs @@ -441,7 +441,6 @@ data HaddockProjectFlags = HaddockProjectFlags , haddockProjectVerbosity :: Flag Verbosity , -- haddockBaseUrl is not supported, a fixed value is provided haddockProjectResourcesDir :: Flag String - , haddockProjectOutputDir :: Flag FilePath } deriving (Show, Generic, Typeable) @@ -465,7 +464,6 @@ defaultHaddockProjectFlags = , haddockProjectKeepTempFiles = Flag False , haddockProjectVerbosity = Flag normal , haddockProjectResourcesDir = NoFlag - , haddockProjectOutputDir = NoFlag , haddockProjectInterfaces = NoFlag } @@ -613,13 +611,6 @@ haddockProjectOptions _showOrParseArgs = haddockProjectResourcesDir (\v flags -> flags{haddockProjectResourcesDir = v}) (reqArgFlag "DIR") - , option - "" - ["output-dir"] - "Generate haddock documentation into this directory. This flag is provided as a technology preview and is subject to change in the next releases." - haddockProjectOutputDir - (\v flags -> flags{haddockProjectOutputDir = v}) - (reqArgFlag "DIR") ] emptyHaddockProjectFlags :: HaddockProjectFlags diff --git a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs index 5da4e970b1c..0b88a795810 100644 --- a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs +++ b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs @@ -3,6 +3,7 @@ module Distribution.Client.CmdHaddockProject , haddockProjectAction ) where +import Control.Monad (mapM) import Distribution.Client.Compat.Prelude hiding (get) import Prelude () @@ -11,8 +12,8 @@ import qualified Distribution.Client.CmdHaddock as CmdHaddock import Distribution.Client.DistDirLayout ( CabalDirLayout (..) - , DistDirLayout (..) , StoreDirLayout (..) + , distBuildDirectory ) import Distribution.Client.InstallPlan (foldPlanPackage) import qualified Distribution.Client.InstallPlan as InstallPlan @@ -24,7 +25,6 @@ import Distribution.Client.ProjectOrchestration , ProjectBaseContext (..) , ProjectBuildContext (..) , TargetSelector (..) - , printPlan , pruneInstallPlanToTargets , resolveTargets , runProjectPreBuildPhase @@ -52,6 +52,12 @@ import Distribution.Client.Setup ) import Distribution.Client.TargetProblem (TargetProblem (..)) +import Distribution.Simple.BuildPaths + ( haddockDirName + , haddockLibraryDirPath + , haddockLibraryPath + , haddockPath + ) import Distribution.Simple.Command ( CommandUI (..) ) @@ -75,6 +81,7 @@ import Distribution.Simple.Program.Db import Distribution.Simple.Setup ( HaddockFlags (..) , HaddockProjectFlags (..) + , HaddockTarget (..) , Visibility (..) , defaultCommonSetupFlags , defaultHaddockFlags @@ -84,9 +91,11 @@ import Distribution.Simple.Utils ( copyDirectoryRecursive , createDirectoryIfMissingVerbose , dieWithException + , info , warn ) import Distribution.Types.InstalledPackageInfo (InstalledPackageInfo (..)) +import Distribution.Types.PackageDescription (PackageDescription (subLibraries)) import Distribution.Types.PackageId (pkgName) import Distribution.Types.PackageName (unPackageName) import Distribution.Types.UnitId (unUnitId) @@ -98,7 +107,7 @@ import Distribution.Verbosity as Verbosity import Distribution.Client.Errors import System.Directory (doesDirectoryExist, doesFileExist) -import System.FilePath (normalise, takeDirectory, (<.>), ()) +import System.FilePath (normalise, takeDirectory, ()) haddockProjectAction :: HaddockProjectFlags -> [String] -> GlobalFlags -> IO () haddockProjectAction flags _extraArgs globalFlags = do @@ -149,7 +158,10 @@ haddockProjectAction flags _extraArgs globalFlags = do else NoFlag , haddockKeepTempFiles = haddockProjectKeepTempFiles flags , haddockResourcesDir = haddockProjectResourcesDir flags - , haddockOutputDir = haddockProjectOutputDir flags + -- NOTE: we don't pass `haddockOutputDir`. If we do, we'll need to + -- make sure `InstalledPackageInfo` contains the right path to + -- haddock interfaces. Instead we build documentation inside + -- `dist-newstyle` directory and copy it to the output directory. } nixFlags = (commandDefaultFlags CmdHaddock.haddockCommand) @@ -199,8 +211,6 @@ haddockProjectAction flags _extraArgs globalFlags = do elaboratedPlan return (elaboratedPlan', targets) - printPlan verbosity baseCtx buildCtx - let elaboratedPlan :: ElaboratedInstallPlan elaboratedPlan = elaboratedPlanOriginal buildCtx @@ -255,68 +265,68 @@ haddockProjectAction flags _extraArgs globalFlags = do packageInfos <- fmap (nub . concat) $ for pkgs $ \pkg -> case pkg of - Left _ - | not localStyle -> - return [] - Left package -> do - -- TODO: this might not work for public packages with sublibraries. - -- Issue #9026. + Left package | localStyle -> do let packageName = unPackageName (pkgName $ sourcePackageId package) destDir = outputDir packageName fmap catMaybes $ for (haddockInterfaces package) $ \interfacePath -> do let docDir = takeDirectory interfacePath a <- doesFileExist interfacePath case a of - True -> + True -> do copyDirectoryRecursive verbosity docDir destDir - >> return - ( Just - ( packageName - , interfacePath - , Hidden - ) - ) + return $ Just $ Right (packageName, interfacePath, Hidden) False -> return Nothing + Left _ -> return [] Right package -> case elabLocalToProject package of True -> do let distDirParams = elabDistDirParams sharedConfig' package - unitId = unUnitId (elabUnitId package) + pkg_descr = elabPkgDescription package + + packageName = pkgName $ elabPkgSourceId package + unitId = elabUnitId package + packageDir = haddockDirName ForDevelopment pkg_descr + destDir = outputDir packageDir + interfacePath = destDir haddockPath pkg_descr + buildDir = distBuildDirectory distLayout distDirParams - packageName = unPackageName (pkgName $ elabPkgSourceId package) - -- TODO: is there a better way to recognise if the library - -- is the main library? - mainLib = - prettyShow (elabPkgSourceId package) ++ "-inplace" - == prettyShow (elabUnitId package) - name = if mainLib then packageName else unitId - - let docDir = + docDir = buildDir "doc" "html" - packageName - destDir = outputDir name - interfacePath = - destDir - packageName - <.> "haddock" + packageDir + a <- doesDirectoryExist docDir - case a of - True -> do + if a + then do copyDirectoryRecursive verbosity docDir destDir - return - [ - ( name - , interfacePath - , Visible + let infos :: [(String, FilePath, Visibility)] + infos = + (unPackageName packageName, interfacePath, Visible) + : [ (sublibDirPath, sublibInterfacePath, Visible) + | lib <- subLibraries pkg_descr + , let sublibDirPath = haddockLibraryDirPath ForDevelopment pkg_descr lib + sublibInterfacePath = + outputDir + sublibDirPath + haddockLibraryPath pkg_descr lib + ] + infos' <- + mapM + ( \x@(_, path, _) -> do + e <- doesFileExist path + return $ + if e + then Right x + else Left path ) - ] - False -> do + infos + return infos' + else do warn verbosity ( "haddocks of " - ++ show unitId + ++ unUnitId unitId ++ " not found in the store" ) return [] @@ -324,56 +334,51 @@ haddockProjectAction flags _extraArgs globalFlags = do | not localStyle -> return [] False -> do - let packageName = unPackageName (pkgName $ elabPkgSourceId package) + let pkg_descr = elabPkgDescription package unitId = unUnitId (elabUnitId package) packageDir = storePackageDirectory (cabalStoreDirLayout cabalLayout) (pkgConfigCompiler sharedConfig') (elabUnitId package) + -- TODO: use `InstallDirTemplates` docDir = packageDir "share" "doc" "html" - destDir = outputDir packageName - interfacePath = - destDir - packageName - <.> "haddock" + destDir = outputDir haddockDirName ForDevelopment pkg_descr + interfacePath = destDir haddockPath pkg_descr a <- doesDirectoryExist docDir case a of - True -> + True -> do copyDirectoryRecursive verbosity docDir destDir - -- non local packages will be hidden in haddock's - -- generated contents page - >> return - [ - ( unitId - , interfacePath - , Hidden - ) - ] + -- non local packages will be hidden in haddock's + -- generated contents page + return [Right (unitId, interfacePath, Hidden)] False -> do - warn - verbosity - ( "haddocks of " - ++ show unitId - ++ " not found in the store" - ) - return [] + return [Left unitId] -- -- generate index, content, etc. -- + let (missingHaddocks, packageInfos') = partitionEithers packageInfos + when (not (null missingHaddocks)) $ do + warn verbosity "missing haddocks for some packages from the store" + -- Show the package list if `-v1` is passed; it's usually a long list. + -- One needs to add `package` stantza in `cabal.project` file for + -- `cabal` to include a version which has haddocks (or set + -- `documentation: True` in the global config). + info verbosity (intercalate "\n" missingHaddocks) + let flags' = flags { haddockProjectDir = Flag outputDir , haddockProjectInterfaces = Flag [ ( interfacePath - , Just name - , Just name + , Just url + , Just url , visibility ) - | (name, interfacePath, visibility) <- packageInfos + | (url, interfacePath, visibility) <- packageInfos' ] } createHaddockIndex diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.cabal.out b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.cabal.out index cb4f8288291..0448dac63ff 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.cabal.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.cabal.out @@ -8,7 +8,7 @@ for mylib-0.1.0.0... Preprocessing library for mylib-0.1.0.0... Running Haddock on library instantiated with Database = for mylib-0.1.0.0... -Documentation created: ../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib/ +Documentation created: ../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib # Setup copy Installing library in # Setup register @@ -22,7 +22,7 @@ Building library for mysql-0.1.0.0... # Setup haddock Preprocessing library for mysql-0.1.0.0... Running Haddock on library for mysql-0.1.0.0... -Documentation created: ../setup-external.cabal.dist/work/mysql/dist/doc/html/mysql/ +Documentation created: ../setup-external.cabal.dist/work/mysql/dist/doc/html/mysql # Setup copy Installing library in # Setup register @@ -35,7 +35,7 @@ Building library for postgresql-0.1.0.0... # Setup haddock Preprocessing library for postgresql-0.1.0.0... Running Haddock on library for postgresql-0.1.0.0... -Documentation created: ../setup-external.cabal.dist/work/postgresql/dist/doc/html/postgresql/ +Documentation created: ../setup-external.cabal.dist/work/postgresql/dist/doc/html/postgresql # Setup copy Installing library in # Setup register @@ -51,7 +51,7 @@ Preprocessing library for mylib-0.1.0.0... Running Haddock on library instantiated with Database = mysql-0.1.0.0:Database.MySQL for mylib-0.1.0.0... -Documentation created: ../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib/ +Documentation created: ../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib # Setup copy Installing library in # Setup register @@ -69,7 +69,7 @@ Preprocessing library for mylib-0.1.0.0... Running Haddock on library instantiated with Database = postgresql-0.1.0.0:Database.PostgreSQL for mylib-0.1.0.0... -Documentation created: ../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib/ +Documentation created: ../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib # Setup copy Installing library in # Setup register @@ -84,7 +84,7 @@ Building library for src-0.1.0.0... # Setup haddock Preprocessing library for src-0.1.0.0... Running Haddock on library for src-0.1.0.0... -Documentation created: ../setup-external.cabal.dist/work/src/dist/doc/html/src/ +Documentation created: ../setup-external.cabal.dist/work/src/dist/doc/html/src # Setup copy Installing library in # Setup register diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.out b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.out index 299d6a831b3..19a089db14f 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.out @@ -8,7 +8,7 @@ for mylib-0.1.0.0... Preprocessing library for mylib-0.1.0.0... Running Haddock on library instantiated with Database = for mylib-0.1.0.0... -Documentation created: ../setup-external.dist/work/mylib/dist/doc/html/mylib/ +Documentation created: ../setup-external.dist/work/mylib/dist/doc/html/mylib # Setup copy Installing library in # Setup register @@ -22,7 +22,7 @@ Building library for mysql-0.1.0.0... # Setup haddock Preprocessing library for mysql-0.1.0.0... Running Haddock on library for mysql-0.1.0.0... -Documentation created: ../setup-external.dist/work/mysql/dist/doc/html/mysql/ +Documentation created: ../setup-external.dist/work/mysql/dist/doc/html/mysql # Setup copy Installing library in # Setup register @@ -35,7 +35,7 @@ Building library for postgresql-0.1.0.0... # Setup haddock Preprocessing library for postgresql-0.1.0.0... Running Haddock on library for postgresql-0.1.0.0... -Documentation created: ../setup-external.dist/work/postgresql/dist/doc/html/postgresql/ +Documentation created: ../setup-external.dist/work/postgresql/dist/doc/html/postgresql # Setup copy Installing library in # Setup register @@ -51,7 +51,7 @@ Preprocessing library for mylib-0.1.0.0... Running Haddock on library instantiated with Database = mysql-0.1.0.0:Database.MySQL for mylib-0.1.0.0... -Documentation created: ../setup-external.dist/work/mylib/dist/doc/html/mylib/ +Documentation created: ../setup-external.dist/work/mylib/dist/doc/html/mylib # Setup copy Installing library in # Setup register @@ -69,7 +69,7 @@ Preprocessing library for mylib-0.1.0.0... Running Haddock on library instantiated with Database = postgresql-0.1.0.0:Database.PostgreSQL for mylib-0.1.0.0... -Documentation created: ../setup-external.dist/work/mylib/dist/doc/html/mylib/ +Documentation created: ../setup-external.dist/work/mylib/dist/doc/html/mylib # Setup copy Installing library in # Setup register @@ -84,7 +84,7 @@ Building library for src-0.1.0.0... # Setup haddock Preprocessing library for src-0.1.0.0... Running Haddock on library for src-0.1.0.0... -Documentation created: ../setup-external.dist/work/src/dist/doc/html/src/ +Documentation created: ../setup-external.dist/work/src/dist/doc/html/src # Setup copy Installing library in # Setup register diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out index 01888faed97..36c406d8584 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out @@ -8,7 +8,7 @@ for Includes2-0.1.0.0... Preprocessing library 'mylib' for Includes2-0.1.0.0... Running Haddock on library 'mylib' instantiated with Database = for Includes2-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/ +Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/mylib # Setup copy Installing internal library mylib in # Setup register @@ -22,7 +22,7 @@ Building library 'mysql' for Includes2-0.1.0.0... # Setup haddock Preprocessing library 'mysql' for Includes2-0.1.0.0... Running Haddock on library 'mysql' for Includes2-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/ +Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/mysql # Setup copy Installing internal library mysql in # Setup register @@ -35,7 +35,7 @@ Building library 'postgresql' for Includes2-0.1.0.0... # Setup haddock Preprocessing library 'postgresql' for Includes2-0.1.0.0... Running Haddock on library 'postgresql' for Includes2-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/ +Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/postgresql # Setup copy Installing internal library postgresql in # Setup register @@ -54,7 +54,7 @@ Preprocessing library 'mylib' for Includes2-0.1.0.0... Running Haddock on library 'mylib' instantiated with Database = mysql-0.1.0.0:Database.MySQL for Includes2-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/ +Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/mylib # Setup copy Installing internal library mylib in # Setup register @@ -75,7 +75,7 @@ Preprocessing library 'mylib' for Includes2-0.1.0.0... Running Haddock on library 'mylib' instantiated with Database = postgresql-0.1.0.0:Database.PostgreSQL for Includes2-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/ +Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/mylib # Setup copy Installing internal library mylib in # Setup register @@ -90,7 +90,7 @@ Building library for Includes2-0.1.0.0... # Setup haddock Preprocessing library for Includes2-0.1.0.0... Running Haddock on library for Includes2-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/ +Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2 # Setup copy Installing library in # Setup register diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-explicit.out b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-explicit.out index b27b2d8eb1a..72bf091632d 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-explicit.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-explicit.out @@ -8,7 +8,7 @@ for sigs-0.1.0.0... Preprocessing library for sigs-0.1.0.0... Running Haddock on library instantiated with Data.Map = for sigs-0.1.0.0... -Documentation created: ../../setup-external-explicit.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs/ +Documentation created: ../../setup-external-explicit.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs # Setup copy Installing library in # Setup register @@ -24,7 +24,7 @@ for indef-0.1.0.0... Preprocessing library for indef-0.1.0.0... Running Haddock on library instantiated with Data.Map = for indef-0.1.0.0... -Documentation created: ../../setup-external-explicit.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef/ +Documentation created: ../../setup-external-explicit.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef # Setup copy Installing library in # Setup register diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.cabal.out b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.cabal.out index 6d0abf817af..34e7a1204b5 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.cabal.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.cabal.out @@ -8,7 +8,7 @@ for sigs-0.1.0.0... Preprocessing library for sigs-0.1.0.0... Running Haddock on library instantiated with Data.Map = for sigs-0.1.0.0... -Documentation created: ../../setup-external-ok.cabal.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs/ +Documentation created: ../../setup-external-ok.cabal.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs # Setup copy Installing library in # Setup register @@ -24,7 +24,7 @@ for indef-0.1.0.0... Preprocessing library for indef-0.1.0.0... Running Haddock on library instantiated with Data.Map = for indef-0.1.0.0... -Documentation created: ../../setup-external-ok.cabal.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef/ +Documentation created: ../../setup-external-ok.cabal.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef # Setup copy Installing library in # Setup register @@ -41,7 +41,7 @@ Preprocessing library for sigs-0.1.0.0... Running Haddock on library instantiated with Data.Map = containers-:Data.Map for sigs-0.1.0.0... -Documentation created: ../../setup-external-ok.cabal.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs/ +Documentation created: ../../setup-external-ok.cabal.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs # Setup copy Installing library in # Setup register @@ -58,7 +58,7 @@ Preprocessing library for indef-0.1.0.0... Running Haddock on library instantiated with Data.Map = containers-:Data.Map for indef-0.1.0.0... -Documentation created: ../../setup-external-ok.cabal.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef/ +Documentation created: ../../setup-external-ok.cabal.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef # Setup copy Installing library in # Setup register diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.out b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.out index 8fc173d40f0..630edbba1a2 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.out @@ -8,7 +8,7 @@ for sigs-0.1.0.0... Preprocessing library for sigs-0.1.0.0... Running Haddock on library instantiated with Data.Map = for sigs-0.1.0.0... -Documentation created: ../../setup-external-ok.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs/ +Documentation created: ../../setup-external-ok.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs # Setup copy Installing library in # Setup register @@ -24,7 +24,7 @@ for indef-0.1.0.0... Preprocessing library for indef-0.1.0.0... Running Haddock on library instantiated with Data.Map = for indef-0.1.0.0... -Documentation created: ../../setup-external-ok.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef/ +Documentation created: ../../setup-external-ok.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef # Setup copy Installing library in # Setup register @@ -41,7 +41,7 @@ Preprocessing library for sigs-0.1.0.0... Running Haddock on library instantiated with Data.Map = containers-:Data.Map for sigs-0.1.0.0... -Documentation created: ../../setup-external-ok.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs/ +Documentation created: ../../setup-external-ok.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs # Setup copy Installing library in # Setup register @@ -58,7 +58,7 @@ Preprocessing library for indef-0.1.0.0... Running Haddock on library instantiated with Data.Map = containers-:Data.Map for indef-0.1.0.0... -Documentation created: ../../setup-external-ok.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef/ +Documentation created: ../../setup-external-ok.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef # Setup copy Installing library in # Setup register diff --git a/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.cabal.out b/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.cabal.out index 1c8de306e5d..6cdb5760236 100644 --- a/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.cabal.out +++ b/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.cabal.out @@ -6,7 +6,7 @@ Building library for p-0.1.0.0... # Setup haddock Preprocessing library for p-0.1.0.0... Running Haddock on library for p-0.1.0.0... -Documentation created: ../setup.cabal.dist/work/p/dist/doc/html/p/ +Documentation created: ../setup.cabal.dist/work/p/dist/doc/html/p # Setup copy Installing library in # Setup register @@ -19,4 +19,4 @@ Building library for q-0.1.0.0... # Setup haddock Preprocessing library for q-0.1.0.0... Running Haddock on library for q-0.1.0.0... -Documentation created: ../setup.cabal.dist/work/q/dist/doc/html/q/ +Documentation created: ../setup.cabal.dist/work/q/dist/doc/html/q diff --git a/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.out b/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.out index ee41d01148b..ba66136d02a 100644 --- a/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.out +++ b/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.out @@ -6,7 +6,7 @@ Building library for p-0.1.0.0... # Setup haddock Preprocessing library for p-0.1.0.0... Running Haddock on library for p-0.1.0.0... -Documentation created: ../setup.dist/work/p/dist/doc/html/p/ +Documentation created: ../setup.dist/work/p/dist/doc/html/p # Setup copy Installing library in # Setup register @@ -19,4 +19,4 @@ Building library for q-0.1.0.0... # Setup haddock Preprocessing library for q-0.1.0.0... Running Haddock on library for q-0.1.0.0... -Documentation created: ../setup.dist/work/q/dist/doc/html/q/ +Documentation created: ../setup.dist/work/q/dist/doc/html/q diff --git a/cabal-testsuite/PackageTests/Haddock/setup.cabal.out b/cabal-testsuite/PackageTests/Haddock/setup.cabal.out index a13ae638ac4..a55ef1a732a 100644 --- a/cabal-testsuite/PackageTests/Haddock/setup.cabal.out +++ b/cabal-testsuite/PackageTests/Haddock/setup.cabal.out @@ -3,4 +3,4 @@ Configuring Haddock-0.1... # Setup haddock Preprocessing library for Haddock-0.1... Running Haddock on library for Haddock-0.1... -Documentation created: setup.cabal.dist/work/dist/doc/html/Haddock/ +Documentation created: setup.cabal.dist/work/dist/doc/html/Haddock diff --git a/cabal-testsuite/PackageTests/Haddock/setup.out b/cabal-testsuite/PackageTests/Haddock/setup.out index a16722bc65c..550d84c45ae 100644 --- a/cabal-testsuite/PackageTests/Haddock/setup.out +++ b/cabal-testsuite/PackageTests/Haddock/setup.out @@ -3,4 +3,4 @@ Configuring Haddock-0.1... # Setup haddock Preprocessing library for Haddock-0.1... Running Haddock on library for Haddock-0.1... -Documentation created: setup.dist/work/dist/doc/html/Haddock/ +Documentation created: setup.dist/work/dist/doc/html/Haddock diff --git a/cabal-testsuite/PackageTests/HaddockArgs/quickjump.out b/cabal-testsuite/PackageTests/HaddockArgs/quickjump.out index f81b0b94852..c892ec8e80a 100644 --- a/cabal-testsuite/PackageTests/HaddockArgs/quickjump.out +++ b/cabal-testsuite/PackageTests/HaddockArgs/quickjump.out @@ -14,7 +14,7 @@ for sigs-0.1.0.0... Preprocessing library for sigs-0.1.0.0... Running Haddock on library instantiated with Data.Map = for sigs-0.1.0.0... -Documentation created: /quickjump.dist/work/./dist//sigs-0.1.0.0/dist/doc/html/sigs/ +Documentation created: /quickjump.dist/work/./dist//sigs-0.1.0.0/dist/doc/html/sigs Installing library in Configuring library for indef-0.1.0.0... Preprocessing library for indef-0.1.0.0... @@ -23,7 +23,7 @@ for indef-0.1.0.0... Preprocessing library for indef-0.1.0.0... Running Haddock on library instantiated with Data.Map = for indef-0.1.0.0... -Documentation created: /quickjump.dist/work/./dist//indef-0.1.0.0/dist/doc/html/indef/ +Documentation created: /quickjump.dist/work/./dist//indef-0.1.0.0/dist/doc/html/indef Installing library in Configuring library for example-1.0... Preprocessing library for example-1.0... @@ -32,4 +32,4 @@ for example-1.0... Preprocessing library for example-1.0... Running Haddock on library instantiated with Data.Map = for example-1.0... -Documentation created: /quickjump.dist/work/dist/build//ghc-/example-1.0/doc/html/example/ +Documentation created: /quickjump.dist/work/dist/build//ghc-/example-1.0/doc/html/example diff --git a/cabal-testsuite/PackageTests/HaddockBuildDepends/cabal.out b/cabal-testsuite/PackageTests/HaddockBuildDepends/cabal.out index 64f999e4368..8eff18e3d6c 100644 --- a/cabal-testsuite/PackageTests/HaddockBuildDepends/cabal.out +++ b/cabal-testsuite/PackageTests/HaddockBuildDepends/cabal.out @@ -17,11 +17,11 @@ Preprocessing library for lib-1... Building library for lib-1... Preprocessing library for lib-1... Running Haddock on library for lib-1... -Documentation created: /cabal.dist/work/./dist//lib-1/dist/doc/html/lib/ +Documentation created: /cabal.dist/work/./dist//lib-1/dist/doc/html/lib Installing library in Configuring library for a-0.1.0.0... Preprocessing library for a-0.1.0.0... Building library for a-0.1.0.0... Preprocessing library for a-0.1.0.0... Running Haddock on library for a-0.1.0.0... -Documentation created: /cabal.dist/work/dist/build//ghc-/a-0.1.0.0/doc/html/a/ +Documentation created: /cabal.dist/work/dist/build//ghc-/a-0.1.0.0/doc/html/a diff --git a/cabal-testsuite/PackageTests/HaddockNewline/setup.cabal.out b/cabal-testsuite/PackageTests/HaddockNewline/setup.cabal.out index 7db9a69eefe..57539271f24 100644 --- a/cabal-testsuite/PackageTests/HaddockNewline/setup.cabal.out +++ b/cabal-testsuite/PackageTests/HaddockNewline/setup.cabal.out @@ -3,4 +3,4 @@ Configuring HaddockNewline-0.1.0.0... # Setup haddock Preprocessing library for HaddockNewline-0.1.0.0... Running Haddock on library for HaddockNewline-0.1.0.0... -Documentation created: setup.cabal.dist/work/dist/doc/html/HaddockNewline/ +Documentation created: setup.cabal.dist/work/dist/doc/html/HaddockNewline diff --git a/cabal-testsuite/PackageTests/HaddockNewline/setup.out b/cabal-testsuite/PackageTests/HaddockNewline/setup.out index 57908512556..f18bb263e04 100644 --- a/cabal-testsuite/PackageTests/HaddockNewline/setup.out +++ b/cabal-testsuite/PackageTests/HaddockNewline/setup.out @@ -3,4 +3,4 @@ Configuring HaddockNewline-0.1.0.0... # Setup haddock Preprocessing library for HaddockNewline-0.1.0.0... Running Haddock on library for HaddockNewline-0.1.0.0... -Documentation created: setup.dist/work/dist/doc/html/HaddockNewline/ +Documentation created: setup.dist/work/dist/doc/html/HaddockNewline diff --git a/cabal-testsuite/PackageTests/HaddockProject/haddock-project.out b/cabal-testsuite/PackageTests/HaddockProject/haddock-project.out index 50ede874c75..bfa16bf91c5 100644 --- a/cabal-testsuite/PackageTests/HaddockProject/haddock-project.out +++ b/cabal-testsuite/PackageTests/HaddockProject/haddock-project.out @@ -4,10 +4,6 @@ Downloading the latest package list from test-local-repo Warning: haddock-project command is experimental, it might break in the future Resolving dependencies... Build profile: -w ghc- -O1 -In order, the following will be built: - - async-2.2.4 (lib) (requires build) - - a-0.1.0.0 (lib) (first run) -Build profile: -w ghc- -O1 In order, the following will be built: - async-2.2.4 (lib) (requires build) - a-0.1.0.0 (lib) (configuration changed) @@ -16,10 +12,10 @@ Preprocessing library for async-2.2.4... Building library for async-2.2.4... Preprocessing library for async-2.2.4... Running Haddock on library for async-2.2.4... -Documentation created: /dist-newstyle//async-2.2.4/dist/doc/html/async/ +Documentation created: /dist-newstyle//async-2.2.4/dist/doc/html/async Installing library in Configuring library for a-0.1.0.0... Preprocessing library for a-0.1.0.0... Running Haddock on library for a-0.1.0.0... -Documentation created: /dist-newstyle/build//ghc-/a-0.1.0.0/doc/html/a/ +Documentation created: /dist-newstyle/build//ghc-/a-0.1.0.0/doc/html/a Documentation created: haddocks/index.html diff --git a/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.cabal.out b/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.cabal.out index bdc57a81bfd..dbd8c26e948 100644 --- a/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.cabal.out +++ b/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.cabal.out @@ -18,10 +18,10 @@ Registering library 'foo-internal-after' for foo-0.1.0.0... # Setup haddock Preprocessing library 'foo-internal-before' for foo-0.1.0.0... Running Haddock on library 'foo-internal-before' for foo-0.1.0.0... -Documentation created: haddock.cabal.dist/work/dist/doc/html/foo/ +Documentation created: haddock.cabal.dist/work/dist/doc/html/foo/foo-internal-before Preprocessing library for foo-0.1.0.0... Running Haddock on library for foo-0.1.0.0... -Documentation created: haddock.cabal.dist/work/dist/doc/html/foo/ +Documentation created: haddock.cabal.dist/work/dist/doc/html/foo Preprocessing library 'foo-internal-after' for foo-0.1.0.0... Running Haddock on library 'foo-internal-after' for foo-0.1.0.0... -Documentation created: haddock.cabal.dist/work/dist/doc/html/foo/ +Documentation created: haddock.cabal.dist/work/dist/doc/html/foo/foo-internal-after diff --git a/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.out b/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.out index 44ee7824244..6259fcfeb0c 100644 --- a/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.out +++ b/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.out @@ -18,10 +18,10 @@ Registering library 'foo-internal-after' for foo-0.1.0.0... # Setup haddock Preprocessing library 'foo-internal-before' for foo-0.1.0.0... Running Haddock on library 'foo-internal-before' for foo-0.1.0.0... -Documentation created: haddock.dist/work/dist/doc/html/foo/ +Documentation created: haddock.dist/work/dist/doc/html/foo/foo-internal-before Preprocessing library for foo-0.1.0.0... Running Haddock on library for foo-0.1.0.0... -Documentation created: haddock.dist/work/dist/doc/html/foo/ +Documentation created: haddock.dist/work/dist/doc/html/foo Preprocessing library 'foo-internal-after' for foo-0.1.0.0... Running Haddock on library 'foo-internal-after' for foo-0.1.0.0... -Documentation created: haddock.dist/work/dist/doc/html/foo/ +Documentation created: haddock.dist/work/dist/doc/html/foo/foo-internal-after diff --git a/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/cabal.out b/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/cabal.out index ac34ca8e161..0683a3921ce 100644 --- a/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/cabal.out +++ b/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/cabal.out @@ -13,4 +13,4 @@ Installing library in Configuring library for B-0.1.0.0... Preprocessing library for B-0.1.0.0... Running Haddock on library for B-0.1.0.0... -Documentation created: /cabal.dist/work/dist/build//ghc-/B-0.1.0.0/doc/html/B/ +Documentation created: /cabal.dist/work/dist/build//ghc-/B-0.1.0.0/doc/html/B diff --git a/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockForHackageCmdOutput/cabal.out b/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockForHackageCmdOutput/cabal.out index e17593a966c..5a0ba914174 100644 --- a/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockForHackageCmdOutput/cabal.out +++ b/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockForHackageCmdOutput/cabal.out @@ -6,5 +6,5 @@ In order, the following will be built: Configuring library for A-0.0.0... Preprocessing library for A-0.0.0... Running Haddock on library for A-0.0.0... -Documentation created: /cabal.dist/work/dist/build//ghc-/A-0.0.0/doc/html/A-0.0.0-docs/, /cabal.dist/work/dist/build//ghc-/A-0.0.0/doc/html/A-0.0.0-docs/A.txt +Documentation created: /cabal.dist/work/dist/build//ghc-/A-0.0.0/doc/html/A-0.0.0-docs, /cabal.dist/work/dist/build//ghc-/A-0.0.0/doc/html/A-0.0.0-docs/A.txt Documentation tarball created: /cabal.dist/work/./dist/A-0.0.0-docs.tar.gz diff --git a/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputCmd/cabal.out b/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputCmd/cabal.out index 38e56384678..38614b49b84 100644 --- a/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputCmd/cabal.out +++ b/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputCmd/cabal.out @@ -8,4 +8,4 @@ In order, the following will be built: Configuring library for A-0.0.0... Preprocessing library for A-0.0.0... Running Haddock on library for A-0.0.0... -Documentation created: /docs/ +Documentation created: /docs/A diff --git a/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputCmd/cabal.test.hs b/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputCmd/cabal.test.hs index 1bfe939dab9..de59c2f90ee 100644 --- a/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputCmd/cabal.test.hs +++ b/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputCmd/cabal.test.hs @@ -8,4 +8,4 @@ main = cabalTest . withRepo "repo" $ do let docsDir = testDir "docs" liftIO (removePathForcibly docsDir) r <- cabal' "haddock" ["--haddock-output-dir=docs", "A"] - assertFindInFile "A minimal test package for testing haddock." (docsDir "index.html") + assertFindInFile "A minimal test package for testing haddock." (docsDir "A" "index.html") diff --git a/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputConfig/cabal.out b/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputConfig/cabal.out index 38e56384678..38614b49b84 100644 --- a/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputConfig/cabal.out +++ b/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputConfig/cabal.out @@ -8,4 +8,4 @@ In order, the following will be built: Configuring library for A-0.0.0... Preprocessing library for A-0.0.0... Running Haddock on library for A-0.0.0... -Documentation created: /docs/ +Documentation created: /docs/A diff --git a/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputConfig/cabal.test.hs b/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputConfig/cabal.test.hs index ba3a957ef60..db5b6d493a2 100644 --- a/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputConfig/cabal.test.hs +++ b/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputConfig/cabal.test.hs @@ -8,4 +8,4 @@ main = cabalTest . withRepo "repo" $ do let docsDir = testDir "docs" liftIO (removePathForcibly docsDir) r <- cabal' "haddock" ["A"] - assertFindInFile "A minimal test package for testing haddock." (docsDir "index.html") + assertFindInFile "A minimal test package for testing haddock." (docsDir "A" "index.html") diff --git a/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/cabal.out b/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/cabal.out index 07fc04a1119..32f39065358 100644 --- a/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/cabal.out +++ b/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/cabal.out @@ -11,9 +11,9 @@ Preprocessing library for A-0.1.0.0... Building library for A-0.1.0.0... Preprocessing library for A-0.1.0.0... Running Haddock on library for A-0.1.0.0... -Documentation created: /cabal.dist/work/./dist//A-0.1.0.0/dist/doc/html/A/ +Documentation created: /cabal.dist/work/./dist//A-0.1.0.0/dist/doc/html/A Installing library in Configuring library for B-0.1.0.0... Preprocessing library for B-0.1.0.0... Running Haddock on library for B-0.1.0.0... -Documentation created: /cabal.dist/work/dist/build//ghc-/B-0.1.0.0/doc/html/B/ +Documentation created: /cabal.dist/work/dist/build//ghc-/B-0.1.0.0/doc/html/B From c2f0a0e6ab0076c1ceb81b5fec4c634c905d0bfd Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 18 Jun 2024 09:59:47 +0200 Subject: [PATCH 030/207] haddock-project: copy extra-doc-files to the right directory When running haddock-project `extra-doc-files` should be copied to a subdirectories of the `argOutputDir` corresponding to the component. This doesn't affect `haddock` command. --- Cabal/src/Distribution/Simple/Haddock.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cabal/src/Distribution/Simple/Haddock.hs b/Cabal/src/Distribution/Simple/Haddock.hs index ab3c3fd1d8d..f7d47676e56 100644 --- a/Cabal/src/Distribution/Simple/Haddock.hs +++ b/Cabal/src/Distribution/Simple/Haddock.hs @@ -485,8 +485,9 @@ haddock_setupHooks for_ (extraDocFiles pkg_descr) $ \fpath -> do files <- matchDirFileGlob verbosity (specVersion pkg_descr) mbWorkDir fpath + let targetDir = Dir $ unDir' (argOutputDir commonArgs) haddockDirName haddockTarget pkg_descr for_ files $ - copyFileToCwd verbosity mbWorkDir (unDir $ argOutputDir commonArgs) + copyFileToCwd verbosity mbWorkDir (unDir targetDir) -- | Execute 'Haddock' configured with 'HaddocksFlags'. It is used to build -- index and contents for documentation of multiple packages. From 9bfa1f6e9ea945170c13a30e8220c43526a4b093 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Sat, 21 Oct 2023 22:50:24 +0200 Subject: [PATCH 031/207] haddock: added argComponentName to HaddockArgs Haddock should know the sublibrary name rather than just the package. For sublibraries `package_name:sublib_name` is used. The name is recorded in the `.haddock` file and used when haddock creates the `index.html` file, e.g. when called by `haddock-project` command. --- Cabal/src/Distribution/Simple/Haddock.hs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Cabal/src/Distribution/Simple/Haddock.hs b/Cabal/src/Distribution/Simple/Haddock.hs index f7d47676e56..d5713359e9d 100644 --- a/Cabal/src/Distribution/Simple/Haddock.hs +++ b/Cabal/src/Distribution/Simple/Haddock.hs @@ -107,6 +107,9 @@ data HaddockArgs = HaddockArgs -- ^ Path to the interface file, relative to argOutputDir, required. , argPackageName :: Flag PackageIdentifier -- ^ Package name, required. + , argComponentName :: Flag String + -- ^ Optional name used to construct haddock's `--package-name` option for + -- various components (tests suites, sublibriaries, etc). , argHideModules :: (All, [ModuleName.ModuleName]) -- ^ (Hide modules ?, modules to hide) , argIgnoreExports :: Any @@ -723,6 +726,7 @@ fromLibrary verbosity haddockArtifactsDirs lbi clbi htmlTemplate haddockTarget p args' { argHideModules = (mempty, otherModules (libBuildInfo lib)) , argTitle = Flag $ haddockPackageLibraryName pkg_descr lib + , argComponentName = toFlag (haddockPackageLibraryName' (pkgName (package pkg_descr)) (libName lib)) , -- we need to accommodate for `argOutputDir`, see `haddockLibraryPath` argBaseUrl = case (libName lib, argBaseUrl args') of (LSubLibName _, Flag url) -> Flag $ ".." url @@ -1048,7 +1052,10 @@ renderPureArgs version comp platform args = maybe [] ( \pkg -> - [ "--package-name=" ++ prettyShow (pkgName pkg) + [ "--package-name=" + ++ case argComponentName args of + Flag name -> name + _ -> prettyShow (pkgName pkg) , "--package-version=" ++ prettyShow (pkgVersion pkg) ] ) From aacc2b65e5cb51b8481ddc6b0652c7aecd7a5907 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 18 Jun 2024 20:08:13 +0200 Subject: [PATCH 032/207] haddock: added --use-unicode flag `--use-unicode` is added to `cabal haddock` and `cabal haddock-project`. One cannot simply use `--haddock-option="--use-unicode"` because it makes haddock to fail when building indexes. --- Cabal/src/Distribution/Simple/Haddock.hs | 4 ++++ Cabal/src/Distribution/Simple/Setup/Haddock.hs | 18 ++++++++++++++++++ .../Distribution/Client/CmdHaddockProject.hs | 2 ++ .../src/Distribution/Client/Config.hs | 1 + .../src/Distribution/Client/PackageHash.hs | 2 ++ .../Client/ProjectConfig/Legacy.hs | 4 ++++ .../Distribution/Client/ProjectConfig/Types.hs | 1 + .../src/Distribution/Client/ProjectPlanning.hs | 3 +++ .../Client/ProjectPlanning/Types.hs | 1 + cabal-install/src/Distribution/Client/Setup.hs | 1 + cabal-install/tests/IntegrationTests2.hs | 1 + .../Distribution/Client/ProjectConfig.hs | 5 +++++ doc/cabal-project-description-file.rst | 6 ++++++ test/IntegrationTests2/config/default-config | 1 + .../nix-config/default-config | 1 + tests/IntegrationTests2/config/default-config | 1 + .../nix-config/default-config | 1 + 17 files changed, 53 insertions(+) diff --git a/Cabal/src/Distribution/Simple/Haddock.hs b/Cabal/src/Distribution/Simple/Haddock.hs index d5713359e9d..df637ae9c3c 100644 --- a/Cabal/src/Distribution/Simple/Haddock.hs +++ b/Cabal/src/Distribution/Simple/Haddock.hs @@ -155,6 +155,8 @@ data HaddockArgs = HaddockArgs -- ^ Modules to process. , argResourcesDir :: Flag String -- ^ haddock's static \/ auxiliary files. + , argUseUnicode :: Flag Bool + -- ^ haddock's `--use-unicode` flag } deriving (Generic) @@ -554,6 +556,7 @@ fromFlags env flags = os -> os , argOutputDir = maybe mempty (Dir . getSymbolicPath) . flagToMaybe $ setupDistPref commonFlags , argGhcOptions = mempty{ghcOptExtra = ghcArgs} + , argUseUnicode = haddockUseUnicode flags } where ghcArgs = fromMaybe [] . lookup "ghc" . haddockProgramArgs $ flags @@ -1133,6 +1136,7 @@ renderPureArgs version comp platform args = -- We pass this option by default to haddock to avoid recompilation -- See Note [Hi Haddock Recompilation Avoidance] ["--no-tmp-comp-dir" | version >= mkVersion [2, 28, 0]] + , bool ["--use-unicode"] [] . fromFlagOrDefault False . argUseUnicode $ args ] where -- See Note [Symbolic paths] in Distribution.Utils.Path diff --git a/Cabal/src/Distribution/Simple/Setup/Haddock.hs b/Cabal/src/Distribution/Simple/Setup/Haddock.hs index c896288b431..e8d7ba54a20 100644 --- a/Cabal/src/Distribution/Simple/Setup/Haddock.hs +++ b/Cabal/src/Distribution/Simple/Setup/Haddock.hs @@ -115,6 +115,7 @@ data HaddockFlags = HaddockFlags , haddockBaseUrl :: Flag String , haddockResourcesDir :: Flag String , haddockOutputDir :: Flag FilePath + , haddockUseUnicode :: Flag Bool } deriving (Show, Generic, Typeable) @@ -170,6 +171,7 @@ defaultHaddockFlags = , haddockBaseUrl = NoFlag , haddockResourcesDir = NoFlag , haddockOutputDir = NoFlag + , haddockUseUnicode = Flag False } haddockCommand :: CommandUI HaddockFlags @@ -378,6 +380,13 @@ haddockOptions showOrParseArgs = haddockOutputDir (\v flags -> flags{haddockOutputDir = v}) (reqArgFlag "DIR") + , option + "" + ["use-unicode"] + "Pass --use-unicode option to haddock" + haddockUseUnicode + (\v flags -> flags{haddockUseUnicode = v}) + trueArg ] emptyHaddockFlags :: HaddockFlags @@ -441,6 +450,7 @@ data HaddockProjectFlags = HaddockProjectFlags , haddockProjectVerbosity :: Flag Verbosity , -- haddockBaseUrl is not supported, a fixed value is provided haddockProjectResourcesDir :: Flag String + , haddockProjectUseUnicode :: Flag Bool } deriving (Show, Generic, Typeable) @@ -465,6 +475,7 @@ defaultHaddockProjectFlags = , haddockProjectVerbosity = Flag normal , haddockProjectResourcesDir = NoFlag , haddockProjectInterfaces = NoFlag + , haddockProjectUseUnicode = NoFlag } haddockProjectCommand :: CommandUI HaddockProjectFlags @@ -611,6 +622,13 @@ haddockProjectOptions _showOrParseArgs = haddockProjectResourcesDir (\v flags -> flags{haddockProjectResourcesDir = v}) (reqArgFlag "DIR") + , option + "" + ["use-unicode"] + "Pass --use-unicode option to haddock" + haddockProjectUseUnicode + (\v flags -> flags{haddockProjectUseUnicode = v}) + trueArg ] emptyHaddockProjectFlags :: HaddockProjectFlags diff --git a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs index 0b88a795810..510d4084be6 100644 --- a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs +++ b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs @@ -158,6 +158,7 @@ haddockProjectAction flags _extraArgs globalFlags = do else NoFlag , haddockKeepTempFiles = haddockProjectKeepTempFiles flags , haddockResourcesDir = haddockProjectResourcesDir flags + , haddockUseUnicode = haddockProjectUseUnicode flags -- NOTE: we don't pass `haddockOutputDir`. If we do, we'll need to -- make sure `InstalledPackageInfo` contains the right path to -- haddock interfaces. Instead we build documentation inside @@ -380,6 +381,7 @@ haddockProjectAction flags _extraArgs globalFlags = do ) | (url, interfacePath, visibility) <- packageInfos' ] + , haddockProjectUseUnicode = NoFlag } createHaddockIndex verbosity diff --git a/cabal-install/src/Distribution/Client/Config.hs b/cabal-install/src/Distribution/Client/Config.hs index 951155d365b..2faf9e1756d 100644 --- a/cabal-install/src/Distribution/Client/Config.hs +++ b/cabal-install/src/Distribution/Client/Config.hs @@ -634,6 +634,7 @@ instance Semigroup SavedConfig where , haddockBaseUrl = combine haddockBaseUrl , haddockResourcesDir = combine haddockResourcesDir , haddockOutputDir = combine haddockOutputDir + , haddockUseUnicode = combine haddockUseUnicode } where combine = combine' savedHaddockFlags diff --git a/cabal-install/src/Distribution/Client/PackageHash.hs b/cabal-install/src/Distribution/Client/PackageHash.hs index 2e7b9320e3d..1b30b125204 100644 --- a/cabal-install/src/Distribution/Client/PackageHash.hs +++ b/cabal-install/src/Distribution/Client/PackageHash.hs @@ -240,6 +240,7 @@ data PackageHashConfigInputs = PackageHashConfigInputs , pkgHashHaddockBaseUrl :: Maybe String , pkgHashHaddockResourcesDir :: Maybe String , pkgHashHaddockOutputDir :: Maybe FilePath + , pkgHashHaddockUseUnicode :: Bool -- TODO: [required eventually] pkgHashToolsVersions ? -- TODO: [required eventually] pkgHashToolsExtraOptions ? } @@ -349,6 +350,7 @@ renderPackageHashInputs , opt "haddock-base-url" Nothing (fromMaybe "") pkgHashHaddockBaseUrl , opt "haddock-resources-dir" Nothing (fromMaybe "") pkgHashHaddockResourcesDir , opt "haddock-output-dir" Nothing (fromMaybe "") pkgHashHaddockOutputDir + , opt "haddock-use-unicode" False prettyShow pkgHashHaddockUseUnicode ] ++ Map.foldrWithKey (\prog args acc -> opt (prog ++ "-options") [] unwords args : acc) [] pkgHashProgramArgs where diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs index 0de745526c1..fe8ea884ccc 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs @@ -508,6 +508,7 @@ commandLineFlagsToProjectConfig globalFlags NixStyleFlags{..} clientInstallFlags , packageConfigHaddockInternal = packageConfigHaddockInternal pc , packageConfigHaddockQuickJump = packageConfigHaddockQuickJump pc , packageConfigHaddockLinkedSource = packageConfigHaddockLinkedSource pc + , packageConfigHaddockUseUnicode = packageConfigHaddockUseUnicode pc } ) @@ -824,6 +825,7 @@ convertLegacyPerPackageFlags , haddockBaseUrl = packageConfigHaddockBaseUrl , haddockResourcesDir = packageConfigHaddockResourcesDir , haddockOutputDir = packageConfigHaddockOutputDir + , haddockUseUnicode = packageConfigHaddockUseUnicode } = haddockFlags TestFlags @@ -1225,6 +1227,7 @@ convertToLegacyPerPackageConfig PackageConfig{..} = , haddockBaseUrl = packageConfigHaddockBaseUrl , haddockResourcesDir = packageConfigHaddockResourcesDir , haddockOutputDir = packageConfigHaddockOutputDir + , haddockUseUnicode = packageConfigHaddockUseUnicode } testFlags = @@ -1628,6 +1631,7 @@ legacyPackageConfigFieldDescrs = , "base-url" , "resources-dir" , "output-dir" + , "use-unicode" ] . commandOptionsToFields ) diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs index 08c27b00a3d..4c2555c472c 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs @@ -308,6 +308,7 @@ data PackageConfig = PackageConfig , packageConfigHaddockBaseUrl :: Flag String -- TODO: [required eventually] use this , packageConfigHaddockResourcesDir :: Flag String -- TODO: [required eventually] use this , packageConfigHaddockOutputDir :: Flag FilePath -- TODO: [required eventually] use this + , packageConfigHaddockUseUnicode :: Flag Bool -- TODO: [required eventually] use this , packageConfigHaddockForHackage :: Flag HaddockTarget , -- Test options packageConfigTestHumanLog :: Flag PathTemplate diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 19f9907703c..23fed2c5bd1 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -2298,6 +2298,7 @@ elaborateInstallPlan elabHaddockBaseUrl = perPkgOptionMaybe pkgid packageConfigHaddockBaseUrl elabHaddockResourcesDir = perPkgOptionMaybe pkgid packageConfigHaddockResourcesDir elabHaddockOutputDir = perPkgOptionMaybe pkgid packageConfigHaddockOutputDir + elabHaddockUseUnicode = perPkgOptionFlag pkgid False packageConfigHaddockUseUnicode elabTestMachineLog = perPkgOptionMaybe pkgid packageConfigTestMachineLog elabTestHumanLog = perPkgOptionMaybe pkgid packageConfigTestHumanLog @@ -4244,6 +4245,7 @@ setupHsHaddockFlags , haddockBaseUrl = maybe mempty toFlag elabHaddockBaseUrl , haddockResourcesDir = maybe mempty toFlag elabHaddockResourcesDir , haddockOutputDir = maybe mempty toFlag elabHaddockOutputDir + , haddockUseUnicode = toFlag elabHaddockUseUnicode } setupHsHaddockArgs :: ElaboratedConfiguredPackage -> [String] @@ -4402,6 +4404,7 @@ packageHashConfigInputs shared@ElaboratedSharedConfig{..} pkg = , pkgHashHaddockBaseUrl = elabHaddockBaseUrl , pkgHashHaddockResourcesDir = elabHaddockResourcesDir , pkgHashHaddockOutputDir = elabHaddockOutputDir + , pkgHashHaddockUseUnicode = elabHaddockUseUnicode } where ElaboratedConfiguredPackage{..} = normaliseConfiguredPackage shared pkg diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs index 352e35d4150..e7efc4cc486 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs @@ -302,6 +302,7 @@ data ElaboratedConfiguredPackage = ElaboratedConfiguredPackage , elabHaddockBaseUrl :: Maybe String , elabHaddockResourcesDir :: Maybe String , elabHaddockOutputDir :: Maybe FilePath + , elabHaddockUseUnicode :: Bool , elabTestMachineLog :: Maybe PathTemplate , elabTestHumanLog :: Maybe PathTemplate , elabTestShowDetails :: Maybe TestShowDetails diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index a8db5c98106..8d594b2a414 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -2446,6 +2446,7 @@ haddockOptions showOrParseArgs = , "base-url" , "resources-dir" , "output-dir" + , "use-unicode" ] ] diff --git a/cabal-install/tests/IntegrationTests2.hs b/cabal-install/tests/IntegrationTests2.hs index b5b49053b6d..c4341ed72ef 100644 --- a/cabal-install/tests/IntegrationTests2.hs +++ b/cabal-install/tests/IntegrationTests2.hs @@ -2101,6 +2101,7 @@ testConfigOptionComments = do " -- base-url" @=? findLineWith True "base-url" defaultConfigFile " -- resources-dir" @=? findLineWith True "resources-dir" defaultConfigFile " -- output-dir" @=? findLineWith True "output-dir" defaultConfigFile + " -- use-unicode" @=? findLineWith True "use-unicode" defaultConfigFile " -- interactive" @=? findLineWith True "interactive" defaultConfigFile " -- quiet" @=? findLineWith True "quiet" defaultConfigFile diff --git a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs index 2c4de05a9a2..04dd86fc92a 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs @@ -727,6 +727,7 @@ instance Arbitrary PackageConfig where <*> arbitrary <*> arbitrary <*> arbitrary + <*> arbitrary <*> arbitraryFlag arbitraryShortToken <*> arbitrary <*> shortListOf 5 arbitrary @@ -795,6 +796,7 @@ instance Arbitrary PackageConfig where , packageConfigHaddockBaseUrl = x55 , packageConfigHaddockResourcesDir = x56 , packageConfigHaddockOutputDir = x57 + , packageConfigHaddockUseUnicode = x58 , packageConfigTestHumanLog = x44 , packageConfigTestMachineLog = x45 , packageConfigTestShowDetails = x46 @@ -859,6 +861,7 @@ instance Arbitrary PackageConfig where , packageConfigHaddockBaseUrl = x55' , packageConfigHaddockResourcesDir = x56' , packageConfigHaddockOutputDir = x57' + , packageConfigHaddockUseUnicode = x58' , packageConfigTestHumanLog = x44' , packageConfigTestMachineLog = x45' , packageConfigTestShowDetails = x46' @@ -881,6 +884,7 @@ instance Arbitrary PackageConfig where , (x44', x45', x46', x47', x48', x49', x51', x52', x54', x55') , x56' , x57' + , x58' ) ) <- shrink @@ -906,6 +910,7 @@ instance Arbitrary PackageConfig where , (x44, x45, x46, x47, x48, x49, x51, x52, x54, x55) , x56 , x57 + , x58 ) ) ] diff --git a/doc/cabal-project-description-file.rst b/doc/cabal-project-description-file.rst index cd80cd3ab72..c2f224cf421 100644 --- a/doc/cabal-project-description-file.rst +++ b/doc/cabal-project-description-file.rst @@ -1616,6 +1616,12 @@ running ``setup haddock``. This flag is provided as a technology preview and is subject to change in the next releases. +.. cfg-field:: haddock-use-unicode: boolean + --haddock-use-unicode + :synopsis: Pass --use-unicode option to haddock. + + Generate HTML documentation which contains unicode characters. + .. cfg-field:: haddock-resources-dir: DIR --haddock-resources-dir=DIR :synopsis: Location of Haddock's static/auxiliary files. diff --git a/test/IntegrationTests2/config/default-config b/test/IntegrationTests2/config/default-config index e74a2c97764..57ae6f847ec 100644 --- a/test/IntegrationTests2/config/default-config +++ b/test/IntegrationTests2/config/default-config @@ -143,6 +143,7 @@ haddock -- base-url: -- resources-dir: -- output-dir: + -- use-unicode: False init -- interactive: False diff --git a/test/IntegrationTests2/nix-config/default-config b/test/IntegrationTests2/nix-config/default-config index e74a2c97764..57ae6f847ec 100644 --- a/test/IntegrationTests2/nix-config/default-config +++ b/test/IntegrationTests2/nix-config/default-config @@ -143,6 +143,7 @@ haddock -- base-url: -- resources-dir: -- output-dir: + -- use-unicode: False init -- interactive: False diff --git a/tests/IntegrationTests2/config/default-config b/tests/IntegrationTests2/config/default-config index 8d5b2ea1df6..94a10d9c113 100644 --- a/tests/IntegrationTests2/config/default-config +++ b/tests/IntegrationTests2/config/default-config @@ -145,6 +145,7 @@ haddock -- base-url: -- resources-dir: -- output-dir: + -- use-unicode: False init -- interactive: False diff --git a/tests/IntegrationTests2/nix-config/default-config b/tests/IntegrationTests2/nix-config/default-config index e74a2c97764..57ae6f847ec 100644 --- a/tests/IntegrationTests2/nix-config/default-config +++ b/tests/IntegrationTests2/nix-config/default-config @@ -143,6 +143,7 @@ haddock -- base-url: -- resources-dir: -- output-dir: + -- use-unicode: False init -- interactive: False From eb160107d8a529259f463a9f505017c0f47624f4 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Thu, 20 Jun 2024 08:12:51 +0200 Subject: [PATCH 033/207] haddock: refactored prologue args --- Cabal/src/Distribution/Simple/Haddock.hs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Cabal/src/Distribution/Simple/Haddock.hs b/Cabal/src/Distribution/Simple/Haddock.hs index df637ae9c3c..facfe14a6be 100644 --- a/Cabal/src/Distribution/Simple/Haddock.hs +++ b/Cabal/src/Distribution/Simple/Haddock.hs @@ -993,20 +993,18 @@ renderArgs verbosity mbWorkDir tmpFileOpts version comp platform args k = do renderedArgs (\responseFileName -> k ["@" ++ responseFileName] result) else k renderedArgs result - case argPrologue args of - Flag prologueText -> + case (argPrologueFile args, argPrologue args) of + (Flag pfile, _) -> + withPrologueArgs ["--prologue=" ++ pfile] + (_, Flag prologueText) -> withTempFileEx tmpFileOpts mbWorkDir outputDir "haddock-prologue.txt" $ \prologueFileName h -> do when haddockSupportsUTF8 (hSetEncoding h utf8) hPutStrLn h prologueText hClose h withPrologueArgs ["--prologue=" ++ u prologueFileName] - _ -> - withPrologueArgs - ( case argPrologueFile args of - Flag pfile -> ["--prologue=" ++ pfile] - _ -> [] - ) + (NoFlag, NoFlag) -> + withPrologueArgs [] where -- See Note [Symbolic paths] in Distribution.Utils.Path i = interpretSymbolicPath mbWorkDir From 759325a7e8c72b1dea07d19ad781c9a5c5d9e926 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 19 Jun 2024 22:23:46 +0200 Subject: [PATCH 034/207] haddock-project: test suites and benchmarks Link test suites & benchmarks from the index.html; Provide the right `--base-url` flag for them. --- Cabal/src/Distribution/Simple/BuildPaths.hs | 62 +++++++ Cabal/src/Distribution/Simple/Haddock.hs | 166 ++++++++++++++++-- .../Distribution/Client/CmdHaddockProject.hs | 22 ++- 3 files changed, 238 insertions(+), 12 deletions(-) diff --git a/Cabal/src/Distribution/Simple/BuildPaths.hs b/Cabal/src/Distribution/Simple/BuildPaths.hs index c0305b7e9f0..0875de87c91 100644 --- a/Cabal/src/Distribution/Simple/BuildPaths.hs +++ b/Cabal/src/Distribution/Simple/BuildPaths.hs @@ -20,6 +20,8 @@ module Distribution.Simple.BuildPaths , buildInfoPref , haddockDirName , haddockLibraryDirPath + , haddockTestDirPath + , haddockBenchmarkDirPath , hscolourPref , haddockPref , autogenPackageModulesDir @@ -49,6 +51,8 @@ module Distribution.Simple.BuildPaths , getSourceFiles , getLibSourceFiles , getExeSourceFiles + , getTestSourceFiles + , getBenchmarkSourceFiles , getFLibSourceFiles , exeBuildDir , flibBuildDir @@ -119,6 +123,22 @@ haddockLibraryDirPath haddockTarget pkg_descr lib = haddockDirName haddockTarget pkg_descr prettyShow sublib_name _ -> haddockDirName haddockTarget pkg_descr +haddockTestDirPath + :: HaddockTarget + -> PackageDescription + -> TestSuite + -> FilePath +haddockTestDirPath haddockTarget pkg_descr test = + haddockDirName haddockTarget pkg_descr prettyShow (testName test) + +haddockBenchmarkDirPath + :: HaddockTarget + -> PackageDescription + -> Benchmark + -> FilePath +haddockBenchmarkDirPath haddockTarget pkg_descr bench = + haddockDirName haddockTarget pkg_descr prettyShow (benchmarkName bench) + -- | The directory to which generated haddock documentation should be written. haddockPref :: HaddockTarget @@ -234,6 +254,48 @@ getExeSourceFiles verbosity lbi exe clbi = do : coerceSymbolicPath (exeBuildDir lbi exe) : hsSourceDirs bi +getTestSourceFiles + :: Verbosity + -> LocalBuildInfo + -> TestSuite + -> ComponentLocalBuildInfo + -> IO [(ModuleName.ModuleName, SymbolicPath Pkg 'File)] +getTestSourceFiles verbosity lbi test@TestSuite{testInterface = TestSuiteExeV10 _ path} clbi = do + moduleFiles <- getSourceFiles verbosity mbWorkDir searchpaths modules + srcMainPath <- findFileCwd verbosity mbWorkDir (hsSourceDirs bi) path + return ((ModuleName.main, srcMainPath) : moduleFiles) + where + mbWorkDir = mbWorkDirLBI lbi + bi = testBuildInfo test + modules = otherModules bi + searchpaths = + autogenComponentModulesDir lbi clbi + : autogenPackageModulesDir lbi + : coerceSymbolicPath (testBuildDir lbi test) + : hsSourceDirs bi +getTestSourceFiles _ _ _ _ = return [] + +getBenchmarkSourceFiles + :: Verbosity + -> LocalBuildInfo + -> Benchmark + -> ComponentLocalBuildInfo + -> IO [(ModuleName.ModuleName, SymbolicPath Pkg 'File)] +getBenchmarkSourceFiles verbosity lbi bench@Benchmark{benchmarkInterface = BenchmarkExeV10 _ path} clbi = do + moduleFiles <- getSourceFiles verbosity mbWorkDir searchpaths modules + srcMainPath <- findFileCwd verbosity mbWorkDir (hsSourceDirs bi) path + return ((ModuleName.main, srcMainPath) : moduleFiles) + where + mbWorkDir = mbWorkDirLBI lbi + bi = benchmarkBuildInfo bench + modules = otherModules bi + searchpaths = + autogenComponentModulesDir lbi clbi + : autogenPackageModulesDir lbi + : coerceSymbolicPath (benchmarkBuildDir lbi bench) + : hsSourceDirs bi +getBenchmarkSourceFiles _ _ _ _ = return [] + getFLibSourceFiles :: Verbosity -> LocalBuildInfo diff --git a/Cabal/src/Distribution/Simple/Haddock.hs b/Cabal/src/Distribution/Simple/Haddock.hs index facfe14a6be..ba025a85549 100644 --- a/Cabal/src/Distribution/Simple/Haddock.hs +++ b/Cabal/src/Distribution/Simple/Haddock.hs @@ -92,6 +92,7 @@ import Distribution.Verbosity import Distribution.Version import Control.Monad +import Data.Bool (bool) import Data.Either (rights) import System.Directory (doesDirectoryExist, doesFileExist) import System.FilePath (isAbsolute, normalise) @@ -483,8 +484,54 @@ haddock_setupHooks ) >> return index CExe _ -> when (flag haddockExecutables) (smsg >> doExe component) >> return index - CTest _ -> when (flag haddockTestSuites) (smsg >> doExe component) >> return index - CBench _ -> when (flag haddockBenchmarks) (smsg >> doExe component) >> return index + CTest test -> do + when (flag haddockTestSuites) $ do + smsg + testArgs <- + fromTest + verbosity + haddockArtifactsDirs + lbi' + clbi + htmlTemplate + haddockTarget + pkg_descr + test + commonArgs + runHaddock + verbosity + mbWorkDir + tmpFileOpts + comp + platform + haddockProg + True + testArgs + return index + CBench bench -> do + when (flag haddockBenchmarks) $ do + smsg + benchArgs <- + fromBenchmark + verbosity + haddockArtifactsDirs + lbi' + clbi + htmlTemplate + haddockTarget + pkg_descr + bench + commonArgs + runHaddock + verbosity + mbWorkDir + tmpFileOpts + comp + platform + haddockProg + True + benchArgs + return index return ipi @@ -792,6 +839,106 @@ fromExecutable verbosity haddockArtifactsDirs lbi clbi htmlTemplate haddockTarge NoFlag -> NoFlag } +fromTest + :: Verbosity + -> (SymbolicPath Pkg (Path.Dir Artifacts), SymbolicPath Pkg (Path.Dir Artifacts), SymbolicPath Pkg (Path.Dir Artifacts)) + -- ^ Directories for -hidir, -odir, and -stubdir to GHC through Haddock. + -- See Note [Hi Haddock Recompilation Avoidance] + -> LocalBuildInfo + -> ComponentLocalBuildInfo + -> Maybe PathTemplate + -- ^ template for HTML location + -> HaddockTarget + -> PackageDescription + -> TestSuite + -> HaddockArgs + -- ^ common args + -> IO HaddockArgs +fromTest verbosity haddockArtifactsDirs lbi clbi htmlTemplate haddockTarget pkg_descr test commonArgs = do + inFiles <- map snd `fmap` getTestSourceFiles verbosity lbi test clbi + args <- + mkHaddockArgs + verbosity + haddockArtifactsDirs + lbi + clbi + htmlTemplate + inFiles + (testBuildInfo test) + let args' = + commonArgs + <> args + { argOutputDir = + Dir $ + haddockDirName haddockTarget pkg_descr + unUnqualComponentName (testName test) + } + return + args' + { argTitle = Flag $ prettyShow (packageName pkg_descr) + , argComponentName = Flag $ prettyShow (packageName pkg_descr) ++ ":" ++ unUnqualComponentName (testName test) + , -- we need to accommodate `argOutputDir` + argBaseUrl = case argBaseUrl args' of + Flag url -> Flag $ ".." url + NoFlag -> NoFlag + , argContents = case argContents args' of + Flag url -> Flag $ ".." url + NoFlag -> NoFlag + , argIndex = case argIndex args' of + Flag url -> Flag $ ".." url + NoFlag -> NoFlag + } + +fromBenchmark + :: Verbosity + -> (SymbolicPath Pkg (Path.Dir Artifacts), SymbolicPath Pkg (Path.Dir Artifacts), SymbolicPath Pkg (Path.Dir Artifacts)) + -- ^ Directories for -hidir, -odir, and -stubdir to GHC through Haddock. + -- See Note [Hi Haddock Recompilation Avoidance] + -> LocalBuildInfo + -> ComponentLocalBuildInfo + -> Maybe PathTemplate + -- ^ template for HTML location + -> HaddockTarget + -> PackageDescription + -> Benchmark + -> HaddockArgs + -- ^ common args + -> IO HaddockArgs +fromBenchmark verbosity haddockArtifactsDirs lbi clbi htmlTemplate haddockTarget pkg_descr bench commonArgs = do + inFiles <- map snd `fmap` getBenchmarkSourceFiles verbosity lbi bench clbi + args <- + mkHaddockArgs + verbosity + haddockArtifactsDirs + lbi + clbi + htmlTemplate + inFiles + (benchmarkBuildInfo bench) + let args' = + commonArgs + <> args + { argOutputDir = + Dir $ + haddockDirName haddockTarget pkg_descr + unUnqualComponentName (benchmarkName bench) + } + return + args' + { argTitle = Flag $ prettyShow (packageName pkg_descr) + , argComponentName = Flag $ prettyShow (packageName pkg_descr) ++ ":" ++ unUnqualComponentName (benchmarkName bench) + , -- we need to accommodate `argOutputDir` + argBaseUrl = case argBaseUrl args' of + Flag url -> Flag $ ".." url + NoFlag -> NoFlag + , argContents = case argContents args' of + Flag url -> Flag $ ".." url + NoFlag -> NoFlag + , argIndex = case argIndex args' of + Flag url -> Flag $ ".." url + NoFlag -> NoFlag + } + fromForeignLib :: Verbosity -> (SymbolicPath Pkg (Path.Dir Artifacts), SymbolicPath Pkg (Path.Dir Artifacts), SymbolicPath Pkg (Path.Dir Artifacts)) @@ -1068,10 +1215,10 @@ renderPureArgs version comp platform args = , [ "--quickjump" | isVersion 2 19, True <- flagToList . argQuickJump $ args ] , ["--hyperlinked-source" | isHyperlinkedSource] - , (\(All b, xs) -> bool (map (("--hide=" ++) . prettyShow) xs) [] b) + , (\(All b, xs) -> bool [] (map (("--hide=" ++) . prettyShow) xs) b) . argHideModules $ args - , bool ["--ignore-all-exports"] [] . getAny . argIgnoreExports $ args + , bool [] ["--ignore-all-exports"] . getAny . argIgnoreExports $ args , -- Haddock's --source-* options are ignored once --hyperlinked-source is -- set. -- See https://haskell-haddock.readthedocs.io/en/latest/invoking.html#cmdoption-hyperlinked-source @@ -1095,11 +1242,11 @@ renderPureArgs version comp platform args = $ args , maybe [] ((: []) . ("--css=" ++)) . flagToMaybe . argCssFile $ args , maybe [] ((: []) . ("--use-contents=" ++)) . flagToMaybe . argContents $ args - , bool ["--gen-contents"] [] . fromFlagOrDefault False . argGenContents $ args + , bool [] ["--gen-contents"] . fromFlagOrDefault False . argGenContents $ args , maybe [] ((: []) . ("--use-index=" ++)) . flagToMaybe . argIndex $ args - , bool ["--gen-index"] [] . fromFlagOrDefault False . argGenIndex $ args + , bool [] ["--gen-index"] . fromFlagOrDefault False . argGenIndex $ args , maybe [] ((: []) . ("--base-url=" ++)) . flagToMaybe . argBaseUrl $ args - , bool [] [verbosityFlag] . getAny . argVerbose $ args + , bool [verbosityFlag] [] . getAny . argVerbose $ args , map (\o -> case o of Hoogle -> "--hoogle"; Html -> "--html") . fromFlagOrDefault [] . argOutput @@ -1111,8 +1258,8 @@ renderPureArgs version comp platform args = ( (: []) . ("--title=" ++) . ( bool - (++ " (internal documentation)") id + (++ " (internal documentation)") (getAny $ argIgnoreExports args) ) ) @@ -1134,7 +1281,7 @@ renderPureArgs version comp platform args = -- We pass this option by default to haddock to avoid recompilation -- See Note [Hi Haddock Recompilation Avoidance] ["--no-tmp-comp-dir" | version >= mkVersion [2, 28, 0]] - , bool ["--use-unicode"] [] . fromFlagOrDefault False . argUseUnicode $ args + , bool [] ["--use-unicode"] . fromFlagOrDefault False . argUseUnicode $ args ] where -- See Note [Symbolic paths] in Distribution.Utils.Path @@ -1173,7 +1320,6 @@ renderPureArgs version comp platform args = ] ) - bool a b c = if c then a else b isVersion major minor = version >= mkVersion [major, minor] verbosityFlag | isVersion 2 5 = "--verbosity=1" diff --git a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs index 510d4084be6..f632e8b7caa 100644 --- a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs +++ b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs @@ -53,10 +53,12 @@ import Distribution.Client.Setup import Distribution.Client.TargetProblem (TargetProblem (..)) import Distribution.Simple.BuildPaths - ( haddockDirName + ( haddockBenchmarkDirPath + , haddockDirName , haddockLibraryDirPath , haddockLibraryPath , haddockPath + , haddockTestDirPath ) import Distribution.Simple.Command ( CommandUI (..) @@ -95,7 +97,7 @@ import Distribution.Simple.Utils , warn ) import Distribution.Types.InstalledPackageInfo (InstalledPackageInfo (..)) -import Distribution.Types.PackageDescription (PackageDescription (subLibraries)) +import Distribution.Types.PackageDescription (PackageDescription (benchmarks, subLibraries, testSuites)) import Distribution.Types.PackageId (pkgName) import Distribution.Types.PackageName (unPackageName) import Distribution.Types.UnitId (unUnitId) @@ -312,6 +314,22 @@ haddockProjectAction flags _extraArgs globalFlags = do sublibDirPath haddockLibraryPath pkg_descr lib ] + ++ [ (testPath, testInterfacePath, Visible) + | test <- testSuites pkg_descr + , let testPath = haddockTestDirPath ForDevelopment pkg_descr test + testInterfacePath = + outputDir + testPath + haddockPath pkg_descr + ] + ++ [ (benchPath, benchInterfacePath, Visible) + | bench <- benchmarks pkg_descr + , let benchPath = haddockBenchmarkDirPath ForDevelopment pkg_descr bench + benchInterfacePath = + outputDir + benchPath + haddockPath pkg_descr + ] infos' <- mapM ( \x@(_, path, _) -> do From 8fb01ec0f8a19a336bd48b86eb5f7a5861dd0fdd Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 22 Mar 2024 19:23:06 +0100 Subject: [PATCH 035/207] haddock-project: added changelog.d entry --- changelog.d/pr-9821 | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 changelog.d/pr-9821 diff --git a/changelog.d/pr-9821 b/changelog.d/pr-9821 new file mode 100644 index 00000000000..bc3e9dcae50 --- /dev/null +++ b/changelog.d/pr-9821 @@ -0,0 +1,21 @@ +synopsis: `haddock-project` support for subcomponents +packages: cabal-install +prs: #9821 +issues: +significance: significant + +description: { + +- `haddock-project` handles sublibraries, test suites and benchmarks. +- `haddock` receives `--package-name` flag whcih allows to set names of + components which are included in the main `index.html` file. +- added `--use-unicode` flag to `haddock` and `haddock-project` commands. +- The directory structure of `./dist-newstyle` has changed. `haddock` + subcommand will install `package:sublib` component in a directory + `package/sublib` under `l/sublib/doc/html/`. This is important for + `haddock-project` command and in the future might will be useful for hackage + support of sublibraries. See + https://github.com/haskell/cabal/pull/9821#discussion_r1548557115. + +} + From a228d35425dc36d64c5c6e970d840e7189834541 Mon Sep 17 00:00:00 2001 From: Mike Pilgrem Date: Mon, 24 Jun 2024 19:54:18 +0100 Subject: [PATCH 036/207] Improve online docs for `includes:` field Bases: * https://downloads.haskell.org/~ghc/6.10.1/docs/html/users_guide/release-6-10-1.html * https://hackage.haskell.org/package/Cabal-2.0.0.2/changelog * https://github.com/haskell/cabal/commit/e1c39fc9ff4bf4eb8e956e2ee77da95d6cc73bbe --- doc/cabal-package-description-file.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/cabal-package-description-file.rst b/doc/cabal-package-description-file.rst index d560b69e05d..710765c6f1e 100644 --- a/doc/cabal-package-description-file.rst +++ b/doc/cabal-package-description-file.rst @@ -1954,6 +1954,11 @@ system-dependent values for these fields. Like :pkg-field:`ghc-prof-shared-options` but applies to GHCJS .. pkg-field:: includes: filename list + :since: 1.0 + :deprecated: 2.0 + + From GHC 6.10.1, :pkg-field:`includes` has no effect when compiling with + GHC. From Cabal 2.0, support for GHC versions before GHC 6.12 was removed. A list of header files to be included in any compilations via C. This field applies to both header files that are already installed From 0f0d24f92f48c4259e78f3667e198c40ec43e85f Mon Sep 17 00:00:00 2001 From: Artem Pelenitsyn Date: Wed, 3 Jul 2024 16:05:53 -0400 Subject: [PATCH 037/207] cabal-testsuite.cabal: bump custom-setup bounds on Cabal(-syntax) after the release --- cabal-testsuite/cabal-testsuite.cabal | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cabal-testsuite/cabal-testsuite.cabal b/cabal-testsuite/cabal-testsuite.cabal index 1c27e40c23c..bc890efb7e3 100644 --- a/cabal-testsuite/cabal-testsuite.cabal +++ b/cabal-testsuite/cabal-testsuite.cabal @@ -148,6 +148,6 @@ custom-setup -- and due to Custom complexity and ConstraintSetupCabalMaxVersion -- it has to be the latest release version plus -- you have to use the latest cabal-install release - setup-depends: Cabal == 3.10.*, - Cabal-syntax == 3.10.*, + setup-depends: Cabal == 3.12.*, + Cabal-syntax == 3.12.*, base, filepath, directory From 0f6b776ce1c69aa82bedf06213b4ce1ca3e7fd08 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Thu, 4 Jul 2024 11:11:48 +0100 Subject: [PATCH 038/207] ci: Use latest cabal-install for quick-jobs This matches the installation logic for the validate jobs. --- .github/workflows/quick-jobs.yml | 48 ++++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/workflows/quick-jobs.yml b/.github/workflows/quick-jobs.yml index 87e553176a1..82c3fbd1244 100644 --- a/.github/workflows/quick-jobs.yml +++ b/.github/workflows/quick-jobs.yml @@ -29,12 +29,12 @@ jobs: gen-spdx gen-spdx-exc steps: - - name: ghcup - run: | - ghcup --version - ghcup config set cache true - ghcup install ghc $GHC_FOR_QUICK_JOBS - ghcup set ghc $GHC_FOR_QUICK_JOBS + - name: Install primary compiler + uses: haskell-actions/setup@v2 + id: setup-haskell + with: + ghc-version: ${{ env.GHC_FOR_QUICK_JOBS }} + cabal-version: latest - name: Haskell versions run: | ghc --version @@ -72,12 +72,12 @@ jobs: name: Doctest Cabal runs-on: ubuntu-latest steps: - - name: ghcup - run: | - ghcup --version - ghcup config set cache true - ghcup install ghc $GHC_FOR_QUICK_JOBS - ghcup set ghc $GHC_FOR_QUICK_JOBS + - name: Install primary compiler + uses: haskell-actions/setup@v2 + id: setup-haskell + with: + ghc-version: ${{ env.GHC_FOR_QUICK_JOBS }} + cabal-version: latest - name: Haskell versions run: | ghc --version @@ -117,12 +117,12 @@ jobs: env: cabal_build: cabal build buildinfo-reference-generator steps: - - name: ghcup - run: | - ghcup --version - ghcup config set cache true - ghcup install ghc $GHC_FOR_QUICK_JOBS - ghcup set ghc $GHC_FOR_QUICK_JOBS + - name: Install primary compiler + uses: haskell-actions/setup@v2 + id: setup-haskell + with: + ghc-version: ${{ env.GHC_FOR_QUICK_JOBS }} + cabal-version: latest - name: Haskell versions run: | ghc --version @@ -154,12 +154,12 @@ jobs: name: Check Release Project runs-on: ubuntu-latest steps: - - name: ghcup - run: | - ghcup --version - ghcup config set cache true - ghcup install ghc $GHC_FOR_QUICK_JOBS - ghcup set ghc $GHC_FOR_QUICK_JOBS + - name: Install primary compiler + uses: haskell-actions/setup@v2 + id: setup-haskell + with: + ghc-version: ${{ env.GHC_FOR_QUICK_JOBS }} + cabal-version: latest - name: Haskell versions run: | ghc --version From 6ca27be5f0c18efdc4aecb153266558c26030ef0 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 1 Jul 2024 08:41:17 +0200 Subject: [PATCH 039/207] haddock-project: added `--all` switch Added `--all` (`--haddock-all`) switches for compatibility with `haddock` command. `--haddock-all` alias is added, since that's what is suggested by some warning messages. Fixes #10051 --- .../src/Distribution/Simple/Setup/Haddock.hs | 21 +++++++++++++++++++ changelog.d/issue-10051 | 4 ++++ 2 files changed, 25 insertions(+) create mode 100644 changelog.d/issue-10051 diff --git a/Cabal/src/Distribution/Simple/Setup/Haddock.hs b/Cabal/src/Distribution/Simple/Setup/Haddock.hs index e8d7ba54a20..aee2210d907 100644 --- a/Cabal/src/Distribution/Simple/Setup/Haddock.hs +++ b/Cabal/src/Distribution/Simple/Setup/Haddock.hs @@ -584,6 +584,27 @@ haddockProjectOptions _showOrParseArgs = haddockProjectForeignLibs (\v flags -> flags{haddockProjectForeignLibs = v}) trueArg + , option + "" + ["all", "haddock-all"] + "Run haddock for all targets" + ( \f -> + allFlags + [ haddockProjectExecutables f + , haddockProjectTestSuites f + , haddockProjectBenchmarks f + , haddockProjectForeignLibs f + ] + ) + ( \v flags -> + flags + { haddockProjectExecutables = v + , haddockProjectTestSuites = v + , haddockProjectBenchmarks = v + , haddockProjectForeignLibs = v + } + ) + trueArg , option "" ["internal"] diff --git a/changelog.d/issue-10051 b/changelog.d/issue-10051 new file mode 100644 index 00000000000..b582fc2b619 --- /dev/null +++ b/changelog.d/issue-10051 @@ -0,0 +1,4 @@ +synopsis: Added `--all` and `--haddock-all` switches to `haddock-project` subcommand +packages: cabal-install +issues: #10051 +prs: #2272 From fa05c790c808632d84c3227d79d01dc2e4aad6e6 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 1 Jul 2024 08:49:36 +0200 Subject: [PATCH 040/207] Updated CONTRIBUTING guide --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fa1d5385d68..f9d24a6e113 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -344,7 +344,7 @@ description: { } ``` -Only the `synopsis` field is actually required, but you should also set the others where applicable. +Only the `synopsis` and `prs` fields are required, but you should also set the others where applicable. | Field | Description | | ----- | ----------- | From fbc511b649a4adbc2a72710228e14b19b76336b9 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Tue, 2 Jul 2024 09:33:04 +0100 Subject: [PATCH 041/207] copy: Take into account extra-dyn-lib-flavours when copying bundled library This fixes the DynWay case to match the other cases which take into account extra-dyn-lib-flavours. --- Cabal/src/Distribution/Simple/GHC.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cabal/src/Distribution/Simple/GHC.hs b/Cabal/src/Distribution/Simple/GHC.hs index 8d7dda4de34..3ce66bb38bc 100644 --- a/Cabal/src/Distribution/Simple/GHC.hs +++ b/Cabal/src/Distribution/Simple/GHC.hs @@ -961,7 +961,7 @@ installLib verbosity lbi targetDir dynlibTargetDir _builtDir pkg lib clbi = do mkGenericSharedBundledLibName platform compiler_id - l + (l ++ f) forM_ files $ \file -> when (l' `isPrefixOf` file) $ do isFile <- doesFileExist (i $ builtDir makeRelativePathEx file) @@ -971,6 +971,7 @@ installLib verbosity lbi targetDir dynlibTargetDir _builtDir pkg lib clbi = do dynlibTargetDir file | l <- extraBundledLibs (libBuildInfo lib) + , f <- "" : extraDynLibFlavours (libBuildInfo lib) ] where -- See Note [Symbolic paths] in Distribution.Utils.Path From 0e7a12689f7d061c891918050975c3a91c2ba31c Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 6 Jul 2024 17:21:58 +0000 Subject: [PATCH 042/207] missed the two changelog pointers (#10138) (#10139) * missed the two changelog pointers * Apply suggestions from code review fixup! missed the two changelog pointers Co-authored-by: ffaf1 * squash! and the other two changelogs --------- Co-authored-by: ffaf1 (cherry picked from commit 82cad891a8b6f966a6a160d6fe3997680760abda) Co-authored-by: brandon s allbery kf8nh Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- Cabal-syntax/ChangeLog.md | 2 +- Cabal/ChangeLog.md | 3 +++ cabal-install-solver/ChangeLog.md | 2 +- cabal-install/changelog | 3 +++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Cabal-syntax/ChangeLog.md b/Cabal-syntax/ChangeLog.md index 7554aaf4980..73c417220df 100644 --- a/Cabal-syntax/ChangeLog.md +++ b/Cabal-syntax/ChangeLog.md @@ -1 +1 @@ -Please see https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.12.0.0.md +Please see https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.12.1.0.md diff --git a/Cabal/ChangeLog.md b/Cabal/ChangeLog.md index 7aebc02edda..681bbc5a84a 100644 --- a/Cabal/ChangeLog.md +++ b/Cabal/ChangeLog.md @@ -1,3 +1,6 @@ +# 3.12.1.0 [Artem Pelenitsyn](mailto:a.pelenitsyn@gmail.com) June 2024 +* See https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.12.1.0.md + # 3.12.0.0 [Francesco Ariis](mailto:fa-ml@ariis.it) May 2024 # 3.12.0.0 [Francesco Ariis](mailto:fa-ml@ariis.it) March 2024 * See https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.12.0.0.md diff --git a/cabal-install-solver/ChangeLog.md b/cabal-install-solver/ChangeLog.md index 3bfdd653afe..3cd7794fe29 100644 --- a/cabal-install-solver/ChangeLog.md +++ b/cabal-install-solver/ChangeLog.md @@ -1 +1 @@ -Please see https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.10.3.0.md +Please see https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.12.1.0.md diff --git a/cabal-install/changelog b/cabal-install/changelog index 2d742052eeb..281329c7fe7 100644 --- a/cabal-install/changelog +++ b/cabal-install/changelog @@ -1,5 +1,8 @@ -*-change-log-*- +3.12.1.0 Artem Pelenitsyn June 2024 + * See https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.12.1.0.md + 3.10.3.0 Hécate January 2024 * See https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.10.3.0.md From 634fba29a7ba1d16b61b0c5f93493de6657a0e57 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Wed, 3 Jul 2024 21:23:58 -0400 Subject: [PATCH 043/207] fix non-POSIX [[ ]] Otherwise CI prints `validate.sh: 332: [[: not found` and the line does nothing (but `validate.sh` continues to run), unless the system shell is `ksh` / `bash` / `zsh`. This may explain https://github.com/haskell/cabal/pull/10114#issuecomment-2178163927. --- validate.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validate.sh b/validate.sh index 40ad0576b5f..edb1db83277 100755 --- a/validate.sh +++ b/validate.sh @@ -329,7 +329,7 @@ CABALLISTBIN="${CABAL} list-bin --builddir=$BUILDDIR --project-file=$PROJECTFILE # of validate.sh # https://github.com/haskell/cabal/issues/9571 # https://github.com/haskell/cabal/pull/10114 -RTSOPTS="$([[ $ARCH = "x86_64-windows" && -z "$CI" ]] && echo "+RTS --io-manager=native" || echo "")" +RTSOPTS="$([ $ARCH = "x86_64-windows" ] && [ -z "$CI" ] && echo "+RTS --io-manager=native" || echo "")" # header ####################################################################### From b98a1b0008320aaa36c9c566fe476ec5649a3af1 Mon Sep 17 00:00:00 2001 From: Rodrigo Mesquita Date: Wed, 3 Jul 2024 17:27:55 +0100 Subject: [PATCH 044/207] Lookup main-is C sources in hs-source-dirs In the 2decb0e729b795b198cdef719984ca4c5ca1f657 refactor we stopped looking for non-Haskell `main-is` files in the hs-source-dirs and other appropriate directories. This commit fixes that oversight. Even if it is not intuitive that main-is-C-sources are searched in the hs-source-dirs, we don't wish to break users relying on this behaviour as there does not exist that strong of a motivation to do so. Fixes #10168 Co-authored-by: sheaf --- Cabal/src/Distribution/Simple/GHC/Build.hs | 17 +++++- .../Simple/GHC/Build/ExtraSources.hs | 39 +++++++------ .../Distribution/Simple/GHC/Build/Modules.hs | 57 ++++++++++--------- .../Distribution/Simple/GHC/Build/Utils.hs | 2 +- .../PackageTests/CMain/10168/Setup.hs | 2 + .../PackageTests/CMain/10168/app/Main.hs | 6 ++ .../PackageTests/CMain/10168/c-app/main.c | 12 ++++ .../CMain/10168/haskell-c-tests.cabal | 27 +++++++++ .../PackageTests/CMain/10168/setup.out | 10 ++++ .../PackageTests/CMain/10168/setup.test.hs | 7 +++ .../PackageTests/CMain/10168/src/Lib.hs | 6 ++ .../PackageTests/CMain/{ => Simple}/Bar.hs | 0 .../PackageTests/CMain/{ => Simple}/foo.c | 0 .../PackageTests/CMain/{ => Simple}/my.cabal | 0 .../CMain/{ => Simple}/setup.cabal.out | 0 .../PackageTests/CMain/{ => Simple}/setup.out | 0 .../CMain/{ => Simple}/setup.test.hs | 0 17 files changed, 134 insertions(+), 51 deletions(-) create mode 100644 cabal-testsuite/PackageTests/CMain/10168/Setup.hs create mode 100644 cabal-testsuite/PackageTests/CMain/10168/app/Main.hs create mode 100644 cabal-testsuite/PackageTests/CMain/10168/c-app/main.c create mode 100644 cabal-testsuite/PackageTests/CMain/10168/haskell-c-tests.cabal create mode 100644 cabal-testsuite/PackageTests/CMain/10168/setup.out create mode 100644 cabal-testsuite/PackageTests/CMain/10168/setup.test.hs create mode 100644 cabal-testsuite/PackageTests/CMain/10168/src/Lib.hs rename cabal-testsuite/PackageTests/CMain/{ => Simple}/Bar.hs (100%) rename cabal-testsuite/PackageTests/CMain/{ => Simple}/foo.c (100%) rename cabal-testsuite/PackageTests/CMain/{ => Simple}/my.cabal (100%) rename cabal-testsuite/PackageTests/CMain/{ => Simple}/setup.cabal.out (100%) rename cabal-testsuite/PackageTests/CMain/{ => Simple}/setup.out (100%) rename cabal-testsuite/PackageTests/CMain/{ => Simple}/setup.test.hs (100%) diff --git a/Cabal/src/Distribution/Simple/GHC/Build.hs b/Cabal/src/Distribution/Simple/GHC/Build.hs index 1f88f07552b..f62cdcf8b66 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build.hs @@ -12,11 +12,14 @@ import Distribution.Simple.Flag (Flag) import Distribution.Simple.GHC.Build.ExtraSources import Distribution.Simple.GHC.Build.Link import Distribution.Simple.GHC.Build.Modules +import Distribution.Simple.GHC.Build.Utils (isHaskell) import Distribution.Simple.LocalBuildInfo import Distribution.Simple.Program.Builtin (ghcProgram) import Distribution.Simple.Program.Db (requireProgram) import Distribution.Simple.Utils + import Distribution.Types.ComponentLocalBuildInfo +import Distribution.Types.PackageName.Magic (fakePackageId) import Distribution.Types.ParStrat import Distribution.Utils.NubList (fromNubListR) import Distribution.Utils.Path @@ -114,8 +117,18 @@ build numJobs pkg_descr pbci = do -- We need a separate build and link phase, and C sources must be compiled -- after Haskell modules, because C sources may depend on stub headers -- generated from compiling Haskell modules (#842, #3294). - buildOpts <- buildHaskellModules numJobs ghcProg pkg_descr buildTargetDir (wantedLibWays isIndef) pbci - extraSources <- buildAllExtraSources ghcProg buildTargetDir wantedWays pbci + (mbMainFile, inputModules) <- componentInputs buildTargetDir pkg_descr pbci + let (hsMainFile, nonHsMainFile) = + case mbMainFile of + Just mainFile + | PD.package pkg_descr == fakePackageId + || isHaskell (getSymbolicPath mainFile) -> + (Just mainFile, Nothing) + | otherwise -> + (Nothing, Just mainFile) + Nothing -> (Nothing, Nothing) + buildOpts <- buildHaskellModules numJobs ghcProg hsMainFile inputModules buildTargetDir (wantedLibWays isIndef) pbci + extraSources <- buildAllExtraSources nonHsMainFile ghcProg buildTargetDir wantedWays pbci linkOrLoadComponent ghcProg pkg_descr diff --git a/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs b/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs index 83bcf9a6bca..31aa92a3b2a 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs @@ -25,14 +25,15 @@ import Distribution.Simple.LocalBuildInfo import Distribution.Simple.Program.Types import Distribution.System (Arch (JavaScript), Platform (..)) import Distribution.Types.ComponentLocalBuildInfo -import Distribution.Types.Executable import Distribution.Utils.Path import Distribution.Verbosity (Verbosity) -- | An action that builds all the extra build sources of a component, i.e. C, -- C++, Js, Asm, C-- sources. buildAllExtraSources - :: ConfiguredProgram + :: Maybe (SymbolicPath Pkg File) + -- ^ An optional non-Haskell Main file + -> ConfiguredProgram -- ^ The GHC configured program -> SymbolicPath Pkg (Dir Artifacts) -- ^ The build directory for this target @@ -56,7 +57,9 @@ buildCSources , buildJsSources , buildAsmSources , buildCmmSources - :: ConfiguredProgram + :: Maybe (SymbolicPath Pkg File) + -- ^ An optional non-Haskell Main file + -> ConfiguredProgram -- ^ The GHC configured program -> SymbolicPath Pkg (Dir Artifacts) -- ^ The build directory for this target @@ -66,37 +69,33 @@ buildCSources -- ^ The context and component being built in it. -> IO (NubListR (SymbolicPath Pkg File)) -- ^ Returns the list of extra sources that were built -buildCSources = +buildCSources mbMainFile = buildExtraSources "C Sources" Internal.componentCcGhcOptions ( \c -> do let cFiles = cSources (componentBuildInfo c) case c of - CExe exe - | let mainPath = getSymbolicPath $ modulePath exe - , isC mainPath -> - cFiles ++ [makeSymbolicPath mainPath] - -- NB: Main.hs is relative to hs-source-dirs, but Main.c - -- is relative to the package. + CExe{} + | Just main <- mbMainFile + , isC $ getSymbolicPath main -> + cFiles ++ [main] _otherwise -> cFiles ) -buildCxxSources = +buildCxxSources mbMainFile = buildExtraSources "C++ Sources" Internal.componentCxxGhcOptions ( \c -> do let cxxFiles = cxxSources (componentBuildInfo c) case c of - CExe exe - | let mainPath = getSymbolicPath $ modulePath exe - , isCxx mainPath -> - do cxxFiles ++ [makeSymbolicPath mainPath] - -- NB: Main.hs is relative to hs-source-dirs, but Main.c++ - -- is relative to the package. + CExe{} + | Just main <- mbMainFile + , isCxx $ getSymbolicPath main -> + cxxFiles ++ [main] _otherwise -> cxxFiles ) -buildJsSources ghcProg buildTargetDir neededWays = do +buildJsSources _mbMainFile ghcProg buildTargetDir neededWays = do Platform hostArch _ <- hostPlatform <$> localBuildInfo let hasJsSupport = hostArch == JavaScript buildExtraSources @@ -114,12 +113,12 @@ buildJsSources ghcProg buildTargetDir neededWays = do ghcProg buildTargetDir neededWays -buildAsmSources = +buildAsmSources _mbMainFile = buildExtraSources "Assembler Sources" Internal.componentAsmGhcOptions (asmSources . componentBuildInfo) -buildCmmSources = +buildCmmSources _mbMainFile = buildExtraSources "C-- Sources" Internal.componentCmmGhcOptions diff --git a/Cabal/src/Distribution/Simple/GHC/Build/Modules.hs b/Cabal/src/Distribution/Simple/GHC/Build/Modules.hs index 0c89d860a1b..2e8ba35ccb6 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build/Modules.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build/Modules.hs @@ -5,7 +5,12 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TupleSections #-} -module Distribution.Simple.GHC.Build.Modules (buildHaskellModules, BuildWay (..), buildWayPrefix) where +module Distribution.Simple.GHC.Build.Modules + ( buildHaskellModules + , BuildWay (..) + , buildWayPrefix + , componentInputs + ) where import Control.Monad.IO.Class import Distribution.Compat.Prelude @@ -98,8 +103,10 @@ buildHaskellModules -- ^ The parallelism strategy (e.g. num of jobs) -> ConfiguredProgram -- ^ The GHC configured program - -> PD.PackageDescription - -- ^ The package description + -> Maybe (SymbolicPath Pkg File) + -- ^ Optional path to a Haskell Main file to build + -> [ModuleName] + -- ^ The Haskell modules to build -> SymbolicPath Pkg ('Dir Artifacts) -- ^ The path to the build directory for this target, which -- has already been created. @@ -112,7 +119,7 @@ buildHaskellModules -- invocation used to compile the component in that 'BuildWay'. -- This can be useful in, eg, a linker invocation, in which we want to use the -- same options and list the same inputs as those used for building. -buildHaskellModules numJobs ghcProg pkg_descr buildTargetDir neededLibWays pbci = do +buildHaskellModules numJobs ghcProg mbMainFile inputModules buildTargetDir neededLibWays pbci = do -- See Note [Building Haskell Modules accounting for TH] let @@ -141,13 +148,14 @@ buildHaskellModules numJobs ghcProg pkg_descr buildTargetDir neededLibWays pbci | isCoverageEnabled = Flag $ Hpc.mixDir (coerceSymbolicPath $ coerceSymbolicPath buildTargetDir extraCompilationArtifacts) way | otherwise = mempty - (inputFiles, inputModules) <- componentInputs buildTargetDir pkg_descr pbci - let mbWorkDir = mbWorkDirLBI lbi runGhcProg = runGHC verbosity ghcProg comp platform mbWorkDir platform = hostPlatform lbi + (hsMains, scriptMains) = + partition (isHaskell . getSymbolicPath) (maybeToList mbMainFile) + -- We define the base opts which are shared across different build ways in -- 'buildHaskellModules' baseOpts way = @@ -161,16 +169,8 @@ buildHaskellModules numJobs ghcProg pkg_descr buildTargetDir neededLibWays pbci ghcOptNoLink = if isLib then NoFlag else toFlag True , ghcOptNumJobs = numJobs , ghcOptInputModules = toNubListR inputModules - , ghcOptInputFiles = - toNubListR $ - if PD.package pkg_descr == fakePackageId - then filter (isHaskell . getSymbolicPath) inputFiles - else inputFiles - , ghcOptInputScripts = - toNubListR $ - if PD.package pkg_descr == fakePackageId - then filter (not . isHaskell . getSymbolicPath) inputFiles - else [] + , ghcOptInputFiles = toNubListR hsMains + , ghcOptInputScripts = toNubListR scriptMains , ghcOptExtra = buildWayExtraHcOptions way GHC bi , ghcOptHiSuffix = optSuffixFlag (buildWayPrefix way) "hi" , ghcOptObjSuffix = optSuffixFlag (buildWayPrefix way) "o" @@ -248,7 +248,7 @@ buildHaskellModules numJobs ghcProg pkg_descr buildTargetDir neededLibWays pbci ProfDynWay -> profDynOpts -- If there aren't modules, or if we're loading the modules in repl, don't build. - unless (forRepl || (null inputFiles && null inputModules)) $ liftIO $ do + unless (forRepl || (isNothing mbMainFile && null inputModules)) $ liftIO $ do -- See Note [Building Haskell Modules accounting for TH] let neededLibWaysSet = Set.fromList neededLibWays @@ -348,25 +348,26 @@ buildWayExtraHcOptions = \case DynWay -> hcSharedOptions ProfDynWay -> hcProfSharedOptions --- | Returns a pair of the Haskell input files and Haskell modules of the --- component being built. +-- | Returns a pair of the main file and Haskell modules of the component being +-- built. The main file is not necessarily a Haskell file. It could also be +-- e.g. a C source, or, a Haskell repl script (that does not necessarily have +-- an extension). -- --- The "input files" are either the path to the main Haskell module, or a repl --- script (that does not necessarily have an extension). +-- The main file is Nothing if the component is not executable. componentInputs :: SymbolicPath Pkg (Dir Artifacts) -- ^ Target build dir -> PD.PackageDescription -> PreBuildComponentInputs -- ^ The context and component being built in it. - -> IO ([SymbolicPath Pkg File], [ModuleName]) - -- ^ The Haskell input files, and the Haskell modules + -> IO (Maybe (SymbolicPath Pkg File), [ModuleName]) + -- ^ The main input file, and the Haskell modules componentInputs buildTargetDir pkg_descr pbci = case component of CLib lib -> - pure ([], allLibModules lib clbi) + pure (Nothing, allLibModules lib clbi) CFLib flib -> - pure ([], foreignLibModules flib) + pure (Nothing, foreignLibModules flib) CExe Executable{buildInfo = bi', modulePath} -> exeLikeInputs bi' modulePath CTest TestSuite{testBuildInfo = bi', testInterface = TestSuiteExeV10 _ mainFile} -> @@ -405,6 +406,6 @@ componentInputs buildTargetDir pkg_descr pbci = "Enabling workaround for Main module '" ++ prettyShow mainModName ++ "' listed in 'other-modules' illegally!" - return ([main], filter (/= mainModName) otherModNames) - else return ([main], otherModNames) - else return ([], otherModNames) + return (Just main, filter (/= mainModName) otherModNames) + else return (Just main, otherModNames) + else return (Just main, otherModNames) diff --git a/Cabal/src/Distribution/Simple/GHC/Build/Utils.hs b/Cabal/src/Distribution/Simple/GHC/Build/Utils.hs index c87d074c202..e61fc50c9c4 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build/Utils.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build/Utils.hs @@ -31,7 +31,7 @@ import System.FilePath ) -- | Find the path to the entry point of an executable (typically specified in --- @main-is@, and found in @hs-source-dirs@). +-- @main-is@, and found in @hs-source-dirs@ -- yes, even when @main-is@ is not a Haskell file). findExecutableMain :: Verbosity -> Maybe (SymbolicPath CWD (Dir Pkg)) diff --git a/cabal-testsuite/PackageTests/CMain/10168/Setup.hs b/cabal-testsuite/PackageTests/CMain/10168/Setup.hs new file mode 100644 index 00000000000..9a994af677b --- /dev/null +++ b/cabal-testsuite/PackageTests/CMain/10168/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/cabal-testsuite/PackageTests/CMain/10168/app/Main.hs b/cabal-testsuite/PackageTests/CMain/10168/app/Main.hs new file mode 100644 index 00000000000..718f1d5a74c --- /dev/null +++ b/cabal-testsuite/PackageTests/CMain/10168/app/Main.hs @@ -0,0 +1,6 @@ +module Main ( main ) where + +import Lib ( myMax ) + +main :: IO () +main = print $ myMax 10 100 diff --git a/cabal-testsuite/PackageTests/CMain/10168/c-app/main.c b/cabal-testsuite/PackageTests/CMain/10168/c-app/main.c new file mode 100644 index 00000000000..2cf1d456e33 --- /dev/null +++ b/cabal-testsuite/PackageTests/CMain/10168/c-app/main.c @@ -0,0 +1,12 @@ +#include +#include +#ifdef __GLASGOW_HASKELL__ +#include "Lib_stub.h" +#endif + +int main(int argc, char *argv[]) { + hs_init(&argc, &argv); + printf("%lld\n", myMax(10,100)); + hs_exit(); + return 0; +} diff --git a/cabal-testsuite/PackageTests/CMain/10168/haskell-c-tests.cabal b/cabal-testsuite/PackageTests/CMain/10168/haskell-c-tests.cabal new file mode 100644 index 00000000000..9f5f9e1dff2 --- /dev/null +++ b/cabal-testsuite/PackageTests/CMain/10168/haskell-c-tests.cabal @@ -0,0 +1,27 @@ +cabal-version: 2.0 + +name: haskell-c-tests +version: 0.1.0.0 +build-type: Simple + +library + exposed-modules: Lib + hs-source-dirs: src + ghc-options: -stubdir autogen-stubs + build-depends: base + default-language: Haskell2010 + +executable c-exe + main-is: main.c + hs-source-dirs: c-app + ghc-options: -no-hs-main + include-dirs: autogen-stubs + build-depends: base, haskell-c-tests + default-language: Haskell2010 + +executable haskell-exe + main-is: Main.hs + hs-source-dirs: app + ghc-options: -threaded -rtsopts -with-rtsopts=-N + build-depends: base, haskell-c-tests + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/CMain/10168/setup.out b/cabal-testsuite/PackageTests/CMain/10168/setup.out new file mode 100644 index 00000000000..bb075774c77 --- /dev/null +++ b/cabal-testsuite/PackageTests/CMain/10168/setup.out @@ -0,0 +1,10 @@ +# Setup configure +Configuring haskell-c-tests-0.1.0.0... +Warning: [unknown-directory] 'include-dirs: autogen-stubs' specifies a directory which does not exist. +# Setup build +Preprocessing library for haskell-c-tests-0.1.0.0... +Building library for haskell-c-tests-0.1.0.0... +Preprocessing executable 'c-exe' for haskell-c-tests-0.1.0.0... +Building executable 'c-exe' for haskell-c-tests-0.1.0.0... +Preprocessing executable 'haskell-exe' for haskell-c-tests-0.1.0.0... +Building executable 'haskell-exe' for haskell-c-tests-0.1.0.0... diff --git a/cabal-testsuite/PackageTests/CMain/10168/setup.test.hs b/cabal-testsuite/PackageTests/CMain/10168/setup.test.hs new file mode 100644 index 00000000000..bcefa0b29be --- /dev/null +++ b/cabal-testsuite/PackageTests/CMain/10168/setup.test.hs @@ -0,0 +1,7 @@ +import Test.Cabal.Prelude +-- Test building an executable whose main-is is a C source found in the hs-source-dirs. +-- It is a bit counter intuitive that we look for non-haskell sources in +-- `hs-source-dirs`, but that is a behaviour that users rely on (see #10168) +-- and there's no good reason to break it. +main = setupTest $ do + setup_build [] diff --git a/cabal-testsuite/PackageTests/CMain/10168/src/Lib.hs b/cabal-testsuite/PackageTests/CMain/10168/src/Lib.hs new file mode 100644 index 00000000000..ba1bcce7ab9 --- /dev/null +++ b/cabal-testsuite/PackageTests/CMain/10168/src/Lib.hs @@ -0,0 +1,6 @@ +module Lib ( myMax ) where + +myMax :: Int -> Int -> Int +myMax x1 x2 = if x1 > x2 then x1 else x2 + +foreign export ccall myMax :: Int -> Int -> Int diff --git a/cabal-testsuite/PackageTests/CMain/Bar.hs b/cabal-testsuite/PackageTests/CMain/Simple/Bar.hs similarity index 100% rename from cabal-testsuite/PackageTests/CMain/Bar.hs rename to cabal-testsuite/PackageTests/CMain/Simple/Bar.hs diff --git a/cabal-testsuite/PackageTests/CMain/foo.c b/cabal-testsuite/PackageTests/CMain/Simple/foo.c similarity index 100% rename from cabal-testsuite/PackageTests/CMain/foo.c rename to cabal-testsuite/PackageTests/CMain/Simple/foo.c diff --git a/cabal-testsuite/PackageTests/CMain/my.cabal b/cabal-testsuite/PackageTests/CMain/Simple/my.cabal similarity index 100% rename from cabal-testsuite/PackageTests/CMain/my.cabal rename to cabal-testsuite/PackageTests/CMain/Simple/my.cabal diff --git a/cabal-testsuite/PackageTests/CMain/setup.cabal.out b/cabal-testsuite/PackageTests/CMain/Simple/setup.cabal.out similarity index 100% rename from cabal-testsuite/PackageTests/CMain/setup.cabal.out rename to cabal-testsuite/PackageTests/CMain/Simple/setup.cabal.out diff --git a/cabal-testsuite/PackageTests/CMain/setup.out b/cabal-testsuite/PackageTests/CMain/Simple/setup.out similarity index 100% rename from cabal-testsuite/PackageTests/CMain/setup.out rename to cabal-testsuite/PackageTests/CMain/Simple/setup.out diff --git a/cabal-testsuite/PackageTests/CMain/setup.test.hs b/cabal-testsuite/PackageTests/CMain/Simple/setup.test.hs similarity index 100% rename from cabal-testsuite/PackageTests/CMain/setup.test.hs rename to cabal-testsuite/PackageTests/CMain/Simple/setup.test.hs From d8dd7c3b4511c4e7fc3401d39f905c4e63d775af Mon Sep 17 00:00:00 2001 From: Artem Pelenitsyn Date: Sat, 13 Jul 2024 19:59:59 -0400 Subject: [PATCH 045/207] CI: don't allow-newer for GHC 9.10 (#10194) * CI: don't allow-newer for GHC 9.10 * allow-newer base for rere * buildinfo-reference-generator: bump base bound * cabal-testsuite: bump base bound --- .../buildinfo-reference-generator.cabal | 2 +- cabal-testsuite/cabal-testsuite.cabal | 2 +- project-cabal/ghc-latest.config | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/buildinfo-reference-generator/buildinfo-reference-generator.cabal b/buildinfo-reference-generator/buildinfo-reference-generator.cabal index 667e8346b63..47068ee33b1 100644 --- a/buildinfo-reference-generator/buildinfo-reference-generator.cabal +++ b/buildinfo-reference-generator/buildinfo-reference-generator.cabal @@ -8,7 +8,7 @@ executable buildinfo-reference-generator ghc-options: -Wall main-is: Main.hs build-depends: - , base >=4.11 && <4.20 + , base >=4.11 && <4.21 , Cabal , Cabal-described , containers diff --git a/cabal-testsuite/cabal-testsuite.cabal b/cabal-testsuite/cabal-testsuite.cabal index bc890efb7e3..92becccd8dc 100644 --- a/cabal-testsuite/cabal-testsuite.cabal +++ b/cabal-testsuite/cabal-testsuite.cabal @@ -26,7 +26,7 @@ common shared default-language: Haskell2010 build-depends: - , base >= 4.11 && < 4.20 + , base >= 4.11 && < 4.21 -- this needs to match the in-tree lib:Cabal version , Cabal ^>= 3.13.0.0 diff --git a/project-cabal/ghc-latest.config b/project-cabal/ghc-latest.config index 5f8d40290db..e4608ea26ab 100644 --- a/project-cabal/ghc-latest.config +++ b/project-cabal/ghc-latest.config @@ -6,9 +6,11 @@ -- - cabal.validate.project (Cabal CI), -- Commented out below are the usual suspects. Feel free to add more. --- NOTE: don't forget to update the compiler version in the conditional +-- NOTE: don't forget to update the compiler version in the conditionals -- when upgrading to a newer GHC if impl(ghc >= 9.10.0) + allow-newer: rere:base +if impl(ghc >= 9.12.0) allow-newer: --windns:*, rere:*, tree-diff:*, uuid-types:*, these:*, hashable:*, assoc:*, semialign:*, indexed-traversable-instances:*, indexed-traversable:*, OneTuple:*, scientific:*, time-compat:*, text-short:*, integer-conversion:*, generically:*, data-fix:*, binary:* -- Artem, 2024-04-21: I started and then gave up... From f7f41164d97558ac18786381fa1506abe2d35605 Mon Sep 17 00:00:00 2001 From: Mike Pilgrem Date: Tue, 16 Jul 2024 01:37:04 +0100 Subject: [PATCH 046/207] Fix Haddock docs for `Distribution.Types.Dependency` (#10197) Type `Dependency` is an instance of `Ord`, from `Cabal-syntax-3.10.1.0`. Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- Cabal-syntax/src/Distribution/Types/Dependency.hs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Types/Dependency.hs b/Cabal-syntax/src/Distribution/Types/Dependency.hs index 10d0506b57e..222a699a3f9 100644 --- a/Cabal-syntax/src/Distribution/Types/Dependency.hs +++ b/Cabal-syntax/src/Distribution/Types/Dependency.hs @@ -33,10 +33,6 @@ import qualified Text.PrettyPrint as PP -- -- /Invariant:/ package name does not appear as 'LSubLibName' in -- set of library names. --- --- /Note:/ 'Dependency' is not an instance of 'Ord', and so it cannot be used --- in 'Set' or as the key to a 'Map'. For these and similar use cases see --- 'DependencyMap'. data Dependency = -- | The set of libraries required from the package. -- Only the selected libraries will be built. From f4726b8dfed2383ce205c25080329d83d71b6aa7 Mon Sep 17 00:00:00 2001 From: Simon Hengel Date: Tue, 16 Jul 2024 10:53:21 +0700 Subject: [PATCH 047/207] Update cabal-commands.rst (#10198) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- doc/cabal-commands.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/cabal-commands.rst b/doc/cabal-commands.rst index 5da0ec7a939..8c05a9b6593 100644 --- a/doc/cabal-commands.rst +++ b/doc/cabal-commands.rst @@ -343,6 +343,7 @@ While this interface is intended to be used for scripting, it is an experimental Scripting example: :: + $ ls $(cabal path --installdir) ... From e06cc2195bd91e5284a531f8cc43805b31fb117c Mon Sep 17 00:00:00 2001 From: Andrea Bedini Date: Wed, 10 Jul 2024 14:23:35 +0800 Subject: [PATCH 048/207] ci(validate.yml): Allow workflow_dispatch with no allow-newer or constraints --- .github/workflows/validate.yml | 16 ++++++++++------ CONTRIBUTING.md | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 600e8e982bb..62b446b2293 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -31,11 +31,11 @@ on: inputs: allow-newer: description: allow-newer line - required: true + required: false type: string constraints: description: constraints line - required: true + required: false type: string env: @@ -92,11 +92,15 @@ jobs: - uses: actions/checkout@v4 # See https://github.com/haskell/cabal/blob/master/CONTRIBUTING.md#hackage-revisions - - name: Manually supplied constraints/allow-newer - if: github.event_name == 'workflow_dispatch' + - name: Add manually supplied allow-newer + if: github.event_name == 'workflow_dispatch' && github.event.inputs.allow-newer != '' run: | - echo "allow-newer: ${ALLOWNEWER}" >> cabal.validate.project - echo "constraints: ${CONSTRAINTS}" >> cabal.validate.project + echo "allow-newer: ${{ github.event.inputs.allow-newer }}" >> cabal.validate.project + + - name: Add manually supplied constraints + if: github.event_name == 'workflow_dispatch' && github.event.inputs.constraints != '' + run: | + echo "constraints: ${{ github.event.inputs.constraints }}" >> cabal.validate.project - uses: haskell-actions/setup@v2 id: setup-haskell diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f9d24a6e113..c6944eb1227 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -429,7 +429,7 @@ it, someone with enough permissions needs to go on the [Validate workflow page](https://github.com/haskell/cabal/actions/workflows/validate.yml) and dispatch it manually by clicking "Run workflow". -Running workflow manually as discussed above requires you to supply two inputs: +Running workflow manually as discussed above allows you to supply two inputs: > allow-newer line > constraints line From 38eed47d65ac989df968bceac8b2562902cc8b5d Mon Sep 17 00:00:00 2001 From: Artem Pelenitsyn Date: Wed, 17 Jul 2024 18:52:16 -0400 Subject: [PATCH 049/207] ghc-latest.config: rere is up to date with GHC 9.10 now (#10202) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- project-cabal/ghc-latest.config | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/project-cabal/ghc-latest.config b/project-cabal/ghc-latest.config index e4608ea26ab..24810b986a4 100644 --- a/project-cabal/ghc-latest.config +++ b/project-cabal/ghc-latest.config @@ -6,10 +6,8 @@ -- - cabal.validate.project (Cabal CI), -- Commented out below are the usual suspects. Feel free to add more. --- NOTE: don't forget to update the compiler version in the conditionals +-- NOTE: don't forget to update the compiler version in the conditional -- when upgrading to a newer GHC -if impl(ghc >= 9.10.0) - allow-newer: rere:base if impl(ghc >= 9.12.0) allow-newer: --windns:*, rere:*, tree-diff:*, uuid-types:*, these:*, hashable:*, assoc:*, semialign:*, indexed-traversable-instances:*, indexed-traversable:*, OneTuple:*, scientific:*, time-compat:*, text-short:*, integer-conversion:*, generically:*, data-fix:*, binary:* From 00f3abdec3a1df92b278c82d9f12a8cead2e1f35 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Wed, 3 Jul 2024 22:52:18 +0200 Subject: [PATCH 050/207] Document program-options --- doc/cabal-package-description-file.rst | 9 +++- doc/cabal-project-description-file.rst | 62 +++++++++++++++++++++----- doc/cabaldomain.py | 39 +++++++++++++++- 3 files changed, 96 insertions(+), 14 deletions(-) diff --git a/doc/cabal-package-description-file.rst b/doc/cabal-package-description-file.rst index 710765c6f1e..590fd6a4fa8 100644 --- a/doc/cabal-package-description-file.rst +++ b/doc/cabal-package-description-file.rst @@ -1451,6 +1451,8 @@ to have a way of finding out where a platform library got installed (other than searching the ``lib/`` directory). Instead, we install foreign libraries in ``~/.local/lib``. +.. _build-info: + Build information ^^^^^^^^^^^^^^^^^ .. pkg-section:: None @@ -1892,8 +1894,11 @@ system-dependent values for these fields. .. pkg-field:: ghc-options: token list - Additional options for GHC. You can often achieve the same effect - using the :pkg-field:`default-extensions` field, which is preferred. + Additional options for GHC. + + If specifying extensions (via ``-X`` flags) one can often achieve + the same effect using the :pkg-field:`default-extensions` field, which is + preferred. Options required only by one module may be specified by placing an ``OPTIONS_GHC`` pragma in the source file affected. diff --git a/doc/cabal-project-description-file.rst b/doc/cabal-project-description-file.rst index c2f224cf421..9e955a0a096 100644 --- a/doc/cabal-project-description-file.rst +++ b/doc/cabal-project-description-file.rst @@ -785,20 +785,17 @@ ways a package option can be specified: apply to all packages, local ones from the project and also external dependencies. - For example, the following options specify that :cfg-field:`optimization` -should be turned off for all local packages, and that ``bytestring`` (possibly -an external dependency) should be built with ``-fno-state-hack``:: +should be turned off for all local packages, and that ``awesome-package`` (possibly +an external dependency) should have the flag ``some-flag`` disabled :: optimization: False - package bytestring - ghc-options: -fno-state-hack + package awesome-package + flags: -some-flag -``ghc-options`` is not specifically described in this documentation, but is one -of many fields for configuring programs. They take the form -``progname-options`` and ``progname-location``, and can be set for all local -packages in a ``program-options`` stanza or under a package stanza. +Note that options at the top level take precedence over those at the ``package`` +stanza for local packages. On the command line, these options are applied to all local packages. There is no per-package command line interface. @@ -808,6 +805,26 @@ means that they are NOT supported by packages which use Custom setup scripts that require a version of the Cabal library older than when the feature was added. +.. cfg-section:: package name or * + + Specify package configuration options for the specific package (be it an + external or local package) or for all packages (external and local). + + A ``package`` stanza can contain the configuration fields listed in this + section and ``-options``: + + :: + + package awesome-package + flags: -some-flag + profiling: True + cxx-options: -Wall + + Program options are not extensively described in this documentation but a + good amount of them can be found in the :ref:`build-info` section. + +.. cfg-section:: None + .. cfg-field:: flags: list of +flagname or -flagname (space separated) -f FLAGS or -fFLAGS, --flags=FLAGS --flags="+foo -bar", -ffoo, -f-bar @@ -1639,11 +1656,36 @@ running ``setup haddock``. when complete. This will use ``xdg-open`` on Linux and BSD systems, ``open`` on macOS, and ``start`` on Windows. +Program options +^^^^^^^^^^^^^^^ + +.. cfg-section:: program-options + +Program options can be specified once for all local packages by means of the +``program-options`` stanza. For example: + +:: + + program-options + ghc-options: -Werror + +indicates that all **local packages** will provide ``-Werror`` to GHC when being +built. On the other hand, the following snippet: + +:: + + package * + ghc-options: -Werror + +will apply ``-Werror`` to all packages, local and remote. + Advanced global configuration options ------------------------------------- +.. cfg-section:: None + .. cfg-field:: write-ghc-environment-files: always, never, or ghc8.4.4+ - --write-ghc-environment-files=always\|never\|ghc8.4.4+ + --write-ghc-environment-files=always|never|ghc8.4.4+ :synopsis: Whether a ``.ghc.environment`` should be created after a successful build. :default: ``never`` diff --git a/doc/cabaldomain.py b/doc/cabaldomain.py index 2d318f8508f..9e16aefa6d6 100644 --- a/doc/cabaldomain.py +++ b/doc/cabaldomain.py @@ -548,7 +548,7 @@ class CabalPackageFieldXRef(CabalFieldXRef): ''' section_key = 'cabal:pkg-section' -class CabalConfigSection(CabalSection): +class CabalConfigSection(CabalObject): """ Marks section in package.cabal file """ @@ -556,6 +556,39 @@ class CabalConfigSection(CabalSection): section_key = 'cabal:cfg-section' target_prefix = 'cfg-section-' + def handle_signature(self, sig, signode): + ''' + As in sphinx.directives.ObjectDescription + + By default make an object description from name and adding + either deprecated or since as annotation. + ''' + env = self.state.document.settings.env + + sig = sig.strip() + parts = sig.split(' ',1) + name = parts[0] + signode += addnodes.desc_name(name, name) + signode += addnodes.desc_addname(' ', ' ') + if len(parts) > 1: + rest = parts[1].strip() + signode += addnodes.desc_annotation(rest, rest) + + return name + + def get_env_key(self, env, name): + store = CabalDomain.types[self.objtype] + return name, store + + def run(self): + env = self.state.document.settings.env + section = self.arguments[0].strip().split(' ',1)[0] + if section == 'None': + env.ref_context.pop('cabal:cfg-section', None) + return [] + env.ref_context['cabal:cfg-section'] = section + return super(CabalConfigSection, self).run() + class ConfigField(CabalField): section_key = 'cabal:cfg-section' indextemplate = '%s ; cabal project option' @@ -791,6 +824,9 @@ def make_full_name(typ, key, meta): if typ == 'pkg-section': return 'pkg-section-' + key + elif typ == 'cfg-section': + return 'cfg-section-' + key + elif typ == 'pkg-field': section, name = key if section is not None: @@ -914,4 +950,3 @@ class CabalLexer(lexer.RegexLexer): def setup(app): app.add_domain(CabalDomain) app.add_lexer('cabal', CabalLexer) - From 59c719e7b8e0b71fbd7312060d2fbbb100daa317 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Fri, 5 Jul 2024 13:57:17 +0200 Subject: [PATCH 051/207] Document `PROG-options` --- doc/cabal-package-description-file.rst | 310 +++++++++++++------------ doc/cabal-project-description-file.rst | 2 +- doc/config.rst | 99 ++++++++ 3 files changed, 258 insertions(+), 153 deletions(-) diff --git a/doc/cabal-package-description-file.rst b/doc/cabal-package-description-file.rst index 590fd6a4fa8..2fa6e7415f2 100644 --- a/doc/cabal-package-description-file.rst +++ b/doc/cabal-package-description-file.rst @@ -1310,147 +1310,6 @@ Example: end <- getCurrentTime putStrLn $ "fib 20 took " ++ show (diffUTCTime end start) - -Foreign libraries -^^^^^^^^^^^^^^^^^ - -Foreign libraries are system libraries intended to be linked against -programs written in C or other "foreign" languages. They -come in two primary flavours: dynamic libraries (``.so`` files on Linux, -``.dylib`` files on OSX, ``.dll`` files on Windows, etc.) are linked against -executables when the executable is run (or even lazily during -execution), while static libraries (``.a`` files on Linux/OSX, ``.lib`` -files on Windows) get linked against the executable at compile time. - -Foreign libraries only work with GHC 7.8 and later. - -A typical stanza for a foreign library looks like - -:: - - foreign-library myforeignlib - type: native-shared - lib-version-info: 6:3:2 - - if os(Windows) - options: standalone - mod-def-file: MyForeignLib.def - - other-modules: MyForeignLib.SomeModule - MyForeignLib.SomeOtherModule - build-depends: base >=4.7 && <4.9 - hs-source-dirs: src - c-sources: csrc/MyForeignLibWrapper.c - default-language: Haskell2010 - - -.. pkg-section:: foreign-library name - :since: 2.0 - :synopsis: Foreign library build information. - - Build information for `foreign libraries`_. - -.. pkg-field:: type: foreign library type - - Cabal recognizes ``native-static`` and ``native-shared`` here, although - we currently only support building `native-shared` libraries. - -.. pkg-field:: options: foreign library option list - - Options for building the foreign library, typically specific to the - specified type of foreign library. Currently we only support - ``standalone`` here. A standalone dynamic library is one that does not - have any dependencies on other (Haskell) shared libraries; without - the ``standalone`` option the generated library would have dependencies - on the Haskell runtime library (``libHSrts``), the base library - (``libHSbase``), etc. Currently, ``standalone`` *must* be used on Windows - and *must not* be used on any other platform. - -.. pkg-field:: mod-def-file: filename - - This option can only be used when creating dynamic Windows libraries - (that is, when using ``native-shared`` and the ``os`` is ``Windows``). If - used, it must be a path to a *module definition file*. The details of - module definition files are beyond the scope of this document; see the - `GHC `_ - manual for some details and some further pointers. - -.. pkg-field:: lib-version-info: current:revision:age - - This field is currently only used on Linux. - - This field specifies a Libtool-style version-info field that sets - an appropriate ABI version for the foreign library. Note that the - three numbers specified in this field do not directly specify the - actual ABI version: ``6:3:2`` results in library version ``4.2.3``. - - With this field set, the SONAME of the library is set, and symlinks - are installed. - - How you should bump this field on an ABI change depends on the - breakage you introduce: - - - Programs using the previous version may use the new version as - drop-in replacement, and programs using the new version can also - work with the previous one. In other words, no recompiling nor - relinking is needed. In this case, bump ``revision`` only, don't - touch current nor age. - - Programs using the previous version may use the new version as - drop-in replacement, but programs using the new version may use - APIs not present in the previous one. In other words, a program - linking against the new version may fail with "unresolved - symbols" if linking against the old version at runtime: set - revision to 0, bump current and age. - - Programs may need to be changed, recompiled, and relinked in - order to use the new version. Bump current, set revision and age - to 0. - - Also refer to the Libtool documentation on the version-info field. - -.. pkg-field:: lib-version-linux: version - - This field is only used on Linux. - - Specifies the library ABI version directly for foreign libraries - built on Linux: so specifying ``4.2.3`` causes a library - ``libfoo.so.4.2.3`` to be built with SONAME ``libfoo.so.4``, and - appropriate symlinks ``libfoo.so.4`` and ``libfoo.so`` to be - installed. - -Note that typically foreign libraries should export a way to initialize -and shutdown the Haskell runtime. In the example above, this is done by -the ``csrc/MyForeignLibWrapper.c`` file, which might look something like - -.. code-block:: c - - #include - #include "HsFFI.h" - - HsBool myForeignLibInit(void){ - int argc = 2; - char *argv[] = { "+RTS", "-A32m", NULL }; - char **pargv = argv; - - // Initialize Haskell runtime - hs_init(&argc, &pargv); - - // do any other initialization here and - // return false if there was a problem - return HS_BOOL_TRUE; - } - - void myForeignLibExit(void){ - hs_exit(); - } - -With modern ghc regular libraries are installed in directories that contain -package keys. This isn't usually a problem because the package gets registered -in ghc's package DB and so we can figure out what the location of the library -is. Foreign libraries however don't get registered, which means that we'd have -to have a way of finding out where a platform library got installed (other than by -searching the ``lib/`` directory). Instead, we install foreign libraries in -``~/.local/lib``. - .. _build-info: Build information @@ -2014,6 +1873,8 @@ system-dependent values for these fields. locate files listed in :pkg-field:`includes` and :pkg-field:`install-includes`. + Directories here will be passed as ``-I`` flags to GHC. + .. pkg-field:: c-sources: filename list A list of C source files to be compiled and linked with the Haskell @@ -2050,7 +1911,7 @@ system-dependent values for these fields. .. pkg-field:: extra-libraries: token list A list of extra libraries to link with (when not linking fully static - executables). + executables). Libraries will be passed as ``-optl-l`` flags to GHC. .. pkg-field:: extra-libraries-static: token list @@ -2084,7 +1945,7 @@ system-dependent values for these fields. .. pkg-field:: extra-lib-dirs: directory list A list of directories to search for libraries (when not linking fully static - executables). + executables). Directories will be passed as ``-optl-L`` flags to GHC. .. pkg-field:: extra-lib-dirs-static: directory list @@ -2101,7 +1962,8 @@ system-dependent values for these fields. .. pkg-field:: cc-options: token list - Command-line arguments to be passed to the C compiler. Since the + Command-line arguments to be passed to the Haskell compiler for the C + compiling phase (as ``-optc`` flags for GHC). Since the arguments are compiler-dependent, this field is more useful with the setup described in the section on `system-dependent parameters`_. @@ -2110,12 +1972,14 @@ system-dependent values for these fields. Command-line arguments for pre-processing Haskell code. Applies to Haskell source and other pre-processed Haskell source like .hsc .chs. Does not apply to C code, that's what cc-options is for. + Flags here will be passed as ``-optP`` flags to GHC. .. pkg-field:: cxx-options: token list :since: 2.2 - Command-line arguments to be passed to the compiler when compiling - C++ code. The C++ sources to which these command-line arguments + Command-line arguments to be passed to the Haskell compiler for the C++ + compiling phase (as ``-optcxx`` flags for GHC). + The C++ sources to which these command-line arguments should be applied can be specified with the :pkg-field:`cxx-sources` field. Command-line options for C and C++ can be passed separately to the compiler when compiling both C and C++ sources by segregating the C @@ -2127,20 +1991,22 @@ system-dependent values for these fields. .. pkg-field:: cmm-options: token list :since: 3.0 - Command-line arguments to be passed to the compiler when compiling + Command-line arguments to be passed to the Haskell compiler when compiling C-- code. See also :pkg-field:`cmm-sources`. .. pkg-field:: asm-options: token list :since: 3.0 - Command-line arguments to be passed to the assembler when compiling - assembler code. See also :pkg-field:`asm-sources`. + Command-line arguments to be passed to the Haskell compiler (as ``-opta`` + flags for GHC) when compiling assembler code. See also :pkg-field:`asm-sources`. .. pkg-field:: ld-options: token list - Command-line arguments to be passed to the linker. Since the - arguments are compiler-dependent, this field is more useful with the - setup described in the section on `system-dependent parameters`_. + Command-line arguments to be passed to the Haskell compiler (as ``-optl`` + flags for GHC) for the linking phase. Note that only executables (including + test-suites and benchmarks) are linked so this has no effect in libraries. + Since the arguments are compiler-dependent, this field is more useful with + the setup described in the section on `system-dependent parameters`_. .. pkg-field:: hsc2hs-options: token list :since: 3.6 @@ -2287,6 +2153,146 @@ system-dependent values for these fields. in a different package dependency, or at least in a separate internal library. +Foreign libraries +^^^^^^^^^^^^^^^^^ + +Foreign libraries are system libraries intended to be linked against +programs written in C or other "foreign" languages. They +come in two primary flavours: dynamic libraries (``.so`` files on Linux, +``.dylib`` files on OSX, ``.dll`` files on Windows, etc.) are linked against +executables when the executable is run (or even lazily during +execution), while static libraries (``.a`` files on Linux/OSX, ``.lib`` +files on Windows) get linked against the executable at compile time. + +Foreign libraries only work with GHC 7.8 and later. + +A typical stanza for a foreign library looks like + +:: + + foreign-library myforeignlib + type: native-shared + lib-version-info: 6:3:2 + + if os(Windows) + options: standalone + mod-def-file: MyForeignLib.def + + other-modules: MyForeignLib.SomeModule + MyForeignLib.SomeOtherModule + build-depends: base >=4.7 && <4.9 + hs-source-dirs: src + c-sources: csrc/MyForeignLibWrapper.c + default-language: Haskell2010 + + +.. pkg-section:: foreign-library name + :since: 2.0 + :synopsis: Foreign library build information. + + Build information for `foreign libraries`_. + +.. pkg-field:: type: foreign library type + + Cabal recognizes ``native-static`` and ``native-shared`` here, although + we currently only support building `native-shared` libraries. + +.. pkg-field:: options: foreign library option list + + Options for building the foreign library, typically specific to the + specified type of foreign library. Currently we only support + ``standalone`` here. A standalone dynamic library is one that does not + have any dependencies on other (Haskell) shared libraries; without + the ``standalone`` option the generated library would have dependencies + on the Haskell runtime library (``libHSrts``), the base library + (``libHSbase``), etc. Currently, ``standalone`` *must* be used on Windows + and *must not* be used on any other platform. + +.. pkg-field:: mod-def-file: filename + + This option can only be used when creating dynamic Windows libraries + (that is, when using ``native-shared`` and the ``os`` is ``Windows``). If + used, it must be a path to a *module definition file*. The details of + module definition files are beyond the scope of this document; see the + `GHC `_ + manual for some details and some further pointers. + +.. pkg-field:: lib-version-info: current:revision:age + + This field is currently only used on Linux. + + This field specifies a Libtool-style version-info field that sets + an appropriate ABI version for the foreign library. Note that the + three numbers specified in this field do not directly specify the + actual ABI version: ``6:3:2`` results in library version ``4.2.3``. + + With this field set, the SONAME of the library is set, and symlinks + are installed. + + How you should bump this field on an ABI change depends on the + breakage you introduce: + + - Programs using the previous version may use the new version as + drop-in replacement, and programs using the new version can also + work with the previous one. In other words, no recompiling nor + relinking is needed. In this case, bump ``revision`` only, don't + touch current nor age. + - Programs using the previous version may use the new version as + drop-in replacement, but programs using the new version may use + APIs not present in the previous one. In other words, a program + linking against the new version may fail with "unresolved + symbols" if linking against the old version at runtime: set + revision to 0, bump current and age. + - Programs may need to be changed, recompiled, and relinked in + order to use the new version. Bump current, set revision and age + to 0. + + Also refer to the Libtool documentation on the version-info field. + +.. pkg-field:: lib-version-linux: version + + This field is only used on Linux. + + Specifies the library ABI version directly for foreign libraries + built on Linux: so specifying ``4.2.3`` causes a library + ``libfoo.so.4.2.3`` to be built with SONAME ``libfoo.so.4``, and + appropriate symlinks ``libfoo.so.4`` and ``libfoo.so`` to be + installed. + +Note that typically foreign libraries should export a way to initialize +and shutdown the Haskell runtime. In the example above, this is done by +the ``csrc/MyForeignLibWrapper.c`` file, which might look something like + +.. code-block:: c + + #include + #include "HsFFI.h" + + HsBool myForeignLibInit(void){ + int argc = 2; + char *argv[] = { "+RTS", "-A32m", NULL }; + char **pargv = argv; + + // Initialize Haskell runtime + hs_init(&argc, &pargv); + + // do any other initialization here and + // return false if there was a problem + return HS_BOOL_TRUE; + } + + void myForeignLibExit(void){ + hs_exit(); + } + +With modern ghc regular libraries are installed in directories that contain +package keys. This isn't usually a problem because the package gets registered +in ghc's package DB and so we can figure out what the location of the library +is. Foreign libraries however don't get registered, which means that we'd have +to have a way of finding out where a platform library got installed (other than by +searching the ``lib/`` directory). Instead, we install foreign libraries in +``~/.local/lib``. + Configurations ^^^^^^^^^^^^^^ diff --git a/doc/cabal-project-description-file.rst b/doc/cabal-project-description-file.rst index 9e955a0a096..cf480875e7f 100644 --- a/doc/cabal-project-description-file.rst +++ b/doc/cabal-project-description-file.rst @@ -1661,7 +1661,7 @@ Program options .. cfg-section:: program-options -Program options can be specified once for all local packages by means of the +:ref:`Program options` can be specified once for all local packages by means of the ``program-options`` stanza. For example: :: diff --git a/doc/config.rst b/doc/config.rst index 5c85498b181..36a53f958b0 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -297,3 +297,102 @@ recommended instead to use a *secure* local repository: The layout of these secure local repos matches the layout of remote repositories exactly; the :hackage-pkg:`hackage-repo-tool` can be used to create and manage such repositories. + +.. _program_options: + +Program options +--------------- + +Programs that ``cabal`` knows about can be provided with options that will be +passed in whenever the program is invoked by ``cabal``. The configuration file +can contain a stanza of ``program-default-options`` with ``-options`` +fields to specify these. + +:: + + program-default-options + ghc-options: ... + happy-options: ... + +The list of known programs is: + ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| Program | Notes | ++=======================+====================================================================================================================================+ +| ``alex`` | ``_ | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``ar`` | Usually provided by GHC's ``"ar command"`` entry in ``ghc --info``. Note this might refer to ``llvm-ar`` instead of GNU's ``ar``. | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``c2hs`` | ``_ | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``doctest`` | ``_ | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``gcc`` | Usually provided by GHC's ``"C compiler command"`` entry in ``ghc --info``. Note this might refer to ``clang`` instead of ``gcc``. | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``ghc`` | | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``ghc-pkg`` | | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``ghcjs`` | | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``ghcjs-pkg`` | | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``greencard`` | Greencard hasn't been updated since 2014, it doesn't build with newer GHCs ``_ | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``haddock`` | ``_ | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``happy`` | ``_ | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``haskell-suite`` | Haskell suite was abandoned a long time ago. | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``haskell-suite-pkg`` | Haskell suite was abandoned a long time ago. | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``hmake`` | Seems like hmake disappeared a long time ago ``_ | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``hpc`` | ``_ | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``hsc2hs`` | ``_ | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``hscolour`` | ``_ | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``jhc`` | ``_ | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``ld`` | Usually provided by GHC's ``"ld command"`` entry in ``ghc --info``. | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``pkg-config`` | | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``runghc`` | | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``strip`` | | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``tar`` | | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ +| ``uhc`` | ``_ | ++-----------------------+------------------------------------------------------------------------------------------------------------------------------------+ + +.. warning:: + + It is important to not confuse these options with the ones listed in the + :ref:`build info` section. The ``*-options`` fields mentioned are in + fact syntactic sugar for specific ``ghc-options`` that will be passed only on + certain phases. + +.. warning:: + + These options will be used when ``cabal`` invokes the tool as part of the build process or as part of a + :pkg-field:`build-tool-depends` declaration, not whenever the tool is invoked by + third parties. + + In particular this means that for example ``gcc-options`` will be used when ``cabal`` + invokes ``gcc``, which is **not** when C sources are compiled by GHC (even though GHC + might invoke ``gcc`` internally). In order to provide options through GHC for those programs, one has to check the + GHC User guide's `Section `_. + In short, those options have to be given as ``-opt`` flags to GHC. + +.. note:: + + The only case that violates the rule specified in this last warning above is + ``ld-options``, which get passed as ``-optl`` options when GHC is invoked for + linking, as with the :pkg-field:`ld-options` field in package descriptions. + Notably, although ``gcc-options`` could be passed as :pkg-field:`cc-options` + in the appropriate phases, they are actually **not** passed. From 87b559bc60d5635149eec955d69e3b1fbe7a0347 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Tue, 9 Jul 2024 00:57:48 +0200 Subject: [PATCH 052/207] Clarify why we can't run .bat files --- Cabal/src/Distribution/Simple/Utils.hs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Cabal/src/Distribution/Simple/Utils.hs b/Cabal/src/Distribution/Simple/Utils.hs index 47caab077af..3688f602759 100644 --- a/Cabal/src/Distribution/Simple/Utils.hs +++ b/Cabal/src/Distribution/Simple/Utils.hs @@ -1950,6 +1950,13 @@ exeExtensions = case (buildArch, buildOS) of -- Possible improvement: on Windows, read the list of extensions from the -- PATHEXT environment variable. By default PATHEXT is ".com; .exe; .bat; -- .cmd". + -- + -- See also #10179. + -- + -- Also we cannot actually run @.bat@ files as we do now, because of + -- https://github.com/haskell/process/issues/140. If we detect one of those, + -- we should record that the program is a script and run a @Process.shell@ instead + -- of a @Process.proc@. (_, Windows) -> ["", "exe"] (_, Ghcjs) -> ["", "exe"] (Wasm32, _) -> ["", "wasm"] From c94c06245492ec3c77c1e8813e3e5e1c3c35188f Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Tue, 9 Jul 2024 00:59:27 +0200 Subject: [PATCH 053/207] Fix local+noindex repos on Windows --- .../src/Distribution/Client/IndexUtils.hs | 4 ++-- cabal-testsuite/src/Test/Cabal/Prelude.hs | 14 +++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/cabal-install/src/Distribution/Client/IndexUtils.hs b/cabal-install/src/Distribution/Client/IndexUtils.hs index 5958deca553..23a7754a065 100644 --- a/cabal-install/src/Distribution/Client/IndexUtils.hs +++ b/cabal-install/src/Distribution/Client/IndexUtils.hs @@ -149,7 +149,7 @@ import System.FilePath , (<.>) , () ) -import qualified System.FilePath.Posix as FilePath.Posix +import qualified System.FilePath as FilePath import System.IO import System.IO.Error (isDoesNotExistError) import System.IO.Unsafe (unsafeInterleaveIO) @@ -928,7 +928,7 @@ withIndexEntries verbosity (RepoIndex _repoCtxt (RepoLocalNoIndex (LocalRepo nam let bs = BS.toStrict contents in ((`CacheGPD` bs) <$> parseGenericPackageDescriptionMaybe bs) where - filename = prettyShow pkgId FilePath.Posix. prettyShow (packageName pkgId) ++ ".cabal" + filename = prettyShow pkgId FilePath. prettyShow (packageName pkgId) ++ ".cabal" readCabalEntry _ _ x = x withIndexEntries verbosity index callback _ = do -- non-secure repositories diff --git a/cabal-testsuite/src/Test/Cabal/Prelude.hs b/cabal-testsuite/src/Test/Cabal/Prelude.hs index d110bd9f433..176b3d994aa 100644 --- a/cabal-testsuite/src/Test/Cabal/Prelude.hs +++ b/cabal-testsuite/src/Test/Cabal/Prelude.hs @@ -544,7 +544,6 @@ src `archiveTo` dst = do -- TODO: --format ustar, like createArchive? -- --force-local is necessary for handling colons in Windows paths. tar $ ["-czf", dst] - ++ ["--force-local" | buildOS == Windows] ++ ["-C", src_parent, src_dir] infixr 4 `archiveTo` @@ -554,10 +553,6 @@ infixr 4 `archiveTo` -- external repository corresponding to all of these packages withRepo :: FilePath -> TestM a -> TestM a withRepo repo_dir m = do - -- https://github.com/haskell/cabal/issues/7065 - -- you don't simply put a windows path into URL... - skipIfWindows - env <- getTestEnv -- 1. Initialize repo directory @@ -603,16 +598,17 @@ withRepo repo_dir m = do withReaderT (\env' -> env' { testHaveRepo = True }) m -- TODO: Arguably should undo everything when we're done... where - repoUri env ="file+noindex://" ++ testRepoDir env + repoUri env ="file+noindex://" ++ (if isWindows + then map (\x -> case x of + '\\' -> '/' + _ -> x) + else id) (testRepoDir env) -- | Given a directory (relative to the 'testCurrentDir') containing -- a series of directories representing packages, generate an -- remote repository corresponding to all of these packages withRemoteRepo :: FilePath -> TestM a -> TestM a withRemoteRepo repoDir m = do - -- https://github.com/haskell/cabal/issues/7065 - -- you don't simply put a windows path into URL... - skipIfWindows -- we rely on the presence of python3 for a simple http server skipUnless "no python3" =<< isAvailableProgram python3Program From 05155c57f29fd4457679bde9557043972fe1d23c Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Tue, 9 Jul 2024 01:00:36 +0200 Subject: [PATCH 054/207] Provide `skip*IO` functions and report issue in known failures --- cabal-testsuite/src/Test/Cabal/Monad.hs | 25 ++++++++++++++++------ cabal-testsuite/src/Test/Cabal/TestCode.hs | 12 +++++------ 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/cabal-testsuite/src/Test/Cabal/Monad.hs b/cabal-testsuite/src/Test/Cabal/Monad.hs index 861538692aa..3dd1c747d32 100644 --- a/cabal-testsuite/src/Test/Cabal/Monad.hs +++ b/cabal-testsuite/src/Test/Cabal/Monad.hs @@ -45,12 +45,14 @@ module Test.Cabal.Monad ( testActualFile, -- * Skipping tests skip, + skipIO, skipIf, + skipIfIO, skipUnless, + skipUnlessIO, -- * Known broken tests expectedBroken, unexpectedSuccess, - -- whenHasSharedLibraries, -- * Arguments (TODO: move me) CommonArgs(..), renderCommonArgs, @@ -176,23 +178,32 @@ testArgParser = TestArgs <*> argument str ( metavar "FILE") <*> commonArgParser -skip :: String -> TestM () -skip reason = liftIO $ do +skipIO :: String -> IO () +skipIO reason = do putStrLn ("SKIP " ++ reason) E.throwIO (TestCodeSkip reason) +skip :: String -> TestM () +skip = liftIO . skipIO + +skipIfIO :: String -> Bool -> IO () +skipIfIO reason b = when b (skipIO reason) + skipIf :: String -> Bool -> TestM () skipIf reason b = when b (skip reason) +skipUnlessIO :: String -> Bool -> IO () +skipUnlessIO reason b = unless b (skipIO reason) + skipUnless :: String -> Bool -> TestM () skipUnless reason b = unless b (skip reason) -expectedBroken :: TestM () -expectedBroken = liftIO $ do +expectedBroken :: Int -> TestM a +expectedBroken t = liftIO $ do putStrLn "EXPECTED FAIL" - E.throwIO TestCodeKnownFail + E.throwIO (TestCodeKnownFail t) -unexpectedSuccess :: TestM () +unexpectedSuccess :: TestM a unexpectedSuccess = liftIO $ do putStrLn "UNEXPECTED OK" E.throwIO TestCodeUnexpectedOk diff --git a/cabal-testsuite/src/Test/Cabal/TestCode.hs b/cabal-testsuite/src/Test/Cabal/TestCode.hs index e29c9ea6b45..4d0762bdae5 100644 --- a/cabal-testsuite/src/Test/Cabal/TestCode.hs +++ b/cabal-testsuite/src/Test/Cabal/TestCode.hs @@ -19,7 +19,7 @@ import Data.Typeable (Typeable) data TestCode = TestCodeOk | TestCodeSkip String - | TestCodeKnownFail + | TestCodeKnownFail Int | TestCodeUnexpectedOk | TestCodeFail deriving (Eq, Show, Read, Typeable) @@ -31,11 +31,11 @@ instance Exception TestCode #endif displayTestCode :: TestCode -> String -displayTestCode TestCodeOk = "OK" -displayTestCode (TestCodeSkip msg) = "SKIP " ++ msg -displayTestCode TestCodeKnownFail = "OK (known failure)" -displayTestCode TestCodeUnexpectedOk = "FAIL (unexpected success)" -displayTestCode TestCodeFail = "FAIL" +displayTestCode TestCodeOk = "OK" +displayTestCode (TestCodeSkip msg) = "SKIP " ++ msg +displayTestCode (TestCodeKnownFail t) = "OK (known failure, see #" <> show t <> ")" +displayTestCode TestCodeUnexpectedOk = "FAIL (unexpected success)" +displayTestCode TestCodeFail = "FAIL" isTestCodeSkip :: TestCode -> Bool isTestCodeSkip (TestCodeSkip _) = True From f40f979323aec786a9783cf0a608f0a38d44d12b Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Tue, 9 Jul 2024 01:01:15 +0200 Subject: [PATCH 055/207] Fix some output normalization issues on Windows --- cabal-testsuite/src/Test/Cabal/Monad.hs | 20 +++++++++++++++---- .../src/Test/Cabal/OutputNormalizer.hs | 18 ++++++++++++++--- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/cabal-testsuite/src/Test/Cabal/Monad.hs b/cabal-testsuite/src/Test/Cabal/Monad.hs index 3dd1c747d32..04eb659696c 100644 --- a/cabal-testsuite/src/Test/Cabal/Monad.hs +++ b/cabal-testsuite/src/Test/Cabal/Monad.hs @@ -556,13 +556,25 @@ mkNormalizerEnv = do return NormalizerEnv { normalizerRoot - = addTrailingPathSeparator (testSourceDir env), + = (if buildOS == Windows + then joinDrive "\\" . dropDrive + else id) + $ addTrailingPathSeparator (testSourceDir env), normalizerTmpDir - = addTrailingPathSeparator (testTmpDir env), + = (if buildOS == Windows + then joinDrive "\\" . dropDrive + else id) + $ addTrailingPathSeparator (testTmpDir env), normalizerCanonicalTmpDir - = addTrailingPathSeparator canonicalizedTestTmpDir, + = (if buildOS == Windows + then joinDrive "\\" . dropDrive + else id) + $ addTrailingPathSeparator canonicalizedTestTmpDir, normalizerGblTmpDir - = addTrailingPathSeparator tmpDir, + = (if buildOS == Windows + then joinDrive "\\" . dropDrive + else id) + $ addTrailingPathSeparator tmpDir, normalizerGhcVersion = compilerVersion (testCompiler env), normalizerGhcPath diff --git a/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs b/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs index 42daa708885..3f4dcf5bc5a 100644 --- a/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs +++ b/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs @@ -19,26 +19,34 @@ import qualified Data.Foldable as F normalizeOutput :: NormalizerEnv -> String -> String normalizeOutput nenv = - -- Munge away .exe suffix on filenames (Windows) - resub "([A-Za-z0-9.-]+)\\.exe" "\\1" -- Normalize backslashes to forward slashes to normalize -- file paths - . map (\c -> if c == '\\' then '/' else c) + map (\c -> if c == '\\' then '/' else c) -- Install path frequently has architecture specific elements, so -- nub it out . resub "Installing (.+) in .+" "Installing \\1 in " -- Things that look like libraries . resub "libHS[A-Za-z0-9.-]+\\.(so|dll|a|dynlib)" "" -- look for PackageHash directories + . (if buildOS == Windows + then resub "\\\\(([A-Za-z0-9_]+)(-[A-Za-z0-9\\._]+)*)-[0-9a-f]{4,64}\\\\" + "\\\\-\\\\" + else id) . resub "/(([A-Za-z0-9_]+)(-[A-Za-z0-9\\._]+)*)-[0-9a-f]{4,64}/" "/-/" -- This is dumb but I don't feel like pulling in another dep for -- string search-replace. Make sure we do this before backslash -- normalization! . resub (posixRegexEscape (normalizerGblTmpDir nenv) ++ "[a-z0-9\\.-]+") "" + -- Munge away .exe suffix on filenames (Windows) + . (if buildOS == Windows then resub "([A-Za-z0-9.-]+)\\.exe" "\\1" else id) + -- tmp/src-[0-9]+ is tmp\src-[0-9]+ in Windows + . (if buildOS == Windows then resub (posixRegexEscape "tmp\\src-" ++ "[0-9]+") "" else id) . resub (posixRegexEscape "tmp/src-" ++ "[0-9]+") "" . resub (posixRegexEscape (normalizerTmpDir nenv) ++ sameDir) "/" . resub (posixRegexEscape (normalizerCanonicalTmpDir nenv) ++ sameDir) "/" + -- Munge away C: prefix on filenames (Windows). We convert C:\\ to \\. + . (if buildOS == Windows then resub "([A-Z]):\\\\" "\\\\" else id) . appEndo (F.fold (map (Endo . packageIdRegex) (normalizerKnownPackages nenv))) -- Look for 0.1/installed-0d6uzW7Ubh1Fb4TB5oeQ3G -- These installed packages will vary depending on GHC version @@ -46,6 +54,10 @@ normalizeOutput nenv = . resub "[0-9]+(\\.[0-9]+)*/installed-[A-Za-z0-9.+]+" "/installed-" -- incoming directories in the store + . (if buildOS == Windows then resub "\\\\incoming\\\\new-[0-9]+" + "\\\\incoming\\\\new-" + else id) + -- incoming directories in the store . resub "/incoming/new-[0-9]+" "/incoming/new-" -- Normalize architecture From 71ad6378597ce3d590b4a8d0a21d0e17ef001ffa Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Tue, 9 Jul 2024 01:01:41 +0200 Subject: [PATCH 056/207] Rework how the skipping and expected functions work --- cabal-testsuite/src/Test/Cabal/Prelude.hs | 42 ++++++++++++----------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/cabal-testsuite/src/Test/Cabal/Prelude.hs b/cabal-testsuite/src/Test/Cabal/Prelude.hs index 176b3d994aa..80653c49f3a 100644 --- a/cabal-testsuite/src/Test/Cabal/Prelude.hs +++ b/cabal-testsuite/src/Test/Cabal/Prelude.hs @@ -846,6 +846,9 @@ hasProfiledLibraries = testCompilerWithArgs ["-prof"] hasProfiledSharedLibraries = testCompilerWithArgs ["-prof", "-dynamic"] hasSharedLibraries = testCompilerWithArgs ["-dynamic"] +skipIfNoSharedLibraries :: TestM () +skipIfNoSharedLibraries = skipUnless "no shared libraries" =<< hasSharedLibraries + -- | Check if the GHC that is used for compiling package tests has -- a shared library of the cabal library under test in its database. -- @@ -881,7 +884,6 @@ isCabalVersion decide range = do skipUnlessAnyCabalVersion :: String -> TestM () skipUnlessAnyCabalVersion range = skipUnless ("needs any Cabal " ++ range) =<< anyCabalVersion range - -- | Skip a test if any available Cabal library version matches the predicate. skipIfAnyCabalVersion :: String -> TestM () skipIfAnyCabalVersion range = skipIf ("incompatible with Cabal " ++ range) =<< anyCabalVersion range @@ -912,28 +914,28 @@ skipUnlessGhcVersion range = skipUnless ("needs ghc " ++ range) =<< isGhcVersion skipIfGhcVersion :: String -> TestM () skipIfGhcVersion range = skipIf ("incompatible with ghc " ++ range) =<< isGhcVersion range -skipUnlessJavaScript :: TestM () -skipUnlessJavaScript = skipUnless "needs the JavaScript backend" =<< isJavaScript +skipUnlessJavaScript :: IO () +skipUnlessJavaScript = skipUnlessIO "needs the JavaScript backend" isJavaScript -skipIfJavaScript :: TestM () -skipIfJavaScript = skipIf "incompatible with the JavaScript backend" =<< isJavaScript +skipIfJavaScript :: IO () +skipIfJavaScript = skipIfIO "incompatible with the JavaScript backend" isJavaScript -isWindows :: TestM Bool -isWindows = return (buildOS == Windows) +isWindows :: Bool +isWindows = buildOS == Windows -isOSX :: TestM Bool -isOSX = return (buildOS == OSX) +isOSX :: Bool +isOSX = buildOS == OSX -isLinux :: TestM Bool -isLinux = return (buildOS == Linux) +isLinux :: Bool +isLinux = buildOS == Linux -isJavaScript :: TestM Bool -isJavaScript = return (buildArch == JavaScript) +isJavaScript :: Bool +isJavaScript = buildArch == JavaScript -- should probably be `hostArch` but Cabal doesn't distinguish build platform -- and host platform -skipIfWindows :: TestM () -skipIfWindows = skipIf "Windows" =<< isWindows +skipIfWindows :: String -> IO () +skipIfWindows why = skipIfIO ("Windows " <> why) isWindows getOpenFilesLimit :: TestM (Maybe Integer) #ifdef mingw32_HOST_OS @@ -962,7 +964,7 @@ hasNewBuildCompatBootCabal = isGhcVersion ">= 7.9" ------------------------------------------------------------------------ -- * Broken tests -expectBroken :: Int -> TestM a -> TestM () +expectBroken :: Int -> TestM a -> TestM a expectBroken ticket m = do env <- getTestEnv liftIO . withAsync (runReaderT m env) $ \a -> do @@ -971,15 +973,15 @@ expectBroken ticket m = do Left e -> do putStrLn $ "This test is known broken, see #" ++ show ticket ++ ":" print e - runReaderT expectedBroken env + runReaderT (expectedBroken ticket) env Right _ -> do runReaderT unexpectedSuccess env -expectBrokenIf :: Bool -> Int -> TestM a -> TestM () -expectBrokenIf False _ m = void $ m +expectBrokenIf :: Bool -> Int -> TestM a -> TestM a +expectBrokenIf False _ m = m expectBrokenIf True ticket m = expectBroken ticket m -expectBrokenUnless :: Bool -> Int -> TestM a -> TestM () +expectBrokenUnless :: Bool -> Int -> TestM a -> TestM a expectBrokenUnless b = expectBrokenIf (not b) -- * Programs From aa6ec820933e4d56f1c3ca066cbb0b8a063eb3b3 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Tue, 9 Jul 2024 01:01:52 +0200 Subject: [PATCH 057/207] Un-ignore .bat files --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 957786d7055..3450353924b 100644 --- a/.gitignore +++ b/.gitignore @@ -78,7 +78,6 @@ testdb/intree/store/*/package.db/package.cache.lock # windows test artifacts cabal-testsuite/**/*.exe -cabal-testsuite/**/*.bat cabal-testsuite/**/haddocks # python artifacts from documentation builds From d57853326d2071294873d1819b0dfbf56ad3ca32 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Mon, 15 Jul 2024 17:33:37 +0200 Subject: [PATCH 058/207] Docs: Clarify MSYS2 complications --- doc/how-to-run-in-windows.rst | 67 +++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/doc/how-to-run-in-windows.rst b/doc/how-to-run-in-windows.rst index 5c06f62bbb3..53aeb33b849 100644 --- a/doc/how-to-run-in-windows.rst +++ b/doc/how-to-run-in-windows.rst @@ -8,7 +8,7 @@ more explanations. For a TL;DR, jump to the :ref:`Complete configuration`. Install the Haskell environment ------------------------------- -Haskell development on Windows makes use of the `MSYS2 `_ +Haskell development on Windows makes use of the `MSYS2 `_ tools. The recommended way of setting up a Haskell environment in Windows is by using @@ -19,11 +19,43 @@ system in your computer unless told not to do so: refer to `its documentation .. NOTE:: Stack is another tool you can use to set up a Haskell environment on Windows. Stack - can be installed on its own or via GHCup. See - `Stack's webpage `_ and/or + can be installed on its own or via GHCup. See + `Stack's webpage `_ and/or `GHCup's section on Stack integration `_, in particular the `Windows related subsection `_. +MSYS2 environments and packages +------------------------------- + +A particular environment has to be chosen when using MSYS2. By default GHCup will +use ``MINGW64``. You can learn more about the different environments in the `MSYS2 +documentation `_. + +GHCs before 9.4.1 are shipped with a minimal set of packages based on the +``MINGW64`` environment, and GHC 9.4.1 and newer are shipped with a minimal set +of packages based on the ``CLANG64`` environment. It is in general advisable to +work inside the same environment as your GHC uses, but (with some exceptions) +it shouldn't matter whether environments are mixed. Stay warned that it can +sometimes lead to undecipherable errors. + +We will refer to the chosen environment as ```` through this +documentation. + +Third-party libraries and tools can be installed using the ``pacman`` package +manager on the MSYS2 installation +(`see `_). If MSYS2 was +installed via GHCup, check GHCup's documentation on how to call ``pacman``. Note +that installing a package ``mingw-w64--x86_64-`` will install +it in the ``\`` tree of directories, and might not be +visible if working on a different environment than ````. In +general, it is advisable to install only packages for the environment that was +chosen above. + +Apart from these environments, there is the ``msys`` environment which is based +on Cygwin. Some tools only exist for this environment. Tools from this environment +are callable when working in any other environment. It is in general not possible +to link to libraries installed in the ``msys`` environment. + Ensure that Cabal can call the tools it needs --------------------------------------------- @@ -39,11 +71,10 @@ Windows. The directories where those are located need to be made visible in the extra-prog-path: \\bin \usr\bin -Where ```` points to the location of your MSYS2 installation. Refer to -GHCup's documentation on the default location of this directory. -```` has to be one of the environments of MSYS2, which for GHCup is -``mingw64``. You can learn more about the different environments in the `MSYS2 -documentation `_. +Where ```` points to the location of your MSYS2 installation. If MSYS2 +was installed via GHCup, refer to GHCup's documentation on the default location +of this directory. If MSYS2 was installed system-wide this is usually +``C:\msys64``. .. note:: @@ -53,8 +84,7 @@ documentation `_. Ensure that Cabal can use system libraries ------------------------------------------ -Third-party libraries can be installed using the ``pacman`` package manager on -the MSYS2 installation. When installing a third party package its libraries and +When installing a third party package its libraries and header files will (usually) be placed in ``\\{lib,include}`` respectively. These directories need to be specified in the ``extra-lib-dirs`` and ``extra-include-dirs`` @@ -74,11 +104,18 @@ include these options: .. warning:: - Packages in the ``msys/`` repo are not native Windows libraries and will - probably not work when one tries to link to them. Install the packages for - your selected environment, which for GHCup is ``mingw64/``. Refer to `MSYS2's - package management documentation - `_ for more information. + GHCs older than 9.4.1 will crash if a recent + ``mingw-w64--x86_64-crt-git`` is installed for whichever ```` and + these directories are set globally . + + Effectively this means that if you have installed ``mingw-w64--x86_64-crt-git`` + (which you probably have if you are using ``clang`` in the ``CLANG64`` + environment or ``gcc`` in the ``UCRT64`` or ``MINGW64`` environments outside of + Haskell, as this package is part of the ``mingw-w64--x86_64-toolchain`` + meta-packages) and are using a GHC older than 9.4.1, you cannot simply depend on system + libraries by adding these paths to the global config, and instead you will + have to go through some other method to depend on those libraries like + :pkg-field:`pkgconfig-depends`. Ensure that Cabal can call Haskell tools ---------------------------------------- From a136189101eeaade20b3db01980e22993ad63999 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Mon, 15 Jul 2024 17:33:22 +0200 Subject: [PATCH 059/207] Fix a bunch of Windows tests, clarify why others are broken --- .../AutoconfBadPaths/cabal.test.hs | 60 ++++++------ .../Includes2/{Includes2.cabal => I.cabal} | 6 +- .../Includes2.cabal => I.cabal.fail} | 0 .../I.cabal} | 0 .../Includes2/{Includes2.cabal => I.cabal} | 4 +- .../Backpack/Includes2/cabal-external.test.hs | 4 +- .../Includes2/cabal-internal-target.out | 8 +- .../Backpack/Includes2/cabal-internal.out | 66 ++++++------- .../Backpack/Includes2/cabal-internal.test.hs | 5 +- .../PackageTests/Backpack/Includes2/cov.out | 70 +++++++------- .../Backpack/Includes2/cov.test.hs | 1 - .../Includes2/setup-internal.cabal.out | 50 +++++----- .../Backpack/Includes2/setup-internal.out | 50 +++++----- .../Includes2/setup-per-component.out | 92 +++++++++---------- .../Includes2/setup-per-component.test.hs | 2 +- .../Includes3/{Includes3.cabal => I.cabal} | 2 +- .../Backpack/Includes3/cabal-external.test.hs | 4 +- .../Backpack/Includes3/cabal-internal.out | 34 +++---- .../Backpack/Includes3/cabal-internal.test.hs | 5 +- .../Backpack/Includes3/cabal-repo.test.hs | 1 - .../Includes3/setup-internal.cabal.out | 40 ++++---- .../Backpack/Includes3/setup-internal.out | 40 ++++---- .../PackageTests/Backpack/T6385/cabal.test.hs | 3 +- .../bkpcabal01/{bkpcabal01.cabal => b.cabal} | 2 +- .../Backpack/bkpcabal01/cabal.out | 56 +++++------ .../Backpack/bkpcabal01/cabal.test.hs | 4 +- .../PackageTests/BuildTools/Foreign/A.hs | 5 + .../Foreign/my-foreign-preprocessor.bat | 2 + .../Foreign/my-foreign-preprocessor.ps1 | 1 + .../BuildTools/Foreign/setup.test.hs | 2 - .../CCompilerOverride/setup.test.hs | 3 +- .../Paths/InvalidWin/cabal.test.hs | 17 ++-- .../PackageTests/CmmSourcesDyn/cabal.test.hs | 2 +- .../ConditionalAndImport/cabal.test.hs | 49 +++++----- .../PackageTests/CustomSegfault/cabal.test.hs | 3 +- .../PackageTests/ExtraProgPath/setup.test.hs | 10 +- .../PackageTests/ForeignLibs/setup.test.hs | 3 +- .../GHCJS/BuildRunner/cabal.test.hs | 4 +- .../GhcPkgGuess/SameDirectory/setup.test.hs | 17 ++-- .../SameDirectoryGhcVersion/setup.test.hs | 17 ++-- .../SameDirectoryVersion/setup.test.hs | 17 ++-- .../GhcPkgGuess/Symlink/setup.test.hs | 5 +- .../SymlinkGhcVersion/setup.test.hs | 5 +- .../GhcPkgGuess/SymlinkVersion/setup.test.hs | 5 +- .../HaddockKeepsTmps/cabal.test.hs | 21 +++-- .../Executable/setup-static.test.hs | 2 +- .../setup-gen-script.test.hs | 3 +- .../PackageTests/JS/JsSources/js-arch.test.hs | 12 +-- .../JS/JsSources/other-arch.test.hs | 9 +- .../JS/JsSourcesExe/js-arch.test.hs | 12 +-- .../JS/JsSourcesExe/other-arch.test.hs | 9 +- .../NonignoredConfigs/cabal.test.hs | 9 +- .../LinkerOptions/T7339/setup.test.hs | 11 +-- .../MultiRepl/EnabledSucc/cabal.test.hs | 1 - .../NewBuild/CmdRun/Terminate/cabal.test.hs | 54 +++++------ ...ackage-from-repo-with-custom-setup.test.hs | 6 +- .../PackageTests/NewBuild/T3827/cabal.test.hs | 4 +- .../PackageTests/NewFreeze/T9799b/src/None.hs | 5 +- .../OfflineFlag/offlineFlag.test.hs | 1 - .../Executable-Relocatable/setup.test.hs | 9 +- .../PackageTests/PkgConfigParse/setup.test.hs | 4 +- .../PreProcess/Hsc2HsOptionsCC/my.cabal | 1 - .../PreProcess/Hsc2HsOptionsCC/setup.test.hs | 32 ++++--- .../PackageTests/ProfShared/setup.test.hs | 5 +- .../QuasiQuotes/dynamic/setup.test.hs | 2 +- .../Regression/T4025/setup.test.hs | 27 +++--- .../Regression/T4270/setup.test.hs | 5 +- .../Regression/T4291/setup.test.hs | 25 ++--- .../Regression/T5309/cabal.test.hs | 12 ++- .../Regression/T5677/cabal.test.hs | 1 - .../Regression/T6906/cabal.test.hs | 3 +- .../ExeV10/cabal-with-hpc.multitest.hs | 4 +- .../clean-install-by-copy.test.hs | 18 ++-- .../clean-install-by-symlink.test.hs | 12 +-- .../WarnEarlyOverwrite/dirty-install.test.hs | 21 ++--- .../postCheckoutCommand/cabal.test.hs | 5 +- validate.sh | 2 +- 77 files changed, 554 insertions(+), 569 deletions(-) rename cabal-testsuite/PackageTests/Backpack/Includes2/{Includes2.cabal => I.cabal} (92%) rename cabal-testsuite/PackageTests/Backpack/Includes2/{Includes2-fail/Includes2.cabal => I.cabal.fail} (100%) rename cabal-testsuite/PackageTests/Backpack/Includes2/{Includes2.cabal.fail => Includes2-fail/I.cabal} (100%) rename cabal-testsuite/PackageTests/Backpack/Includes2/Includes2/{Includes2.cabal => I.cabal} (93%) rename cabal-testsuite/PackageTests/Backpack/Includes3/{Includes3.cabal => I.cabal} (95%) rename cabal-testsuite/PackageTests/Backpack/bkpcabal01/{bkpcabal01.cabal => b.cabal} (96%) create mode 100644 cabal-testsuite/PackageTests/BuildTools/Foreign/my-foreign-preprocessor.bat create mode 100644 cabal-testsuite/PackageTests/BuildTools/Foreign/my-foreign-preprocessor.ps1 diff --git a/cabal-testsuite/PackageTests/AutoconfBadPaths/cabal.test.hs b/cabal-testsuite/PackageTests/AutoconfBadPaths/cabal.test.hs index 93ce9825a36..544764affcd 100644 --- a/cabal-testsuite/PackageTests/AutoconfBadPaths/cabal.test.hs +++ b/cabal-testsuite/PackageTests/AutoconfBadPaths/cabal.test.hs @@ -2,36 +2,38 @@ import Test.Cabal.Prelude import Data.Foldable (traverse_) import Distribution.Simple.Utils import System.Directory -main = cabalTest $ do - -- Test the forbidden characters except NUL. Reference: - -- https://www.gnu.org/software/autoconf/manual/autoconf.html#File-System-Conventions +main = do -- Most of these are magic on Windows, so don't bother testing there. - -- - -- Note: we bundle the configure script so no need to autoreconf - -- while building - skipIfWindows - traverse_ check - [ "foo bar" - , "foo\tbar" - , "foo\nbar" - , "foo\"bar" - , "foo#bar" - , "foo$bar" - , "foo&bar" - , "foo'bar" - , "foo(bar" - , "foo)bar" - , "foo*bar" - , "foo;bar" - , "foobar" - , "foo?bar" - , "foo[bar" - , "foo\\bar" - , "foo`bar" - , "foo|bar" - ] + skipIfWindows "uninteresting" + cabalTest $ + -- Test the forbidden characters except NUL. Reference: + -- https://www.gnu.org/software/autoconf/manual/autoconf.html#File-System-Conventions + -- + -- Note: we bundle the configure script so no need to autoreconf + -- while building + + traverse_ check + [ "foo bar" + , "foo\tbar" + , "foo\nbar" + , "foo\"bar" + , "foo#bar" + , "foo$bar" + , "foo&bar" + , "foo'bar" + , "foo(bar" + , "foo)bar" + , "foo*bar" + , "foo;bar" + , "foobar" + , "foo?bar" + , "foo[bar" + , "foo\\bar" + , "foo`bar" + , "foo|bar" + ] where setup dir = do env <- getTestEnv diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/Includes2.cabal b/cabal-testsuite/PackageTests/Backpack/Includes2/I.cabal similarity index 92% rename from cabal-testsuite/PackageTests/Backpack/Includes2/Includes2.cabal rename to cabal-testsuite/PackageTests/Backpack/Includes2/I.cabal index e6aa6169e68..efaa83b4837 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/Includes2.cabal +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/I.cabal @@ -1,4 +1,4 @@ -name: Includes2 +name: I version: 0.1.0.0 license: BSD3 author: Edward Z. Yang @@ -35,14 +35,14 @@ library default-language: Haskell2010 executable exe - build-depends: base, Includes2 + build-depends: base, I main-is: Main.hs hs-source-dirs: exe default-language: Haskell2010 test-suite includes2-test type: exitcode-stdio-1.0 - build-depends: base, Includes2 + build-depends: base, I main-is: test.hs hs-source-dirs: test default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/Includes2-fail/Includes2.cabal b/cabal-testsuite/PackageTests/Backpack/Includes2/I.cabal.fail similarity index 100% rename from cabal-testsuite/PackageTests/Backpack/Includes2/Includes2-fail/Includes2.cabal rename to cabal-testsuite/PackageTests/Backpack/Includes2/I.cabal.fail diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/Includes2.cabal.fail b/cabal-testsuite/PackageTests/Backpack/Includes2/Includes2-fail/I.cabal similarity index 100% rename from cabal-testsuite/PackageTests/Backpack/Includes2/Includes2.cabal.fail rename to cabal-testsuite/PackageTests/Backpack/Includes2/Includes2-fail/I.cabal diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/Includes2/Includes2.cabal b/cabal-testsuite/PackageTests/Backpack/Includes2/Includes2/I.cabal similarity index 93% rename from cabal-testsuite/PackageTests/Backpack/Includes2/Includes2/Includes2.cabal rename to cabal-testsuite/PackageTests/Backpack/Includes2/Includes2/I.cabal index 7a02fcd961c..793f6a31979 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/Includes2/Includes2.cabal +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/Includes2/I.cabal @@ -1,4 +1,4 @@ -name: Includes2 +name: I version: 0.1.0.0 license: BSD3 author: Edward Z. Yang @@ -35,7 +35,7 @@ library default-language: Haskell2010 executable exe - build-depends: base, Includes2 + build-depends: base, I main-is: Main.hs hs-source-dirs: exe default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-external.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-external.test.hs index 7197786ff2a..432911b1714 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-external.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-external.test.hs @@ -1,8 +1,8 @@ import Test.Cabal.Prelude -main = cabalTest $ do +main = do + cabalTest $ do skipUnlessGhcVersion ">= 8.1" - skipIfWindows -- TODO: https://github.com/haskell/cabal/issues/6271 withProjectFile "cabal.external.project" $ do cabal "v2-build" ["exe"] withPlan $ do diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal-target.out b/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal-target.out index 8b63d59d82c..2a91ccc557a 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal-target.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal-target.out @@ -2,8 +2,8 @@ Resolving dependencies... Build profile: -w ghc- -O1 In order, the following will be built: - - Includes2-0.1.0.0 (lib:mylib) (first run) -Configuring library 'mylib' for Includes2-0.1.0.0... -Preprocessing library 'mylib' for Includes2-0.1.0.0... + - I-0.1.0.0 (lib:mylib) (first run) +Configuring library 'mylib' for I-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with Database = -for Includes2-0.1.0.0... +for I-0.1.0.0... diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.out b/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.out index f8dfb64d9e6..42f77888c8c 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.out @@ -2,42 +2,42 @@ Resolving dependencies... Build profile: -w ghc- -O1 In order, the following will be built: - - Includes2-0.1.0.0 (lib:mylib) (first run) - - Includes2-0.1.0.0 (lib:mysql) (first run) - - Includes2-0.1.0.0 (lib:postgresql) (first run) - - Includes2-0.1.0.0 (lib:mylib with Database=Includes2-0.1.0.0-inplace-mysql:Database.MySQL) (first run) - - Includes2-0.1.0.0 (lib:mylib with Database=Includes2-0.1.0.0-inplace-postgresql:Database.PostgreSQL) (first run) - - Includes2-0.1.0.0 (lib) (first run) - - Includes2-0.1.0.0 (exe:exe) (first run) -Configuring library 'mylib' for Includes2-0.1.0.0... -Preprocessing library 'mylib' for Includes2-0.1.0.0... + - I-0.1.0.0 (lib:mylib) (first run) + - I-0.1.0.0 (lib:mysql) (first run) + - I-0.1.0.0 (lib:postgresql) (first run) + - I-0.1.0.0 (lib:mylib with Database=I-0.1.0.0-inplace-mysql:Database.MySQL) (first run) + - I-0.1.0.0 (lib:mylib with Database=I-0.1.0.0-inplace-postgresql:Database.PostgreSQL) (first run) + - I-0.1.0.0 (lib) (first run) + - I-0.1.0.0 (exe:exe) (first run) +Configuring library 'mylib' for I-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with Database = -for Includes2-0.1.0.0... -Configuring library 'mysql' for Includes2-0.1.0.0... -Preprocessing library 'mysql' for Includes2-0.1.0.0... -Building library 'mysql' for Includes2-0.1.0.0... -Configuring library 'postgresql' for Includes2-0.1.0.0... -Preprocessing library 'postgresql' for Includes2-0.1.0.0... -Building library 'postgresql' for Includes2-0.1.0.0... +for I-0.1.0.0... +Configuring library 'mysql' for I-0.1.0.0... +Preprocessing library 'mysql' for I-0.1.0.0... +Building library 'mysql' for I-0.1.0.0... +Configuring library 'postgresql' for I-0.1.0.0... +Preprocessing library 'postgresql' for I-0.1.0.0... +Building library 'postgresql' for I-0.1.0.0... Configuring library 'mylib' instantiated with - Database = Includes2-0.1.0.0-inplace-mysql:Database.MySQL -for Includes2-0.1.0.0... -Preprocessing library 'mylib' for Includes2-0.1.0.0... + Database = I-0.1.0.0-inplace-mysql:Database.MySQL +for I-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with - Database = Includes2-0.1.0.0-inplace-mysql:Database.MySQL -for Includes2-0.1.0.0... + Database = I-0.1.0.0-inplace-mysql:Database.MySQL +for I-0.1.0.0... Configuring library 'mylib' instantiated with - Database = Includes2-0.1.0.0-inplace-postgresql:Database.PostgreSQL -for Includes2-0.1.0.0... -Preprocessing library 'mylib' for Includes2-0.1.0.0... + Database = I-0.1.0.0-inplace-postgresql:Database.PostgreSQL +for I-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with - Database = Includes2-0.1.0.0-inplace-postgresql:Database.PostgreSQL -for Includes2-0.1.0.0... -Configuring library for Includes2-0.1.0.0... -Preprocessing library for Includes2-0.1.0.0... -Building library for Includes2-0.1.0.0... -Configuring executable 'exe' for Includes2-0.1.0.0... -Preprocessing executable 'exe' for Includes2-0.1.0.0... -Building executable 'exe' for Includes2-0.1.0.0... -# Includes2 exe + Database = I-0.1.0.0-inplace-postgresql:Database.PostgreSQL +for I-0.1.0.0... +Configuring library for I-0.1.0.0... +Preprocessing library for I-0.1.0.0... +Building library for I-0.1.0.0... +Configuring executable 'exe' for I-0.1.0.0... +Preprocessing executable 'exe' for I-0.1.0.0... +Building executable 'exe' for I-0.1.0.0... +# I exe "minemysql minepostgresql" diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.test.hs index a04fdd4987a..6a05d9f0e96 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.test.hs @@ -2,9 +2,8 @@ import Test.Cabal.Prelude main = cabalTest $ do skipUnlessGhcVersion ">= 8.1" - skipIfWindows -- TODO: https://github.com/haskell/cabal/issues/6271 - withProjectFile "cabal.internal.project" $ do + expectBrokenIf isWindows 10191 $ withProjectFile "cabal.internal.project" $ do cabal "v2-build" ["exe"] withPlan $ do - r <- runPlanExe' "Includes2" "exe" [] + r <- runPlanExe' "I" "exe" [] assertOutputContains "minemysql minepostgresql" r diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/cov.out b/cabal-testsuite/PackageTests/Backpack/Includes2/cov.out index 784baff09e7..0d1b2c027b5 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/cov.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/cov.out @@ -2,47 +2,47 @@ Resolving dependencies... Build profile: -w ghc- -O1 In order, the following will be built: - - Includes2-0.1.0.0 (lib:mylib) (first run) - - Includes2-0.1.0.0 (lib:mysql) (first run) - - Includes2-0.1.0.0 (lib:postgresql) (first run) - - Includes2-0.1.0.0 (lib:mylib with Database=Includes2-0.1.0.0-inplace-mysql:Database.MySQL) (first run) - - Includes2-0.1.0.0 (lib:mylib with Database=Includes2-0.1.0.0-inplace-postgresql:Database.PostgreSQL) (first run) - - Includes2-0.1.0.0 (lib) (first run) - - Includes2-0.1.0.0 (test:includes2-test) (first run) -Configuring library 'mylib' for Includes2-0.1.0.0... -Preprocessing library 'mylib' for Includes2-0.1.0.0... + - I-0.1.0.0 (lib:mylib) (first run) + - I-0.1.0.0 (lib:mysql) (first run) + - I-0.1.0.0 (lib:postgresql) (first run) + - I-0.1.0.0 (lib:mylib with Database=I-0.1.0.0-inplace-mysql:Database.MySQL) (first run) + - I-0.1.0.0 (lib:mylib with Database=I-0.1.0.0-inplace-postgresql:Database.PostgreSQL) (first run) + - I-0.1.0.0 (lib) (first run) + - I-0.1.0.0 (test:includes2-test) (first run) +Configuring library 'mylib' for I-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with Database = -for Includes2-0.1.0.0... -Configuring library 'mysql' for Includes2-0.1.0.0... -Preprocessing library 'mysql' for Includes2-0.1.0.0... -Building library 'mysql' for Includes2-0.1.0.0... -Configuring library 'postgresql' for Includes2-0.1.0.0... -Preprocessing library 'postgresql' for Includes2-0.1.0.0... -Building library 'postgresql' for Includes2-0.1.0.0... +for I-0.1.0.0... +Configuring library 'mysql' for I-0.1.0.0... +Preprocessing library 'mysql' for I-0.1.0.0... +Building library 'mysql' for I-0.1.0.0... +Configuring library 'postgresql' for I-0.1.0.0... +Preprocessing library 'postgresql' for I-0.1.0.0... +Building library 'postgresql' for I-0.1.0.0... Configuring library 'mylib' instantiated with - Database = Includes2-0.1.0.0-inplace-mysql:Database.MySQL -for Includes2-0.1.0.0... -Preprocessing library 'mylib' for Includes2-0.1.0.0... + Database = I-0.1.0.0-inplace-mysql:Database.MySQL +for I-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with - Database = Includes2-0.1.0.0-inplace-mysql:Database.MySQL -for Includes2-0.1.0.0... + Database = I-0.1.0.0-inplace-mysql:Database.MySQL +for I-0.1.0.0... Configuring library 'mylib' instantiated with - Database = Includes2-0.1.0.0-inplace-postgresql:Database.PostgreSQL -for Includes2-0.1.0.0... -Preprocessing library 'mylib' for Includes2-0.1.0.0... + Database = I-0.1.0.0-inplace-postgresql:Database.PostgreSQL +for I-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with - Database = Includes2-0.1.0.0-inplace-postgresql:Database.PostgreSQL -for Includes2-0.1.0.0... -Configuring library for Includes2-0.1.0.0... -Preprocessing library for Includes2-0.1.0.0... -Building library for Includes2-0.1.0.0... -Configuring test suite 'includes2-test' for Includes2-0.1.0.0... -Preprocessing test suite 'includes2-test' for Includes2-0.1.0.0... -Building test suite 'includes2-test' for Includes2-0.1.0.0... + Database = I-0.1.0.0-inplace-postgresql:Database.PostgreSQL +for I-0.1.0.0... +Configuring library for I-0.1.0.0... +Preprocessing library for I-0.1.0.0... +Building library for I-0.1.0.0... +Configuring test suite 'includes2-test' for I-0.1.0.0... +Preprocessing test suite 'includes2-test' for I-0.1.0.0... +Building test suite 'includes2-test' for I-0.1.0.0... Running 1 test suites... Test suite includes2-test: RUNNING... Test suite includes2-test: PASS -Test suite logged to: /cov.dist/work/./dist/build//ghc-/Includes2-0.1.0.0/t/includes2-test/test/Includes2-0.1.0.0-includes2-test.log -Package coverage report written to /cov.dist/work/./dist/build//ghc-/Includes2-0.1.0.0/t/includes2-test/hpc/vanilla/html/hpc_index.html +Test suite logged to: /cov.dist/work/./dist/build//ghc-/I-0.1.0.0/t/includes2-test/test/I-0.1.0.0-includes2-test.log +Package coverage report written to /cov.dist/work/./dist/build//ghc-/I-0.1.0.0/t/includes2-test/hpc/vanilla/html/hpc_index.html 1 of 1 test suites (1 of 1 test cases) passed. -Package coverage report written to /cov.dist/work/./dist/build//ghc-/Includes2-0.1.0.0/t/includes2-test/hpc/vanilla/html/hpc_index.html +Package coverage report written to /cov.dist/work/./dist/build//ghc-/I-0.1.0.0/t/includes2-test/hpc/vanilla/html/hpc_index.html diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/cov.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes2/cov.test.hs index 24c1662c375..40079c0e787 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/cov.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/cov.test.hs @@ -1,6 +1,5 @@ import Test.Cabal.Prelude main = cabalTest $ do skipUnlessGhcVersion ">= 8.1" - skipIfWindows -- TODO: https://github.com/haskell/cabal/issues/6271 -- #6397 cabal "test" ["--enable-coverage", "includes2-test"] diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-internal.cabal.out b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-internal.cabal.out index 12dc4aecc6c..e8f2fa18d85 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-internal.cabal.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-internal.cabal.out @@ -1,25 +1,25 @@ # Setup configure -Configuring Includes2-0.1.0.0... +Configuring I-0.1.0.0... # Setup build -Preprocessing library 'postgresql' for Includes2-0.1.0.0... -Building library 'postgresql' for Includes2-0.1.0.0... -Preprocessing library 'mysql' for Includes2-0.1.0.0... -Building library 'mysql' for Includes2-0.1.0.0... -Preprocessing library 'mylib' for Includes2-0.1.0.0... +Preprocessing library 'postgresql' for I-0.1.0.0... +Building library 'postgresql' for I-0.1.0.0... +Preprocessing library 'mysql' for I-0.1.0.0... +Building library 'mysql' for I-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with Database = -for Includes2-0.1.0.0... -Preprocessing library 'mylib' for Includes2-0.1.0.0... +for I-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with - Database = Includes2-0.1.0.0-mysql:Database.MySQL -for Includes2-0.1.0.0... -Preprocessing library 'mylib' for Includes2-0.1.0.0... + Database = I-0.1.0.0-postgresql:Database.PostgreSQL +for I-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with - Database = Includes2-0.1.0.0-postgresql:Database.PostgreSQL -for Includes2-0.1.0.0... -Preprocessing library for Includes2-0.1.0.0... -Building library for Includes2-0.1.0.0... -Preprocessing executable 'exe' for Includes2-0.1.0.0... -Building executable 'exe' for Includes2-0.1.0.0... + Database = I-0.1.0.0-mysql:Database.MySQL +for I-0.1.0.0... +Preprocessing library for I-0.1.0.0... +Building library for I-0.1.0.0... +Preprocessing executable 'exe' for I-0.1.0.0... +Building executable 'exe' for I-0.1.0.0... # Setup copy Installing internal library postgresql in Installing internal library mysql in @@ -30,16 +30,16 @@ Installing library in Installing executable exe in Warning: The directory /setup-internal.cabal.dist/usr/bin is not in the system search path. # Setup register -Registering library 'postgresql' for Includes2-0.1.0.0... -Registering library 'mysql' for Includes2-0.1.0.0... +Registering library 'postgresql' for I-0.1.0.0... +Registering library 'mysql' for I-0.1.0.0... Registering library 'mylib' instantiated with Database = -for Includes2-0.1.0.0... +for I-0.1.0.0... Registering library 'mylib' instantiated with - Database = Includes2-0.1.0.0-mysql:Database.MySQL -for Includes2-0.1.0.0... + Database = I-0.1.0.0-postgresql:Database.PostgreSQL +for I-0.1.0.0... Registering library 'mylib' instantiated with - Database = Includes2-0.1.0.0-postgresql:Database.PostgreSQL -for Includes2-0.1.0.0... -Registering library for Includes2-0.1.0.0... + Database = I-0.1.0.0-mysql:Database.MySQL +for I-0.1.0.0... +Registering library for I-0.1.0.0... # exe "minemysql minepostgresql" diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-internal.out b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-internal.out index 700f1b2fbfc..0cb3b8768c3 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-internal.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-internal.out @@ -1,25 +1,25 @@ # Setup configure -Configuring Includes2-0.1.0.0... +Configuring I-0.1.0.0... # Setup build -Preprocessing library 'postgresql' for Includes2-0.1.0.0... -Building library 'postgresql' for Includes2-0.1.0.0... -Preprocessing library 'mysql' for Includes2-0.1.0.0... -Building library 'mysql' for Includes2-0.1.0.0... -Preprocessing library 'mylib' for Includes2-0.1.0.0... +Preprocessing library 'postgresql' for I-0.1.0.0... +Building library 'postgresql' for I-0.1.0.0... +Preprocessing library 'mysql' for I-0.1.0.0... +Building library 'mysql' for I-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with Database = -for Includes2-0.1.0.0... -Preprocessing library 'mylib' for Includes2-0.1.0.0... +for I-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with - Database = Includes2-0.1.0.0-mysql:Database.MySQL -for Includes2-0.1.0.0... -Preprocessing library 'mylib' for Includes2-0.1.0.0... + Database = I-0.1.0.0-postgresql:Database.PostgreSQL +for I-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with - Database = Includes2-0.1.0.0-postgresql:Database.PostgreSQL -for Includes2-0.1.0.0... -Preprocessing library for Includes2-0.1.0.0... -Building library for Includes2-0.1.0.0... -Preprocessing executable 'exe' for Includes2-0.1.0.0... -Building executable 'exe' for Includes2-0.1.0.0... + Database = I-0.1.0.0-mysql:Database.MySQL +for I-0.1.0.0... +Preprocessing library for I-0.1.0.0... +Building library for I-0.1.0.0... +Preprocessing executable 'exe' for I-0.1.0.0... +Building executable 'exe' for I-0.1.0.0... # Setup copy Installing internal library postgresql in Installing internal library mysql in @@ -30,16 +30,16 @@ Installing library in Installing executable exe in Warning: The directory /setup-internal.dist/usr/bin is not in the system search path. # Setup register -Registering library 'postgresql' for Includes2-0.1.0.0... -Registering library 'mysql' for Includes2-0.1.0.0... +Registering library 'postgresql' for I-0.1.0.0... +Registering library 'mysql' for I-0.1.0.0... Registering library 'mylib' instantiated with Database = -for Includes2-0.1.0.0... +for I-0.1.0.0... Registering library 'mylib' instantiated with - Database = Includes2-0.1.0.0-mysql:Database.MySQL -for Includes2-0.1.0.0... + Database = I-0.1.0.0-postgresql:Database.PostgreSQL +for I-0.1.0.0... Registering library 'mylib' instantiated with - Database = Includes2-0.1.0.0-postgresql:Database.PostgreSQL -for Includes2-0.1.0.0... -Registering library for Includes2-0.1.0.0... + Database = I-0.1.0.0-mysql:Database.MySQL +for I-0.1.0.0... +Registering library for I-0.1.0.0... # exe "minemysql minepostgresql" diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out index 36c406d8584..5fff9a72819 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out @@ -1,107 +1,107 @@ # Setup configure -Configuring library 'mylib' for Includes2-0.1.0.0... +Configuring library 'mylib' for I-0.1.0.0... # Setup build -Preprocessing library 'mylib' for Includes2-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with Database = -for Includes2-0.1.0.0... +for I-0.1.0.0... # Setup haddock -Preprocessing library 'mylib' for Includes2-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Running Haddock on library 'mylib' instantiated with Database = -for Includes2-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/mylib +for I-0.1.0.0... +Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/I/mylib # Setup copy Installing internal library mylib in # Setup register Registering library 'mylib' instantiated with Database = -for Includes2-0.1.0.0... +for I-0.1.0.0... # Setup configure -Configuring library 'mysql' for Includes2-0.1.0.0... +Configuring library 'mysql' for I-0.1.0.0... # Setup build -Preprocessing library 'mysql' for Includes2-0.1.0.0... -Building library 'mysql' for Includes2-0.1.0.0... +Preprocessing library 'mysql' for I-0.1.0.0... +Building library 'mysql' for I-0.1.0.0... # Setup haddock -Preprocessing library 'mysql' for Includes2-0.1.0.0... -Running Haddock on library 'mysql' for Includes2-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/mysql +Preprocessing library 'mysql' for I-0.1.0.0... +Running Haddock on library 'mysql' for I-0.1.0.0... +Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/I/mysql # Setup copy Installing internal library mysql in # Setup register -Registering library 'mysql' for Includes2-0.1.0.0... +Registering library 'mysql' for I-0.1.0.0... # Setup configure -Configuring library 'postgresql' for Includes2-0.1.0.0... +Configuring library 'postgresql' for I-0.1.0.0... # Setup build -Preprocessing library 'postgresql' for Includes2-0.1.0.0... -Building library 'postgresql' for Includes2-0.1.0.0... +Preprocessing library 'postgresql' for I-0.1.0.0... +Building library 'postgresql' for I-0.1.0.0... # Setup haddock -Preprocessing library 'postgresql' for Includes2-0.1.0.0... -Running Haddock on library 'postgresql' for Includes2-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/postgresql +Preprocessing library 'postgresql' for I-0.1.0.0... +Running Haddock on library 'postgresql' for I-0.1.0.0... +Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/I/postgresql # Setup copy Installing internal library postgresql in # Setup register -Registering library 'postgresql' for Includes2-0.1.0.0... +Registering library 'postgresql' for I-0.1.0.0... # Setup configure Configuring library 'mylib' instantiated with Database = mysql-0.1.0.0:Database.MySQL -for Includes2-0.1.0.0... +for I-0.1.0.0... # Setup build -Preprocessing library 'mylib' for Includes2-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with Database = mysql-0.1.0.0:Database.MySQL -for Includes2-0.1.0.0... +for I-0.1.0.0... # Setup haddock -Preprocessing library 'mylib' for Includes2-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Running Haddock on library 'mylib' instantiated with Database = mysql-0.1.0.0:Database.MySQL -for Includes2-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/mylib +for I-0.1.0.0... +Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/I/mylib # Setup copy Installing internal library mylib in # Setup register Registering library 'mylib' instantiated with Database = mysql-0.1.0.0:Database.MySQL -for Includes2-0.1.0.0... +for I-0.1.0.0... # Setup configure Configuring library 'mylib' instantiated with Database = postgresql-0.1.0.0:Database.PostgreSQL -for Includes2-0.1.0.0... +for I-0.1.0.0... # Setup build -Preprocessing library 'mylib' for Includes2-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Building library 'mylib' instantiated with Database = postgresql-0.1.0.0:Database.PostgreSQL -for Includes2-0.1.0.0... +for I-0.1.0.0... # Setup haddock -Preprocessing library 'mylib' for Includes2-0.1.0.0... +Preprocessing library 'mylib' for I-0.1.0.0... Running Haddock on library 'mylib' instantiated with Database = postgresql-0.1.0.0:Database.PostgreSQL -for Includes2-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2/mylib +for I-0.1.0.0... +Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/I/mylib # Setup copy Installing internal library mylib in # Setup register Registering library 'mylib' instantiated with Database = postgresql-0.1.0.0:Database.PostgreSQL -for Includes2-0.1.0.0... +for I-0.1.0.0... # Setup configure -Configuring library for Includes2-0.1.0.0... +Configuring library for I-0.1.0.0... # Setup build -Preprocessing library for Includes2-0.1.0.0... -Building library for Includes2-0.1.0.0... +Preprocessing library for I-0.1.0.0... +Building library for I-0.1.0.0... # Setup haddock -Preprocessing library for Includes2-0.1.0.0... -Running Haddock on library for Includes2-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/Includes2 +Preprocessing library for I-0.1.0.0... +Running Haddock on library for I-0.1.0.0... +Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/I # Setup copy Installing library in # Setup register -Registering library for Includes2-0.1.0.0... +Registering library for I-0.1.0.0... # Setup configure -Configuring executable 'exe' for Includes2-0.1.0.0... +Configuring executable 'exe' for I-0.1.0.0... # Setup build -Preprocessing executable 'exe' for Includes2-0.1.0.0... -Building executable 'exe' for Includes2-0.1.0.0... +Preprocessing executable 'exe' for I-0.1.0.0... +Building executable 'exe' for I-0.1.0.0... # Setup haddock -Preprocessing executable 'exe' for Includes2-0.1.0.0... +Preprocessing executable 'exe' for I-0.1.0.0... # Setup copy Installing executable exe in Warning: The directory /setup-per-component.dist/usr/bin is not in the system search path. diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs index 5bbb1b02af2..b6034011a14 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs @@ -14,6 +14,6 @@ main = setupTest $ do "--instantiate-with", "Database=mysql-0.1.0.0:Database.MySQL"] setup_install' ["mylib", "--cid", "mylib-0.1.0.0", "--instantiate-with", "Database=postgresql-0.1.0.0:Database.PostgreSQL"] - setup_install' ["Includes2"] + setup_install' ["I"] setup_install' ["exe"] runExe' "exe" [] >>= assertOutputContains "minemysql minepostgresql" diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/Includes3.cabal b/cabal-testsuite/PackageTests/Backpack/Includes3/I.cabal similarity index 95% rename from cabal-testsuite/PackageTests/Backpack/Includes3/Includes3.cabal rename to cabal-testsuite/PackageTests/Backpack/Includes3/I.cabal index 7016e221218..ca17845e21d 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/Includes3.cabal +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/I.cabal @@ -1,4 +1,4 @@ -name: Includes3 +name: I version: 0.1.0.0 license: BSD3 author: Edward Z. Yang diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs index 80a4c47d068..6e6f017ee9f 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs @@ -1,9 +1,9 @@ import Test.Cabal.Prelude main = cabalTest $ do + ghcVer <- isGhcVersion ">= 9.10" skipUnlessGhcVersion ">= 8.1" - skipIfWindows -- TODO: https://github.com/haskell/cabal/issues/6271 - withProjectFile "cabal.external.project" $ do + expectBrokenIf (isWindows && ghcVer) 10191 $ withProjectFile "cabal.external.project" $ do cabal "v2-build" ["exe"] withPlan $ do r <- runPlanExe' "exe" "exe" [] diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.out b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.out index 88b36e02c50..f7e2f2d75ef 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.out @@ -2,27 +2,27 @@ Resolving dependencies... Build profile: -w ghc- -O1 In order, the following will be built: - - Includes3-0.1.0.0 (lib:sigs) (first run) - - Includes3-0.1.0.0 (lib:indef) (first run) - - Includes3-0.1.0.0 (lib:indef with Data.Map=containers-:Data.Map) (first run) - - Includes3-0.1.0.0 (exe:exe) (first run) -Configuring library 'sigs' for Includes3-0.1.0.0... -Preprocessing library 'sigs' for Includes3-0.1.0.0... + - I-0.1.0.0 (lib:sigs) (first run) + - I-0.1.0.0 (lib:indef) (first run) + - I-0.1.0.0 (lib:indef with Data.Map=containers-:Data.Map) (first run) + - I-0.1.0.0 (exe:exe) (first run) +Configuring library 'sigs' for I-0.1.0.0... +Preprocessing library 'sigs' for I-0.1.0.0... Building library 'sigs' instantiated with Data.Map = -for Includes3-0.1.0.0... -Configuring library 'indef' for Includes3-0.1.0.0... -Preprocessing library 'indef' for Includes3-0.1.0.0... +for I-0.1.0.0... +Configuring library 'indef' for I-0.1.0.0... +Preprocessing library 'indef' for I-0.1.0.0... Building library 'indef' instantiated with Data.Map = -for Includes3-0.1.0.0... +for I-0.1.0.0... Configuring library 'indef' instantiated with Data.Map = containers-:Data.Map -for Includes3-0.1.0.0... -Preprocessing library 'indef' for Includes3-0.1.0.0... +for I-0.1.0.0... +Preprocessing library 'indef' for I-0.1.0.0... Building library 'indef' instantiated with Data.Map = containers-:Data.Map -for Includes3-0.1.0.0... -Configuring executable 'exe' for Includes3-0.1.0.0... -Preprocessing executable 'exe' for Includes3-0.1.0.0... -Building executable 'exe' for Includes3-0.1.0.0... -# Includes3 exe +for I-0.1.0.0... +Configuring executable 'exe' for I-0.1.0.0... +Preprocessing executable 'exe' for I-0.1.0.0... +Building executable 'exe' for I-0.1.0.0... +# I exe fromList [(0,2),(2,4)] diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.test.hs index b247e56259a..cca3ecf2954 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.test.hs @@ -2,9 +2,8 @@ import Test.Cabal.Prelude main = cabalTest $ do skipUnlessGhcVersion ">= 8.1" - skipIfWindows -- TODO: https://github.com/haskell/cabal/issues/6271 - withProjectFile "cabal.internal.project" $ do + expectBrokenIf isWindows 10191 $ withProjectFile "cabal.internal.project" $ do cabal "v2-build" ["exe"] withPlan $ do - r <- runPlanExe' "Includes3" "exe" [] + r <- runPlanExe' "I" "exe" [] assertOutputContains "fromList [(0,2),(2,4)]" r diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-repo.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-repo.test.hs index 00e2aff3c84..03b74a01b9a 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-repo.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-repo.test.hs @@ -1,7 +1,6 @@ import Test.Cabal.Prelude main = cabalTest $ withShorterPathForNewBuildStore $ do skipUnlessGhcVersion ">= 8.1" - skipIfWindows -- TODO: https://github.com/haskell/cabal/issues/6271 withProjectFile "cabal.repo.project" $ do withRepo "repo" $ do cabal "v2-build" ["exe"] diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-internal.cabal.out b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-internal.cabal.out index ea300c9286d..9ac4463aa6e 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-internal.cabal.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-internal.cabal.out @@ -1,18 +1,18 @@ # Setup configure -Configuring Includes3-0.1.0.0... +Configuring I-0.1.0.0... # Setup build -Preprocessing library 'sigs' for Includes3-0.1.0.0... +Preprocessing library 'sigs' for I-0.1.0.0... Building library 'sigs' instantiated with Data.Map = -for Includes3-0.1.0.0... -Preprocessing library 'indef' for Includes3-0.1.0.0... +for I-0.1.0.0... +Preprocessing library 'indef' for I-0.1.0.0... Building library 'indef' instantiated with Data.Map = -for Includes3-0.1.0.0... -Preprocessing library 'indef' for Includes3-0.1.0.0... +for I-0.1.0.0... +Preprocessing library 'indef' for I-0.1.0.0... Building library 'indef' instantiated with Data.Map = containers-:Data.Map -for Includes3-0.1.0.0... -Preprocessing executable 'exe' for Includes3-0.1.0.0... -Building executable 'exe' for Includes3-0.1.0.0... +for I-0.1.0.0... +Preprocessing executable 'exe' for I-0.1.0.0... +Building executable 'exe' for I-0.1.0.0... # Setup copy Installing internal library sigs in Installing internal library indef in @@ -21,24 +21,24 @@ Installing executable exe in Warning: The directory /setup-internal.cabal.dist/usr/bin is not in the system search path. # Setup register Registering library 'sigs' instantiated with Data.Map = -for Includes3-0.1.0.0... +for I-0.1.0.0... Registering library 'indef' instantiated with Data.Map = -for Includes3-0.1.0.0... +for I-0.1.0.0... Registering library 'indef' instantiated with Data.Map = containers-:Data.Map -for Includes3-0.1.0.0... +for I-0.1.0.0... # Setup build -Preprocessing library 'sigs' for Includes3-0.1.0.0... +Preprocessing library 'sigs' for I-0.1.0.0... Building library 'sigs' instantiated with Data.Map = -for Includes3-0.1.0.0... -Preprocessing library 'indef' for Includes3-0.1.0.0... +for I-0.1.0.0... +Preprocessing library 'indef' for I-0.1.0.0... Building library 'indef' instantiated with Data.Map = -for Includes3-0.1.0.0... -Preprocessing library 'indef' for Includes3-0.1.0.0... +for I-0.1.0.0... +Preprocessing library 'indef' for I-0.1.0.0... Building library 'indef' instantiated with Data.Map = containers-:Data.Map -for Includes3-0.1.0.0... -Preprocessing executable 'exe' for Includes3-0.1.0.0... -Building executable 'exe' for Includes3-0.1.0.0... +for I-0.1.0.0... +Preprocessing executable 'exe' for I-0.1.0.0... +Building executable 'exe' for I-0.1.0.0... # exe fromList [(0,2),(2,4)] diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-internal.out b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-internal.out index cb9caef57a7..6912ab117cd 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-internal.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-internal.out @@ -1,18 +1,18 @@ # Setup configure -Configuring Includes3-0.1.0.0... +Configuring I-0.1.0.0... # Setup build -Preprocessing library 'sigs' for Includes3-0.1.0.0... +Preprocessing library 'sigs' for I-0.1.0.0... Building library 'sigs' instantiated with Data.Map = -for Includes3-0.1.0.0... -Preprocessing library 'indef' for Includes3-0.1.0.0... +for I-0.1.0.0... +Preprocessing library 'indef' for I-0.1.0.0... Building library 'indef' instantiated with Data.Map = -for Includes3-0.1.0.0... -Preprocessing library 'indef' for Includes3-0.1.0.0... +for I-0.1.0.0... +Preprocessing library 'indef' for I-0.1.0.0... Building library 'indef' instantiated with Data.Map = containers-:Data.Map -for Includes3-0.1.0.0... -Preprocessing executable 'exe' for Includes3-0.1.0.0... -Building executable 'exe' for Includes3-0.1.0.0... +for I-0.1.0.0... +Preprocessing executable 'exe' for I-0.1.0.0... +Building executable 'exe' for I-0.1.0.0... # Setup copy Installing internal library sigs in Installing internal library indef in @@ -21,24 +21,24 @@ Installing executable exe in Warning: The directory /setup-internal.dist/usr/bin is not in the system search path. # Setup register Registering library 'sigs' instantiated with Data.Map = -for Includes3-0.1.0.0... +for I-0.1.0.0... Registering library 'indef' instantiated with Data.Map = -for Includes3-0.1.0.0... +for I-0.1.0.0... Registering library 'indef' instantiated with Data.Map = containers-:Data.Map -for Includes3-0.1.0.0... +for I-0.1.0.0... # Setup build -Preprocessing library 'sigs' for Includes3-0.1.0.0... +Preprocessing library 'sigs' for I-0.1.0.0... Building library 'sigs' instantiated with Data.Map = -for Includes3-0.1.0.0... -Preprocessing library 'indef' for Includes3-0.1.0.0... +for I-0.1.0.0... +Preprocessing library 'indef' for I-0.1.0.0... Building library 'indef' instantiated with Data.Map = -for Includes3-0.1.0.0... -Preprocessing library 'indef' for Includes3-0.1.0.0... +for I-0.1.0.0... +Preprocessing library 'indef' for I-0.1.0.0... Building library 'indef' instantiated with Data.Map = containers-:Data.Map -for Includes3-0.1.0.0... -Preprocessing executable 'exe' for Includes3-0.1.0.0... -Building executable 'exe' for Includes3-0.1.0.0... +for I-0.1.0.0... +Preprocessing executable 'exe' for I-0.1.0.0... +Building executable 'exe' for I-0.1.0.0... # exe fromList [(0,2),(2,4)] diff --git a/cabal-testsuite/PackageTests/Backpack/T6385/cabal.test.hs b/cabal-testsuite/PackageTests/Backpack/T6385/cabal.test.hs index 0a31702615c..930a61bb54e 100644 --- a/cabal-testsuite/PackageTests/Backpack/T6385/cabal.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/T6385/cabal.test.hs @@ -1,7 +1,6 @@ import Test.Cabal.Prelude main = - cabalTest $ withShorterPathForNewBuildStore $ do + cabalTest $ expectBrokenIf isWindows 10191 $ withShorterPathForNewBuildStore $ do skipUnlessGhcVersion ">= 8.1" - skipIfWindows -- TODO: https://github.com/haskell/cabal/issues/6271 withRepo "repo" $ do cabal "v2-build" ["T6385"] diff --git a/cabal-testsuite/PackageTests/Backpack/bkpcabal01/bkpcabal01.cabal b/cabal-testsuite/PackageTests/Backpack/bkpcabal01/b.cabal similarity index 96% rename from cabal-testsuite/PackageTests/Backpack/bkpcabal01/bkpcabal01.cabal rename to cabal-testsuite/PackageTests/Backpack/bkpcabal01/b.cabal index f10d1aad151..f1e92112a1f 100644 --- a/cabal-testsuite/PackageTests/Backpack/bkpcabal01/bkpcabal01.cabal +++ b/cabal-testsuite/PackageTests/Backpack/bkpcabal01/b.cabal @@ -1,5 +1,5 @@ cabal-version: 2.0 -name: bkpcabal01 +name: b version: 0.1.0.0 description: This test also exists in GHC's test-suite under the same name and was ported over to cabal's testsuite as it exposed a diff --git a/cabal-testsuite/PackageTests/Backpack/bkpcabal01/cabal.out b/cabal-testsuite/PackageTests/Backpack/bkpcabal01/cabal.out index 4630087ccc2..3ebec1cc5c1 100644 --- a/cabal-testsuite/PackageTests/Backpack/bkpcabal01/cabal.out +++ b/cabal-testsuite/PackageTests/Backpack/bkpcabal01/cabal.out @@ -2,33 +2,33 @@ Resolving dependencies... Build profile: -w ghc- -O1 In order, the following will be built: - - bkpcabal01-0.1.0.0 (lib:impl) (first run) - - bkpcabal01-0.1.0.0 (lib:p) (first run) - - bkpcabal01-0.1.0.0 (lib:p with H=bkpcabal01-0.1.0.0-inplace-impl:H) (first run) - - bkpcabal01-0.1.0.0 (lib:q) (first run) - - bkpcabal01-0.1.0.0 (lib:q with I=bkpcabal01-0.1.0.0-inplace-impl:I) (first run) - - bkpcabal01-0.1.0.0 (exe:exe) (first run) -Configuring library 'impl' for bkpcabal01-0.1.0.0... -Preprocessing library 'impl' for bkpcabal01-0.1.0.0... -Building library 'impl' for bkpcabal01-0.1.0.0... -Configuring library 'p' for bkpcabal01-0.1.0.0... -Preprocessing library 'p' for bkpcabal01-0.1.0.0... + - b-0.1.0.0 (lib:impl) (first run) + - b-0.1.0.0 (lib:p) (first run) + - b-0.1.0.0 (lib:p with H=b-0.1.0.0-inplace-impl:H) (first run) + - b-0.1.0.0 (lib:q) (first run) + - b-0.1.0.0 (lib:q with I=b-0.1.0.0-inplace-impl:I) (first run) + - b-0.1.0.0 (exe:exe) (first run) +Configuring library 'impl' for b-0.1.0.0... +Preprocessing library 'impl' for b-0.1.0.0... +Building library 'impl' for b-0.1.0.0... +Configuring library 'p' for b-0.1.0.0... +Preprocessing library 'p' for b-0.1.0.0... Building library 'p' instantiated with H = -for bkpcabal01-0.1.0.0... -Configuring library 'p' instantiated with H = bkpcabal01-0.1.0.0-inplace-impl:H -for bkpcabal01-0.1.0.0... -Preprocessing library 'p' for bkpcabal01-0.1.0.0... -Building library 'p' instantiated with H = bkpcabal01-0.1.0.0-inplace-impl:H -for bkpcabal01-0.1.0.0... -Configuring library 'q' for bkpcabal01-0.1.0.0... -Preprocessing library 'q' for bkpcabal01-0.1.0.0... +for b-0.1.0.0... +Configuring library 'p' instantiated with H = b-0.1.0.0-inplace-impl:H +for b-0.1.0.0... +Preprocessing library 'p' for b-0.1.0.0... +Building library 'p' instantiated with H = b-0.1.0.0-inplace-impl:H +for b-0.1.0.0... +Configuring library 'q' for b-0.1.0.0... +Preprocessing library 'q' for b-0.1.0.0... Building library 'q' instantiated with I = -for bkpcabal01-0.1.0.0... -Configuring library 'q' instantiated with I = bkpcabal01-0.1.0.0-inplace-impl:I -for bkpcabal01-0.1.0.0... -Preprocessing library 'q' for bkpcabal01-0.1.0.0... -Building library 'q' instantiated with I = bkpcabal01-0.1.0.0-inplace-impl:I -for bkpcabal01-0.1.0.0... -Configuring executable 'exe' for bkpcabal01-0.1.0.0... -Preprocessing executable 'exe' for bkpcabal01-0.1.0.0... -Building executable 'exe' for bkpcabal01-0.1.0.0... +for b-0.1.0.0... +Configuring library 'q' instantiated with I = b-0.1.0.0-inplace-impl:I +for b-0.1.0.0... +Preprocessing library 'q' for b-0.1.0.0... +Building library 'q' instantiated with I = b-0.1.0.0-inplace-impl:I +for b-0.1.0.0... +Configuring executable 'exe' for b-0.1.0.0... +Preprocessing executable 'exe' for b-0.1.0.0... +Building executable 'exe' for b-0.1.0.0... diff --git a/cabal-testsuite/PackageTests/Backpack/bkpcabal01/cabal.test.hs b/cabal-testsuite/PackageTests/Backpack/bkpcabal01/cabal.test.hs index 5a30f6a867a..0f1b7544e07 100644 --- a/cabal-testsuite/PackageTests/Backpack/bkpcabal01/cabal.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/bkpcabal01/cabal.test.hs @@ -1,6 +1,6 @@ import Test.Cabal.Prelude -main = cabalTest $ do +main = do + cabalTest $ do -- GHC 8.2.2 had a regression ("unknown package: hole"), see also #4908 skipUnlessGhcVersion ">= 8.2 && <8.2.2 || >8.2.2" - skipIfWindows -- TODO: https://github.com/haskell/cabal/issues/6271 cabal "v2-build" ["all"] diff --git a/cabal-testsuite/PackageTests/BuildTools/Foreign/A.hs b/cabal-testsuite/PackageTests/BuildTools/Foreign/A.hs index eae7f4476f3..45fc0ecfe9e 100644 --- a/cabal-testsuite/PackageTests/BuildTools/Foreign/A.hs +++ b/cabal-testsuite/PackageTests/BuildTools/Foreign/A.hs @@ -1,4 +1,9 @@ +{-# LANGUAGE CPP #-} +#if mingw32_HOST_OS +{-# OPTIONS_GHC -F -pgmF my-foreign-preprocessor.bat #-} +#else {-# OPTIONS_GHC -F -pgmF my-foreign-preprocessor #-} +#endif module A where a :: String diff --git a/cabal-testsuite/PackageTests/BuildTools/Foreign/my-foreign-preprocessor.bat b/cabal-testsuite/PackageTests/BuildTools/Foreign/my-foreign-preprocessor.bat new file mode 100644 index 00000000000..51e58f1b40c --- /dev/null +++ b/cabal-testsuite/PackageTests/BuildTools/Foreign/my-foreign-preprocessor.bat @@ -0,0 +1,2 @@ +echo @off +pwsh my-foreign-preprocessor.ps1 %1 %2 %3 diff --git a/cabal-testsuite/PackageTests/BuildTools/Foreign/my-foreign-preprocessor.ps1 b/cabal-testsuite/PackageTests/BuildTools/Foreign/my-foreign-preprocessor.ps1 new file mode 100644 index 00000000000..1bb89bcc1b8 --- /dev/null +++ b/cabal-testsuite/PackageTests/BuildTools/Foreign/my-foreign-preprocessor.ps1 @@ -0,0 +1 @@ +get-content $args[1] | %{$_ -replace "0","1"} > $args[2] diff --git a/cabal-testsuite/PackageTests/BuildTools/Foreign/setup.test.hs b/cabal-testsuite/PackageTests/BuildTools/Foreign/setup.test.hs index 9860683f7b0..b698f579f93 100644 --- a/cabal-testsuite/PackageTests/BuildTools/Foreign/setup.test.hs +++ b/cabal-testsuite/PackageTests/BuildTools/Foreign/setup.test.hs @@ -5,9 +5,7 @@ import Control.Monad.IO.Class import System.Environment -- Test PATH-munging --- TODO: Enable this test on Windows main = setupAndCabalTest $ do - skipIfWindows path <- liftIO $ getEnv "PATH" cwd <- testCurrentDir <$> getTestEnv r <- withEnv [("PATH", Just $ cwd ++ ":" ++ path)] $ setup_build [] diff --git a/cabal-testsuite/PackageTests/CCompilerOverride/setup.test.hs b/cabal-testsuite/PackageTests/CCompilerOverride/setup.test.hs index b4f7f04ddb1..7cdb7c75287 100644 --- a/cabal-testsuite/PackageTests/CCompilerOverride/setup.test.hs +++ b/cabal-testsuite/PackageTests/CCompilerOverride/setup.test.hs @@ -9,13 +9,12 @@ import Test.Cabal.Prelude -- https://gitlab.haskell.org/ghc/ghc/-/commit/8ff3134ed4aa323b0199ad683f72165e51a59ab6 main = setupAndCabalTest $ do skipUnlessGhcVersion ">= 8.8" - isWin <- isWindows ghc94 <- isGhcVersion ">= 9.4.1" env <- getTestEnv let pwd = testCurrentDir env win_suffix = if ghc94 then "-clang.bat" else ".bat" customCC = - pwd ++ "/custom-cc" ++ if isWin then win_suffix else "" + pwd ++ "/custom-cc" ++ if isWindows then win_suffix else "" setup "configure" [ "--ghc-option=-optc=-DNOERROR2" diff --git a/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/InvalidWin/cabal.test.hs b/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/InvalidWin/cabal.test.hs index 2201d7c73dc..12398950ed9 100644 --- a/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/InvalidWin/cabal.test.hs +++ b/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/InvalidWin/cabal.test.hs @@ -3,11 +3,12 @@ import Test.Cabal.Prelude import System.Directory (createDirectoryIfMissing) -- Invalid Windows filepath. -main = cabalTest $ do - skipIfWindows - cwd <- testCurrentDir <$> getTestEnv - liftIO $ createDirectoryIfMissing False $ cwd "n?ul" - liftIO $ writeFile (cwd "n?ul" "test.a") "" - -- A directory named like `n?ul` on Windows will make external - -- tools like git — and hence the whole testsuite — error. - fails $ cabal "check" [] +main = do + -- A directory named like `n?ul` on Windows will make external + -- tools like git — and hence the whole testsuite — error. + skipIfWindows "uninteresting" + cabalTest $ do + cwd <- testCurrentDir <$> getTestEnv + liftIO $ createDirectoryIfMissing False $ cwd "n?ul" + liftIO $ writeFile (cwd "n?ul" "test.a") "" + fails $ cabal "check" [] diff --git a/cabal-testsuite/PackageTests/CmmSourcesDyn/cabal.test.hs b/cabal-testsuite/PackageTests/CmmSourcesDyn/cabal.test.hs index ee8aa155ac2..0e39257c843 100644 --- a/cabal-testsuite/PackageTests/CmmSourcesDyn/cabal.test.hs +++ b/cabal-testsuite/PackageTests/CmmSourcesDyn/cabal.test.hs @@ -1,7 +1,7 @@ import Test.Cabal.Prelude main = cabalTest $ do - skipIfWindows + skipIfNoSharedLibraries res <- cabal' "v2-run" ["demo"] assertOutputContains "= Post common block elimination =" res assertOutputContains "In Box we have 0x" res diff --git a/cabal-testsuite/PackageTests/ConditionalAndImport/cabal.test.hs b/cabal-testsuite/PackageTests/ConditionalAndImport/cabal.test.hs index f0ba4299c7a..c1aea47ce85 100644 --- a/cabal-testsuite/PackageTests/ConditionalAndImport/cabal.test.hs +++ b/cabal-testsuite/PackageTests/ConditionalAndImport/cabal.test.hs @@ -1,5 +1,8 @@ import Test.Cabal.Prelude +normalizeWindowsOutput :: String -> String +normalizeWindowsOutput = if isWindows then map (\x -> case x of '/' -> '\\'; _ -> x) else id + main = cabalTest . withRepo "repo" . recordMode RecordMarked $ do let log = recordHeader . pure @@ -76,7 +79,7 @@ main = cabalTest . withRepo "repo" . recordMode RecordMarked $ do -- +-- etc log "checking that cyclical check catches a same file name that imports itself" cyclical4a <- fails $ cabal' "v2-build" [ "--project-file=cyclical-same-filename-out-out-self.project" ] - assertOutputContains "cyclical import of same-filename/cyclical-same-filename-out-out-self.config" cyclical4a + assertOutputContains (normalizeWindowsOutput "cyclical import of same-filename/cyclical-same-filename-out-out-self.config") cyclical4a -- +-- cyclical-same-filename-out-out-backback.project -- +-- cyclical-same-filename-out-out-backback.config @@ -112,31 +115,31 @@ main = cabalTest . withRepo "repo" . recordMode RecordMarked $ do assertOutputContains "- hops-0.project" hopping assertOutputContains - "- hops-2.config \ + (normalizeWindowsOutput "- hops-2.config \ \ imported by: hops/hops-1.config \ - \ imported by: hops-0.project" + \ imported by: hops-0.project") hopping assertOutputContains - "- hops-4.config \ + (normalizeWindowsOutput "- hops-4.config \ \ imported by: hops/hops-3.config \ \ imported by: hops-2.config \ \ imported by: hops/hops-1.config \ - \ imported by: hops-0.project" + \ imported by: hops-0.project") hopping assertOutputContains - "- hops-6.config \ + (normalizeWindowsOutput "- hops-6.config \ \ imported by: hops/hops-5.config \ \ imported by: hops-4.config \ \ imported by: hops/hops-3.config \ \ imported by: hops-2.config \ \ imported by: hops/hops-1.config \ - \ imported by: hops-0.project" + \ imported by: hops-0.project") hopping assertOutputContains - "- hops-8.config \ + (normalizeWindowsOutput "- hops-8.config \ \ imported by: hops/hops-7.config \ \ imported by: hops-6.config \ \ imported by: hops/hops-5.config \ @@ -144,43 +147,43 @@ main = cabalTest . withRepo "repo" . recordMode RecordMarked $ do \ imported by: hops/hops-3.config \ \ imported by: hops-2.config \ \ imported by: hops/hops-1.config \ - \ imported by: hops-0.project" + \ imported by: hops-0.project") hopping assertOutputContains - "- hops/hops-1.config \ - \ imported by: hops-0.project" + (normalizeWindowsOutput "- hops/hops-1.config \ + \ imported by: hops-0.project") hopping assertOutputContains - "- hops/hops-3.config \ + (normalizeWindowsOutput "- hops/hops-3.config \ \ imported by: hops-2.config \ \ imported by: hops/hops-1.config \ - \ imported by: hops-0.project" + \ imported by: hops-0.project") hopping assertOutputContains - "- hops/hops-5.config \ + (normalizeWindowsOutput "- hops/hops-5.config \ \ imported by: hops-4.config \ \ imported by: hops/hops-3.config \ \ imported by: hops-2.config \ \ imported by: hops/hops-1.config \ - \ imported by: hops-0.project" + \ imported by: hops-0.project") hopping assertOutputContains - "- hops/hops-7.config \ + (normalizeWindowsOutput "- hops/hops-7.config \ \ imported by: hops-6.config \ \ imported by: hops/hops-5.config \ \ imported by: hops-4.config \ \ imported by: hops/hops-3.config \ \ imported by: hops-2.config \ \ imported by: hops/hops-1.config \ - \ imported by: hops-0.project" + \ imported by: hops-0.project") hopping assertOutputContains - "- hops/hops-9.config \ + (normalizeWindowsOutput "- hops/hops-9.config \ \ imported by: hops-8.config \ \ imported by: hops/hops-7.config \ \ imported by: hops-6.config \ @@ -189,7 +192,7 @@ main = cabalTest . withRepo "repo" . recordMode RecordMarked $ do \ imported by: hops/hops-3.config \ \ imported by: hops-2.config \ \ imported by: hops/hops-1.config \ - \ imported by: hops-0.project" + \ imported by: hops-0.project") hopping -- The project is named oops as it is like hops but has conflicting constraints. @@ -210,7 +213,7 @@ main = cabalTest . withRepo "repo" . recordMode RecordMarked $ do assertOutputContains "(constraint from oops-0.project requires ==1.4.3.0)" oopsing assertOutputContains - " (constraint from oops/oops-9.config requires ==1.4.2.0) \ + (normalizeWindowsOutput " (constraint from oops/oops-9.config requires ==1.4.2.0) \ \ imported by: oops-8.config \ \ imported by: oops/oops-7.config \ \ imported by: oops-6.config \ @@ -219,7 +222,7 @@ main = cabalTest . withRepo "repo" . recordMode RecordMarked $ do \ imported by: oops/oops-3.config \ \ imported by: oops-2.config \ \ imported by: oops/oops-1.config \ - \ imported by: oops-0.project" + \ imported by: oops-0.project") oopsing log "checking bad conditional" @@ -229,12 +232,12 @@ main = cabalTest . withRepo "repo" . recordMode RecordMarked $ do log "checking that missing package message lists configuration provenance" missing <- fails $ cabal' "v2-build" [ "--project-file=cabal-missing-package.project" ] assertOutputContains - "When using configuration from: \ + (normalizeWindowsOutput "When using configuration from: \ \ - cabal-missing-package.project \ \ - missing/pkgs.config \ \ - missing/pkgs/default.config \ \The following errors occurred: \ - \ - The package location 'pkg-doesnt-exist' does not exist." + \ - The package location 'pkg-doesnt-exist' does not exist.") missing return () diff --git a/cabal-testsuite/PackageTests/CustomSegfault/cabal.test.hs b/cabal-testsuite/PackageTests/CustomSegfault/cabal.test.hs index a6c74dab745..b543cc5de45 100644 --- a/cabal-testsuite/PackageTests/CustomSegfault/cabal.test.hs +++ b/cabal-testsuite/PackageTests/CustomSegfault/cabal.test.hs @@ -1,6 +1,5 @@ import Test.Cabal.Prelude main = cabalTest $ do - -- TODO: this test ought to work on Windows too - skipUnless "not Linux" =<< isLinux + skipUnless "depends on `unix` and needs Linux" isLinux skipUnlessGhcVersion ">= 7.8" fails $ cabal' "v2-build" [] >>= assertOutputContains "SIGSEGV" diff --git a/cabal-testsuite/PackageTests/ExtraProgPath/setup.test.hs b/cabal-testsuite/PackageTests/ExtraProgPath/setup.test.hs index 80ee56f6287..ecc6696c1f2 100644 --- a/cabal-testsuite/PackageTests/ExtraProgPath/setup.test.hs +++ b/cabal-testsuite/PackageTests/ExtraProgPath/setup.test.hs @@ -1,8 +1,8 @@ import Test.Cabal.Prelude -- Test that extra-prog-path overrides the path for pkg-config -main = cabalTest $ do - -- skipped on windows because using a script to dummy up an executable doesn't work the same. - skipIfWindows - cdir <- testCurrentDir `fmap` getTestEnv - fails $ cabal "v2-build" ["--extra-prog-path="++cdir] +main = do + skipIfWindows "useless test (CI has no pkg-config already)" + cabalTest $ do + cdir <- testCurrentDir `fmap` getTestEnv + fails $ cabal "v2-build" ["--extra-prog-path="++cdir] diff --git a/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs b/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs index 1dcf918eaed..73d02e90987 100644 --- a/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs +++ b/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs @@ -27,9 +27,8 @@ import Test.Cabal.Prelude main = setupAndCabalTest . recordMode DoNotRecord $ do -- Foreign libraries don't work with GHC 7.6 and earlier skipUnlessGhcVersion ">= 7.8" - win <- isWindows ghc94 <- isGhcVersion ">= 9.4.1" - expectBrokenIf (win && ghc94) 8451 $ + expectBrokenIf (isWindows && ghc94) 8451 $ withPackageDb $ do setup_install [] setup "copy" [] -- regression test #4156 diff --git a/cabal-testsuite/PackageTests/GHCJS/BuildRunner/cabal.test.hs b/cabal-testsuite/PackageTests/GHCJS/BuildRunner/cabal.test.hs index fd7328da0c2..18fa0d364fe 100644 --- a/cabal-testsuite/PackageTests/GHCJS/BuildRunner/cabal.test.hs +++ b/cabal-testsuite/PackageTests/GHCJS/BuildRunner/cabal.test.hs @@ -1,7 +1,7 @@ import Test.Cabal.Prelude -main = cabalTest . recordMode DoNotRecord $ do - skipIfWindows -- disabled because (I presume) Windows doesn't have BASH +main = do + cabalTest . expectBrokenIf isWindows 10179 . recordMode DoNotRecord $ do cwd <- fmap testCurrentDir getTestEnv testInvokedWithBuildRunner cwd "test" [] testInvokedWithBuildRunner cwd "run" ["ghcjs-exe"] diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/setup.test.hs index 85b30b87523..0f0e86a3c60 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/setup.test.hs @@ -1,10 +1,9 @@ import Test.Cabal.Prelude --- TODO: Enable this test on Windows -main = setupAndCabalTest $ do - skipIfWindows - env <- getTestEnv - let cwd = testCurrentDir env - ghc_path <- programPathM ghcProgram - r <- withEnv [("WITH_GHC", Just ghc_path)] - . fails $ setup' "configure" ["-w", cwd "ghc"] - assertOutputContains "is version 9999999" r + +main = setupAndCabalTest $ expectBrokenIf isWindows 10179 $ do + env <- getTestEnv + let cwd = testCurrentDir env + ghc_path <- programPathM ghcProgram + r <- withEnv [("WITH_GHC", Just ghc_path)] + . fails $ setup' "configure" ["-w", cwd "ghc"] + assertOutputContains "is version 9999999" r diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/setup.test.hs index 746c8015fca..20a661437bf 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/setup.test.hs @@ -1,10 +1,9 @@ import Test.Cabal.Prelude --- TODO: Enable this test on Windows -main = setupAndCabalTest $ do - skipIfWindows - env <- getTestEnv - let cwd = testCurrentDir env - ghc_path <- programPathM ghcProgram - r <- withEnv [("WITH_GHC", Just ghc_path)] - . fails $ setup' "configure" ["-w", cwd "ghc-7.10"] - assertOutputContains "is version 9999999" r + +main = setupAndCabalTest $ expectBrokenIf isWindows 10179 $ do + env <- getTestEnv + let cwd = testCurrentDir env + ghc_path <- programPathM ghcProgram + r <- withEnv [("WITH_GHC", Just ghc_path)] + . fails $ setup' "configure" ["-w", cwd "ghc-7.10"] + assertOutputContains "is version 9999999" r diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/setup.test.hs index 746c8015fca..20a661437bf 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/setup.test.hs @@ -1,10 +1,9 @@ import Test.Cabal.Prelude --- TODO: Enable this test on Windows -main = setupAndCabalTest $ do - skipIfWindows - env <- getTestEnv - let cwd = testCurrentDir env - ghc_path <- programPathM ghcProgram - r <- withEnv [("WITH_GHC", Just ghc_path)] - . fails $ setup' "configure" ["-w", cwd "ghc-7.10"] - assertOutputContains "is version 9999999" r + +main = setupAndCabalTest $ expectBrokenIf isWindows 10179 $ do + env <- getTestEnv + let cwd = testCurrentDir env + ghc_path <- programPathM ghcProgram + r <- withEnv [("WITH_GHC", Just ghc_path)] + . fails $ setup' "configure" ["-w", cwd "ghc-7.10"] + assertOutputContains "is version 9999999" r diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/setup.test.hs index eab35100802..18cb32829b1 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/setup.test.hs @@ -1,7 +1,6 @@ import Test.Cabal.Prelude --- TODO: Enable this test on Windows -main = setupAndCabalTest $ do - skipIfWindows + +main = setupAndCabalTest $ expectBrokenIf isWindows 10179 $ do withSymlink "bin/ghc" "ghc" $ do env <- getTestEnv let cwd = testCurrentDir env diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/setup.test.hs index eb95044b941..7837f5f9f3b 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/setup.test.hs @@ -1,7 +1,6 @@ import Test.Cabal.Prelude --- TODO: Enable this test on Windows -main = setupAndCabalTest $ do - skipIfWindows + +main = setupAndCabalTest $ expectBrokenIf isWindows 10179 $ do withSymlink "bin/ghc-7.10" "ghc" $ do env <- getTestEnv let cwd = testCurrentDir env diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/setup.test.hs index eb95044b941..7837f5f9f3b 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/setup.test.hs @@ -1,7 +1,6 @@ import Test.Cabal.Prelude --- TODO: Enable this test on Windows -main = setupAndCabalTest $ do - skipIfWindows + +main = setupAndCabalTest $ expectBrokenIf isWindows 10179 $ do withSymlink "bin/ghc-7.10" "ghc" $ do env <- getTestEnv let cwd = testCurrentDir env diff --git a/cabal-testsuite/PackageTests/HaddockKeepsTmps/cabal.test.hs b/cabal-testsuite/PackageTests/HaddockKeepsTmps/cabal.test.hs index 9a3dfe1777b..a4db6795625 100644 --- a/cabal-testsuite/PackageTests/HaddockKeepsTmps/cabal.test.hs +++ b/cabal-testsuite/PackageTests/HaddockKeepsTmps/cabal.test.hs @@ -1,20 +1,21 @@ {-# LANGUAGE LambdaCase #-} import Test.Cabal.Prelude +import Data.List (sort) import Distribution.Verbosity import Distribution.Simple.Glob import Distribution.Simple.Glob.Internal +import Distribution.Simple.Utils -- Test that "cabal haddock" preserves temporary files -- We use haddock-keep-temp-file: True in the cabal.project. -main = cabalTest $ recordMode DoNotRecord $ do - skipIfWindows +main = cabalTest $ recordMode DoNotRecord $ withProjectFile "cabal.project" $ do + cabal "haddock" [] - cabal "haddock" [] + cwd <- fmap testCurrentDir getTestEnv - cwd <- fmap testCurrentDir getTestEnv - - (globMatches <$> liftIO (runDirFileGlob silent Nothing cwd (GlobDirRecursive [WildCard, Literal "response", WildCard, Literal "txt"]))) >>= \case - [] -> error "Expecting a response file to exist" - (m:_) -> - -- Assert the matched response file is not empty. - assertFileDoesContain (cwd m) "Simple.hs" + -- Windows has multiple response files, and only the last one (alphabetically) is the important one. + (safeLast . sort . globMatches <$> liftIO (runDirFileGlob silent Nothing cwd (GlobDirRecursive [WildCard, Literal "txt"]))) >>= \case + Nothing -> error "Expecting a response file to exist" + Just m -> do + -- Assert the matched response file is not empty, and indeed a haddock rsp + assertFileDoesContain (cwd m) "--package-name" diff --git a/cabal-testsuite/PackageTests/InternalLibraries/Executable/setup-static.test.hs b/cabal-testsuite/PackageTests/InternalLibraries/Executable/setup-static.test.hs index e84be709823..1c12fd03a7a 100644 --- a/cabal-testsuite/PackageTests/InternalLibraries/Executable/setup-static.test.hs +++ b/cabal-testsuite/PackageTests/InternalLibraries/Executable/setup-static.test.hs @@ -24,7 +24,7 @@ import System.Directory -- this does build shared libraries just to make sure they -- don't get installed, so this test doesn't work on Windows.) main = setupAndCabalTest $ do - skipUnless "no shared libs" =<< hasSharedLibraries + skipIfNoSharedLibraries withPackageDb $ do -- MULTI forM_ [False, True] $ \is_dynamic -> do diff --git a/cabal-testsuite/PackageTests/InternalLibraries/setup-gen-script.test.hs b/cabal-testsuite/PackageTests/InternalLibraries/setup-gen-script.test.hs index 644d437b8ab..ada96fc159a 100644 --- a/cabal-testsuite/PackageTests/InternalLibraries/setup-gen-script.test.hs +++ b/cabal-testsuite/PackageTests/InternalLibraries/setup-gen-script.test.hs @@ -1,13 +1,12 @@ import Test.Cabal.Prelude -- Test to see if --gen-script main = setupAndCabalTest $ do - is_windows <- isWindows withPackageDb $ do withDirectory "p" $ do setup_build [] setup "copy" [] setup "register" ["--gen-script"] - _ <- if is_windows + _ <- if isWindows then shell "cmd" ["/C", "register.bat"] else shell "sh" ["register.sh"] return () diff --git a/cabal-testsuite/PackageTests/JS/JsSources/js-arch.test.hs b/cabal-testsuite/PackageTests/JS/JsSources/js-arch.test.hs index 1fed749bdb8..2b318af6670 100644 --- a/cabal-testsuite/PackageTests/JS/JsSources/js-arch.test.hs +++ b/cabal-testsuite/PackageTests/JS/JsSources/js-arch.test.hs @@ -1,9 +1,9 @@ import Test.Cabal.Prelude -main = setupAndCabalTest $ do - skipUnlessGhcVersion ">= 9.6" +main = do skipUnlessJavaScript - skipIfWindows - - res <- cabal' "v2-run" ["demo"] - assertOutputContains "Hello JS!" res + skipIfWindows "" + setupAndCabalTest $ do + skipUnlessGhcVersion ">= 9.6" + res <- cabal' "v2-run" ["demo"] + assertOutputContains "Hello JS!" res diff --git a/cabal-testsuite/PackageTests/JS/JsSources/other-arch.test.hs b/cabal-testsuite/PackageTests/JS/JsSources/other-arch.test.hs index 187a9cf73bd..2e92eb1fcc5 100644 --- a/cabal-testsuite/PackageTests/JS/JsSources/other-arch.test.hs +++ b/cabal-testsuite/PackageTests/JS/JsSources/other-arch.test.hs @@ -1,7 +1,8 @@ import Test.Cabal.Prelude -main = cabalTest $ do +main = do skipIfJavaScript - -- Ensure the field `js-sources` does not raise issues - res <- cabal' "v2-run" ["demo"] - assertOutputContains "Hello Not JS!" res + cabalTest $ do + -- Ensure the field `js-sources` does not raise issues + res <- cabal' "v2-run" ["demo"] + assertOutputContains "Hello Not JS!" res diff --git a/cabal-testsuite/PackageTests/JS/JsSourcesExe/js-arch.test.hs b/cabal-testsuite/PackageTests/JS/JsSourcesExe/js-arch.test.hs index 1fed749bdb8..2b318af6670 100644 --- a/cabal-testsuite/PackageTests/JS/JsSourcesExe/js-arch.test.hs +++ b/cabal-testsuite/PackageTests/JS/JsSourcesExe/js-arch.test.hs @@ -1,9 +1,9 @@ import Test.Cabal.Prelude -main = setupAndCabalTest $ do - skipUnlessGhcVersion ">= 9.6" +main = do skipUnlessJavaScript - skipIfWindows - - res <- cabal' "v2-run" ["demo"] - assertOutputContains "Hello JS!" res + skipIfWindows "" + setupAndCabalTest $ do + skipUnlessGhcVersion ">= 9.6" + res <- cabal' "v2-run" ["demo"] + assertOutputContains "Hello JS!" res diff --git a/cabal-testsuite/PackageTests/JS/JsSourcesExe/other-arch.test.hs b/cabal-testsuite/PackageTests/JS/JsSourcesExe/other-arch.test.hs index 187a9cf73bd..2e92eb1fcc5 100644 --- a/cabal-testsuite/PackageTests/JS/JsSourcesExe/other-arch.test.hs +++ b/cabal-testsuite/PackageTests/JS/JsSourcesExe/other-arch.test.hs @@ -1,7 +1,8 @@ import Test.Cabal.Prelude -main = cabalTest $ do +main = do skipIfJavaScript - -- Ensure the field `js-sources` does not raise issues - res <- cabal' "v2-run" ["demo"] - assertOutputContains "Hello Not JS!" res + cabalTest $ do + -- Ensure the field `js-sources` does not raise issues + res <- cabal' "v2-run" ["demo"] + assertOutputContains "Hello Not JS!" res diff --git a/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.test.hs b/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.test.hs index 8e7c8a6391d..55ec5ee6144 100644 --- a/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.test.hs +++ b/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.test.hs @@ -52,14 +52,7 @@ lrun :: [Linking] lrun = [Static, Dynamic, Static, Dynamic] main = cabalTest $ do - -- Skip if on Windows, since my default Chocolatey Windows setup (and the CI - -- server setup at the time, presumably) lacks support for dynamic builds - -- since the base package appears to be static only, lacking e.g. ‘.dyn_o’ - -- files. Normal Windows installations would need support for dynamic - -- builds, or else this test would fail when it tries to build with the - -- dynamic flags. - skipIfWindows - + skipIfNoSharedLibraries env <- getTestEnv withPackageDb $ do -- Phase 1: get 4 hashes according to config flags. diff --git a/cabal-testsuite/PackageTests/LinkerOptions/T7339/setup.test.hs b/cabal-testsuite/PackageTests/LinkerOptions/T7339/setup.test.hs index a46921de895..233d3b20736 100644 --- a/cabal-testsuite/PackageTests/LinkerOptions/T7339/setup.test.hs +++ b/cabal-testsuite/PackageTests/LinkerOptions/T7339/setup.test.hs @@ -18,8 +18,7 @@ import Test.Cabal.Prelude main = setupTest $ do - - skipIfWindows + skipIfNoSharedLibraries skipUnlessGhcVersion ">= 8.4" withPackageDb $ do @@ -59,9 +58,9 @@ main = setupTest $ do pkgDb <- testPackageDbDir <$> getTestEnv ghciScript <- liftIO $ readFile (cwd "T19350.script") _ <- runProgramM ghcProgram - [ "--interactive" - , "-package", "T7339" - , "-package-db", pkgDb - ] (Just ghciScript) + [ "--interactive" + , "-package", "T7339" + , "-package-db", pkgDb + ] (Just ghciScript) return () diff --git a/cabal-testsuite/PackageTests/MultiRepl/EnabledSucc/cabal.test.hs b/cabal-testsuite/PackageTests/MultiRepl/EnabledSucc/cabal.test.hs index 7ea2f71ea49..5a8434c5467 100644 --- a/cabal-testsuite/PackageTests/MultiRepl/EnabledSucc/cabal.test.hs +++ b/cabal-testsuite/PackageTests/MultiRepl/EnabledSucc/cabal.test.hs @@ -3,6 +3,5 @@ import Test.Cabal.Prelude main = do cabalTest $ do skipUnlessGhcVersion ">= 9.4" - skipIfWindows -- heisenbug, see #9103 res <- cabalWithStdin "v2-repl" ["--enable-multi-repl","pkg-b", "pkg-a"] "Bar.bar" assertOutputContains "3735929054" res diff --git a/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/cabal.test.hs b/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/cabal.test.hs index 44f88c26656..8c3277174b8 100644 --- a/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/cabal.test.hs +++ b/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/cabal.test.hs @@ -17,36 +17,36 @@ without forking in the future.) -} main :: IO () -main = cabalTest $ do - skipIfWindows -- test project relies on Posix +main = do + skipIfWindows "depends on `unix`" + cabalTest $ do + -- timestamped logging to aid with #8416 + let logIO msg = do + ts <- Time.getCurrentTime + let tsfmt = Time.formatTime Time.defaultTimeLocale "%H:%M:%S.%q" ts + putStrLn $ tsfmt <> " [cabal.test] " <> msg + log = liftIO . logIO - -- timestamped logging to aid with #8416 - let logIO msg = do - ts <- Time.getCurrentTime - let tsfmt = Time.formatTime Time.defaultTimeLocale "%H:%M:%S.%q" ts - putStrLn $ tsfmt <> " [cabal.test] " <> msg - log = liftIO . logIO + dir <- fmap testCurrentDir getTestEnv + let runFile = dir "exe.run" + liftIO $ removeFile runFile `catchNoExist` return () - dir <- fmap testCurrentDir getTestEnv - let runFile = dir "exe.run" - liftIO $ removeFile runFile `catchNoExist` return () + log "about to v2-build" + cabal_raw_action ["v2-build", "exe"] (\_ -> return ()) + log "about to v2-run" + r <- fails $ cabal_raw_action ["v2-run", "exe"] $ \cabalHandle -> do + -- wait for "cabal run" to have started "exe" + logIO "about to wait for file" + waitFile total runFile + -- then kill "cabal run" + logIO "about to terminate cabal" + Process.terminateProcess cabalHandle + log "v2-run done" - log "about to v2-build" - cabal_raw_action ["v2-build", "exe"] (\_ -> return ()) - log "about to v2-run" - r <- fails $ cabal_raw_action ["v2-run", "exe"] $ \cabalHandle -> do - -- wait for "cabal run" to have started "exe" - logIO "about to wait for file" - waitFile total runFile - -- then kill "cabal run" - logIO "about to terminate cabal" - Process.terminateProcess cabalHandle - log "v2-run done" - - -- "exe" should exit, and should have been interrupted before - -- finishing its sleep - assertOutputContains "exiting" r - assertOutputDoesNotContain "done sleeping" r + -- "exe" should exit, and should have been interrupted before + -- finishing its sleep + assertOutputContains "exiting" r + assertOutputDoesNotContain "done sleeping" r where catchNoExist action handle = diff --git a/cabal-testsuite/PackageTests/NewBuild/CustomSetup/RemotePackageWithCustomSetup/build-package-from-repo-with-custom-setup.test.hs b/cabal-testsuite/PackageTests/NewBuild/CustomSetup/RemotePackageWithCustomSetup/build-package-from-repo-with-custom-setup.test.hs index f3774f78cd7..114d3487e8e 100644 --- a/cabal-testsuite/PackageTests/NewBuild/CustomSetup/RemotePackageWithCustomSetup/build-package-from-repo-with-custom-setup.test.hs +++ b/cabal-testsuite/PackageTests/NewBuild/CustomSetup/RemotePackageWithCustomSetup/build-package-from-repo-with-custom-setup.test.hs @@ -2,11 +2,7 @@ import Test.Cabal.Prelude -- The one local package, pkg, has a dependency on remote-pkg-2.0, which has a -- setup dependency on remote-setup-dep-3.0. -main = - cabalTest $ withShorterPathForNewBuildStore $ do - - -- TODO: Debug this failure on Windows. - skipIfWindows +main = cabalTest $ withShorterPathForNewBuildStore $ do skipUnless "no v2-build compatible boot-Cabal" =<< hasNewBuildCompatBootCabal withRepo "repo" $ do diff --git a/cabal-testsuite/PackageTests/NewBuild/T3827/cabal.test.hs b/cabal-testsuite/PackageTests/NewBuild/T3827/cabal.test.hs index f418538b074..93d28460c83 100644 --- a/cabal-testsuite/PackageTests/NewBuild/T3827/cabal.test.hs +++ b/cabal-testsuite/PackageTests/NewBuild/T3827/cabal.test.hs @@ -1,6 +1,4 @@ import Test.Cabal.Prelude main = cabalTest $ do - linux <- isLinux - osx <- isOSX - skipIf "8032 heisenbug profiling" (linux || osx) + skipIf "8032 heisenbug profiling" (isLinux || isOSX) cabal "v2-build" ["exe:q"] diff --git a/cabal-testsuite/PackageTests/NewFreeze/T9799b/src/None.hs b/cabal-testsuite/PackageTests/NewFreeze/T9799b/src/None.hs index f4c629a9329..e4aa4f2393a 100644 --- a/cabal-testsuite/PackageTests/NewFreeze/T9799b/src/None.hs +++ b/cabal-testsuite/PackageTests/NewFreeze/T9799b/src/None.hs @@ -3,8 +3,11 @@ module None where import MyLib import Language.Haskell.TH +import System.IO $(do - runIO $ putStrLn $ "Building: " ++ renamedVers + runIO $ do + putStrLn $ "Building: " ++ renamedVers + hFlush stdout [d| x = () |] ) diff --git a/cabal-testsuite/PackageTests/OfflineFlag/offlineFlag.test.hs b/cabal-testsuite/PackageTests/OfflineFlag/offlineFlag.test.hs index 7c9617a623c..00dc5c17ba6 100644 --- a/cabal-testsuite/PackageTests/OfflineFlag/offlineFlag.test.hs +++ b/cabal-testsuite/PackageTests/OfflineFlag/offlineFlag.test.hs @@ -3,7 +3,6 @@ import Test.Cabal.Prelude main = cabalTest $ withShorterPathForNewBuildStore $ do skipUnlessGhcVersion ">= 8.1" - skipIfWindows withProjectFile "cabal.repo.project" $ do withRepo "repo" $ do fails $ cabal "v2-build" ["current", "--offline"] diff --git a/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/setup.test.hs b/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/setup.test.hs index ea88c7f9e41..fab6c7c0a06 100644 --- a/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/setup.test.hs +++ b/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/setup.test.hs @@ -1,7 +1,8 @@ import Test.Cabal.Prelude -- Test that Paths module is generated and usable when relocatable is turned on. -main = setupAndCabalTest $ do - skipIfWindows - skipUnlessGhcVersion ">= 8.0" - withPackageDb $ setup_build ["--enable-relocatable"] +main = do + skipIfWindows "no relocatable builds" + setupAndCabalTest $ do + skipUnlessGhcVersion ">= 8.0" + withPackageDb $ setup_build ["--enable-relocatable"] diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs b/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs index 0f860ab637a..7ccdfca1655 100644 --- a/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs +++ b/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs @@ -1,9 +1,7 @@ import Test.Cabal.Prelude -- Test that invalid unicode in pkg-config output doesn't trip up cabal very much -main = cabalTest $ do - -- skipped on windows because using a script to dummy up an executable doesn't work the same. - skipIfWindows +main = cabalTest $ expectBrokenIf isWindows 10179 $ do cdir <- testCurrentDir `fmap` getTestEnv res <- cabal' "v2-build" ["--extra-prog-path="++cdir, "-v2"] assertOutputContains "Some pkg-config packages have names containing invalid unicode: or" res diff --git a/cabal-testsuite/PackageTests/PreProcess/Hsc2HsOptionsCC/my.cabal b/cabal-testsuite/PackageTests/PreProcess/Hsc2HsOptionsCC/my.cabal index 6d195b52b44..a1f30e58d6c 100644 --- a/cabal-testsuite/PackageTests/PreProcess/Hsc2HsOptionsCC/my.cabal +++ b/cabal-testsuite/PackageTests/PreProcess/Hsc2HsOptionsCC/my.cabal @@ -11,4 +11,3 @@ executable my-executable main-is: Main.hs build-depends: base other-modules: Foo - hsc2hs-options: "--cc=g++" diff --git a/cabal-testsuite/PackageTests/PreProcess/Hsc2HsOptionsCC/setup.test.hs b/cabal-testsuite/PackageTests/PreProcess/Hsc2HsOptionsCC/setup.test.hs index 8dfca6d7d52..eb3a5eb255e 100644 --- a/cabal-testsuite/PackageTests/PreProcess/Hsc2HsOptionsCC/setup.test.hs +++ b/cabal-testsuite/PackageTests/PreProcess/Hsc2HsOptionsCC/setup.test.hs @@ -5,24 +5,34 @@ import System.Directory (findExecutable) -- Check that preprocessors (hsc2hs) are run main = setupAndCabalTest $ do - -- we need "g++" - hasGxx <- liftIO $ fmap isJust $ findExecutable "g++" - skipUnless "g++" hasGxx - - -- Figure out how recent GHC we need - -- https://github.com/msys2/MINGW-packages/issues/3531 - skipIfWindows + -- we need "g++" (or "clang++" in newer Windows) + ghcVer <- isGhcVersion ">= 9.4" + cc <- if isWindows + then + -- The mingw tools distributed with GHC are not usually on the + -- path so we specify the path to cc directly. + joinPath + . (++ ["mingw", "bin", if ghcVer then "clang++.exe" else "g++.exe"]) + . init + . splitPath + . resultOutput + <$> runProgramM ghcProgram ["--print-libdir"] Nothing + else do + hasGxx <- liftIO $ fmap isJust $ findExecutable "g++" + skipUnless "g++" hasGxx + pure "g++" -- we need recent enough hsc2hs -- hsc2hs commit 9671202c11f7fe98e5b96d379532b6f691dc46dd -- Fix when using g++ as C compiler. Patch from elaforge. Fixes ghc #7232 + -- We also require 0.68.8 so that last --cc is the one that applies. p <- requireProgramM hsc2hsProgram case programVersion p of - Nothing -> skip "Unknown hsc2hs version" - Just v | v < mkVersion [0,68] -> skip $ "hsc2hs version: " ++ prettyShow v ++ " < 0.68" - _ -> return () + Nothing -> skip "Unknown hsc2hs version" + Just v | v < mkVersion [0,68,8] -> skip $ "hsc2hs version: " ++ prettyShow v ++ " < 0.68.8" + _ -> return () -- Actual test - setup_build [] + setup_build ["--hsc2hs-options=\"--cc=" <> cc <> "\""] r <- runExe' "my-executable" [] assertOutputContains "Is not C, is C++" r diff --git a/cabal-testsuite/PackageTests/ProfShared/setup.test.hs b/cabal-testsuite/PackageTests/ProfShared/setup.test.hs index 754ff7a290d..84fcbd47e57 100644 --- a/cabal-testsuite/PackageTests/ProfShared/setup.test.hs +++ b/cabal-testsuite/PackageTests/ProfShared/setup.test.hs @@ -8,11 +8,9 @@ data BuildWay = StaticWay | DynWay | ProfWay | ProfDynWay -- Test building with profiling shared support main = do setupTest $ recordMode DoNotRecord $ do - has_prof_shared <- hasProfiledSharedLibraries - has_shared <- hasSharedLibraries -- Tests are not robust against missing dynamic libraries yet. Would -- be better to fix this. - skipUnless "Missing shared libraries" has_shared + skipIfNoSharedLibraries let analyse_result expected r = do @@ -142,4 +140,3 @@ main = do run_cabal_test ["--enable-profiling", "--enable-executable-dynamic"] ([ProfDynWay, ProfWay, DynWay, StaticWay], [ProfDynWay]) run_cabal_test ["prof-shared", "--disable-library-profiling", "--enable-profiling", "--enable-executable-dynamic"] ([ProfDynWay, DynWay, StaticWay], []) - diff --git a/cabal-testsuite/PackageTests/QuasiQuotes/dynamic/setup.test.hs b/cabal-testsuite/PackageTests/QuasiQuotes/dynamic/setup.test.hs index 31309a46f0c..bbc850992fa 100644 --- a/cabal-testsuite/PackageTests/QuasiQuotes/dynamic/setup.test.hs +++ b/cabal-testsuite/PackageTests/QuasiQuotes/dynamic/setup.test.hs @@ -1,5 +1,5 @@ import Test.Cabal.Prelude -- Test building a dynamic library/executable which uses QuasiQuotes main = setupAndCabalTest $ do - skipUnless "no shared libs" =<< hasSharedLibraries + skipIfNoSharedLibraries setup_build ["--enable-shared", "--enable-executable-dynamic"] diff --git a/cabal-testsuite/PackageTests/Regression/T4025/setup.test.hs b/cabal-testsuite/PackageTests/Regression/T4025/setup.test.hs index 0ec5d068147..d6034c7c3f2 100644 --- a/cabal-testsuite/PackageTests/Regression/T4025/setup.test.hs +++ b/cabal-testsuite/PackageTests/Regression/T4025/setup.test.hs @@ -1,16 +1,15 @@ import Test.Cabal.Prelude -- Test that we don't accidentally add the inplace directory to --- an executable RPATH. Don't test on Windows, which doesn't --- support RPATH. -main = setupAndCabalTest $ do - skipIfWindows - osx <- isOSX - ghc <- isGhcVersion ">= 8.10.7" - expectBrokenIf (osx && ghc) 7610 $ do -- see also issue #7988 - setup "configure" ["--enable-executable-dynamic"] - setup "build" [] - -- This should fail as it we should NOT be able to find the - -- dynamic library for the internal library (since we didn't - -- install it). If we incorrectly encoded our local dist - -- dir in the RPATH, this will succeed. - recordMode DoNotRecord . fails $ runExe "exe" [] +-- an executable RPATH. +main = do + skipIfWindows "doesn't support RPATH" + setupAndCabalTest $ do + ghc <- isGhcVersion ">= 8.10.7" + expectBrokenIf (isOSX && ghc) 7610 $ do -- see also issue #7988 + setup "configure" ["--enable-executable-dynamic"] + setup "build" [] + -- This should fail as it we should NOT be able to find the + -- dynamic library for the internal library (since we didn't + -- install it). If we incorrectly encoded our local dist + -- dir in the RPATH, this will succeed. + recordMode DoNotRecord . fails $ runExe "exe" [] diff --git a/cabal-testsuite/PackageTests/Regression/T4270/setup.test.hs b/cabal-testsuite/PackageTests/Regression/T4270/setup.test.hs index 258dcc21e16..bd227b75f3e 100644 --- a/cabal-testsuite/PackageTests/Regression/T4270/setup.test.hs +++ b/cabal-testsuite/PackageTests/Regression/T4270/setup.test.hs @@ -4,10 +4,9 @@ import Test.Cabal.Prelude -- See https://github.com/haskell/cabal/issues/4270 main = setupAndCabalTest $ do skipIfAllCabalVersion "< 2.2" - skipUnless "no shared libs" =<< hasSharedLibraries + skipIfNoSharedLibraries skipUnless "no shared Cabal" =<< hasCabalShared ghc <- isGhcVersion "== 8.0.2" - osx <- isOSX - expectBrokenIf (osx && ghc) 8028 $ do + expectBrokenIf (isOSX && ghc) 8028 $ do setup_build ["--enable-tests", "--enable-executable-dynamic"] setup "test" [] diff --git a/cabal-testsuite/PackageTests/Regression/T4291/setup.test.hs b/cabal-testsuite/PackageTests/Regression/T4291/setup.test.hs index a6eb9844785..f5152c93ccb 100644 --- a/cabal-testsuite/PackageTests/Regression/T4291/setup.test.hs +++ b/cabal-testsuite/PackageTests/Regression/T4291/setup.test.hs @@ -3,15 +3,16 @@ import Test.Cabal.Prelude -- Test that checkRelocate doesn't fail when library directory of dependee -- contains '..' -main = setupAndCabalTest $ withPackageDb $ do - skipIfWindows - skipUnlessGhcVersion ">= 7.6" - env <- getTestEnv - let pkgroot = takeDirectory $ testPackageDbDir env - prefix = testTmpDir env "prefix" - assertBool "we need a prefix that is not under pkgroot for this test" $ - not $ pkgroot `isPrefixOf` prefix - withDirectory "dependee" $ - setup_install ["--enable-relocatable", "--prefix", prefix] - withDirectory "depender" $ - setup_install ["--enable-relocatable", "--prefix", prefix] +main = do + skipIfWindows "no relocatable builds" + setupAndCabalTest $ withPackageDb $ do + skipUnlessGhcVersion ">= 7.6" + env <- getTestEnv + let pkgroot = takeDirectory $ testPackageDbDir env + prefix = testTmpDir env "prefix" + assertBool "we need a prefix that is not under pkgroot for this test" $ + not $ pkgroot `isPrefixOf` prefix + withDirectory "dependee" $ + setup_install ["--enable-relocatable", "--prefix", prefix] + withDirectory "depender" $ + setup_install ["--enable-relocatable", "--prefix", prefix] diff --git a/cabal-testsuite/PackageTests/Regression/T5309/cabal.test.hs b/cabal-testsuite/PackageTests/Regression/T5309/cabal.test.hs index a81a75197f3..e64f2e36951 100644 --- a/cabal-testsuite/PackageTests/Regression/T5309/cabal.test.hs +++ b/cabal-testsuite/PackageTests/Regression/T5309/cabal.test.hs @@ -1,6 +1,8 @@ import Test.Cabal.Prelude -main = cabalTest $ do - skipIfWindows -- TODO: https://github.com/haskell/cabal/issues/6271 - cabal "v2-build" ["all"] - cabal "v2-test" ["all"] - cabal "v2-bench" ["all"] +main = do + cabalTest $ do + ghcVer <- isGhcVersion ">= 9.4" + expectBrokenIf (isWindows && ghcVer) 10189 $ do + cabal "v2-build" ["all"] + cabal "v2-test" ["all"] + cabal "v2-bench" ["all"] diff --git a/cabal-testsuite/PackageTests/Regression/T5677/cabal.test.hs b/cabal-testsuite/PackageTests/Regression/T5677/cabal.test.hs index 27edba49486..a8ea261289a 100644 --- a/cabal-testsuite/PackageTests/Regression/T5677/cabal.test.hs +++ b/cabal-testsuite/PackageTests/Regression/T5677/cabal.test.hs @@ -2,5 +2,4 @@ import Test.Cabal.Prelude main = cabalTest $ do -- -Wmissing-export-lists is new in 8.4. skipUnlessGhcVersion ">= 8.3" - skipIfWindows -- TODO: https://github.com/haskell/cabal/issues/6271 cabal "v2-build" ["all"] diff --git a/cabal-testsuite/PackageTests/Regression/T6906/cabal.test.hs b/cabal-testsuite/PackageTests/Regression/T6906/cabal.test.hs index 233f4a2a3d1..fabfcbdbede 100644 --- a/cabal-testsuite/PackageTests/Regression/T6906/cabal.test.hs +++ b/cabal-testsuite/PackageTests/Regression/T6906/cabal.test.hs @@ -1,9 +1,8 @@ import Test.Cabal.Prelude main = cabalTest $ do - win <- isWindows ghcsWithMaxPathIssue <- isGhcVersion "< 8.6.5" - expectBrokenIf (win && ghcsWithMaxPathIssue) 6271 $ do + expectBrokenIf (isWindows && ghcsWithMaxPathIssue) 6271 $ do res <- recordMode DoNotRecord $ cabalG' ["--config=cabal.config"] "v2-install" ["-v3"] assertOutputContains "creating file with the inputs used to compute the package hash:" res assertOutputContains "extra-lib-dirs: bar" res diff --git a/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/cabal-with-hpc.multitest.hs b/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/cabal-with-hpc.multitest.hs index 14f12247548..c62f83385a3 100644 --- a/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/cabal-with-hpc.multitest.hs +++ b/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/cabal-with-hpc.multitest.hs @@ -9,8 +9,8 @@ import qualified Distribution.Verbosity as Verbosity import Test.Cabal.Prelude main = cabalTest $ do - skipIf "osx" =<< isOSX -- TODO: re-enable this once the macOS CI - -- issues are resolved, see discussion in #4902. + skipIf "osx" isOSX -- TODO: re-enable this once the macOS CI + -- issues are resolved, see discussion in #4902. hasShared <- hasSharedLibraries hasProfiled <- hasProfiledLibraries diff --git a/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-copy.test.hs b/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-copy.test.hs index 710878ce1f0..e05f52953f5 100644 --- a/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-copy.test.hs +++ b/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-copy.test.hs @@ -1,14 +1,8 @@ import Test.Cabal.Prelude -main = cabalTest $ withShorterPathForNewBuildStore $ do - storeDir <- testStoreDir <$> getTestEnv - let options = ["--installdir=" ++ storeDir] - -- Use install method copy that should surely work on Windows too but our - -- path normalization for testing is not good enough yet as can be seen in - -- this CI failure snippet diff: - -- -Warning: The directory /ghc-/incoming/new-/ghc-/-/bin is not in the system search path. - -- -Copying 'warn-early-overwrite' to '/warn-early-overwrite' - -- +Warning: The directory /incoming/new-2448/Users/RUNNER~1/AppData/Local/Temp/cabal-test-store-28260/ghc-/WarnEarlyOver_-0.1.0.0-4c19059e06a32b93b2812983631117e77a2d3833/bin is not in the system search path. - -- +Copying 'warn-early-overwrite' to '' - skipIfWindows - cabalG options "v2-install" ["--install-method=copy"] +main = do + skipIfWindows "#10180" + cabalTest $ withShorterPathForNewBuildStore $ do + storeDir <- testStoreDir <$> getTestEnv + let options = ["--installdir=" ++ storeDir] + cabalG options "v2-install" ["--install-method=copy"] diff --git a/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-symlink.test.hs b/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-symlink.test.hs index f4e6556b167..d25ecb0465e 100644 --- a/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-symlink.test.hs +++ b/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-symlink.test.hs @@ -1,8 +1,8 @@ import Test.Cabal.Prelude -main = cabalTest $ withShorterPathForNewBuildStore $ do - storeDir <- testStoreDir <$> getTestEnv - -- The default install method is symlink that may not work on Windows. - skipIfWindows - let options = ["--installdir=" ++ storeDir] - cabalG options "v2-install" [] +main = do + skipIfWindows "#10180" + cabalTest $ withShorterPathForNewBuildStore $ do + storeDir <- testStoreDir <$> getTestEnv + let options = ["--installdir=" ++ storeDir] + cabalG options "v2-install" [] diff --git a/cabal-testsuite/PackageTests/WarnEarlyOverwrite/dirty-install.test.hs b/cabal-testsuite/PackageTests/WarnEarlyOverwrite/dirty-install.test.hs index 8d2ae8e6cc5..232d526f983 100644 --- a/cabal-testsuite/PackageTests/WarnEarlyOverwrite/dirty-install.test.hs +++ b/cabal-testsuite/PackageTests/WarnEarlyOverwrite/dirty-install.test.hs @@ -2,14 +2,13 @@ import Test.Cabal.Prelude import System.FilePath -main = cabalTest $ withShorterPathForNewBuildStore $ do - - storeDir <- testStoreDir <$> getTestEnv - -- Windows does not natively include a touch command. - -- SEE: https://stackoverflow.com/questions/30011267/create-an-empty-file-on-the-commandline-in-windows-like-the-linux-touch-command - skipIfWindows - let options = ["--installdir=" ++ storeDir] - -- Touch the target to see if the warning is made early before the build. - _ <- runM "touch" [storeDir "warn-early-overwrite"] Nothing - fails $ cabalG options "v2-install" [] - cabalG options "v2-install" ["--overwrite-policy=always"] +main = do + skipIfWindows "#10180" + cabalTest $ withShorterPathForNewBuildStore $ do + storeDir <- testStoreDir <$> getTestEnv + let options = ["--installdir=" ++ storeDir] + -- Touch the target to see if the warning is made early before the build. + _ <- runM "touch" [ (if isWindows then (<.> "exe") else id) + $ storeDir "warn-early-overwrite" ] Nothing + fails $ cabalG options "v2-install" [] + cabalG options "v2-install" ["--overwrite-policy=always"] diff --git a/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs b/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs index d4747aceb92..65fddd48be5 100644 --- a/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs +++ b/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs @@ -1,7 +1,8 @@ import Test.Cabal.Prelude -main = cabalTest $ do - skipIfWindows +main = do + skipIfWindows "see #10182" + cabalTest $ do withProjectFile "cabal.positive.project" $ do cabal "v2-build" ["-v0"] withProjectFile "cabal.negative.project" $ do diff --git a/validate.sh b/validate.sh index edb1db83277..47705300a2d 100755 --- a/validate.sh +++ b/validate.sh @@ -329,7 +329,7 @@ CABALLISTBIN="${CABAL} list-bin --builddir=$BUILDDIR --project-file=$PROJECTFILE # of validate.sh # https://github.com/haskell/cabal/issues/9571 # https://github.com/haskell/cabal/pull/10114 -RTSOPTS="$([ $ARCH = "x86_64-windows" ] && [ -z "$CI" ] && echo "+RTS --io-manager=native" || echo "")" +RTSOPTS="$([ $ARCH = "x86_64-windows" ] && [ -z "$CI" ] && [ "$($HC --numeric-version)" != "8.10.7" ] && echo "+RTS --io-manager=native" || echo "")" # header ####################################################################### From bba83e63f04035fafba8ebb7700a13c014ebe0b9 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Tue, 16 Jul 2024 19:04:56 -0400 Subject: [PATCH 060/207] make cabal-install integration tests hermetic They were using the user's config, which is a problem if they don't have one or if it contains settings that interfere with tests (such as `documentation: True`). I'm not entirely certain of this, but it seems to work here. It's a bit of a hack, though. --- .gitignore | 1 + cabal-install/cabal-install.cabal | 1 + cabal-install/tests/IntegrationTests2.hs | 17 ++++++++++++++--- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 3450353924b..f2568f428f8 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ bootstrap/*.plan.json /cabal-install/dist/ /cabal-install/Setup /cabal-install/source-file-list +/cabal-install/tests/IntegrationTests2/config/cabal-config .stylish-haskell.yaml .stylish-haskell.yml diff --git a/cabal-install/cabal-install.cabal b/cabal-install/cabal-install.cabal index 5f20b3db947..9d307b4e1c6 100644 --- a/cabal-install/cabal-install.cabal +++ b/cabal-install/cabal-install.cabal @@ -399,6 +399,7 @@ test-suite integration-tests2 containers, directory, filepath, + process, tasty >= 1.2.3 && <1.6, tasty-hunit >= 0.10, tagged diff --git a/cabal-install/tests/IntegrationTests2.hs b/cabal-install/tests/IntegrationTests2.hs index c4341ed72ef..e6373cd18b8 100644 --- a/cabal-install/tests/IntegrationTests2.hs +++ b/cabal-install/tests/IntegrationTests2.hs @@ -74,7 +74,9 @@ import Control.Concurrent (threadDelay) import Control.Exception hiding (assert) import System.FilePath import System.Directory +import System.Environment (setEnv) import System.IO (hPutStrLn, stderr) +import System.Process (callProcess) import Test.Tasty import Test.Tasty.HUnit @@ -93,7 +95,16 @@ removePathForcibly = removeDirectoryRecursive #endif main :: IO () -main = +main = do + -- this is needed to ensure tests aren't affected by the user's cabal config + cwd <- getCurrentDirectory + let configDir = cwd basedir "config" "cabal-config" + setEnv "CABAL_DIR" configDir + removeDirectoryRecursive configDir <|> return () + createDirectoryIfMissing True configDir + -- sigh + callProcess "cabal" ["user-config", "init", "-f"] + callProcess "cabal" ["update"] defaultMainWithIngredients (defaultIngredients ++ [includingOptions projectConfigOptionDescriptions]) (withProjectConfig $ \config -> @@ -1971,8 +1982,8 @@ testNixFlags = do -- Tests whether config options are commented or not testConfigOptionComments :: Assertion testConfigOptionComments = do - _ <- createDefaultConfigFile verbosity [] (basedir "config/default-config") - defaultConfigFile <- readFile (basedir "config/default-config") + _ <- createDefaultConfigFile verbosity [] (basedir "config" "default-config") + defaultConfigFile <- readFile (basedir "config" "default-config") " url" @=? findLineWith False "url" defaultConfigFile " -- secure" @=? findLineWith True "secure" defaultConfigFile From 693bdb31e7bdcd2b0a6283e4c85bab6371eb5344 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Fri, 19 Jul 2024 00:31:23 +0200 Subject: [PATCH 061/207] Fix ForeignLibs test for Windows --- cabal-testsuite/PackageTests/ForeignLibs/MyForeignLib.def | 4 ++++ cabal-testsuite/PackageTests/ForeignLibs/my-foreign-lib.cabal | 3 ++- cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs | 3 +-- 3 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 cabal-testsuite/PackageTests/ForeignLibs/MyForeignLib.def diff --git a/cabal-testsuite/PackageTests/ForeignLibs/MyForeignLib.def b/cabal-testsuite/PackageTests/ForeignLibs/MyForeignLib.def new file mode 100644 index 00000000000..b9438c8d6a0 --- /dev/null +++ b/cabal-testsuite/PackageTests/ForeignLibs/MyForeignLib.def @@ -0,0 +1,4 @@ +EXPORTS + sayHi + myForeignLibExit + myForeignLibInit diff --git a/cabal-testsuite/PackageTests/ForeignLibs/my-foreign-lib.cabal b/cabal-testsuite/PackageTests/ForeignLibs/my-foreign-lib.cabal index 8b63dc24e9e..43a5a655567 100644 --- a/cabal-testsuite/PackageTests/ForeignLibs/my-foreign-lib.cabal +++ b/cabal-testsuite/PackageTests/ForeignLibs/my-foreign-lib.cabal @@ -16,7 +16,8 @@ foreign-library myforeignlib type: native-shared if os(windows) - options: standalone + options: standalone + mod-def-file: MyForeignLib.def other-modules: MyForeignLib.Hello MyForeignLib.SomeBindings diff --git a/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs b/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs index 73d02e90987..07a01cd0323 100644 --- a/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs +++ b/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs @@ -28,8 +28,7 @@ main = setupAndCabalTest . recordMode DoNotRecord $ do -- Foreign libraries don't work with GHC 7.6 and earlier skipUnlessGhcVersion ">= 7.8" ghc94 <- isGhcVersion ">= 9.4.1" - expectBrokenIf (isWindows && ghc94) 8451 $ - withPackageDb $ do + withPackageDb $ do setup_install [] setup "copy" [] -- regression test #4156 dist_dir <- fmap testDistDir getTestEnv From d68c4071d29fc776e72f4534a9355e22a0b32f31 Mon Sep 17 00:00:00 2001 From: Jaro Reinders Date: Fri, 19 Jul 2024 16:35:46 +0200 Subject: [PATCH 062/207] Fix write-ghc-environment-files documentation --- doc/cabal-project-description-file.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cabal-project-description-file.rst b/doc/cabal-project-description-file.rst index cf480875e7f..f024e540010 100644 --- a/doc/cabal-project-description-file.rst +++ b/doc/cabal-project-description-file.rst @@ -1694,7 +1694,7 @@ Advanced global configuration options should be created after a successful build. Since Cabal 3.0, defaults to ``never``. Before that, defaulted to - creating them only when compiling with GHC 8.4.4 and older (GHC + creating them only when compiling with GHC 8.4.4 and later (GHC 8.4.4 `is the first version `_ that supports the ``-package-env -`` option that allows ignoring the package From 6948203eaea1c362c1279f9247f9187dcfc60096 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Mon, 22 Jul 2024 23:39:17 +0200 Subject: [PATCH 063/207] Die if dynamic executable is requested on Windows --- Cabal/src/Distribution/Simple/Configure.hs | 17 ++++++++++++++++- Cabal/src/Distribution/Simple/Errors.hs | 7 ++++--- changelog.d/pr-10217 | 10 ++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 changelog.d/pr-10217 diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index cae6dd7d101..6c6610cb2be 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -1305,6 +1305,9 @@ configureComponents when (LBC.relocatable $ LBC.withBuildOptions lbc) $ checkRelocatable verbosity pkg_descr lbi + when (LBC.withDynExe $ LBC.withBuildOptions lbc) $ + checkSharedExes verbosity lbi + -- TODO: This is not entirely correct, because the dirs may vary -- across libraries/executables let dirs = absoluteInstallDirs pkg_descr lbi NoCopyDest @@ -2719,6 +2722,18 @@ checkPackageProblems verbosity dir gpkg pkg = do classEW (PackageDistSuspiciousWarn _) = Nothing classEW (PackageDistInexcusable _) = Nothing +-- | Perform checks if a shared executable can be built +checkSharedExes + :: Verbosity + -> LocalBuildInfo + -> IO () +checkSharedExes verbosity lbi = + when (os == Windows) $ + dieWithException verbosity $ + NoOSSupport os "shared executables" + where + (Platform _ os) = hostPlatform lbi + -- | Preform checks if a relocatable build is allowed checkRelocatable :: Verbosity @@ -2741,7 +2756,7 @@ checkRelocatable verbosity pkg lbi = checkOS = unless (os `elem` [OSX, Linux]) $ dieWithException verbosity $ - NoOSSupport os + NoOSSupport os "relocatable builds" where (Platform _ os) = hostPlatform lbi diff --git a/Cabal/src/Distribution/Simple/Errors.hs b/Cabal/src/Distribution/Simple/Errors.hs index 67f97a7f889..e39f63823a8 100644 --- a/Cabal/src/Distribution/Simple/Errors.hs +++ b/Cabal/src/Distribution/Simple/Errors.hs @@ -138,7 +138,7 @@ data CabalException | BadVersion String String PkgconfigVersion | UnknownCompilerException | NoWorkingGcc - | NoOSSupport OS + | NoOSSupport OS String | NoCompilerSupport String | InstallDirsNotPrefixRelative (InstallDirs FilePath) | ExplainErrors (Maybe (Either [Char] [Char])) [String] @@ -622,10 +622,11 @@ exceptionMessage e = case e of ++ "non-standard location you can use the --with-gcc " ++ "flag to specify it." ] - NoOSSupport os -> + NoOSSupport os what -> "Operating system: " ++ prettyShow os - ++ ", does not support relocatable builds" + ++ ", does not support " + ++ what NoCompilerSupport comp -> "Compiler: " ++ comp diff --git a/changelog.d/pr-10217 b/changelog.d/pr-10217 new file mode 100644 index 00000000000..8e520bab27e --- /dev/null +++ b/changelog.d/pr-10217 @@ -0,0 +1,10 @@ +synopsis: Do not try to build dynamic executables on Windows +packages: Cabal +prs: #10217 + +description: { + +- Cabal will now exit with a descriptive error message instead of attempting to + build a dynamic executable on Windows. + +} From 04c34088ab0d9832542df905de0ae35bbad329fd Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Mon, 22 Jul 2024 23:39:41 +0200 Subject: [PATCH 064/207] Add tests for unsupported builds on Windows --- .gitignore | 1 + .../PackageTests/NoOSSupport/DynExe/Main.hs | 4 ++++ .../PackageTests/NoOSSupport/DynExe/a.cabal | 8 ++++++++ .../PackageTests/NoOSSupport/DynExe/cabal.out | 12 ++++++++++++ .../PackageTests/NoOSSupport/DynExe/cabal.test.hs | 5 +++++ .../PackageTests/NoOSSupport/RelocatableExe/Main.hs | 4 ++++ .../PackageTests/NoOSSupport/RelocatableExe/a.cabal | 8 ++++++++ .../NoOSSupport/RelocatableExe/cabal.out | 10 ++++++++++ .../NoOSSupport/RelocatableExe/cabal.test.hs | 5 +++++ cabal-testsuite/src/Test/Cabal/Prelude.hs | 3 +++ 10 files changed, 60 insertions(+) create mode 100644 cabal-testsuite/PackageTests/NoOSSupport/DynExe/Main.hs create mode 100644 cabal-testsuite/PackageTests/NoOSSupport/DynExe/a.cabal create mode 100644 cabal-testsuite/PackageTests/NoOSSupport/DynExe/cabal.out create mode 100644 cabal-testsuite/PackageTests/NoOSSupport/DynExe/cabal.test.hs create mode 100644 cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/Main.hs create mode 100644 cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/a.cabal create mode 100644 cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/cabal.out create mode 100644 cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/cabal.test.hs diff --git a/.gitignore b/.gitignore index f2568f428f8..783d3862eec 100644 --- a/.gitignore +++ b/.gitignore @@ -69,6 +69,7 @@ register.sh # listed explicitly to show which files are generated but ignored testdb/intree/cabal.project-test testdb/intree/store/**/bin/alex +testdb/intree/store/**/bin/alex.exe testdb/intree/store/**/cabal-hash.txt testdb/intree/store/**/share/AlexTemplate.hs testdb/intree/store/**/share/AlexWrappers.hs diff --git a/cabal-testsuite/PackageTests/NoOSSupport/DynExe/Main.hs b/cabal-testsuite/PackageTests/NoOSSupport/DynExe/Main.hs new file mode 100644 index 00000000000..6f2b80aa9ed --- /dev/null +++ b/cabal-testsuite/PackageTests/NoOSSupport/DynExe/Main.hs @@ -0,0 +1,4 @@ +module Main where + +main :: IO () +main = pure () diff --git a/cabal-testsuite/PackageTests/NoOSSupport/DynExe/a.cabal b/cabal-testsuite/PackageTests/NoOSSupport/DynExe/a.cabal new file mode 100644 index 00000000000..58868453b6b --- /dev/null +++ b/cabal-testsuite/PackageTests/NoOSSupport/DynExe/a.cabal @@ -0,0 +1,8 @@ +cabal-version: 3.0 +name: aa +version: 0.1.0.0 +build-type: Simple + +executable a + default-language: Haskell2010 + main-is: Main.hs diff --git a/cabal-testsuite/PackageTests/NoOSSupport/DynExe/cabal.out b/cabal-testsuite/PackageTests/NoOSSupport/DynExe/cabal.out new file mode 100644 index 00000000000..53ccefe2347 --- /dev/null +++ b/cabal-testsuite/PackageTests/NoOSSupport/DynExe/cabal.out @@ -0,0 +1,12 @@ +# cabal build +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - aa-0.1.0.0 (exe:a) (first run) +Configuring executable 'a' for aa-0.1.0.0... +Warning: Executables will use dynamic linking, but a shared library is not +being built. Linking will fail if any executables depend on the library. +Error: [Cabal-3339] +Operating system: windows, does not support shared executables +Error: [Cabal-7125] +Failed to build aa-0.1.0.0-inplace-a. The failure occurred during the configure step. diff --git a/cabal-testsuite/PackageTests/NoOSSupport/DynExe/cabal.test.hs b/cabal-testsuite/PackageTests/NoOSSupport/DynExe/cabal.test.hs new file mode 100644 index 00000000000..aa0c8e83b7b --- /dev/null +++ b/cabal-testsuite/PackageTests/NoOSSupport/DynExe/cabal.test.hs @@ -0,0 +1,5 @@ +import Test.Cabal.Prelude + +main = do + skipUnlessWindows + cabalTest $ fails $ cabal "build" ["--enable-executable-dynamic", "--disable-shared"] diff --git a/cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/Main.hs b/cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/Main.hs new file mode 100644 index 00000000000..6f2b80aa9ed --- /dev/null +++ b/cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/Main.hs @@ -0,0 +1,4 @@ +module Main where + +main :: IO () +main = pure () diff --git a/cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/a.cabal b/cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/a.cabal new file mode 100644 index 00000000000..58868453b6b --- /dev/null +++ b/cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/a.cabal @@ -0,0 +1,8 @@ +cabal-version: 3.0 +name: aa +version: 0.1.0.0 +build-type: Simple + +executable a + default-language: Haskell2010 + main-is: Main.hs diff --git a/cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/cabal.out b/cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/cabal.out new file mode 100644 index 00000000000..f59d29e6b17 --- /dev/null +++ b/cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/cabal.out @@ -0,0 +1,10 @@ +# cabal build +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - aa-0.1.0.0 (exe:a) (first run) +Configuring executable 'a' for aa-0.1.0.0... +Error: [Cabal-3339] +Operating system: windows, does not support relocatable builds +Error: [Cabal-7125] +Failed to build aa-0.1.0.0-inplace-a. The failure occurred during the configure step. diff --git a/cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/cabal.test.hs b/cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/cabal.test.hs new file mode 100644 index 00000000000..448fc6fc22a --- /dev/null +++ b/cabal-testsuite/PackageTests/NoOSSupport/RelocatableExe/cabal.test.hs @@ -0,0 +1,5 @@ +import Test.Cabal.Prelude + +main = do + skipUnlessWindows + cabalTest $ fails $ cabal "build" ["--enable-relocatable"] diff --git a/cabal-testsuite/src/Test/Cabal/Prelude.hs b/cabal-testsuite/src/Test/Cabal/Prelude.hs index 80653c49f3a..c9a975e0fb7 100644 --- a/cabal-testsuite/src/Test/Cabal/Prelude.hs +++ b/cabal-testsuite/src/Test/Cabal/Prelude.hs @@ -937,6 +937,9 @@ isJavaScript = buildArch == JavaScript skipIfWindows :: String -> IO () skipIfWindows why = skipIfIO ("Windows " <> why) isWindows +skipUnlessWindows :: IO () +skipUnlessWindows = skipIfIO "Only interesting in Windows" (not isWindows) + getOpenFilesLimit :: TestM (Maybe Integer) #ifdef mingw32_HOST_OS -- No MS-specified limit, was determined experimentally on Windows 10 Pro x64, From f6946b95287ec2450c989a8a2f253987fa197d0e Mon Sep 17 00:00:00 2001 From: Nadia Yvette Chambers Date: Fri, 26 Jul 2024 07:58:51 -0400 Subject: [PATCH 065/207] rm-old-base: remove ifdefs for pre-4.13 bases (#10092) * rm-old-base: remove ifdefs for pre-4.13 bases 4.13 and older have fallen out of the support window. Hence this commit removes code only conditionally included for base 4.13 and older. Some occasional transitive removals were implied and done in this same commit. * Remove 8.6.5 from CI and Makefile * Remove test for GHC <8.6.5 * Update GHC versions mentioned in the user guide * rm-old-base: use Distribution.Compat.Prelude The change was likely an artifact of a rebase. * rm-old-base: restore builds not of cabal itself The #ifdefs being generated need to be kept here so that projects other than cabal can be built using older ghc versions and current cabal versions. * rm-old-base: restore older catchIO This needs to be included so running with older bases and ghcs can be done even while building cabal itself demands recent ghcs. * Bump base lower bounds to >=4.13 * Update a few package version in the documentation * rm-old-base: remove Distribution.Compat.Typeable It's not needed with our currently supported ghcs. * rm-old-base: restore T6906 --------- Co-authored-by: Andrea Bedini Co-authored-by: brandon s allbery kf8nh Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .github/workflows/validate.yml | 121 +++++++++--------- .../src/Test/QuickCheck/GenericArbitrary.hs | 4 - .../src/Test/QuickCheck/Instances/Cabal.hs | 16 +-- Cabal-hooks/Cabal-hooks.cabal | 2 +- Cabal-syntax/Cabal-syntax.cabal | 3 +- Cabal-syntax/src/Distribution/Compat/Graph.hs | 16 +-- .../src/Distribution/Compat/Newtype.hs | 17 +-- .../src/Distribution/Compat/NonEmptySet.hs | 7 +- .../src/Distribution/Compat/Prelude.hs | 13 +- .../src/Distribution/Compat/Typeable.hs | 19 --- .../src/Distribution/Fields/ParseResult.hs | 21 +-- Cabal-syntax/src/Distribution/Parsec.hs | 4 - Cabal-syntax/src/Distribution/System.hs | 4 - .../src/Distribution/Utils/Structured.hs | 2 +- Cabal-tests/Cabal-tests.cabal | 3 +- .../UnitTests/Distribution/Utils/CharSet.hs | 4 - .../Distribution/Utils/Structured.hs | 2 - Cabal-tests/tests/UnitTests/Orphans.hs | 10 -- Cabal-tests/tests/custom-setup/IdrisSetup.hs | 9 -- Cabal/Cabal.cabal | 3 +- Cabal/src/Distribution/Compat/Async.hs | 10 +- Cabal/src/Distribution/Compat/ResponseFile.hs | 54 +------- Cabal/src/Distribution/Compat/Stack.hs | 74 +---------- Cabal/src/Distribution/Compat/Time.hs | 10 -- Makefile | 6 - cabal-dev-scripts/cabal-dev-scripts.cabal | 4 +- .../cabal-install-solver.cabal | 4 +- cabal-install/cabal-install.cabal | 2 +- .../src/Distribution/Client/Compat/Orphans.hs | 2 +- .../src/Distribution/Client/FileMonitor.hs | 7 +- .../src/Distribution/Client/ProjectConfig.hs | 40 +----- .../Client/ProjectOrchestration.hs | 4 - .../src/Distribution/Client/Security/HTTP.hs | 5 - .../src/Distribution/Client/Store.hs | 2 - .../src/Distribution/Deprecated/ParseUtils.hs | 7 - .../src/Distribution/Deprecated/ReadP.hs | 12 -- .../Distribution/Client/ProjectConfig.hs | 4 - .../Distribution/Client/UserConfig.hs | 3 - .../Solver/Types/OptionalStanza.hs | 4 - cabal-testsuite/main/cabal-tests.hs | 6 - cabal-testsuite/src/Test/Cabal/TestCode.hs | 2 - cabal-testsuite/src/Test/Cabal/Workdir.hs | 3 +- doc/cabal-package-description-file.rst | 70 ++++------ 43 files changed, 127 insertions(+), 488 deletions(-) delete mode 100644 Cabal-syntax/src/Distribution/Compat/Typeable.hs delete mode 100644 Cabal-tests/tests/UnitTests/Orphans.hs diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 62b446b2293..a886214c01d 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -11,16 +11,16 @@ concurrency: on: push: paths-ignore: - - 'doc/**' - - '**/README.md' - - 'CONTRIBUTING.md' + - "doc/**" + - "**/README.md" + - "CONTRIBUTING.md" branches: - master pull_request: paths-ignore: - - 'doc/**' - - '**/README.md' - - 'CONTRIBUTING.md' + - "doc/**" + - "**/README.md" + - "CONTRIBUTING.md" release: types: - created @@ -41,17 +41,16 @@ on: env: # We choose a stable ghc version across all os's # which will be used to do the next release - GHC_FOR_RELEASE: '9.4.8' + GHC_FOR_RELEASE: "9.4.8" # Ideally we should use the version about to be released for hackage tests and benchmarks - GHC_FOR_SOLVER_BENCHMARKS: '9.4.8' - GHC_FOR_COMPLETE_HACKAGE_TESTS: '9.4.8' - COMMON_FLAGS: '-j 2 -v' + GHC_FOR_SOLVER_BENCHMARKS: "9.4.8" + GHC_FOR_COMPLETE_HACKAGE_TESTS: "9.4.8" + COMMON_FLAGS: "-j 2 -v" # See https://github.com/haskell/cabal/blob/master/CONTRIBUTING.md#hackage-revisions ALLOWNEWER: ${{ github.event.inputs.allow-newer }} CONSTRAINTS: ${{ github.event.inputs.constraints }} - jobs: validate: name: Validate ${{ matrix.sys.os }} ghc-${{ matrix.ghc }} @@ -61,28 +60,36 @@ jobs: strategy: matrix: sys: - - { os: windows-latest, shell: 'C:/msys64/usr/bin/bash.exe -e {0}' } - - { os: ubuntu-latest, shell: bash } - - { os: macos-13, shell: bash} + - { os: windows-latest, shell: "C:/msys64/usr/bin/bash.exe -e {0}" } + - { os: ubuntu-latest, shell: bash } + - { os: macos-13, shell: bash } # If you remove something from here, then add it to the old-ghcs job. # Also a removed GHC from here means that we are actually dropping # support, so the PR *must* have a changelog entry. - ghc: ['9.10.1', '9.8.2', '9.6.4', '9.4.8', '9.2.8', '9.0.2', '8.10.7', '8.8.4', '8.6.5'] + ghc: + [ + "9.10.1", + "9.8.2", + "9.6.4", + "9.4.8", + "9.2.8", + "9.0.2", + "8.10.7", + "8.8.4", + ] exclude: # corrupts GHA cache or the fabric of reality itself, see https://github.com/haskell/cabal/issues/8356 - - sys: { os: windows-latest, shell: 'C:/msys64/usr/bin/bash.exe -e {0}' } - ghc: '8.10.7' + - sys: + { os: windows-latest, shell: "C:/msys64/usr/bin/bash.exe -e {0}" } + ghc: "8.10.7" # lot of segfaults caused by ghc bugs - - sys: { os: windows-latest, shell: 'C:/msys64/usr/bin/bash.exe -e {0}' } - ghc: '8.8.4' - # it often randomly does "C:\Users\RUNNER~1\AppData\Local\Temp\ghcFEDE.c: DeleteFile "\\\\?\\C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\ghcFEDE.c": permission denied (Access is denied.)" - - sys: { os: windows-latest, shell: 'C:/msys64/usr/bin/bash.exe -e {0}' } - ghc: '8.6.5' + - sys: + { os: windows-latest, shell: "C:/msys64/usr/bin/bash.exe -e {0}" } + ghc: "8.8.4" defaults: - run: - shell: ${{ matrix.sys.shell }} + run: + shell: ${{ matrix.sys.shell }} steps: - - name: Work around XDG directories existence (haskell-actions/setup#62) if: runner.os == 'macOS' run: | @@ -213,7 +220,6 @@ jobs: if: matrix.ghc == env.GHC_FOR_SOLVER_BENCHMARKS run: sh validate.sh $FLAGS -s solver-benchmarks-run - validate-old-ghcs: name: Validate old ghcs ${{ matrix.extra-ghc }} runs-on: ubuntu-latest @@ -221,13 +227,13 @@ jobs: strategy: matrix: - extra-ghc: ['8.4.4', '8.2.2', '8.0.2'] + extra-ghc: + ["8.4.4", "8.2.2", "8.0.2"] ## GHC 7.10.3 does not install on ubuntu-22.04 with ghcup. ## Older GHCs are not supported by ghcup in the first place. fail-fast: false steps: - - uses: actions/checkout@v4 - name: Install prerequisites for old GHCs @@ -276,7 +282,7 @@ jobs: build-alpine: name: Build statically linked using alpine runs-on: ubuntu-latest - container: 'alpine:3.19' + container: "alpine:3.19" steps: - name: Install extra dependencies shell: sh @@ -336,7 +342,6 @@ jobs: name: cabal-${{ runner.os }}-static-x86_64 path: ${{ env.CABAL_EXEC_TAR }} - # The previous jobs use a released version of cabal to build cabal HEAD itself # This one uses the cabal HEAD generated executable in the previous step # to build itself again, as sanity check @@ -393,34 +398,34 @@ jobs: needs: [validate, validate-old-ghcs, build-alpine, dogfooding] steps: - - uses: actions/download-artifact@v3 - with: - name: cabal-Windows-x86_64 - - - uses: actions/download-artifact@v3 - with: - name: cabal-Linux-x86_64 - - - uses: actions/download-artifact@v3 - with: - name: cabal-Linux-static-x86_64 - - - uses: actions/download-artifact@v3 - with: - name: cabal-macOS-x86_64 - - - name: Create GitHub prerelease - uses: marvinpinto/action-automatic-releases@v1.2.1 - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - automatic_release_tag: cabal-head - prerelease: true - title: cabal-head - files: | - cabal-head-Windows-x86_64.tar.gz - cabal-head-Linux-x86_64.tar.gz - cabal-head-Linux-static-x86_64.tar.gz - cabal-head-macOS-x86_64.tar.gz + - uses: actions/download-artifact@v3 + with: + name: cabal-Windows-x86_64 + + - uses: actions/download-artifact@v3 + with: + name: cabal-Linux-x86_64 + + - uses: actions/download-artifact@v3 + with: + name: cabal-Linux-static-x86_64 + + - uses: actions/download-artifact@v3 + with: + name: cabal-macOS-x86_64 + + - name: Create GitHub prerelease + uses: marvinpinto/action-automatic-releases@v1.2.1 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + automatic_release_tag: cabal-head + prerelease: true + title: cabal-head + files: | + cabal-head-Windows-x86_64.tar.gz + cabal-head-Linux-x86_64.tar.gz + cabal-head-Linux-static-x86_64.tar.gz + cabal-head-macOS-x86_64.tar.gz # We use this job as a summary of the workflow # It will fail if any of the previous jobs does it diff --git a/Cabal-QuickCheck/src/Test/QuickCheck/GenericArbitrary.hs b/Cabal-QuickCheck/src/Test/QuickCheck/GenericArbitrary.hs index 00f32bc0d70..29f0b5d85e9 100644 --- a/Cabal-QuickCheck/src/Test/QuickCheck/GenericArbitrary.hs +++ b/Cabal-QuickCheck/src/Test/QuickCheck/GenericArbitrary.hs @@ -10,10 +10,6 @@ module Test.QuickCheck.GenericArbitrary ( import GHC.Generics import Test.QuickCheck -#if !MIN_VERSION_base(4,8,0) -import Control.Applicative (pure, (<$>), (<*>)) -#endif - -- Generic arbitrary for non-recursive types genericArbitrary :: (Generic a, GArbitrary (Rep a)) => Gen a genericArbitrary = fmap to garbitrary diff --git a/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs b/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs index e5b5077d414..8eabc450b03 100644 --- a/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs +++ b/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs @@ -6,19 +6,13 @@ module Test.QuickCheck.Instances.Cabal () where #if !MIN_VERSION_base(4,18,0) import Control.Applicative (liftA2) #endif -import Data.Bits (shiftR) +import Data.Bits (countLeadingZeros, finiteBitSize, shiftL, shiftR) import Data.Char (isAlphaNum, isDigit, toLower) import Data.List (intercalate, (\\)) import Data.List.NonEmpty (NonEmpty (..)) import Distribution.Utils.Generic (lowercase) import Test.QuickCheck -#if MIN_VERSION_base(4,8,0) -import Data.Bits (countLeadingZeros, finiteBitSize, shiftL) -#else -import Data.Bits (popCount) -#endif - import Distribution.CabalSpecVersion import Distribution.Compat.NonEmptySet (NonEmptySet) import Distribution.Compiler @@ -54,10 +48,6 @@ import Test.QuickCheck.GenericArbitrary import qualified Data.ByteString.Char8 as BS8 import qualified Distribution.Compat.NonEmptySet as NES -#if !MIN_VERSION_base(4,8,0) -import Control.Applicative (pure, (<$>), (<*>)) -#endif - ------------------------------------------------------------------------------- -- CabalSpecVersion ------------------------------------------------------------------------------- @@ -541,8 +531,4 @@ intSqrt n = case compare n 0 of iter x = shiftR (x + n `div` x) 1 guess :: Int -#if MIN_VERSION_base(4,8,0) guess = shiftR n (shiftL (finiteBitSize n - countLeadingZeros n) 1) -#else - guess = shiftR n (shiftR (popCount n) 1) -#endif diff --git a/Cabal-hooks/Cabal-hooks.cabal b/Cabal-hooks/Cabal-hooks.cabal index 367ef185610..db309369330 100644 --- a/Cabal-hooks/Cabal-hooks.cabal +++ b/Cabal-hooks/Cabal-hooks.cabal @@ -29,7 +29,7 @@ library build-depends: Cabal-syntax >= 3.13 && < 3.15, Cabal >= 3.13 && < 3.15, - base >= 4.11 && < 5, + base >= 4.13 && < 5, containers >= 0.5.0.0 && < 0.8, transformers >= 0.5.6.0 && < 0.7 diff --git a/Cabal-syntax/Cabal-syntax.cabal b/Cabal-syntax/Cabal-syntax.cabal index a1873228428..1bc8bcabeb2 100644 --- a/Cabal-syntax/Cabal-syntax.cabal +++ b/Cabal-syntax/Cabal-syntax.cabal @@ -29,7 +29,7 @@ library build-depends: array >= 0.4.0.1 && < 0.6, - base >= 4.11 && < 5, + base >= 4.13 && < 5, binary >= 0.7 && < 0.9, bytestring >= 0.10.0.0 && < 0.13, containers >= 0.5.0.0 && < 0.8, @@ -76,7 +76,6 @@ library Distribution.Compat.Parsing Distribution.Compat.Prelude Distribution.Compat.Semigroup - Distribution.Compat.Typeable Distribution.Compiler Distribution.FieldGrammar Distribution.FieldGrammar.Class diff --git a/Cabal-syntax/src/Distribution/Compat/Graph.hs b/Cabal-syntax/src/Distribution/Compat/Graph.hs index c01f3162b2d..1a6de3a571b 100644 --- a/Cabal-syntax/src/Distribution/Compat/Graph.hs +++ b/Cabal-syntax/src/Distribution/Compat/Graph.hs @@ -148,24 +148,20 @@ instance (Eq (Key a), Eq a) => Eq (Graph a) where g1 == g2 = graphMap g1 == graphMap g2 instance Foldable.Foldable Graph where + elem x = Foldable.elem x . graphMap fold = Foldable.fold . graphMap - foldr f z = Foldable.foldr f z . graphMap foldl f z = Foldable.foldl f z . graphMap - foldMap f = Foldable.foldMap f . graphMap foldl' f z = Foldable.foldl' f z . graphMap + foldr f z = Foldable.foldr f z . graphMap foldr' f z = Foldable.foldr' f z . graphMap -#ifdef MIN_VERSION_base -#if MIN_VERSION_base(4,8,0) + foldMap f = Foldable.foldMap f . graphMap length = Foldable.length . graphMap - null = Foldable.null . graphMap - toList = Foldable.toList . graphMap - elem x = Foldable.elem x . graphMap maximum = Foldable.maximum . graphMap minimum = Foldable.minimum . graphMap - sum = Foldable.sum . graphMap + null = Foldable.null . graphMap product = Foldable.product . graphMap -#endif -#endif + sum = Foldable.sum . graphMap + toList = Foldable.toList . graphMap instance (NFData a, NFData (Key a)) => NFData (Graph a) where rnf diff --git a/Cabal-syntax/src/Distribution/Compat/Newtype.hs b/Cabal-syntax/src/Distribution/Compat/Newtype.hs index 00da1e83542..56f55a9282b 100644 --- a/Cabal-syntax/src/Distribution/Compat/Newtype.hs +++ b/Cabal-syntax/src/Distribution/Compat/Newtype.hs @@ -14,15 +14,10 @@ module Distribution.Compat.Newtype , unpack' ) where +import Data.Coerce (Coercible, coerce) import Data.Functor.Identity (Identity (..)) import Data.Monoid (Endo (..), Product (..), Sum (..)) -#if MIN_VERSION_base(4,7,0) -import Data.Coerce (coerce, Coercible) -#else -import Unsafe.Coerce (unsafeCoerce) -#endif - -- | The @FunctionalDependencies@ version of 'Newtype' type-class. -- -- Since Cabal-3.0 class arguments are in a different order than in @newtype@ package. @@ -40,22 +35,12 @@ import Unsafe.Coerce (unsafeCoerce) {- FOURMOLU_DISABLE -} class Newtype o n | n -> o where pack :: o -> n -#if MIN_VERSION_base(4,7,0) default pack :: Coercible o n => o -> n pack = coerce -#else - default pack :: o -> n - pack = unsafeCoerce -#endif unpack :: n -> o -#if MIN_VERSION_base(4,7,0) default unpack :: Coercible n o => n -> o unpack = coerce -#else - default unpack :: n -> o - unpack = unsafeCoerce -#endif {- FOURMOLU_ENABLE -} instance Newtype a (Identity a) diff --git a/Cabal-syntax/src/Distribution/Compat/NonEmptySet.hs b/Cabal-syntax/src/Distribution/Compat/NonEmptySet.hs index 034da7ee90c..17e3811e9a4 100644 --- a/Cabal-syntax/src/Distribution/Compat/NonEmptySet.hs +++ b/Cabal-syntax/src/Distribution/Compat/NonEmptySet.hs @@ -87,12 +87,9 @@ instance Ord a => Semigroup (NonEmptySet a) where instance F.Foldable NonEmptySet where foldMap f (NES s) = F.foldMap f s foldr f z (NES s) = F.foldr f z s - -#if MIN_VERSION_base(4,8,0) - toList = toList - null _ = False + toList = toList + null _ = False length (NES s) = F.length s -#endif ------------------------------------------------------------------------------- -- Constructors diff --git a/Cabal-syntax/src/Distribution/Compat/Prelude.hs b/Cabal-syntax/src/Distribution/Compat/Prelude.hs index 3cbf3c17a8a..2d6f92b5da6 100644 --- a/Cabal-syntax/src/Distribution/Compat/Prelude.hs +++ b/Cabal-syntax/src/Distribution/Compat/Prelude.hs @@ -4,14 +4,6 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE TypeOperators #-} -{- FOURMOLU_DISABLE -} -#ifdef MIN_VERSION_base -#define MINVER_base_411 MIN_VERSION_base(4,11,0) -#else -#define MINVER_base_411 (__GLASGOW_HASKELL__ >= 804) -#endif -{- FOURMOLU_ENABLE -} - -- | This module does two things: -- -- * Acts as a compatibility layer, like @base-compat@. @@ -194,11 +186,10 @@ import Prelude as BasePrelude hiding ( mapM, mapM_, sequence, any, all, head, tail, last, init -- partial functions , read -#if MINVER_base_411 + , foldr1, foldl1 -- As of base 4.11.0.0 Prelude exports part of Semigroup(..). -- Hide this so we instead rely on Distribution.Compat.Semigroup. , Semigroup(..) -#endif , Word -- We hide them, as we import only some members , Traversable, traverse, sequenceA @@ -243,11 +234,11 @@ import Data.Ord (comparing) import Data.Proxy (Proxy (..)) import Data.Set (Set) import Data.String (IsString (..)) +import Data.Typeable (TypeRep, Typeable, typeRep) import Data.Void (Void, absurd, vacuous) import Data.Word (Word, Word16, Word32, Word64, Word8) import Distribution.Compat.Binary (Binary (..)) import Distribution.Compat.Semigroup (Semigroup (..), gmappend, gmempty) -import Distribution.Compat.Typeable (TypeRep, Typeable, typeRep) import GHC.Generics (Generic (..), K1 (unK1), M1 (unM1), U1 (U1), V1, (:*:) ((:*:)), (:+:) (L1, R1)) import System.Exit (ExitCode (..), exitFailure, exitSuccess, exitWith) import Text.Read (readMaybe) diff --git a/Cabal-syntax/src/Distribution/Compat/Typeable.hs b/Cabal-syntax/src/Distribution/Compat/Typeable.hs deleted file mode 100644 index 161f868a823..00000000000 --- a/Cabal-syntax/src/Distribution/Compat/Typeable.hs +++ /dev/null @@ -1,19 +0,0 @@ -{-# LANGUAGE CPP #-} -{-# LANGUAGE ScopedTypeVariables #-} - -module Distribution.Compat.Typeable - ( Typeable - , TypeRep - , typeRep - ) where - -#if MIN_VERSION_base(4,7,0) -import Data.Typeable (Typeable, TypeRep, typeRep) -#else -import Data.Typeable (Typeable, TypeRep, typeOf) -#endif - -#if !MIN_VERSION_base(4,7,0) -typeRep :: forall a proxy. Typeable a => proxy a -> TypeRep -typeRep _ = typeOf (undefined :: a) -#endif diff --git a/Cabal-syntax/src/Distribution/Fields/ParseResult.hs b/Cabal-syntax/src/Distribution/Fields/ParseResult.hs index 7174aaa99bf..aad7de2737a 100644 --- a/Cabal-syntax/src/Distribution/Fields/ParseResult.hs +++ b/Cabal-syntax/src/Distribution/Fields/ParseResult.hs @@ -18,22 +18,11 @@ module Distribution.Fields.ParseResult , withoutWarnings ) where +import Distribution.Compat.Prelude import Distribution.Parsec.Error (PError (..)) import Distribution.Parsec.Position (Position (..), zeroPos) import Distribution.Parsec.Warning (PWarnType (..), PWarning (..)) import Distribution.Version (Version) -import Prelude () - --- liftA2 is not in base <4.10, hence we need to only import it explicitly when we're on >=4.10 --- --- Additionally, since liftA2 will be exported from Prelude starting with ~4.18, we should hide --- it from Prelude and get it from Control.Applicative to be backwards compatible and avoid warnings -#if MIN_VERSION_base(4,10,0) -import Distribution.Compat.Prelude hiding (Applicative(..)) -import Control.Applicative (Applicative (..)) -#else -import Distribution.Compat.Prelude -#endif -- | A monad with failure and accumulating errors and warnings. newtype ParseResult a = PR @@ -100,14 +89,6 @@ instance Applicative ParseResult where success s2 x' {-# INLINE (<*) #-} -#if MIN_VERSION_base(4,10,0) - liftA2 f x y = PR $ \ !s0 failure success -> - unPR x s0 failure $ \ !s1 x' -> - unPR y s1 failure $ \ !s2 y' -> - success s2 (f x' y') - {-# INLINE liftA2 #-} -#endif - instance Monad ParseResult where return = pure (>>) = (*>) diff --git a/Cabal-syntax/src/Distribution/Parsec.hs b/Cabal-syntax/src/Distribution/Parsec.hs index 4c6e31e5aaa..3bf62597222 100644 --- a/Cabal-syntax/src/Distribution/Parsec.hs +++ b/Cabal-syntax/src/Distribution/Parsec.hs @@ -145,10 +145,6 @@ instance Monad ParsecParser where (>>) = (*>) {-# INLINE (>>) #-} -#if !(MIN_VERSION_base(4,13,0)) - fail = Fail.fail -#endif - instance MonadPlus ParsecParser where mzero = empty mplus = (<|>) diff --git a/Cabal-syntax/src/Distribution/System.hs b/Cabal-syntax/src/Distribution/System.hs index e1e75aa2315..1bf6d598d03 100644 --- a/Cabal-syntax/src/Distribution/System.hs +++ b/Cabal-syntax/src/Distribution/System.hs @@ -46,10 +46,6 @@ import Control.Applicative (Applicative (..)) import Distribution.Compat.Prelude hiding (Applicative (..)) import Prelude () -#if !MIN_VERSION_base(4,10,0) -import Control.Applicative (liftA2) -#endif - import Distribution.Utils.Generic (lowercase) import qualified System.Info (arch, os) diff --git a/Cabal-syntax/src/Distribution/Utils/Structured.hs b/Cabal-syntax/src/Distribution/Utils/Structured.hs index ba10212bca1..3a21d47a0dd 100644 --- a/Cabal-syntax/src/Distribution/Utils/Structured.hs +++ b/Cabal-syntax/src/Distribution/Utils/Structured.hs @@ -106,8 +106,8 @@ import qualified Data.Aeson as Aeson #endif import Data.Kind (Type) +import Data.Typeable (TypeRep, Typeable, typeRep) -import Distribution.Compat.Typeable (TypeRep, Typeable, typeRep) import Distribution.Utils.MD5 import Data.Monoid (mconcat) diff --git a/Cabal-tests/Cabal-tests.cabal b/Cabal-tests/Cabal-tests.cabal index dd443d1fc21..52647f8a6b4 100644 --- a/Cabal-tests/Cabal-tests.cabal +++ b/Cabal-tests/Cabal-tests.cabal @@ -52,12 +52,11 @@ test-suite unit-tests UnitTests.Distribution.Utils.ShortText UnitTests.Distribution.Utils.Structured UnitTests.Distribution.Version - UnitTests.Orphans main-is: UnitTests.hs build-depends: array - , base >=4.11 && <5 + , base >=4.13 && <5 , bytestring , Cabal , Cabal-described diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/CharSet.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/CharSet.hs index c2180b630b7..a7d629ccb08 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/CharSet.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/CharSet.hs @@ -1,8 +1,4 @@ {-# LANGUAGE CPP #-} --- isAlpha and isAlphaNum definitions change from base to base -#if MIN_VERSION_base(4,12,0) && !MIN_VERSION_base(4,13,0) -#define HAS_TESTS -#endif module UnitTests.Distribution.Utils.CharSet where import Prelude hiding (Foldable(..)) diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs index 63841cba729..0db6844928a 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs @@ -13,8 +13,6 @@ import Distribution.Types.VersionRange (VersionRange) import Distribution.Types.GenericPackageDescription (GenericPackageDescription) import Distribution.Types.LocalBuildInfo (LocalBuildInfo) -import UnitTests.Orphans () - tests :: TestTree tests = testGroup "Distribution.Utils.Structured" -- This test also verifies that structureHash doesn't loop. diff --git a/Cabal-tests/tests/UnitTests/Orphans.hs b/Cabal-tests/tests/UnitTests/Orphans.hs deleted file mode 100644 index d6b49a91929..00000000000 --- a/Cabal-tests/tests/UnitTests/Orphans.hs +++ /dev/null @@ -1,10 +0,0 @@ -{-# LANGUAGE CPP #-} -{-# LANGUAGE StandaloneDeriving #-} -{-# OPTIONS_GHC -fno-warn-orphans #-} -module UnitTests.Orphans where - -#if !MIN_VERSION_base(4,7,0) -import GHC.Fingerprint (Fingerprint (..)) - -deriving instance Show Fingerprint -#endif diff --git a/Cabal-tests/tests/custom-setup/IdrisSetup.hs b/Cabal-tests/tests/custom-setup/IdrisSetup.hs index 952be052961..339f9fd9c38 100644 --- a/Cabal-tests/tests/custom-setup/IdrisSetup.hs +++ b/Cabal-tests/tests/custom-setup/IdrisSetup.hs @@ -45,10 +45,6 @@ module IdrisSetup (main) where # define MIN_VERSION_Cabal(x,y,z) 0 #endif -#if !defined(MIN_VERSION_base) -# define MIN_VERSION_base(x,y,z) 0 -#endif - import Control.Monad import Data.IORef import Control.Exception (SomeException, catch) @@ -85,11 +81,6 @@ configConfigurationsFlags = unFlagAssignment . S.configConfigurationsFlags configConfigurationsFlags = S.configConfigurationsFlags #endif -#if !MIN_VERSION_base(4,6,0) -lookupEnv :: String -> IO (Maybe String) -lookupEnv v = lookup v `fmap` getEnvironment -#endif - -- After Idris is built, we need to check and install the prelude and other libs -- ----------------------------------------------------------------------------- diff --git a/Cabal/Cabal.cabal b/Cabal/Cabal.cabal index deaad72cef1..14e7050c5db 100644 --- a/Cabal/Cabal.cabal +++ b/Cabal/Cabal.cabal @@ -36,7 +36,7 @@ library build-depends: Cabal-syntax ^>= 3.13, array >= 0.4.0.1 && < 0.6, - base >= 4.11 && < 5, + base >= 4.13 && < 5, bytestring >= 0.10.0.0 && < 0.13, containers >= 0.5.0.0 && < 0.8, deepseq >= 1.3.0.1 && < 1.6, @@ -189,7 +189,6 @@ library Distribution.Compat.Parsing, Distribution.Compat.Prelude, Distribution.Compat.Semigroup, - Distribution.Compat.Typeable, Distribution.Compiler, Distribution.FieldGrammar, Distribution.FieldGrammar.Class, diff --git a/Cabal/src/Distribution/Compat/Async.hs b/Cabal/src/Distribution/Compat/Async.hs index dbc22c58359..b1234c8e346 100644 --- a/Cabal/src/Distribution/Compat/Async.hs +++ b/Cabal/src/Distribution/Compat/Async.hs @@ -29,6 +29,8 @@ import Control.Exception ( BlockedIndefinitelyOnMVar (..) , Exception (..) , SomeException (..) + , asyncExceptionFromException + , asyncExceptionToException , catch , evaluate , mask @@ -41,10 +43,6 @@ import Control.Monad (void) import Data.Typeable (Typeable) import GHC.Exts (inline) -#if MIN_VERSION_base(4,7,0) -import Control.Exception (asyncExceptionFromException, asyncExceptionToException) -#endif - -- | Async, but based on 'MVar', as we don't depend on @stm@. data AsyncM a = Async { asyncThreadId :: {-# UNPACK #-} !ThreadId @@ -148,15 +146,11 @@ data AsyncCancelled = AsyncCancelled , Typeable ) -{- FOURMOLU_DISABLE -} instance Exception AsyncCancelled where -#if MIN_VERSION_base(4,7,0) -- wraps in SomeAsyncException -- See https://github.com/ghc/ghc/commit/756a970eacbb6a19230ee3ba57e24999e4157b09 fromException = asyncExceptionFromException toException = asyncExceptionToException -#endif -{- FOURMOLU_ENABLE -} -- | Cancel an asynchronous action -- diff --git a/Cabal/src/Distribution/Compat/ResponseFile.hs b/Cabal/src/Distribution/Compat/ResponseFile.hs index 189a423bd08..8619ae56962 100644 --- a/Cabal/src/Distribution/Compat/ResponseFile.hs +++ b/Cabal/src/Distribution/Compat/ResponseFile.hs @@ -8,63 +8,15 @@ module Distribution.Compat.ResponseFile (expandResponse, escapeArgs) where import Distribution.Compat.Prelude + +import GHC.ResponseFile (escapeArgs, unescapeArgs) + import Prelude () import System.FilePath import System.IO (hPutStrLn, stderr) import System.IO.Error -#if MIN_VERSION_base(4,12,0) -import GHC.ResponseFile (unescapeArgs, escapeArgs) -#else - -unescapeArgs :: String -> [String] -unescapeArgs = filter (not . null) . unescape - -data Quoting = NoneQ | SngQ | DblQ - -unescape :: String -> [String] -unescape args = reverse . map reverse $ go args NoneQ False [] [] - where - -- n.b., the order of these cases matters; these are cribbed from gcc - -- case 1: end of input - go [] _q _bs a as = a:as - -- case 2: back-slash escape in progress - go (c:cs) q True a as = go cs q False (c:a) as - -- case 3: no back-slash escape in progress, but got a back-slash - go (c:cs) q False a as - | '\\' == c = go cs q True a as - -- case 4: single-quote escaping in progress - go (c:cs) SngQ False a as - | '\'' == c = go cs NoneQ False a as - | otherwise = go cs SngQ False (c:a) as - -- case 5: double-quote escaping in progress - go (c:cs) DblQ False a as - | '"' == c = go cs NoneQ False a as - | otherwise = go cs DblQ False (c:a) as - -- case 6: no escaping is in progress - go (c:cs) NoneQ False a as - | isSpace c = go cs NoneQ False [] (a:as) - | '\'' == c = go cs SngQ False a as - | '"' == c = go cs DblQ False a as - | otherwise = go cs NoneQ False (c:a) as - -escapeArgs :: [String] -> String -escapeArgs = unlines . map escapeArg - -escapeArg :: String -> String -escapeArg = reverse . foldl' escape [] - -escape :: String -> Char -> String -escape cs c - | isSpace c - || '\\' == c - || '\'' == c - || '"' == c = c:'\\':cs -- n.b., our caller must reverse the result - | otherwise = c:cs - -#endif - -- | The arg file / response file parser. -- -- This is not a well-documented capability, and is a bit eccentric diff --git a/Cabal/src/Distribution/Compat/Stack.hs b/Cabal/src/Distribution/Compat/Stack.hs index 41d4ff8b460..616a66d090d 100644 --- a/Cabal/src/Distribution/Compat/Stack.hs +++ b/Cabal/src/Distribution/Compat/Stack.hs @@ -13,91 +13,31 @@ module Distribution.Compat.Stack , parentSrcLocPrefix ) where -import System.IO.Error - -#ifdef MIN_VERSION_base -#if MIN_VERSION_base(4,8,1) -#define GHC_STACK_SUPPORTED 1 -#endif -#endif - -#ifdef GHC_STACK_SUPPORTED import GHC.Stack -#endif - -#ifdef GHC_STACK_SUPPORTED +import System.IO.Error -#if MIN_VERSION_base(4,9,0) type WithCallStack a = HasCallStack => a -#elif MIN_VERSION_base(4,8,1) -type WithCallStack a = (?callStack :: CallStack) => a -#endif - -#if !MIN_VERSION_base(4,9,0) --- NB: Can't say WithCallStack (WithCallStack a -> a); --- Haskell doesn't support this kind of implicit parameter! --- See https://mail.haskell.org/pipermail/ghc-devs/2016-January/011096.html --- Since this function doesn't do anything, it's OK to --- give it a less good type. -withFrozenCallStack :: WithCallStack (a -> a) -withFrozenCallStack x = x - -callStack :: (?callStack :: CallStack) => CallStack -callStack = ?callStack - -prettyCallStack :: CallStack -> String -prettyCallStack = showCallStack -#endif -- | Give the *parent* of the person who invoked this; -- so it's most suitable for being called from a utility function. -- You probably want to call this using 'withFrozenCallStack'; otherwise -- it's not very useful. We didn't implement this for base-4.8.1 -- because we cannot rely on freezing to have taken place. --- parentSrcLocPrefix :: WithCallStack String -#if MIN_VERSION_base(4,9,0) parentSrcLocPrefix = case getCallStack callStack of - (_:(_, loc):_) -> showLoc loc + (_ : (_, loc) : _) -> showLoc loc [(_, loc)] -> showLoc loc [] -> error "parentSrcLocPrefix: empty call stack" - where - showLoc loc = - srcLocFile loc ++ ":" ++ show (srcLocStartLine loc) ++ ": " -#else -parentSrcLocPrefix = "Call sites not available with base < 4.9.0.0 (GHC 8.0): " -#endif + where + showLoc loc = + srcLocFile loc ++ ":" ++ show (srcLocStartLine loc) ++ ": " -- Yeah, this uses skivvy implementation details. withLexicalCallStack :: (a -> WithCallStack (IO b)) -> WithCallStack (a -> IO b) withLexicalCallStack f = - let stk = ?callStack - in \x -> let ?callStack = stk in f x - -#else - -data CallStack = CallStack - deriving (Eq, Show) - -type WithCallStack a = a - -withFrozenCallStack :: a -> a -withFrozenCallStack x = x - -callStack :: CallStack -callStack = CallStack - -prettyCallStack :: CallStack -> String -prettyCallStack _ = "Call stacks not available with base < 4.8.1.0 (GHC 7.10)" - -parentSrcLocPrefix :: String -parentSrcLocPrefix = "Call sites not available with base < 4.9.0.0 (GHC 8.0): " - -withLexicalCallStack :: (a -> IO b) -> a -> IO b -withLexicalCallStack f = f - -#endif + let stk = ?callStack + in \x -> let ?callStack = stk in f x -- | This function is for when you *really* want to add a call -- stack to raised IO, but you don't have a diff --git a/Cabal/src/Distribution/Compat/Time.hs b/Cabal/src/Distribution/Compat/Time.hs index 9af0500fae1..03d57449eb4 100644 --- a/Cabal/src/Distribution/Compat/Time.hs +++ b/Cabal/src/Distribution/Compat/Time.hs @@ -34,11 +34,7 @@ import Data.Time.Clock.POSIX (POSIXTime, getPOSIXTime, posixDayLength) import qualified Prelude import Data.Bits ((.|.), unsafeShiftL) -#if MIN_VERSION_base(4,7,0) import Data.Bits (finiteBitSize) -#else -import Data.Bits (bitSize) -#endif import Foreign ( allocaBytes, peekByteOff ) import System.IO.Error ( mkIOError, doesNotExistErrorType ) @@ -92,15 +88,9 @@ getModTime path = allocaBytes size_WIN32_FILE_ATTRIBUTE_DATA $ \info -> do index_WIN32_FILE_ATTRIBUTE_DATA_ftLastWriteTime_dwLowDateTime dwHigh <- peekByteOff info index_WIN32_FILE_ATTRIBUTE_DATA_ftLastWriteTime_dwHighDateTime -#if MIN_VERSION_base(4,7,0) let qwTime = (fromIntegral (dwHigh :: DWORD) `unsafeShiftL` finiteBitSize dwHigh) .|. (fromIntegral (dwLow :: DWORD)) -#else - let qwTime = - (fromIntegral (dwHigh :: DWORD) `unsafeShiftL` bitSize dwHigh) - .|. (fromIntegral (dwLow :: DWORD)) -#endif return $! ModTime (qwTime :: Word64) {- FOURMOLU_DISABLE -} diff --git a/Makefile b/Makefile index d305ca16353..447f3a88fe2 100644 --- a/Makefile +++ b/Makefile @@ -178,14 +178,12 @@ cabal-install-test-accept: .PHONY: validate-via-docker-all validate-via-docker-all : validate-via-docker-8.2.2 validate-via-docker-all : validate-via-docker-8.4.4 -validate-via-docker-all : validate-via-docker-8.6.5 validate-via-docker-all : validate-via-docker-8.8.4 validate-via-docker-all : validate-via-docker-8.10.4 .PHONY: validate-dockerfiles validate-dockerfiles : .docker/validate-8.10.4.dockerfile validate-dockerfiles : .docker/validate-8.8.4.dockerfile -validate-dockerfiles : .docker/validate-8.6.5.dockerfile validate-dockerfiles : .docker/validate-8.4.4.dockerfile validate-dockerfiles : .docker/validate-8.2.2.dockerfile @@ -204,10 +202,6 @@ validate-via-docker-8.2.2: validate-via-docker-8.4.4: docker build $(DOCKERARGS) -t cabal-validate:8.4.4 -f .docker/validate-8.4.4.dockerfile . -.PHONY: validate-via-docker-8.6.5 -validate-via-docker-8.6.5: - docker build $(DOCKERARGS) -t cabal-validate:8.6.5 -f .docker/validate-8.6.5.dockerfile . - .PHONY: validate-via-docker-8.8.4 validate-via-docker-8.8.4: docker build $(DOCKERARGS) -t cabal-validate:8.8.4 -f .docker/validate-8.8.4.dockerfile . diff --git a/cabal-dev-scripts/cabal-dev-scripts.cabal b/cabal-dev-scripts/cabal-dev-scripts.cabal index 399888dfb8d..5ae899febe1 100644 --- a/cabal-dev-scripts/cabal-dev-scripts.cabal +++ b/cabal-dev-scripts/cabal-dev-scripts.cabal @@ -18,7 +18,7 @@ executable gen-spdx ghc-options: -Wall build-depends: , aeson ^>=1.4.1.0 || ^>=1.5.2.0 || ^>=2.2.1.0 - , base >=4.11 && <4.20 + , base >=4.13 && <4.20 , bytestring , containers , Diff ^>=0.4 @@ -35,7 +35,7 @@ executable gen-spdx-exc ghc-options: -Wall build-depends: , aeson ^>=1.4.1.0 || ^>=1.5.2.0 || ^>=2.2.1.0 - , base >=4.11 && <4.20 + , base >=4.13 && <4.20 , bytestring , containers , Diff ^>=0.4 diff --git a/cabal-install-solver/cabal-install-solver.cabal b/cabal-install-solver/cabal-install-solver.cabal index b2b2b12b7af..4bc75a32569 100644 --- a/cabal-install-solver/cabal-install-solver.cabal +++ b/cabal-install-solver/cabal-install-solver.cabal @@ -99,7 +99,7 @@ library build-depends: , array >=0.4 && <0.6 - , base >=4.11 && <4.21 + , base >=4.13 && <4.21 , bytestring >=0.10.6.0 && <0.13 , Cabal ^>=3.13 , Cabal-syntax ^>=3.13 @@ -131,7 +131,7 @@ Test-Suite unit-tests UnitTests.Distribution.Solver.Modular.MessageUtils build-depends: - , base >= 4.11 && <4.21 + , base >= 4.13 && <4.21 , Cabal-syntax , cabal-install-solver , tasty >= 1.2.3 && <1.6 diff --git a/cabal-install/cabal-install.cabal b/cabal-install/cabal-install.cabal index 9d307b4e1c6..115b9457d4b 100644 --- a/cabal-install/cabal-install.cabal +++ b/cabal-install/cabal-install.cabal @@ -52,7 +52,7 @@ common warnings ghc-options: -Wnoncanonical-monadfail-instances common base-dep - build-depends: base >=4.11 && <4.21 + build-depends: base >=4.13 && <4.21 common cabal-dep build-depends: Cabal ^>=3.13 diff --git a/cabal-install/src/Distribution/Client/Compat/Orphans.hs b/cabal-install/src/Distribution/Client/Compat/Orphans.hs index 4a2e28a10fb..bbc44bb5c8a 100644 --- a/cabal-install/src/Distribution/Client/Compat/Orphans.hs +++ b/cabal-install/src/Distribution/Client/Compat/Orphans.hs @@ -4,8 +4,8 @@ module Distribution.Client.Compat.Orphans () where import Control.Exception (SomeException) +import Data.Typeable (typeRep) import Distribution.Compat.Binary (Binary (..)) -import Distribution.Compat.Typeable (typeRep) import Distribution.Utils.Structured (Structure (Nominal), Structured (..)) import Network.URI (URI (..), URIAuth (..)) import Prelude (error, return) diff --git a/cabal-install/src/Distribution/Client/FileMonitor.hs b/cabal-install/src/Distribution/Client/FileMonitor.hs index 59742cc1b80..0872a9a9504 100644 --- a/cabal-install/src/Distribution/Client/FileMonitor.hs +++ b/cabal-install/src/Distribution/Client/FileMonitor.hs @@ -1127,12 +1127,9 @@ checkDirectoryModificationTime dir mtime = -- | Run an IO computation, returning the first argument @e@ if there is an 'error' -- call. ('ErrorCall') handleErrorCall :: a -> IO a -> IO a -handleErrorCall e = handle handler where -#if MIN_VERSION_base(4,9,0) +handleErrorCall e = handle handler + where handler (ErrorCallWithLocation _ _) = return e -#else - handler (ErrorCall _) = return e -#endif -- | Run an IO computation, returning @e@ if there is any 'IOException'. -- diff --git a/cabal-install/src/Distribution/Client/ProjectConfig.hs b/cabal-install/src/Distribution/Client/ProjectConfig.hs index cec000b6a9b..06f4e4e555d 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig.hs @@ -610,21 +610,10 @@ data BadProjectRoot | BadProjectRootDir FilePath | BadProjectRootAbsoluteFile FilePath | BadProjectRootDirFile FilePath FilePath -#if MIN_VERSION_base(4,8,0) deriving (Show, Typeable) -#else - deriving (Typeable) - -instance Show BadProjectRoot where - show = renderBadProjectRoot -#endif -#if MIN_VERSION_base(4,8,0) instance Exception BadProjectRoot where displayException = renderBadProjectRoot -#else -instance Exception BadProjectRoot -#endif renderBadProjectRoot :: BadProjectRoot -> String renderBadProjectRoot = \case @@ -844,21 +833,11 @@ data ProjectPackageLocation -- | Exception thrown by 'findProjectPackages'. data BadPackageLocations = BadPackageLocations (Set ProjectConfigProvenance) [BadPackageLocation] -#if MIN_VERSION_base(4,8,0) deriving (Show, Typeable) -#else - deriving (Typeable) -instance Show BadPackageLocations where - show = renderBadPackageLocations -#endif - -#if MIN_VERSION_base(4,8,0) instance Exception BadPackageLocations where displayException = renderBadPackageLocations -#else -instance Exception BadPackageLocations -#endif + -- TODO: [nice to have] custom exception subclass for Doc rendering, colour etc data BadPackageLocation @@ -1530,11 +1509,8 @@ instance Show CabalFileParseError where . showChar ' ' . showsPrec 11 ws -instance Exception CabalFileParseError -#if MIN_VERSION_base(4,8,0) - where +instance Exception CabalFileParseError where displayException = renderCabalFileParseError -#endif renderCabalFileParseError :: CabalFileParseError -> String renderCabalFileParseError (CabalFileParseError filePath contents errors _ warnings) = @@ -1676,21 +1652,11 @@ truncateString n s data BadPerPackageCompilerPaths = BadPerPackageCompilerPaths [(PackageName, String)] -#if MIN_VERSION_base(4,8,0) deriving (Show, Typeable) -#else - deriving (Typeable) -instance Show BadPerPackageCompilerPaths where - show = renderBadPerPackageCompilerPaths -#endif - -#if MIN_VERSION_base(4,8,0) instance Exception BadPerPackageCompilerPaths where displayException = renderBadPerPackageCompilerPaths -#else -instance Exception BadPerPackageCompilerPaths -#endif + -- TODO: [nice to have] custom exception subclass for Doc rendering, colour etc renderBadPerPackageCompilerPaths :: BadPerPackageCompilerPaths -> String diff --git a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs index 7f26ac12382..8fb0ca8e65f 100644 --- a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs +++ b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs @@ -1412,11 +1412,7 @@ dieOnBuildFailures verbosity currentCommand plan buildOutcomes " The build process terminated with exit code " ++ show n _ -> " The exception was:\n " -#if MIN_VERSION_base(4,8,0) ++ displayException e -#else - ++ show e -#endif buildFailureException :: BuildFailureReason -> Maybe SomeException buildFailureException reason = diff --git a/cabal-install/src/Distribution/Client/Security/HTTP.hs b/cabal-install/src/Distribution/Client/Security/HTTP.hs index f433c61ab21..941d0b28dab 100644 --- a/cabal-install/src/Distribution/Client/Security/HTTP.hs +++ b/cabal-install/src/Distribution/Client/Security/HTTP.hs @@ -189,13 +189,8 @@ instance HC.Pretty UnexpectedResponse where ++ " for " ++ show uri -#if MIN_VERSION_base(4,8,0) deriving instance Show UnexpectedResponse instance Exception UnexpectedResponse where displayException = HC.pretty -#else -instance Show UnexpectedResponse where show = HC.pretty -instance Exception UnexpectedResponse -#endif wrapCustomEx :: ( ( HC.Throws UnexpectedResponse diff --git a/cabal-install/src/Distribution/Client/Store.hs b/cabal-install/src/Distribution/Client/Store.hs index a8358ec2f18..9ffe6099c7f 100644 --- a/cabal-install/src/Distribution/Client/Store.hs +++ b/cabal-install/src/Distribution/Client/Store.hs @@ -48,10 +48,8 @@ import Lukko #else import System.IO (openFile, IOMode(ReadWriteMode), hClose) import GHC.IO.Handle.Lock (hLock, hTryLock, LockMode(ExclusiveLock)) -#if MIN_VERSION_base(4,11,0) import GHC.IO.Handle.Lock (hUnlock) #endif -#endif -- $concurrency -- diff --git a/cabal-install/src/Distribution/Deprecated/ParseUtils.hs b/cabal-install/src/Distribution/Deprecated/ParseUtils.hs index b3b5f8bab9d..e1d389ac9aa 100644 --- a/cabal-install/src/Distribution/Deprecated/ParseUtils.hs +++ b/cabal-install/src/Distribution/Deprecated/ParseUtils.hs @@ -121,19 +121,12 @@ instance Applicative ParseResult where pure = ParseOk [] (<*>) = ap -{- FOURMOLU_DISABLE -} instance Monad ParseResult where return = pure ParseFailed err >>= _ = ParseFailed err ParseOk ws x >>= f = case f x of ParseFailed err -> ParseFailed err ParseOk ws' x' -> ParseOk (ws' ++ ws) x' -#if !(MIN_VERSION_base(4,9,0)) - fail = parseResultFail -#elif !(MIN_VERSION_base(4,13,0)) - fail = Fail.fail -#endif -{- FOURMOLU_ENABLE -} instance Foldable ParseResult where foldMap _ (ParseFailed _) = mempty diff --git a/cabal-install/src/Distribution/Deprecated/ReadP.hs b/cabal-install/src/Distribution/Deprecated/ReadP.hs index f0626d5cfe7..2e6f9c189b8 100644 --- a/cabal-install/src/Distribution/Deprecated/ReadP.hs +++ b/cabal-install/src/Distribution/Deprecated/ReadP.hs @@ -119,12 +119,6 @@ instance Monad (P s) where (Result x p) >>= k = k x `mplus` (p >>= k) (Final r) >>= k = final [ys' | (x, s) <- r, ys' <- run (k x) s] -#if !(MIN_VERSION_base(4,9,0)) - fail _ = Fail -#elif !(MIN_VERSION_base(4,13,0)) - fail = Fail.fail -#endif - instance Fail.MonadFail (P s) where fail _ = Fail @@ -180,12 +174,6 @@ instance Monad (Parser r s) where return = pure R m >>= f = R (\k -> m (\a -> let R m' = f a in m' k)) -#if !(MIN_VERSION_base(4,9,0)) - fail _ = R (const Fail) -#elif !(MIN_VERSION_base(4,13,0)) - fail = Fail.fail -#endif - instance Fail.MonadFail (Parser r s) where fail _ = R (const Fail) diff --git a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs index 04dd86fc92a..9b7c31e2376 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs @@ -10,10 +10,6 @@ module UnitTests.Distribution.Client.ProjectConfig (tests) where -#if !MIN_VERSION_base(4,8,0) -import Data.Monoid -import Control.Applicative -#endif import Control.Monad import Data.Either (isRight) import Data.Foldable (for_) diff --git a/cabal-install/tests/UnitTests/Distribution/Client/UserConfig.hs b/cabal-install/tests/UnitTests/Distribution/Client/UserConfig.hs index 17adc1b75b4..91ed61c86cd 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/UserConfig.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/UserConfig.hs @@ -7,9 +7,6 @@ module UnitTests.Distribution.Client.UserConfig import Control.Exception (bracket) import Control.Monad (replicateM_) import Data.List (nub, sort) -#if !MIN_VERSION_base(4,8,0) -import Data.Monoid -#endif import System.Directory ( doesFileExist , getCurrentDirectory diff --git a/cabal-install/tests/UnitTests/Distribution/Solver/Types/OptionalStanza.hs b/cabal-install/tests/UnitTests/Distribution/Solver/Types/OptionalStanza.hs index 8f068d2ae53..3e2959b01f2 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Types/OptionalStanza.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Types/OptionalStanza.hs @@ -10,10 +10,6 @@ import UnitTests.Distribution.Client.ArbitraryInstances () import Test.Tasty import Test.Tasty.QuickCheck -#if !MIN_VERSION_base(4,8,0) -import Data.Monoid -#endif - tests :: [TestTree] tests = [ testProperty "fromList . toList = id" $ \xs -> diff --git a/cabal-testsuite/main/cabal-tests.hs b/cabal-testsuite/main/cabal-tests.hs index f27ea9b6094..517416a8773 100644 --- a/cabal-testsuite/main/cabal-tests.hs +++ b/cabal-testsuite/main/cabal-tests.hs @@ -33,12 +33,6 @@ import System.Directory import Distribution.Pretty import Data.Maybe -#if !MIN_VERSION_base(4,12,0) -import Data.Monoid ((<>)) -#endif -#if !MIN_VERSION_base(4,8,0) -import Data.Monoid (mempty) -#endif {- Note [Testsuite package environments] diff --git a/cabal-testsuite/src/Test/Cabal/TestCode.hs b/cabal-testsuite/src/Test/Cabal/TestCode.hs index 4d0762bdae5..800269c89d4 100644 --- a/cabal-testsuite/src/Test/Cabal/TestCode.hs +++ b/cabal-testsuite/src/Test/Cabal/TestCode.hs @@ -25,10 +25,8 @@ data TestCode deriving (Eq, Show, Read, Typeable) instance Exception TestCode -#if MIN_VERSION_base(4,8,0) where displayException = displayTestCode -#endif displayTestCode :: TestCode -> String displayTestCode TestCodeOk = "OK" diff --git a/cabal-testsuite/src/Test/Cabal/Workdir.hs b/cabal-testsuite/src/Test/Cabal/Workdir.hs index bbb545c6494..148508eb606 100644 --- a/cabal-testsuite/src/Test/Cabal/Workdir.hs +++ b/cabal-testsuite/src/Test/Cabal/Workdir.hs @@ -15,9 +15,8 @@ import Distribution.Utils.Path ) import System.Directory -import System.FilePath - import System.Environment ( getExecutablePath ) +import System.FilePath -- | Guess what the dist directory of a running executable is, -- by using the conventional layout of built executables diff --git a/doc/cabal-package-description-file.rst b/doc/cabal-package-description-file.rst index 2fa6e7415f2..416aa3df76c 100644 --- a/doc/cabal-package-description-file.rst +++ b/doc/cabal-package-description-file.rst @@ -646,42 +646,24 @@ describe the package as a whole: :: - tested-with: GHC == 9.0.1, GHC == 8.10.4, GHC == 8.8.4, - GHC == 8.6.5, GHC == 8.4.4, GHC == 8.2.2, GHC == 8.0.2, - GHC == 7.10.3, GHC == 7.8.4, GHC == 7.6.3, GHC == 7.4.2 + tested-with: GHC == 9.10.1, GHC == 9.8.2, GHC == 9.6.5 The same can be spread over several lines, for instance: :: - tested-with: GHC == 9.0.1 - , GHC == 8.10.4 - , GHC == 8.8.4 - , GHC == 8.6.5 - , GHC == 8.4.4 - , GHC == 8.2.2 - , GHC == 8.0.2 - , GHC == 7.10.3 - , GHC == 7.8.4 - , GHC == 7.6.3 - , GHC == 7.4.2 + tested-with: GHC == 9.10.1 + , GHC == 9.8.2 + , GHC == 9.6.5 The separating comma can also be dropped altogether: :: tested-with: - GHC == 9.0.1 - GHC == 8.10.4 - GHC == 8.8.4 - GHC == 8.6.5 - GHC == 8.4.4 - GHC == 8.2.2 - GHC == 8.0.2 - GHC == 7.10.3 - GHC == 7.8.4 - GHC == 7.6.3 - GHC == 7.4.2 + GHC == 9.10.1 + GHC == 9.8.2 + GHC == 9.6.5 However, this alternative might `disappear `__ @@ -696,24 +678,16 @@ describe the package as a whole: :: tested-with: - , GHC == 9.0.1 - , GHC == 8.10.4 - , GHC == 8.8.4 - , GHC == 8.6.5 - , GHC == 8.4.4 - , GHC == 8.2.2 - , GHC == 8.0.2 - , GHC == 7.10.3 - , GHC == 7.8.4 - , GHC == 7.6.3 - , GHC == 7.4.2 + , GHC == 9.10.1 + , GHC == 9.8.2 + , GHC == 9.6.5 2. A concise set notation syntax is available: :: - tested-with: GHC == { 9.0.1, 8.10.4, 8.8.4, 8.6.5, 8.4.4, 8.2.2, 8.0.2, 7.10.3, 7.8.4, 7.6.3, 7.4.2 } + tested-with: GHC == { 9.10.1, 9.8.2, 9.6.5 } .. pkg-field:: data-files: filename list @@ -993,10 +967,10 @@ is an example: library build-depends: - , base ^>= 4.11.1.0 - , bytestring ^>= 0.10.2.0 - , containers ^>= 0.4.2.1 || ^>= 0.5.0.0 - , transformers ^>= 0.5.0.0 + , base ^>= 4.19.0.0 + , bytestring ^>= 0.12.0.0 + , containers ^>= 0.6.8 || ^>= 0.7.0 + , transformers ^>= 0.6.1.0 hs-source-dirs: src @@ -1010,9 +984,9 @@ is an example: library attoparsec build-depends: - , base ^>= 4.11.1.0 - , bytestring ^>= 0.10.2.0 - , deepseq ^>= 1.4.0.0 + , base ^>= 4.19.0.0 + , bytestring ^>= 0.12.0.0 + , deepseq ^>= 1.5.0.0 hs-source-dirs: vendor/attoparsec-0.13.1.0 @@ -2664,11 +2638,11 @@ Starting with Cabal-2.2 it's possible to use common build info stanzas. :: common deps - build-depends: base ^>= 4.11 + build-depends: base ^>= 4.18 ghc-options: -Wall common test-deps - build-depends: tasty ^>= 0.12.0.1 + build-depends: tasty ^>= 1.4 library import: deps @@ -2879,8 +2853,8 @@ Declaring a ``custom-setup`` stanza also enables the generation of custom-setup setup-depends: - base >= 4.5 && < 4.11, - Cabal >= 1.14 && < 1.25 + base >= 4.18 && < 5, + Cabal >= 3.10 .. pkg-field:: setup-depends: package list :since: 1.24 From 554fd65e84db64cc6169be06525731f9ae25d7ae Mon Sep 17 00:00:00 2001 From: Simon Hengel Date: Sat, 27 Jul 2024 08:46:00 +0700 Subject: [PATCH 066/207] Makefile: Use `cabal doctest` --- Makefile | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 447f3a88fe2..d06395a9da8 100644 --- a/Makefile +++ b/Makefile @@ -5,12 +5,9 @@ CABALBUILD := cabal build CABALRUN := cabal run -# The newer and prefered way to call the doctest tool is: -# $ cabal repl --with-ghc=doctest -# SEE: https://github.com/haskell/cabal/issues/8504 -# There is but one caveat, we have to avoid allow-newer. +# We have to avoid allow-newer. # SEE: https://github.com/haskell/cabal/issues/6859 -DOCTEST := cabal repl --with-ghc=doctest --repl-options="-w" --ghc-options="-Wwarn" --allow-newer=False +DOCTEST := cabal doctest --allow-newer=False # default rules @@ -107,11 +104,11 @@ ghcid-cli : .PHONY: doctest doctest : - $(DOCTEST) Cabal-syntax - $(DOCTEST) Cabal-described - $(DOCTEST) --build-depends=QuickCheck Cabal - $(DOCTEST) cabal-install-solver - $(DOCTEST) cabal-install + cd Cabal-syntax && $(DOCTEST) + cd Cabal-described && $(DOCTEST) + cd Cabal && $(DOCTEST) + cd cabal-install-solver && $(DOCTEST) + cd cabal-install && $(DOCTEST) # This is not run as part of validate.sh (we need hackage-security, which is tricky to get). .PHONY: doctest-cli @@ -120,7 +117,7 @@ doctest-cli : .PHONY: doctest-install doctest-install: - cabal install doctest --overwrite-policy=always --ignore-project + cabal install doctest --overwrite-policy=always --ignore-project --flag cabal-doctest # tests From 857cb9ca00a1f978be806848f4ec2d3f1f512aa4 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Mon, 24 Jun 2024 18:00:39 -0400 Subject: [PATCH 067/207] regenerate bootstrap files without arch-native (cherry picked from commit aede6c4ea44d2b76fd7314111c1ead9f3209450c) Also remove 8.10.7 to match 3.12 branch. --- .github/workflows/bootstrap.yml | 2 +- Makefile | 2 +- bootstrap/linux-8.10.7.json | 575 ---------------- bootstrap/linux-9.0.2.json | 1146 +++++++++++++++---------------- bootstrap/linux-9.2.8.json | 1066 ++++++++++++++-------------- bootstrap/linux-9.4.8.json | 1046 ++++++++++++++-------------- bootstrap/linux-9.6.4.json | 986 +++++++++++++------------- bootstrap/linux-9.8.2.json | 974 +++++++++++++------------- cabal.bootstrap.project | 5 + 9 files changed, 2616 insertions(+), 3186 deletions(-) delete mode 100644 bootstrap/linux-8.10.7.json diff --git a/.github/workflows/bootstrap.yml b/.github/workflows/bootstrap.yml index 56970448239..ecfb015c699 100644 --- a/.github/workflows/bootstrap.yml +++ b/.github/workflows/bootstrap.yml @@ -30,7 +30,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - ghc: ["8.10.7", "9.0.2", "9.2.8", "9.4.8", "9.6.4", "9.8.2"] + ghc: ["9.0.2", "9.2.8", "9.4.8", "9.6.4", "9.8.2"] include: - os: macos-latest ghc: "9.2.8" diff --git a/Makefile b/Makefile index d06395a9da8..835c73b8ff9 100644 --- a/Makefile +++ b/Makefile @@ -226,7 +226,7 @@ bootstrap-json-%: phony cd bootstrap && cabal run -v0 cabal-bootstrap-gen -- linux-$*.plan.json \ | python3 -m json.tool > linux-$*.json -BOOTSTRAP_GHC_VERSIONS := 8.10.7 9.0.2 9.2.8 9.4.8 9.6.4 9.8.2 +BOOTSTRAP_GHC_VERSIONS := 9.0.2 9.2.8 9.4.8 9.6.4 9.8.2 .PHONY: bootstrap-jsons bootstrap-jsons: $(BOOTSTRAP_GHC_VERSIONS:%=bootstrap-json-%) diff --git a/bootstrap/linux-8.10.7.json b/bootstrap/linux-8.10.7.json deleted file mode 100644 index b1a2eef78f4..00000000000 --- a/bootstrap/linux-8.10.7.json +++ /dev/null @@ -1,575 +0,0 @@ -{ - "builtin": [ - { - "package": "rts", - "version": "1.0.1" - }, - { - "package": "ghc-prim", - "version": "0.6.1" - }, - { - "package": "integer-gmp", - "version": "1.0.3.0" - }, - { - "package": "base", - "version": "4.14.3.0" - }, - { - "package": "array", - "version": "0.5.4.0" - }, - { - "package": "deepseq", - "version": "1.4.4.0" - }, - { - "package": "containers", - "version": "0.6.5.1" - }, - { - "package": "ghc-boot-th", - "version": "8.10.7" - }, - { - "package": "pretty", - "version": "1.1.3.6" - }, - { - "package": "template-haskell", - "version": "2.16.0.0" - }, - { - "package": "transformers", - "version": "0.5.6.2" - }, - { - "package": "mtl", - "version": "2.2.2" - }, - { - "package": "stm", - "version": "2.5.0.1" - }, - { - "package": "exceptions", - "version": "0.10.4" - }, - { - "package": "time", - "version": "1.9.3" - } - ], - "dependencies": [ - { - "cabal_sha256": "a4a1975fde77e289b605c45a3ef78d731d8c1834e4cef311152d910a1e94d98c", - "component": "lib:data-array-byte", - "flags": [], - "package": "data-array-byte", - "revision": 3, - "source": "hackage", - "src_sha256": "1bb6eca0b3e02d057fe7f4e14c81ef395216f421ab30fdaa1b18017c9c025600", - "version": "0.1.0.1" - }, - { - "cabal_sha256": "98e79e1c97117143e4012983509ec95f7e5e4f6adff6914d07812a39f83404b9", - "component": "lib:bytestring", - "flags": [ - "-pure-haskell" - ], - "package": "bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "ebc3b8a6ef74a5cd6ddbb8d447d1c9a5fd4964c7975ebcae0b8ab0bcc406cc8c", - "version": "0.12.1.0" - }, - { - "cabal_sha256": "345cbb1afe414a09e47737e4d14cbd51891a734e67c0ef3d77a1439518bb81e8", - "component": "lib:filepath", - "flags": [ - "-cpphs" - ], - "package": "filepath", - "revision": 0, - "source": "hackage", - "src_sha256": "88d6452fd199e333e66e68d2dc5d715f5c6d361661a4a8add88320a82864b788", - "version": "1.4.300.2" - }, - { - "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", - "component": "lib:unix", - "flags": [ - "-os-string" - ], - "package": "unix", - "revision": 0, - "source": "hackage", - "src_sha256": "5ab6c346aef2eb9bf80b4d29ca7e22063fc23e52fd69fbc4d18a9f98b154e424", - "version": "2.8.5.1" - }, - { - "cabal_sha256": "fbeec9ec346e5272167f63dcb86af513b457a7b9fc36dc818e4c7b81608d612b", - "component": "lib:directory", - "flags": [ - "-os-string" - ], - "package": "directory", - "revision": 0, - "source": "hackage", - "src_sha256": "e864ed54ddfc6e15d2eb02c87f4be8edd7719e1f9cea13e0f86909400b6ea768", - "version": "1.3.8.5" - }, - { - "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", - "component": "exe:alex", - "flags": [], - "package": "alex", - "revision": 0, - "source": "hackage", - "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", - "version": "3.5.1.0" - }, - { - "cabal_sha256": "03381e511429c44d13990c6d76281c4fc2468371cede4fe684b0c98d9b7d5f5a", - "component": "lib:binary", - "flags": [], - "package": "binary", - "revision": 0, - "source": "hackage", - "src_sha256": "8437116b4eccdba13cb9badb62331c0d4598c3f0252a587e37d8f5990d9bf74c", - "version": "0.8.9.2" - }, - { - "cabal_sha256": "78c3fb91055d0607a80453327f087b9dc82168d41d0dca3ff410d21033b5e87d", - "component": "lib:text", - "flags": [ - "-developer", - "-pure-haskell", - "+simdutf" - ], - "package": "text", - "revision": 1, - "source": "hackage", - "src_sha256": "e40cdda8b285f4d72476ed35dc2f5f167d524e6b38bb5ec964d00ee1ff24feab", - "version": "2.1.1" - }, - { - "cabal_sha256": "8407cbd428d7f640a0fff8891bd2f7aca13cebe70a5e654856f8abec9a648b56", - "component": "lib:parsec", - "flags": [], - "package": "parsec", - "revision": 1, - "source": "hackage", - "src_sha256": "58c500bec1ec3c849c8243ddfd675a5983b17a8e5da55acea6adade5ae179d36", - "version": "3.1.17.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-syntax", - "flags": [], - "package": "Cabal-syntax", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "2a9393de33f18415fb8f4826957a87a94ffe8840ca8472a9b69dca6de45aca03", - "component": "lib:process", - "flags": [], - "package": "process", - "revision": 1, - "source": "hackage", - "src_sha256": "cefda221c3009fa2316b5cf148215cb340dad7eb8503f22e49e33722559df99a", - "version": "1.6.20.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal", - "flags": [], - "package": "Cabal", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-hooks", - "flags": [], - "package": "Cabal-hooks", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "0.1" - }, - { - "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", - "component": "exe:hsc2hs", - "flags": [ - "-in-ghc-tree" - ], - "package": "hsc2hs", - "revision": 2, - "source": "hackage", - "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", - "version": "0.68.10" - }, - { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", - "component": "lib:network", - "flags": [ - "-devel" - ], - "package": "network", - "revision": 0, - "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" - }, - { - "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", - "component": "lib:th-compat", - "flags": [], - "package": "th-compat", - "revision": 2, - "source": "hackage", - "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", - "version": "0.1.5" - }, - { - "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", - "component": "lib:network-uri", - "flags": [], - "package": "network-uri", - "revision": 1, - "source": "hackage", - "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", - "version": "2.6.4.2" - }, - { - "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", - "component": "lib:HTTP", - "flags": [ - "-conduit10", - "+network-uri", - "-warn-as-error", - "-warp-tests" - ], - "package": "HTTP", - "revision": 4, - "source": "hackage", - "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", - "version": "4000.4.1" - }, - { - "cabal_sha256": "455d863c96cf4b1804772c630a235f535fdb52ca9137a4150967b521ee4734ab", - "component": "lib:base-orphans", - "flags": [], - "package": "base-orphans", - "revision": 0, - "source": "hackage", - "src_sha256": "6211900916955b84687c61b5e4fa98ce110e511a96086b7a93f06dd63c97ba93", - "version": "0.9.2" - }, - { - "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", - "component": "lib:hashable", - "flags": [ - "+arch-native", - "+integer-gmp", - "-random-initial-seed" - ], - "package": "hashable", - "revision": 0, - "source": "hackage", - "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", - "version": "1.4.6.0" - }, - { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", - "component": "lib:async", - "flags": [ - "-bench" - ], - "package": "async", - "revision": 1, - "source": "hackage", - "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", - "version": "2.2.5" - }, - { - "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", - "component": "lib:base16-bytestring", - "flags": [], - "package": "base16-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", - "version": "1.0.2.0" - }, - { - "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", - "component": "lib:base64-bytestring", - "flags": [], - "package": "base64-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", - "version": "1.2.1.0" - }, - { - "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", - "component": "lib:splitmix", - "flags": [ - "-optimised-mixer" - ], - "package": "splitmix", - "revision": 1, - "source": "hackage", - "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", - "version": "0.1.0.5" - }, - { - "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", - "component": "lib:random", - "flags": [], - "package": "random", - "revision": 0, - "source": "hackage", - "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", - "version": "1.2.1.2" - }, - { - "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", - "component": "lib:edit-distance", - "flags": [], - "package": "edit-distance", - "revision": 1, - "source": "hackage", - "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", - "version": "0.2.2.1" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install-solver", - "flags": [ - "-debug-expensive-assertions", - "-debug-tracetree" - ], - "package": "cabal-install-solver", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", - "component": "lib:cryptohash-sha256", - "flags": [ - "-exe", - "+use-cbits" - ], - "package": "cryptohash-sha256", - "revision": 4, - "source": "hackage", - "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", - "version": "0.11.102.1" - }, - { - "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", - "component": "lib:echo", - "flags": [ - "-example" - ], - "package": "echo", - "revision": 0, - "source": "hackage", - "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", - "version": "0.1.4" - }, - { - "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", - "component": "lib:ed25519", - "flags": [ - "+no-donna", - "+test-doctests", - "+test-hlint", - "+test-properties" - ], - "package": "ed25519", - "revision": 8, - "source": "hackage", - "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", - "version": "0.0.5.0" - }, - { - "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", - "component": "lib:lukko", - "flags": [ - "+ofd-locking" - ], - "package": "lukko", - "revision": 0, - "source": "hackage", - "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", - "version": "0.1.2" - }, - { - "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", - "component": "lib:os-string", - "flags": [], - "package": "os-string", - "revision": 0, - "source": "hackage", - "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", - "version": "2.0.3" - }, - { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", - "component": "lib:tar-internal", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", - "version": "0.6.3.0" - }, - { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", - "component": "lib:tar", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", - "version": "0.6.3.0" - }, - { - "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", - "component": "lib:zlib", - "flags": [ - "-bundled-c-zlib", - "+non-blocking-ffi", - "-pkg-config" - ], - "package": "zlib", - "revision": 0, - "source": "hackage", - "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", - "version": "0.7.1.0" - }, - { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", - "component": "lib:hackage-security", - "flags": [ - "+cabal-syntax", - "+lukko" - ], - "package": "hackage-security", - "revision": 1, - "source": "hackage", - "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", - "version": "0.6.2.6" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "lib:open-browser", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - }, - { - "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", - "component": "lib:regex-base", - "flags": [], - "package": "regex-base", - "revision": 4, - "source": "hackage", - "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", - "version": "0.94.0.2" - }, - { - "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", - "component": "lib:regex-posix", - "flags": [ - "-_regex-posix-clib" - ], - "package": "regex-posix", - "revision": 3, - "source": "hackage", - "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", - "version": "0.96.0.1" - }, - { - "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", - "component": "lib:resolv", - "flags": [], - "package": "resolv", - "revision": 3, - "source": "hackage", - "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", - "version": "0.2.0.2" - }, - { - "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", - "component": "lib:safe-exceptions", - "flags": [], - "package": "safe-exceptions", - "revision": 1, - "source": "hackage", - "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", - "version": "0.1.7.4" - }, - { - "cabal_sha256": "2de5218cef72b8ef090bd7d0fd930ffa143242a120c62e013b5cf039858f1855", - "component": "lib:semaphore-compat", - "flags": [], - "package": "semaphore-compat", - "revision": 3, - "source": "hackage", - "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", - "version": "1.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "exe:cabal", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "exe:example", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - } - ] -} diff --git a/bootstrap/linux-9.0.2.json b/bootstrap/linux-9.0.2.json index eb885f6b305..d260767f667 100644 --- a/bootstrap/linux-9.0.2.json +++ b/bootstrap/linux-9.0.2.json @@ -1,575 +1,575 @@ { - "builtin": [ - { - "package": "rts", - "version": "1.0.2" - }, - { - "package": "ghc-prim", - "version": "0.7.0" - }, - { - "package": "ghc-bignum", - "version": "1.1" - }, - { - "package": "base", - "version": "4.15.1.0" - }, - { - "package": "array", - "version": "0.5.4.0" - }, - { - "package": "deepseq", - "version": "1.4.5.0" - }, - { - "package": "containers", - "version": "0.6.4.1" - }, - { - "package": "ghc-boot-th", - "version": "9.0.2" - }, - { - "package": "pretty", - "version": "1.1.3.6" - }, - { - "package": "template-haskell", - "version": "2.17.0.0" - }, - { - "package": "transformers", - "version": "0.5.6.2" - }, - { - "package": "mtl", - "version": "2.2.2" - }, - { - "package": "stm", - "version": "2.5.0.0" - }, - { - "package": "exceptions", - "version": "0.10.4" - }, - { - "package": "time", - "version": "1.9.3" - } - ], - "dependencies": [ - { - "cabal_sha256": "a4a1975fde77e289b605c45a3ef78d731d8c1834e4cef311152d910a1e94d98c", - "component": "lib:data-array-byte", - "flags": [], - "package": "data-array-byte", - "revision": 3, - "source": "hackage", - "src_sha256": "1bb6eca0b3e02d057fe7f4e14c81ef395216f421ab30fdaa1b18017c9c025600", - "version": "0.1.0.1" - }, - { - "cabal_sha256": "98e79e1c97117143e4012983509ec95f7e5e4f6adff6914d07812a39f83404b9", - "component": "lib:bytestring", - "flags": [ - "-pure-haskell" - ], - "package": "bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "ebc3b8a6ef74a5cd6ddbb8d447d1c9a5fd4964c7975ebcae0b8ab0bcc406cc8c", - "version": "0.12.1.0" - }, - { - "cabal_sha256": "345cbb1afe414a09e47737e4d14cbd51891a734e67c0ef3d77a1439518bb81e8", - "component": "lib:filepath", - "flags": [ - "-cpphs" - ], - "package": "filepath", - "revision": 0, - "source": "hackage", - "src_sha256": "88d6452fd199e333e66e68d2dc5d715f5c6d361661a4a8add88320a82864b788", - "version": "1.4.300.2" - }, - { - "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", - "component": "lib:unix", - "flags": [ - "-os-string" - ], - "package": "unix", - "revision": 0, - "source": "hackage", - "src_sha256": "5ab6c346aef2eb9bf80b4d29ca7e22063fc23e52fd69fbc4d18a9f98b154e424", - "version": "2.8.5.1" - }, - { - "cabal_sha256": "fbeec9ec346e5272167f63dcb86af513b457a7b9fc36dc818e4c7b81608d612b", - "component": "lib:directory", - "flags": [ - "-os-string" - ], - "package": "directory", - "revision": 0, - "source": "hackage", - "src_sha256": "e864ed54ddfc6e15d2eb02c87f4be8edd7719e1f9cea13e0f86909400b6ea768", - "version": "1.3.8.5" - }, - { - "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", - "component": "exe:alex", - "flags": [], - "package": "alex", - "revision": 0, - "source": "hackage", - "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", - "version": "3.5.1.0" - }, - { - "cabal_sha256": "03381e511429c44d13990c6d76281c4fc2468371cede4fe684b0c98d9b7d5f5a", - "component": "lib:binary", - "flags": [], - "package": "binary", - "revision": 0, - "source": "hackage", - "src_sha256": "8437116b4eccdba13cb9badb62331c0d4598c3f0252a587e37d8f5990d9bf74c", - "version": "0.8.9.2" - }, - { - "cabal_sha256": "78c3fb91055d0607a80453327f087b9dc82168d41d0dca3ff410d21033b5e87d", - "component": "lib:text", - "flags": [ - "-developer", - "-pure-haskell", - "+simdutf" - ], - "package": "text", - "revision": 1, - "source": "hackage", - "src_sha256": "e40cdda8b285f4d72476ed35dc2f5f167d524e6b38bb5ec964d00ee1ff24feab", - "version": "2.1.1" - }, - { - "cabal_sha256": "8407cbd428d7f640a0fff8891bd2f7aca13cebe70a5e654856f8abec9a648b56", - "component": "lib:parsec", - "flags": [], - "package": "parsec", - "revision": 1, - "source": "hackage", - "src_sha256": "58c500bec1ec3c849c8243ddfd675a5983b17a8e5da55acea6adade5ae179d36", - "version": "3.1.17.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-syntax", - "flags": [], - "package": "Cabal-syntax", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "2a9393de33f18415fb8f4826957a87a94ffe8840ca8472a9b69dca6de45aca03", - "component": "lib:process", - "flags": [], - "package": "process", - "revision": 1, - "source": "hackage", - "src_sha256": "cefda221c3009fa2316b5cf148215cb340dad7eb8503f22e49e33722559df99a", - "version": "1.6.20.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal", - "flags": [], - "package": "Cabal", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-hooks", - "flags": [], - "package": "Cabal-hooks", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "0.1" - }, - { - "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", - "component": "exe:hsc2hs", - "flags": [ - "-in-ghc-tree" - ], - "package": "hsc2hs", - "revision": 2, - "source": "hackage", - "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", - "version": "0.68.10" - }, - { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", - "component": "lib:network", - "flags": [ - "-devel" - ], - "package": "network", - "revision": 0, - "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" - }, - { - "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", - "component": "lib:th-compat", - "flags": [], - "package": "th-compat", - "revision": 2, - "source": "hackage", - "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", - "version": "0.1.5" - }, - { - "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", - "component": "lib:network-uri", - "flags": [], - "package": "network-uri", - "revision": 1, - "source": "hackage", - "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", - "version": "2.6.4.2" - }, - { - "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", - "component": "lib:HTTP", - "flags": [ - "-conduit10", - "+network-uri", - "-warn-as-error", - "-warp-tests" - ], - "package": "HTTP", - "revision": 4, - "source": "hackage", - "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", - "version": "4000.4.1" - }, - { - "cabal_sha256": "455d863c96cf4b1804772c630a235f535fdb52ca9137a4150967b521ee4734ab", - "component": "lib:base-orphans", - "flags": [], - "package": "base-orphans", - "revision": 0, - "source": "hackage", - "src_sha256": "6211900916955b84687c61b5e4fa98ce110e511a96086b7a93f06dd63c97ba93", - "version": "0.9.2" - }, - { - "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", - "component": "lib:hashable", - "flags": [ - "+arch-native", - "+integer-gmp", - "-random-initial-seed" - ], - "package": "hashable", - "revision": 0, - "source": "hackage", - "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", - "version": "1.4.6.0" - }, - { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", - "component": "lib:async", - "flags": [ - "-bench" - ], - "package": "async", - "revision": 1, - "source": "hackage", - "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", - "version": "2.2.5" - }, - { - "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", - "component": "lib:base16-bytestring", - "flags": [], - "package": "base16-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", - "version": "1.0.2.0" - }, - { - "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", - "component": "lib:base64-bytestring", - "flags": [], - "package": "base64-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", - "version": "1.2.1.0" - }, - { - "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", - "component": "lib:splitmix", - "flags": [ - "-optimised-mixer" - ], - "package": "splitmix", - "revision": 1, - "source": "hackage", - "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", - "version": "0.1.0.5" - }, - { - "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", - "component": "lib:random", - "flags": [], - "package": "random", - "revision": 0, - "source": "hackage", - "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", - "version": "1.2.1.2" - }, - { - "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", - "component": "lib:edit-distance", - "flags": [], - "package": "edit-distance", - "revision": 1, - "source": "hackage", - "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", - "version": "0.2.2.1" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install-solver", - "flags": [ - "-debug-expensive-assertions", - "-debug-tracetree" - ], - "package": "cabal-install-solver", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", - "component": "lib:cryptohash-sha256", - "flags": [ - "-exe", - "+use-cbits" - ], - "package": "cryptohash-sha256", - "revision": 4, - "source": "hackage", - "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", - "version": "0.11.102.1" - }, - { - "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", - "component": "lib:echo", - "flags": [ - "-example" - ], - "package": "echo", - "revision": 0, - "source": "hackage", - "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", - "version": "0.1.4" - }, - { - "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", - "component": "lib:ed25519", - "flags": [ - "+no-donna", - "+test-doctests", - "+test-hlint", - "+test-properties" - ], - "package": "ed25519", - "revision": 8, - "source": "hackage", - "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", - "version": "0.0.5.0" - }, - { - "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", - "component": "lib:lukko", - "flags": [ - "+ofd-locking" - ], - "package": "lukko", - "revision": 0, - "source": "hackage", - "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", - "version": "0.1.2" - }, - { - "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", - "component": "lib:os-string", - "flags": [], - "package": "os-string", - "revision": 0, - "source": "hackage", - "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", - "version": "2.0.3" - }, - { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", - "component": "lib:tar-internal", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", - "version": "0.6.3.0" - }, - { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", - "component": "lib:tar", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", - "version": "0.6.3.0" - }, - { - "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", - "component": "lib:zlib", - "flags": [ - "-bundled-c-zlib", - "+non-blocking-ffi", - "-pkg-config" - ], - "package": "zlib", - "revision": 0, - "source": "hackage", - "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", - "version": "0.7.1.0" - }, - { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", - "component": "lib:hackage-security", - "flags": [ - "+cabal-syntax", - "+lukko" - ], - "package": "hackage-security", - "revision": 1, - "source": "hackage", - "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", - "version": "0.6.2.6" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "lib:open-browser", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - }, - { - "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", - "component": "lib:regex-base", - "flags": [], - "package": "regex-base", - "revision": 4, - "source": "hackage", - "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", - "version": "0.94.0.2" - }, - { - "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", - "component": "lib:regex-posix", - "flags": [ - "-_regex-posix-clib" - ], - "package": "regex-posix", - "revision": 3, - "source": "hackage", - "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", - "version": "0.96.0.1" - }, - { - "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", - "component": "lib:resolv", - "flags": [], - "package": "resolv", - "revision": 3, - "source": "hackage", - "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", - "version": "0.2.0.2" - }, - { - "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", - "component": "lib:safe-exceptions", - "flags": [], - "package": "safe-exceptions", - "revision": 1, - "source": "hackage", - "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", - "version": "0.1.7.4" - }, - { - "cabal_sha256": "2de5218cef72b8ef090bd7d0fd930ffa143242a120c62e013b5cf039858f1855", - "component": "lib:semaphore-compat", - "flags": [], - "package": "semaphore-compat", - "revision": 3, - "source": "hackage", - "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", - "version": "1.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "exe:cabal", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "exe:example", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - } - ] + "builtin": [ + { + "package": "rts", + "version": "1.0.2" + }, + { + "package": "ghc-prim", + "version": "0.7.0" + }, + { + "package": "ghc-bignum", + "version": "1.1" + }, + { + "package": "base", + "version": "4.15.1.0" + }, + { + "package": "array", + "version": "0.5.4.0" + }, + { + "package": "deepseq", + "version": "1.4.5.0" + }, + { + "package": "containers", + "version": "0.6.4.1" + }, + { + "package": "ghc-boot-th", + "version": "9.0.2" + }, + { + "package": "pretty", + "version": "1.1.3.6" + }, + { + "package": "template-haskell", + "version": "2.17.0.0" + }, + { + "package": "transformers", + "version": "0.5.6.2" + }, + { + "package": "mtl", + "version": "2.2.2" + }, + { + "package": "stm", + "version": "2.5.0.0" + }, + { + "package": "exceptions", + "version": "0.10.4" + }, + { + "package": "time", + "version": "1.9.3" + } + ], + "dependencies": [ + { + "cabal_sha256": "a4a1975fde77e289b605c45a3ef78d731d8c1834e4cef311152d910a1e94d98c", + "component": "lib:data-array-byte", + "flags": [], + "package": "data-array-byte", + "revision": 3, + "source": "hackage", + "src_sha256": "1bb6eca0b3e02d057fe7f4e14c81ef395216f421ab30fdaa1b18017c9c025600", + "version": "0.1.0.1" + }, + { + "cabal_sha256": "98e79e1c97117143e4012983509ec95f7e5e4f6adff6914d07812a39f83404b9", + "component": "lib:bytestring", + "flags": [ + "-pure-haskell" + ], + "package": "bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "ebc3b8a6ef74a5cd6ddbb8d447d1c9a5fd4964c7975ebcae0b8ab0bcc406cc8c", + "version": "0.12.1.0" + }, + { + "cabal_sha256": "345cbb1afe414a09e47737e4d14cbd51891a734e67c0ef3d77a1439518bb81e8", + "component": "lib:filepath", + "flags": [ + "-cpphs" + ], + "package": "filepath", + "revision": 0, + "source": "hackage", + "src_sha256": "88d6452fd199e333e66e68d2dc5d715f5c6d361661a4a8add88320a82864b788", + "version": "1.4.300.2" + }, + { + "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", + "component": "lib:unix", + "flags": [ + "-os-string" + ], + "package": "unix", + "revision": 0, + "source": "hackage", + "src_sha256": "5ab6c346aef2eb9bf80b4d29ca7e22063fc23e52fd69fbc4d18a9f98b154e424", + "version": "2.8.5.1" + }, + { + "cabal_sha256": "fbeec9ec346e5272167f63dcb86af513b457a7b9fc36dc818e4c7b81608d612b", + "component": "lib:directory", + "flags": [ + "-os-string" + ], + "package": "directory", + "revision": 0, + "source": "hackage", + "src_sha256": "e864ed54ddfc6e15d2eb02c87f4be8edd7719e1f9cea13e0f86909400b6ea768", + "version": "1.3.8.5" + }, + { + "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", + "component": "exe:alex", + "flags": [], + "package": "alex", + "revision": 0, + "source": "hackage", + "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", + "version": "3.5.1.0" + }, + { + "cabal_sha256": "03381e511429c44d13990c6d76281c4fc2468371cede4fe684b0c98d9b7d5f5a", + "component": "lib:binary", + "flags": [], + "package": "binary", + "revision": 0, + "source": "hackage", + "src_sha256": "8437116b4eccdba13cb9badb62331c0d4598c3f0252a587e37d8f5990d9bf74c", + "version": "0.8.9.2" + }, + { + "cabal_sha256": "78c3fb91055d0607a80453327f087b9dc82168d41d0dca3ff410d21033b5e87d", + "component": "lib:text", + "flags": [ + "-developer", + "-pure-haskell", + "+simdutf" + ], + "package": "text", + "revision": 1, + "source": "hackage", + "src_sha256": "e40cdda8b285f4d72476ed35dc2f5f167d524e6b38bb5ec964d00ee1ff24feab", + "version": "2.1.1" + }, + { + "cabal_sha256": "8407cbd428d7f640a0fff8891bd2f7aca13cebe70a5e654856f8abec9a648b56", + "component": "lib:parsec", + "flags": [], + "package": "parsec", + "revision": 1, + "source": "hackage", + "src_sha256": "58c500bec1ec3c849c8243ddfd675a5983b17a8e5da55acea6adade5ae179d36", + "version": "3.1.17.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-syntax", + "flags": [], + "package": "Cabal-syntax", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "2a9393de33f18415fb8f4826957a87a94ffe8840ca8472a9b69dca6de45aca03", + "component": "lib:process", + "flags": [], + "package": "process", + "revision": 1, + "source": "hackage", + "src_sha256": "cefda221c3009fa2316b5cf148215cb340dad7eb8503f22e49e33722559df99a", + "version": "1.6.20.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal", + "flags": [], + "package": "Cabal", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-hooks", + "flags": [], + "package": "Cabal-hooks", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "0.1" + }, + { + "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", + "component": "exe:hsc2hs", + "flags": [ + "-in-ghc-tree" + ], + "package": "hsc2hs", + "revision": 2, + "source": "hackage", + "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", + "version": "0.68.10" + }, + { + "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", + "component": "lib:network", + "flags": [ + "-devel" + ], + "package": "network", + "revision": 0, + "source": "hackage", + "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", + "version": "3.2.0.0" + }, + { + "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", + "component": "lib:th-compat", + "flags": [], + "package": "th-compat", + "revision": 2, + "source": "hackage", + "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", + "version": "0.1.5" + }, + { + "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", + "component": "lib:network-uri", + "flags": [], + "package": "network-uri", + "revision": 1, + "source": "hackage", + "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", + "version": "2.6.4.2" + }, + { + "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", + "component": "lib:HTTP", + "flags": [ + "-conduit10", + "+network-uri", + "-warn-as-error", + "-warp-tests" + ], + "package": "HTTP", + "revision": 4, + "source": "hackage", + "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", + "version": "4000.4.1" + }, + { + "cabal_sha256": "455d863c96cf4b1804772c630a235f535fdb52ca9137a4150967b521ee4734ab", + "component": "lib:base-orphans", + "flags": [], + "package": "base-orphans", + "revision": 0, + "source": "hackage", + "src_sha256": "6211900916955b84687c61b5e4fa98ce110e511a96086b7a93f06dd63c97ba93", + "version": "0.9.2" + }, + { + "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", + "component": "lib:hashable", + "flags": [ + "-arch-native", + "+integer-gmp", + "-random-initial-seed" + ], + "package": "hashable", + "revision": 0, + "source": "hackage", + "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", + "version": "1.4.6.0" + }, + { + "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", + "component": "lib:async", + "flags": [ + "-bench" + ], + "package": "async", + "revision": 1, + "source": "hackage", + "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", + "version": "2.2.5" + }, + { + "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", + "component": "lib:base16-bytestring", + "flags": [], + "package": "base16-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", + "version": "1.0.2.0" + }, + { + "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", + "component": "lib:base64-bytestring", + "flags": [], + "package": "base64-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", + "version": "1.2.1.0" + }, + { + "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", + "component": "lib:splitmix", + "flags": [ + "-optimised-mixer" + ], + "package": "splitmix", + "revision": 1, + "source": "hackage", + "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", + "version": "0.1.0.5" + }, + { + "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", + "component": "lib:random", + "flags": [], + "package": "random", + "revision": 0, + "source": "hackage", + "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", + "version": "1.2.1.2" + }, + { + "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", + "component": "lib:edit-distance", + "flags": [], + "package": "edit-distance", + "revision": 1, + "source": "hackage", + "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", + "version": "0.2.2.1" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install-solver", + "flags": [ + "-debug-expensive-assertions", + "-debug-tracetree" + ], + "package": "cabal-install-solver", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", + "component": "lib:cryptohash-sha256", + "flags": [ + "-exe", + "+use-cbits" + ], + "package": "cryptohash-sha256", + "revision": 4, + "source": "hackage", + "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", + "version": "0.11.102.1" + }, + { + "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", + "component": "lib:echo", + "flags": [ + "-example" + ], + "package": "echo", + "revision": 0, + "source": "hackage", + "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", + "version": "0.1.4" + }, + { + "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", + "component": "lib:ed25519", + "flags": [ + "+no-donna", + "+test-doctests", + "+test-hlint", + "+test-properties" + ], + "package": "ed25519", + "revision": 8, + "source": "hackage", + "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", + "version": "0.0.5.0" + }, + { + "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", + "component": "lib:lukko", + "flags": [ + "+ofd-locking" + ], + "package": "lukko", + "revision": 0, + "source": "hackage", + "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", + "version": "0.1.2" + }, + { + "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", + "component": "lib:os-string", + "flags": [], + "package": "os-string", + "revision": 0, + "source": "hackage", + "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", + "version": "2.0.3" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar-internal", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", + "component": "lib:zlib", + "flags": [ + "-bundled-c-zlib", + "+non-blocking-ffi", + "+pkg-config" + ], + "package": "zlib", + "revision": 0, + "source": "hackage", + "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", + "version": "0.7.1.0" + }, + { + "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", + "component": "lib:hackage-security", + "flags": [ + "+cabal-syntax", + "+lukko" + ], + "package": "hackage-security", + "revision": 1, + "source": "hackage", + "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", + "version": "0.6.2.6" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "lib:open-browser", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + }, + { + "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", + "component": "lib:regex-base", + "flags": [], + "package": "regex-base", + "revision": 4, + "source": "hackage", + "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", + "version": "0.94.0.2" + }, + { + "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", + "component": "lib:regex-posix", + "flags": [ + "-_regex-posix-clib" + ], + "package": "regex-posix", + "revision": 3, + "source": "hackage", + "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", + "version": "0.96.0.1" + }, + { + "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", + "component": "lib:resolv", + "flags": [], + "package": "resolv", + "revision": 3, + "source": "hackage", + "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", + "version": "0.2.0.2" + }, + { + "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", + "component": "lib:safe-exceptions", + "flags": [], + "package": "safe-exceptions", + "revision": 1, + "source": "hackage", + "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", + "version": "0.1.7.4" + }, + { + "cabal_sha256": "2de5218cef72b8ef090bd7d0fd930ffa143242a120c62e013b5cf039858f1855", + "component": "lib:semaphore-compat", + "flags": [], + "package": "semaphore-compat", + "revision": 3, + "source": "hackage", + "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", + "version": "1.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "exe:cabal", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "exe:example", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + } + ] } diff --git a/bootstrap/linux-9.2.8.json b/bootstrap/linux-9.2.8.json index c004593615b..8a19bb40027 100644 --- a/bootstrap/linux-9.2.8.json +++ b/bootstrap/linux-9.2.8.json @@ -1,535 +1,535 @@ { - "builtin": [ - { - "package": "rts", - "version": "1.0.2" - }, - { - "package": "ghc-prim", - "version": "0.8.0" - }, - { - "package": "ghc-bignum", - "version": "1.2" - }, - { - "package": "base", - "version": "4.16.4.0" - }, - { - "package": "array", - "version": "0.5.4.0" - }, - { - "package": "deepseq", - "version": "1.4.6.1" - }, - { - "package": "containers", - "version": "0.6.5.1" - }, - { - "package": "ghc-boot-th", - "version": "9.2.8" - }, - { - "package": "pretty", - "version": "1.1.3.6" - }, - { - "package": "template-haskell", - "version": "2.18.0.0" - }, - { - "package": "bytestring", - "version": "0.11.4.0" - }, - { - "package": "transformers", - "version": "0.5.6.2" - }, - { - "package": "mtl", - "version": "2.2.2" - }, - { - "package": "stm", - "version": "2.5.0.2" - }, - { - "package": "exceptions", - "version": "0.10.4" - }, - { - "package": "time", - "version": "1.11.1.1" - }, - { - "package": "binary", - "version": "0.8.9.0" - }, - { - "package": "text", - "version": "1.2.5.0" - }, - { - "package": "parsec", - "version": "3.1.15.0" - } - ], - "dependencies": [ - { - "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", - "component": "lib:os-string", - "flags": [], - "package": "os-string", - "revision": 0, - "source": "hackage", - "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", - "version": "2.0.3" - }, - { - "cabal_sha256": "8af7a843cba7eddc8d44ae94002b766ee8c23cbcd3ecdb2cc79ee6e0a694419a", - "component": "lib:filepath", - "flags": [ - "-cpphs" - ], - "package": "filepath", - "revision": 1, - "source": "hackage", - "src_sha256": "d2606db4fa8517932a2d9ea6415c365da4d1794afcb264a5b3c10110123978a7", - "version": "1.5.2.0" - }, - { - "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", - "component": "lib:unix", - "flags": [ - "+os-string" - ], - "package": "unix", - "revision": 0, - "source": "hackage", - "src_sha256": "5ab6c346aef2eb9bf80b4d29ca7e22063fc23e52fd69fbc4d18a9f98b154e424", - "version": "2.8.5.1" - }, - { - "cabal_sha256": "fbeec9ec346e5272167f63dcb86af513b457a7b9fc36dc818e4c7b81608d612b", - "component": "lib:directory", - "flags": [ - "+os-string" - ], - "package": "directory", - "revision": 0, - "source": "hackage", - "src_sha256": "e864ed54ddfc6e15d2eb02c87f4be8edd7719e1f9cea13e0f86909400b6ea768", - "version": "1.3.8.5" - }, - { - "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", - "component": "exe:alex", - "flags": [], - "package": "alex", - "revision": 0, - "source": "hackage", - "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", - "version": "3.5.1.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-syntax", - "flags": [], - "package": "Cabal-syntax", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "2a9393de33f18415fb8f4826957a87a94ffe8840ca8472a9b69dca6de45aca03", - "component": "lib:process", - "flags": [], - "package": "process", - "revision": 1, - "source": "hackage", - "src_sha256": "cefda221c3009fa2316b5cf148215cb340dad7eb8503f22e49e33722559df99a", - "version": "1.6.20.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal", - "flags": [], - "package": "Cabal", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-hooks", - "flags": [], - "package": "Cabal-hooks", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "0.1" - }, - { - "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", - "component": "exe:hsc2hs", - "flags": [ - "-in-ghc-tree" - ], - "package": "hsc2hs", - "revision": 2, - "source": "hackage", - "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", - "version": "0.68.10" - }, - { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", - "component": "lib:network", - "flags": [ - "-devel" - ], - "package": "network", - "revision": 0, - "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" - }, - { - "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", - "component": "lib:th-compat", - "flags": [], - "package": "th-compat", - "revision": 2, - "source": "hackage", - "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", - "version": "0.1.5" - }, - { - "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", - "component": "lib:network-uri", - "flags": [], - "package": "network-uri", - "revision": 1, - "source": "hackage", - "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", - "version": "2.6.4.2" - }, - { - "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", - "component": "lib:HTTP", - "flags": [ - "-conduit10", - "+network-uri", - "-warn-as-error", - "-warp-tests" - ], - "package": "HTTP", - "revision": 4, - "source": "hackage", - "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", - "version": "4000.4.1" - }, - { - "cabal_sha256": "a4a1975fde77e289b605c45a3ef78d731d8c1834e4cef311152d910a1e94d98c", - "component": "lib:data-array-byte", - "flags": [], - "package": "data-array-byte", - "revision": 3, - "source": "hackage", - "src_sha256": "1bb6eca0b3e02d057fe7f4e14c81ef395216f421ab30fdaa1b18017c9c025600", - "version": "0.1.0.1" - }, - { - "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", - "component": "lib:hashable", - "flags": [ - "+arch-native", - "+integer-gmp", - "-random-initial-seed" - ], - "package": "hashable", - "revision": 0, - "source": "hackage", - "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", - "version": "1.4.6.0" - }, - { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", - "component": "lib:async", - "flags": [ - "-bench" - ], - "package": "async", - "revision": 1, - "source": "hackage", - "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", - "version": "2.2.5" - }, - { - "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", - "component": "lib:base16-bytestring", - "flags": [], - "package": "base16-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", - "version": "1.0.2.0" - }, - { - "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", - "component": "lib:base64-bytestring", - "flags": [], - "package": "base64-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", - "version": "1.2.1.0" - }, - { - "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", - "component": "lib:splitmix", - "flags": [ - "-optimised-mixer" - ], - "package": "splitmix", - "revision": 1, - "source": "hackage", - "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", - "version": "0.1.0.5" - }, - { - "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", - "component": "lib:random", - "flags": [], - "package": "random", - "revision": 0, - "source": "hackage", - "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", - "version": "1.2.1.2" - }, - { - "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", - "component": "lib:edit-distance", - "flags": [], - "package": "edit-distance", - "revision": 1, - "source": "hackage", - "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", - "version": "0.2.2.1" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install-solver", - "flags": [ - "-debug-expensive-assertions", - "-debug-tracetree" - ], - "package": "cabal-install-solver", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", - "component": "lib:cryptohash-sha256", - "flags": [ - "-exe", - "+use-cbits" - ], - "package": "cryptohash-sha256", - "revision": 4, - "source": "hackage", - "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", - "version": "0.11.102.1" - }, - { - "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", - "component": "lib:echo", - "flags": [ - "-example" - ], - "package": "echo", - "revision": 0, - "source": "hackage", - "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", - "version": "0.1.4" - }, - { - "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", - "component": "lib:ed25519", - "flags": [ - "+no-donna", - "+test-doctests", - "+test-hlint", - "+test-properties" - ], - "package": "ed25519", - "revision": 8, - "source": "hackage", - "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", - "version": "0.0.5.0" - }, - { - "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", - "component": "lib:lukko", - "flags": [ - "+ofd-locking" - ], - "package": "lukko", - "revision": 0, - "source": "hackage", - "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", - "version": "0.1.2" - }, - { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", - "component": "lib:tar-internal", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", - "version": "0.6.3.0" - }, - { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", - "component": "lib:tar", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", - "version": "0.6.3.0" - }, - { - "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", - "component": "lib:zlib", - "flags": [ - "-bundled-c-zlib", - "+non-blocking-ffi", - "-pkg-config" - ], - "package": "zlib", - "revision": 0, - "source": "hackage", - "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", - "version": "0.7.1.0" - }, - { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", - "component": "lib:hackage-security", - "flags": [ - "+cabal-syntax", - "+lukko" - ], - "package": "hackage-security", - "revision": 1, - "source": "hackage", - "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", - "version": "0.6.2.6" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "lib:open-browser", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - }, - { - "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", - "component": "lib:regex-base", - "flags": [], - "package": "regex-base", - "revision": 4, - "source": "hackage", - "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", - "version": "0.94.0.2" - }, - { - "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", - "component": "lib:regex-posix", - "flags": [ - "-_regex-posix-clib" - ], - "package": "regex-posix", - "revision": 3, - "source": "hackage", - "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", - "version": "0.96.0.1" - }, - { - "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", - "component": "lib:resolv", - "flags": [], - "package": "resolv", - "revision": 3, - "source": "hackage", - "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", - "version": "0.2.0.2" - }, - { - "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", - "component": "lib:safe-exceptions", - "flags": [], - "package": "safe-exceptions", - "revision": 1, - "source": "hackage", - "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", - "version": "0.1.7.4" - }, - { - "cabal_sha256": "2de5218cef72b8ef090bd7d0fd930ffa143242a120c62e013b5cf039858f1855", - "component": "lib:semaphore-compat", - "flags": [], - "package": "semaphore-compat", - "revision": 3, - "source": "hackage", - "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", - "version": "1.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "exe:cabal", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "exe:example", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - } - ] + "builtin": [ + { + "package": "rts", + "version": "1.0.2" + }, + { + "package": "ghc-prim", + "version": "0.8.0" + }, + { + "package": "ghc-bignum", + "version": "1.2" + }, + { + "package": "base", + "version": "4.16.4.0" + }, + { + "package": "array", + "version": "0.5.4.0" + }, + { + "package": "deepseq", + "version": "1.4.6.1" + }, + { + "package": "containers", + "version": "0.6.5.1" + }, + { + "package": "ghc-boot-th", + "version": "9.2.8" + }, + { + "package": "pretty", + "version": "1.1.3.6" + }, + { + "package": "template-haskell", + "version": "2.18.0.0" + }, + { + "package": "bytestring", + "version": "0.11.4.0" + }, + { + "package": "transformers", + "version": "0.5.6.2" + }, + { + "package": "mtl", + "version": "2.2.2" + }, + { + "package": "stm", + "version": "2.5.0.2" + }, + { + "package": "exceptions", + "version": "0.10.4" + }, + { + "package": "time", + "version": "1.11.1.1" + }, + { + "package": "binary", + "version": "0.8.9.0" + }, + { + "package": "text", + "version": "1.2.5.0" + }, + { + "package": "parsec", + "version": "3.1.15.0" + } + ], + "dependencies": [ + { + "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", + "component": "lib:os-string", + "flags": [], + "package": "os-string", + "revision": 0, + "source": "hackage", + "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", + "version": "2.0.3" + }, + { + "cabal_sha256": "8af7a843cba7eddc8d44ae94002b766ee8c23cbcd3ecdb2cc79ee6e0a694419a", + "component": "lib:filepath", + "flags": [ + "-cpphs" + ], + "package": "filepath", + "revision": 1, + "source": "hackage", + "src_sha256": "d2606db4fa8517932a2d9ea6415c365da4d1794afcb264a5b3c10110123978a7", + "version": "1.5.2.0" + }, + { + "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", + "component": "lib:unix", + "flags": [ + "+os-string" + ], + "package": "unix", + "revision": 0, + "source": "hackage", + "src_sha256": "5ab6c346aef2eb9bf80b4d29ca7e22063fc23e52fd69fbc4d18a9f98b154e424", + "version": "2.8.5.1" + }, + { + "cabal_sha256": "fbeec9ec346e5272167f63dcb86af513b457a7b9fc36dc818e4c7b81608d612b", + "component": "lib:directory", + "flags": [ + "+os-string" + ], + "package": "directory", + "revision": 0, + "source": "hackage", + "src_sha256": "e864ed54ddfc6e15d2eb02c87f4be8edd7719e1f9cea13e0f86909400b6ea768", + "version": "1.3.8.5" + }, + { + "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", + "component": "exe:alex", + "flags": [], + "package": "alex", + "revision": 0, + "source": "hackage", + "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", + "version": "3.5.1.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-syntax", + "flags": [], + "package": "Cabal-syntax", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "2a9393de33f18415fb8f4826957a87a94ffe8840ca8472a9b69dca6de45aca03", + "component": "lib:process", + "flags": [], + "package": "process", + "revision": 1, + "source": "hackage", + "src_sha256": "cefda221c3009fa2316b5cf148215cb340dad7eb8503f22e49e33722559df99a", + "version": "1.6.20.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal", + "flags": [], + "package": "Cabal", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-hooks", + "flags": [], + "package": "Cabal-hooks", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "0.1" + }, + { + "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", + "component": "exe:hsc2hs", + "flags": [ + "-in-ghc-tree" + ], + "package": "hsc2hs", + "revision": 2, + "source": "hackage", + "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", + "version": "0.68.10" + }, + { + "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", + "component": "lib:network", + "flags": [ + "-devel" + ], + "package": "network", + "revision": 0, + "source": "hackage", + "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", + "version": "3.2.0.0" + }, + { + "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", + "component": "lib:th-compat", + "flags": [], + "package": "th-compat", + "revision": 2, + "source": "hackage", + "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", + "version": "0.1.5" + }, + { + "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", + "component": "lib:network-uri", + "flags": [], + "package": "network-uri", + "revision": 1, + "source": "hackage", + "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", + "version": "2.6.4.2" + }, + { + "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", + "component": "lib:HTTP", + "flags": [ + "-conduit10", + "+network-uri", + "-warn-as-error", + "-warp-tests" + ], + "package": "HTTP", + "revision": 4, + "source": "hackage", + "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", + "version": "4000.4.1" + }, + { + "cabal_sha256": "a4a1975fde77e289b605c45a3ef78d731d8c1834e4cef311152d910a1e94d98c", + "component": "lib:data-array-byte", + "flags": [], + "package": "data-array-byte", + "revision": 3, + "source": "hackage", + "src_sha256": "1bb6eca0b3e02d057fe7f4e14c81ef395216f421ab30fdaa1b18017c9c025600", + "version": "0.1.0.1" + }, + { + "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", + "component": "lib:hashable", + "flags": [ + "-arch-native", + "+integer-gmp", + "-random-initial-seed" + ], + "package": "hashable", + "revision": 0, + "source": "hackage", + "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", + "version": "1.4.6.0" + }, + { + "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", + "component": "lib:async", + "flags": [ + "-bench" + ], + "package": "async", + "revision": 1, + "source": "hackage", + "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", + "version": "2.2.5" + }, + { + "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", + "component": "lib:base16-bytestring", + "flags": [], + "package": "base16-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", + "version": "1.0.2.0" + }, + { + "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", + "component": "lib:base64-bytestring", + "flags": [], + "package": "base64-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", + "version": "1.2.1.0" + }, + { + "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", + "component": "lib:splitmix", + "flags": [ + "-optimised-mixer" + ], + "package": "splitmix", + "revision": 1, + "source": "hackage", + "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", + "version": "0.1.0.5" + }, + { + "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", + "component": "lib:random", + "flags": [], + "package": "random", + "revision": 0, + "source": "hackage", + "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", + "version": "1.2.1.2" + }, + { + "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", + "component": "lib:edit-distance", + "flags": [], + "package": "edit-distance", + "revision": 1, + "source": "hackage", + "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", + "version": "0.2.2.1" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install-solver", + "flags": [ + "-debug-expensive-assertions", + "-debug-tracetree" + ], + "package": "cabal-install-solver", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", + "component": "lib:cryptohash-sha256", + "flags": [ + "-exe", + "+use-cbits" + ], + "package": "cryptohash-sha256", + "revision": 4, + "source": "hackage", + "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", + "version": "0.11.102.1" + }, + { + "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", + "component": "lib:echo", + "flags": [ + "-example" + ], + "package": "echo", + "revision": 0, + "source": "hackage", + "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", + "version": "0.1.4" + }, + { + "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", + "component": "lib:ed25519", + "flags": [ + "+no-donna", + "+test-doctests", + "+test-hlint", + "+test-properties" + ], + "package": "ed25519", + "revision": 8, + "source": "hackage", + "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", + "version": "0.0.5.0" + }, + { + "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", + "component": "lib:lukko", + "flags": [ + "+ofd-locking" + ], + "package": "lukko", + "revision": 0, + "source": "hackage", + "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", + "version": "0.1.2" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar-internal", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", + "component": "lib:zlib", + "flags": [ + "-bundled-c-zlib", + "+non-blocking-ffi", + "+pkg-config" + ], + "package": "zlib", + "revision": 0, + "source": "hackage", + "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", + "version": "0.7.1.0" + }, + { + "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", + "component": "lib:hackage-security", + "flags": [ + "+cabal-syntax", + "+lukko" + ], + "package": "hackage-security", + "revision": 1, + "source": "hackage", + "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", + "version": "0.6.2.6" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "lib:open-browser", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + }, + { + "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", + "component": "lib:regex-base", + "flags": [], + "package": "regex-base", + "revision": 4, + "source": "hackage", + "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", + "version": "0.94.0.2" + }, + { + "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", + "component": "lib:regex-posix", + "flags": [ + "-_regex-posix-clib" + ], + "package": "regex-posix", + "revision": 3, + "source": "hackage", + "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", + "version": "0.96.0.1" + }, + { + "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", + "component": "lib:resolv", + "flags": [], + "package": "resolv", + "revision": 3, + "source": "hackage", + "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", + "version": "0.2.0.2" + }, + { + "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", + "component": "lib:safe-exceptions", + "flags": [], + "package": "safe-exceptions", + "revision": 1, + "source": "hackage", + "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", + "version": "0.1.7.4" + }, + { + "cabal_sha256": "2de5218cef72b8ef090bd7d0fd930ffa143242a120c62e013b5cf039858f1855", + "component": "lib:semaphore-compat", + "flags": [], + "package": "semaphore-compat", + "revision": 3, + "source": "hackage", + "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", + "version": "1.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "exe:cabal", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "exe:example", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + } + ] } diff --git a/bootstrap/linux-9.4.8.json b/bootstrap/linux-9.4.8.json index 901a3071b55..aa97cbabe35 100644 --- a/bootstrap/linux-9.4.8.json +++ b/bootstrap/linux-9.4.8.json @@ -1,525 +1,525 @@ { - "builtin": [ - { - "package": "rts", - "version": "1.0.2" - }, - { - "package": "ghc-prim", - "version": "0.9.1" - }, - { - "package": "ghc-bignum", - "version": "1.3" - }, - { - "package": "base", - "version": "4.17.2.1" - }, - { - "package": "array", - "version": "0.5.4.0" - }, - { - "package": "deepseq", - "version": "1.4.8.0" - }, - { - "package": "ghc-boot-th", - "version": "9.4.8" - }, - { - "package": "pretty", - "version": "1.1.3.6" - }, - { - "package": "template-haskell", - "version": "2.19.0.0" - }, - { - "package": "containers", - "version": "0.6.7" - }, - { - "package": "bytestring", - "version": "0.11.5.3" - }, - { - "package": "transformers", - "version": "0.5.6.2" - }, - { - "package": "mtl", - "version": "2.2.2" - }, - { - "package": "stm", - "version": "2.5.1.0" - }, - { - "package": "exceptions", - "version": "0.10.5" - }, - { - "package": "time", - "version": "1.12.2" - }, - { - "package": "binary", - "version": "0.8.9.1" - }, - { - "package": "text", - "version": "2.0.2" - }, - { - "package": "parsec", - "version": "3.1.16.1" - } - ], - "dependencies": [ - { - "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", - "component": "lib:os-string", - "flags": [], - "package": "os-string", - "revision": 0, - "source": "hackage", - "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", - "version": "2.0.3" - }, - { - "cabal_sha256": "8af7a843cba7eddc8d44ae94002b766ee8c23cbcd3ecdb2cc79ee6e0a694419a", - "component": "lib:filepath", - "flags": [ - "-cpphs" - ], - "package": "filepath", - "revision": 1, - "source": "hackage", - "src_sha256": "d2606db4fa8517932a2d9ea6415c365da4d1794afcb264a5b3c10110123978a7", - "version": "1.5.2.0" - }, - { - "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", - "component": "lib:unix", - "flags": [ - "+os-string" - ], - "package": "unix", - "revision": 0, - "source": "hackage", - "src_sha256": "5ab6c346aef2eb9bf80b4d29ca7e22063fc23e52fd69fbc4d18a9f98b154e424", - "version": "2.8.5.1" - }, - { - "cabal_sha256": "fbeec9ec346e5272167f63dcb86af513b457a7b9fc36dc818e4c7b81608d612b", - "component": "lib:directory", - "flags": [ - "+os-string" - ], - "package": "directory", - "revision": 0, - "source": "hackage", - "src_sha256": "e864ed54ddfc6e15d2eb02c87f4be8edd7719e1f9cea13e0f86909400b6ea768", - "version": "1.3.8.5" - }, - { - "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", - "component": "exe:alex", - "flags": [], - "package": "alex", - "revision": 0, - "source": "hackage", - "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", - "version": "3.5.1.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-syntax", - "flags": [], - "package": "Cabal-syntax", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "2a9393de33f18415fb8f4826957a87a94ffe8840ca8472a9b69dca6de45aca03", - "component": "lib:process", - "flags": [], - "package": "process", - "revision": 1, - "source": "hackage", - "src_sha256": "cefda221c3009fa2316b5cf148215cb340dad7eb8503f22e49e33722559df99a", - "version": "1.6.20.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal", - "flags": [], - "package": "Cabal", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-hooks", - "flags": [], - "package": "Cabal-hooks", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "0.1" - }, - { - "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", - "component": "exe:hsc2hs", - "flags": [ - "-in-ghc-tree" - ], - "package": "hsc2hs", - "revision": 2, - "source": "hackage", - "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", - "version": "0.68.10" - }, - { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", - "component": "lib:network", - "flags": [ - "-devel" - ], - "package": "network", - "revision": 0, - "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" - }, - { - "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", - "component": "lib:th-compat", - "flags": [], - "package": "th-compat", - "revision": 2, - "source": "hackage", - "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", - "version": "0.1.5" - }, - { - "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", - "component": "lib:network-uri", - "flags": [], - "package": "network-uri", - "revision": 1, - "source": "hackage", - "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", - "version": "2.6.4.2" - }, - { - "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", - "component": "lib:HTTP", - "flags": [ - "-conduit10", - "+network-uri", - "-warn-as-error", - "-warp-tests" - ], - "package": "HTTP", - "revision": 4, - "source": "hackage", - "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", - "version": "4000.4.1" - }, - { - "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", - "component": "lib:hashable", - "flags": [ - "+arch-native", - "+integer-gmp", - "-random-initial-seed" - ], - "package": "hashable", - "revision": 0, - "source": "hackage", - "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", - "version": "1.4.6.0" - }, - { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", - "component": "lib:async", - "flags": [ - "-bench" - ], - "package": "async", - "revision": 1, - "source": "hackage", - "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", - "version": "2.2.5" - }, - { - "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", - "component": "lib:base16-bytestring", - "flags": [], - "package": "base16-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", - "version": "1.0.2.0" - }, - { - "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", - "component": "lib:base64-bytestring", - "flags": [], - "package": "base64-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", - "version": "1.2.1.0" - }, - { - "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", - "component": "lib:splitmix", - "flags": [ - "-optimised-mixer" - ], - "package": "splitmix", - "revision": 1, - "source": "hackage", - "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", - "version": "0.1.0.5" - }, - { - "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", - "component": "lib:random", - "flags": [], - "package": "random", - "revision": 0, - "source": "hackage", - "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", - "version": "1.2.1.2" - }, - { - "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", - "component": "lib:edit-distance", - "flags": [], - "package": "edit-distance", - "revision": 1, - "source": "hackage", - "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", - "version": "0.2.2.1" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install-solver", - "flags": [ - "-debug-expensive-assertions", - "-debug-tracetree" - ], - "package": "cabal-install-solver", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", - "component": "lib:cryptohash-sha256", - "flags": [ - "-exe", - "+use-cbits" - ], - "package": "cryptohash-sha256", - "revision": 4, - "source": "hackage", - "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", - "version": "0.11.102.1" - }, - { - "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", - "component": "lib:echo", - "flags": [ - "-example" - ], - "package": "echo", - "revision": 0, - "source": "hackage", - "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", - "version": "0.1.4" - }, - { - "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", - "component": "lib:ed25519", - "flags": [ - "+no-donna", - "+test-doctests", - "+test-hlint", - "+test-properties" - ], - "package": "ed25519", - "revision": 8, - "source": "hackage", - "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", - "version": "0.0.5.0" - }, - { - "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", - "component": "lib:lukko", - "flags": [ - "+ofd-locking" - ], - "package": "lukko", - "revision": 0, - "source": "hackage", - "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", - "version": "0.1.2" - }, - { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", - "component": "lib:tar-internal", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", - "version": "0.6.3.0" - }, - { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", - "component": "lib:tar", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", - "version": "0.6.3.0" - }, - { - "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", - "component": "lib:zlib", - "flags": [ - "-bundled-c-zlib", - "+non-blocking-ffi", - "-pkg-config" - ], - "package": "zlib", - "revision": 0, - "source": "hackage", - "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", - "version": "0.7.1.0" - }, - { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", - "component": "lib:hackage-security", - "flags": [ - "+cabal-syntax", - "+lukko" - ], - "package": "hackage-security", - "revision": 1, - "source": "hackage", - "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", - "version": "0.6.2.6" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "lib:open-browser", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - }, - { - "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", - "component": "lib:regex-base", - "flags": [], - "package": "regex-base", - "revision": 4, - "source": "hackage", - "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", - "version": "0.94.0.2" - }, - { - "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", - "component": "lib:regex-posix", - "flags": [ - "-_regex-posix-clib" - ], - "package": "regex-posix", - "revision": 3, - "source": "hackage", - "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", - "version": "0.96.0.1" - }, - { - "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", - "component": "lib:resolv", - "flags": [], - "package": "resolv", - "revision": 3, - "source": "hackage", - "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", - "version": "0.2.0.2" - }, - { - "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", - "component": "lib:safe-exceptions", - "flags": [], - "package": "safe-exceptions", - "revision": 1, - "source": "hackage", - "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", - "version": "0.1.7.4" - }, - { - "cabal_sha256": "2de5218cef72b8ef090bd7d0fd930ffa143242a120c62e013b5cf039858f1855", - "component": "lib:semaphore-compat", - "flags": [], - "package": "semaphore-compat", - "revision": 3, - "source": "hackage", - "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", - "version": "1.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "exe:cabal", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "exe:example", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - } - ] + "builtin": [ + { + "package": "rts", + "version": "1.0.2" + }, + { + "package": "ghc-prim", + "version": "0.9.1" + }, + { + "package": "ghc-bignum", + "version": "1.3" + }, + { + "package": "base", + "version": "4.17.2.1" + }, + { + "package": "array", + "version": "0.5.4.0" + }, + { + "package": "deepseq", + "version": "1.4.8.0" + }, + { + "package": "ghc-boot-th", + "version": "9.4.8" + }, + { + "package": "pretty", + "version": "1.1.3.6" + }, + { + "package": "template-haskell", + "version": "2.19.0.0" + }, + { + "package": "containers", + "version": "0.6.7" + }, + { + "package": "bytestring", + "version": "0.11.5.3" + }, + { + "package": "transformers", + "version": "0.5.6.2" + }, + { + "package": "mtl", + "version": "2.2.2" + }, + { + "package": "stm", + "version": "2.5.1.0" + }, + { + "package": "exceptions", + "version": "0.10.5" + }, + { + "package": "time", + "version": "1.12.2" + }, + { + "package": "binary", + "version": "0.8.9.1" + }, + { + "package": "text", + "version": "2.0.2" + }, + { + "package": "parsec", + "version": "3.1.16.1" + } + ], + "dependencies": [ + { + "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", + "component": "lib:os-string", + "flags": [], + "package": "os-string", + "revision": 0, + "source": "hackage", + "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", + "version": "2.0.3" + }, + { + "cabal_sha256": "8af7a843cba7eddc8d44ae94002b766ee8c23cbcd3ecdb2cc79ee6e0a694419a", + "component": "lib:filepath", + "flags": [ + "-cpphs" + ], + "package": "filepath", + "revision": 1, + "source": "hackage", + "src_sha256": "d2606db4fa8517932a2d9ea6415c365da4d1794afcb264a5b3c10110123978a7", + "version": "1.5.2.0" + }, + { + "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", + "component": "lib:unix", + "flags": [ + "+os-string" + ], + "package": "unix", + "revision": 0, + "source": "hackage", + "src_sha256": "5ab6c346aef2eb9bf80b4d29ca7e22063fc23e52fd69fbc4d18a9f98b154e424", + "version": "2.8.5.1" + }, + { + "cabal_sha256": "fbeec9ec346e5272167f63dcb86af513b457a7b9fc36dc818e4c7b81608d612b", + "component": "lib:directory", + "flags": [ + "+os-string" + ], + "package": "directory", + "revision": 0, + "source": "hackage", + "src_sha256": "e864ed54ddfc6e15d2eb02c87f4be8edd7719e1f9cea13e0f86909400b6ea768", + "version": "1.3.8.5" + }, + { + "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", + "component": "exe:alex", + "flags": [], + "package": "alex", + "revision": 0, + "source": "hackage", + "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", + "version": "3.5.1.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-syntax", + "flags": [], + "package": "Cabal-syntax", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "2a9393de33f18415fb8f4826957a87a94ffe8840ca8472a9b69dca6de45aca03", + "component": "lib:process", + "flags": [], + "package": "process", + "revision": 1, + "source": "hackage", + "src_sha256": "cefda221c3009fa2316b5cf148215cb340dad7eb8503f22e49e33722559df99a", + "version": "1.6.20.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal", + "flags": [], + "package": "Cabal", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-hooks", + "flags": [], + "package": "Cabal-hooks", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "0.1" + }, + { + "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", + "component": "exe:hsc2hs", + "flags": [ + "-in-ghc-tree" + ], + "package": "hsc2hs", + "revision": 2, + "source": "hackage", + "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", + "version": "0.68.10" + }, + { + "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", + "component": "lib:network", + "flags": [ + "-devel" + ], + "package": "network", + "revision": 0, + "source": "hackage", + "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", + "version": "3.2.0.0" + }, + { + "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", + "component": "lib:th-compat", + "flags": [], + "package": "th-compat", + "revision": 2, + "source": "hackage", + "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", + "version": "0.1.5" + }, + { + "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", + "component": "lib:network-uri", + "flags": [], + "package": "network-uri", + "revision": 1, + "source": "hackage", + "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", + "version": "2.6.4.2" + }, + { + "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", + "component": "lib:HTTP", + "flags": [ + "-conduit10", + "+network-uri", + "-warn-as-error", + "-warp-tests" + ], + "package": "HTTP", + "revision": 4, + "source": "hackage", + "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", + "version": "4000.4.1" + }, + { + "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", + "component": "lib:hashable", + "flags": [ + "-arch-native", + "+integer-gmp", + "-random-initial-seed" + ], + "package": "hashable", + "revision": 0, + "source": "hackage", + "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", + "version": "1.4.6.0" + }, + { + "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", + "component": "lib:async", + "flags": [ + "-bench" + ], + "package": "async", + "revision": 1, + "source": "hackage", + "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", + "version": "2.2.5" + }, + { + "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", + "component": "lib:base16-bytestring", + "flags": [], + "package": "base16-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", + "version": "1.0.2.0" + }, + { + "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", + "component": "lib:base64-bytestring", + "flags": [], + "package": "base64-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", + "version": "1.2.1.0" + }, + { + "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", + "component": "lib:splitmix", + "flags": [ + "-optimised-mixer" + ], + "package": "splitmix", + "revision": 1, + "source": "hackage", + "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", + "version": "0.1.0.5" + }, + { + "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", + "component": "lib:random", + "flags": [], + "package": "random", + "revision": 0, + "source": "hackage", + "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", + "version": "1.2.1.2" + }, + { + "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", + "component": "lib:edit-distance", + "flags": [], + "package": "edit-distance", + "revision": 1, + "source": "hackage", + "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", + "version": "0.2.2.1" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install-solver", + "flags": [ + "-debug-expensive-assertions", + "-debug-tracetree" + ], + "package": "cabal-install-solver", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", + "component": "lib:cryptohash-sha256", + "flags": [ + "-exe", + "+use-cbits" + ], + "package": "cryptohash-sha256", + "revision": 4, + "source": "hackage", + "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", + "version": "0.11.102.1" + }, + { + "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", + "component": "lib:echo", + "flags": [ + "-example" + ], + "package": "echo", + "revision": 0, + "source": "hackage", + "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", + "version": "0.1.4" + }, + { + "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", + "component": "lib:ed25519", + "flags": [ + "+no-donna", + "+test-doctests", + "+test-hlint", + "+test-properties" + ], + "package": "ed25519", + "revision": 8, + "source": "hackage", + "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", + "version": "0.0.5.0" + }, + { + "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", + "component": "lib:lukko", + "flags": [ + "+ofd-locking" + ], + "package": "lukko", + "revision": 0, + "source": "hackage", + "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", + "version": "0.1.2" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar-internal", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", + "component": "lib:zlib", + "flags": [ + "-bundled-c-zlib", + "+non-blocking-ffi", + "+pkg-config" + ], + "package": "zlib", + "revision": 0, + "source": "hackage", + "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", + "version": "0.7.1.0" + }, + { + "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", + "component": "lib:hackage-security", + "flags": [ + "+cabal-syntax", + "+lukko" + ], + "package": "hackage-security", + "revision": 1, + "source": "hackage", + "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", + "version": "0.6.2.6" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "lib:open-browser", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + }, + { + "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", + "component": "lib:regex-base", + "flags": [], + "package": "regex-base", + "revision": 4, + "source": "hackage", + "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", + "version": "0.94.0.2" + }, + { + "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", + "component": "lib:regex-posix", + "flags": [ + "-_regex-posix-clib" + ], + "package": "regex-posix", + "revision": 3, + "source": "hackage", + "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", + "version": "0.96.0.1" + }, + { + "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", + "component": "lib:resolv", + "flags": [], + "package": "resolv", + "revision": 3, + "source": "hackage", + "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", + "version": "0.2.0.2" + }, + { + "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", + "component": "lib:safe-exceptions", + "flags": [], + "package": "safe-exceptions", + "revision": 1, + "source": "hackage", + "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", + "version": "0.1.7.4" + }, + { + "cabal_sha256": "2de5218cef72b8ef090bd7d0fd930ffa143242a120c62e013b5cf039858f1855", + "component": "lib:semaphore-compat", + "flags": [], + "package": "semaphore-compat", + "revision": 3, + "source": "hackage", + "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", + "version": "1.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "exe:cabal", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "exe:example", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + } + ] } diff --git a/bootstrap/linux-9.6.4.json b/bootstrap/linux-9.6.4.json index 8edfb255f49..c0c138d5110 100644 --- a/bootstrap/linux-9.6.4.json +++ b/bootstrap/linux-9.6.4.json @@ -1,495 +1,495 @@ { - "builtin": [ - { - "package": "rts", - "version": "1.0.2" - }, - { - "package": "ghc-prim", - "version": "0.10.0" - }, - { - "package": "ghc-bignum", - "version": "1.3" - }, - { - "package": "base", - "version": "4.18.2.0" - }, - { - "package": "array", - "version": "0.5.6.0" - }, - { - "package": "deepseq", - "version": "1.4.8.1" - }, - { - "package": "ghc-boot-th", - "version": "9.6.4" - }, - { - "package": "pretty", - "version": "1.1.3.6" - }, - { - "package": "template-haskell", - "version": "2.20.0.0" - }, - { - "package": "containers", - "version": "0.6.7" - }, - { - "package": "bytestring", - "version": "0.11.5.3" - }, - { - "package": "transformers", - "version": "0.6.1.0" - }, - { - "package": "mtl", - "version": "2.3.1" - }, - { - "package": "stm", - "version": "2.5.1.0" - }, - { - "package": "exceptions", - "version": "0.10.7" - }, - { - "package": "filepath", - "version": "1.4.200.1" - }, - { - "package": "time", - "version": "1.12.2" - }, - { - "package": "unix", - "version": "2.8.4.0" - }, - { - "package": "directory", - "version": "1.3.8.1" - }, - { - "package": "binary", - "version": "0.8.9.1" - }, - { - "package": "text", - "version": "2.0.2" - }, - { - "package": "parsec", - "version": "3.1.16.1" - }, - { - "package": "process", - "version": "1.6.17.0" - } - ], - "dependencies": [ - { - "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", - "component": "exe:alex", - "flags": [], - "package": "alex", - "revision": 0, - "source": "hackage", - "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", - "version": "3.5.1.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-syntax", - "flags": [], - "package": "Cabal-syntax", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal", - "flags": [], - "package": "Cabal", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-hooks", - "flags": [], - "package": "Cabal-hooks", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "0.1" - }, - { - "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", - "component": "exe:hsc2hs", - "flags": [ - "-in-ghc-tree" - ], - "package": "hsc2hs", - "revision": 2, - "source": "hackage", - "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", - "version": "0.68.10" - }, - { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", - "component": "lib:network", - "flags": [ - "-devel" - ], - "package": "network", - "revision": 0, - "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" - }, - { - "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", - "component": "lib:th-compat", - "flags": [], - "package": "th-compat", - "revision": 2, - "source": "hackage", - "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", - "version": "0.1.5" - }, - { - "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", - "component": "lib:network-uri", - "flags": [], - "package": "network-uri", - "revision": 1, - "source": "hackage", - "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", - "version": "2.6.4.2" - }, - { - "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", - "component": "lib:HTTP", - "flags": [ - "-conduit10", - "+network-uri", - "-warn-as-error", - "-warp-tests" - ], - "package": "HTTP", - "revision": 4, - "source": "hackage", - "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", - "version": "4000.4.1" - }, - { - "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", - "component": "lib:os-string", - "flags": [], - "package": "os-string", - "revision": 0, - "source": "hackage", - "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", - "version": "2.0.3" - }, - { - "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", - "component": "lib:hashable", - "flags": [ - "+arch-native", - "+integer-gmp", - "-random-initial-seed" - ], - "package": "hashable", - "revision": 0, - "source": "hackage", - "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", - "version": "1.4.6.0" - }, - { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", - "component": "lib:async", - "flags": [ - "-bench" - ], - "package": "async", - "revision": 1, - "source": "hackage", - "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", - "version": "2.2.5" - }, - { - "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", - "component": "lib:base16-bytestring", - "flags": [], - "package": "base16-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", - "version": "1.0.2.0" - }, - { - "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", - "component": "lib:base64-bytestring", - "flags": [], - "package": "base64-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", - "version": "1.2.1.0" - }, - { - "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", - "component": "lib:splitmix", - "flags": [ - "-optimised-mixer" - ], - "package": "splitmix", - "revision": 1, - "source": "hackage", - "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", - "version": "0.1.0.5" - }, - { - "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", - "component": "lib:random", - "flags": [], - "package": "random", - "revision": 0, - "source": "hackage", - "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", - "version": "1.2.1.2" - }, - { - "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", - "component": "lib:edit-distance", - "flags": [], - "package": "edit-distance", - "revision": 1, - "source": "hackage", - "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", - "version": "0.2.2.1" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install-solver", - "flags": [ - "-debug-expensive-assertions", - "-debug-tracetree" - ], - "package": "cabal-install-solver", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", - "component": "lib:cryptohash-sha256", - "flags": [ - "-exe", - "+use-cbits" - ], - "package": "cryptohash-sha256", - "revision": 4, - "source": "hackage", - "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", - "version": "0.11.102.1" - }, - { - "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", - "component": "lib:echo", - "flags": [ - "-example" - ], - "package": "echo", - "revision": 0, - "source": "hackage", - "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", - "version": "0.1.4" - }, - { - "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", - "component": "lib:ed25519", - "flags": [ - "+no-donna", - "+test-doctests", - "+test-hlint", - "+test-properties" - ], - "package": "ed25519", - "revision": 8, - "source": "hackage", - "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", - "version": "0.0.5.0" - }, - { - "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", - "component": "lib:lukko", - "flags": [ - "+ofd-locking" - ], - "package": "lukko", - "revision": 0, - "source": "hackage", - "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", - "version": "0.1.2" - }, - { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", - "component": "lib:tar-internal", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", - "version": "0.6.3.0" - }, - { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", - "component": "lib:tar", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", - "version": "0.6.3.0" - }, - { - "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", - "component": "lib:zlib", - "flags": [ - "-bundled-c-zlib", - "+non-blocking-ffi", - "-pkg-config" - ], - "package": "zlib", - "revision": 0, - "source": "hackage", - "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", - "version": "0.7.1.0" - }, - { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", - "component": "lib:hackage-security", - "flags": [ - "+cabal-syntax", - "+lukko" - ], - "package": "hackage-security", - "revision": 1, - "source": "hackage", - "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", - "version": "0.6.2.6" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "lib:open-browser", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - }, - { - "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", - "component": "lib:regex-base", - "flags": [], - "package": "regex-base", - "revision": 4, - "source": "hackage", - "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", - "version": "0.94.0.2" - }, - { - "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", - "component": "lib:regex-posix", - "flags": [ - "-_regex-posix-clib" - ], - "package": "regex-posix", - "revision": 3, - "source": "hackage", - "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", - "version": "0.96.0.1" - }, - { - "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", - "component": "lib:resolv", - "flags": [], - "package": "resolv", - "revision": 3, - "source": "hackage", - "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", - "version": "0.2.0.2" - }, - { - "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", - "component": "lib:safe-exceptions", - "flags": [], - "package": "safe-exceptions", - "revision": 1, - "source": "hackage", - "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", - "version": "0.1.7.4" - }, - { - "cabal_sha256": "2de5218cef72b8ef090bd7d0fd930ffa143242a120c62e013b5cf039858f1855", - "component": "lib:semaphore-compat", - "flags": [], - "package": "semaphore-compat", - "revision": 3, - "source": "hackage", - "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", - "version": "1.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "exe:cabal", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "exe:example", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - } - ] + "builtin": [ + { + "package": "rts", + "version": "1.0.2" + }, + { + "package": "ghc-prim", + "version": "0.10.0" + }, + { + "package": "ghc-bignum", + "version": "1.3" + }, + { + "package": "base", + "version": "4.18.2.0" + }, + { + "package": "array", + "version": "0.5.6.0" + }, + { + "package": "deepseq", + "version": "1.4.8.1" + }, + { + "package": "ghc-boot-th", + "version": "9.6.4" + }, + { + "package": "pretty", + "version": "1.1.3.6" + }, + { + "package": "template-haskell", + "version": "2.20.0.0" + }, + { + "package": "containers", + "version": "0.6.7" + }, + { + "package": "bytestring", + "version": "0.11.5.3" + }, + { + "package": "transformers", + "version": "0.6.1.0" + }, + { + "package": "mtl", + "version": "2.3.1" + }, + { + "package": "stm", + "version": "2.5.1.0" + }, + { + "package": "exceptions", + "version": "0.10.7" + }, + { + "package": "filepath", + "version": "1.4.200.1" + }, + { + "package": "time", + "version": "1.12.2" + }, + { + "package": "unix", + "version": "2.8.4.0" + }, + { + "package": "directory", + "version": "1.3.8.1" + }, + { + "package": "binary", + "version": "0.8.9.1" + }, + { + "package": "text", + "version": "2.0.2" + }, + { + "package": "parsec", + "version": "3.1.16.1" + }, + { + "package": "process", + "version": "1.6.17.0" + } + ], + "dependencies": [ + { + "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", + "component": "exe:alex", + "flags": [], + "package": "alex", + "revision": 0, + "source": "hackage", + "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", + "version": "3.5.1.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-syntax", + "flags": [], + "package": "Cabal-syntax", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal", + "flags": [], + "package": "Cabal", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-hooks", + "flags": [], + "package": "Cabal-hooks", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "0.1" + }, + { + "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", + "component": "exe:hsc2hs", + "flags": [ + "-in-ghc-tree" + ], + "package": "hsc2hs", + "revision": 2, + "source": "hackage", + "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", + "version": "0.68.10" + }, + { + "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", + "component": "lib:network", + "flags": [ + "-devel" + ], + "package": "network", + "revision": 0, + "source": "hackage", + "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", + "version": "3.2.0.0" + }, + { + "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", + "component": "lib:th-compat", + "flags": [], + "package": "th-compat", + "revision": 2, + "source": "hackage", + "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", + "version": "0.1.5" + }, + { + "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", + "component": "lib:network-uri", + "flags": [], + "package": "network-uri", + "revision": 1, + "source": "hackage", + "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", + "version": "2.6.4.2" + }, + { + "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", + "component": "lib:HTTP", + "flags": [ + "-conduit10", + "+network-uri", + "-warn-as-error", + "-warp-tests" + ], + "package": "HTTP", + "revision": 4, + "source": "hackage", + "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", + "version": "4000.4.1" + }, + { + "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", + "component": "lib:os-string", + "flags": [], + "package": "os-string", + "revision": 0, + "source": "hackage", + "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", + "version": "2.0.3" + }, + { + "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", + "component": "lib:hashable", + "flags": [ + "-arch-native", + "+integer-gmp", + "-random-initial-seed" + ], + "package": "hashable", + "revision": 0, + "source": "hackage", + "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", + "version": "1.4.6.0" + }, + { + "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", + "component": "lib:async", + "flags": [ + "-bench" + ], + "package": "async", + "revision": 1, + "source": "hackage", + "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", + "version": "2.2.5" + }, + { + "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", + "component": "lib:base16-bytestring", + "flags": [], + "package": "base16-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", + "version": "1.0.2.0" + }, + { + "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", + "component": "lib:base64-bytestring", + "flags": [], + "package": "base64-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", + "version": "1.2.1.0" + }, + { + "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", + "component": "lib:splitmix", + "flags": [ + "-optimised-mixer" + ], + "package": "splitmix", + "revision": 1, + "source": "hackage", + "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", + "version": "0.1.0.5" + }, + { + "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", + "component": "lib:random", + "flags": [], + "package": "random", + "revision": 0, + "source": "hackage", + "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", + "version": "1.2.1.2" + }, + { + "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", + "component": "lib:edit-distance", + "flags": [], + "package": "edit-distance", + "revision": 1, + "source": "hackage", + "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", + "version": "0.2.2.1" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install-solver", + "flags": [ + "-debug-expensive-assertions", + "-debug-tracetree" + ], + "package": "cabal-install-solver", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", + "component": "lib:cryptohash-sha256", + "flags": [ + "-exe", + "+use-cbits" + ], + "package": "cryptohash-sha256", + "revision": 4, + "source": "hackage", + "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", + "version": "0.11.102.1" + }, + { + "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", + "component": "lib:echo", + "flags": [ + "-example" + ], + "package": "echo", + "revision": 0, + "source": "hackage", + "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", + "version": "0.1.4" + }, + { + "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", + "component": "lib:ed25519", + "flags": [ + "+no-donna", + "+test-doctests", + "+test-hlint", + "+test-properties" + ], + "package": "ed25519", + "revision": 8, + "source": "hackage", + "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", + "version": "0.0.5.0" + }, + { + "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", + "component": "lib:lukko", + "flags": [ + "+ofd-locking" + ], + "package": "lukko", + "revision": 0, + "source": "hackage", + "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", + "version": "0.1.2" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar-internal", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", + "component": "lib:zlib", + "flags": [ + "-bundled-c-zlib", + "+non-blocking-ffi", + "+pkg-config" + ], + "package": "zlib", + "revision": 0, + "source": "hackage", + "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", + "version": "0.7.1.0" + }, + { + "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", + "component": "lib:hackage-security", + "flags": [ + "+cabal-syntax", + "+lukko" + ], + "package": "hackage-security", + "revision": 1, + "source": "hackage", + "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", + "version": "0.6.2.6" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "lib:open-browser", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + }, + { + "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", + "component": "lib:regex-base", + "flags": [], + "package": "regex-base", + "revision": 4, + "source": "hackage", + "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", + "version": "0.94.0.2" + }, + { + "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", + "component": "lib:regex-posix", + "flags": [ + "-_regex-posix-clib" + ], + "package": "regex-posix", + "revision": 3, + "source": "hackage", + "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", + "version": "0.96.0.1" + }, + { + "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", + "component": "lib:resolv", + "flags": [], + "package": "resolv", + "revision": 3, + "source": "hackage", + "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", + "version": "0.2.0.2" + }, + { + "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", + "component": "lib:safe-exceptions", + "flags": [], + "package": "safe-exceptions", + "revision": 1, + "source": "hackage", + "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", + "version": "0.1.7.4" + }, + { + "cabal_sha256": "2de5218cef72b8ef090bd7d0fd930ffa143242a120c62e013b5cf039858f1855", + "component": "lib:semaphore-compat", + "flags": [], + "package": "semaphore-compat", + "revision": 3, + "source": "hackage", + "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", + "version": "1.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "exe:cabal", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "exe:example", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + } + ] } diff --git a/bootstrap/linux-9.8.2.json b/bootstrap/linux-9.8.2.json index c1cc7a760b0..638ae20adb4 100644 --- a/bootstrap/linux-9.8.2.json +++ b/bootstrap/linux-9.8.2.json @@ -1,489 +1,489 @@ { - "builtin": [ - { - "package": "rts", - "version": "1.0.2" - }, - { - "package": "ghc-prim", - "version": "0.11.0" - }, - { - "package": "ghc-bignum", - "version": "1.3" - }, - { - "package": "base", - "version": "4.19.1.0" - }, - { - "package": "array", - "version": "0.5.6.0" - }, - { - "package": "deepseq", - "version": "1.5.0.0" - }, - { - "package": "ghc-boot-th", - "version": "9.8.2" - }, - { - "package": "pretty", - "version": "1.1.3.6" - }, - { - "package": "template-haskell", - "version": "2.21.0.0" - }, - { - "package": "containers", - "version": "0.6.8" - }, - { - "package": "bytestring", - "version": "0.12.1.0" - }, - { - "package": "transformers", - "version": "0.6.1.0" - }, - { - "package": "mtl", - "version": "2.3.1" - }, - { - "package": "stm", - "version": "2.5.2.1" - }, - { - "package": "exceptions", - "version": "0.10.7" - }, - { - "package": "filepath", - "version": "1.4.200.1" - }, - { - "package": "time", - "version": "1.12.2" - }, - { - "package": "unix", - "version": "2.8.4.0" - }, - { - "package": "directory", - "version": "1.3.8.1" - }, - { - "package": "binary", - "version": "0.8.9.1" - }, - { - "package": "text", - "version": "2.1.1" - }, - { - "package": "parsec", - "version": "3.1.17.0" - }, - { - "package": "process", - "version": "1.6.18.0" - }, - { - "package": "semaphore-compat", - "version": "1.0.0" - } - ], - "dependencies": [ - { - "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", - "component": "exe:alex", - "flags": [], - "package": "alex", - "revision": 0, - "source": "hackage", - "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", - "version": "3.5.1.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-syntax", - "flags": [], - "package": "Cabal-syntax", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal", - "flags": [], - "package": "Cabal", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "lib:Cabal-hooks", - "flags": [], - "package": "Cabal-hooks", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "0.1" - }, - { - "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", - "component": "exe:hsc2hs", - "flags": [ - "-in-ghc-tree" - ], - "package": "hsc2hs", - "revision": 2, - "source": "hackage", - "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", - "version": "0.68.10" - }, - { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", - "component": "lib:network", - "flags": [ - "-devel" - ], - "package": "network", - "revision": 0, - "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" - }, - { - "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", - "component": "lib:th-compat", - "flags": [], - "package": "th-compat", - "revision": 2, - "source": "hackage", - "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", - "version": "0.1.5" - }, - { - "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", - "component": "lib:network-uri", - "flags": [], - "package": "network-uri", - "revision": 1, - "source": "hackage", - "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", - "version": "2.6.4.2" - }, - { - "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", - "component": "lib:HTTP", - "flags": [ - "-conduit10", - "+network-uri", - "-warn-as-error", - "-warp-tests" - ], - "package": "HTTP", - "revision": 4, - "source": "hackage", - "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", - "version": "4000.4.1" - }, - { - "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", - "component": "lib:os-string", - "flags": [], - "package": "os-string", - "revision": 0, - "source": "hackage", - "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", - "version": "2.0.3" - }, - { - "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", - "component": "lib:hashable", - "flags": [ - "+arch-native", - "+integer-gmp", - "-random-initial-seed" - ], - "package": "hashable", - "revision": 0, - "source": "hackage", - "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", - "version": "1.4.6.0" - }, - { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", - "component": "lib:async", - "flags": [ - "-bench" - ], - "package": "async", - "revision": 1, - "source": "hackage", - "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", - "version": "2.2.5" - }, - { - "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", - "component": "lib:base16-bytestring", - "flags": [], - "package": "base16-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", - "version": "1.0.2.0" - }, - { - "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", - "component": "lib:base64-bytestring", - "flags": [], - "package": "base64-bytestring", - "revision": 1, - "source": "hackage", - "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", - "version": "1.2.1.0" - }, - { - "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", - "component": "lib:splitmix", - "flags": [ - "-optimised-mixer" - ], - "package": "splitmix", - "revision": 1, - "source": "hackage", - "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", - "version": "0.1.0.5" - }, - { - "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", - "component": "lib:random", - "flags": [], - "package": "random", - "revision": 0, - "source": "hackage", - "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", - "version": "1.2.1.2" - }, - { - "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", - "component": "lib:edit-distance", - "flags": [], - "package": "edit-distance", - "revision": 1, - "source": "hackage", - "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", - "version": "0.2.2.1" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install-solver", - "flags": [ - "-debug-expensive-assertions", - "-debug-tracetree" - ], - "package": "cabal-install-solver", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", - "component": "lib:cryptohash-sha256", - "flags": [ - "-exe", - "+use-cbits" - ], - "package": "cryptohash-sha256", - "revision": 4, - "source": "hackage", - "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", - "version": "0.11.102.1" - }, - { - "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", - "component": "lib:echo", - "flags": [ - "-example" - ], - "package": "echo", - "revision": 0, - "source": "hackage", - "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", - "version": "0.1.4" - }, - { - "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", - "component": "lib:ed25519", - "flags": [ - "+no-donna", - "+test-doctests", - "+test-hlint", - "+test-properties" - ], - "package": "ed25519", - "revision": 8, - "source": "hackage", - "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", - "version": "0.0.5.0" - }, - { - "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", - "component": "lib:lukko", - "flags": [ - "+ofd-locking" - ], - "package": "lukko", - "revision": 0, - "source": "hackage", - "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", - "version": "0.1.2" - }, - { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", - "component": "lib:tar-internal", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", - "version": "0.6.3.0" - }, - { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", - "component": "lib:tar", - "flags": [], - "package": "tar", - "revision": 0, - "source": "hackage", - "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", - "version": "0.6.3.0" - }, - { - "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", - "component": "lib:zlib", - "flags": [ - "-bundled-c-zlib", - "+non-blocking-ffi", - "-pkg-config" - ], - "package": "zlib", - "revision": 0, - "source": "hackage", - "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", - "version": "0.7.1.0" - }, - { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", - "component": "lib:hackage-security", - "flags": [ - "+cabal-syntax", - "+lukko" - ], - "package": "hackage-security", - "revision": 1, - "source": "hackage", - "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", - "version": "0.6.2.6" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "lib:open-browser", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - }, - { - "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", - "component": "lib:regex-base", - "flags": [], - "package": "regex-base", - "revision": 4, - "source": "hackage", - "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", - "version": "0.94.0.2" - }, - { - "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", - "component": "lib:regex-posix", - "flags": [ - "-_regex-posix-clib" - ], - "package": "regex-posix", - "revision": 3, - "source": "hackage", - "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", - "version": "0.96.0.1" - }, - { - "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", - "component": "lib:resolv", - "flags": [], - "package": "resolv", - "revision": 3, - "source": "hackage", - "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", - "version": "0.2.0.2" - }, - { - "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", - "component": "lib:safe-exceptions", - "flags": [], - "package": "safe-exceptions", - "revision": 1, - "source": "hackage", - "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", - "version": "0.1.7.4" - }, - { - "cabal_sha256": null, - "component": "lib:cabal-install", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": null, - "component": "exe:cabal", - "flags": [ - "+lukko", - "+native-dns" - ], - "package": "cabal-install", - "revision": null, - "source": "local", - "src_sha256": null, - "version": "3.13.0.0" - }, - { - "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", - "component": "exe:example", - "flags": [], - "package": "open-browser", - "revision": 0, - "source": "hackage", - "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", - "version": "0.2.1.0" - } - ] + "builtin": [ + { + "package": "rts", + "version": "1.0.2" + }, + { + "package": "ghc-prim", + "version": "0.11.0" + }, + { + "package": "ghc-bignum", + "version": "1.3" + }, + { + "package": "base", + "version": "4.19.1.0" + }, + { + "package": "array", + "version": "0.5.6.0" + }, + { + "package": "deepseq", + "version": "1.5.0.0" + }, + { + "package": "ghc-boot-th", + "version": "9.8.2" + }, + { + "package": "pretty", + "version": "1.1.3.6" + }, + { + "package": "template-haskell", + "version": "2.21.0.0" + }, + { + "package": "containers", + "version": "0.6.8" + }, + { + "package": "bytestring", + "version": "0.12.1.0" + }, + { + "package": "transformers", + "version": "0.6.1.0" + }, + { + "package": "mtl", + "version": "2.3.1" + }, + { + "package": "stm", + "version": "2.5.2.1" + }, + { + "package": "exceptions", + "version": "0.10.7" + }, + { + "package": "filepath", + "version": "1.4.200.1" + }, + { + "package": "time", + "version": "1.12.2" + }, + { + "package": "unix", + "version": "2.8.4.0" + }, + { + "package": "directory", + "version": "1.3.8.1" + }, + { + "package": "binary", + "version": "0.8.9.1" + }, + { + "package": "text", + "version": "2.1.1" + }, + { + "package": "parsec", + "version": "3.1.17.0" + }, + { + "package": "process", + "version": "1.6.18.0" + }, + { + "package": "semaphore-compat", + "version": "1.0.0" + } + ], + "dependencies": [ + { + "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", + "component": "exe:alex", + "flags": [], + "package": "alex", + "revision": 0, + "source": "hackage", + "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", + "version": "3.5.1.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-syntax", + "flags": [], + "package": "Cabal-syntax", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal", + "flags": [], + "package": "Cabal", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-hooks", + "flags": [], + "package": "Cabal-hooks", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "0.1" + }, + { + "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", + "component": "exe:hsc2hs", + "flags": [ + "-in-ghc-tree" + ], + "package": "hsc2hs", + "revision": 2, + "source": "hackage", + "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", + "version": "0.68.10" + }, + { + "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", + "component": "lib:network", + "flags": [ + "-devel" + ], + "package": "network", + "revision": 0, + "source": "hackage", + "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", + "version": "3.2.0.0" + }, + { + "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", + "component": "lib:th-compat", + "flags": [], + "package": "th-compat", + "revision": 2, + "source": "hackage", + "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", + "version": "0.1.5" + }, + { + "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", + "component": "lib:network-uri", + "flags": [], + "package": "network-uri", + "revision": 1, + "source": "hackage", + "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", + "version": "2.6.4.2" + }, + { + "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", + "component": "lib:HTTP", + "flags": [ + "-conduit10", + "+network-uri", + "-warn-as-error", + "-warp-tests" + ], + "package": "HTTP", + "revision": 4, + "source": "hackage", + "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", + "version": "4000.4.1" + }, + { + "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", + "component": "lib:os-string", + "flags": [], + "package": "os-string", + "revision": 0, + "source": "hackage", + "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", + "version": "2.0.3" + }, + { + "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", + "component": "lib:hashable", + "flags": [ + "-arch-native", + "+integer-gmp", + "-random-initial-seed" + ], + "package": "hashable", + "revision": 0, + "source": "hackage", + "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", + "version": "1.4.6.0" + }, + { + "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", + "component": "lib:async", + "flags": [ + "-bench" + ], + "package": "async", + "revision": 1, + "source": "hackage", + "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", + "version": "2.2.5" + }, + { + "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", + "component": "lib:base16-bytestring", + "flags": [], + "package": "base16-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", + "version": "1.0.2.0" + }, + { + "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", + "component": "lib:base64-bytestring", + "flags": [], + "package": "base64-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", + "version": "1.2.1.0" + }, + { + "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", + "component": "lib:splitmix", + "flags": [ + "-optimised-mixer" + ], + "package": "splitmix", + "revision": 1, + "source": "hackage", + "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", + "version": "0.1.0.5" + }, + { + "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", + "component": "lib:random", + "flags": [], + "package": "random", + "revision": 0, + "source": "hackage", + "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", + "version": "1.2.1.2" + }, + { + "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", + "component": "lib:edit-distance", + "flags": [], + "package": "edit-distance", + "revision": 1, + "source": "hackage", + "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", + "version": "0.2.2.1" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install-solver", + "flags": [ + "-debug-expensive-assertions", + "-debug-tracetree" + ], + "package": "cabal-install-solver", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", + "component": "lib:cryptohash-sha256", + "flags": [ + "-exe", + "+use-cbits" + ], + "package": "cryptohash-sha256", + "revision": 4, + "source": "hackage", + "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", + "version": "0.11.102.1" + }, + { + "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", + "component": "lib:echo", + "flags": [ + "-example" + ], + "package": "echo", + "revision": 0, + "source": "hackage", + "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", + "version": "0.1.4" + }, + { + "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", + "component": "lib:ed25519", + "flags": [ + "+no-donna", + "+test-doctests", + "+test-hlint", + "+test-properties" + ], + "package": "ed25519", + "revision": 8, + "source": "hackage", + "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", + "version": "0.0.5.0" + }, + { + "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", + "component": "lib:lukko", + "flags": [ + "+ofd-locking" + ], + "package": "lukko", + "revision": 0, + "source": "hackage", + "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", + "version": "0.1.2" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar-internal", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "component": "lib:tar", + "flags": [], + "package": "tar", + "revision": 0, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", + "component": "lib:zlib", + "flags": [ + "-bundled-c-zlib", + "+non-blocking-ffi", + "+pkg-config" + ], + "package": "zlib", + "revision": 0, + "source": "hackage", + "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", + "version": "0.7.1.0" + }, + { + "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", + "component": "lib:hackage-security", + "flags": [ + "+cabal-syntax", + "+lukko" + ], + "package": "hackage-security", + "revision": 1, + "source": "hackage", + "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", + "version": "0.6.2.6" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "lib:open-browser", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + }, + { + "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", + "component": "lib:regex-base", + "flags": [], + "package": "regex-base", + "revision": 4, + "source": "hackage", + "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", + "version": "0.94.0.2" + }, + { + "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", + "component": "lib:regex-posix", + "flags": [ + "-_regex-posix-clib" + ], + "package": "regex-posix", + "revision": 3, + "source": "hackage", + "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", + "version": "0.96.0.1" + }, + { + "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", + "component": "lib:resolv", + "flags": [], + "package": "resolv", + "revision": 3, + "source": "hackage", + "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", + "version": "0.2.0.2" + }, + { + "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", + "component": "lib:safe-exceptions", + "flags": [], + "package": "safe-exceptions", + "revision": 1, + "source": "hackage", + "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", + "version": "0.1.7.4" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": null, + "component": "exe:cabal", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.13.0.0" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "exe:example", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + } + ] } diff --git a/cabal.bootstrap.project b/cabal.bootstrap.project index 74c8ca5e47a..5b0c59367af 100644 --- a/cabal.bootstrap.project +++ b/cabal.bootstrap.project @@ -9,4 +9,9 @@ packages: tests: False benchmarks: False +-- This project file is used to generate bootstrap plans, +-- as such we cannot enable "-march=native". +constraints: + hashable -arch-native + index-state: hackage.haskell.org 2024-06-17T00:00:01Z From b5b953cdfeba5707f9cf25f30a5bf63741f63327 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Tue, 9 Jul 2024 10:01:24 +1200 Subject: [PATCH 068/207] New `extra-files` field for neutral sdist files The new `extra-files` field provides a way to specify extra files that should be included in sdist, without adding any other semantics (cf. `extra-source-files` are tracked by `cabal build`). Resolves #8817. --- .../PackageDescription/FieldGrammar.hs | 2 ++ .../Distribution/Types/PackageDescription.hs | 4 ++++ .../Types/PackageDescription/Lens.hs | 4 ++++ .../ParserTests/regressions/Octree-0.5.expr | 3 ++- .../tests/ParserTests/regressions/anynone.expr | 3 ++- .../ParserTests/regressions/big-version.expr | 3 ++- .../regressions/common-conditional.expr | 3 ++- .../tests/ParserTests/regressions/common.expr | 3 ++- .../tests/ParserTests/regressions/common2.expr | 3 ++- .../tests/ParserTests/regressions/common3.expr | 3 ++- .../tests/ParserTests/regressions/elif.expr | 3 ++- .../tests/ParserTests/regressions/elif2.expr | 3 ++- .../ParserTests/regressions/encoding-0.8.expr | 3 ++- .../ParserTests/regressions/generics-sop.expr | 3 ++- .../ParserTests/regressions/hasktorch.expr | 3 ++- .../regressions/hidden-main-lib.expr | 3 ++- .../ParserTests/regressions/indentation.expr | 3 ++- .../ParserTests/regressions/indentation2.expr | 3 ++- .../ParserTests/regressions/indentation3.expr | 3 ++- .../ParserTests/regressions/issue-5055.expr | 3 ++- .../ParserTests/regressions/issue-5846.expr | 3 ++- .../ParserTests/regressions/issue-6083-a.expr | 3 ++- .../ParserTests/regressions/issue-6083-b.expr | 3 ++- .../ParserTests/regressions/issue-6083-c.expr | 3 ++- .../regressions/issue-6083-pkg-pkg.expr | 3 ++- .../ParserTests/regressions/issue-774.expr | 3 ++- .../regressions/jaeger-flamegraph.expr | 3 ++- .../regressions/leading-comma-2.expr | 3 ++- .../ParserTests/regressions/leading-comma.expr | 3 ++- .../tests/ParserTests/regressions/libpq1.expr | 3 ++- .../tests/ParserTests/regressions/libpq2.expr | 3 ++- .../tests/ParserTests/regressions/mixin-1.expr | 3 ++- .../tests/ParserTests/regressions/mixin-2.expr | 3 ++- .../tests/ParserTests/regressions/mixin-3.expr | 3 ++- .../ParserTests/regressions/monad-param.expr | 3 ++- .../regressions/multiple-libs-2.expr | 3 ++- .../ParserTests/regressions/noVersion.expr | 3 ++- .../regressions/nothing-unicode.expr | 3 ++- .../tests/ParserTests/regressions/shake.expr | 3 ++- .../tests/ParserTests/regressions/spdx-1.expr | 3 ++- .../tests/ParserTests/regressions/spdx-2.expr | 3 ++- .../tests/ParserTests/regressions/spdx-3.expr | 3 ++- .../regressions/th-lift-instances.expr | 3 ++- .../ParserTests/regressions/version-sets.expr | 3 ++- .../regressions/wl-pprint-indef.expr | 3 ++- .../UnitTests/Distribution/Utils/Structured.hs | 8 ++++---- .../Distribution/PackageDescription/Check.hs | 15 +++++++++++---- Cabal/src/Distribution/Simple/SrcDist.hs | 4 ++++ .../PackageTests/SDist/T8817/cabal.out | 2 ++ .../PackageTests/SDist/T8817/cabal.project | 1 + .../PackageTests/SDist/T8817/cabal.test.hs | 17 +++++++++++++++++ .../PackageTests/SDist/T8817/pkg/Main.hs | 1 + .../PackageTests/SDist/T8817/pkg/d1/f2.txt | 1 + .../PackageTests/SDist/T8817/pkg/d1/f3.txt | 1 + cabal-testsuite/PackageTests/SDist/T8817/pkg/f1 | 1 + .../PackageTests/SDist/T8817/pkg/t8817.cabal | 11 +++++++++++ changelog.d/issue-8817 | 17 +++++++++++++++++ doc/buildinfo-fields-reference.rst | 8 ++++++++ doc/cabal-package-description-file.rst | 5 +++++ doc/file-format-changelog.rst | 7 +++++++ doc/setup-commands.rst | 3 ++- editors/vim/syntax/cabal.vim | 1 + 62 files changed, 188 insertions(+), 51 deletions(-) create mode 100644 cabal-testsuite/PackageTests/SDist/T8817/cabal.out create mode 100644 cabal-testsuite/PackageTests/SDist/T8817/cabal.project create mode 100644 cabal-testsuite/PackageTests/SDist/T8817/cabal.test.hs create mode 100644 cabal-testsuite/PackageTests/SDist/T8817/pkg/Main.hs create mode 100644 cabal-testsuite/PackageTests/SDist/T8817/pkg/d1/f2.txt create mode 100644 cabal-testsuite/PackageTests/SDist/T8817/pkg/d1/f3.txt create mode 100644 cabal-testsuite/PackageTests/SDist/T8817/pkg/f1 create mode 100644 cabal-testsuite/PackageTests/SDist/T8817/pkg/t8817.cabal create mode 100644 changelog.d/issue-8817 diff --git a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs index 4d9ada935af..49db03ee3c1 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs @@ -143,6 +143,8 @@ packageDescriptionFieldGrammar = <*> monoidalFieldAla "extra-source-files" formatExtraSourceFiles L.extraSrcFiles <*> monoidalFieldAla "extra-tmp-files" (alaList' VCat RelativePathNT) L.extraTmpFiles <*> monoidalFieldAla "extra-doc-files" formatExtraSourceFiles L.extraDocFiles + <*> monoidalFieldAla "extra-files" formatExtraSourceFiles L.extraFiles + ^^^ availableSince CabalSpecV3_14 [] where packageIdentifierGrammar = PackageIdentifier diff --git a/Cabal-syntax/src/Distribution/Types/PackageDescription.hs b/Cabal-syntax/src/Distribution/Types/PackageDescription.hs index a3f1d0c33da..5e64694ac1f 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageDescription.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageDescription.hs @@ -149,6 +149,7 @@ data PackageDescription = PackageDescription , extraSrcFiles :: [RelativePath Pkg File] , extraTmpFiles :: [RelativePath Pkg File] , extraDocFiles :: [RelativePath Pkg File] + , extraFiles :: [RelativePath Pkg File] } deriving (Generic, Show, Read, Eq, Ord, Typeable, Data) @@ -235,6 +236,7 @@ emptyPackageDescription = , extraSrcFiles = [] , extraTmpFiles = [] , extraDocFiles = [] + , extraFiles = [] } -- --------------------------------------------------------------------------- @@ -491,6 +493,7 @@ instance L.HasBuildInfos PackageDescription where a22 a23 a24 + a25 ) = PackageDescription a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 <$> (traverse . L.buildInfo) f x1 -- library @@ -504,3 +507,4 @@ instance L.HasBuildInfos PackageDescription where <*> pure a22 -- extra src files <*> pure a23 -- extra temp files <*> pure a24 -- extra doc files + <*> pure a25 -- extra files diff --git a/Cabal-syntax/src/Distribution/Types/PackageDescription/Lens.hs b/Cabal-syntax/src/Distribution/Types/PackageDescription/Lens.hs index 201b10d859f..5d91e32492c 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageDescription/Lens.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageDescription/Lens.hs @@ -159,6 +159,10 @@ extraDocFiles :: Lens' PackageDescription [RelativePath Pkg File] extraDocFiles f s = fmap (\x -> s{T.extraDocFiles = x}) (f (T.extraDocFiles s)) {-# INLINE extraDocFiles #-} +extraFiles :: Lens' PackageDescription [RelativePath Pkg File] +extraFiles f s = fmap (\x -> s{T.extraFiles = x}) (f (T.extraFiles s)) +{-# INLINE extraFiles #-} + -- | @since 3.0.0.0 allLibraries :: Traversal' PackageDescription Library allLibraries f pd = mk <$> traverse f (T.library pd) <*> traverse f (T.subLibraries pd) diff --git a/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.expr b/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.expr index b3494104aed..04f54ea5d93 100644 --- a/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.expr +++ b/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.expr @@ -66,7 +66,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/anynone.expr b/Cabal-tests/tests/ParserTests/regressions/anynone.expr index 8c9c8879ab4..919f554180a 100644 --- a/Cabal-tests/tests/ParserTests/regressions/anynone.expr +++ b/Cabal-tests/tests/ParserTests/regressions/anynone.expr @@ -32,7 +32,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/big-version.expr b/Cabal-tests/tests/ParserTests/regressions/big-version.expr index d4ef82adf52..c219ac95241 100644 --- a/Cabal-tests/tests/ParserTests/regressions/big-version.expr +++ b/Cabal-tests/tests/ParserTests/regressions/big-version.expr @@ -34,7 +34,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/common-conditional.expr b/Cabal-tests/tests/ParserTests/regressions/common-conditional.expr index 9cacba2b770..8969ff6f5fa 100644 --- a/Cabal-tests/tests/ParserTests/regressions/common-conditional.expr +++ b/Cabal-tests/tests/ParserTests/regressions/common-conditional.expr @@ -44,7 +44,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [ MkPackageFlag { diff --git a/Cabal-tests/tests/ParserTests/regressions/common.expr b/Cabal-tests/tests/ParserTests/regressions/common.expr index 25abadef9e7..e39820ec833 100644 --- a/Cabal-tests/tests/ParserTests/regressions/common.expr +++ b/Cabal-tests/tests/ParserTests/regressions/common.expr @@ -47,7 +47,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/common2.expr b/Cabal-tests/tests/ParserTests/regressions/common2.expr index cd501d11cf2..ae85c83ea2b 100644 --- a/Cabal-tests/tests/ParserTests/regressions/common2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/common2.expr @@ -43,7 +43,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/common3.expr b/Cabal-tests/tests/ParserTests/regressions/common3.expr index fc1fc155c09..5436936b3a2 100644 --- a/Cabal-tests/tests/ParserTests/regressions/common3.expr +++ b/Cabal-tests/tests/ParserTests/regressions/common3.expr @@ -47,7 +47,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/elif.expr b/Cabal-tests/tests/ParserTests/regressions/elif.expr index f17c1e17b88..5bf616b7c15 100644 --- a/Cabal-tests/tests/ParserTests/regressions/elif.expr +++ b/Cabal-tests/tests/ParserTests/regressions/elif.expr @@ -42,7 +42,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/elif2.expr b/Cabal-tests/tests/ParserTests/regressions/elif2.expr index ec01a92a79d..f0ecd6bb111 100644 --- a/Cabal-tests/tests/ParserTests/regressions/elif2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/elif2.expr @@ -42,7 +42,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/encoding-0.8.expr b/Cabal-tests/tests/ParserTests/regressions/encoding-0.8.expr index 0d248029a31..4e45a86b8c4 100644 --- a/Cabal-tests/tests/ParserTests/regressions/encoding-0.8.expr +++ b/Cabal-tests/tests/ParserTests/regressions/encoding-0.8.expr @@ -47,7 +47,8 @@ GenericPackageDescription { SymbolicPath "--", SymbolicPath "--"], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/generics-sop.expr b/Cabal-tests/tests/ParserTests/regressions/generics-sop.expr index 25786cdfad5..60be619bd16 100644 --- a/Cabal-tests/tests/ParserTests/regressions/generics-sop.expr +++ b/Cabal-tests/tests/ParserTests/regressions/generics-sop.expr @@ -123,7 +123,8 @@ GenericPackageDescription { extraSrcFiles = [ SymbolicPath "CHANGELOG.md"], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/hasktorch.expr b/Cabal-tests/tests/ParserTests/regressions/hasktorch.expr index c68fac467e1..7eea76ce8c1 100644 --- a/Cabal-tests/tests/ParserTests/regressions/hasktorch.expr +++ b/Cabal-tests/tests/ParserTests/regressions/hasktorch.expr @@ -54,7 +54,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [ MkPackageFlag { diff --git a/Cabal-tests/tests/ParserTests/regressions/hidden-main-lib.expr b/Cabal-tests/tests/ParserTests/regressions/hidden-main-lib.expr index b51b4adacb2..3e67f519199 100644 --- a/Cabal-tests/tests/ParserTests/regressions/hidden-main-lib.expr +++ b/Cabal-tests/tests/ParserTests/regressions/hidden-main-lib.expr @@ -34,7 +34,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/indentation.expr b/Cabal-tests/tests/ParserTests/regressions/indentation.expr index c97630ddb00..ea8c219ca0a 100644 --- a/Cabal-tests/tests/ParserTests/regressions/indentation.expr +++ b/Cabal-tests/tests/ParserTests/regressions/indentation.expr @@ -44,7 +44,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/indentation2.expr b/Cabal-tests/tests/ParserTests/regressions/indentation2.expr index 605cba525d1..f26c9a4e005 100644 --- a/Cabal-tests/tests/ParserTests/regressions/indentation2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/indentation2.expr @@ -37,7 +37,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/indentation3.expr b/Cabal-tests/tests/ParserTests/regressions/indentation3.expr index 55d0533c3fe..08db6b1fec6 100644 --- a/Cabal-tests/tests/ParserTests/regressions/indentation3.expr +++ b/Cabal-tests/tests/ParserTests/regressions/indentation3.expr @@ -39,7 +39,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr b/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr index 3b5092639e4..03fab0246e4 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr @@ -34,7 +34,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Nothing, diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-5846.expr b/Cabal-tests/tests/ParserTests/regressions/issue-5846.expr index 61a7b7d2ca1..0d031503a53 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-5846.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-5846.expr @@ -32,7 +32,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-6083-a.expr b/Cabal-tests/tests/ParserTests/regressions/issue-6083-a.expr index c9c57785ac6..bbe56f81a5c 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-6083-a.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-6083-a.expr @@ -32,7 +32,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-6083-b.expr b/Cabal-tests/tests/ParserTests/regressions/issue-6083-b.expr index b0ed19062fc..17b9f8319bb 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-6083-b.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-6083-b.expr @@ -32,7 +32,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-6083-c.expr b/Cabal-tests/tests/ParserTests/regressions/issue-6083-c.expr index c901eebc8ce..8db694b7389 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-6083-c.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-6083-c.expr @@ -32,7 +32,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-6083-pkg-pkg.expr b/Cabal-tests/tests/ParserTests/regressions/issue-6083-pkg-pkg.expr index 62ed5fd2fb9..26a3c260959 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-6083-pkg-pkg.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-6083-pkg-pkg.expr @@ -32,7 +32,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-774.expr b/Cabal-tests/tests/ParserTests/regressions/issue-774.expr index 2f58de4eb00..a9b2fc7bcc3 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-774.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-774.expr @@ -41,7 +41,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/jaeger-flamegraph.expr b/Cabal-tests/tests/ParserTests/regressions/jaeger-flamegraph.expr index 9994c9b72c1..fd9b1fa3a28 100644 --- a/Cabal-tests/tests/ParserTests/regressions/jaeger-flamegraph.expr +++ b/Cabal-tests/tests/ParserTests/regressions/jaeger-flamegraph.expr @@ -73,7 +73,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/leading-comma-2.expr b/Cabal-tests/tests/ParserTests/regressions/leading-comma-2.expr index 99f7cddf881..37bb5adfea5 100644 --- a/Cabal-tests/tests/ParserTests/regressions/leading-comma-2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/leading-comma-2.expr @@ -34,7 +34,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/leading-comma.expr b/Cabal-tests/tests/ParserTests/regressions/leading-comma.expr index 441fe75261d..6b31a91ecc4 100644 --- a/Cabal-tests/tests/ParserTests/regressions/leading-comma.expr +++ b/Cabal-tests/tests/ParserTests/regressions/leading-comma.expr @@ -34,7 +34,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/libpq1.expr b/Cabal-tests/tests/ParserTests/regressions/libpq1.expr index 2e0bc309f9f..db39305d20f 100644 --- a/Cabal-tests/tests/ParserTests/regressions/libpq1.expr +++ b/Cabal-tests/tests/ParserTests/regressions/libpq1.expr @@ -111,7 +111,8 @@ GenericPackageDescription { "cbits/noticehandlers.h", SymbolicPath "CHANGELOG.md"], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [ MkPackageFlag { diff --git a/Cabal-tests/tests/ParserTests/regressions/libpq2.expr b/Cabal-tests/tests/ParserTests/regressions/libpq2.expr index b74143af0b9..80b558d0b91 100644 --- a/Cabal-tests/tests/ParserTests/regressions/libpq2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/libpq2.expr @@ -115,7 +115,8 @@ GenericPackageDescription { "cbits/noticehandlers.h", SymbolicPath "CHANGELOG.md"], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [ MkPackageFlag { diff --git a/Cabal-tests/tests/ParserTests/regressions/mixin-1.expr b/Cabal-tests/tests/ParserTests/regressions/mixin-1.expr index 77821302ddf..b8372437dd6 100644 --- a/Cabal-tests/tests/ParserTests/regressions/mixin-1.expr +++ b/Cabal-tests/tests/ParserTests/regressions/mixin-1.expr @@ -32,7 +32,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Nothing, diff --git a/Cabal-tests/tests/ParserTests/regressions/mixin-2.expr b/Cabal-tests/tests/ParserTests/regressions/mixin-2.expr index d8b58ff5a0b..a4d3459be3d 100644 --- a/Cabal-tests/tests/ParserTests/regressions/mixin-2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/mixin-2.expr @@ -32,7 +32,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Nothing, diff --git a/Cabal-tests/tests/ParserTests/regressions/mixin-3.expr b/Cabal-tests/tests/ParserTests/regressions/mixin-3.expr index c0cbfe921ad..2b1d37c79e9 100644 --- a/Cabal-tests/tests/ParserTests/regressions/mixin-3.expr +++ b/Cabal-tests/tests/ParserTests/regressions/mixin-3.expr @@ -32,7 +32,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Nothing, diff --git a/Cabal-tests/tests/ParserTests/regressions/monad-param.expr b/Cabal-tests/tests/ParserTests/regressions/monad-param.expr index e450672e868..aaeb1af1044 100644 --- a/Cabal-tests/tests/ParserTests/regressions/monad-param.expr +++ b/Cabal-tests/tests/ParserTests/regressions/monad-param.expr @@ -42,7 +42,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/multiple-libs-2.expr b/Cabal-tests/tests/ParserTests/regressions/multiple-libs-2.expr index aa7d6954637..dc6371bc75c 100644 --- a/Cabal-tests/tests/ParserTests/regressions/multiple-libs-2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/multiple-libs-2.expr @@ -34,7 +34,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/noVersion.expr b/Cabal-tests/tests/ParserTests/regressions/noVersion.expr index dfe79d768fb..0d5bf636569 100644 --- a/Cabal-tests/tests/ParserTests/regressions/noVersion.expr +++ b/Cabal-tests/tests/ParserTests/regressions/noVersion.expr @@ -34,7 +34,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/nothing-unicode.expr b/Cabal-tests/tests/ParserTests/regressions/nothing-unicode.expr index 2ed17f6d557..f6a8c64a566 100644 --- a/Cabal-tests/tests/ParserTests/regressions/nothing-unicode.expr +++ b/Cabal-tests/tests/ParserTests/regressions/nothing-unicode.expr @@ -44,7 +44,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [ MkPackageFlag { diff --git a/Cabal-tests/tests/ParserTests/regressions/shake.expr b/Cabal-tests/tests/ParserTests/regressions/shake.expr index 4dd37e84de0..560c38e1dc4 100644 --- a/Cabal-tests/tests/ParserTests/regressions/shake.expr +++ b/Cabal-tests/tests/ParserTests/regressions/shake.expr @@ -149,7 +149,8 @@ GenericPackageDescription { extraTmpFiles = [], extraDocFiles = [ SymbolicPath "CHANGES.txt", - SymbolicPath "README.md"]}, + SymbolicPath "README.md"], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [ MkPackageFlag { diff --git a/Cabal-tests/tests/ParserTests/regressions/spdx-1.expr b/Cabal-tests/tests/ParserTests/regressions/spdx-1.expr index ddeaf37cbe4..24f0aff227a 100644 --- a/Cabal-tests/tests/ParserTests/regressions/spdx-1.expr +++ b/Cabal-tests/tests/ParserTests/regressions/spdx-1.expr @@ -33,7 +33,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/spdx-2.expr b/Cabal-tests/tests/ParserTests/regressions/spdx-2.expr index b865b1f31db..992486c3be5 100644 --- a/Cabal-tests/tests/ParserTests/regressions/spdx-2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/spdx-2.expr @@ -37,7 +37,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/spdx-3.expr b/Cabal-tests/tests/ParserTests/regressions/spdx-3.expr index dc8f3f922b9..f38e0b24b30 100644 --- a/Cabal-tests/tests/ParserTests/regressions/spdx-3.expr +++ b/Cabal-tests/tests/ParserTests/regressions/spdx-3.expr @@ -37,7 +37,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.expr b/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.expr index 5e781597f30..fa6fd5ee308 100644 --- a/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.expr +++ b/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.expr @@ -61,7 +61,8 @@ GenericPackageDescription { SymbolicPath ".vim.custom", SymbolicPath "README.md"], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/version-sets.expr b/Cabal-tests/tests/ParserTests/regressions/version-sets.expr index 3244bc1cc45..8983fa4ea73 100644 --- a/Cabal-tests/tests/ParserTests/regressions/version-sets.expr +++ b/Cabal-tests/tests/ParserTests/regressions/version-sets.expr @@ -59,7 +59,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/ParserTests/regressions/wl-pprint-indef.expr b/Cabal-tests/tests/ParserTests/regressions/wl-pprint-indef.expr index 6e718e3e685..a8b4fa3c604 100644 --- a/Cabal-tests/tests/ParserTests/regressions/wl-pprint-indef.expr +++ b/Cabal-tests/tests/ParserTests/regressions/wl-pprint-indef.expr @@ -51,7 +51,8 @@ GenericPackageDescription { dataDir = SymbolicPath ".", extraSrcFiles = [], extraTmpFiles = [], - extraDocFiles = []}, + extraDocFiles = [], + extraFiles = []}, gpdScannedVersion = Nothing, genPackageFlags = [], condLibrary = Just diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs index 0db6844928a..40770290073 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs @@ -31,15 +31,15 @@ md5Check proxy md5Int = structureHash proxy @?= md5FromInteger md5Int md5CheckGenericPackageDescription :: Proxy GenericPackageDescription -> Assertion md5CheckGenericPackageDescription proxy = md5Check proxy #if MIN_VERSION_base(4,19,0) - 0xe28f08e7ac644f836d8b3fe7f9428dcf + 0x3da8883a286b8fbfd9f94790d57cc06e #else - 0x3442058190aa48c2f795b83ee995f702 + 0x245e544da05f50f9dd0339a96ac99860 #endif md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion md5CheckLocalBuildInfo proxy = md5Check proxy #if MIN_VERSION_base(4,19,0) - 0x6809d4d86ae1810f2a032bc90c952b76 + 0x7683c2daece12ba7982e80f860454f47 #else - 0x9409dca80a2e1522b1c3a39356e9aaef + 0xe694b39b10bc861f47ea9c7b926a422a #endif diff --git a/Cabal/src/Distribution/PackageDescription/Check.hs b/Cabal/src/Distribution/PackageDescription/Check.hs index ef97b0d23be..5787dec3b77 100644 --- a/Cabal/src/Distribution/PackageDescription/Check.hs +++ b/Cabal/src/Distribution/PackageDescription/Check.hs @@ -409,6 +409,7 @@ checkPackageDescription extraSrcFiles_ extraTmpFiles_ extraDocFiles_ + extraFiles_ ) = do -- § Sanity checks. checkPackageId package_ @@ -456,6 +457,7 @@ checkPackageDescription mapM_ (checkPath False "extra-source-files" PathKindGlob . getSymbolicPath) extraSrcFiles_ mapM_ (checkPath False "extra-tmp-files" PathKindFile . getSymbolicPath) extraTmpFiles_ mapM_ (checkPath False "extra-doc-files" PathKindGlob . getSymbolicPath) extraDocFiles_ + mapM_ (checkPath False "extra-files" PathKindGlob . getSymbolicPath) extraFiles_ mapM_ (checkPath False "data-files" PathKindGlob . getSymbolicPath) dataFiles_ let rawDataDir = getSymbolicPath dataDir_ checkPath True "data-dir" PathKindDirectory rawDataDir @@ -465,15 +467,17 @@ checkPackageDescription -- § Globs. dataGlobs <- mapM (checkGlob "data-files" . getSymbolicPath) dataFiles_ - extraGlobs <- mapM (checkGlob "extra-source-files" . getSymbolicPath) extraSrcFiles_ + extraSrcGlobs <- mapM (checkGlob "extra-source-files" . getSymbolicPath) extraSrcFiles_ docGlobs <- mapM (checkGlob "extra-doc-files" . getSymbolicPath) extraDocFiles_ + extraGlobs <- mapM (checkGlob "extra-files" . getSymbolicPath) extraFiles_ -- We collect globs to feed them to checkMissingDocs. -- § Missing documentation. checkMissingDocs (catMaybes dataGlobs) - (catMaybes extraGlobs) + (catMaybes extraSrcGlobs) (catMaybes docGlobs) + (catMaybes extraGlobs) -- § Datafield checks. checkSetupBuildInfo setupBuildInfo_ @@ -519,6 +523,7 @@ checkPackageDescription checkCabalFile (packageName pkg) mapM_ (checkGlobFile specVersion_ "." "extra-source-files" . getSymbolicPath) extraSrcFiles_ mapM_ (checkGlobFile specVersion_ "." "extra-doc-files" . getSymbolicPath) extraDocFiles_ + mapM_ (checkGlobFile specVersion_ "." "extra-files" . getSymbolicPath) extraFiles_ mapM_ (checkGlobFile specVersion_ rawDataDir "data-files" . getSymbolicPath) dataFiles_ where checkNull @@ -985,8 +990,9 @@ checkMissingDocs => [Glob] -- data-files globs. -> [Glob] -- extra-source-files globs. -> [Glob] -- extra-doc-files globs. + -> [Glob] -- extra-files globs. -> CheckM m () -checkMissingDocs dgs esgs edgs = do +checkMissingDocs dgs esgs edgs efgs = do extraDocSupport <- (>= CabalSpecV1_18) <$> asksCM ccSpecVersion -- Everything in this block uses CheckPreDistributionOps interface. @@ -1005,9 +1011,10 @@ checkMissingDocs dgs esgs edgs = do rgs <- realGlob dgs res <- realGlob esgs red <- realGlob edgs + ref <- realGlob efgs -- 3. Check if anything in 1. is missing in 2. - let mcs = checkDoc extraDocSupport des (rgs ++ res ++ red) + let mcs = checkDoc extraDocSupport des (rgs ++ res ++ red ++ ref) -- 4. Check if files are present but in the wrong field. let pcsData = checkDocMove extraDocSupport "data-files" des rgs diff --git a/Cabal/src/Distribution/Simple/SrcDist.hs b/Cabal/src/Distribution/Simple/SrcDist.hs index eb9096271ef..67f901bf7fb 100644 --- a/Cabal/src/Distribution/Simple/SrcDist.hs +++ b/Cabal/src/Distribution/Simple/SrcDist.hs @@ -264,6 +264,10 @@ listPackageSources' verbosity rip mbWorkDir pkg_descr pps = $ \filename -> fmap (coerceSymbolicPath . relativeSymbolicPath) <$> matchDirFileGlobWithDie verbosity rip (specVersion pkg_descr) mbWorkDir filename + , -- Extra files. + fmap concat . for (extraFiles pkg_descr) $ \fpath -> + fmap relativeSymbolicPath + <$> matchDirFileGlobWithDie verbosity rip (specVersion pkg_descr) mbWorkDir fpath , -- License file(s). return (map (relativeSymbolicPath . coerceSymbolicPath) $ licenseFiles pkg_descr) , -- Install-include files, without autogen-include files diff --git a/cabal-testsuite/PackageTests/SDist/T8817/cabal.out b/cabal-testsuite/PackageTests/SDist/T8817/cabal.out new file mode 100644 index 00000000000..c99d15276fe --- /dev/null +++ b/cabal-testsuite/PackageTests/SDist/T8817/cabal.out @@ -0,0 +1,2 @@ +# cabal v2-sdist +Wrote tarball sdist to /t8817-0.tar.gz diff --git a/cabal-testsuite/PackageTests/SDist/T8817/cabal.project b/cabal-testsuite/PackageTests/SDist/T8817/cabal.project new file mode 100644 index 00000000000..f69442ca765 --- /dev/null +++ b/cabal-testsuite/PackageTests/SDist/T8817/cabal.project @@ -0,0 +1 @@ +packages: pkg/*.cabal diff --git a/cabal-testsuite/PackageTests/SDist/T8817/cabal.test.hs b/cabal-testsuite/PackageTests/SDist/T8817/cabal.test.hs new file mode 100644 index 00000000000..1fca4955b48 --- /dev/null +++ b/cabal-testsuite/PackageTests/SDist/T8817/cabal.test.hs @@ -0,0 +1,17 @@ +import Test.Cabal.Prelude + +main = cabalTest $ do + tmpdir <- fmap testTmpDir getTestEnv + + cabal "v2-sdist" ["--output-directory", tmpdir, "all"] + + let distTarPath = tmpdir "t8817-0.tar.gz" + distExtractedPath = tmpdir "t8817-0" + + shouldExist distTarPath + + tar ["-xzf", distTarPath] + + shouldExist (distExtractedPath "f1") + shouldExist (distExtractedPath "d1" "f2.txt") + shouldExist (distExtractedPath "d1" "f3.txt") diff --git a/cabal-testsuite/PackageTests/SDist/T8817/pkg/Main.hs b/cabal-testsuite/PackageTests/SDist/T8817/pkg/Main.hs new file mode 100644 index 00000000000..4233a67ecdd --- /dev/null +++ b/cabal-testsuite/PackageTests/SDist/T8817/pkg/Main.hs @@ -0,0 +1 @@ +main = putStrLn "hi" diff --git a/cabal-testsuite/PackageTests/SDist/T8817/pkg/d1/f2.txt b/cabal-testsuite/PackageTests/SDist/T8817/pkg/d1/f2.txt new file mode 100644 index 00000000000..9de77c18733 --- /dev/null +++ b/cabal-testsuite/PackageTests/SDist/T8817/pkg/d1/f2.txt @@ -0,0 +1 @@ +f2 diff --git a/cabal-testsuite/PackageTests/SDist/T8817/pkg/d1/f3.txt b/cabal-testsuite/PackageTests/SDist/T8817/pkg/d1/f3.txt new file mode 100644 index 00000000000..45d9e0e9fc8 --- /dev/null +++ b/cabal-testsuite/PackageTests/SDist/T8817/pkg/d1/f3.txt @@ -0,0 +1 @@ +f3 diff --git a/cabal-testsuite/PackageTests/SDist/T8817/pkg/f1 b/cabal-testsuite/PackageTests/SDist/T8817/pkg/f1 new file mode 100644 index 00000000000..8e1e71d5ce3 --- /dev/null +++ b/cabal-testsuite/PackageTests/SDist/T8817/pkg/f1 @@ -0,0 +1 @@ +f1 diff --git a/cabal-testsuite/PackageTests/SDist/T8817/pkg/t8817.cabal b/cabal-testsuite/PackageTests/SDist/T8817/pkg/t8817.cabal new file mode 100644 index 00000000000..899eb191b84 --- /dev/null +++ b/cabal-testsuite/PackageTests/SDist/T8817/pkg/t8817.cabal @@ -0,0 +1,11 @@ +cabal-version: 3.14 +name: t8817 +version: 0 + +extra-files: + d1/*.txt + f1 + +executable foo + default-language: Haskell2010 + main-is: Main.hs diff --git a/changelog.d/issue-8817 b/changelog.d/issue-8817 new file mode 100644 index 00000000000..0743671fa0d --- /dev/null +++ b/changelog.d/issue-8817 @@ -0,0 +1,17 @@ +synopsis: Neutral field to add files to sdist +packages: Cabal Cabal-syntax +prs: #10107 +issues: #8817 +significance: significant + +description: { + +Adds the `extra-files` field to the cabal file specification. This is like +the other `extra-*` fields in that it is copied with the `sdist` command, +except there are no other semantics. Compare to: + +* `extra-source-files`: Tracked by `cabal build`. + +* `extra-doc-files`: Copied by Haddock to the html directory. + +} diff --git a/doc/buildinfo-fields-reference.rst b/doc/buildinfo-fields-reference.rst index cfabe5ee448..a289292945a 100644 --- a/doc/buildinfo-fields-reference.rst +++ b/doc/buildinfo-fields-reference.rst @@ -595,6 +595,14 @@ extra-doc-files .. math:: \mathrm{commalist}\left\{ \mathop{\mathit{hs\text{-}string}}\mid{{[\mathop{\mathord{``}\mathtt{\ }\mathord{"}}\mathop{\mathord{``}\mathtt{\text{,}}\mathord{"}}]^c}}^+_{} \right\} +extra-files + * Monoidal field + * Available since ``cabal-version: 3.14``. + * Documentation of :pkg-field:`extra-files` + + .. math:: + \mathrm{commalist}\left\{ \mathop{\mathit{hs\text{-}string}}\mid{{[\mathop{\mathord{``}\mathtt{\ }\mathord{"}}\mathop{\mathord{``}\mathtt{\text{,}}\mathord{"}}]^c}}^+_{} \right\} + extra-source-files * Monoidal field * Documentation of :pkg-field:`extra-source-files` diff --git a/doc/cabal-package-description-file.rst b/doc/cabal-package-description-file.rst index 416aa3df76c..e5e170f3984 100644 --- a/doc/cabal-package-description-file.rst +++ b/doc/cabal-package-description-file.rst @@ -773,6 +773,11 @@ describe the package as a whole: additional hooks, such as the scheme described in the section on `system-dependent parameters`_. +.. pkg-field:: extra-files: filename list + + A list of additional files to be included in source distributions built with :ref:`setup-sdist`. + As with :pkg-field:`data-files` it can use a limited form of ``*`` wildcards in file names. + Library ^^^^^^^ diff --git a/doc/file-format-changelog.rst b/doc/file-format-changelog.rst index 854f949b301..e57eb2508fc 100644 --- a/doc/file-format-changelog.rst +++ b/doc/file-format-changelog.rst @@ -19,6 +19,13 @@ relative to the respective preceding *published* version. versions of the ``Cabal`` library denote unreleased development branches which have no stability guarantee. +``cabal-version: 3.14`` +----------------------- + +* Added field ``extra-files`` for specifying extra files to be included in + ``sdist`` without adding any other semantics (cf. ``extra-source-files`` + is tracked by ``cabal build``). + ``cabal-version: 3.12`` ----------------------- diff --git a/doc/setup-commands.rst b/doc/setup-commands.rst index 5ed8077f46b..4babff6f40c 100644 --- a/doc/setup-commands.rst +++ b/doc/setup-commands.rst @@ -1385,7 +1385,8 @@ The files placed in this distribution are the package description file, the setup script, the sources of the modules named in the package description file, and files named in the ``license-file``, ``main-is``, ``c-sources``, ``asm-sources``, ``cmm-sources``, ``js-sources``, -``data-files``, ``extra-source-files`` and ``extra-doc-files`` fields. +``data-files``, ``extra-source-files``, ``extra-doc-files``, and +``extra-files`` fields. This command takes the following option: diff --git a/editors/vim/syntax/cabal.vim b/editors/vim/syntax/cabal.vim index 119a5ccb767..d3374dbd27f 100644 --- a/editors/vim/syntax/cabal.vim +++ b/editors/vim/syntax/cabal.vim @@ -80,6 +80,7 @@ syn keyword cabalFieldName contained \ extra-bundled-libraries \ extra-doc-files \ extra-dynamic-library-flavours + \ extra-files \ extra-framework-dirs \ extra-ghci-libraries \ extra-lib-dirs From cdf14c5c1c5ada758b09b32ba0500afa5ae5216b Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Sat, 3 Aug 2024 15:42:31 -0400 Subject: [PATCH 069/207] clarify "configure" messages from Cabal (#9476) * clarify "configure" messages from Cabal * add changelog * Apply suggestions from code review Co-authored-by: Javier Sagredo --------- Co-authored-by: Javier Sagredo Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- Cabal/src/Distribution/Simple/Configure.hs | 10 ++--- Cabal/src/Distribution/Simple/Errors.hs | 49 +++++++++++----------- changelog.d/configure-messages | 13 ++++++ 3 files changed, 42 insertions(+), 30 deletions(-) create mode 100644 changelog.d/configure-messages diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index 6c6610cb2be..6e98ee6c25f 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -208,20 +208,20 @@ data ConfigStateFileError dispConfigStateFileError :: ConfigStateFileError -> Doc dispConfigStateFileError ConfigStateFileNoHeader = text "Saved package config file header is missing." - <+> text "Re-run the 'configure' command." + <+> text "Re-run the 'Setup configure' command." dispConfigStateFileError ConfigStateFileBadHeader = text "Saved package config file header is corrupt." - <+> text "Re-run the 'configure' command." + <+> text "Re-run the 'Setup configure' command." dispConfigStateFileError ConfigStateFileNoParse = text "Saved package config file is corrupt." - <+> text "Re-run the 'configure' command." + <+> text "Re-run the 'Setup configure' command." dispConfigStateFileError ConfigStateFileMissing{} = - text "Run the 'configure' command first." + text "Run the 'Setup configure' command first." dispConfigStateFileError (ConfigStateFileBadVersion oldCabal oldCompiler _) = text "Saved package config file is outdated:" $+$ badCabal $+$ badCompiler - $+$ text "Re-run the 'configure' command." + $+$ text "Re-run the 'Setup configure' command." where badCabal = text "• the Cabal version changed from" diff --git a/Cabal/src/Distribution/Simple/Errors.hs b/Cabal/src/Distribution/Simple/Errors.hs index e39f63823a8..c1cc75b5ad1 100644 --- a/Cabal/src/Distribution/Simple/Errors.hs +++ b/Cabal/src/Distribution/Simple/Errors.hs @@ -314,7 +314,7 @@ versionRequirement range exceptionMessage :: CabalException -> String exceptionMessage e = case e of NoBenchMarkProgram cmd -> "Could not find benchmark program \"" ++ cmd ++ "\". Did you build the package first?" - EnableBenchMark -> "No benchmarks enabled. Did you remember to configure with " ++ "\'--enable-benchmarks\'?" + EnableBenchMark -> "No benchmarks enabled. Did you remember to \'Setup configure\' with " ++ "\'--enable-benchmarks\'?" BenchMarkNameDisabled bmName -> "Package configured with benchmark " ++ bmName ++ " disabled." NoBenchMark bmName -> "no such benchmark: " ++ bmName NoLibraryFound -> "No executables and no library found. Nothing to do." @@ -331,8 +331,8 @@ exceptionMessage e = case e of ++ ".\n" ++ "If the module " ++ "is autogenerated it should be added to 'autogen-modules'." - RegMultipleInstancePkg -> "HcPkg.register: the compiler does not support,registering multiple instances of packages." - SuppressingChecksOnFile -> "HcPkg.register: the compiler does not support ,suppressing checks on files." + RegMultipleInstancePkg -> "HcPkg.register: the compiler does not support registering multiple instances of packages." + SuppressingChecksOnFile -> "HcPkg.register: the compiler does not support suppressing checks on files." NoSupportDirStylePackageDb -> "HcPkg.writeRegistrationFileDirectly: compiler does not support dir style package dbs" OnlySupportSpecificPackageDb -> "HcPkg.writeRegistrationFileDirectly: only supports SpecificPackageDB for now" FailedToParseOutputDescribe programId pkgId -> "failed to parse output of '" ++ programId ++ " describe " ++ prettyShow pkgId ++ "'" @@ -353,7 +353,7 @@ exceptionMessage e = case e of ++ " but " ++ "haddock is using GHC version " ++ prettyShow haddockGhcVersion - MustHaveSharedLibraries -> "Must have vanilla or shared libraries " ++ "enabled in order to run haddock" + MustHaveSharedLibraries -> "Must have vanilla or shared libraries enabled in order to run haddock" HaddockPackageFlags inf -> "internal error when calculating transitive " ++ "package dependencies.\nDebug info: " @@ -391,7 +391,7 @@ exceptionMessage e = case e of GlobalPackageDBLimitation -> "With current ghc versions the global package db is always used " ++ "and must be listed first. This ghc limitation may be lifted in " - ++ "future, see https://gitlab.haskell.org/ghc/ghc/-/issues/5977" + ++ "the future, see https://gitlab.haskell.org/ghc/ghc/-/issues/5977" GlobalPackageDBSpecifiedFirst -> "If the global package db is specified, it must be " ++ "specified first and cannot be specified multiple times" @@ -487,8 +487,7 @@ exceptionMessage e = case e of ++ "suite type " ++ prettyShow tt NoSupportForPreProcessingBenchmark tt -> - "No support for preprocessing benchmark " - ++ "type " + "No support for preprocessing benchmark type " ++ prettyShow tt CantFindSourceForPreProcessFile errorStr -> errorStr NoSupportPreProcessingTestExtras tt -> @@ -511,11 +510,11 @@ exceptionMessage e = case e of SanityCheckHookedBuildInfo exe1 -> "The buildinfo contains info for an executable called '" ++ prettyShow exe1 - ++ "' but the package does not have a " + ++ "' but the package does not have an " ++ "executable with that name." ConfigureScriptNotFound fp -> "configure script not found at " ++ fp ++ "." NoValidComponent -> "No valid component targets found" - ConfigureEitherSingleOrAll -> "Can only configure either single component or all of them" + ConfigureEitherSingleOrAll -> "Can only configure either a single component or all of them" ConfigCIDValidForPreComponent -> "--cid is only supported for per-component configure" SanityCheckForEnableComponents -> "--enable-tests/--enable-benchmarks are incompatible with" @@ -525,23 +524,23 @@ exceptionMessage e = case e of ++ " are incompatible with each other." UnsupportedLanguages pkgId compilerId langs -> "The package " - ++ prettyShow (pkgId) + ++ prettyShow pkgId ++ " requires the following languages which are not " ++ "supported by " - ++ prettyShow (compilerId) + ++ prettyShow compilerId ++ ": " ++ intercalate ", " langs UnsupportedLanguageExtension pkgId compilerId exts -> "The package " - ++ prettyShow (pkgId) + ++ prettyShow pkgId ++ " requires the following language extensions which are not " ++ "supported by " - ++ prettyShow (compilerId) + ++ prettyShow compilerId ++ ": " ++ intercalate ", " exts CantFindForeignLibraries unsupportedFLibs -> "Cannot build some foreign libraries: " - ++ intercalate "," unsupportedFLibs + ++ intercalate ", " unsupportedFLibs ExpectedAbsoluteDirectory fPath -> "expected an absolute directory name for --prefix: " ++ fPath FlagsNotSpecified diffFlags -> "'--exact-configuration' was given, " @@ -572,7 +571,7 @@ exceptionMessage e = case e of ++ "' refers to a library which is defined within the same " ++ "package. To use this feature the package must specify at " ++ "least 'cabal-version: >= 1.8'." - ReportFailedDependencies failed hackageUrl -> (intercalate "\n\n" (map reportFailedDependency failed)) + ReportFailedDependencies failed hackageUrl -> intercalate "\n\n" (map reportFailedDependency failed) where reportFailedDependency (DependencyNotExists pkgname) = "there is no version of " @@ -617,7 +616,7 @@ exceptionMessage e = case e of NoWorkingGcc -> unlines [ "No working gcc" - , "This package depends on foreign library but we cannot " + , "This package depends on a foreign library but we cannot " ++ "find a working C compiler. If you have it in a " ++ "non-standard location you can use the --with-gcc " ++ "flag to specify it." @@ -674,8 +673,8 @@ exceptionMessage e = case e of ++ "where it is." ++ "If the library file does exist, it may contain errors that " ++ "are caught by the C compiler at the preprocessing stage. " - ++ "In this case you can re-run configure with the verbosity " - ++ "flag -v3 to see the error messages." + ++ "In this case you can re-run 'Setup configure' with the " + ++ "verbosity flag -v3 to see the error messages." messagePlural = "This problem can usually be solved by installing the system " ++ "packages that provide these libraries (you may need the " @@ -685,18 +684,18 @@ exceptionMessage e = case e of ++ "where they are." ++ "If the library files do exist, it may contain errors that " ++ "are caught by the C compiler at the preprocessing stage. " - ++ "In this case you can re-run configure with the verbosity " - ++ "flag -v3 to see the error messages." + ++ "In this case you can re-run 'Setup configure' with the " + ++ "verbosity flag -v3 to see the error messages." headerCppMessage = "If the header file does exist, it may contain errors that " ++ "are caught by the C compiler at the preprocessing stage. " - ++ "In this case you can re-run configure with the verbosity " - ++ "flag -v3 to see the error messages." + ++ "In this case you can re-run 'Setup configure' with the " + ++ "verbosity flag -v3 to see the error messages." headerCcMessage = "The header file contains a compile error. " - ++ "You can re-run configure with the verbosity flag " + ++ "You can re-run 'Setup configure' with the verbosity flag " ++ "-v3 to see the error messages from the C compiler." - CheckPackageProblems errors -> (intercalate "\n\n" $ errors) + CheckPackageProblems errors -> intercalate "\n\n" errors LibDirDepsPrefixNotRelative l p -> "Library directory of a dependency: " ++ show l @@ -757,7 +756,7 @@ exceptionMessage e = case e of RegisMultiplePkgNotSupported -> "Registering multiple package instances is not yet supported for this compiler" RegisteringNotImplemented -> "Registering is not implemented for this compiler" NoTestSuitesEnabled -> - "No test suites enabled. Did you remember to configure with " + "No test suites enabled. Did you remember to 'Setup configure' with " ++ "\'--enable-tests\'?" TestNameDisabled tName -> "Package configured with test suite " diff --git a/changelog.d/configure-messages b/changelog.d/configure-messages new file mode 100644 index 00000000000..f0fab79e734 --- /dev/null +++ b/changelog.d/configure-messages @@ -0,0 +1,13 @@ +synopsis: clarify Cabal "configure" messages +packages: Cabal +prs: #9476 + +synopsis: { + + Cabal can issue a number of error messages referencing "Setup configure", + but it simply references "configure" which could mean any of three + things (Setup configure, the package's "configure" script, or "cabal + configure"). This has recently caught out even Cabal devs. Clarify these + messages. + +} From 10b4bfe8ffe6a2e1cc2c72380d7bb87fd882a4f6 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Tue, 23 Jul 2024 18:34:09 -0400 Subject: [PATCH 070/207] reorder Haddock markup for dynprof constructor Older ghcs don't like it being after the constructor. --- .../src/Distribution/Solver/Types/ConstraintSource.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cabal-install-solver/src/Distribution/Solver/Types/ConstraintSource.hs b/cabal-install-solver/src/Distribution/Solver/Types/ConstraintSource.hs index 55b35212d3c..cb91bc742b4 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/ConstraintSource.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/ConstraintSource.hs @@ -41,9 +41,9 @@ data ConstraintSource = -- from Cabal >= 3.11 | ConstraintSourceMultiRepl - | ConstraintSourceProfiledDynamic -- | Constraint introduced by --enable-profiling-shared, which requires features -- from Cabal >= 3.13 + | ConstraintSourceProfiledDynamic -- | The source of the constraint is not specified. | ConstraintSourceUnknown From bae3383e723acfa3c6d1052808f11df09a01888b Mon Sep 17 00:00:00 2001 From: Artem Pelenitsyn Date: Sat, 3 Aug 2024 19:41:31 -0400 Subject: [PATCH 071/207] Update cabal-install-solver synopsis (fix #10183) (#10192) * Update cabal-install-solver synopsis (fix #10183) * fixup! remove trailing dot --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- cabal-install-solver/cabal-install-solver.cabal | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cabal-install-solver/cabal-install-solver.cabal b/cabal-install-solver/cabal-install-solver.cabal index 4bc75a32569..5340fae3f7f 100644 --- a/cabal-install-solver/cabal-install-solver.cabal +++ b/cabal-install-solver/cabal-install-solver.cabal @@ -1,9 +1,9 @@ cabal-version: 2.2 name: cabal-install-solver version: 3.13.0.0 -synopsis: The command-line interface for Cabal and Hackage. +synopsis: The solver component of cabal-install description: - The solver component used in cabal-install command-line program + The solver component used in the cabal-install command-line program. homepage: http://www.haskell.org/cabal/ bug-reports: https://github.com/haskell/cabal/issues From 15c6a28b5d2cae1de91f754442da99fa2058eb9e Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Sat, 3 Aug 2024 10:45:04 -0700 Subject: [PATCH 072/207] Add MultilineStrings extension --- Cabal-syntax/src/Language/Haskell/Extension.hs | 2 ++ .../tests/UnitTests/Distribution/Utils/Structured.hs | 8 ++++---- changelog.d/pr-10245 | 8 ++++++++ editors/vim/syntax/cabal.vim | 1 + 4 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 changelog.d/pr-10245 diff --git a/Cabal-syntax/src/Language/Haskell/Extension.hs b/Cabal-syntax/src/Language/Haskell/Extension.hs index 22082d6d0b3..13796c80666 100644 --- a/Cabal-syntax/src/Language/Haskell/Extension.hs +++ b/Cabal-syntax/src/Language/Haskell/Extension.hs @@ -551,6 +551,8 @@ data KnownExtension | -- | Allow the use of built-in syntax for list, tuple and sum type constructors -- rather than being exclusive to data constructors. ListTuplePuns + | -- | Support multiline strings + MultilineStrings deriving (Generic, Show, Read, Eq, Ord, Enum, Bounded, Typeable, Data) instance Binary KnownExtension diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs index 40770290073..d932ef59a33 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs @@ -31,15 +31,15 @@ md5Check proxy md5Int = structureHash proxy @?= md5FromInteger md5Int md5CheckGenericPackageDescription :: Proxy GenericPackageDescription -> Assertion md5CheckGenericPackageDescription proxy = md5Check proxy #if MIN_VERSION_base(4,19,0) - 0x3da8883a286b8fbfd9f94790d57cc06e + 0x62ad178a75f041af29947c9b3d83e6ed #else - 0x245e544da05f50f9dd0339a96ac99860 + 0xba8f0baa8074fd238ad36a309399349e #endif md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion md5CheckLocalBuildInfo proxy = md5Check proxy #if MIN_VERSION_base(4,19,0) - 0x7683c2daece12ba7982e80f860454f47 + 0xc68e9c0758c4bf2d72fe82b3d55cee34 #else - 0xe694b39b10bc861f47ea9c7b926a422a + 0xcf7e7bbcaec504d745fe086eec1786ff #endif diff --git a/changelog.d/pr-10245 b/changelog.d/pr-10245 new file mode 100644 index 00000000000..2ed3690720a --- /dev/null +++ b/changelog.d/pr-10245 @@ -0,0 +1,8 @@ +synopsis: Add MultilineStrings extension +packages: Cabal-syntax +prs: #10245 +description: { + +- adds support for the `MultilineStrings` language extension (GHC proposal #637) + +} diff --git a/editors/vim/syntax/cabal.vim b/editors/vim/syntax/cabal.vim index d3374dbd27f..db08e8e0d92 100644 --- a/editors/vim/syntax/cabal.vim +++ b/editors/vim/syntax/cabal.vim @@ -219,6 +219,7 @@ syn keyword cabalExtension contained \ MonoLocalBinds \ MonoPatBinds \ MonomorphismRestriction + \ MultilineStrings \ MultiParamTypeClasses \ MultiWayIf \ NPlusKPatterns From 5f4b56eab8d3a7bf12501fc96b6efd1e4427a478 Mon Sep 17 00:00:00 2001 From: Kristen Kozak Date: Mon, 29 Jul 2024 22:51:45 -0700 Subject: [PATCH 073/207] Add simple QuickCheck test for solver exceptions The solver QuickCheck tests can already detect exceptions, but this test is simpler and easier to debug. --- .../Distribution/Solver/Modular/QuickCheck.hs | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs index 1a2bc97224f..c891f60692b 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs @@ -52,7 +52,20 @@ import UnitTests.Distribution.Solver.Modular.QuickCheck.Utils tests :: [TestTree] tests = - [ -- This test checks that certain solver parameters do not affect the + [ testPropertyWithSeed "solver does not throw exceptions" $ + \test goalOrder reorderGoals indepGoals prefOldest -> + let r = + solve + (EnableBackjumping True) + (FineGrainedConflicts True) + reorderGoals + (CountConflicts True) + indepGoals + prefOldest + (getBlind <$> goalOrder) + test + in resultPlan r `seq` () + , -- This test checks that certain solver parameters do not affect the -- existence of a solution. It runs the solver twice, and only sets those -- parameters on the second run. The test also applies parameters that -- can affect the existence of a solution to both runs. @@ -516,6 +529,11 @@ instance Arbitrary IndependentGoals where shrink (IndependentGoals indep) = [IndependentGoals False | indep] +instance Arbitrary PreferOldest where + arbitrary = PreferOldest <$> arbitrary + + shrink (PreferOldest prefOldest) = [PreferOldest False | prefOldest] + instance Arbitrary Component where arbitrary = oneof From 63954d988f8b302c90a56cd5579d218a3979aaff Mon Sep 17 00:00:00 2001 From: Artem Pelenitsyn Date: Wed, 7 Aug 2024 08:38:08 -0400 Subject: [PATCH 074/207] 3.14 pre-flight checks: bump dependencies (#10244) * allow hashable-1.5 * allow tasty-quickcheck 0.11, and in case of cabal-install:test move to ^>=0.11 --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- Cabal-described/Cabal-described.cabal | 2 +- Cabal-tests/Cabal-tests.cabal | 4 ++-- cabal-install-solver/cabal-install-solver.cabal | 2 +- cabal-install/cabal-install.cabal | 6 +++--- .../Distribution/Solver/Modular/QuickCheck/Utils.hs | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Cabal-described/Cabal-described.cabal b/Cabal-described/Cabal-described.cabal index d8471940cea..86b516d94ef 100644 --- a/Cabal-described/Cabal-described.cabal +++ b/Cabal-described/Cabal-described.cabal @@ -19,7 +19,7 @@ library , QuickCheck , rere >=0.1 && <0.3 , tasty <1.6 - , tasty-quickcheck <0.11 + , tasty-quickcheck <0.12 exposed-modules: Distribution.Described diff --git a/Cabal-tests/Cabal-tests.cabal b/Cabal-tests/Cabal-tests.cabal index 52647f8a6b4..f7fdc2fb85d 100644 --- a/Cabal-tests/Cabal-tests.cabal +++ b/Cabal-tests/Cabal-tests.cabal @@ -70,7 +70,7 @@ test-suite unit-tests , QuickCheck >=2.14 && <2.15 , tasty >=1.2.3 && <1.6 , tasty-hunit - , tasty-quickcheck <0.11 + , tasty-quickcheck <0.12 , temporary , text @@ -175,7 +175,7 @@ test-suite rpmvercmp QuickCheck , tasty >=1.2.3 && <1.6 , tasty-hunit - , tasty-quickcheck <0.11 + , tasty-quickcheck <0.12 c-sources: tests/cbits/rpmvercmp.c cc-options: -Wall diff --git a/cabal-install-solver/cabal-install-solver.cabal b/cabal-install-solver/cabal-install-solver.cabal index 5340fae3f7f..2cb276e910a 100644 --- a/cabal-install-solver/cabal-install-solver.cabal +++ b/cabal-install-solver/cabal-install-solver.cabal @@ -135,5 +135,5 @@ Test-Suite unit-tests , Cabal-syntax , cabal-install-solver , tasty >= 1.2.3 && <1.6 - , tasty-quickcheck <0.11 + , tasty-quickcheck <0.12 , tasty-hunit >= 0.10 diff --git a/cabal-install/cabal-install.cabal b/cabal-install/cabal-install.cabal index 115b9457d4b..db6d1452ae3 100644 --- a/cabal-install/cabal-install.cabal +++ b/cabal-install/cabal-install.cabal @@ -231,7 +231,7 @@ library edit-distance >= 0.2.2 && < 0.3, exceptions >= 0.10.4 && < 0.11, filepath >= 1.4.0.0 && < 1.6, - hashable >= 1.0 && < 1.5, + hashable >= 1.0 && < 1.6, HTTP >= 4000.1.5 && < 4000.5, mtl >= 2.0 && < 2.4, network-uri >= 2.6.0.2 && < 2.7, @@ -350,7 +350,7 @@ test-suite unit-tests zlib, tasty >= 1.2.3 && <1.6, tasty-golden >=2.3.1.1 && <2.4, - tasty-quickcheck <0.11, + tasty-quickcheck ^>=0.11, tasty-expected-failure, tasty-hunit >= 0.10, tree-diff, @@ -439,6 +439,6 @@ test-suite long-tests tasty >= 1.2.3 && <1.6, tasty-expected-failure, tasty-hunit >= 0.10, - tasty-quickcheck <0.11, + tasty-quickcheck <0.12, QuickCheck >= 2.14 && <2.16, pretty-show >= 1.6.15 diff --git a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck/Utils.hs b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck/Utils.hs index 72283639cd9..c1882bc659a 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck/Utils.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck/Utils.hs @@ -31,7 +31,7 @@ instance IsTest QCWithSeed where run options (QCWithSeed test) progress = do replay <- case lookupOption options of - QuickCheckReplay (Just override) -> return override - QuickCheckReplay Nothing -> getStdRandom random + QuickCheckReplayLegacy override -> return override + _ -> getStdRandom random notice normal $ "Using --quickcheck-replay=" ++ show replay - run (setOption (QuickCheckReplay (Just replay)) options) test progress + run (setOption (QuickCheckReplayLegacy replay) options) test progress From 4d68109fb832f9d17785befa236626d1393ecca1 Mon Sep 17 00:00:00 2001 From: Taimoor Zaeem Date: Thu, 8 Aug 2024 21:32:41 +0500 Subject: [PATCH 075/207] Update haskell packages to launch nix-shell in CONTRIBUTING.md (#10221) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- CONTRIBUTING.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c6944eb1227..2049b978528 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,10 +38,11 @@ $ cabal run cabal -- build --help ``` > [!NOTE] -> If you're using Nix, you might find it convenient to work within a shell that has all the `Cabal` development dependencies: -> ``` -> $ nix-shell -p cabal-install ghc ghcid haskellPackages.fourmolu_0_12_0_0 pkgconfig zlib.dev +> If you're using Nix, you might find it convenient to work within a shell that has the following `Cabal` development dependencies: +> ```bash +> $ nix-shell -p cabal-install ghc ghcid pkg-config zlib.dev # incomplete > ``` +> One dependency that we left out in the above command is `haskellPackages.fourmolu_0_12_0_0` which would need to be installed manually. > A Nix flake developer shell with these dependencies is also available, supported solely by the community, through the command `nix develop github:yvan-sraka/cabal.nix`. The location of your build products will vary depending on which version of From 9c7a2f3d78aa364a3d6295afbc7749b34b6c9ede Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Wed, 7 Aug 2024 23:19:43 -0400 Subject: [PATCH 076/207] use fixed cabal version per #10175 --- .github/workflows/validate.yml | 2 +- cabal-testsuite/cabal-testsuite.cabal | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index a886214c01d..8aec3e52f83 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -113,7 +113,7 @@ jobs: id: setup-haskell with: ghc-version: ${{ matrix.ghc }} - cabal-version: latest # latest is mandatory for cabal-testsuite, see https://github.com/haskell/cabal/issues/8133 + cabal-version: 3.12.1.0 # see https://github.com/haskell/cabal/pull/10251 ghcup-release-channel: https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.8.yaml # See the following link for a breakdown of the following step diff --git a/cabal-testsuite/cabal-testsuite.cabal b/cabal-testsuite/cabal-testsuite.cabal index 92becccd8dc..479b372b8ca 100644 --- a/cabal-testsuite/cabal-testsuite.cabal +++ b/cabal-testsuite/cabal-testsuite.cabal @@ -145,9 +145,8 @@ executable test-runtime-deps custom-setup -- we only depend on even stable releases of lib:Cabal - -- and due to Custom complexity and ConstraintSetupCabalMaxVersion - -- it has to be the latest release version plus - -- you have to use the latest cabal-install release - setup-depends: Cabal == 3.12.*, - Cabal-syntax == 3.12.*, + -- and must match the release used in validate.yml (see + -- https://github.com/haskell/cabal/pull/10251) + setup-depends: Cabal ^>= 3.12.1, + Cabal-syntax ^>= 3.12.1, base, filepath, directory From 38e317b9cbc27e8e9d40130798a88bb15a1341ca Mon Sep 17 00:00:00 2001 From: Artem Pelenitsyn Date: Tue, 13 Aug 2024 13:35:32 -0400 Subject: [PATCH 077/207] CI: skip cli-suite on Windows due to #9571 (#10257) --- .github/workflows/validate.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 8aec3e52f83..5244fabe9fb 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -210,6 +210,7 @@ jobs: run: sh validate.sh $FLAGS -s cli-tests - name: Validate cli-suite + if: runner.os != 'Windows' run: sh validate.sh $FLAGS -s cli-suite - name: Validate solver-benchmarks-tests From f027a212a8a795d2c4db3def82846ed58800f41a Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Fri, 2 Aug 2024 11:47:01 +0100 Subject: [PATCH 078/207] Filter out -dinitial-unique and -dunique-increment from hash flags These options shouldn't affect the output of the package and hence shouldn't affect the store hash of a package. --- Cabal/src/Distribution/Simple/Program/GHC.hs | 2 ++ changelog.d/pr-10240 | 13 +++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 changelog.d/pr-10240 diff --git a/Cabal/src/Distribution/Simple/Program/GHC.hs b/Cabal/src/Distribution/Simple/Program/GHC.hs index c42eb18e3b1..a0655793792 100644 --- a/Cabal/src/Distribution/Simple/Program/GHC.hs +++ b/Cabal/src/Distribution/Simple/Program/GHC.hs @@ -324,6 +324,8 @@ normaliseGhcArgs (Just ghcVersion) PackageDescription{..} ghcArgs , "-ddpr-cols" , "-dtrace-level" , "-fghci-hist-size" + , "-dinitial-unique" + , "-dunique-increment" ] , from [8, 2] ["-fmax-uncovered-patterns", "-fmax-errors"] , from [8, 4] $ to [8, 6] ["-fmax-valid-substitutions"] diff --git a/changelog.d/pr-10240 b/changelog.d/pr-10240 new file mode 100644 index 00000000000..9bd05100ab7 --- /dev/null +++ b/changelog.d/pr-10240 @@ -0,0 +1,13 @@ +synopsis: Filter out dinitial-unique and dunique-increment from package hash +packages: cabal-install +prs: #10122 + +description: { + +`-dinitial-unique` and `-dunique-increment` are now filtered out when computing the +store hash of a package. + +These options shouldn't affect the output of the package and hence +shouldn't affect the store hash of a package. + +} From 45d088d4036396cbf668c08c0a90350cad073357 Mon Sep 17 00:00:00 2001 From: Rodrigo Mesquita Date: Wed, 7 Aug 2024 17:28:42 +0100 Subject: [PATCH 079/207] hpc: Don't cover non-dependency libraries We were passing the flag --coverage-for for every library in the package when building the testsuites. However, if a particular testsuite doesn't depend on one of the packages passed with --coverage-for we would crash. Since we look for the unit ids of all packages given in --coverage-for in the package database (to find hpc artifacts), if the testsuite builds before the library this lookup would fail. The fix is easy: don't pass --coverage-for= to if doesn't depend on . If is an indirect dependency of it'll no longer be covered by HPC, but this is a weird behaviour that I doubt anyone relies on. Fixes #10046 --- Cabal/src/Distribution/Simple/Configure.hs | 4 ++- .../Distribution/Client/ProjectPlanning.hs | 18 +++++++----- .../PackageTests/Regression/T10046/aa.cabal | 28 +++++++++++++++++++ .../Regression/T10046/app/Main.hs | 1 + .../Regression/T10046/cabal.project | 1 + .../Regression/T10046/cabal.test.hs | 6 ++++ .../Regression/T10046/src/MyLib.hs | 11 ++++++++ .../Regression/T10046/test/Main.hs | 1 + .../Regression/T10046/testbb/Main.hs | 1 + changelog.d/issue-10046 | 4 +++ 10 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 cabal-testsuite/PackageTests/Regression/T10046/aa.cabal create mode 100644 cabal-testsuite/PackageTests/Regression/T10046/app/Main.hs create mode 100644 cabal-testsuite/PackageTests/Regression/T10046/cabal.project create mode 100644 cabal-testsuite/PackageTests/Regression/T10046/cabal.test.hs create mode 100644 cabal-testsuite/PackageTests/Regression/T10046/src/MyLib.hs create mode 100644 cabal-testsuite/PackageTests/Regression/T10046/test/Main.hs create mode 100644 cabal-testsuite/PackageTests/Regression/T10046/testbb/Main.hs create mode 100644 changelog.d/issue-10046 diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index 6e98ee6c25f..04929bad030 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -1280,7 +1280,9 @@ configureComponents extraCoverageUnitIds = case enabled of -- Whole package configure, add package libs ComponentRequestedSpec{} -> mapMaybe mbCompUnitId buildComponents - -- Component configure, no need to do anything + -- Component configure, no need to do anything since + -- extra-coverage-for will be passed for all other components that + -- should be covered. OneComponentRequestedSpec{} -> [] mbCompUnitId LibComponentLocalBuildInfo{componentUnitId} = Just componentUnitId mbCompUnitId _ = Nothing diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 23fed2c5bd1..4efa5f313b1 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -4058,7 +4058,7 @@ setupHsConfigureFlags Just _ -> error "non-library dependency" Nothing -> LMainLibName - configCoverageFor = determineCoverageFor elabPkgSourceId plan + configCoverageFor = determineCoverageFor elab plan setupHsConfigureArgs :: ElaboratedConfiguredPackage @@ -4469,13 +4469,14 @@ inplaceBinRoot layout config package = -- The list of non-pre-existing libraries without module holes, i.e. the -- main library and sub-libraries components of all the local packages in --- the project that do not require instantiations or are instantiations. +-- the project that are dependencies of the components being built and that do +-- not require instantiations or are instantiations. determineCoverageFor - :: PackageId - -- ^ The 'PackageId' of the package or component being configured + :: ElaboratedConfiguredPackage + -- ^ The package or component being configured -> ElaboratedInstallPlan -> Flag [UnitId] -determineCoverageFor configuredPkgSourceId plan = +determineCoverageFor configuredPkg plan = Flag $ mapMaybe ( \case @@ -4488,15 +4489,18 @@ determineCoverageFor configuredPkgSourceId plan = $ Graph.toList $ InstallPlan.toGraph plan where - shouldCoverPkg elab@ElaboratedConfiguredPackage{elabModuleShape, elabPkgSourceId, elabLocalToProject} = + libDeps = elabLibDependencies configuredPkg + shouldCoverPkg elab@ElaboratedConfiguredPackage{elabModuleShape, elabPkgSourceId = pkgSID, elabLocalToProject} = elabLocalToProject && not (isIndefiniteOrInstantiation elabModuleShape) -- TODO(#9493): We can only cover libraries in the same package -- as the testsuite - && configuredPkgSourceId == elabPkgSourceId + && elabPkgSourceId configuredPkg == pkgSID -- Libraries only! We don't cover testsuite modules, so we never need -- the paths to their mix dirs. Furthermore, we do not install testsuites... && maybe False (\case CLibName{} -> True; CNotLibName{} -> False) (elabComponentName elab) + -- We only want coverage for libraries which are dependencies of the given one + && pkgSID `elem` map (confSrcId . fst) libDeps isIndefiniteOrInstantiation :: ModuleShape -> Bool isIndefiniteOrInstantiation = not . Set.null . modShapeRequires diff --git a/cabal-testsuite/PackageTests/Regression/T10046/aa.cabal b/cabal-testsuite/PackageTests/Regression/T10046/aa.cabal new file mode 100644 index 00000000000..4acc7154baa --- /dev/null +++ b/cabal-testsuite/PackageTests/Regression/T10046/aa.cabal @@ -0,0 +1,28 @@ +cabal-version: 3.0 +name: aa +version: 0.1.0.0 +license: NONE +build-type: Simple +extra-doc-files: CHANGELOG.md + +library + exposed-modules: MyLib + build-depends: base, template-haskell + hs-source-dirs: src + default-language: Haskell2010 + +test-suite bb-test + default-language: Haskell2010 + type: exitcode-stdio-1.0 + hs-source-dirs: testbb + main-is: Main.hs + build-depends: + base, aa + +test-suite aa-test + default-language: Haskell2010 + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: + base diff --git a/cabal-testsuite/PackageTests/Regression/T10046/app/Main.hs b/cabal-testsuite/PackageTests/Regression/T10046/app/Main.hs new file mode 100644 index 00000000000..76a9bdb5d48 --- /dev/null +++ b/cabal-testsuite/PackageTests/Regression/T10046/app/Main.hs @@ -0,0 +1 @@ +main = pure () diff --git a/cabal-testsuite/PackageTests/Regression/T10046/cabal.project b/cabal-testsuite/PackageTests/Regression/T10046/cabal.project new file mode 100644 index 00000000000..e6fdbadb439 --- /dev/null +++ b/cabal-testsuite/PackageTests/Regression/T10046/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/cabal-testsuite/PackageTests/Regression/T10046/cabal.test.hs b/cabal-testsuite/PackageTests/Regression/T10046/cabal.test.hs new file mode 100644 index 00000000000..9b857e2f09a --- /dev/null +++ b/cabal-testsuite/PackageTests/Regression/T10046/cabal.test.hs @@ -0,0 +1,6 @@ +import Test.Cabal.Prelude + +-- T10046 +main = cabalTest $ recordMode DoNotRecord $ do + out <- cabal' "test" ["all"] + assertOutputDoesNotContain "Failed to find the installed unit 'aa-0.1.0.0-inplace'" out diff --git a/cabal-testsuite/PackageTests/Regression/T10046/src/MyLib.hs b/cabal-testsuite/PackageTests/Regression/T10046/src/MyLib.hs new file mode 100644 index 00000000000..ca3816aaab9 --- /dev/null +++ b/cabal-testsuite/PackageTests/Regression/T10046/src/MyLib.hs @@ -0,0 +1,11 @@ +{-# LANGUAGE TemplateHaskell #-} +module MyLib where + +import Control.Concurrent +import Language.Haskell.TH + +-- Must take longer to compile than the testsuite +$(do runIO $ + threadDelay (5*1000*1000) -- 5s + [d| data X |] + ) diff --git a/cabal-testsuite/PackageTests/Regression/T10046/test/Main.hs b/cabal-testsuite/PackageTests/Regression/T10046/test/Main.hs new file mode 100644 index 00000000000..76a9bdb5d48 --- /dev/null +++ b/cabal-testsuite/PackageTests/Regression/T10046/test/Main.hs @@ -0,0 +1 @@ +main = pure () diff --git a/cabal-testsuite/PackageTests/Regression/T10046/testbb/Main.hs b/cabal-testsuite/PackageTests/Regression/T10046/testbb/Main.hs new file mode 100644 index 00000000000..76a9bdb5d48 --- /dev/null +++ b/cabal-testsuite/PackageTests/Regression/T10046/testbb/Main.hs @@ -0,0 +1 @@ +main = pure () diff --git a/changelog.d/issue-10046 b/changelog.d/issue-10046 new file mode 100644 index 00000000000..668d077271e --- /dev/null +++ b/changelog.d/issue-10046 @@ -0,0 +1,4 @@ +synopsis: Bug fix - Don't pass --coverage-for for non-dependency libs of testsuite +packages: cabal-install +issues: #10046 +prs: #10250 From 2fb68e878215ba0a75ecf45531f3fd883411a671 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 19 Aug 2024 08:17:37 -0400 Subject: [PATCH 080/207] Always pass `ghc-options` (#8717) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Always pass `ghc-options` The [documentation for `ghc-shared-options`][1] states that they are combined with `ghc-options`: > Additional options for GHC when the package is built as shared > library. The options specified via this field are combined with the > ones specified via `ghc-options`, and are passed to GHC during both > the compile and link phases. However, _only_ `ghc-shared-options` and not `ghc-options` are passed in many cases. This is an issue because it requires setting `ghc-shared-options` even if the shared (dynamic) parts of the build don't actually need different options; this has the unpleasant side-effect of causing modules to be compiled twice, effectively doubling compile time! See here, where any non-empty `ghc-shared-options` causes Cabal to not set `-dynamic-too`: https://github.com/haskell/cabal/blob/acbc0f3a5cc9faf0913ff3e270196693816cec41/Cabal/src/Distribution/Simple/GHC.hs#L1466-L1469 This issue was discovered while integrating the `mold` linker with a Haskell project. [1]: https://cabal.readthedocs.io/en/latest/cabal-package.html#pkg-field-ghc-shared-options * Add documentation * Also enhance profArgs and profDynArgs --------- Co-authored-by: Hécate Moonlight Co-authored-by: Hécate --- Cabal/src/Distribution/Simple/GHC.hs | 6 +++--- Cabal/src/Distribution/Simple/GHCJS.hs | 8 ++++---- changelog.d/pr-8717 | 25 +++++++++++++++++++++++++ doc/cabal-package-description-file.rst | 5 +++++ 4 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 changelog.d/pr-8717 diff --git a/Cabal/src/Distribution/Simple/GHC.hs b/Cabal/src/Distribution/Simple/GHC.hs index 3ce66bb38bc..a8f15bc92da 100644 --- a/Cabal/src/Distribution/Simple/GHC.hs +++ b/Cabal/src/Distribution/Simple/GHC.hs @@ -734,7 +734,7 @@ libAbiHash verbosity _pkg_descr lbi lib clbi = do , ghcOptFPic = toFlag True , ghcOptHiSuffix = toFlag "dyn_hi" , ghcOptObjSuffix = toFlag "dyn_o" - , ghcOptExtra = hcSharedOptions GHC libBi + , ghcOptExtra = hcOptions GHC libBi ++ hcSharedOptions GHC libBi } profArgs = vanillaArgs @@ -746,7 +746,7 @@ libAbiHash verbosity _pkg_descr lbi lib clbi = do (withProfLibDetail lbi) , ghcOptHiSuffix = toFlag "p_hi" , ghcOptObjSuffix = toFlag "p_o" - , ghcOptExtra = hcProfOptions GHC libBi + , ghcOptExtra = hcOptions GHC libBi ++ hcProfOptions GHC libBi } profDynArgs = vanillaArgs @@ -760,7 +760,7 @@ libAbiHash verbosity _pkg_descr lbi lib clbi = do , ghcOptFPic = toFlag True , ghcOptHiSuffix = toFlag "p_dyn_hi" , ghcOptObjSuffix = toFlag "p_dyn_o" - , ghcOptExtra = hcProfSharedOptions GHC libBi + , ghcOptExtra = hcOptions GHC libBi ++ hcProfSharedOptions GHC libBi } ghcArgs = let (libWays, _, _) = buildWays lbi diff --git a/Cabal/src/Distribution/Simple/GHCJS.hs b/Cabal/src/Distribution/Simple/GHCJS.hs index 973230ee3c7..05fa3016738 100644 --- a/Cabal/src/Distribution/Simple/GHCJS.hs +++ b/Cabal/src/Distribution/Simple/GHCJS.hs @@ -583,7 +583,7 @@ buildOrReplLib mReplFlags verbosity numJobs _pkg_descr lbi lib clbi = do , ghcOptFPic = toFlag True , -- ghcOptHiSuffix = toFlag "dyn_hi", -- ghcOptObjSuffix = toFlag "dyn_o", - ghcOptExtra = hcSharedOptions GHC libBi + ghcOptExtra = hcOptions GHC libBi ++ hcSharedOptions GHC libBi , ghcOptHPCDir = hpcdir Hpc.Dyn } @@ -772,7 +772,7 @@ buildOrReplLib mReplFlags verbosity numJobs _pkg_descr lbi lib clbi = do , ghcOptDynLinkMode = toFlag GhcDynamicOnly , ghcOptInputFiles = toNubListR dynamicObjectFiles , ghcOptOutputFile = toFlag sharedLibFilePath - , ghcOptExtra = hcSharedOptions GHC libBi + , ghcOptExtra = hcOptions GHC libBi ++ hcSharedOptions GHC libBi , -- For dynamic libs, Mac OS/X needs to know the install location -- at build time. This only applies to GHC < 7.8 - see the -- discussion in #1660. @@ -1330,7 +1330,7 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do ghcOptFPic = toFlag True , ghcOptHiSuffix = toFlag "dyn_hi" , ghcOptObjSuffix = toFlag "dyn_o" - , ghcOptExtra = hcSharedOptions GHC bnfo + , ghcOptExtra = hcOptions GHC bnfo ++ hcSharedOptions GHC bnfo , ghcOptHPCDir = hpcdir Hpc.Dyn } dynTooOpts = @@ -1781,7 +1781,7 @@ libAbiHash verbosity _pkg_descr lbi lib clbi = do , ghcOptFPic = toFlag True , ghcOptHiSuffix = toFlag "js_dyn_hi" , ghcOptObjSuffix = toFlag "js_dyn_o" - , ghcOptExtra = hcSharedOptions GHC libBi + , ghcOptExtra = hcOptions GHC libBi ++ hcSharedOptions GHC libBi } profArgs = vanillaArgs diff --git a/changelog.d/pr-8717 b/changelog.d/pr-8717 new file mode 100644 index 00000000000..b0ac7e09388 --- /dev/null +++ b/changelog.d/pr-8717 @@ -0,0 +1,25 @@ +synopsis: Always pass `ghc-options` to GHC +packages: Cabal +prs: #8717 +issues: + +description: { + +Previously, options set in the package field `ghc-options` would not be passed +to GHC during the link phase for shared objects (where multiple `.o` or +`.dyn_o` files are merged into a single object file). This made it impossible +to use `ghc-options` to use a different linker by setting (for example) +`ghc-options: -optl-fuse-ld=mold -optlm-fuse-ld=mold`; the options would be +dropped in the link phase, falling back to the default linker. + +It was possible to work around this by duplicating the `ghc-options` to +`ghc-shared-options`, which _are_ passed in the shared link phase, but that had +the (undocumented and unfortunate) side-effect of disabling the GHC +`-dynamic-too` flag, effectively doubling compilation times when +`ghc-shared-options` are set. + +Now, `ghc-options` are combined with `ghc-shared-options` (to accurately +reflect the documentation on this feature) and the fact that +`ghc-shared-options` disables `-dynamic-too` is documented. + +} diff --git a/doc/cabal-package-description-file.rst b/doc/cabal-package-description-file.rst index e5e170f3984..839b2dc37db 100644 --- a/doc/cabal-package-description-file.rst +++ b/doc/cabal-package-description-file.rst @@ -1780,6 +1780,11 @@ system-dependent values for these fields. ones specified via :pkg-field:`ghc-options`, and are passed to GHC during both the compile and link phases. + Note that if any :pkg-field:`ghc-shared-options` are set, the + ``-dynamic-too` option will never be passed to GHC, leading to all modules + being compiled twice (once to generate the ``.o`` files and another to + generate the ``.dyn_o`` files). + .. pkg-field:: ghcjs-options: token list Like :pkg-field:`ghc-options` but applies to GHCJS From 55bd381b4619458877024d90f97bea8859e06bf8 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Mon, 19 Aug 2024 13:26:55 -0400 Subject: [PATCH 081/207] Mergify and actions upgrades (#10260) * upgrade actions/upload-artifact to v4 * update Mergify queue strategies Mergify is requiring that separate queues be used for different merge strategies, staerting in mid-September with a brownout in mid-August. https://docs.mergify.com/configuration/file-format/#queue-rules * update actions/download-artifact This one wasn't throwing warnings, but has also been updated with the same deprecation timeframe. It's also incompatible with actions/upload-artifact@v4. --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .github/mergify.yml | 26 +++++++++----------------- .github/workflows/bootstrap.yml | 2 +- .github/workflows/users-guide.yml | 2 +- .github/workflows/validate.yml | 16 ++++++++-------- 4 files changed, 19 insertions(+), 27 deletions(-) diff --git a/.github/mergify.yml b/.github/mergify.yml index 4a1efe926a8..a7bc364c473 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -19,10 +19,6 @@ pull_request_rules: - actions: queue: name: default - # Merge into master with a merge commit - method: merge - # Update the pr branch with rebase, so the history is clean - update_method: rebase name: Put pull requests in the rebase+merge queue conditions: - base=master @@ -33,11 +29,7 @@ pull_request_rules: # merge+squash strategy - actions: queue: - name: default - method: squash - # both update methods get absorbed by the squash, so we use the most - # reliable - update_method: merge + name: squash-merge name: Put pull requests in the squash+merge queue conditions: - base=master @@ -61,9 +53,6 @@ pull_request_rules: queue: name: default # Merge with a merge commit - method: merge - # Update the pr branch with rebase, so the history is clean - update_method: rebase name: Put backports in the rebase+merge queue conditions: - label=merge me @@ -74,11 +63,7 @@ pull_request_rules: # merge+squash strategy for backports: require 1 approver instead of 2 - actions: queue: - name: default - method: squash - # both update methods get absorbed by the squash, so we use the most - # reliable - update_method: merge + name: squash-merge name: Put backports in the squash+merge queue conditions: - label=squash+merge me @@ -96,5 +81,12 @@ pull_request_rules: - body~=automatic backport queue_rules: + # Mergify now requires different queues for different strategies - name: default update_bot_account: Mikolaj + merge_method: merge + update_method: rebase + - name: squash-merge + update_bot_account: Mikolaj + merge_method: squash + update_method: merge diff --git a/.github/workflows/bootstrap.yml b/.github/workflows/bootstrap.yml index ecfb015c699..e74d355360f 100644 --- a/.github/workflows/bootstrap.yml +++ b/.github/workflows/bootstrap.yml @@ -69,7 +69,7 @@ jobs: run: | _build/bin/cabal --version - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: cabal-${{ matrix.os }}-${{ matrix.ghc }}-bootstrapped path: _build/artifacts/* diff --git a/.github/workflows/users-guide.yml b/.github/workflows/users-guide.yml index 8442b39c2f4..64969e427c4 100644 --- a/.github/workflows/users-guide.yml +++ b/.github/workflows/users-guide.yml @@ -73,7 +73,7 @@ jobs: run: | make SPHINX_HTML_OUTDIR=html users-guide - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: users-guide-html path: html/ diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 5244fabe9fb..9ca6470d2d2 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -191,7 +191,7 @@ jobs: # - Make it available in the workflow to make easier testing it locally - name: Upload cabal-install executable to workflow artifacts if: matrix.ghc == env.GHC_FOR_RELEASE - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: cabal-${{ runner.os }}-x86_64 path: ${{ env.CABAL_EXEC_TAR }} @@ -338,7 +338,7 @@ jobs: echo "CABAL_EXEC_TAR=$CABAL_EXEC_TAR" >> "$GITHUB_ENV" - name: Upload cabal-install executable to workflow artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: cabal-${{ runner.os }}-static-x86_64 path: ${{ env.CABAL_EXEC_TAR }} @@ -374,7 +374,7 @@ jobs: cabal-version: latest # default, we are not using it in this job - name: Download cabal executable from workflow artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: cabal-${{ runner.os }}-x86_64 path: cabal-head @@ -399,19 +399,19 @@ jobs: needs: [validate, validate-old-ghcs, build-alpine, dogfooding] steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: cabal-Windows-x86_64 - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: cabal-Linux-x86_64 - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: cabal-Linux-static-x86_64 - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: cabal-macOS-x86_64 @@ -429,7 +429,7 @@ jobs: cabal-head-macOS-x86_64.tar.gz # We use this job as a summary of the workflow - # It will fail if any of the previous jobs does it + # It will fail if any of the previous jobs does # This way we can use it exclusively in branch protection rules # and abstract away the concrete jobs of the workflow, including their names validate-post-job: From 8d421c804ac97370aa80c3e423f115b8955fabef Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Sat, 17 Aug 2024 15:22:46 +0200 Subject: [PATCH 082/207] git:// protocol check: add test files --- .../PackageTests/Check/GitProtocol/cabal.out | 5 +++++ .../PackageTests/Check/GitProtocol/cabal.test.hs | 3 +++ .../PackageTests/Check/GitProtocol/pkg.cabal | 16 ++++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 cabal-testsuite/PackageTests/Check/GitProtocol/cabal.out create mode 100644 cabal-testsuite/PackageTests/Check/GitProtocol/cabal.test.hs create mode 100644 cabal-testsuite/PackageTests/Check/GitProtocol/pkg.cabal diff --git a/cabal-testsuite/PackageTests/Check/GitProtocol/cabal.out b/cabal-testsuite/PackageTests/Check/GitProtocol/cabal.out new file mode 100644 index 00000000000..1bc8481c2c0 --- /dev/null +++ b/cabal-testsuite/PackageTests/Check/GitProtocol/cabal.out @@ -0,0 +1,5 @@ +# cabal check +The following errors are likely to affect your build negatively: +Error: [git-protocol] Cloning over git:// might lead to an arbitrary code +execution vulnerability. Use https:// or ssh:// instead. +Error: Hackage would reject this package. diff --git a/cabal-testsuite/PackageTests/Check/GitProtocol/cabal.test.hs b/cabal-testsuite/PackageTests/Check/GitProtocol/cabal.test.hs new file mode 100644 index 00000000000..d57f8e16590 --- /dev/null +++ b/cabal-testsuite/PackageTests/Check/GitProtocol/cabal.test.hs @@ -0,0 +1,3 @@ +import Test.Cabal.Prelude + +main = cabalTest $ fails $ cabal "check" [] diff --git a/cabal-testsuite/PackageTests/Check/GitProtocol/pkg.cabal b/cabal-testsuite/PackageTests/Check/GitProtocol/pkg.cabal new file mode 100644 index 00000000000..5622d522ac3 --- /dev/null +++ b/cabal-testsuite/PackageTests/Check/GitProtocol/pkg.cabal @@ -0,0 +1,16 @@ +cabal-version: 3.0 +name: pkg +version: 0 +category: example +maintainer: me@example.com +synopsis: small synopsis +description: longer description +license: GPL-3.0-only + +library + exposed-modules: Foo + default-language: Haskell2010 + +source-repository head + type: git + location: git://www.example.org/my-repo/ From 911bf5423ebc85b5b64ac406d4811ff6937b65e8 Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Sat, 17 Aug 2024 16:02:38 +0200 Subject: [PATCH 083/207] git:// protocol check: add docs --- doc/cabal-commands.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/cabal-commands.rst b/doc/cabal-commands.rst index 8c05a9b6593..c1987afbfd8 100644 --- a/doc/cabal-commands.rst +++ b/doc/cabal-commands.rst @@ -1327,6 +1327,9 @@ A list of all warnings with their constructor: - ``unrecognised-repo-type``: unrecognised kind of source-repository. - ``repo-no-type``: missing ``type`` in ``source-repository``. - ``repo-no-location``: missing ``location`` in ``source-repository``. +- ``git-protocol``: using insecure ``git://`` protocol + (`explanation `__ + in Git Book). - ``repo-no-module``: missing ``module`` in ``source-repository``. - ``repo-no-tag``: missing ``tag`` in ``source-repository``. - ``repo-relative-dir``: ``subdir`` in ``source-repository`` must be relative. From c87abde5a6faadae79794275914add0a371b2ef7 Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Sat, 17 Aug 2024 15:58:34 +0200 Subject: [PATCH 084/207] Implement git:// protocol check --- Cabal/src/Distribution/PackageDescription/Check.hs | 12 ++++++++++++ .../Distribution/PackageDescription/Check/Warning.hs | 7 +++++++ 2 files changed, 19 insertions(+) diff --git a/Cabal/src/Distribution/PackageDescription/Check.hs b/Cabal/src/Distribution/PackageDescription/Check.hs index 5787dec3b77..8bab6ec961a 100644 --- a/Cabal/src/Distribution/PackageDescription/Check.hs +++ b/Cabal/src/Distribution/PackageDescription/Check.hs @@ -684,6 +684,7 @@ checkSourceRepos rs = do checkP (isNothing repoLocation_) (PackageDistInexcusable MissingLocation) + checkGitProtocol repoLocation_ checkP ( repoType_ == Just (KnownRepoType CVS) && isNothing repoModule_ @@ -722,6 +723,17 @@ checkMissingVcsInfo rs = repoTypeDirname Monotone = ["_MTN"] repoTypeDirname Pijul = [".pijul"] +-- git:// lacks TLS or other encryption, see +-- https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols#_the_cons_4 +checkGitProtocol + :: Monad m + => Maybe String -- Repository location + -> CheckM m () +checkGitProtocol mloc = + checkP + (fmap (isPrefixOf "git://") mloc == Just True) + (PackageBuildWarning GitProtocol) + -- ------------------------------------------------------------ -- Package and distribution checks -- ------------------------------------------------------------ diff --git a/Cabal/src/Distribution/PackageDescription/Check/Warning.hs b/Cabal/src/Distribution/PackageDescription/Check/Warning.hs index 859b3f12c50..4a587a8772f 100644 --- a/Cabal/src/Distribution/PackageDescription/Check/Warning.hs +++ b/Cabal/src/Distribution/PackageDescription/Check/Warning.hs @@ -193,6 +193,7 @@ data CheckExplanation | UnrecognisedSourceRepo String | MissingType | MissingLocation + | GitProtocol | MissingModule | MissingTag | SubdirRelPath @@ -355,6 +356,7 @@ data CheckExplanationID | CIUnrecognisedSourceRepo | CIMissingType | CIMissingLocation + | CIGitProtocol | CIMissingModule | CIMissingTag | CISubdirRelPath @@ -496,6 +498,7 @@ checkExplanationId (NoLicenseFile{}) = CINoLicenseFile checkExplanationId (UnrecognisedSourceRepo{}) = CIUnrecognisedSourceRepo checkExplanationId (MissingType{}) = CIMissingType checkExplanationId (MissingLocation{}) = CIMissingLocation +checkExplanationId (GitProtocol{}) = CIGitProtocol checkExplanationId (MissingModule{}) = CIMissingModule checkExplanationId (MissingTag{}) = CIMissingTag checkExplanationId (SubdirRelPath{}) = CISubdirRelPath @@ -642,6 +645,7 @@ ppCheckExplanationId CINoLicenseFile = "no-license-file" ppCheckExplanationId CIUnrecognisedSourceRepo = "unrecognised-repo-type" ppCheckExplanationId CIMissingType = "repo-no-type" ppCheckExplanationId CIMissingLocation = "repo-no-location" +ppCheckExplanationId CIGitProtocol = "git-protocol" ppCheckExplanationId CIMissingModule = "repo-no-module" ppCheckExplanationId CIMissingTag = "repo-no-tag" ppCheckExplanationId CISubdirRelPath = "repo-relative-dir" @@ -964,6 +968,9 @@ ppExplanation MissingType = "The source-repository 'type' is a required field." ppExplanation MissingLocation = "The source-repository 'location' is a required field." +ppExplanation GitProtocol = + "Cloning over git:// might lead to an arbitrary code execution " + ++ "vulnerability. Use https:// or ssh:// instead." ppExplanation MissingModule = "For a CVS source-repository, the 'module' is a required field." ppExplanation MissingTag = From 87d11a61f019b731be0da46c1b62d401d8682b6f Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Sat, 17 Aug 2024 16:10:41 +0200 Subject: [PATCH 085/207] Add changelog for #10261 --- changelog.d/pr-10261 | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 changelog.d/pr-10261 diff --git a/changelog.d/pr-10261 b/changelog.d/pr-10261 new file mode 100644 index 00000000000..adcae60fd88 --- /dev/null +++ b/changelog.d/pr-10261 @@ -0,0 +1,12 @@ +synopsis: Warn about git:// protocol +packages: cabal-install +prs: #10261 + +description: { + +`cabal check` will warn about insecure git:// protocol in `source-repository`. + +See [Git Book](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols#_the_cons_4) +for an explanation. + +} From 3d60fdd2d120d8812012ef429642e90cd298c98e Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Sat, 17 Aug 2024 18:02:13 +0200 Subject: [PATCH 086/207] Specify GitHub does not support git:// --- Cabal/src/Distribution/PackageDescription/Check/Warning.hs | 3 ++- cabal-testsuite/PackageTests/Check/GitProtocol/cabal.out | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cabal/src/Distribution/PackageDescription/Check/Warning.hs b/Cabal/src/Distribution/PackageDescription/Check/Warning.hs index 4a587a8772f..778a89ddfbe 100644 --- a/Cabal/src/Distribution/PackageDescription/Check/Warning.hs +++ b/Cabal/src/Distribution/PackageDescription/Check/Warning.hs @@ -970,7 +970,8 @@ ppExplanation MissingLocation = "The source-repository 'location' is a required field." ppExplanation GitProtocol = "Cloning over git:// might lead to an arbitrary code execution " - ++ "vulnerability. Use https:// or ssh:// instead." + ++ "vulnerability. Furthermore, popular forges like GitHub do " + ++ "not support it. Use https:// or ssh:// instead." ppExplanation MissingModule = "For a CVS source-repository, the 'module' is a required field." ppExplanation MissingTag = diff --git a/cabal-testsuite/PackageTests/Check/GitProtocol/cabal.out b/cabal-testsuite/PackageTests/Check/GitProtocol/cabal.out index 1bc8481c2c0..eb61b32ab3e 100644 --- a/cabal-testsuite/PackageTests/Check/GitProtocol/cabal.out +++ b/cabal-testsuite/PackageTests/Check/GitProtocol/cabal.out @@ -1,5 +1,6 @@ # cabal check The following errors are likely to affect your build negatively: Error: [git-protocol] Cloning over git:// might lead to an arbitrary code -execution vulnerability. Use https:// or ssh:// instead. +execution vulnerability. Furthermore, popular forges like GitHub do not +support it. Use https:// or ssh:// instead. Error: Hackage would reject this package. From 65c10cdaf59d7bab2d4ca24d523b856804bab094 Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Thu, 22 Aug 2024 00:32:33 -0300 Subject: [PATCH 087/207] Let `cabal init` remember chosen language within current session (#10115) * Add session to keep last chosen language * Drop do block in initCmd * Rename _runPrompt to runPrompt * Rename _runPromptState to runPromptState * Add type alias for NonEmpty String as Inputs * Split fmap and rename newSessionState * Rename arguments based on input and session (state) * Update UnitTest regarding _runPrompt rename * Make PromptIO a newtype * Formatting * Drop unneeded extensions * Hide MonadReader to consumes of PromptIO --------- Co-authored-by: brandon s allbery kf8nh --- cabal-install/src/Distribution/Client/Init.hs | 3 +- .../Client/Init/Interactive/Command.hs | 6 +- .../src/Distribution/Client/Init/Types.hs | 130 +++++++++++++----- .../src/Distribution/Client/InstallSymlink.hs | 4 +- .../ProjectBuilding/PackageFileMonitor.hs | 4 +- .../Distribution/Client/Init/FileCreators.hs | 2 +- .../Distribution/Client/Init/Golden.hs | 10 +- .../Distribution/Client/Init/Interactive.hs | 34 +++-- .../Client/Init/NonInteractive.hs | 24 ++-- .../Distribution/Client/Init/Simple.hs | 14 +- changelog.d/pr-10115 | 10 ++ 11 files changed, 162 insertions(+), 79 deletions(-) create mode 100644 changelog.d/pr-10115 diff --git a/cabal-install/src/Distribution/Client/Init.hs b/cabal-install/src/Distribution/Client/Init.hs index 1a8be086a3f..28cac9fe119 100644 --- a/cabal-install/src/Distribution/Client/Init.hs +++ b/cabal-install/src/Distribution/Client/Init.hs @@ -41,8 +41,7 @@ initCmd v packageDBs repoCtxt comp progdb initFlags = do installedPkgIndex <- getInstalledPackages v comp packageDBs progdb sourcePkgDb <- getSourcePackages v repoCtxt hSetBuffering stdout NoBuffering - settings <- createProject v installedPkgIndex sourcePkgDb initFlags - writeProject settings + runPromptIO (writeProject =<< createProject v installedPkgIndex sourcePkgDb initFlags) where -- When no flag is set, default to interactive. -- diff --git a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs index 48209d37067..a50df356f60 100644 --- a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs @@ -460,14 +460,18 @@ languagePrompt flags pkgType = getLanguage flags $ do ghc2021 = "GHC2021 (requires at least GHC 9.2)" ghc2024 = "GHC2024 (requires at least GHC 9.10)" + lastChosenLanguage <- getLastChosenLanguage + l <- promptList ("Choose a language for your " ++ pkgType) [h2010, h98, ghc2021, ghc2024] - (DefaultPrompt h2010) + (DefaultPrompt (maybe h2010 id lastChosenLanguage)) Nothing True + setLastChosenLanguage (Just l) + if | l == h2010 -> return Haskell2010 | l == h98 -> return Haskell98 diff --git a/cabal-install/src/Distribution/Client/Init/Types.hs b/cabal-install/src/Distribution/Client/Init/Types.hs index ee7d7cbe0c3..0887cb54a71 100644 --- a/cabal-install/src/Distribution/Client/Init/Types.hs +++ b/cabal-install/src/Distribution/Client/Init/Types.hs @@ -1,6 +1,7 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE LambdaCase #-} -- | @@ -39,7 +40,11 @@ module Distribution.Client.Init.Types -- * Typeclasses , Interactive (..) , BreakException (..) - , PurePrompt (..) + , PromptIO + , runPromptIO + , Inputs + , PurePrompt + , runPrompt , evalPrompt , Severity (..) @@ -63,9 +68,12 @@ import qualified Distribution.Client.Compat.Prelude as P import Prelude (read) import Control.Monad.Catch +import Control.Monad.IO.Class +import Control.Monad.Reader import Data.List.NonEmpty (fromList) +import qualified Data.IORef import Distribution.CabalSpecVersion import Distribution.Client.Utils as P import Distribution.Fields.Pretty @@ -282,15 +290,33 @@ mkLiterate _ hs = hs -- -------------------------------------------------------------------- -- -- Interactive prompt monad +newtype PromptIO a = PromptIO (ReaderT (Data.IORef.IORef SessionState) IO a) + deriving (Functor, Applicative, Monad, MonadIO) + +sessionState :: PromptIO (Data.IORef.IORef SessionState) +sessionState = PromptIO ask + +runPromptIO :: PromptIO a -> IO a +runPromptIO (PromptIO pio) = + (Data.IORef.newIORef newSessionState) >>= (runReaderT pio) + +type Inputs = NonEmpty String + newtype PurePrompt a = PurePrompt - { _runPrompt - :: NonEmpty String - -> Either BreakException (a, NonEmpty String) + { runPromptState + :: (Inputs, SessionState) + -> Either BreakException (a, (Inputs, SessionState)) } deriving (Functor) -evalPrompt :: PurePrompt a -> NonEmpty String -> a -evalPrompt act s = case _runPrompt act s of +runPrompt :: PurePrompt a -> Inputs -> Either BreakException (a, Inputs) +runPrompt act args = + fmap + (\(a, (s, _)) -> (a, s)) + (runPromptState act (args, newSessionState)) + +evalPrompt :: PurePrompt a -> Inputs -> a +evalPrompt act s = case runPrompt act s of Left e -> error $ show e Right (a, _) -> a @@ -306,7 +332,7 @@ instance Monad PurePrompt where return = pure PurePrompt a >>= k = PurePrompt $ \s -> case a s of Left e -> Left e - Right (a', s') -> _runPrompt (k a') s' + Right (a', s') -> runPromptState (k a') s' class Monad m => Interactive m where -- input functions @@ -341,36 +367,61 @@ class Monad m => Interactive m where break :: m Bool throwPrompt :: BreakException -> m a -instance Interactive IO where - getLine = P.getLine - readFile = P.readFile - getCurrentDirectory = P.getCurrentDirectory - getHomeDirectory = P.getHomeDirectory - getDirectoryContents = P.getDirectoryContents - listDirectory = P.listDirectory - doesDirectoryExist = P.doesDirectoryExist - doesFileExist = P.doesFileExist - canonicalizePathNoThrow = P.canonicalizePathNoThrow - readProcessWithExitCode = Process.readProcessWithExitCode - getEnvironment = P.getEnvironment - getCurrentYear = P.getCurrentYear - listFilesInside = P.listFilesInside - listFilesRecursive = P.listFilesRecursive - - putStr = P.putStr - putStrLn = P.putStrLn - createDirectory = P.createDirectory - removeDirectory = P.removeDirectoryRecursive - writeFile = P.writeFile - removeExistingFile = P.removeExistingFile - copyFile = P.copyFile - renameDirectory = P.renameDirectory - hFlush = System.IO.hFlush + -- session state functions + getLastChosenLanguage :: m (Maybe String) + setLastChosenLanguage :: (Maybe String) -> m () + +newtype SessionState = SessionState + { lastChosenLanguage :: (Maybe String) + } + +newSessionState :: SessionState +newSessionState = SessionState{lastChosenLanguage = Nothing} + +instance Interactive PromptIO where + getLine = liftIO P.getLine + readFile = liftIO <$> P.readFile + getCurrentDirectory = liftIO P.getCurrentDirectory + getHomeDirectory = liftIO P.getHomeDirectory + getDirectoryContents = liftIO <$> P.getDirectoryContents + listDirectory = liftIO <$> P.listDirectory + doesDirectoryExist = liftIO <$> P.doesDirectoryExist + doesFileExist = liftIO <$> P.doesFileExist + canonicalizePathNoThrow = liftIO <$> P.canonicalizePathNoThrow + readProcessWithExitCode a b c = liftIO $ Process.readProcessWithExitCode a b c + getEnvironment = liftIO P.getEnvironment + getCurrentYear = liftIO P.getCurrentYear + listFilesInside test dir = do + -- test is run within a new env and not the current env + -- all usages of listFilesInside are pure functions actually + liftIO $ P.listFilesInside (\f -> liftIO $ runPromptIO (test f)) dir + listFilesRecursive = liftIO <$> P.listFilesRecursive + + putStr = liftIO <$> P.putStr + putStrLn = liftIO <$> P.putStrLn + createDirectory = liftIO <$> P.createDirectory + removeDirectory = liftIO <$> P.removeDirectoryRecursive + writeFile a b = liftIO $ P.writeFile a b + removeExistingFile = liftIO <$> P.removeExistingFile + copyFile a b = liftIO $ P.copyFile a b + renameDirectory a b = liftIO $ P.renameDirectory a b + hFlush = liftIO <$> System.IO.hFlush message q severity msg | q == silent = pure () | otherwise = putStrLn $ "[" ++ displaySeverity severity ++ "] " ++ msg break = return False - throwPrompt = throwM + throwPrompt = liftIO <$> throwM + + getLastChosenLanguage = do + stateRef <- sessionState + liftIO $ lastChosenLanguage <$> Data.IORef.readIORef stateRef + + setLastChosenLanguage value = do + stateRef <- sessionState + liftIO $ + Data.IORef.modifyIORef + stateRef + (\state -> state{lastChosenLanguage = value}) instance Interactive PurePrompt where getLine = pop @@ -411,13 +462,18 @@ instance Interactive PurePrompt where _ -> return () break = return True - throwPrompt (BreakException e) = PurePrompt $ \s -> + throwPrompt (BreakException e) = PurePrompt $ \(i, _) -> Left $ BreakException - ("Error: " ++ e ++ "\nStacktrace: " ++ show s) + ("Error: " ++ e ++ "\nStacktrace: " ++ show i) + + getLastChosenLanguage = PurePrompt $ \(i, s) -> + Right (lastChosenLanguage s, (i, s)) + setLastChosenLanguage l = PurePrompt $ \(i, s) -> + Right ((), (i, s{lastChosenLanguage = l})) pop :: PurePrompt String -pop = PurePrompt $ \(p :| ps) -> Right (p, fromList ps) +pop = PurePrompt $ \(i :| is, s) -> Right (i, (fromList is, s)) popAbsolute :: PurePrompt String popAbsolute = do @@ -429,7 +485,7 @@ popBool = pop >>= \case "True" -> pure True "False" -> pure False - s -> throwPrompt $ BreakException $ "popBool: " ++ s + i -> throwPrompt $ BreakException $ "popBool: " ++ i popList :: PurePrompt [String] popList = diff --git a/cabal-install/src/Distribution/Client/InstallSymlink.hs b/cabal-install/src/Distribution/Client/InstallSymlink.hs index 1701aa1f652..7a470843779 100644 --- a/cabal-install/src/Distribution/Client/InstallSymlink.hs +++ b/cabal-install/src/Distribution/Client/InstallSymlink.hs @@ -99,7 +99,7 @@ import System.IO.Error import Distribution.Client.Compat.Directory (createFileLink, getSymbolicLinkTarget, pathIsSymbolicLink) import Distribution.Client.Init.Prompt (promptYesNo) -import Distribution.Client.Init.Types (DefaultPrompt (MandatoryPrompt)) +import Distribution.Client.Init.Types (DefaultPrompt (MandatoryPrompt), runPromptIO) import Distribution.Client.Types.OverwritePolicy import qualified Data.ByteString as BS @@ -336,7 +336,7 @@ symlinkBinary inputs@Symlink{publicBindir, privateBindir, publicName, privateNam promptRun :: String -> IO Bool -> IO Bool promptRun s m = do - a <- promptYesNo s MandatoryPrompt + a <- runPromptIO $ promptYesNo s MandatoryPrompt if a then m else pure a -- | Check a file path of a symlink that we would like to create to see if it diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding/PackageFileMonitor.hs b/cabal-install/src/Distribution/Client/ProjectBuilding/PackageFileMonitor.hs index b93064ea7be..71d31cb5926 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding/PackageFileMonitor.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding/PackageFileMonitor.hs @@ -26,7 +26,7 @@ import Distribution.Simple.LocalBuildInfo ) import qualified Data.Set as Set -import Distribution.Client.Init.Types (removeExistingFile) +import Distribution.Client.Init.Types (removeExistingFile, runPromptIO) ----------------------------- -- Package change detection @@ -291,4 +291,4 @@ updatePackageRegFileMonitor invalidatePackageRegFileMonitor :: PackageFileMonitor -> IO () invalidatePackageRegFileMonitor PackageFileMonitor{pkgFileMonitorReg} = - removeExistingFile (fileMonitorCacheFile pkgFileMonitorReg) + runPromptIO $ removeExistingFile (fileMonitorCacheFile pkgFileMonitorReg) diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/FileCreators.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/FileCreators.hs index 38c488dd3a7..63a5774acb1 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/FileCreators.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/FileCreators.hs @@ -81,7 +81,7 @@ tests _v _initFlags comp pkgIx srcDb = "False" ] - case flip _runPrompt inputs $ do + case flip runPrompt inputs $ do projSettings <- createProject comp silent pkgIx srcDb dummyFlags' writeProject projSettings of Left (BreakException ex) -> assertFailure $ show ex diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs index 19efe2eea1a..78387d404da 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs @@ -105,7 +105,7 @@ goldenPkgDescTests v srcDb pkgDir pkgName = ] where runPkgDesc opts flags args = do - case _runPrompt (genPkgDescription flags srcDb) args of + case runPrompt (genPkgDescription flags srcDb) args of Left e -> assertFailure $ show e Right (pkg, _) -> mkStanza $ mkPkgDescription opts pkg @@ -146,7 +146,7 @@ goldenExeTests v pkgIx pkgDir pkgName = ] where runGoldenExe opts args flags = - case _runPrompt (genExeTarget flags pkgIx) args of + case runPrompt (genExeTarget flags pkgIx) args of Right (t, _) -> mkStanza [mkExeStanza opts $ t{_exeDependencies = mangleBaseDep t _exeDependencies}] Left e -> assertFailure $ show e @@ -192,7 +192,7 @@ goldenLibTests v pkgIx pkgDir pkgName = ] where runGoldenLib opts args flags = - case _runPrompt (genLibTarget flags pkgIx) args of + case runPrompt (genLibTarget flags pkgIx) args of Right (t, _) -> mkStanza [mkLibStanza opts $ t{_libDependencies = mangleBaseDep t _libDependencies}] Left e -> assertFailure $ show e @@ -243,7 +243,7 @@ goldenTestTests v pkgIx pkgDir pkgName = ] where runGoldenTest opts args flags = - case _runPrompt (genTestTarget flags pkgIx) args of + case runPrompt (genTestTarget flags pkgIx) args of Left e -> assertFailure $ show e Right (Nothing, _) -> assertFailure @@ -286,7 +286,7 @@ goldenCabalTests v pkgIx srcDb = ] where runGoldenTest args flags = - case _runPrompt (createProject v pkgIx srcDb flags) args of + case runPrompt (createProject v pkgIx srcDb flags) args of Left e -> assertFailure $ show e (Right (ProjectSettings opts pkgDesc (Just libTarget) (Just exeTarget) (Just testTarget), _)) -> do let pkgFields = mkPkgDescription opts pkgDesc diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs index 15714bba952..9ba237cbadc 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs @@ -76,7 +76,7 @@ createProjectTest pkgIx srcDb = , dependencies = Flag [] } - case (_runPrompt $ createProject silent pkgIx srcDb dummyFlags') (fromList ["[]", "3", "quxTest/Main.hs"]) of + case (runPrompt $ createProject silent pkgIx srcDb dummyFlags') (fromList ["[]", "3", "quxTest/Main.hs"]) of Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -186,7 +186,7 @@ createProjectTest pkgIx srcDb = "y" ] - case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + case (runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -286,7 +286,7 @@ createProjectTest pkgIx srcDb = "y" ] - case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + case (runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc (Just lib) Nothing (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -372,7 +372,7 @@ createProjectTest pkgIx srcDb = "y" ] - case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + case (runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc Nothing Nothing (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -460,7 +460,7 @@ createProjectTest pkgIx srcDb = "y" ] - case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + case (runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -546,7 +546,7 @@ createProjectTest pkgIx srcDb = "y" ] - case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + case (runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc (Just lib) Nothing Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -631,7 +631,7 @@ createProjectTest pkgIx srcDb = , extraSrc = Flag ["README.md"] } - case (_runPrompt $ createProject silent pkgIx srcDb flags) inputs of + case (runPrompt $ createProject silent pkgIx srcDb flags) inputs of Right (ProjectSettings opts desc (Just lib) Nothing Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -709,7 +709,7 @@ createProjectTest pkgIx srcDb = "y" ] - case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + case (runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc Nothing (Just exe) Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -809,7 +809,7 @@ fileCreatorTests pkgIx srcDb _pkgName = ] ] where - runGenTest inputs go = case _runPrompt go inputs of + runGenTest inputs go = case runPrompt go inputs of Left e -> assertFailure $ show e Right{} -> return () @@ -1030,6 +1030,20 @@ interactiveTests srcDb = , "Lang_TS!" ] ] + , testGroup + "Check languagePrompt session state" + [ testSimplePrompt + "Use last language" + ( \flags -> do + a <- languagePrompt flags "first language" + b <- languagePrompt flags "second language" + pure (a, b) + ) + (GHC2024, GHC2024) + [ "4" + , "" -- default + ] + ] , testGroup "Check srcDirsPrompt output" [ testNumberedPrompt @@ -1113,7 +1127,7 @@ testPrompt -> [String] -> TestTree testPrompt label f g h input = testCase label $ - case (_runPrompt $ f emptyFlags) (fromList input) of + case (runPrompt $ f emptyFlags) (fromList input) of Left x -> g x -- :: BreakException Right x -> h x -- :: (a, other inputs) diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs index cd618622201..711d50c8e3b 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs @@ -93,7 +93,7 @@ driverFunctionTest pkgIx srcDb comp = , "[\"quxTest/Main.hs\"]" ] - case (_runPrompt $ createProject comp silent pkgIx srcDb dummyFlags') inputs of + case (runPrompt $ createProject comp silent pkgIx srcDb dummyFlags') inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -180,7 +180,7 @@ driverFunctionTest pkgIx srcDb comp = "False" ] - case (_runPrompt $ createProject comp silent pkgIx srcDb dummyFlags') inputs of + case (runPrompt $ createProject comp silent pkgIx srcDb dummyFlags') inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -356,7 +356,7 @@ driverFunctionTest pkgIx srcDb comp = , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]" ] - case ( _runPrompt $ + case ( runPrompt $ createProject comp silent @@ -508,7 +508,7 @@ driverFunctionTest pkgIx srcDb comp = , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]" ] - case ( _runPrompt $ + case ( runPrompt $ createProject comp silent @@ -664,7 +664,7 @@ driverFunctionTest pkgIx srcDb comp = , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] - case (_runPrompt $ createProject comp silent pkgIx srcDb emptyFlags) inputs of + case (runPrompt $ createProject comp silent pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -774,7 +774,7 @@ driverFunctionTest pkgIx srcDb comp = , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] - case (_runPrompt $ createProject comp silent pkgIx srcDb emptyFlags) inputs of + case (runPrompt $ createProject comp silent pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc (Just lib) Nothing Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -865,7 +865,7 @@ driverFunctionTest pkgIx srcDb comp = , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] - case (_runPrompt $ createProject comp silent pkgIx srcDb emptyFlags) inputs of + case (runPrompt $ createProject comp silent pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc Nothing (Just exe) Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -931,7 +931,7 @@ fileCreatorTests pkgIx srcDb comp = , "[]" ] - case (_runPrompt $ genPkgDescription emptyFlags srcDb) inputs of + case (runPrompt $ genPkgDescription emptyFlags srcDb) inputs of Left e -> assertFailure $ show e Right{} -> return () ] @@ -980,7 +980,7 @@ fileCreatorTests pkgIx srcDb comp = , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] - case (_runPrompt $ genLibTarget emptyFlags comp pkgIx defaultCabalVersion) inputs of + case (runPrompt $ genLibTarget emptyFlags comp pkgIx defaultCabalVersion) inputs of Left e -> assertFailure $ show e Right{} -> return () ] @@ -1021,7 +1021,7 @@ fileCreatorTests pkgIx srcDb comp = , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] - case (_runPrompt $ genExeTarget emptyFlags comp pkgIx defaultCabalVersion) inputs of + case (runPrompt $ genExeTarget emptyFlags comp pkgIx defaultCabalVersion) inputs of Left e -> assertFailure $ show e Right{} -> return () ] @@ -1058,7 +1058,7 @@ fileCreatorTests pkgIx srcDb comp = ] flags = emptyFlags{initializeTestSuite = Flag True} - case (_runPrompt $ genTestTarget flags comp pkgIx defaultCabalVersion) inputs of + case (runPrompt $ genTestTarget flags comp pkgIx defaultCabalVersion) inputs of Left e -> assertFailure $ show e Right{} -> return () ] @@ -1403,7 +1403,7 @@ testGo -> [String] -> TestTree testGo label f g h inputs = testCase label $ - case (_runPrompt $ f emptyFlags) (NEL.fromList inputs) of + case (runPrompt $ f emptyFlags) (NEL.fromList inputs) of Left x -> g x Right x -> h x diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs index 13a12ba0827..bbe3c0401bb 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs @@ -69,7 +69,7 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = Nothing Nothing - case _runPrompt (createProject v pkgIx srcDb flags) inputs of + case runPrompt (createProject v pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple lib project: " ++ show e Right (settings', _) -> settings @=? settings' , testCase "Simple lib createProject - with tests" $ do @@ -83,7 +83,7 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = Nothing (Just $ simpleTestTarget (Just pkgName) baseDep) - case _runPrompt (createProject v pkgIx srcDb flags) inputs of + case runPrompt (createProject v pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple lib (with tests)project: " ++ show e Right (settings', _) -> settings @=? settings' , testCase "Simple exe createProject" $ do @@ -97,7 +97,7 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = (Just $ simpleExeTarget Nothing baseDep) Nothing - case _runPrompt (createProject v pkgIx srcDb flags) inputs of + case runPrompt (createProject v pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple exe project: " ++ show e Right (settings', _) -> settings @=? settings' , testCase "Simple lib+exe createProject - no tests" $ do @@ -111,7 +111,7 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = (Just $ simpleExeTarget (Just pkgName) baseDep) Nothing - case _runPrompt (createProject v pkgIx srcDb flags) inputs of + case runPrompt (createProject v pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple lib+exe project: " ++ show e Right (settings', _) -> settings @=? settings' , testCase "Simple lib+exe createProject - with tests" $ do @@ -125,7 +125,7 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = (Just $ simpleExeTarget (Just pkgName) baseDep) (Just $ simpleTestTarget (Just pkgName) baseDep) - case _runPrompt (createProject v pkgIx srcDb flags) inputs of + case runPrompt (createProject v pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple lib+exe (with tests) project: " ++ show e Right (settings', _) -> settings @=? settings' , testCase "Simple standalone tests" $ do @@ -139,12 +139,12 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = Nothing (Just $ simpleTestTarget Nothing baseDep) - case _runPrompt (createProject v pkgIx srcDb flags) inputs of + case runPrompt (createProject v pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple standalone test project: " ++ show e Right (settings', _) -> settings @=? settings' ] where - baseDep = case _runPrompt (getBaseDep pkgIx emptyFlags) $ fromList [] of + baseDep = case runPrompt (getBaseDep pkgIx emptyFlags) $ fromList [] of Left e -> error $ show e Right a -> fst a diff --git a/changelog.d/pr-10115 b/changelog.d/pr-10115 new file mode 100644 index 00000000000..ce288c105c1 --- /dev/null +++ b/changelog.d/pr-10115 @@ -0,0 +1,10 @@ +synopsis: Let cabal init remember chosen language within current session +packages: cabal-install +prs: #10115 +issues: #10096 + +description: { + +When cabal init asks for a language, the last choice will be used as the new default for the current session. + +} \ No newline at end of file From 5eda1fca19763b16507d1c5b54ca1e95586c6a9e Mon Sep 17 00:00:00 2001 From: Fraser Tweedale Date: Thu, 22 Aug 2024 16:06:42 +1000 Subject: [PATCH 088/207] cabal-install: update curl transport to support Basic authentication (#10089) * cabal-install: extract url scheme checks Extract a bunch of string equality checks for the URI scheme to top-level functions. * cabal-install: refactor and document transport checks "They're the same picture". Thus, refactor the *transport supports https* checks. * cabal-install: allow Basic authentication in curl transport Allow the curl transport to use Basic authentication, if and only if the url scheme is HTTPS (i.e. TLS will be used). Retain the existing behaviour (force Digest scheme) for insecure requests. This change is required to support upcoming hackage-server changes. The wget transport already supports Basic authentication. --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .../src/Distribution/Client/HttpUtils.hs | 45 ++++++++++++++----- changelog.d/pr-10089 | 12 +++++ 2 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 changelog.d/pr-10089 diff --git a/cabal-install/src/Distribution/Client/HttpUtils.hs b/cabal-install/src/Distribution/Client/HttpUtils.hs index cad511ef9f8..956241ab307 100644 --- a/cabal-install/src/Distribution/Client/HttpUtils.hs +++ b/cabal-install/src/Distribution/Client/HttpUtils.hs @@ -192,7 +192,7 @@ downloadURI transport verbosity uri path = do -- Only use the external http transports if we actually have to -- (or have been told to do so) let transport' - | uriScheme uri == "http:" + | isHttpURI uri , not (transportManuallySelected transport) = plainHttpTransport | otherwise = @@ -251,20 +251,35 @@ downloadURI transport verbosity uri path = do -- Utilities for repo url management -- +-- | If the remote repo is accessed over HTTPS, ensure that the transport +-- supports HTTPS. remoteRepoCheckHttps :: Verbosity -> HttpTransport -> RemoteRepo -> IO () -remoteRepoCheckHttps verbosity transport repo - | uriScheme (remoteRepoURI repo) == "https:" - , not (transportSupportsHttps transport) = - dieWithException verbosity $ RemoteRepoCheckHttps (unRepoName (remoteRepoName repo)) requiresHttpsErrorMessage - | otherwise = return () +remoteRepoCheckHttps verbosity transport repo = + transportCheckHttpsWithError verbosity transport (remoteRepoURI repo) $ + RemoteRepoCheckHttps (unRepoName (remoteRepoName repo)) requiresHttpsErrorMessage +-- | If the URI scheme is HTTPS, ensure the transport supports HTTPS. transportCheckHttps :: Verbosity -> HttpTransport -> URI -> IO () -transportCheckHttps verbosity transport uri - | uriScheme uri == "https:" +transportCheckHttps verbosity transport uri = + transportCheckHttpsWithError verbosity transport uri $ + TransportCheckHttps uri requiresHttpsErrorMessage + +-- | If the URI scheme is HTTPS, ensure the transport supports HTTPS. +-- If not, fail with the given error. +transportCheckHttpsWithError + :: Verbosity -> HttpTransport -> URI -> CabalInstallException -> IO () +transportCheckHttpsWithError verbosity transport uri err + | isHttpsURI uri , not (transportSupportsHttps transport) = - dieWithException verbosity $ TransportCheckHttps uri requiresHttpsErrorMessage + dieWithException verbosity err | otherwise = return () +isHttpsURI :: URI -> Bool +isHttpsURI uri = uriScheme uri == "https:" + +isHttpURI :: URI -> Bool +isHttpURI uri = uriScheme uri == "http:" + requiresHttpsErrorMessage :: String requiresHttpsErrorMessage = "requires HTTPS however the built-in HTTP implementation " @@ -280,12 +295,12 @@ requiresHttpsErrorMessage = remoteRepoTryUpgradeToHttps :: Verbosity -> HttpTransport -> RemoteRepo -> IO RemoteRepo remoteRepoTryUpgradeToHttps verbosity transport repo | remoteRepoShouldTryHttps repo - , uriScheme (remoteRepoURI repo) == "http:" + , isHttpURI (remoteRepoURI repo) , not (transportSupportsHttps transport) , not (transportManuallySelected transport) = dieWithException verbosity $ TryUpgradeToHttps [name | (name, _, True, _) <- supportedTransports] | remoteRepoShouldTryHttps repo - , uriScheme (remoteRepoURI repo) == "http:" + , isHttpURI (remoteRepoURI repo) , transportSupportsHttps transport = return repo @@ -505,12 +520,18 @@ curlTransport prog = (Just (Left (uname, passwd)), _) -> Just $ Left (uname ++ ":" ++ passwd) (Nothing, Just a) -> Just $ Left a (Nothing, Nothing) -> Nothing + let authnSchemeArg + -- When using TLS, we can accept Basic authentication. Let curl + -- decide based on the scheme(s) offered by the server. + | isHttpsURI uri = "--anyauth" + -- When not using TLS, force Digest scheme + | otherwise = "--digest" case mbAuthStringToken of Just (Left up) -> progInvocation { progInvokeInput = Just . IODataText . unlines $ - [ "--digest" + [ authnSchemeArg , "--user " ++ up ] , progInvokeArgs = ["--config", "-"] ++ progInvokeArgs progInvocation diff --git a/changelog.d/pr-10089 b/changelog.d/pr-10089 new file mode 100644 index 00000000000..ed322194e21 --- /dev/null +++ b/changelog.d/pr-10089 @@ -0,0 +1,12 @@ +synopsis: `curl` transport now supports Basic authentication +packages: cabal-install +prs: #10089 + +description: { + +- The `curl` HTTP transport previously only supported the HTTP Digest + authentication scheme. Basic authentication is now supported + when using HTTPS; Curl will use the scheme offered by the server. + The `wget` transport already supports HTTPS. + +} From 7dd8e8f812d2562efeeca6b17042216e329a8a92 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Tue, 20 Aug 2024 19:06:35 -0400 Subject: [PATCH 089/207] index Paths and Paths_ (resp. for PackageInfo) These can currently be found by searching the documentation for `Paths_pkgname` and `PackageInfo_pkgname`, but you pretty much need to know that to begin with to find them. Add Sphinx index entries to make them more discoverable. --- doc/cabal-package-description-file.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/cabal-package-description-file.rst b/doc/cabal-package-description-file.rst index 839b2dc37db..6ae467b4774 100644 --- a/doc/cabal-package-description-file.rst +++ b/doc/cabal-package-description-file.rst @@ -3015,6 +3015,9 @@ Right now :pkg-field:`executable:main-is` modules are not supported on Accessing data files from package code -------------------------------------- +.. index:: Paths +.. index:: Paths_ + The placement on the target system of files listed in the :pkg-field:`data-files` field varies between systems, and in some cases one can even move packages around after installation @@ -3070,6 +3073,9 @@ the configured data directory for ``pretty-show`` is controlled with the Accessing the package version ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. index:: PackageInfo +.. index:: PackageInfo_ + The auto generated :file:`PackageInfo_{pkgname}` module exports the constant ``version ::`` `Version `__ which is defined as the version of your package as specified in the From 46b9494dca6fd7821574c538e5e062711036c890 Mon Sep 17 00:00:00 2001 From: Francesco Gazzetta Date: Fri, 23 Aug 2024 15:13:42 +0000 Subject: [PATCH 090/207] Update changelog-d to 1.0.1 (#10266) Release: https://codeberg.org/fgaz/changelog-d/releases/tag/v1.0.1 Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .github/workflows/changelogs.yml | 3 ++- changelog.d/config | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/changelogs.yml b/.github/workflows/changelogs.yml index 85bd169b221..388739dfb19 100644 --- a/.github/workflows/changelogs.yml +++ b/.github/workflows/changelogs.yml @@ -28,7 +28,8 @@ jobs: - name: Install changelog-d run: | - curl --create-dirs -o "$HOME/.local/bin/changelog-d" "https://codeberg.org/fgaz/changelog-d/releases/download/v1.0/changelog-d-v1.0-x86_64-linux" + curl --create-dirs -o "$HOME/.local/bin/changelog-d" -sS --fail \ + "https://codeberg.org/fgaz/changelog-d/releases/download/v1.0.1/changelog-d-v1.0.1-x86_64-linux" chmod +x "$HOME/.local/bin/changelog-d" # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-system-path echo "$HOME/.local/bin" >> $GITHUB_PATH diff --git a/changelog.d/config b/changelog.d/config index f4f1b9e5f57..58f62d6a4f3 100644 --- a/changelog.d/config +++ b/changelog.d/config @@ -1,3 +1,9 @@ organization: haskell repository: cabal required-fields: packages prs +packages: + Cabal + Cabal-hooks + Cabal-syntax + cabal-install + cabal-install-solver From f52f5463d006f59f94d5990d04fa544eba301861 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Tue, 20 Aug 2024 22:29:36 -0400 Subject: [PATCH 091/207] Ignore VSCodium work directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 783d3862eec..b14ad050e58 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ _build *~ .*.swp *.bak +.vscode # GHC build From 160dda051edeb512760146e6ce8df65bebfc467c Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Sat, 24 Aug 2024 00:46:26 -0400 Subject: [PATCH 092/207] implement mergify rules for release branches (#10135) * implement mergify rules for release branches We only handled the case of backports previously, but the current release checklist expects that we can commit PRs to release branches during a release (e.g. changelogs, because we want the list of changelog.d files that are actually part of the release). * block merging if PR has a 'blocked:' label * update backports strategy for #10260 --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .github/mergify.yml | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/.github/mergify.yml b/.github/mergify.yml index a7bc364c473..a7336e6a6c7 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -1,3 +1,6 @@ +# Note: We do not use the rebase strategy to merge PRs, because that +# loses information needed by changelog-d to associate commits with PRs. + pull_request_rules: # implementing PR delay logic: apply a label after 2 days of inactivity @@ -25,6 +28,7 @@ pull_request_rules: - label=merge me - label=merge delay passed - '#approved-reviews-by>=2' + - '-label~=^blocked:' # merge+squash strategy - actions: @@ -36,6 +40,7 @@ pull_request_rules: - label=squash+merge me - label=merge delay passed - '#approved-reviews-by>=2' + - '-label~=^blocked:' # merge+no rebase strategy - actions: @@ -47,18 +52,43 @@ pull_request_rules: - label=merge+no rebase - label=merge delay passed - '#approved-reviews-by>=2' + - '-label~=^blocked:' + + # merge strategy for release branches + - actions: + queue: + name: default + name: Put release branch pull requests in the rebase+merge queue + conditions: + - label=merge me + - base!=master + - -body~=backport + - '#approved-reviews-by>=2' + - '-label~=^blocked:' - # rebase+merge strategy for backports: require 1 approver instead of 2 + # merge+squash strategy for release branches + - actions: + queue: + name: squash-merge + name: Put release branch pull requests in the squash+merge queue + conditions: + - base!=master + - label=squash+merge me + - -body~=backport + - '#approved-reviews-by>=2' + - '-label~=^blocked:' + + # merge strategy for backports: require 1 approver instead of 2 - actions: queue: name: default - # Merge with a merge commit name: Put backports in the rebase+merge queue conditions: - label=merge me - base!=master - body~=backport - '#approved-reviews-by>=1' + - '-label~=^blocked:' # merge+squash strategy for backports: require 1 approver instead of 2 - actions: @@ -70,6 +100,7 @@ pull_request_rules: - base!=master - body~=backport - '#approved-reviews-by>=1' + - '-label~=^blocked:' # backports should be labeled as such - actions: @@ -86,6 +117,7 @@ queue_rules: update_bot_account: Mikolaj merge_method: merge update_method: rebase + - name: squash-merge update_bot_account: Mikolaj merge_method: squash From 9ba9228e7d9db17eae3d0e29dba8884e7bc55fe9 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Wed, 21 Aug 2024 23:58:29 -0400 Subject: [PATCH 093/207] validate dependabot configuration Borrowed from Ubuntu (https://github.com/ubuntu/authd/commit/3f9df8f21d952cd33fd44d3834d0edeec1f5766f) Sadly, this won't check our existing config unless I make a dummy update. --- .github/dependabot.yml | 1 + .github/workflows/dependabot.yml | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 .github/workflows/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b3b2315d909..b1c8bd9d9d8 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -13,3 +13,4 @@ updates: schedule: # Check for updates to GitHub Actions every week interval: "weekly" + diff --git a/.github/workflows/dependabot.yml b/.github/workflows/dependabot.yml new file mode 100644 index 00000000000..6219653e4fe --- /dev/null +++ b/.github/workflows/dependabot.yml @@ -0,0 +1,17 @@ +# copied from https://github.com/ubuntu/authd/commit/3f9df8f21d952cd33fd44d3834d0edeec1f5766f + +name: Dependabot rules validation + +on: + pull_request: + paths: + - '.github/dependabot.yml' + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: marocchino/validate-dependabot@v3 + id: validate From c34d8211398357984ebd718ac14283b7f36b28cc Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Wed, 21 Aug 2024 12:47:54 +0100 Subject: [PATCH 094/207] tests: Make structured hash tests invariant to GHC version In 9.8 the Generic instance for tuples changed (see https://gitlab.haskell.org/ghc/ghc/-/issues/24291) for more details. Therefore we remove the dependency on the `Generic` instance and the hashes will be invariant across GHC versions (for now). Fixes #10269 --- .../src/Distribution/Utils/Structured.hs | 43 ++++++++++++++++--- .../Distribution/Utils/Structured.hs | 12 +----- .../Distribution/Client/FileMonitor.hs | 15 ++----- 3 files changed, 43 insertions(+), 27 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Utils/Structured.hs b/Cabal-syntax/src/Distribution/Utils/Structured.hs index 3a21d47a0dd..83ae28995a8 100644 --- a/Cabal-syntax/src/Distribution/Utils/Structured.hs +++ b/Cabal-syntax/src/Distribution/Utils/Structured.hs @@ -5,6 +5,7 @@ {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} @@ -418,12 +419,42 @@ instance Structured a => Structured (Ratio a) where structure = containerStructu instance Structured a => Structured [a] where structure = containerStructure instance Structured a => Structured (NonEmpty a) where structure = containerStructure -instance (Structured a1, Structured a2) => Structured (a1, a2) -instance (Structured a1, Structured a2, Structured a3) => Structured (a1, a2, a3) -instance (Structured a1, Structured a2, Structured a3, Structured a4) => Structured (a1, a2, a3, a4) -instance (Structured a1, Structured a2, Structured a3, Structured a4, Structured a5) => Structured (a1, a2, a3, a4, a5) -instance (Structured a1, Structured a2, Structured a3, Structured a4, Structured a5, Structured a6) => Structured (a1, a2, a3, a4, a5, a6) -instance (Structured a1, Structured a2, Structured a3, Structured a4, Structured a5, Structured a6, Structured a7) => Structured (a1, a2, a3, a4, a5, a6, a7) +-- These instances are defined directly because the generic names for tuples changed +-- in 9.6 (https://gitlab.haskell.org/ghc/ghc/-/issues/24291). +-- +-- By defining our own instances the STuple2 identifier will be used in the hash and +-- hence the same on all GHC versions. + +data STuple2 a b = STuple2 a b deriving (Generic) +data STuple3 a b c = STuple3 a b c deriving (Generic) +data STuple4 a b c d = STuple4 a b c d deriving (Generic) +data STuple5 a b c d e = STuple5 a b c d e deriving (Generic) +data STuple6 a b c d e f = STuple6 a b c d e f deriving (Generic) +data STuple7 a b c d e f g = STuple7 a b c d e f g deriving (Generic) + +instance (Structured a1, Structured a2) => Structured (STuple2 a1 a2) +instance (Structured a1, Structured a2) => Structured (a1, a2) where + structure Proxy = structure @(STuple2 a1 a2) Proxy + +instance (Structured a1, Structured a2, Structured a3) => Structured (STuple3 a1 a2 a3) +instance (Structured a1, Structured a2, Structured a3) => Structured (a1, a2, a3) where + structure Proxy = structure @(STuple3 a1 a2 a3) Proxy + +instance (Structured a1, Structured a2, Structured a3, Structured a4) => Structured (STuple4 a1 a2 a3 a4) +instance (Structured a1, Structured a2, Structured a3, Structured a4) => Structured (a1, a2, a3, a4) where + structure Proxy = structure @(STuple4 a1 a2 a3 a4) Proxy + +instance (Structured a1, Structured a2, Structured a3, Structured a4, Structured a5) => Structured (STuple5 a1 a2 a3 a4 a5) +instance (Structured a1, Structured a2, Structured a3, Structured a4, Structured a5) => Structured (a1, a2, a3, a4, a5) where + structure Proxy = structure @(STuple5 a1 a2 a3 a4 a5) Proxy + +instance (Structured a1, Structured a2, Structured a3, Structured a4, Structured a5, Structured a6) => Structured (STuple6 a1 a2 a3 a4 a5 a6) +instance (Structured a1, Structured a2, Structured a3, Structured a4, Structured a5, Structured a6) => Structured (a1, a2, a3, a4, a5, a6) where + structure Proxy = structure @(STuple6 a1 a2 a3 a4 a5 a6) Proxy + +instance (Structured a1, Structured a2, Structured a3, Structured a4, Structured a5, Structured a6, Structured a7) => Structured (STuple7 a1 a2 a3 a4 a5 a6 a7) +instance (Structured a1, Structured a2, Structured a3, Structured a4, Structured a5, Structured a6, Structured a7) => Structured (a1, a2, a3, a4, a5, a6, a7) where + structure Proxy = structure @(STuple7 a1 a2 a3 a4 a5 a6 a7) Proxy instance Structured BS.ByteString where structure = nominalStructure instance Structured LBS.ByteString where structure = nominalStructure diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs index d932ef59a33..5f7e5cd36fe 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs @@ -30,16 +30,8 @@ md5Check proxy md5Int = structureHash proxy @?= md5FromInteger md5Int md5CheckGenericPackageDescription :: Proxy GenericPackageDescription -> Assertion md5CheckGenericPackageDescription proxy = md5Check proxy -#if MIN_VERSION_base(4,19,0) - 0x62ad178a75f041af29947c9b3d83e6ed -#else - 0xba8f0baa8074fd238ad36a309399349e -#endif + 0xe40d8d67b85712f245354657d7a80165 md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion md5CheckLocalBuildInfo proxy = md5Check proxy -#if MIN_VERSION_base(4,19,0) - 0xc68e9c0758c4bf2d72fe82b3d55cee34 -#else - 0xcf7e7bbcaec504d745fe086eec1786ff -#endif + 0xb0a61f1d93717a92b2b4ecbe0bc3abd4 diff --git a/cabal-install/tests/UnitTests/Distribution/Client/FileMonitor.hs b/cabal-install/tests/UnitTests/Distribution/Client/FileMonitor.hs index f3c8145bc49..88901d17cb7 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/FileMonitor.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/FileMonitor.hs @@ -88,17 +88,10 @@ tests mtimeChange = Windows -> expectFailBecause msg _ -> id fingerprintStateGlob1, fingerprintStateGlob2, fingerprintStateFileSet1, fingerprintStateFileSet2 :: Word64 -#if MIN_VERSION_base(4,19,0) - fingerprintStateGlob1 = 0x4ebc6a7d12bb2132 - fingerprintStateGlob2 = 0x2c2292eeda0a9319 - fingerprintStateFileSet1 = 0x01df5796f9030851 - fingerprintStateFileSet2 = 0x2f5c472be17bee98 -#else - fingerprintStateGlob1 = 0xf32c0d1644dd9ee5 - fingerprintStateGlob2 = 0x0f2494f7b6031fb6 - fingerprintStateFileSet1 = 0x06d4a13275c24282 - fingerprintStateFileSet2 = 0x791b2a88684b5f37 -#endif + fingerprintStateGlob1 = 0x8d6292a27f48ab78 + fingerprintStateGlob2 = 0xa69393cf17cb6c71 + fingerprintStateFileSet1 = 0x441fcb5eaf403013 + fingerprintStateFileSet2 = 0x129db82bba47f56f -- Check the file system behaves the way we expect it to From 6972c6d8120e02f982d611db7014c2018d6053ce Mon Sep 17 00:00:00 2001 From: Alberto Fanton Date: Mon, 26 Aug 2024 13:00:06 +0200 Subject: [PATCH 095/207] Add check on project root file and fail if broken link (#10103) * Add ProjectRootUsability datatype * Make findProjectRoot aware of broken files * Add changelog entry * Fix typos --- .../src/Distribution/Client/ProjectConfig.hs | 103 +++++++++++++----- .../Distribution/Client/ProjectConfig.hs | 45 ++++++++ .../cabal.project.dir.broken/.gitkeep | 0 .../project-root/cabal.project.symlink | 1 + .../project-root/cabal.project.symlink.broken | 1 + changelog.d/pr-10103 | 14 +++ 6 files changed, 139 insertions(+), 25 deletions(-) create mode 100644 cabal-install/tests/fixtures/project-root/cabal.project.dir.broken/.gitkeep create mode 120000 cabal-install/tests/fixtures/project-root/cabal.project.symlink create mode 120000 cabal-install/tests/fixtures/project-root/cabal.project.symlink.broken create mode 100644 changelog.d/pr-10103 diff --git a/cabal-install/src/Distribution/Client/ProjectConfig.hs b/cabal-install/src/Distribution/Client/ProjectConfig.hs index 06f4e4e555d..aabb318e9d9 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig.hs @@ -3,6 +3,7 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TypeApplications #-} -- | Handling project configuration. module Distribution.Client.ProjectConfig @@ -18,8 +19,10 @@ module Distribution.Client.ProjectConfig -- * Project root , findProjectRoot + , getProjectRootUsability , ProjectRoot (..) - , BadProjectRoot + , BadProjectRoot (..) + , ProjectRootUsability (..) -- * Project config files , readProjectConfig @@ -196,6 +199,7 @@ import qualified Codec.Archive.Tar.Entry as Tar import qualified Distribution.Client.GZipUtils as GZipUtils import qualified Distribution.Client.Tar as Tar +import Control.Exception (handle) import Control.Monad.Trans (liftIO) import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy as LBS @@ -215,9 +219,11 @@ import System.Directory ( canonicalizePath , doesDirectoryExist , doesFileExist + , doesPathExist , getCurrentDirectory , getDirectoryContents , getHomeDirectory + , pathIsSymbolicLink ) import System.FilePath hiding (combine) import System.IO @@ -529,6 +535,24 @@ resolveBuildTimeSettings -- Reading and writing project config files -- +-- | Get @ProjectRootUsability@ of a given file +getProjectRootUsability :: FilePath -> IO ProjectRootUsability +getProjectRootUsability filePath = do + exists <- doesFileExist filePath + if exists + then return ProjectRootUsabilityPresentAndUsable + else do + let isUsableAction = + handle @IOException + -- NOTE: if any IOException is raised, we assume the file does not exist. + -- That is what happen when we call @pathIsSymbolicLink@ on a @FilePath@ that does not exist. + (const $ pure False) + ((||) <$> pathIsSymbolicLink filePath <*> doesPathExist filePath) + isUnusable <- isUsableAction + if isUnusable + then return ProjectRootUsabilityPresentAndUnusable + else return ProjectRootUsabilityNotPresent + -- | Find the root of this project. -- -- The project directory will be one of the following: @@ -552,13 +576,18 @@ findProjectRoot verbosity mprojectDir mprojectFile = do "Specifying an absolute path to the project file is deprecated." <> " Use --project-dir to set the project's directory." - doesFileExist file >>= \case - False -> left (BadProjectRootExplicitFile file) - True -> uncurry projectRoot =<< first dropTrailingPathSeparator . splitFileName <$> canonicalizePath file + getProjectRootUsability file >>= \case + ProjectRootUsabilityPresentAndUsable -> + uncurry projectRoot + =<< first dropTrailingPathSeparator . splitFileName <$> canonicalizePath file + ProjectRootUsabilityNotPresent -> + left (BadProjectRootExplicitFileNotFound file) + ProjectRootUsabilityPresentAndUnusable -> + left (BadProjectRootFileBroken file) | otherwise -> probeProjectRoot mprojectFile Just dir -> doesDirectoryExist dir >>= \case - False -> left (BadProjectRootDir dir) + False -> left (BadProjectRootDirNotFound dir) True -> do projectDir <- canonicalizePath dir @@ -566,13 +595,21 @@ findProjectRoot verbosity mprojectDir mprojectFile = do Nothing -> pure $ Right (ProjectRootExplicit projectDir defaultProjectFile) Just projectFile | isAbsolute projectFile -> - doesFileExist projectFile >>= \case - False -> left (BadProjectRootAbsoluteFile projectFile) - True -> Right . ProjectRootExplicitAbsolute dir <$> canonicalizePath projectFile + getProjectRootUsability projectFile >>= \case + ProjectRootUsabilityNotPresent -> + left (BadProjectRootAbsoluteFileNotFound projectFile) + ProjectRootUsabilityPresentAndUsable -> + Right . ProjectRootExplicitAbsolute dir <$> canonicalizePath projectFile + ProjectRootUsabilityPresentAndUnusable -> + left (BadProjectRootFileBroken projectFile) | otherwise -> - doesFileExist (projectDir projectFile) >>= \case - False -> left (BadProjectRootDirFile dir projectFile) - True -> projectRoot projectDir projectFile + getProjectRootUsability (projectDir projectFile) >>= \case + ProjectRootUsabilityNotPresent -> + left (BadProjectRootDirFileNotFound dir projectFile) + ProjectRootUsabilityPresentAndUsable -> + projectRoot projectDir projectFile + ProjectRootUsabilityPresentAndUnusable -> + left (BadProjectRootFileBroken projectFile) where left = pure . Left @@ -597,34 +634,50 @@ probeProjectRoot mprojectFile = do go dir | isDrive dir || dir == homedir = case mprojectFile of Nothing -> return (Right (ProjectRootImplicit startdir)) - Just file -> return (Left (BadProjectRootExplicitFile file)) + Just file -> return (Left (BadProjectRootExplicitFileNotFound file)) go dir = do - exists <- doesFileExist (dir projectFileName) - if exists - then return (Right (ProjectRootExplicit dir projectFileName)) - else go (takeDirectory dir) + getProjectRootUsability (dir projectFileName) >>= \case + ProjectRootUsabilityNotPresent -> + go (takeDirectory dir) + ProjectRootUsabilityPresentAndUsable -> + return (Right $ ProjectRootExplicit dir projectFileName) + ProjectRootUsabilityPresentAndUnusable -> + return (Left $ BadProjectRootFileBroken projectFileName) -- | Errors returned by 'findProjectRoot'. data BadProjectRoot - = BadProjectRootExplicitFile FilePath - | BadProjectRootDir FilePath - | BadProjectRootAbsoluteFile FilePath - | BadProjectRootDirFile FilePath FilePath - deriving (Show, Typeable) + = BadProjectRootExplicitFileNotFound FilePath + | BadProjectRootDirNotFound FilePath + | BadProjectRootAbsoluteFileNotFound FilePath + | BadProjectRootDirFileNotFound FilePath FilePath + | BadProjectRootFileBroken FilePath + deriving (Show, Typeable, Eq) instance Exception BadProjectRoot where displayException = renderBadProjectRoot renderBadProjectRoot :: BadProjectRoot -> String renderBadProjectRoot = \case - BadProjectRootExplicitFile projectFile -> + BadProjectRootExplicitFileNotFound projectFile -> "The given project file '" ++ projectFile ++ "' does not exist." - BadProjectRootDir dir -> + BadProjectRootDirNotFound dir -> "The given project directory '" <> dir <> "' does not exist." - BadProjectRootAbsoluteFile file -> + BadProjectRootAbsoluteFileNotFound file -> "The given project file '" <> file <> "' does not exist." - BadProjectRootDirFile dir file -> + BadProjectRootDirFileNotFound dir file -> "The given project directory/file combination '" <> dir file <> "' does not exist." + BadProjectRootFileBroken file -> + "The given project file '" <> file <> "' is broken. Is it a broken symbolic link?" + +-- | State of the project file, encodes if the file can be used +data ProjectRootUsability + = -- | The file is present and can be used + ProjectRootUsabilityPresentAndUsable + | -- | The file is present but can't be used (e.g. broken symlink) + ProjectRootUsabilityPresentAndUnusable + | -- | The file is not present + ProjectRootUsabilityNotPresent + deriving (Eq, Show) withGlobalConfig :: Verbosity diff --git a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs index 9b7c31e2376..1996dab1a1d 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs @@ -98,6 +98,7 @@ tests = , testProperty "specific" prop_roundtrip_printparse_specific , testProperty "all" prop_roundtrip_printparse_all ] + , testGetProjectRootUsability , testFindProjectRoot ] where @@ -106,6 +107,31 @@ tests = CompilerId GHC v -> v < mkVersion [7, 7] _ -> False +testGetProjectRootUsability :: TestTree +testGetProjectRootUsability = + testGroup + "getProjectRootUsability" + [ test "relative path" file ProjectRootUsabilityPresentAndUsable + , test "absolute path" absFile ProjectRootUsabilityPresentAndUsable + , test "symbolic link" fileSymlink ProjectRootUsabilityPresentAndUsable + , test "file not present" fileNotPresent ProjectRootUsabilityNotPresent + , test "directory" brokenDirCabalProject ProjectRootUsabilityPresentAndUnusable + , test "broken symbolic link" fileSymlinkBroken ProjectRootUsabilityPresentAndUnusable + ] + where + dir = fixturesDir "project-root" + file = defaultProjectFile + absFile = dir file + fileNotPresent = file <.> "not-present" + fileSymlink = file <.> "symlink" + fileSymlinkBroken = fileSymlink <.> "broken" + brokenDirCabalProject = "cabal" <.> "project" <.> "dir" <.> "broken" + test name fileName expectedState = + testCase name $ + withCurrentDirectory dir $ + getProjectRootUsability fileName + >>= (@?= expectedState) + testFindProjectRoot :: TestTree testFindProjectRoot = testGroup @@ -116,6 +142,10 @@ testFindProjectRoot = , test "explicit file in lib" (cd libDir) Nothing (Just file) (succeeds dir file) , test "other file" (cd dir) Nothing (Just fileOther) (succeeds dir fileOther) , test "other file in lib" (cd libDir) Nothing (Just fileOther) (succeeds dir fileOther) + , test "symbolic link" (cd dir) Nothing (Just fileSymlink) (succeeds dir fileSymlink) + , test "symbolic link in lib" (cd libDir) Nothing (Just fileSymlink) (succeeds dir fileSymlink) + , test "broken symbolic link" (cd dir) Nothing (Just fileSymlinkBroken) (failsWith $ BadProjectRootFileBroken fileSymlinkBroken) + , test "broken symbolic link in lib" (cd libDir) Nothing (Just fileSymlinkBroken) (failsWith $ BadProjectRootFileBroken fileSymlinkBroken) , -- Deprecated use-case test "absolute file" Nothing Nothing (Just absFile) (succeeds dir file) , test "nested file" (cd dir) Nothing (Just nixFile) (succeeds dir nixFile) @@ -137,6 +167,9 @@ testFindProjectRoot = nixFile = "nix" file nixOther = nixFile <.> "other" + fileSymlink = file <.> "symlink" + fileSymlinkBroken = fileSymlink <.> "broken" + missing path = Just (path <.> "does_not_exist") test name wrap projectDir projectFile validate = @@ -165,6 +198,18 @@ testFindProjectRoot = Left _ -> pure () Right x -> assertFailure $ "Expected an error, but found " <> show x + failsWith expectedError result = case result of + Left actualError -> + if actualError == expectedError + then pure () + else + assertFailure $ + "Expected an error " + <> show expectedError + <> ", but found " + <> show actualError + Right x -> assertFailure $ "Expected an error, but found " <> show x + fixturesDir :: FilePath fixturesDir = unsafePerformIO $ diff --git a/cabal-install/tests/fixtures/project-root/cabal.project.dir.broken/.gitkeep b/cabal-install/tests/fixtures/project-root/cabal.project.dir.broken/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cabal-install/tests/fixtures/project-root/cabal.project.symlink b/cabal-install/tests/fixtures/project-root/cabal.project.symlink new file mode 120000 index 00000000000..b4c9ceac597 --- /dev/null +++ b/cabal-install/tests/fixtures/project-root/cabal.project.symlink @@ -0,0 +1 @@ +cabal.project \ No newline at end of file diff --git a/cabal-install/tests/fixtures/project-root/cabal.project.symlink.broken b/cabal-install/tests/fixtures/project-root/cabal.project.symlink.broken new file mode 120000 index 00000000000..cfa0a46515b --- /dev/null +++ b/cabal-install/tests/fixtures/project-root/cabal.project.symlink.broken @@ -0,0 +1 @@ +does-not-exist \ No newline at end of file diff --git a/changelog.d/pr-10103 b/changelog.d/pr-10103 new file mode 100644 index 00000000000..3e68cf38d3c --- /dev/null +++ b/changelog.d/pr-10103 @@ -0,0 +1,14 @@ +synopsis: Enhance error detection for cabal root project files, including broken symlinks + +packages: cabal-install + +prs: #10103 + +issues: #9937 + +description: { + +- Added proper detection and reporting for issues with cabal root project files. Previously, these files were silently ignored if they were broken symlinks. Now, `cabal` will exit +with an error in such case. + +} From 5b83f86a516c3a50391cfcf720d49097fb5ea93c Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Tue, 27 Aug 2024 13:08:03 +0100 Subject: [PATCH 096/207] hackage-tests: Add --index-state argument to fix the cabal files We need to fix the index-state we test against so a new bad cabal file doesn't take down the CI for everyone. Towards #10284 --- Cabal-tests/Cabal-tests.cabal | 1 + Cabal-tests/tests/HackageTests.hs | 53 ++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/Cabal-tests/Cabal-tests.cabal b/Cabal-tests/Cabal-tests.cabal index f7fdc2fb85d..60ae8828610 100644 --- a/Cabal-tests/Cabal-tests.cabal +++ b/Cabal-tests/Cabal-tests.cabal @@ -149,6 +149,7 @@ test-suite hackage-tests , deepseq , directory , filepath + , time build-depends: base-compat >=0.11.0 && <0.14 diff --git a/Cabal-tests/tests/HackageTests.hs b/Cabal-tests/tests/HackageTests.hs index 9bff0ce05cc..e400e73629d 100644 --- a/Cabal-tests/tests/HackageTests.hs +++ b/Cabal-tests/tests/HackageTests.hs @@ -33,6 +33,7 @@ import System.FilePath (()) import Data.Orphans () import qualified Codec.Archive.Tar as Tar +import qualified Codec.Archive.Tar.Entry as Tar import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteString.Lazy as BSL @@ -56,11 +57,14 @@ import Data.TreeDiff.Instances.Cabal () import Data.TreeDiff.Pretty (ansiWlEditExprCompact) #endif +import Data.Time.Clock.System +import Data.Time.Format + ------------------------------------------------------------------------------- -- parseIndex: Index traversal ------------------------------------------------------------------------------- -parseIndex :: (Monoid a, NFData a) => (FilePath -> Bool) +parseIndex :: (Monoid a, NFData a) => (Tar.EpochTime -> FilePath -> Bool) -> (FilePath -> B.ByteString -> IO a) -> IO a parseIndex predicate action = do configPath <- getCabalConfigPath @@ -99,7 +103,7 @@ parseIndex predicate action = do parseIndex' :: (Monoid a, NFData a) - => (FilePath -> Bool) + => (Tar.EpochTime -> FilePath -> Bool) -> (FilePath -> B.ByteString -> IO a) -> FilePath -> IO a parseIndex' predicate action path = do putStrLn $ "Reading index from: " ++ path @@ -110,7 +114,7 @@ parseIndex' predicate action path = do where cons entry entries - | predicate (Tar.entryPath entry) = entry : entries + | predicate (Tar.entryTime entry) (Tar.entryPath entry) = entry : entries | otherwise = entries f entry = case Tar.entryContent entry of @@ -320,6 +324,13 @@ main = join (O.execParser opts) , O.progDesc "tests using Hackage's index" ] + indexP = + fmap cvt <$> O.optional (O.strOption (O.long "index-state" <> O.metavar "YYYY-MM-DD")) + where + cvt = + systemSeconds . utcToSystemTime . + parseTimeOrError False defaultTimeLocale "%Y-%m-%d" + optsP = subparser [ command "read-fields" readFieldsP "Parse outer format (to '[Field]', TODO: apply Quirks)" @@ -330,20 +341,20 @@ main = join (O.execParser opts) defaultA = do putStrLn "Default action: parsec k" - parsecA (mkPredicate ["k"]) False + parsecA ["k"] False Nothing - readFieldsP = readFieldsA <$> prefixP - readFieldsA pfx = parseIndex pfx readFieldTest + readFieldsP = readFieldsA <$> prefixP <*> indexP + readFieldsA pfx idx = parseIndex (mkPredicate pfx idx) readFieldTest - parsecP = parsecA <$> prefixP <*> keepGoingP + parsecP = parsecA <$> prefixP <*> keepGoingP <*> indexP keepGoingP = O.flag' True (O.long "keep-going") <|> O.flag' False (O.long "no-keep-going") <|> pure False - parsecA pfx keepGoing = do + parsecA pfx keepGoing idx = do begin <- Clock.getTime Clock.Monotonic - ParsecResult n w f <- parseIndex pfx (parseParsecTest keepGoing) + ParsecResult n w f <- parseIndex (mkPredicate pfx idx) (parseParsecTest keepGoing) end <- Clock.getTime Clock.Monotonic let diff = Clock.toNanoSecs $ Clock.diffTimeSpec end begin @@ -353,14 +364,14 @@ main = join (O.execParser opts) putStrLn $ showFFloat (Just 6) (fromInteger diff / 1e9 :: Double) " seconds elapsed" putStrLn $ showFFloat (Just 6) (fromInteger diff / 1e6 / fromIntegral n :: Double) " milliseconds per file" - roundtripP = roundtripA <$> prefixP <*> testFieldsP - roundtripA pfx testFieldsTransform = do - Sum n <- parseIndex pfx (roundtripTest testFieldsTransform) + roundtripP = roundtripA <$> prefixP <*> testFieldsP <*> indexP + roundtripA pfx testFieldsTransform idx = do + Sum n <- parseIndex (mkPredicate pfx idx) (roundtripTest testFieldsTransform) putStrLn $ show n ++ " files processed" - checkP = checkA <$> prefixP - checkA pfx = do - CheckResult n w x a b c d e <- parseIndex pfx parseCheckTest + checkP = checkA <$> prefixP <*> indexP + checkA pfx idx = do + CheckResult n w x a b c d e <- parseIndex (mkPredicate pfx idx) parseCheckTest putStrLn $ show n ++ " files processed" putStrLn $ show w ++ " files have lexer/parser warnings" putStrLn $ show x ++ " files have check warnings" @@ -370,7 +381,7 @@ main = join (O.execParser opts) putStrLn $ show d ++ " build dist suspicious warning" putStrLn $ show e ++ " build dist inexcusable" - prefixP = fmap mkPredicate $ many $ O.strArgument $ mconcat + prefixP = many $ O.strArgument $ mconcat [ O.metavar "PREFIX" , O.help "Check only files starting with a prefix" ] @@ -380,8 +391,14 @@ main = join (O.execParser opts) , O.help "Test also 'showFields . fromParsecFields . readFields' transform" ] - mkPredicate [] = const True - mkPredicate pfxs = \n -> any (`isPrefixOf` n) pfxs + indexPredicate :: Maybe Tar.EpochTime -> (k -> Bool) -> (Tar.EpochTime -> k -> Bool) + indexPredicate Nothing k = const k + indexPredicate (Just indexDate) k = + \e -> if (e <= indexDate) then k else const False + + mkPredicate :: [String] -> Maybe Tar.EpochTime -> (Tar.EpochTime -> FilePath -> Bool) + mkPredicate [] idx = indexPredicate idx (const True) + mkPredicate pfxs idx = indexPredicate idx (\n -> any (`isPrefixOf` n) pfxs) command name p desc = O.command name (O.info (p <**> O.helper) (O.progDesc desc)) From c8ff66ebb63b628055f6d7b41d224d178f52f418 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Tue, 27 Aug 2024 13:11:43 +0100 Subject: [PATCH 097/207] ci: Fix --index-state for hackage roundtrip tests As a principle, tests which are required for CI to pass should be reproducible and not depending on external resources changes or being modified. The hackage tests currently violate this by depending on the latest index state from hackage. This is problematic because until the test is fixed all merges into master are blocked. Even though the patches in question have nothing to do with the test. It would be more suitable for a nightly job to run on the latest index and for normal CI to run with a fixed index which is updated periodically in a controlled manner. Fixes #10284 --- validate.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/validate.sh b/validate.sh index 47705300a2d..ff1c9e139a9 100755 --- a/validate.sh +++ b/validate.sh @@ -417,14 +417,18 @@ CMD="$($CABALLISTBIN Cabal-tests:test:rpmvercmp) $TESTSUITEJOBS --hide-successes CMD="$($CABALLISTBIN Cabal-tests:test:no-thunks-test) $TESTSUITEJOBS --hide-successes" (cd Cabal-tests && timed $CMD) || exit 1 + +# See #10284 for why this value is pinned. +HACKAGE_TESTS_INDEX_STATE="--index-state=2024-08-25" + CMD=$($CABALLISTBIN Cabal-tests:test:hackage-tests) -(cd Cabal-tests && timed $CMD read-fields) || exit 1 +(cd Cabal-tests && timed $CMD read-fields $HACKAGE_TESTS_INDEX_STATE) || exit 1 if $HACKAGETESTSALL; then - (cd Cabal-tests && timed $CMD parsec) || exit 1 - (cd Cabal-tests && timed $CMD roundtrip) || exit 1 + (cd Cabal-tests && timed $CMD parsec $HACKAGE_TESTS_INDEX_STATE) || exit 1 + (cd Cabal-tests && timed $CMD roundtrip $HACKAGE_TESTS_INDEX_STATE) || exit 1 else - (cd Cabal-tests && timed $CMD parsec d) || exit 1 - (cd Cabal-tests && timed $CMD roundtrip k) || exit 1 + (cd Cabal-tests && timed $CMD parsec d $HACKAGE_TESTS_INDEX_STATE) || exit 1 + (cd Cabal-tests && timed $CMD roundtrip k $HACKAGE_TESTS_INDEX_STATE) || exit 1 fi } From 912efaeaa2c30931c5d95d244a74a0d25949c6b6 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Sun, 25 Aug 2024 22:34:59 -0400 Subject: [PATCH 098/207] update the pinned index-state to get the new `rere` Without this, #10202 breaks `cabal.project.release` on ghc 9.10.1. --- cabal.bootstrap.project | 2 +- cabal.release.project | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cabal.bootstrap.project b/cabal.bootstrap.project index 5b0c59367af..00e676c24ad 100644 --- a/cabal.bootstrap.project +++ b/cabal.bootstrap.project @@ -14,4 +14,4 @@ benchmarks: False constraints: hashable -arch-native -index-state: hackage.haskell.org 2024-06-17T00:00:01Z +index-state: hackage.haskell.org 2024-07-15T21:05:18Z diff --git a/cabal.release.project b/cabal.release.project index ffd7c18adc1..ee061449efc 100644 --- a/cabal.release.project +++ b/cabal.release.project @@ -5,4 +5,4 @@ import: project-cabal/pkgs/tests.config constraints: hashable -arch-native -index-state: hackage.haskell.org 2024-06-17T00:00:01Z +index-state: hackage.haskell.org 2024-07-15T21:05:18Z From c212577bcb802e717e458d425b7863f4182c58b8 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Mon, 22 Jul 2024 21:25:11 -0400 Subject: [PATCH 099/207] add "ready and waiting" Mergify label The bot can use this to announce PRs that are entering the 2-day waiting period. --- .github/mergify.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.github/mergify.yml b/.github/mergify.yml index a7336e6a6c7..485d34d50d0 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -18,6 +18,32 @@ pull_request_rules: - label=merge+no rebase - '#approved-reviews-by>=2' + # label when Mergify is ready but waiting for the above + - actions: + label: + add: + - ready and waiting + name: Waiting out merge delay (used by bot) + conditions: + - base=master + - -draft + - -closed + - or: + - label=merge me + - label=squash+merge me + - label=merge+no rebase + - '#approved-reviews-by>=2' + - '#changes-requested-reviews-by=0' + # oy + # lifted these from branch protection imports + - check-success=fourmolu + - check-success=hlint + - check-success=Meta checks + - check-success=Doctest Cabal + - check-success=Validate post job + - check-success=Bootstrap post job + - 'check-success=docs/readthedocs.org:cabal' + # rebase+merge strategy - actions: queue: From ed881ecdb91df0a524163c77b500bb3dbf2802ce Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Mon, 5 Aug 2024 11:38:40 +0100 Subject: [PATCH 100/207] Include package version in --promised-dependency flag In the original implementation of promised dependencies I accidentally left over the hard coded `currentCabalId` in the `configureDependencies` function. This led to several errors happening later when the package name and version would be incorrect if you looked at this field (package arguments are not computed using it), it is used when generating cabal macros and something in the haddock options. The solution is to pass the package version in the `--promised-depenency` flag so the format is now ``` NAME-VER[:COMPONENT_NAME]=CID` ``` rather than ``` NAME[:COMPONENT_NAME]=CID ``` Fixes #10166 --- .../Distribution/Utils/Structured.hs | 2 +- Cabal/src/Distribution/Backpack/Configure.hs | 8 ++--- .../Backpack/PreExistingComponent.hs | 6 ++-- Cabal/src/Distribution/Simple/Configure.hs | 28 ++++++++-------- Cabal/src/Distribution/Simple/GHC/Internal.hs | 6 ++-- Cabal/src/Distribution/Simple/Setup/Config.hs | 33 ++++++++++++++++--- .../src/Distribution/Types/GivenComponent.hs | 19 +++++++++++ .../Distribution/Types/LocalBuildConfig.hs | 4 +-- .../src/Distribution/Types/LocalBuildInfo.hs | 3 +- .../Distribution/Client/ProjectPlanning.hs | 11 ++++++- .../src/Distribution/Client/Setup.hs | 25 ++++++++++---- .../MultiRepl/CabalMacros/cabal.out | 10 ++++++ .../MultiRepl/CabalMacros/cabal.project | 2 ++ .../MultiRepl/CabalMacros/cabal.test.hs | 7 ++++ .../MultiRepl/CabalMacros/pkg-a/Foo.hs | 5 +++ .../MultiRepl/CabalMacros/pkg-a/pkg-a.cabal | 8 +++++ .../MultiRepl/CabalMacros/pkg-b/Bar.hs | 12 +++++++ .../MultiRepl/CabalMacros/pkg-b/pkg-b.cabal | 8 +++++ changelog.d/issue-10166 | 20 +++++++++++ 19 files changed, 177 insertions(+), 40 deletions(-) create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CabalMacros/cabal.out create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CabalMacros/cabal.project create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CabalMacros/cabal.test.hs create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-a/Foo.hs create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-a/pkg-a.cabal create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-b/Bar.hs create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-b/pkg-b.cabal create mode 100644 changelog.d/issue-10166 diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs index 5f7e5cd36fe..e30a8790c2b 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs @@ -34,4 +34,4 @@ md5CheckGenericPackageDescription proxy = md5Check proxy md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion md5CheckLocalBuildInfo proxy = md5Check proxy - 0xb0a61f1d93717a92b2b4ecbe0bc3abd4 + 0x2c8550e1552f68bf169fafbfcd8f845a diff --git a/Cabal/src/Distribution/Backpack/Configure.hs b/Cabal/src/Distribution/Backpack/Configure.hs index 8e9eb18ae6a..f3dec5055ee 100644 --- a/Cabal/src/Distribution/Backpack/Configure.hs +++ b/Cabal/src/Distribution/Backpack/Configure.hs @@ -70,7 +70,7 @@ configureComponentLocalBuildInfos -> Flag String -- configIPID -> Flag ComponentId -- configCID -> PackageDescription - -> ([PreExistingComponent], [PromisedComponent]) + -> ([PreExistingComponent], [ConfiguredPromisedComponent]) -> FlagAssignment -- configConfigurationsFlags -> [(ModuleName, Module)] -- configInstantiateWith -> InstalledPackageIndex @@ -118,7 +118,7 @@ configureComponentLocalBuildInfos `Map.union` Map.fromListWith Map.union [ (pkg, Map.singleton (ann_cname aid) aid) - | PromisedComponent pkg aid <- promisedPkgDeps + | ConfiguredPromisedComponent pkg aid <- promisedPkgDeps ] graph1 <- toConfiguredComponents @@ -151,7 +151,7 @@ configureComponentLocalBuildInfos , emptyModuleShape ) ) - | PromisedComponent _ aid <- promisedPkgDeps + | ConfiguredPromisedComponent _ aid <- promisedPkgDeps ] uid_lookup def_uid | Just pkg <- PackageIndex.lookupUnitId installedPackageSet uid = @@ -208,7 +208,7 @@ configureComponentLocalBuildInfos toComponentLocalBuildInfos :: Compiler -> InstalledPackageIndex -- FULL set - -> [PromisedComponent] + -> [ConfiguredPromisedComponent] -> PackageDescription -> [PreExistingComponent] -- external package deps -> [ReadyComponent] diff --git a/Cabal/src/Distribution/Backpack/PreExistingComponent.hs b/Cabal/src/Distribution/Backpack/PreExistingComponent.hs index 5f937de9062..0fba79bcb87 100644 --- a/Cabal/src/Distribution/Backpack/PreExistingComponent.hs +++ b/Cabal/src/Distribution/Backpack/PreExistingComponent.hs @@ -1,7 +1,7 @@ -- | See module Distribution.Backpack.PreExistingComponent ( PreExistingComponent (..) - , PromisedComponent (..) + , ConfiguredPromisedComponent (..) , ipiToPreExistingComponent ) where @@ -24,12 +24,12 @@ import Distribution.Types.AnnotatedId -- These components are promised to @configure@ but are not yet built. -- -- In other words this is 'PreExistingComponent' which doesn't yet exist. -data PromisedComponent = PromisedComponent +data ConfiguredPromisedComponent = ConfiguredPromisedComponent { pr_pkgname :: PackageName , pr_cid :: AnnotatedId ComponentId } -instance Package PromisedComponent where +instance Package ConfiguredPromisedComponent where packageId = packageId . pr_cid -- | Stripped down version of 'LinkedComponent' for things diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index 04929bad030..c9d5d081354 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -828,7 +828,7 @@ computeLocalBuildConfig cfg comp programDb = do data PackageInfo = PackageInfo { internalPackageSet :: Set LibraryName - , promisedDepsSet :: Map (PackageName, ComponentName) ComponentId + , promisedDepsSet :: Map (PackageName, ComponentName) PromisedComponent , installedPackageSet :: InstalledPackageIndex , requiredDepsMap :: Map (PackageName, ComponentName) InstalledPackageInfo } @@ -1113,7 +1113,7 @@ finalCheckPackage -> LBC.PackageBuildDescr -> HookedBuildInfo -> PackageInfo - -> IO ([PreExistingComponent], [PromisedComponent]) + -> IO ([PreExistingComponent], [ConfiguredPromisedComponent]) finalCheckPackage g_pkg_descr ( LBC.PackageBuildDescr @@ -1210,7 +1210,7 @@ configureComponents :: LBC.LocalBuildConfig -> LBC.PackageBuildDescr -> PackageInfo - -> ([PreExistingComponent], [PromisedComponent]) + -> ([PreExistingComponent], [ConfiguredPromisedComponent]) -> IO LocalBuildInfo configureComponents lbc@(LBC.LocalBuildConfig{withPrograms = programDb}) @@ -1373,8 +1373,8 @@ configureComponents return lbi -mkPromisedDepsSet :: [GivenComponent] -> Map (PackageName, ComponentName) ComponentId -mkPromisedDepsSet comps = Map.fromList [((pn, CLibName ln), cid) | GivenComponent pn ln cid <- comps] +mkPromisedDepsSet :: [PromisedComponent] -> Map (PackageName, ComponentName) PromisedComponent +mkPromisedDepsSet comps = Map.fromList [((packageName pn, CLibName ln), p) | p@(PromisedComponent pn ln _) <- comps] -- | Adds the extra program paths from the flags provided to @configure@ as -- well as specified locations for certain known programs and their default @@ -1477,7 +1477,7 @@ dependencySatisfiable -- ^ installed set -> Set LibraryName -- ^ library components - -> Map (PackageName, ComponentName) ComponentId + -> Map (PackageName, ComponentName) PromisedComponent -> Map (PackageName, ComponentName) InstalledPackageInfo -- ^ required dependencies -> (Dependency -> Bool) @@ -1639,14 +1639,14 @@ configureDependencies :: Verbosity -> UseExternalInternalDeps -> Set LibraryName - -> Map (PackageName, ComponentName) ComponentId + -> Map (PackageName, ComponentName) PromisedComponent -> InstalledPackageIndex -- ^ installed packages -> Map (PackageName, ComponentName) InstalledPackageInfo -- ^ required deps -> PackageDescription -> ComponentRequestedSpec - -> IO ([PreExistingComponent], [PromisedComponent]) + -> IO ([PreExistingComponent], [ConfiguredPromisedComponent]) configureDependencies verbosity use_external_internal_deps @@ -1912,7 +1912,7 @@ data DependencyResolution -- we need to build packages in the interactive ghci session, no matter -- whether they have been built before. -- Building them in the configure phase is then redundant and costs time. - PromisedDependency PromisedComponent + PromisedDependency ConfiguredPromisedComponent | -- | An internal dependency ('PackageId' should be a library name) -- which we are going to have to build. (The -- 'PackageId' here is a hack to get a modest amount of @@ -1925,7 +1925,7 @@ selectDependency -- ^ Package id of current package -> Set LibraryName -- ^ package libraries - -> Map (PackageName, ComponentName) ComponentId + -> Map (PackageName, ComponentName) PromisedComponent -- ^ Set of components that are promised, i.e. are not installed already. See 'PromisedDependency' for more details. -> InstalledPackageIndex -- ^ Installed packages @@ -1977,8 +1977,8 @@ selectDependency -- We have to look it up externally do_external_external :: LibraryName -> Either FailedDependency DependencyResolution do_external_external lib - | Just cid <- Map.lookup (dep_pkgname, CLibName lib) promisedIndex = - return $ PromisedDependency (PromisedComponent dep_pkgname (AnnotatedId currentCabalId (CLibName lib) cid)) + | Just pc <- Map.lookup (dep_pkgname, CLibName lib) promisedIndex = + return $ PromisedDependency (ConfiguredPromisedComponent dep_pkgname (AnnotatedId (promisedComponentPackage pc) (CLibName lib) (promisedComponentId pc))) do_external_external lib = do ipi <- case Map.lookup (dep_pkgname, CLibName lib) requiredDepsMap of -- If we know the exact pkg to use, then use it. @@ -1991,8 +1991,8 @@ selectDependency do_external_internal :: LibraryName -> Either FailedDependency DependencyResolution do_external_internal lib - | Just cid <- Map.lookup (dep_pkgname, CLibName lib) promisedIndex = - return $ PromisedDependency (PromisedComponent dep_pkgname (AnnotatedId currentCabalId (CLibName lib) cid)) + | Just pc <- Map.lookup (dep_pkgname, CLibName lib) promisedIndex = + return $ PromisedDependency (ConfiguredPromisedComponent dep_pkgname (AnnotatedId (promisedComponentPackage pc) (CLibName lib) (promisedComponentId pc))) do_external_internal lib = do ipi <- case Map.lookup (dep_pkgname, CLibName lib) requiredDepsMap of -- If we know the exact pkg to use, then use it. diff --git a/Cabal/src/Distribution/Simple/GHC/Internal.hs b/Cabal/src/Distribution/Simple/GHC/Internal.hs index a4b75cdb6d3..ca78dc0fcd9 100644 --- a/Cabal/src/Distribution/Simple/GHC/Internal.hs +++ b/Cabal/src/Distribution/Simple/GHC/Internal.hs @@ -75,8 +75,8 @@ import Distribution.Simple.Program.GHC import Distribution.Simple.Setup.Common (extraCompilationArtifacts) import Distribution.Simple.Utils import Distribution.System -import Distribution.Types.ComponentId (ComponentId) import Distribution.Types.ComponentLocalBuildInfo +import Distribution.Types.GivenComponent import Distribution.Types.LocalBuildInfo import Distribution.Types.TargetInfo import Distribution.Types.UnitId @@ -672,7 +672,7 @@ getHaskellObjects _implInfo lib lbi clbi pref wanted_obj_ext allow_split_objs -- and is a hack to avoid passing bogus `-package` arguments to GHC. The assumption being that -- in 99% of cases we will include the right `-package` so that the C file finds the right headers. mkGhcOptPackages - :: Map (PackageName, ComponentName) ComponentId + :: Map (PackageName, ComponentName) PromisedComponent -> ComponentLocalBuildInfo -> [(OpenUnitId, ModuleRenaming)] mkGhcOptPackages promisedPkgsMap clbi = @@ -680,7 +680,7 @@ mkGhcOptPackages promisedPkgsMap clbi = ] where -- Promised deps are going to be simple UnitIds - promised_cids = Set.fromList (map newSimpleUnitId (Map.elems promisedPkgsMap)) + promised_cids = Set.fromList (map (newSimpleUnitId . promisedComponentId) (Map.elems promisedPkgsMap)) substTopDir :: FilePath -> IPI.InstalledPackageInfo -> IPI.InstalledPackageInfo substTopDir topDir ipo = diff --git a/Cabal/src/Distribution/Simple/Setup/Config.hs b/Cabal/src/Distribution/Simple/Setup/Config.hs index 244f442af46..2407329fc1b 100644 --- a/Cabal/src/Distribution/Simple/Setup/Config.hs +++ b/Cabal/src/Distribution/Simple/Setup/Config.hs @@ -185,7 +185,7 @@ data ConfigFlags = ConfigFlags -- dependencies. , configDependencies :: [GivenComponent] -- ^ The packages depended on which already exist - , configPromisedDependencies :: [GivenComponent] + , configPromisedDependencies :: [PromisedComponent] -- ^ The packages depended on which doesn't yet exist (i.e. promised). -- Promising dependencies enables us to configure components in parallel, -- and avoids expensive builds if they are not necessary. @@ -779,13 +779,13 @@ configureOptions showOrParseArgs = , option "" ["promised-dependency"] - "A list of promised dependencies. E.g., --promised-dependency=\"void=void-0.5.8-177d5cdf20962d0581fe2e4932a6c309\"" + "A list of promised dependencies. E.g., --promised-dependency=\"void-0.5.8=void-0.5.8-177d5cdf20962d0581fe2e4932a6c309\"" configPromisedDependencies (\v flags -> flags{configPromisedDependencies = v}) ( reqArg - "NAME[:COMPONENT_NAME]=CID" - (parsecToReadE (const "dependency expected") ((\x -> [x]) `fmap` parsecGivenComponent)) - (map prettyGivenComponent) + "NAME-VER[:COMPONENT_NAME]=CID" + (parsecToReadE (const "dependency expected") ((\x -> [x]) `fmap` parsecPromisedComponent)) + (map prettyPromisedComponent) ) , option "" @@ -923,6 +923,29 @@ showProfDetailLevelFlag :: Flag ProfDetailLevel -> [String] showProfDetailLevelFlag NoFlag = [] showProfDetailLevelFlag (Flag dl) = [showProfDetailLevel dl] +parsecPromisedComponent :: ParsecParser PromisedComponent +parsecPromisedComponent = do + pn <- parsec + ln <- P.option LMainLibName $ do + _ <- P.char ':' + ucn <- parsec + return $ + if unUnqualComponentName ucn == unPackageName (pkgName pn) + then LMainLibName + else LSubLibName ucn + _ <- P.char '=' + cid <- parsec + return $ PromisedComponent pn ln cid + +prettyPromisedComponent :: PromisedComponent -> String +prettyPromisedComponent (PromisedComponent pn cn cid) = + prettyShow pn + ++ case cn of + LMainLibName -> "" + LSubLibName n -> ":" ++ prettyShow n + ++ "=" + ++ prettyShow cid + parsecGivenComponent :: ParsecParser GivenComponent parsecGivenComponent = do pn <- parsec diff --git a/Cabal/src/Distribution/Types/GivenComponent.hs b/Cabal/src/Distribution/Types/GivenComponent.hs index c8314311d89..235c8c372a0 100644 --- a/Cabal/src/Distribution/Types/GivenComponent.hs +++ b/Cabal/src/Distribution/Types/GivenComponent.hs @@ -3,12 +3,14 @@ module Distribution.Types.GivenComponent ( GivenComponent (..) + , PromisedComponent (..) ) where import Distribution.Compat.Prelude import Distribution.Types.ComponentId import Distribution.Types.LibraryName +import Distribution.Types.PackageId import Distribution.Types.PackageName -- | A 'GivenComponent' represents a library depended on and explicitly @@ -27,3 +29,20 @@ data GivenComponent = GivenComponent instance Binary GivenComponent instance Structured GivenComponent + +-- | A 'PromisedComponent' represents a promised library depended on and explicitly +-- specified by the user/client with @--promised-dependency@ +-- +-- It enables Cabal to know which 'ComponentId' to associate with a library +-- +-- @since 3.14.0.0 +data PromisedComponent = PromisedComponent + { promisedComponentPackage :: PackageId + , promisedComponentName :: LibraryName -- --dependency is for libraries + -- only, not for any component + , promisedComponentId :: ComponentId + } + deriving (Generic, Read, Show, Eq, Typeable) + +instance Binary PromisedComponent +instance Structured PromisedComponent diff --git a/Cabal/src/Distribution/Types/LocalBuildConfig.hs b/Cabal/src/Distribution/Types/LocalBuildConfig.hs index ce9064b2f43..929b5e60889 100644 --- a/Cabal/src/Distribution/Types/LocalBuildConfig.hs +++ b/Cabal/src/Distribution/Types/LocalBuildConfig.hs @@ -22,9 +22,9 @@ module Distribution.Types.LocalBuildConfig import Distribution.Compat.Prelude import Prelude () -import Distribution.Types.ComponentId import Distribution.Types.ComponentLocalBuildInfo import Distribution.Types.ComponentRequestedSpec +import Distribution.Types.GivenComponent import Distribution.Types.PackageDescription import Distribution.Types.UnitId @@ -101,7 +101,7 @@ data ComponentBuildDescr = ComponentBuildDescr -- ^ A map from component name to all matching -- components. These coincide with 'componentGraph' -- There may be more than one matching component because of backpack instantiations - , promisedPkgs :: Map (PackageName, ComponentName) ComponentId + , promisedPkgs :: Map (PackageName, ComponentName) PromisedComponent -- ^ The packages we were promised, but aren't already installed. -- MP: Perhaps this just needs to be a Set UnitId at this stage. , installedPkgs :: InstalledPackageIndex diff --git a/Cabal/src/Distribution/Types/LocalBuildInfo.hs b/Cabal/src/Distribution/Types/LocalBuildInfo.hs index f6af8c29c77..107eefc2766 100644 --- a/Cabal/src/Distribution/Types/LocalBuildInfo.hs +++ b/Cabal/src/Distribution/Types/LocalBuildInfo.hs @@ -103,6 +103,7 @@ import Prelude () import Distribution.Types.ComponentId import Distribution.Types.ComponentLocalBuildInfo import Distribution.Types.ComponentRequestedSpec +import Distribution.Types.GivenComponent import qualified Distribution.Types.LocalBuildConfig as LBC import Distribution.Types.PackageDescription import Distribution.Types.PackageId @@ -160,7 +161,7 @@ pattern LocalBuildInfo -> Maybe (SymbolicPath Pkg File) -> Graph ComponentLocalBuildInfo -> Map ComponentName [ComponentLocalBuildInfo] - -> Map (PackageName, ComponentName) ComponentId + -> Map (PackageName, ComponentName) PromisedComponent -> InstalledPackageIndex -> PackageDescription -> ProgramDb diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 4efa5f313b1..6082e816c99 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -4017,7 +4017,7 @@ setupHsConfigureFlags ] configPromisedDependencies = - [ cidToGivenComponent cid + [ cidToPromisedComponent cid | (cid, is_internal) <- elabLibDependencies elab , is_internal ] @@ -4060,6 +4060,15 @@ setupHsConfigureFlags configCoverageFor = determineCoverageFor elab plan + cidToPromisedComponent :: ConfiguredId -> PromisedComponent + cidToPromisedComponent (ConfiguredId srcid mb_cn cid) = + PromisedComponent srcid ln cid + where + ln = case mb_cn of + Just (CLibName lname) -> lname + Just _ -> error "non-library dependency" + Nothing -> LMainLibName + setupHsConfigureArgs :: ElaboratedConfiguredPackage -> [String] diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index 8d594b2a414..78e864d1a65 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -210,7 +210,9 @@ import Distribution.Simple.Utils import Distribution.System (Platform) import Distribution.Types.GivenComponent ( GivenComponent (..) + , PromisedComponent (..) ) +import Distribution.Types.PackageId import Distribution.Types.PackageVersionConstraint ( PackageVersionConstraint (..) ) @@ -226,6 +228,7 @@ import Distribution.Verbosity import Distribution.Version ( Version , mkVersion + , nullVersion ) import Control.Exception @@ -714,12 +717,22 @@ filterConfigureFlags' flags cabalLibVersion } flags_3_13_0 = - -- Earlier Cabal versions don't understand about .. - flags_latest - { -- Building profiled shared libraries - configProfShared = NoFlag - , configIgnoreBuildTools = NoFlag - } + let scrubVersion pc = + pc + { promisedComponentPackage = + (promisedComponentPackage pc){pkgVersion = nullVersion} + } + in -- Earlier Cabal versions don't understand about .. + flags_latest + { -- Building profiled shared libraries + configProfShared = NoFlag + , configIgnoreBuildTools = NoFlag + , -- Older versions of Cabal don't include the package version in the + -- --promised-dependency flag, by setting the version to nullVersion, + -- it won't be printed. + configPromisedDependencies = + map scrubVersion (configPromisedDependencies flags) + } flags_3_11_0 = flags_3_13_0 diff --git a/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/cabal.out b/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/cabal.out new file mode 100644 index 00000000000..9c141d7ac42 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/cabal.out @@ -0,0 +1,10 @@ +# cabal v2-repl +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - pkg-a-1 (interactive) (lib) (first run) + - pkg-b-0 (interactive) (lib) (first run) +Configuring library for pkg-a-1... +Preprocessing library for pkg-a-1... +Configuring library for pkg-b-0... +Preprocessing library for pkg-b-0... diff --git a/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/cabal.project b/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/cabal.project new file mode 100644 index 00000000000..bf8292adeb5 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/cabal.project @@ -0,0 +1,2 @@ +packages: pkg-a/*.cabal +packages: pkg-b/*.cabal diff --git a/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/cabal.test.hs b/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/cabal.test.hs new file mode 100644 index 00000000000..5a8434c5467 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/cabal.test.hs @@ -0,0 +1,7 @@ +import Test.Cabal.Prelude + +main = do + cabalTest $ do + skipUnlessGhcVersion ">= 9.4" + res <- cabalWithStdin "v2-repl" ["--enable-multi-repl","pkg-b", "pkg-a"] "Bar.bar" + assertOutputContains "3735929054" res diff --git a/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-a/Foo.hs b/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-a/Foo.hs new file mode 100644 index 00000000000..997ca89eecd --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-a/Foo.hs @@ -0,0 +1,5 @@ +module Foo where + +foo :: Int +foo = 42 + diff --git a/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-a/pkg-a.cabal b/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-a/pkg-a.cabal new file mode 100644 index 00000000000..7e4a3e9ef70 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-a/pkg-a.cabal @@ -0,0 +1,8 @@ +cabal-version: 2.2 +name: pkg-a +version: 1 + +library + default-language: Haskell2010 + build-depends: base + exposed-modules: Foo diff --git a/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-b/Bar.hs b/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-b/Bar.hs new file mode 100644 index 00000000000..c3179aa8db6 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-b/Bar.hs @@ -0,0 +1,12 @@ +{-# LANGUAGE CPP #-} +module Bar (foo, bar) where + +import Foo (foo) + +#if MIN_VERSION_pkg_a(0,1,0) +bar :: Int +bar = 0xdeadc0de +#else +bar :: Int +bar = 0xdeadc0d1 +#endif diff --git a/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-b/pkg-b.cabal b/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-b/pkg-b.cabal new file mode 100644 index 00000000000..8e1a273f0c4 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CabalMacros/pkg-b/pkg-b.cabal @@ -0,0 +1,8 @@ +cabal-version: 2.2 +name: pkg-b +version: 0 + +library + default-language: Haskell2010 + build-depends: base, pkg-a + exposed-modules: Bar diff --git a/changelog.d/issue-10166 b/changelog.d/issue-10166 new file mode 100644 index 00000000000..02d313adca9 --- /dev/null +++ b/changelog.d/issue-10166 @@ -0,0 +1,20 @@ +synopsis: Include package version when passing `--promised-dependency` flag +packages: Cabal Cabal-syntax +prs: #10248 +issues: #10166 + +description: { + +The --promised dependency flag now expects an argument in format + +``` +NAME-VER[:COMPONENT_NAME]=CID` +``` + +rather than + +``` +NAME[:COMPONENT_NAME]=CID +``` + +} From 18442e3c11707e9453054381c938e78f3d259652 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Mon, 12 Aug 2024 16:46:01 +0100 Subject: [PATCH 101/207] Fix Cabal macro bound in test It is only on Cabal 3.13 that the symbolic path abstraction was introduced. On CI we only test with Cabal master so the incorrect bound wasn't picked up. --- cabal-testsuite/PackageTests/CustomPreProcess/Setup.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cabal-testsuite/PackageTests/CustomPreProcess/Setup.hs b/cabal-testsuite/PackageTests/CustomPreProcess/Setup.hs index b315119728b..769f1309339 100644 --- a/cabal-testsuite/PackageTests/CustomPreProcess/Setup.hs +++ b/cabal-testsuite/PackageTests/CustomPreProcess/Setup.hs @@ -15,7 +15,7 @@ import Distribution.Simple import Distribution.Simple.LocalBuildInfo import Distribution.Simple.PreProcess import Distribution.Simple.Utils -#if MIN_VERSION_Cabal(3,11,0) +#if MIN_VERSION_Cabal(3,13,0) import Distribution.Utils.Path (getSymbolicPath) #endif @@ -47,7 +47,7 @@ main = defaultMainWithHooks } where builddir = -#if MIN_VERSION_Cabal(3,11,0) +#if MIN_VERSION_Cabal(3,13,0) getSymbolicPath $ #endif buildDir lbi From d31436795673c28ac35432da9b36754c5e4f7ee0 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Thu, 8 Aug 2024 15:00:16 +0100 Subject: [PATCH 102/207] clean: Fix usage of flags vs flags' This fixes a simple oversight where the flags were passed without updating the `--working-dir` argument appropiately. --- Cabal/src/Distribution/Simple.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cabal/src/Distribution/Simple.hs b/Cabal/src/Distribution/Simple.hs index 1423ed8f992..ada1d6c7aad 100644 --- a/Cabal/src/Distribution/Simple.hs +++ b/Cabal/src/Distribution/Simple.hs @@ -550,7 +550,7 @@ cleanAction globalFlags hooks flags args = do flags' = flags{cleanCommonFlags = common'} - mbWorkDirFlag = cleanWorkingDir flags + mbWorkDirFlag = cleanWorkingDir flags' mbWorkDir = flagToMaybe mbWorkDirFlag pbi <- preClean hooks args flags' From 90f7e9ce367897b32329611af13947ef2a5dfc07 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Thu, 8 Aug 2024 16:35:58 +0100 Subject: [PATCH 103/207] Interpret argument to `--gen-pkg-config` relative to `--working-dir` This fixes the --gen-pkg-config to use the symbolic path abstraction, in turn this ensures that we interpret the path appropiately when `--working-dir` is also set. --- Cabal-syntax/src/Distribution/Utils/Path.hs | 6 ++++++ Cabal/src/Distribution/Simple/Register.hs | 7 ++++--- Cabal/src/Distribution/Simple/Setup/Register.hs | 4 ++-- cabal-install/src/Distribution/Client/Install.hs | 12 +++++------- .../src/Distribution/Client/ProjectPlanning.hs | 2 +- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Utils/Path.hs b/Cabal-syntax/src/Distribution/Utils/Path.hs index 765b0ac6143..11213e93863 100644 --- a/Cabal-syntax/src/Distribution/Utils/Path.hs +++ b/Cabal-syntax/src/Distribution/Utils/Path.hs @@ -30,6 +30,7 @@ module Distribution.Utils.Path , Tix , Tmp , Response + , PkgConf -- * Symbolic paths , RelativePath @@ -499,3 +500,8 @@ data Tmp -- -- See Note [Symbolic paths] in Distribution.Utils.Path. data Response + +-- | Abstract directory: directory for pkg-config files. +-- +-- See Note [Symbolic paths] in Distribution.Utils.Path. +data PkgConf diff --git a/Cabal/src/Distribution/Simple/Register.hs b/Cabal/src/Distribution/Simple/Register.hs index 7648c867f99..ac16a67d428 100644 --- a/Cabal/src/Distribution/Simple/Register.hs +++ b/Cabal/src/Distribution/Simple/Register.hs @@ -203,9 +203,10 @@ registerAll pkg lbi regFlags ipis = where modeGenerateRegFile = isJust (flagToMaybe (regGenPkgConf regFlags)) regFile = - fromMaybe - (prettyShow (packageId pkg) <.> "conf") - (fromFlag (regGenPkgConf regFlags)) + interpretSymbolicPathLBI lbi $ + fromMaybe + (makeSymbolicPath (prettyShow (packageId pkg) <.> "conf")) + (fromFlag (regGenPkgConf regFlags)) modeGenerateRegScript = fromFlag (regGenScript regFlags) diff --git a/Cabal/src/Distribution/Simple/Setup/Register.hs b/Cabal/src/Distribution/Simple/Setup/Register.hs index e3eb8d6ac7a..bbd17932245 100644 --- a/Cabal/src/Distribution/Simple/Setup/Register.hs +++ b/Cabal/src/Distribution/Simple/Setup/Register.hs @@ -58,7 +58,7 @@ data RegisterFlags = RegisterFlags { registerCommonFlags :: !CommonSetupFlags , regPackageDB :: Flag PackageDB , regGenScript :: Flag Bool - , regGenPkgConf :: Flag (Maybe FilePath) + , regGenPkgConf :: Flag (Maybe (SymbolicPath Pkg (Dir PkgConf))) , regInPlace :: Flag Bool , regPrintId :: Flag Bool } @@ -154,7 +154,7 @@ registerCommand = "instead of registering, generate a package registration file/directory" regGenPkgConf (\v flags -> flags{regGenPkgConf = v}) - (optArg' "PKG" Flag flagToList) + (optArg' "PKG" (Flag . fmap makeSymbolicPath) (flagToList . fmap (fmap getSymbolicPath))) , option "" ["print-ipid"] diff --git a/cabal-install/src/Distribution/Client/Install.hs b/cabal-install/src/Distribution/Client/Install.hs index 9cf80d3858c..e10cb518c96 100644 --- a/cabal-install/src/Distribution/Client/Install.hs +++ b/cabal-install/src/Distribution/Client/Install.hs @@ -57,7 +57,6 @@ import System.FilePath ( equalFilePath , takeDirectory , (<.>) - , () ) import System.IO ( IOMode (AppendMode) @@ -222,7 +221,6 @@ import Distribution.Simple.Setup import qualified Distribution.Simple.Setup as Cabal import Distribution.Utils.Path hiding ( (<.>) - , () ) import Distribution.Simple.Utils @@ -2021,7 +2019,7 @@ installUnpackedPackage genPkgConfs flags mLogPath = do tmp <- getTemporaryDirectory withTempDirectory verbosity tmp (tempTemplate "pkgConf") $ \dir -> do - let pkgConfDest = dir "pkgConf" + let pkgConfDest = makeSymbolicPath dir makeRelativePathEx "pkgConf" registerFlags' version = (flags version) { Cabal.regGenPkgConf = toFlag (Just pkgConfDest) @@ -2031,16 +2029,16 @@ installUnpackedPackage registerCommonFlags registerFlags' mLogPath - is_dir <- doesDirectoryExist pkgConfDest + is_dir <- doesDirectoryExist (interpretSymbolicPathCWD pkgConfDest) let notHidden = not . isHidden isHidden name = "." `isPrefixOf` name if is_dir then -- Sort so that each prefix of the package -- configurations is well formed - traverse (readPkgConf pkgConfDest) . sort . filter notHidden - =<< getDirectoryContents pkgConfDest - else fmap (: []) $ readPkgConf "." pkgConfDest + traverse (readPkgConf (getSymbolicPath pkgConfDest)) . sort . filter notHidden + =<< getDirectoryContents (getSymbolicPath pkgConfDest) + else fmap (: []) $ readPkgConf "." (getSymbolicPath pkgConfDest) readPkgConf :: FilePath diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 6082e816c99..765ae803a6d 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -4205,7 +4205,7 @@ setupHsRegisterFlags { registerCommonFlags = common , regPackageDB = mempty -- misfeature , regGenScript = mempty -- never use - , regGenPkgConf = toFlag (Just pkgConfFile) + , regGenPkgConf = toFlag (Just (makeSymbolicPath pkgConfFile)) , regInPlace = case elabBuildStyle of BuildInplaceOnly{} -> toFlag True BuildAndInstall -> toFlag False From b8f1cdc70cb22cbcf79501914ae67c9284aa979a Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Thu, 8 Aug 2024 17:26:32 +0100 Subject: [PATCH 104/207] Replace FilePath in PackageDB with SymbolicPath in Cabal This refactoring enforces a simple property * We use symbolic paths in Cabal in order to represent that paths to package databases. These paths is relative to the package root. * We use normal filepaths in cabal-install to represent the path to a package database. These are relative to the current working directory. Paths are explicitly converted from one type to the other at the interface of `cabal-install` and `Cabal`, see `setupHsConfigureArgs` for where this happens. In order to achieve this `PackageDB` is abstracted over what the type of filepaths a specific package db points to. ``` type PackageDBX fp = ... | SpecificPackageDB fp | ... ``` If you are using the Cabal library then you probably want to migrate to use `PackageDBCWD` and `PackageDBStackCWD`. ``` type PackageDBCWD = PackageDBX FilePath type PackageDBStackCWD = [PackageDBCWD] ``` Then at the point where you call commands in the `Cabal` library convert these paths into paths relative to the root of the relevant package. The easiest way to do this is convert any paths into an absolute path. This patch fixes a double interpretation issue when the `--working-dir` option was used and package db paths were offset incorrectly. --- .../src/Test/QuickCheck/Instances/Cabal.hs | 5 +- Cabal-syntax/src/Distribution/Utils/Path.hs | 14 ++-- .../Distribution/Utils/Structured.hs | 2 +- .../tests/custom-setup/CabalDoctestSetup.hs | 14 ++-- Cabal/src/Distribution/Simple/Build.hs | 2 +- Cabal/src/Distribution/Simple/Compiler.hs | 69 +++++++++++++++---- Cabal/src/Distribution/Simple/Configure.hs | 14 ++-- Cabal/src/Distribution/Simple/GHC.hs | 40 ++++++----- Cabal/src/Distribution/Simple/GHC/Build.hs | 2 +- .../Simple/GHC/EnvironmentParser.hs | 8 +-- Cabal/src/Distribution/Simple/GHC/Internal.hs | 14 ++-- Cabal/src/Distribution/Simple/GHCJS.hs | 26 +++---- Cabal/src/Distribution/Simple/HaskellSuite.hs | 10 +-- Cabal/src/Distribution/Simple/Program/GHC.hs | 8 +-- .../src/Distribution/Simple/Program/HcPkg.hs | 41 +++++------ Cabal/src/Distribution/Simple/Program/Hpc.hs | 2 +- Cabal/src/Distribution/Simple/Register.hs | 13 ++-- Cabal/src/Distribution/Simple/Setup/Config.hs | 4 +- Cabal/src/Distribution/Simple/Test.hs | 2 +- Cabal/src/Distribution/Simple/UHC.hs | 31 +++++---- .../src/Distribution/Client/CmdInstall.hs | 27 ++++---- .../src/Distribution/Client/CmdLegacy.hs | 2 +- .../src/Distribution/Client/Configure.hs | 14 ++-- .../src/Distribution/Client/DistDirLayout.hs | 17 ++--- .../src/Distribution/Client/Fetch.hs | 6 +- .../src/Distribution/Client/Freeze.hs | 8 +-- .../src/Distribution/Client/GenBounds.hs | 6 +- .../src/Distribution/Client/IndexUtils.hs | 8 +-- cabal-install/src/Distribution/Client/Init.hs | 2 +- .../src/Distribution/Client/Install.hs | 23 ++++--- cabal-install/src/Distribution/Client/List.hs | 9 +-- cabal-install/src/Distribution/Client/Main.hs | 34 ++++----- .../src/Distribution/Client/PackageHash.hs | 4 +- .../Distribution/Client/ProjectBuilding.hs | 6 +- .../Client/ProjectBuilding/UnpackedPackage.hs | 30 ++++---- .../Client/ProjectConfig/Legacy.hs | 7 +- .../Client/ProjectConfig/Types.hs | 4 +- .../Client/ProjectOrchestration.hs | 13 ++-- .../Distribution/Client/ProjectPlanOutput.hs | 20 ++---- .../Distribution/Client/ProjectPlanning.hs | 35 ++++++---- .../Client/ProjectPlanning/Types.hs | 14 ++-- cabal-install/src/Distribution/Client/Run.hs | 4 +- .../src/Distribution/Client/SetupWrapper.hs | 19 ++--- .../src/Distribution/Client/Utils.hs | 14 ++++ .../UnitTests/Distribution/Client/Init.hs | 3 +- .../Distribution/Client/TreeDiffInstances.hs | 5 +- .../ShowBuildInfo/Complex/single.out | 10 +-- cabal-testsuite/Setup.hs | 2 +- cabal-testsuite/src/Test/Cabal/Monad.hs | 4 +- cabal-testsuite/src/Test/Cabal/Prelude.hs | 10 +-- cabal-testsuite/src/Test/Cabal/Script.hs | 4 +- 51 files changed, 367 insertions(+), 318 deletions(-) diff --git a/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs b/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs index 8eabc450b03..b99d0223b04 100644 --- a/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs +++ b/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE TypeOperators #-} +{-# LANGUAGE FlexibleInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Test.QuickCheck.Instances.Cabal () where @@ -18,7 +19,7 @@ import Distribution.Compat.NonEmptySet (NonEmptySet) import Distribution.Compiler import Distribution.FieldGrammar.Newtypes import Distribution.ModuleName -import Distribution.Simple.Compiler (DebugInfoLevel (..), OptimisationLevel (..), PackageDB (..), ProfDetailLevel (..), knownProfDetailLevels) +import Distribution.Simple.Compiler import Distribution.Simple.Flag (Flag (..)) import Distribution.Simple.InstallDirs import Distribution.Simple.Setup (HaddockTarget (..), TestShowDetails (..), DumpBuildInfo) @@ -476,7 +477,7 @@ instance Arbitrary TestShowDetails where -- PackageDB ------------------------------------------------------------------------------- -instance Arbitrary PackageDB where +instance Arbitrary (PackageDBX FilePath) where arbitrary = oneof [ pure GlobalPackageDB , pure UserPackageDB , SpecificPackageDB <$> arbitraryShortPath diff --git a/Cabal-syntax/src/Distribution/Utils/Path.hs b/Cabal-syntax/src/Distribution/Utils/Path.hs index 11213e93863..62caa220b74 100644 --- a/Cabal-syntax/src/Distribution/Utils/Path.hs +++ b/Cabal-syntax/src/Distribution/Utils/Path.hs @@ -60,7 +60,7 @@ module Distribution.Utils.Path -- ** Working directory handling , interpretSymbolicPathCWD , absoluteWorkingDir - , tryMakeRelativeToWorkingDir + , tryMakeRelative -- ** Module names , moduleNameSymbolicPath @@ -290,7 +290,7 @@ moduleNameSymbolicPath modNm = SymbolicPath $ ModuleName.toFilePath modNm -- (because the program might expect certain paths to be relative). -- -- See Note [Symbolic paths] in Distribution.Utils.Path. -interpretSymbolicPath :: Maybe (SymbolicPath CWD (Dir Pkg)) -> SymbolicPathX allowAbsolute Pkg to -> FilePath +interpretSymbolicPath :: Maybe (SymbolicPath CWD (Dir from)) -> SymbolicPathX allowAbsolute from to -> FilePath interpretSymbolicPath mbWorkDir (SymbolicPath p) = -- Note that this properly handles an absolute symbolic path, -- because if @q@ is absolute, then @p q = q@. @@ -317,7 +317,7 @@ interpretSymbolicPath mbWorkDir (SymbolicPath p) = -- appropriate to use 'interpretSymbolicPathCWD' to provide its arguments. -- -- See Note [Symbolic paths] in Distribution.Utils.Path. -interpretSymbolicPathCWD :: SymbolicPathX allowAbsolute Pkg to -> FilePath +interpretSymbolicPathCWD :: SymbolicPathX allowAbsolute from to -> FilePath interpretSymbolicPathCWD (SymbolicPath p) = p -- | Change what a symbolic path is pointing to. @@ -347,11 +347,13 @@ absoluteWorkingDir :: Maybe (SymbolicPath CWD to) -> IO FilePath absoluteWorkingDir Nothing = Directory.getCurrentDirectory absoluteWorkingDir (Just wd) = Directory.makeAbsolute $ getSymbolicPath wd --- | Try to make a path relative to the current working directory. +-- | Try to make a symbolic path relative. +-- +-- This function does nothing if the path is already relative. -- -- NB: this function may fail to make the path relative. -tryMakeRelativeToWorkingDir :: Maybe (SymbolicPath CWD (Dir dir)) -> SymbolicPath dir to -> IO (SymbolicPath dir to) -tryMakeRelativeToWorkingDir mbWorkDir (SymbolicPath fp) = do +tryMakeRelative :: Maybe (SymbolicPath CWD (Dir dir)) -> SymbolicPath dir to -> IO (SymbolicPath dir to) +tryMakeRelative mbWorkDir (SymbolicPath fp) = do wd <- absoluteWorkingDir mbWorkDir return $ SymbolicPath (FilePath.makeRelative wd fp) diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs index e30a8790c2b..3bdf0465244 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs @@ -34,4 +34,4 @@ md5CheckGenericPackageDescription proxy = md5Check proxy md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion md5CheckLocalBuildInfo proxy = md5Check proxy - 0x2c8550e1552f68bf169fafbfcd8f845a + 0x94827844fdb1afedee525061749fb16f diff --git a/Cabal-tests/tests/custom-setup/CabalDoctestSetup.hs b/Cabal-tests/tests/custom-setup/CabalDoctestSetup.hs index a89ce9b36e7..a6a59c144c9 100644 --- a/Cabal-tests/tests/custom-setup/CabalDoctestSetup.hs +++ b/Cabal-tests/tests/custom-setup/CabalDoctestSetup.hs @@ -103,7 +103,7 @@ import Distribution.Simple (UserHooks (..), autoconfUserHooks, defaultMainWithHooks, simpleUserHooks) import Distribution.Simple.Compiler - (CompilerFlavor (GHC), CompilerId (..), PackageDB (..), compilerId) + (CompilerFlavor (GHC), CompilerId (..), PackageDB, PackageDBX (..), compilerId) import Distribution.Simple.LocalBuildInfo (ComponentLocalBuildInfo (componentPackageDeps), LocalBuildInfo, compiler, withExeLBI, withLibLBI, withPackageDB, withTestLBI @@ -119,8 +119,6 @@ import Distribution.Simple.Utils import Distribution.Text (display) import Distribution.Verbosity -import System.FilePath - (()) import qualified Data.Foldable as F (for_) @@ -160,7 +158,9 @@ import Distribution.Package import Distribution.Utils.Path ( SymbolicPathX , makeSymbolicPath - , makeRelativePathEx ) + , makeRelativePathEx + , interpretSymbolicPathCWD + , ()) import qualified Distribution.Utils.Path as Cabal (getSymbolicPath) import Distribution.Simple.Utils @@ -336,7 +336,7 @@ generateBuildModule testSuiteName flags pkg lbi = do let distPref = fromFlag (buildDistPref flags) -- Package DBs & environments - let dbStack = withPackageDB lbi ++ [ SpecificPackageDB $ toFilePath distPref "package.conf.inplace" ] + let dbStack = withPackageDB lbi ++ [ SpecificPackageDB $ distPref makeRelativePathEx "package.conf.inplace" ] let dbFlags = "-hide-all-packages" : packageDbArgs dbStack let envFlags | ghcCanBeToldToIgnorePkgEnvs = [ "-package-env=-" ] @@ -539,7 +539,7 @@ generateBuildModule testSuiteName flags pkg lbi = do : concatMap specific dbs _ -> ierror where - specific (SpecificPackageDB db) = [ "-package-conf=" ++ db ] + specific (SpecificPackageDB db) = [ "-package-conf=" ++ interpretSymbolicPathCWD db ] specific _ = ierror ierror = error $ "internal error: unexpected package db stack: " ++ show dbstack @@ -557,7 +557,7 @@ generateBuildModule testSuiteName flags pkg lbi = do dbs -> "-clear-package-db" : concatMap single dbs where - single (SpecificPackageDB db) = [ "-package-db=" ++ db ] + single (SpecificPackageDB db) = [ "-package-db=" ++ interpretSymbolicPathCWD db ] single GlobalPackageDB = [ "-global-package-db" ] single UserPackageDB = [ "-user-package-db" ] isSpecific (SpecificPackageDB _) = True diff --git a/Cabal/src/Distribution/Simple/Build.hs b/Cabal/src/Distribution/Simple/Build.hs index f22b5790239..33b523c6177 100644 --- a/Cabal/src/Distribution/Simple/Build.hs +++ b/Cabal/src/Distribution/Simple/Build.hs @@ -911,7 +911,7 @@ createInternalPackageDB verbosity lbi distPref = do existsAlready <- doesPackageDBExist dbPath when existsAlready $ deletePackageDB dbPath createPackageDB verbosity (compiler lbi) (withPrograms lbi) False dbPath - return (SpecificPackageDB dbPath) + return (SpecificPackageDB dbRelPath) where dbRelPath = internalPackageDBPath lbi distPref dbPath = interpretSymbolicPathLBI lbi dbRelPath diff --git a/Cabal/src/Distribution/Simple/Compiler.hs b/Cabal/src/Distribution/Simple/Compiler.hs index 7b9f2ac8059..52395a56668 100644 --- a/Cabal/src/Distribution/Simple/Compiler.hs +++ b/Cabal/src/Distribution/Simple/Compiler.hs @@ -1,6 +1,9 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveDataTypeable #-} +{-# LANGUAGE DeriveFoldable #-} +{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DeriveTraversable #-} ----------------------------------------------------------------------------- @@ -35,11 +38,21 @@ module Distribution.Simple.Compiler , compilerInfo -- * Support for package databases - , PackageDB (..) + , PackageDB , PackageDBStack + , PackageDBCWD + , PackageDBStackCWD + , PackageDBX (..) + , PackageDBStackX + , PackageDBS + , PackageDBStackS , registrationPackageDB , absolutePackageDBPaths , absolutePackageDBPath + , interpretPackageDB + , interpretPackageDBStack + , coercePackageDB + , coercePackageDBStack -- * Support for optimisation levels , OptimisationLevel (..) @@ -95,7 +108,6 @@ import Language.Haskell.Extension import qualified Data.Map as Map (lookup) import System.Directory (canonicalizePath) -import System.FilePath (isRelative) data Compiler = Compiler { compilerId :: CompilerId @@ -181,15 +193,17 @@ compilerInfo c = -- the file system. This can be used to build isolated environments of -- packages, for example to build a collection of related packages -- without installing them globally. -data PackageDB +-- +-- Abstracted over +data PackageDBX fp = GlobalPackageDB | UserPackageDB | -- | NB: the path might be relative or it might be absolute - SpecificPackageDB FilePath - deriving (Eq, Generic, Ord, Show, Read, Typeable) + SpecificPackageDB fp + deriving (Eq, Generic, Ord, Show, Read, Typeable, Functor, Foldable, Traversable) -instance Binary PackageDB -instance Structured PackageDB +instance Binary fp => Binary (PackageDBX fp) +instance Structured fp => Structured (PackageDBX fp) -- | We typically get packages from several databases, and stack them -- together. This type lets us be explicit about that stacking. For example @@ -206,11 +220,20 @@ instance Structured PackageDB -- we can use several custom package dbs and the user package db together. -- -- When it comes to writing, the top most (last) package is used. -type PackageDBStack = [PackageDB] +type PackageDBStackX from = [PackageDBX from] + +type PackageDB = PackageDBX (SymbolicPath Pkg (Dir PkgDB)) +type PackageDBStack = PackageDBStackX (SymbolicPath Pkg (Dir PkgDB)) + +type PackageDBS from = PackageDBX (SymbolicPath from (Dir PkgDB)) +type PackageDBStackS from = PackageDBStackX (SymbolicPath from (Dir PkgDB)) + +type PackageDBCWD = PackageDBX FilePath +type PackageDBStackCWD = PackageDBStackX FilePath -- | Return the package that we should register into. This is the package db at -- the top of the stack. -registrationPackageDB :: PackageDBStack -> PackageDB +registrationPackageDB :: PackageDBStackX from -> PackageDBX from registrationPackageDB dbs = case safeLast dbs of Nothing -> error "internal error: empty package db set" Just p -> p @@ -230,10 +253,30 @@ absolutePackageDBPath _ GlobalPackageDB = return GlobalPackageDB absolutePackageDBPath _ UserPackageDB = return UserPackageDB absolutePackageDBPath mbWorkDir (SpecificPackageDB db) = do let db' = - if isRelative db - then interpretSymbolicPath mbWorkDir (makeRelativePathEx db) - else db - SpecificPackageDB <$> canonicalizePath db' + case symbolicPathRelative_maybe db of + Nothing -> getSymbolicPath db + Just rel_path -> interpretSymbolicPath mbWorkDir rel_path + SpecificPackageDB . makeSymbolicPath <$> canonicalizePath db' + +interpretPackageDB :: Maybe (SymbolicPath CWD (Dir Pkg)) -> PackageDB -> PackageDBCWD +interpretPackageDB _ GlobalPackageDB = GlobalPackageDB +interpretPackageDB _ UserPackageDB = UserPackageDB +interpretPackageDB mbWorkDir (SpecificPackageDB db) = + SpecificPackageDB (interpretSymbolicPath mbWorkDir db) + +interpretPackageDBStack :: Maybe (SymbolicPath CWD (Dir Pkg)) -> PackageDBStack -> PackageDBStackCWD +interpretPackageDBStack mbWorkDir = map (interpretPackageDB mbWorkDir) + +-- | Transform a package db using a FilePath into one using symbolic paths. +coercePackageDB :: PackageDBCWD -> PackageDBX (SymbolicPath CWD (Dir PkgDB)) +coercePackageDB GlobalPackageDB = GlobalPackageDB +coercePackageDB UserPackageDB = UserPackageDB +coercePackageDB (SpecificPackageDB db) = SpecificPackageDB (makeSymbolicPath db) + +coercePackageDBStack + :: [PackageDBCWD] + -> [PackageDBX (SymbolicPath CWD (Dir PkgDB))] +coercePackageDBStack = map coercePackageDB -- ------------------------------------------------------------ diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index c9d5d081354..033f3c9de54 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -2036,8 +2036,8 @@ reportFailedDependencies verbosity failed = getInstalledPackages :: Verbosity -> Compiler - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> PackageDBStack + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBStackX (SymbolicPath from (Dir PkgDB)) -- ^ The stack of package databases. -> ProgramDb -> IO InstalledPackageIndex @@ -2051,14 +2051,14 @@ getInstalledPackages verbosity comp mbWorkDir packageDBs progdb = do case compilerFlavor comp of GHC -> GHC.getInstalledPackages verbosity comp mbWorkDir packageDBs' progdb GHCJS -> GHCJS.getInstalledPackages verbosity mbWorkDir packageDBs' progdb - UHC -> UHC.getInstalledPackages verbosity comp packageDBs' progdb + UHC -> UHC.getInstalledPackages verbosity comp mbWorkDir packageDBs' progdb HaskellSuite{} -> HaskellSuite.getInstalledPackages verbosity packageDBs' progdb flv -> dieWithException verbosity $ HowToFindInstalledPackages flv where packageDBExists (SpecificPackageDB path0) = do - let path = interpretSymbolicPath mbWorkDir $ makeSymbolicPath path0 + let path = interpretSymbolicPath mbWorkDir path0 exists <- doesPathExist path unless exists $ warn verbosity $ @@ -2096,8 +2096,8 @@ getPackageDBContents verbosity comp mbWorkDir packageDB progdb = do getInstalledPackagesMonitorFiles :: Verbosity -> Compiler - -> Maybe (SymbolicPath CWD ('Dir Pkg)) - -> PackageDBStack + -> Maybe (SymbolicPath CWD ('Dir from)) + -> PackageDBStackS from -> ProgramDb -> Platform -> IO [FilePath] @@ -2144,7 +2144,7 @@ getInstalledPackagesById verbosity lbi@LocalBuildInfo{compiler = comp, withPacka -- @--global@, @--user@ and @--package-db=global|user|clear|$file@. -- This function combines the global/user flag and interprets the package-db -- flag into a single package db stack. -interpretPackageDbFlags :: Bool -> [Maybe PackageDB] -> PackageDBStack +interpretPackageDbFlags :: Bool -> [Maybe (PackageDBX fp)] -> PackageDBStackX fp interpretPackageDbFlags userInstall specificDBs = extra initialStack specificDBs where diff --git a/Cabal/src/Distribution/Simple/GHC.hs b/Cabal/src/Distribution/Simple/GHC.hs index a8f15bc92da..db475a01dd5 100644 --- a/Cabal/src/Distribution/Simple/GHC.hs +++ b/Cabal/src/Distribution/Simple/GHC.hs @@ -4,6 +4,7 @@ {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE RankNTypes #-} +{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} ----------------------------------------------------------------------------- @@ -394,8 +395,8 @@ getGhcInfo verbosity ghcProg = Internal.getGhcInfo verbosity implInfo ghcProg -- | Given a single package DB, return all installed packages. getPackageDBContents :: Verbosity - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> PackageDB + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBX (SymbolicPath from (Dir PkgDB)) -> ProgramDb -> IO InstalledPackageIndex getPackageDBContents verbosity mbWorkDir packagedb progdb = do @@ -406,8 +407,8 @@ getPackageDBContents verbosity mbWorkDir packagedb progdb = do getInstalledPackages :: Verbosity -> Compiler - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> PackageDBStack + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBStackX (SymbolicPath from (Dir PkgDB)) -> ProgramDb -> IO InstalledPackageIndex getInstalledPackages verbosity comp mbWorkDir packagedbs progdb = do @@ -429,7 +430,7 @@ getInstalledPackages verbosity comp mbWorkDir packagedbs progdb = do -- 'getInstalledPackages'. toPackageIndex :: Verbosity - -> [(PackageDB, [InstalledPackageInfo])] + -> [(PackageDBX a, [InstalledPackageInfo])] -> ProgramDb -> IO InstalledPackageIndex toPackageIndex verbosity pkgss progdb = do @@ -492,7 +493,7 @@ checkPackageDbEnvVar :: Verbosity -> IO () checkPackageDbEnvVar verbosity = Internal.checkPackageDbEnvVar verbosity "GHC" "GHC_PACKAGE_PATH" -checkPackageDbStack :: Verbosity -> Compiler -> PackageDBStack -> IO () +checkPackageDbStack :: Eq fp => Verbosity -> Compiler -> PackageDBStackX fp -> IO () checkPackageDbStack verbosity comp = if flagPackageConf implInfo then checkPackageDbStackPre76 verbosity @@ -500,7 +501,7 @@ checkPackageDbStack verbosity comp = where implInfo = ghcVersionImplInfo (compilerVersion comp) -checkPackageDbStackPost76 :: Verbosity -> PackageDBStack -> IO () +checkPackageDbStackPost76 :: Eq fp => Verbosity -> PackageDBStackX fp -> IO () checkPackageDbStackPost76 _ (GlobalPackageDB : rest) | GlobalPackageDB `notElem` rest = return () checkPackageDbStackPost76 verbosity rest @@ -508,7 +509,7 @@ checkPackageDbStackPost76 verbosity rest dieWithException verbosity CheckPackageDbStackPost76 checkPackageDbStackPost76 _ _ = return () -checkPackageDbStackPre76 :: Verbosity -> PackageDBStack -> IO () +checkPackageDbStackPre76 :: Eq fp => Verbosity -> PackageDBStackX fp -> IO () checkPackageDbStackPre76 _ (GlobalPackageDB : rest) | GlobalPackageDB `notElem` rest = return () checkPackageDbStackPre76 verbosity rest @@ -529,10 +530,10 @@ removeMingwIncludeDir pkg = -- | Get the packages from specific PackageDBs, not cumulative. getInstalledPackages' :: Verbosity - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> [PackageDB] + -> Maybe (SymbolicPath CWD (Dir from)) + -> [PackageDBX (SymbolicPath from (Dir PkgDB))] -> ProgramDb - -> IO [(PackageDB, [InstalledPackageInfo])] + -> IO [(PackageDBX (SymbolicPath from (Dir PkgDB)), [InstalledPackageInfo])] getInstalledPackages' verbosity mbWorkDir packagedbs progdb = sequenceA [ do @@ -542,21 +543,22 @@ getInstalledPackages' verbosity mbWorkDir packagedbs progdb = ] getInstalledPackagesMonitorFiles - :: Verbosity - -> Maybe (SymbolicPath CWD (Dir Pkg)) + :: forall from + . Verbosity + -> Maybe (SymbolicPath CWD (Dir from)) -> Platform -> ProgramDb - -> [PackageDB] + -> [PackageDBS from] -> IO [FilePath] getInstalledPackagesMonitorFiles verbosity mbWorkDir platform progdb = traverse getPackageDBPath where - getPackageDBPath :: PackageDB -> IO FilePath + getPackageDBPath :: PackageDBS from -> IO FilePath getPackageDBPath GlobalPackageDB = selectMonitorFile =<< getGlobalPackageDB verbosity ghcProg getPackageDBPath UserPackageDB = selectMonitorFile =<< getUserPackageDB verbosity ghcProg platform - getPackageDBPath (SpecificPackageDB path) = selectMonitorFile path + getPackageDBPath (SpecificPackageDB path) = selectMonitorFile (interpretSymbolicPath mbWorkDir path) -- GHC has old style file dbs, and new style directory dbs. -- Note that for dir style dbs, we only need to monitor the cache file, not @@ -1057,8 +1059,8 @@ hcPkgInfo progdb = registerPackage :: Verbosity -> ProgramDb - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> PackageDBStack + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBStackS from -> InstalledPackageInfo -> HcPkg.RegisterOptions -> IO () @@ -1096,4 +1098,4 @@ pkgRoot verbosity lbi = fmap makeSymbolicPath . pkgRoot' pkgRoot' (SpecificPackageDB fp) = return $ takeDirectory $ - interpretSymbolicPathLBI lbi (unsafeMakeSymbolicPath fp) + interpretSymbolicPathLBI lbi fp diff --git a/Cabal/src/Distribution/Simple/GHC/Build.hs b/Cabal/src/Distribution/Simple/GHC/Build.hs index f62cdcf8b66..1972e9d903f 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build.hs @@ -101,7 +101,7 @@ build numJobs pkg_descr pbci = do if isLib then -- NB: this might fail to make the buildTargetDir relative, -- as noted in #9776. Oh well. - tryMakeRelativeToWorkingDir mbWorkDir buildTargetDir0 + tryMakeRelative mbWorkDir buildTargetDir0 else return buildTargetDir0 -- To preserve the previous behaviour, we don't use relative dirs for -- executables. Historically, this isn't needed to reduce the CLI limit diff --git a/Cabal/src/Distribution/Simple/GHC/EnvironmentParser.hs b/Cabal/src/Distribution/Simple/GHC/EnvironmentParser.hs index 38ec484fe28..709a375a703 100644 --- a/Cabal/src/Distribution/Simple/GHC/EnvironmentParser.hs +++ b/Cabal/src/Distribution/Simple/GHC/EnvironmentParser.hs @@ -11,8 +11,6 @@ import Distribution.Compat.Prelude import Prelude () import Distribution.Simple.Compiler - ( PackageDB (..) - ) import Distribution.Simple.GHC.Internal ( GhcEnvironmentFileEntry (..) ) @@ -26,7 +24,7 @@ import Text.Parsec.String , parseFromFile ) -parseEnvironmentFileLine :: Parser GhcEnvironmentFileEntry +parseEnvironmentFileLine :: Parser (GhcEnvironmentFileEntry FilePath) parseEnvironmentFileLine = GhcEnvFileComment <$> comment <|> GhcEnvFilePackageId <$> unitId @@ -50,10 +48,10 @@ newtype ParseErrorExc = ParseErrorExc P.ParseError instance Exception ParseErrorExc -parseGhcEnvironmentFile :: Parser [GhcEnvironmentFileEntry] +parseGhcEnvironmentFile :: Parser [GhcEnvironmentFileEntry FilePath] parseGhcEnvironmentFile = parseEnvironmentFileLine `P.sepEndBy` P.endOfLine <* P.eof -readGhcEnvironmentFile :: FilePath -> IO [GhcEnvironmentFileEntry] +readGhcEnvironmentFile :: FilePath -> IO [GhcEnvironmentFileEntry FilePath] readGhcEnvironmentFile path = either (throwIO . ParseErrorExc) return =<< parseFromFile parseGhcEnvironmentFile path diff --git a/Cabal/src/Distribution/Simple/GHC/Internal.hs b/Cabal/src/Distribution/Simple/GHC/Internal.hs index ca78dc0fcd9..0686f30ba1b 100644 --- a/Cabal/src/Distribution/Simple/GHC/Internal.hs +++ b/Cabal/src/Distribution/Simple/GHC/Internal.hs @@ -766,7 +766,7 @@ ghcPlatformAndVersionString (Platform arch os) version = -- Constructing GHC environment files -- | The kinds of entries we can stick in a @.ghc.environment@ file. -data GhcEnvironmentFileEntry +data GhcEnvironmentFileEntry fp = -- | @-- a comment@ GhcEnvFileComment String | -- | @package-id foo-1.0-4fe301a...@ @@ -774,7 +774,7 @@ data GhcEnvironmentFileEntry | -- | @global-package-db@, -- @user-package-db@ or -- @package-db blah/package.conf.d/@ - GhcEnvFilePackageDb PackageDB + GhcEnvFilePackageDb (PackageDBX fp) | -- | @clear-package-db@ GhcEnvFileClearPackageDbStack deriving (Eq, Ord, Show) @@ -785,9 +785,9 @@ data GhcEnvironmentFileEntry -- If you need to do anything more complicated then either use this as a basis -- and add more entries, or just make all the entries directly. simpleGhcEnvironmentFile - :: PackageDBStack + :: PackageDBStackX fp -> [UnitId] - -> [GhcEnvironmentFileEntry] + -> [GhcEnvironmentFileEntry fp] simpleGhcEnvironmentFile packageDBs pkgids = GhcEnvFileClearPackageDbStack : map GhcEnvFilePackageDb packageDBs @@ -805,7 +805,7 @@ writeGhcEnvironmentFile -- ^ the GHC target platform -> Version -- ^ the GHC version - -> [GhcEnvironmentFileEntry] + -> [GhcEnvironmentFileEntry FilePath] -- ^ the content -> IO FilePath writeGhcEnvironmentFile directory platform ghcversion entries = do @@ -820,12 +820,12 @@ ghcEnvironmentFileName platform ghcversion = ".ghc.environment." ++ ghcPlatformAndVersionString platform ghcversion -- | Render a bunch of GHC environment file entries -renderGhcEnvironmentFile :: [GhcEnvironmentFileEntry] -> String +renderGhcEnvironmentFile :: [GhcEnvironmentFileEntry FilePath] -> String renderGhcEnvironmentFile = unlines . map renderGhcEnvironmentFileEntry -- | Render an individual GHC environment file entry -renderGhcEnvironmentFileEntry :: GhcEnvironmentFileEntry -> String +renderGhcEnvironmentFileEntry :: GhcEnvironmentFileEntry FilePath -> String renderGhcEnvironmentFileEntry entry = case entry of GhcEnvFileComment comment -> format comment where diff --git a/Cabal/src/Distribution/Simple/GHCJS.hs b/Cabal/src/Distribution/Simple/GHCJS.hs index 05fa3016738..07ba9d660b1 100644 --- a/Cabal/src/Distribution/Simple/GHCJS.hs +++ b/Cabal/src/Distribution/Simple/GHCJS.hs @@ -313,8 +313,8 @@ getGhcInfo verbosity ghcjsProg = Internal.getGhcInfo verbosity implInfo ghcjsPro -- | Given a single package DB, return all installed packages. getPackageDBContents :: Verbosity - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> PackageDB + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBX (SymbolicPath from (Dir PkgDB)) -> ProgramDb -> IO InstalledPackageIndex getPackageDBContents verbosity mbWorkDir packagedb progdb = do @@ -324,8 +324,8 @@ getPackageDBContents verbosity mbWorkDir packagedb progdb = do -- | Given a package DB stack, return all installed packages. getInstalledPackages :: Verbosity - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> PackageDBStack + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBStackX (SymbolicPath from (Dir PkgDB)) -> ProgramDb -> IO InstalledPackageIndex getInstalledPackages verbosity mbWorkDir packagedbs progdb = do @@ -337,7 +337,7 @@ getInstalledPackages verbosity mbWorkDir packagedbs progdb = do toPackageIndex :: Verbosity - -> [(PackageDB, [InstalledPackageInfo])] + -> [(PackageDBX a, [InstalledPackageInfo])] -> ProgramDb -> IO InstalledPackageIndex toPackageIndex verbosity pkgss progdb = do @@ -393,7 +393,7 @@ checkPackageDbEnvVar :: Verbosity -> IO () checkPackageDbEnvVar verbosity = Internal.checkPackageDbEnvVar verbosity "GHCJS" "GHCJS_PACKAGE_PATH" -checkPackageDbStack :: Verbosity -> PackageDBStack -> IO () +checkPackageDbStack :: Eq fp => Verbosity -> PackageDBStackX fp -> IO () checkPackageDbStack _ (GlobalPackageDB : rest) | GlobalPackageDB `notElem` rest = return () checkPackageDbStack verbosity rest @@ -404,10 +404,10 @@ checkPackageDbStack verbosity _ = getInstalledPackages' :: Verbosity - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> [PackageDB] + -> Maybe (SymbolicPath CWD (Dir from)) + -> [PackageDBX (SymbolicPath from (Dir PkgDB))] -> ProgramDb - -> IO [(PackageDB, [InstalledPackageInfo])] + -> IO [(PackageDBX (SymbolicPath from (Dir PkgDB)), [InstalledPackageInfo])] getInstalledPackages' verbosity mbWorkDir packagedbs progdb = sequenceA [ do @@ -432,7 +432,7 @@ getInstalledPackagesMonitorFiles verbosity platform mbWorkDir progdb = selectMonitorFile =<< getGlobalPackageDB verbosity ghcjsProg getPackageDBPath UserPackageDB = selectMonitorFile =<< getUserPackageDB verbosity ghcjsProg platform - getPackageDBPath (SpecificPackageDB path) = selectMonitorFile path + getPackageDBPath (SpecificPackageDB path) = selectMonitorFile (interpretSymbolicPath mbWorkDir path) -- GHC has old style file dbs, and new style directory dbs. -- Note that for dir style dbs, we only need to monitor the cache file, not @@ -2026,8 +2026,8 @@ hcPkgInfo progdb = registerPackage :: Verbosity -> ProgramDb - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> PackageDBStack + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBStackS from -> InstalledPackageInfo -> HcPkg.RegisterOptions -> IO () @@ -2066,7 +2066,7 @@ pkgRoot verbosity lbi = pkgRoot' pkgRoot' (SpecificPackageDB fp) = return $ takeDirectory $ - interpretSymbolicPathLBI lbi (unsafeMakeSymbolicPath fp) + interpretSymbolicPathLBI lbi fp -- | Get the JavaScript file name and command and arguments to run a -- program compiled by GHCJS diff --git a/Cabal/src/Distribution/Simple/HaskellSuite.hs b/Cabal/src/Distribution/Simple/HaskellSuite.hs index d3f43f65904..a61dfb8228e 100644 --- a/Cabal/src/Distribution/Simple/HaskellSuite.hs +++ b/Cabal/src/Distribution/Simple/HaskellSuite.hs @@ -23,6 +23,7 @@ import Distribution.Simple.Program import Distribution.Simple.Program.Builtin import Distribution.Simple.Utils import Distribution.System (Platform) +import Distribution.Utils.Path import Distribution.Verbosity import Distribution.Version import Language.Haskell.Extension @@ -129,7 +130,8 @@ getLanguages verbosity prog = do -- if we need something like that as well. getInstalledPackages :: Verbosity - -> PackageDBStack + -- Not migrated to work with --working-dir but this is legacy dead code + -> PackageDBStackX (SymbolicPath from (Dir PkgDB)) -> ProgramDb -> IO InstalledPackageIndex getInstalledPackages verbosity packagedbs progdb = @@ -239,7 +241,7 @@ installLib verbosity lbi targetDir dynlibTargetDir builtDir pkg lib clbi = do registerPackage :: Verbosity -> ProgramDb - -> PackageDBStack + -> PackageDBStackS from -> InstalledPackageInfo -> IO () registerPackage verbosity progdb packageDbs installedPkgInfo = do @@ -261,7 +263,7 @@ initPackageDB verbosity progdb dbPath = progdb ["init", dbPath] -packageDbOpt :: PackageDB -> String +packageDbOpt :: PackageDBX (SymbolicPath from (Dir PkgDB)) -> String packageDbOpt GlobalPackageDB = "--global" packageDbOpt UserPackageDB = "--user" -packageDbOpt (SpecificPackageDB db) = "--package-db=" ++ db +packageDbOpt (SpecificPackageDB db) = "--package-db=" ++ interpretSymbolicPathCWD db diff --git a/Cabal/src/Distribution/Simple/Program/GHC.hs b/Cabal/src/Distribution/Simple/Program/GHC.hs index a0655793792..ce0ea9db92a 100644 --- a/Cabal/src/Distribution/Simple/Program/GHC.hs +++ b/Cabal/src/Distribution/Simple/Program/GHC.hs @@ -856,7 +856,7 @@ renderGhcOptions comp _platform@(Platform _arch os) opts , ["-hide-all-packages" | flagBool ghcOptHideAllPackages] , ["-Wmissing-home-modules" | flagBool ghcOptWarnMissingHomeModules] , ["-no-auto-link-packages" | flagBool ghcOptNoAutoLinkPackages] - , packageDbArgs implInfo (ghcOptPackageDBs opts) + , packageDbArgs implInfo (interpretPackageDBStack Nothing (ghcOptPackageDBs opts)) , concat $ let space "" = "" space xs = ' ' : xs @@ -918,7 +918,7 @@ verbosityOpts verbosity | otherwise = ["-w", "-v0"] -- | GHC <7.6 uses '-package-conf' instead of '-package-db'. -packageDbArgsConf :: PackageDBStack -> [String] +packageDbArgsConf :: PackageDBStackCWD -> [String] packageDbArgsConf dbstack = case dbstack of (GlobalPackageDB : UserPackageDB : dbs) -> concatMap specific dbs (GlobalPackageDB : dbs) -> @@ -935,7 +935,7 @@ packageDbArgsConf dbstack = case dbstack of -- | GHC >= 7.6 uses the '-package-db' flag. See -- https://gitlab.haskell.org/ghc/ghc/-/issues/5977. -packageDbArgsDb :: PackageDBStack -> [String] +packageDbArgsDb :: PackageDBStackCWD -> [String] -- special cases to make arguments prettier in common scenarios packageDbArgsDb dbstack = case dbstack of (GlobalPackageDB : UserPackageDB : dbs) @@ -954,7 +954,7 @@ packageDbArgsDb dbstack = case dbstack of isSpecific (SpecificPackageDB _) = True isSpecific _ = False -packageDbArgs :: GhcImplInfo -> PackageDBStack -> [String] +packageDbArgs :: GhcImplInfo -> PackageDBStackCWD -> [String] packageDbArgs implInfo | flagPackageConf implInfo = packageDbArgsConf | otherwise = packageDbArgsDb diff --git a/Cabal/src/Distribution/Simple/Program/HcPkg.hs b/Cabal/src/Distribution/Simple/Program/HcPkg.hs index 710020d9f6d..a494bc63f02 100644 --- a/Cabal/src/Distribution/Simple/Program/HcPkg.hs +++ b/Cabal/src/Distribution/Simple/Program/HcPkg.hs @@ -154,8 +154,8 @@ defaultRegisterOptions = register :: HcPkgInfo -> Verbosity - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> PackageDBStack + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBStackS from -> InstalledPackageInfo -> RegisterOptions -> IO () @@ -179,7 +179,7 @@ register hpi verbosity mbWorkDir packagedbs pkgInfo registerOptions , recacheMultiInstance hpi = do let pkgdb = registrationPackageDB packagedbs - writeRegistrationFileDirectly verbosity hpi pkgdb pkgInfo + writeRegistrationFileDirectly verbosity hpi mbWorkDir pkgdb pkgInfo recache hpi verbosity mbWorkDir pkgdb | otherwise = runProgramInvocation @@ -189,17 +189,18 @@ register hpi verbosity mbWorkDir packagedbs pkgInfo registerOptions writeRegistrationFileDirectly :: Verbosity -> HcPkgInfo - -> PackageDB + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBS from -> InstalledPackageInfo -> IO () -writeRegistrationFileDirectly verbosity hpi (SpecificPackageDB dir) pkgInfo +writeRegistrationFileDirectly verbosity hpi mbWorkDir (SpecificPackageDB dir) pkgInfo | supportsDirDbs hpi = do - let pkgfile = dir prettyShow (installedUnitId pkgInfo) <.> "conf" + let pkgfile = interpretSymbolicPath mbWorkDir dir prettyShow (installedUnitId pkgInfo) <.> "conf" writeUTF8File pkgfile (showInstalledPackageInfo pkgInfo) | otherwise = dieWithException verbosity NoSupportDirStylePackageDb -writeRegistrationFileDirectly verbosity _ _ _ = +writeRegistrationFileDirectly verbosity _ _ _ _ = -- We don't know here what the dir for the global or user dbs are, -- if that's needed it'll require a bit more plumbing to support. dieWithException verbosity OnlySupportSpecificPackageDb @@ -216,7 +217,7 @@ unregister hpi verbosity mbWorkDir packagedb pkgid = -- | Call @hc-pkg@ to recache the registered packages. -- -- > hc-pkg recache [--user | --global | --package-db] -recache :: HcPkgInfo -> Verbosity -> Maybe (SymbolicPath CWD (Dir Pkg)) -> PackageDB -> IO () +recache :: HcPkgInfo -> Verbosity -> Maybe (SymbolicPath CWD (Dir from)) -> PackageDBS from -> IO () recache hpi verbosity mbWorkDir packagedb = runProgramInvocation verbosity @@ -278,8 +279,8 @@ hide hpi verbosity mbWorkDir packagedb pkgid = dump :: HcPkgInfo -> Verbosity - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> PackageDB + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBX (SymbolicPath from (Dir PkgDB)) -> IO [InstalledPackageInfo] dump hpi verbosity mbWorkDir packagedb = do output <- @@ -432,8 +433,8 @@ initInvocation hpi verbosity path = registerInvocation :: HcPkgInfo -> Verbosity - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> PackageDBStack + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBStackS from -> InstalledPackageInfo -> RegisterOptions -> ProgramInvocation @@ -474,8 +475,8 @@ unregisterInvocation hpi verbosity mbWorkDir packagedb pkgid = recacheInvocation :: HcPkgInfo -> Verbosity - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> PackageDB + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBS from -> ProgramInvocation recacheInvocation hpi verbosity mbWorkDir packagedb = programInvocationCwd mbWorkDir (hcPkgProgram hpi) $ @@ -522,8 +523,8 @@ hideInvocation hpi verbosity mbWorkDir packagedb pkgid = dumpInvocation :: HcPkgInfo -> Verbosity - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> PackageDB + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBX (SymbolicPath from (Dir PkgDB)) -> ProgramInvocation dumpInvocation hpi _verbosity mbWorkDir packagedb = (programInvocationCwd mbWorkDir (hcPkgProgram hpi) args) @@ -555,7 +556,7 @@ listInvocation hpi _verbosity mbWorkDir packagedb = -- We use verbosity level 'silent' because it is important that we -- do not contaminate the output with info/debug messages. -packageDbStackOpts :: HcPkgInfo -> PackageDBStack -> [String] +packageDbStackOpts :: HcPkgInfo -> PackageDBStackS from -> [String] packageDbStackOpts hpi dbstack | noPkgDbStack hpi = [packageDbOpts hpi (registrationPackageDB dbstack)] | otherwise = case dbstack of @@ -569,7 +570,7 @@ packageDbStackOpts hpi dbstack : map specific dbs _ -> ierror where - specific (SpecificPackageDB db) = "--" ++ packageDbFlag hpi ++ "=" ++ db + specific (SpecificPackageDB db) = "--" ++ packageDbFlag hpi ++ "=" ++ interpretSymbolicPathCWD db specific _ = ierror ierror :: a ierror = error ("internal error: unexpected package db stack: " ++ show dbstack) @@ -581,10 +582,10 @@ packageDbFlag hpi | otherwise = "package-db" -packageDbOpts :: HcPkgInfo -> PackageDB -> String +packageDbOpts :: HcPkgInfo -> PackageDBX (SymbolicPath from (Dir PkgDB)) -> String packageDbOpts _ GlobalPackageDB = "--global" packageDbOpts _ UserPackageDB = "--user" -packageDbOpts hpi (SpecificPackageDB db) = "--" ++ packageDbFlag hpi ++ "=" ++ db +packageDbOpts hpi (SpecificPackageDB db) = "--" ++ packageDbFlag hpi ++ "=" ++ interpretSymbolicPathCWD db verbosityOpts :: HcPkgInfo -> Verbosity -> [String] verbosityOpts hpi v diff --git a/Cabal/src/Distribution/Simple/Program/Hpc.hs b/Cabal/src/Distribution/Simple/Program/Hpc.hs index c508900814d..fd181d32176 100644 --- a/Cabal/src/Distribution/Simple/Program/Hpc.hs +++ b/Cabal/src/Distribution/Simple/Program/Hpc.hs @@ -70,7 +70,7 @@ markup mbWorkDir hpc hpcVer verbosity tixFile hpcDirs destDir included = do return passedDirs -- Prior to GHC 8.0, hpc assumes all .mix paths are relative. - hpcDirs'' <- traverse (tryMakeRelativeToWorkingDir mbWorkDir) hpcDirs' + hpcDirs'' <- traverse (tryMakeRelative mbWorkDir) hpcDirs' runProgramInvocation verbosity diff --git a/Cabal/src/Distribution/Simple/Register.hs b/Cabal/src/Distribution/Simple/Register.hs index ac16a67d428..c3328046857 100644 --- a/Cabal/src/Distribution/Simple/Register.hs +++ b/Cabal/src/Distribution/Simple/Register.hs @@ -282,7 +282,7 @@ generateRegistrationInfo verbosity pkg lib lbi clbi inplace reloc distPref packa clbi ) else do - abi_hash <- abiHash verbosity pkg inplaceDir distPref lbi lib clbi + abi_hash <- abiHash verbosity pkg distPref lbi lib clbi if reloc then relocRegistrationInfo @@ -309,13 +309,12 @@ generateRegistrationInfo verbosity pkg lib lbi clbi inplace reloc distPref packa abiHash :: Verbosity -> PackageDescription - -> FilePath -> SymbolicPath Pkg (Dir Dist) -> LocalBuildInfo -> Library -> ComponentLocalBuildInfo -> IO AbiHash -abiHash verbosity pkg inplaceDir distPref lbi lib clbi = +abiHash verbosity pkg distPref lbi lib clbi = case compilerFlavor comp of GHC -> do fmap mkAbiHash $ GHC.libAbiHash verbosity pkg lbi' lib clbi @@ -328,7 +327,7 @@ abiHash verbosity pkg inplaceDir distPref lbi lib clbi = lbi { withPackageDB = withPackageDB lbi - ++ [SpecificPackageDB (inplaceDir getSymbolicPath (internalPackageDBPath lbi distPref))] + ++ [SpecificPackageDB (internalPackageDBPath lbi distPref)] } relocRegistrationInfo @@ -428,8 +427,8 @@ registerPackage :: Verbosity -> Compiler -> ProgramDb - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -> PackageDBStack + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBStackS from -> InstalledPackageInfo -> HcPkg.RegisterOptions -> IO () @@ -442,7 +441,7 @@ registerPackage verbosity comp progdb mbWorkDir packageDbs installedPkgInfo regi _ | HcPkg.registerMultiInstance registerOptions -> dieWithException verbosity RegisMultiplePkgNotSupported - UHC -> UHC.registerPackage verbosity comp progdb packageDbs installedPkgInfo + UHC -> UHC.registerPackage verbosity mbWorkDir comp progdb packageDbs installedPkgInfo _ -> dieWithException verbosity RegisteringNotImplemented writeHcPkgRegisterScript diff --git a/Cabal/src/Distribution/Simple/Setup/Config.hs b/Cabal/src/Distribution/Simple/Setup/Config.hs index 2407329fc1b..15c1d77f553 100644 --- a/Cabal/src/Distribution/Simple/Setup/Config.hs +++ b/Cabal/src/Distribution/Simple/Setup/Config.hs @@ -905,7 +905,7 @@ readPackageDb :: String -> Maybe PackageDB readPackageDb "clear" = Nothing readPackageDb "global" = Just GlobalPackageDB readPackageDb "user" = Just UserPackageDB -readPackageDb other = Just (SpecificPackageDB other) +readPackageDb other = Just (SpecificPackageDB (makeSymbolicPath other)) showPackageDbList :: [Maybe PackageDB] -> [String] showPackageDbList = map showPackageDb @@ -917,7 +917,7 @@ showPackageDb :: Maybe PackageDB -> String showPackageDb Nothing = "clear" showPackageDb (Just GlobalPackageDB) = "global" showPackageDb (Just UserPackageDB) = "user" -showPackageDb (Just (SpecificPackageDB db)) = db +showPackageDb (Just (SpecificPackageDB db)) = getSymbolicPath db showProfDetailLevelFlag :: Flag ProfDetailLevel -> [String] showProfDetailLevelFlag NoFlag = [] diff --git a/Cabal/src/Distribution/Simple/Test.hs b/Cabal/src/Distribution/Simple/Test.hs index c994fb3d540..5b7a6daa718 100644 --- a/Cabal/src/Distribution/Simple/Test.hs +++ b/Cabal/src/Distribution/Simple/Test.hs @@ -81,7 +81,7 @@ test args pkg_descr lbi0 flags = do enabledTests = LBI.enabledTestLBIs pkg_descr lbi -- We must add the internalPkgDB to the package database stack to lookup -- the path to HPC dirs of libraries local to this package - internalPkgDb = i $ internalPackageDBPath lbi0 distPref + internalPkgDb = internalPackageDBPath lbi0 distPref lbi = lbi0{withPackageDB = withPackageDB lbi0 ++ [SpecificPackageDB internalPkgDb]} doTest diff --git a/Cabal/src/Distribution/Simple/UHC.hs b/Cabal/src/Distribution/Simple/UHC.hs index af085ef3a7c..1fde3e35365 100644 --- a/Cabal/src/Distribution/Simple/UHC.hs +++ b/Cabal/src/Distribution/Simple/UHC.hs @@ -113,14 +113,15 @@ uhcLanguageExtensions = getInstalledPackages :: Verbosity -> Compiler - -> PackageDBStack + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBStackX (SymbolicPath from (Dir PkgDB)) -> ProgramDb -> IO InstalledPackageIndex -getInstalledPackages verbosity comp packagedbs progdb = do +getInstalledPackages verbosity comp mbWorkDir packagedbs progdb = do let compilerid = compilerId comp systemPkgDir <- getGlobalPackageDir verbosity progdb userPkgDir <- getUserPackageDir - let pkgDirs = nub (concatMap (packageDbPaths userPkgDir systemPkgDir) packagedbs) + let pkgDirs = nub (concatMap (packageDbPaths userPkgDir systemPkgDir mbWorkDir) packagedbs) -- putStrLn $ "pkgdirs: " ++ show pkgDirs pkgs <- liftM (map addBuiltinVersions . concat) $ @@ -154,12 +155,17 @@ getUserPackageDir = do homeDir <- getHomeDirectory return $ homeDir ".cabal" "lib" -- TODO: determine in some other way -packageDbPaths :: FilePath -> FilePath -> PackageDB -> [FilePath] -packageDbPaths user system db = +packageDbPaths + :: FilePath + -> FilePath + -> Maybe (SymbolicPath CWD (Dir from)) + -> PackageDBX (SymbolicPath from (Dir PkgDB)) + -> [FilePath] +packageDbPaths user system mbWorkDir db = case db of GlobalPackageDB -> [system] UserPackageDB -> [user] - SpecificPackageDB path -> [path] + SpecificPackageDB path -> [interpretSymbolicPath mbWorkDir path] -- | Hack to add version numbers to UHC-built-in packages. This should sooner or -- later be fixed on the UHC side. @@ -209,7 +215,7 @@ buildLib buildLib verbosity pkg_descr lbi lib clbi = do systemPkgDir <- getGlobalPackageDir verbosity (withPrograms lbi) userPkgDir <- getUserPackageDir - let runUhcProg = runDbProgram verbosity uhcProgram (withPrograms lbi) + let runUhcProg = runDbProgramCwd verbosity (mbWorkDirLBI lbi) uhcProgram (withPrograms lbi) let uhcArgs = -- set package name ["--pkg-build=" ++ prettyShow (packageId pkg_descr)] @@ -306,13 +312,13 @@ constructUHCCmdLine user system lbi bi clbi odir verbosity = MaximumOptimisation -> ["-O2"] ) where - i = interpretSymbolicPathLBI lbi -- See Note [Symbolic paths] in Distribution.Utils.Path + i = interpretSymbolicPathCWD -- See Note [Symbolic paths] in Distribution.Utils.Path uhcPackageDbOptions :: FilePath -> FilePath -> PackageDBStack -> [String] uhcPackageDbOptions user system db = map (\x -> "--pkg-searchpath=" ++ x) - (concatMap (packageDbPaths user system) db) + (concatMap (packageDbPaths user system Nothing) db) -- ----------------------------------------------------------------------------- -- Installation @@ -348,16 +354,17 @@ uhcPackageSubDir compilerid = compilerid uhcTarget uhcTargetVariant registerPackage :: Verbosity + -> Maybe (SymbolicPath CWD (Dir from)) -> Compiler -> ProgramDb - -> PackageDBStack + -> PackageDBStackS from -> InstalledPackageInfo -> IO () -registerPackage verbosity comp progdb packageDbs installedPkgInfo = do +registerPackage verbosity mbWorkDir comp progdb packageDbs installedPkgInfo = do dbdir <- case registrationPackageDB packageDbs of GlobalPackageDB -> getGlobalPackageDir verbosity progdb UserPackageDB -> getUserPackageDir - SpecificPackageDB dir -> return dir + SpecificPackageDB dir -> return (interpretSymbolicPath mbWorkDir dir) let pkgdir = dbdir uhcPackageDir (prettyShow pkgid) (prettyShow compilerid) createDirectoryIfMissingVerbose verbosity True pkgdir writeUTF8File diff --git a/cabal-install/src/Distribution/Client/CmdInstall.hs b/cabal-install/src/Distribution/Client/CmdInstall.hs index 1144ff79613..210ac78ca01 100644 --- a/cabal-install/src/Distribution/Client/CmdInstall.hs +++ b/cabal-install/src/Distribution/Client/CmdInstall.hs @@ -131,8 +131,9 @@ import Distribution.Simple.Compiler ( Compiler (..) , CompilerFlavor (..) , CompilerId (..) - , PackageDB (..) - , PackageDBStack + , PackageDBCWD + , PackageDBStackCWD + , PackageDBX (..) ) import Distribution.Simple.Configure ( configCompilerEx @@ -958,10 +959,10 @@ installLibraries -> ProjectBuildContext -> PI.PackageIndex InstalledPackageInfo -> Compiler - -> PackageDBStack + -> PackageDBStackCWD -> FilePath -- ^ Environment file - -> [GhcEnvironmentFileEntry] + -> [GhcEnvironmentFileEntry FilePath] -> Bool -- ^ Whether we need to show a warning (i.e. we created a new environment -- file, and the user did not use --package-env) @@ -1064,9 +1065,9 @@ warnIfNoExes verbosity buildCtx = -- | Return the package specifiers and non-global environment file entries. getEnvSpecsAndNonGlobalEntries :: PI.InstalledPackageIndex - -> [GhcEnvironmentFileEntry] + -> [GhcEnvironmentFileEntry FilePath] -> Bool - -> ([PackageSpecifier a], [(PackageName, GhcEnvironmentFileEntry)]) + -> ([PackageSpecifier a], [(PackageName, GhcEnvironmentFileEntry FilePath)]) getEnvSpecsAndNonGlobalEntries installedIndex entries installLibs = if installLibs then (envSpecs, envEntries') @@ -1076,8 +1077,8 @@ getEnvSpecsAndNonGlobalEntries installedIndex entries installLibs = environmentFileToSpecifiers :: PI.InstalledPackageIndex - -> [GhcEnvironmentFileEntry] - -> ([PackageSpecifier a], [(PackageName, GhcEnvironmentFileEntry)]) + -> [GhcEnvironmentFileEntry FilePath] + -> ([PackageSpecifier a], [(PackageName, GhcEnvironmentFileEntry FilePath)]) environmentFileToSpecifiers ipi = foldMap $ \case (GhcEnvFilePackageId unitId) | Just @@ -1248,7 +1249,7 @@ installBuiltExe overwrite -- | Create 'GhcEnvironmentFileEntry's for packages with exposed libraries. -entriesForLibraryComponents :: TargetsMap -> [GhcEnvironmentFileEntry] +entriesForLibraryComponents :: TargetsMap -> [GhcEnvironmentFileEntry FilePath] entriesForLibraryComponents = Map.foldrWithKey' (\k v -> mappend (go k v)) [] where hasLib :: (ComponentTarget, NonEmpty TargetSelector) -> Bool @@ -1258,7 +1259,7 @@ entriesForLibraryComponents = Map.foldrWithKey' (\k v -> mappend (go k v)) [] go :: UnitId -> [(ComponentTarget, NonEmpty TargetSelector)] - -> [GhcEnvironmentFileEntry] + -> [GhcEnvironmentFileEntry FilePath] go unitId targets | any hasLib targets = [GhcEnvFilePackageId unitId] | otherwise = [] @@ -1290,7 +1291,7 @@ getEnvFile clientInstallFlags platform compilerVersion = do -- | Returns the list of @GhcEnvFilePackageId@ values already existing in the -- environment being operated on. The @Bool@ is @True@ if we took settings -- from an existing file, @False@ otherwise. -getExistingEnvEntries :: Verbosity -> CompilerFlavor -> Bool -> FilePath -> IO (Bool, [GhcEnvironmentFileEntry]) +getExistingEnvEntries :: Verbosity -> CompilerFlavor -> Bool -> FilePath -> IO (Bool, [GhcEnvironmentFileEntry FilePath]) getExistingEnvEntries verbosity compilerFlavor supportsPkgEnvFiles envFile = do envFileExists <- doesFileExist envFile (usedExisting, allEntries) <- @@ -1334,8 +1335,8 @@ getPackageDbStack :: Compiler -> Flag FilePath -> Flag FilePath - -> [Maybe PackageDB] - -> IO PackageDBStack + -> [Maybe PackageDBCWD] + -> IO PackageDBStackCWD getPackageDbStack compiler storeDirFlag logsDirFlag packageDbs = do mstoreDir <- traverse makeAbsolute $ flagToMaybe storeDirFlag let diff --git a/cabal-install/src/Distribution/Client/CmdLegacy.hs b/cabal-install/src/Distribution/Client/CmdLegacy.hs index 128d5fb4251..38873148dc0 100644 --- a/cabal-install/src/Distribution/Client/CmdLegacy.hs +++ b/cabal-install/src/Distribution/Client/CmdLegacy.hs @@ -78,7 +78,7 @@ wrapperAction command getCommonFlags = Nothing command' getCommonFlags - (const flags) + (const (return flags)) (const extraArgs) -- diff --git a/cabal-install/src/Distribution/Client/Configure.hs b/cabal-install/src/Distribution/Client/Configure.hs index 0586a362dd2..6634f874071 100644 --- a/cabal-install/src/Distribution/Client/Configure.hs +++ b/cabal-install/src/Distribution/Client/Configure.hs @@ -86,8 +86,8 @@ import Distribution.PackageDescription.Configuration import Distribution.Simple.Compiler ( Compiler , CompilerInfo - , PackageDB (..) - , PackageDBStack + , PackageDBStackCWD + , PackageDBX (..) , compilerInfo ) import Distribution.Simple.PackageDescription @@ -144,7 +144,7 @@ chooseCabalVersion _configExFlags maybeVersion = -- | Configure the package found in the local directory configure :: Verbosity - -> PackageDBStack + -> PackageDBStackCWD -> RepoContext -> Compiler -> Platform @@ -203,7 +203,7 @@ configure Nothing configureCommand configCommonFlags - (const configFlags) + (const (return configFlags)) (const extraArgs) Right installPlan0 -> let installPlan = InstallPlan.configureInstallPlan configFlags installPlan0 @@ -253,7 +253,7 @@ configure logMsg message rest = debug verbosity message >> rest configureSetupScript - :: PackageDBStack + :: PackageDBStackCWD -> Compiler -> Platform -> ProgramDb @@ -308,7 +308,7 @@ configureSetupScript -- finding the Cabal lib when compiling any Setup.hs even if we're doing -- a global install. However we also allow looking in a specific package -- db. - packageDBs' :: PackageDBStack + packageDBs' :: PackageDBStackCWD index' :: Maybe InstalledPackageIndex (packageDBs', index') = case packageDBs of @@ -505,7 +505,7 @@ configurePackage (Just pkg) configureCommand configCommonFlags - configureFlags + (return . configureFlags) (const extraArgs) where gpkg :: PkgDesc.GenericPackageDescription diff --git a/cabal-install/src/Distribution/Client/DistDirLayout.hs b/cabal-install/src/Distribution/Client/DistDirLayout.hs index 01da7195d51..64140152453 100644 --- a/cabal-install/src/Distribution/Client/DistDirLayout.hs +++ b/cabal-install/src/Distribution/Client/DistDirLayout.hs @@ -43,8 +43,9 @@ import Distribution.Package import Distribution.Simple.Compiler ( Compiler (..) , OptimisationLevel (..) - , PackageDB (..) - , PackageDBStack + , PackageDBCWD + , PackageDBStackCWD + , PackageDBX (..) ) import Distribution.Simple.Configure (interpretPackageDbFlags) import Distribution.System @@ -111,7 +112,7 @@ data DistDirLayout = DistDirLayout , distSdistDirectory :: FilePath , distTempDirectory :: FilePath , distBinDirectory :: FilePath - , distPackageDB :: CompilerId -> PackageDB + , distPackageDB :: CompilerId -> PackageDBCWD , distHaddockOutputDir :: Maybe FilePath -- ^ Is needed when `--haddock-output-dir` flag is used. } @@ -121,8 +122,8 @@ data StoreDirLayout = StoreDirLayout { storeDirectory :: Compiler -> FilePath , storePackageDirectory :: Compiler -> UnitId -> FilePath , storePackageDBPath :: Compiler -> FilePath - , storePackageDB :: Compiler -> PackageDB - , storePackageDBStack :: Compiler -> [Maybe PackageDB] -> PackageDBStack + , storePackageDB :: Compiler -> PackageDBCWD + , storePackageDBStack :: Compiler -> [Maybe PackageDBCWD] -> PackageDBStackCWD , storeIncomingDirectory :: Compiler -> FilePath , storeIncomingLock :: Compiler -> UnitId -> FilePath } @@ -258,7 +259,7 @@ defaultDistDirLayout projectRoot mdistDirectory haddockOutputDir = distPackageDBPath :: CompilerId -> FilePath distPackageDBPath compid = distDirectory "packagedb" prettyShow compid - distPackageDB :: CompilerId -> PackageDB + distPackageDB :: CompilerId -> PackageDBCWD distPackageDB = SpecificPackageDB . distPackageDBPath distHaddockOutputDir :: Maybe FilePath @@ -282,11 +283,11 @@ defaultStoreDirLayout storeRoot = storePackageDBPath compiler = storeDirectory compiler "package.db" - storePackageDB :: Compiler -> PackageDB + storePackageDB :: Compiler -> PackageDBCWD storePackageDB compiler = SpecificPackageDB (storePackageDBPath compiler) - storePackageDBStack :: Compiler -> [Maybe PackageDB] -> PackageDBStack + storePackageDBStack :: Compiler -> [Maybe PackageDBCWD] -> PackageDBStackCWD storePackageDBStack compiler extraPackageDB = (interpretPackageDbFlags False extraPackageDB) ++ [storePackageDB compiler] diff --git a/cabal-install/src/Distribution/Client/Fetch.hs b/cabal-install/src/Distribution/Client/Fetch.hs index f09ae4d772e..033d3a01e14 100644 --- a/cabal-install/src/Distribution/Client/Fetch.hs +++ b/cabal-install/src/Distribution/Client/Fetch.hs @@ -44,10 +44,6 @@ import Distribution.Package ( packageId ) import Distribution.Simple.Compiler - ( Compiler - , PackageDBStack - , compilerInfo - ) import Distribution.Simple.PackageIndex (InstalledPackageIndex) import Distribution.Simple.Program ( ProgramDb @@ -88,7 +84,7 @@ import Distribution.System -- | Fetch a list of packages and their dependencies. fetch :: Verbosity - -> PackageDBStack + -> PackageDBStackCWD -> RepoContext -> Compiler -> Platform diff --git a/cabal-install/src/Distribution/Client/Freeze.hs b/cabal-install/src/Distribution/Client/Freeze.hs index 92f590bb772..a03b45b6a2d 100644 --- a/cabal-install/src/Distribution/Client/Freeze.hs +++ b/cabal-install/src/Distribution/Client/Freeze.hs @@ -61,10 +61,6 @@ import Distribution.Package , packageVersion ) import Distribution.Simple.Compiler - ( Compiler - , PackageDBStack - , compilerInfo - ) import Distribution.Simple.PackageIndex (InstalledPackageIndex) import Distribution.Simple.Program ( ProgramDb @@ -98,7 +94,7 @@ import Distribution.Version -- constraining each dependency to an exact version. freeze :: Verbosity - -> PackageDBStack + -> PackageDBStackCWD -> RepoContext -> Compiler -> Platform @@ -146,7 +142,7 @@ freeze -- command. getFreezePkgs :: Verbosity - -> PackageDBStack + -> PackageDBStackCWD -> RepoContext -> Compiler -> Platform diff --git a/cabal-install/src/Distribution/Client/GenBounds.hs b/cabal-install/src/Distribution/Client/GenBounds.hs index ae78b50c004..935db05fa43 100644 --- a/cabal-install/src/Distribution/Client/GenBounds.hs +++ b/cabal-install/src/Distribution/Client/GenBounds.hs @@ -46,10 +46,6 @@ import Distribution.PackageDescription.Configuration ( finalizePD ) import Distribution.Simple.Compiler - ( Compiler - , PackageDBStack - , compilerInfo - ) import Distribution.Simple.PackageDescription ( readGenericPackageDescription ) @@ -119,7 +115,7 @@ showBounds padTo p = -- | Entry point for the @gen-bounds@ command. genBounds :: Verbosity - -> PackageDBStack + -> PackageDBStackCWD -> RepoContext -> Compiler -> Platform diff --git a/cabal-install/src/Distribution/Client/IndexUtils.hs b/cabal-install/src/Distribution/Client/IndexUtils.hs index 23a7754a065..f66cf0d651c 100644 --- a/cabal-install/src/Distribution/Client/IndexUtils.hs +++ b/cabal-install/src/Distribution/Client/IndexUtils.hs @@ -1,5 +1,6 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE CPP #-} +{-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE LambdaCase #-} @@ -82,9 +83,6 @@ import Distribution.PackageDescription , emptyPackageDescription ) import Distribution.Simple.Compiler - ( Compiler - , PackageDBStack - ) import qualified Distribution.Simple.Configure as Configure ( getInstalledPackages , getInstalledPackagesMonitorFiles @@ -162,11 +160,11 @@ import qualified Hackage.Security.Util.Some as Sec getInstalledPackages :: Verbosity -> Compiler - -> PackageDBStack + -> PackageDBStackCWD -> ProgramDb -> IO InstalledPackageIndex getInstalledPackages verbosity comp packageDbs progdb = - Configure.getInstalledPackages verbosity' comp Nothing packageDbs progdb + Configure.getInstalledPackages verbosity' comp Nothing (coercePackageDBStack packageDbs) progdb where verbosity' = lessVerbose verbosity diff --git a/cabal-install/src/Distribution/Client/Init.hs b/cabal-install/src/Distribution/Client/Init.hs index 28cac9fe119..f9cd589f2a9 100644 --- a/cabal-install/src/Distribution/Client/Init.hs +++ b/cabal-install/src/Distribution/Client/Init.hs @@ -31,7 +31,7 @@ import System.IO (BufferMode (NoBuffering), hSetBuffering, stdout) -- | This is the main driver for the init script. initCmd :: Verbosity - -> PackageDBStack + -> PackageDBStackCWD -> RepoContext -> Compiler -> ProgramDb diff --git a/cabal-install/src/Distribution/Client/Install.hs b/cabal-install/src/Distribution/Client/Install.hs index e10cb518c96..84a590e3c74 100644 --- a/cabal-install/src/Distribution/Client/Install.hs +++ b/cabal-install/src/Distribution/Client/Install.hs @@ -173,8 +173,9 @@ import Distribution.Simple.Compiler ( Compiler (compilerId) , CompilerId (..) , CompilerInfo (..) - , PackageDB (..) - , PackageDBStack + , PackageDBCWD + , PackageDBStackCWD + , PackageDBX (..) , compilerFlavor , compilerInfo ) @@ -299,7 +300,7 @@ import Distribution.Client.Errors -- | Installs the packages needed to satisfy a list of dependencies. install :: Verbosity - -> PackageDBStack + -> PackageDBStackCWD -> RepoContext -> Compiler -> Platform @@ -390,7 +391,7 @@ type InstallContext = -- | Initial arguments given to 'install' or 'makeInstallContext'. type InstallArgs = - ( PackageDBStack + ( PackageDBStackCWD , RepoContext , Compiler , Platform @@ -1223,7 +1224,7 @@ storeDetailedBuildReports verbosity logsDir reports = regenerateHaddockIndex :: Verbosity - -> [PackageDB] + -> [PackageDBCWD] -> Compiler -> Platform -> ProgramDb @@ -1912,19 +1913,19 @@ installUnpackedPackage -- Configure phase onFailure ConfigureFailed $ do noticeProgress ProgressStarting - setup configureCommand configCommonFlags configureFlags mLogPath + setup configureCommand configCommonFlags (return . configureFlags) mLogPath -- Build phase onFailure BuildFailed $ do noticeProgress ProgressBuilding - setup buildCommand' buildCommonFlags buildFlags mLogPath + setup buildCommand' buildCommonFlags (return . buildFlags) mLogPath -- Doc generation phase docsResult <- if shouldHaddock then ( do - setup haddockCommand haddockCommonFlags haddockFlags' mLogPath + setup haddockCommand haddockCommonFlags (return . haddockFlags') mLogPath return DocsOk ) `catchIO` (\_ -> return DocsFailed) @@ -1934,7 +1935,7 @@ installUnpackedPackage -- Tests phase onFailure TestsFailed $ do when (testsEnabled && PackageDescription.hasTests pkg) $ - setup Cabal.testCommand testCommonFlags testFlags' mLogPath + setup Cabal.testCommand testCommonFlags (return . testFlags') mLogPath let testsResult | testsEnabled = TestsOk @@ -1951,7 +1952,7 @@ installUnpackedPackage platform pkg $ do - setup Cabal.copyCommand copyCommonFlags copyFlags mLogPath + setup Cabal.copyCommand copyCommonFlags (return . copyFlags) mLogPath -- Capture installed package configuration file, so that -- it can be incorporated into the final InstallPlan @@ -2027,7 +2028,7 @@ installUnpackedPackage setup Cabal.registerCommand registerCommonFlags - registerFlags' + (return . registerFlags') mLogPath is_dir <- doesDirectoryExist (interpretSymbolicPathCWD pkgConfDest) let notHidden = not . isHidden diff --git a/cabal-install/src/Distribution/Client/List.hs b/cabal-install/src/Distribution/Client/List.hs index b03211038de..480e2c46fd7 100644 --- a/cabal-install/src/Distribution/Client/List.hs +++ b/cabal-install/src/Distribution/Client/List.hs @@ -43,9 +43,6 @@ import Distribution.Types.Dependency import Distribution.Types.UnqualComponentName import Distribution.Simple.Compiler - ( Compiler - , PackageDBStack - ) import Distribution.Simple.PackageIndex (InstalledPackageIndex) import qualified Distribution.Simple.PackageIndex as InstalledPackageIndex import Distribution.Simple.Program (ProgramDb) @@ -141,7 +138,7 @@ import qualified Text.Regex.Posix.String as Regex -- | Return a list of packages matching given search strings. getPkgList :: Verbosity - -> PackageDBStack + -> PackageDBStackCWD -> RepoContext -> Maybe (Compiler, ProgramDb) -> ListFlags @@ -213,7 +210,7 @@ getPkgList verbosity packageDBs repoCtxt mcompprogdb listFlags pats = do -- | Show information about packages. list :: Verbosity - -> PackageDBStack + -> PackageDBStackCWD -> RepoContext -> Maybe (Compiler, ProgramDb) -> ListFlags @@ -249,7 +246,7 @@ list verbosity packageDBs repos mcompProgdb listFlags pats = do info :: Verbosity - -> PackageDBStack + -> PackageDBStackCWD -> RepoContext -> Compiler -> ProgramDb diff --git a/cabal-install/src/Distribution/Client/Main.hs b/cabal-install/src/Distribution/Client/Main.hs index 46a653b8bf7..e6278a5ef9a 100644 --- a/cabal-install/src/Distribution/Client/Main.hs +++ b/cabal-install/src/Distribution/Client/Main.hs @@ -206,7 +206,7 @@ import Distribution.Simple.Command , defaultCommandFallback , hiddenCommand ) -import Distribution.Simple.Compiler (PackageDBStack) +import Distribution.Simple.Compiler (PackageDBStack, interpretPackageDBStack) import Distribution.Simple.Configure ( ConfigStateFileError (..) , configCompilerAuxEx @@ -527,7 +527,7 @@ wrapperAction command getCommonFlags = Nothing command getCommonFlags - (const flags) + (const (return flags)) (const extraArgs) configureAction @@ -560,7 +560,7 @@ configureAction (configFlags, configExFlags) extraArgs globalFlags = do withRepoContext verbosity globalFlags' $ \repoContext -> configure verbosity - packageDBs + (interpretPackageDBStack Nothing packageDBs) repoContext comp platform @@ -636,7 +636,7 @@ build verbosity config distPref buildFlags extraArgs = Nothing (Cabal.buildCommand progDb) buildCommonFlags - mkBuildFlags + (return . mkBuildFlags) (const extraArgs) where progDb = defaultProgramDb @@ -729,7 +729,7 @@ replAction replFlags extraArgs globalFlags = do Nothing (Cabal.replCommand progDb) Cabal.replCommonFlags - (const replFlags') + (const (return replFlags')) (const extraArgs) -- No .cabal file in the current directory: just start the REPL (possibly @@ -776,7 +776,7 @@ installAction (configFlags, _, installFlags, _, _, _) _ globalFlags Nothing installCommand (const common) - (const (mempty, mempty, mempty, mempty, mempty, mempty)) + (const (return (mempty, mempty, mempty, mempty, mempty, mempty))) (const []) installAction ( configFlags @@ -853,7 +853,7 @@ installAction withRepoContext verb globalFlags' $ \repoContext -> install verb - (configPackageDB' configFlags') + (interpretPackageDBStack Nothing (configPackageDB' configFlags')) repoContext comp platform @@ -943,7 +943,7 @@ testAction (buildFlags, testFlags) extraArgs globalFlags = do Nothing Cabal.testCommand Cabal.testCommonFlags - (const testFlags') + (const (return testFlags')) (const extraArgs') data ComponentNames @@ -1064,7 +1064,7 @@ benchmarkAction Nothing Cabal.benchmarkCommand Cabal.benchmarkCommonFlags - (const benchmarkFlags') + (const (return benchmarkFlags')) (const extraArgs') haddockAction :: HaddockFlags -> [String] -> Action @@ -1104,7 +1104,7 @@ haddockAction haddockFlags extraArgs globalFlags = do Nothing haddockCommand haddockCommonFlags - (const haddockFlags') + (const (return haddockFlags')) (const extraArgs) when (haddockForHackage haddockFlags == Flag ForHackage) $ do pkg <- fmap LBI.localPkgDescr (getPersistBuildConfig mbWorkDir distPref) @@ -1139,7 +1139,7 @@ cleanAction cleanFlags extraArgs globalFlags = do Nothing cleanCommand cleanCommonFlags - (const cleanFlags') + (const (return cleanFlags')) (const extraArgs) listAction :: ListFlags -> [String] -> Action @@ -1164,7 +1164,7 @@ listAction listFlags extraArgs globalFlags = do withRepoContext verbosity globalFlags' $ \repoContext -> List.list verbosity - (configPackageDB' configFlags) + (interpretPackageDBStack Nothing (configPackageDB' configFlags)) repoContext compProgdb listFlags @@ -1187,7 +1187,7 @@ infoAction infoFlags extraArgs globalFlags = do withRepoContext verbosity globalFlags' $ \repoContext -> List.info verbosity - (configPackageDB' configFlags) + (interpretPackageDBStack Nothing (configPackageDB' configFlags)) repoContext comp progdb @@ -1206,7 +1206,7 @@ fetchAction fetchFlags extraArgs globalFlags = do withRepoContext verbosity globalFlags' $ \repoContext -> fetch verbosity - (configPackageDB' configFlags) + (interpretPackageDBStack Nothing (configPackageDB' configFlags)) repoContext comp platform @@ -1228,7 +1228,7 @@ freezeAction freezeFlags _extraArgs globalFlags = do withRepoContext verbosity globalFlags' $ \repoContext -> freeze verbosity - (configPackageDB' configFlags) + (interpretPackageDBStack Nothing (configPackageDB' configFlags)) repoContext comp platform @@ -1249,7 +1249,7 @@ genBoundsAction freezeFlags _extraArgs globalFlags = do withRepoContext verbosity globalFlags' $ \repoContext -> genBounds verbosity - (configPackageDB' configFlags) + (interpretPackageDBStack Nothing (configPackageDB' configFlags)) repoContext comp platform @@ -1433,7 +1433,7 @@ initAction initFlags extraArgs globalFlags = do withRepoContext verbosity globalFlags' $ \repoContext -> initCmd verbosity - (configPackageDB' confFlags') + (interpretPackageDBStack Nothing (configPackageDB' confFlags')) repoContext comp progdb diff --git a/cabal-install/src/Distribution/Client/PackageHash.hs b/cabal-install/src/Distribution/Client/PackageHash.hs index 1b30b125204..2c5eb4897e0 100644 --- a/cabal-install/src/Distribution/Client/PackageHash.hs +++ b/cabal-install/src/Distribution/Client/PackageHash.hs @@ -44,7 +44,7 @@ import Distribution.Simple.Compiler , CompilerId , DebugInfoLevel (..) , OptimisationLevel (..) - , PackageDB + , PackageDBCWD , ProfDetailLevel (..) , showProfDetailLevel ) @@ -221,7 +221,7 @@ data PackageHashConfigInputs = PackageHashConfigInputs , pkgHashExtraIncludeDirs :: [FilePath] , pkgHashProgPrefix :: Maybe PathTemplate , pkgHashProgSuffix :: Maybe PathTemplate - , pkgHashPackageDbs :: [Maybe PackageDB] + , pkgHashPackageDbs :: [Maybe PackageDBCWD] , -- Haddock options pkgHashDocumentation :: Bool , pkgHashHaddockHoogle :: Bool diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding.hs b/cabal-install/src/Distribution/Client/ProjectBuilding.hs index addc35089c2..4d7bde7fc55 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding.hs @@ -72,10 +72,6 @@ import Distribution.Client.Types hiding import Distribution.Package import Distribution.Simple.Compiler - ( Compiler - , PackageDB (..) - , jsemSupported - ) import Distribution.Simple.Program import qualified Distribution.Simple.Register as Cabal @@ -478,7 +474,7 @@ createPackageDBIfMissing :: Verbosity -> Compiler -> ProgramDb - -> PackageDB + -> PackageDBCWD -> IO () createPackageDBIfMissing verbosity diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs index 23dff3ff3ab..f1486388b8c 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs @@ -73,7 +73,8 @@ import qualified Distribution.PackageDescription as PD import Distribution.Simple.BuildPaths (haddockDirName) import Distribution.Simple.Command (CommandUI) import Distribution.Simple.Compiler - ( PackageDBStack + ( PackageDBStackCWD + , coercePackageDBStack ) import qualified Distribution.Simple.InstallDirs as InstallDirs import Distribution.Simple.LocalBuildInfo @@ -133,7 +134,7 @@ data PackageBuildingPhase | PBInstallPhase { runCopy :: FilePath -> IO () , runRegister - :: PackageDBStack + :: PackageDBStackCWD -> Cabal.RegisterOptions -> IO InstalledPackageInfo } @@ -191,21 +192,21 @@ buildAndRegisterUnpackedPackage delegate $ PBBuildPhase $ annotateFailure mlogFile BuildFailed $ do - setup buildCommand Cabal.buildCommonFlags buildFlags buildArgs + setup buildCommand Cabal.buildCommonFlags (return . buildFlags) buildArgs -- Haddock phase whenHaddock $ delegate $ PBHaddockPhase $ annotateFailure mlogFile HaddocksFailed $ do - setup haddockCommand Cabal.haddockCommonFlags haddockFlags haddockArgs + setup haddockCommand Cabal.haddockCommonFlags (return . haddockFlags) haddockArgs -- Install phase delegate $ PBInstallPhase { runCopy = \destdir -> annotateFailure mlogFile InstallFailed $ - setup Cabal.copyCommand Cabal.copyCommonFlags (copyFlags destdir) copyArgs + setup Cabal.copyCommand Cabal.copyCommonFlags (return . copyFlags destdir) copyArgs , runRegister = \pkgDBStack registerOpts -> annotateFailure mlogFile InstallFailed $ do -- We register ourselves rather than via Setup.hs. We need to @@ -219,7 +220,7 @@ buildAndRegisterUnpackedPackage compiler progdb Nothing - pkgDBStack + (coercePackageDBStack pkgDBStack) ipkg registerOpts return ipkg @@ -230,14 +231,14 @@ buildAndRegisterUnpackedPackage delegate $ PBTestPhase $ annotateFailure mlogFile TestsFailed $ - setup testCommand Cabal.testCommonFlags testFlags testArgs + setup testCommand Cabal.testCommonFlags (return . testFlags) testArgs -- Bench phase whenBench $ delegate $ PBBenchPhase $ annotateFailure mlogFile BenchFailed $ - setup benchCommand Cabal.benchmarkCommonFlags benchFlags benchArgs + setup benchCommand Cabal.benchmarkCommonFlags (return . benchFlags) benchArgs -- Repl phase whenRepl $ @@ -277,8 +278,9 @@ buildAndRegisterUnpackedPackage configureCommand = Cabal.configureCommand defaultProgramDb configureFlags v = - flip filterConfigureFlags v $ - setupHsConfigureFlags + flip filterConfigureFlags v + <$> setupHsConfigureFlags + (\p -> makeSymbolicPath <$> canonicalizePath p) plan rpkg pkgshared @@ -349,11 +351,11 @@ buildAndRegisterUnpackedPackage setup :: CommandUI flags -> (flags -> CommonSetupFlags) - -> (Version -> flags) + -> (Version -> IO flags) -> (Version -> [String]) -> IO () setup cmd getCommonFlags flags args = - withLogging $ \mLogFileHandle -> + withLogging $ \mLogFileHandle -> do setupWrapper verbosity scriptOptions @@ -382,7 +384,7 @@ buildAndRegisterUnpackedPackage (Just (elabPkgDescription pkg)) cmd getCommonFlags - flags + (\v -> return (flags v)) args generateInstalledPackageInfo :: IO InstalledPackageInfo @@ -397,7 +399,7 @@ buildAndRegisterUnpackedPackage pkgshared (commonFlags v) pkgConfDest - setup (Cabal.registerCommand) Cabal.registerCommonFlags registerFlags (const []) + setup (Cabal.registerCommand) Cabal.registerCommonFlags (\v -> return (registerFlags v)) (const []) withLogging :: (Maybe Handle -> IO r) -> IO r withLogging action = diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs index fe8ea884ccc..a4191325f8b 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs @@ -85,6 +85,7 @@ import Distribution.Simple.Compiler ( CompilerInfo (..) , DebugInfoLevel (..) , OptimisationLevel (..) + , interpretPackageDB ) import Distribution.Simple.InstallDirs (CopyDest (NoCopyDest)) import Distribution.Simple.LocalBuildInfo @@ -685,6 +686,8 @@ convertLegacyAllPackageFlags globalFlags configFlags configExFlags installFlags , globalStoreDir = projectConfigStoreDir } = globalFlags + projectConfigPackageDBs = (fmap . fmap) (interpretPackageDB Nothing) projectConfigPackageDBs_ + ConfigFlags { configCommonFlags = commonFlags , configHcFlavor = projectConfigHcFlavor @@ -693,7 +696,7 @@ convertLegacyAllPackageFlags globalFlags configFlags configExFlags installFlags , -- configProgramPathExtra = projectConfigProgPathExtra DELETE ME configInstallDirs = projectConfigInstallDirs , -- configUserInstall = projectConfigUserInstall, - configPackageDBs = projectConfigPackageDBs + configPackageDBs = projectConfigPackageDBs_ } = configFlags CommonSetupFlags @@ -977,7 +980,7 @@ convertToLegacySharedConfig configFlags = mempty { configCommonFlags = commonFlags - , configPackageDBs = projectConfigPackageDBs + , configPackageDBs = fmap (fmap (fmap unsafeMakeSymbolicPath)) projectConfigPackageDBs , configInstallDirs = projectConfigInstallDirs } diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs index 4c2555c472c..a2826390de6 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs @@ -69,7 +69,7 @@ import Distribution.Simple.Compiler , CompilerFlavor , DebugInfoLevel (..) , OptimisationLevel (..) - , PackageDB + , PackageDBCWD , ProfDetailLevel ) import Distribution.Simple.InstallDirs @@ -198,7 +198,7 @@ data ProjectConfigShared = ProjectConfigShared -- projectConfigUserInstall :: Flag Bool, projectConfigInstallDirs :: InstallDirs (Flag PathTemplate) - , projectConfigPackageDBs :: [Maybe PackageDB] + , projectConfigPackageDBs :: [Maybe PackageDBCWD] , -- configuration used both by the solver and other phases projectConfigRemoteRepos :: NubList RemoteRepo -- ^ Available Hackage servers. diff --git a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs index 8fb0ca8e65f..77573944a19 100644 --- a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs +++ b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs @@ -1049,11 +1049,14 @@ printPlan Nothing -- omit working directory (makeSymbolicPath "$builddir") fullConfigureFlags = - setupHsConfigureFlags - elaboratedPlan - (ReadyPackage elab) - elaboratedShared - commonFlags + runIdentity $ + ( setupHsConfigureFlags + (\_ -> return (error "unused")) + elaboratedPlan + (ReadyPackage elab) + elaboratedShared + commonFlags + ) -- \| Given a default value @x@ for a flag, nub @Flag x@ -- into @NoFlag@. This gives us a tidier command line -- rendering. diff --git a/cabal-install/src/Distribution/Client/ProjectPlanOutput.hs b/cabal-install/src/Distribution/Client/ProjectPlanOutput.hs index d38f07037a6..6a39694ab56 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanOutput.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanOutput.hs @@ -40,7 +40,6 @@ import qualified Distribution.Solver.Types.ComponentDeps as ComponentDeps import qualified Distribution.Compat.Binary as Binary import Distribution.Compat.Graph (Graph, Node) import qualified Distribution.Compat.Graph as Graph -import Distribution.Compiler (CompilerFlavor (GHC, GHCJS)) import Distribution.InstalledPackageInfo (InstalledPackageInfo) import Distribution.Package import qualified Distribution.PackageDescription as PD @@ -50,15 +49,6 @@ import Distribution.Simple.BuildPaths , exeExtension ) import Distribution.Simple.Compiler - ( Compiler - , CompilerId (..) - , PackageDB (..) - , PackageDBStack - , compilerFlavor - , compilerId - , compilerVersion - , showCompilerId - ) import Distribution.Simple.GHC ( GhcEnvironmentFileEntry (..) , GhcImplInfo (supportsPkgEnvFiles) @@ -871,7 +861,7 @@ renderGhcEnvironmentFile :: FilePath -> ElaboratedInstallPlan -> PostBuildProjectStatus - -> [GhcEnvironmentFileEntry] + -> [GhcEnvironmentFileEntry FilePath] renderGhcEnvironmentFile projectRootDir elaboratedInstallPlan @@ -977,7 +967,7 @@ selectGhcEnvironmentFileLibraries PostBuildProjectStatus{..} = elabRequiresRegistration pkg && installedUnitId pkg `Set.member` packagesProbablyUpToDate -selectGhcEnvironmentFilePackageDbs :: ElaboratedInstallPlan -> PackageDBStack +selectGhcEnvironmentFilePackageDbs :: ElaboratedInstallPlan -> PackageDBStackCWD selectGhcEnvironmentFilePackageDbs elaboratedInstallPlan = -- If we have any inplace packages then their package db stack is the -- one we should use since it'll include the store + the local db but @@ -987,7 +977,7 @@ selectGhcEnvironmentFilePackageDbs elaboratedInstallPlan = ([], pkgs) -> checkSamePackageDBs pkgs (pkgs, _) -> checkSamePackageDBs pkgs where - checkSamePackageDBs :: [ElaboratedConfiguredPackage] -> PackageDBStack + checkSamePackageDBs :: [ElaboratedConfiguredPackage] -> PackageDBStackCWD checkSamePackageDBs pkgs = case ordNub (map elabBuildPackageDBStack pkgs) of [packageDbs] -> packageDbs @@ -1019,10 +1009,10 @@ selectGhcEnvironmentFilePackageDbs elaboratedInstallPlan = InstallPlan.PreExisting _ -> Nothing ] -relativePackageDBPaths :: FilePath -> PackageDBStack -> PackageDBStack +relativePackageDBPaths :: FilePath -> PackageDBStackCWD -> PackageDBStackCWD relativePackageDBPaths relroot = map (relativePackageDBPath relroot) -relativePackageDBPath :: FilePath -> PackageDB -> PackageDB +relativePackageDBPath :: FilePath -> PackageDBCWD -> PackageDBCWD relativePackageDBPath relroot pkgdb = case pkgdb of GlobalPackageDB -> GlobalPackageDB diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 765ae803a6d..50423b2d1df 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -724,7 +724,7 @@ rebuildInstallPlan dieWithException verbosity $ PhaseRunSolverErr msg Right plan -> return (plan, pkgConfigDB, tis, ar) where - corePackageDbs :: [PackageDB] + corePackageDbs :: PackageDBStackCWD corePackageDbs = Cabal.interpretPackageDbFlags False (projectConfigPackageDBs projectConfigShared) @@ -955,7 +955,7 @@ getInstalledPackages -> Compiler -> ProgramDb -> Platform - -> PackageDBStack + -> PackageDBStackCWD -> Rebuild InstalledPackageIndex getInstalledPackages verbosity compiler progdb platform packagedbs = do monitorFiles . map monitorFileOrDirectory @@ -964,7 +964,7 @@ getInstalledPackages verbosity compiler progdb platform packagedbs = do verbosity compiler Nothing -- use ambient working directory - packagedbs + (coercePackageDBStack packagedbs) progdb platform ) @@ -3909,22 +3909,31 @@ computeInstallDirs storeDirLayout defaultInstallDirs elaboratedShared elab -- TODO: [code cleanup] perhaps reorder this code -- based on the ElaboratedInstallPlan + ElaboratedSharedConfig, -- make the various Setup.hs {configure,build,copy} flags - setupHsConfigureFlags - :: ElaboratedInstallPlan + :: Monad m + => (FilePath -> m (SymbolicPath Pkg (Dir PkgDB))) + -- ^ How to transform a path which is relative to cabal-install cwd to one which + -- is relative to the route of the package about to be compiled. The simplest way + -- to do this is to convert the potentially relative path into an absolute path. + -> ElaboratedInstallPlan -> ElaboratedReadyPackage -> ElaboratedSharedConfig -> Cabal.CommonSetupFlags - -> Cabal.ConfigFlags + -> m Cabal.ConfigFlags setupHsConfigureFlags + mkSymbolicPath plan (ReadyPackage elab@ElaboratedConfiguredPackage{..}) sharedConfig@ElaboratedSharedConfig{..} - configCommonFlags = - sanityCheckElaboratedConfiguredPackage - sharedConfig - elab - Cabal.ConfigFlags{..} + configCommonFlags = do + -- explicitly clear, then our package db stack + -- TODO: [required eventually] have to do this differently for older Cabal versions + configPackageDBs <- (traverse . traverse . traverse) mkSymbolicPath (Nothing : map Just elabBuildPackageDBStack) + return $ + sanityCheckElaboratedConfiguredPackage + sharedConfig + elab + Cabal.ConfigFlags{..} where Cabal.ConfigFlags { configVanillaLib @@ -4030,10 +4039,6 @@ setupHsConfigureFlags ] ElabComponent _ -> [] - -- explicitly clear, then our package db stack - -- TODO: [required eventually] have to do this differently for older Cabal versions - configPackageDBs = Nothing : map Just elabBuildPackageDBStack - configTests = case elabPkgOrComp of ElabPackage pkg -> toFlag (TestStanzas `optStanzaSetMember` pkgStanzasEnabled pkg) ElabComponent _ -> mempty diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs index e7efc4cc486..31a0d5df248 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs @@ -262,13 +262,13 @@ data ElaboratedConfiguredPackage = ElaboratedConfiguredPackage -- that a user enabled tests globally, and some local packages -- just happen not to have any tests. (But perhaps we should -- warn if ALL local packages don't have any tests.) - , elabPackageDbs :: [Maybe PackageDB] - , elabSetupPackageDBStack :: PackageDBStack - , elabBuildPackageDBStack :: PackageDBStack - , elabRegisterPackageDBStack :: PackageDBStack - , elabInplaceSetupPackageDBStack :: PackageDBStack - , elabInplaceBuildPackageDBStack :: PackageDBStack - , elabInplaceRegisterPackageDBStack :: PackageDBStack + , elabPackageDbs :: [Maybe PackageDBCWD] + , elabSetupPackageDBStack :: PackageDBStackCWD + , elabBuildPackageDBStack :: PackageDBStackCWD + , elabRegisterPackageDBStack :: PackageDBStackCWD + , elabInplaceSetupPackageDBStack :: PackageDBStackCWD + , elabInplaceBuildPackageDBStack :: PackageDBStackCWD + , elabInplaceRegisterPackageDBStack :: PackageDBStackCWD , elabPkgDescriptionOverride :: Maybe CabalFileText , -- TODO: make per-component variants of these flags elabBuildOptions :: LBC.BuildOptions diff --git a/cabal-install/src/Distribution/Client/Run.hs b/cabal-install/src/Distribution/Client/Run.hs index 0c3e5c89e8a..7ff4c8bb5e8 100644 --- a/cabal-install/src/Distribution/Client/Run.hs +++ b/cabal-install/src/Distribution/Client/Run.hs @@ -27,7 +27,7 @@ import Distribution.PackageDescription , PackageDescription (..) , TestSuite (..) ) -import Distribution.Simple (PackageDB (..)) +import Distribution.Simple (PackageDBX (..)) import Distribution.Simple.Build (addInternalBuildTools) import Distribution.Simple.BuildPaths (exeExtension) import Distribution.Simple.Compiler (CompilerFlavor (..), compilerFlavor) @@ -148,7 +148,7 @@ run verbosity lbi exe exeArgs = do pkg_descr = localPkgDescr lbi i = interpretSymbolicPathLBI lbi -- See Note [Symbolic paths] in Distribution.Utils.Path mbWorkDir = mbWorkDirLBI lbi - internalPkgDb = i $ internalPackageDBPath lbi distPref + internalPkgDb = internalPackageDBPath lbi distPref lbiForExe = lbi { withPackageDB = withPackageDB lbi ++ [SpecificPackageDB internalPkgDb] diff --git a/cabal-install/src/Distribution/Client/SetupWrapper.hs b/cabal-install/src/Distribution/Client/SetupWrapper.hs index 936412cf4fb..1b401ff6f7c 100644 --- a/cabal-install/src/Distribution/Client/SetupWrapper.hs +++ b/cabal-install/src/Distribution/Client/SetupWrapper.hs @@ -34,10 +34,6 @@ import Prelude () import qualified Distribution.Backpack as Backpack import Distribution.CabalSpecVersion (cabalSpecMinimumLibraryVersion) -import Distribution.Compiler - ( CompilerFlavor (GHC, GHCJS) - , buildCompilerId - ) import qualified Distribution.Make as Make import Distribution.Package ( ComponentId @@ -65,11 +61,6 @@ import Distribution.Simple.BuildPaths , exeExtension ) import Distribution.Simple.Compiler - ( Compiler (compilerId) - , PackageDB (..) - , PackageDBStack - , compilerFlavor - ) import Distribution.Simple.Configure ( configCompilerEx ) @@ -126,6 +117,7 @@ import Distribution.Client.JobControl import Distribution.Client.Types import Distribution.Client.Utils ( existsAndIsMoreRecentThan + , makeRelativeToDirS #ifdef mingw32_HOST_OS , canonicalizePathNoThrow #endif @@ -258,7 +250,7 @@ data SetupScriptOptions = SetupScriptOptions -- if needed. , useCompiler :: Maybe Compiler , usePlatform :: Maybe Platform - , usePackageDB :: PackageDBStack + , usePackageDB :: PackageDBStackCWD , usePackageIndex :: Maybe InstalledPackageIndex , useProgramDb :: ProgramDb , useDistPref :: SymbolicPath Pkg (Dir Dist) @@ -511,15 +503,15 @@ setupWrapper -> Maybe PackageDescription -> CommandUI flags -> (flags -> CommonSetupFlags) - -> (Version -> flags) + -> (Version -> IO flags) -- ^ produce command flags given the Cabal library version -> (Version -> [String]) -> IO () setupWrapper verbosity options mpkg cmd getCommonFlags getFlags getExtraArgs = do setup <- getSetup verbosity options mpkg let version = setupVersion setup - flags = getFlags version extraArgs = getExtraArgs version + flags <- getFlags version runSetupCommand verbosity setup @@ -1073,6 +1065,7 @@ getExternalSetupMethod verbosity options pkg bt = do when (outOfDate || forceCompile) $ do debug verbosity "Setup executable needs to be updated, compiling..." (compiler, progdb, options'') <- configureCompiler options' + pkgDbs <- traverse (traverse (makeRelativeToDirS mbWorkDir)) (coercePackageDBStack (usePackageDB options'')) let cabalPkgid = PackageIdentifier (mkPackageName "Cabal") cabalLibVersion (program, extraOpts) = case compilerFlavor compiler of @@ -1118,7 +1111,7 @@ getExternalSetupMethod verbosity options pkg bt = do Custom -> toNubListR [sameDirectory] Hooks -> toNubListR [sameDirectory] _ -> mempty - , ghcOptPackageDBs = usePackageDB options'' + , ghcOptPackageDBs = pkgDbs , ghcOptHideAllPackages = Flag (useDependenciesExclusive options') , ghcOptCabal = Flag (useDependenciesExclusive options') , ghcOptPackages = toNubListR $ map addRenaming selectedDeps diff --git a/cabal-install/src/Distribution/Client/Utils.hs b/cabal-install/src/Distribution/Client/Utils.hs index 69d46f8a473..b1ad7bd9a37 100644 --- a/cabal-install/src/Distribution/Client/Utils.hs +++ b/cabal-install/src/Distribution/Client/Utils.hs @@ -19,6 +19,7 @@ module Distribution.Client.Utils , makeAbsoluteToCwd , makeRelativeToCwd , makeRelativeToDir + , makeRelativeToDirS , makeRelativeCanonical , filePathToByteString , byteStringToFilePath @@ -76,8 +77,11 @@ import Distribution.Utils.Path , Pkg , RelativePath , SymbolicPath + , getSymbolicPath , makeSymbolicPath , relativeSymbolicPath + , sameDirectory + , symbolicPathRelative_maybe ) import Distribution.Version @@ -264,6 +268,16 @@ makeRelativeToDir :: FilePath -> FilePath -> IO FilePath makeRelativeToDir path dir = makeRelativeCanonical <$> canonicalizePath path <*> canonicalizePath dir +-- | makeRelativeToDir for SymbolicPath +makeRelativeToDirS :: Maybe (SymbolicPath CWD (Dir dir)) -> SymbolicPath CWD to -> IO (SymbolicPath dir to) +makeRelativeToDirS Nothing s = makeRelativeToDirS (Just sameDirectory) s +makeRelativeToDirS (Just root) p = + case symbolicPathRelative_maybe p of + -- TODO: Use AbsolutePath + Nothing -> return $ makeSymbolicPath (getSymbolicPath p) + Just rel_path -> + makeSymbolicPath <$> makeRelativeToDir (getSymbolicPath root) (getSymbolicPath rel_path) + -- | Given a canonical absolute path and canonical absolute dir, make the path -- relative to the directory, including using @../..@ if necessary. Returns -- the original absolute path if it is not on the same drive as the given dir. diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init.hs index b06faef5312..ce33e9ab302 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init.hs @@ -17,6 +17,7 @@ import Distribution.Client.IndexUtils import Distribution.Client.Init.Types import Distribution.Client.Sandbox import Distribution.Client.Setup +import Distribution.Simple.Compiler import Distribution.Verbosity tests :: IO [TestTree] @@ -32,7 +33,7 @@ tests = do withRepoContext v globalFlags' $ \repoCtx -> do let pkgDb = configPackageDB' confFlags' - pkgIx <- getInstalledPackages v comp pkgDb progdb + pkgIx <- getInstalledPackages v comp (interpretPackageDBStack Nothing pkgDb) progdb srcDb <- getSourcePackages v repoCtx return diff --git a/cabal-install/tests/UnitTests/Distribution/Client/TreeDiffInstances.hs b/cabal-install/tests/UnitTests/Distribution/Client/TreeDiffInstances.hs index 0dede72858a..da9bd8ad90d 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/TreeDiffInstances.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/TreeDiffInstances.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} @@ -21,7 +22,7 @@ import Distribution.Client.Types import Distribution.Client.Types.OverwritePolicy (OverwritePolicy) import Distribution.Client.Types.SourceRepo (SourceRepositoryPackage) -import Distribution.Simple.Compiler (PackageDB) +import Distribution.Simple.Compiler (PackageDBX) import Data.TreeDiff.Class import Data.TreeDiff.Instances.Cabal () @@ -54,7 +55,7 @@ instance ToExpr OptionalStanza instance ToExpr Outcome instance ToExpr OverwritePolicy instance ToExpr PackageConfig -instance ToExpr PackageDB +instance ToExpr (PackageDBX FilePath) instance ToExpr PackageProperty instance ToExpr PreferOldest instance ToExpr PreSolver diff --git a/cabal-testsuite/PackageTests/ShowBuildInfo/Complex/single.out b/cabal-testsuite/PackageTests/ShowBuildInfo/Complex/single.out index 98ffd99b300..3825d1f6cf8 100644 --- a/cabal-testsuite/PackageTests/ShowBuildInfo/Complex/single.out +++ b/cabal-testsuite/PackageTests/ShowBuildInfo/Complex/single.out @@ -15,11 +15,11 @@ Warning: [unknown-directory] 'hs-source-dirs: doesnt-exist' specifies a director Preprocessing executable 'Complex' for Complex-0.1.0.0... Building executable 'Complex' for Complex-0.1.0.0... # show-build-info Complex exe:Complex -{"cabal-lib-version":"","compiler":{"flavour":"ghc","compiler-id":"ghc-","path":""},"components":[{"type":"exe","name":"exe:Complex","unit-id":"Complex-0.1.0.0-inplace-Complex","compiler-args":["-fbuilding-cabal-package","-O","-outputdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build","-odir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build","-hidir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build","-hiedir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build/extra-compilation-artifacts/hie","-stubdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build","-i","-iapp","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build/Complex/autogen","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build/Complex/autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build","-optP-include","-optPsingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build/Complex/autogen/cabal_macros.h","-this-unit-id","Complex-0.1.0.0-inplace-Complex","-hide-all-packages","-Wmissing-home-modules","-no-user-package-db","-package-db","/single.dist/home/.cabal/store/ghc-/package.db","-package-db","/single.dist/work/./dist/packagedb/ghc-","-package-id","","-package-id","","-XHaskell2010","-threaded","-rtsopts","-with-rtsopts=-N -T","-Wredundant-constraints"],"modules":["Other","Paths_Complex"],"src-files":["Main.lhs"],"hs-src-dirs":["app"],"src-dir":"/","cabal-file":"Complex.cabal"}]} +{"cabal-lib-version":"","compiler":{"flavour":"ghc","compiler-id":"ghc-","path":""},"components":[{"type":"exe","name":"exe:Complex","unit-id":"Complex-0.1.0.0-inplace-Complex","compiler-args":["-fbuilding-cabal-package","-O","-outputdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build","-odir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build","-hidir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build","-hiedir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build/extra-compilation-artifacts/hie","-stubdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build","-i","-iapp","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build/Complex/autogen","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build/Complex/autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build","-optP-include","-optPsingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/x/Complex/build/Complex/autogen/cabal_macros.h","-this-unit-id","Complex-0.1.0.0-inplace-Complex","-hide-all-packages","-Wmissing-home-modules","-no-user-package-db","-package-db","/single.dist/home/.cabal/store/ghc-/package.db","-package-db","/single.dist/work/dist/packagedb/ghc-","-package-id","","-package-id","","-XHaskell2010","-threaded","-rtsopts","-with-rtsopts=-N -T","-Wredundant-constraints"],"modules":["Other","Paths_Complex"],"src-files":["Main.lhs"],"hs-src-dirs":["app"],"src-dir":"/","cabal-file":"Complex.cabal"}]} # cabal build Up to date # show-build-info Complex lib -{"cabal-lib-version":"","compiler":{"flavour":"ghc","compiler-id":"ghc-","path":""},"components":[{"type":"lib","name":"lib","unit-id":"Complex-0.1.0.0-inplace","compiler-args":["-fbuilding-cabal-package","-O","-outputdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build","-odir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build","-hidir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build","-hiedir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build/extra-compilation-artifacts/hie","-stubdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build","-i","-isrc","-idoesnt-exist","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build/autogen","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build/autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build","-optP-include","-optPsingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build/autogen/cabal_macros.h","-this-unit-id","Complex-0.1.0.0-inplace","-hide-all-packages","-Wmissing-home-modules","-no-user-package-db","-package-db","/single.dist/home/.cabal/store/ghc-/package.db","-package-db","/single.dist/work/./dist/packagedb/ghc-","-package-id","","-XHaskell2010","-Wall"],"modules":["A","B","C","D","Paths_Complex"],"src-files":[],"hs-src-dirs":["src","doesnt-exist"],"src-dir":"/","cabal-file":"Complex.cabal"}]} +{"cabal-lib-version":"","compiler":{"flavour":"ghc","compiler-id":"ghc-","path":""},"components":[{"type":"lib","name":"lib","unit-id":"Complex-0.1.0.0-inplace","compiler-args":["-fbuilding-cabal-package","-O","-outputdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build","-odir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build","-hidir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build","-hiedir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build/extra-compilation-artifacts/hie","-stubdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build","-i","-isrc","-idoesnt-exist","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build/autogen","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build/autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build","-optP-include","-optPsingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/build/autogen/cabal_macros.h","-this-unit-id","Complex-0.1.0.0-inplace","-hide-all-packages","-Wmissing-home-modules","-no-user-package-db","-package-db","/single.dist/home/.cabal/store/ghc-/package.db","-package-db","/single.dist/work/dist/packagedb/ghc-","-package-id","","-XHaskell2010","-Wall"],"modules":["A","B","C","D","Paths_Complex"],"src-files":[],"hs-src-dirs":["src","doesnt-exist"],"src-dir":"/","cabal-file":"Complex.cabal"}]} # cabal build Build profile: -w ghc- -O1 In order, the following will be built: @@ -34,7 +34,7 @@ Warning: [unknown-directory] 'hs-source-dirs: doesnt-exist' specifies a director Preprocessing benchmark 'complex-benchmarks' for Complex-0.1.0.0... Building benchmark 'complex-benchmarks' for Complex-0.1.0.0... # show-build-info Complex bench:complex-benchmarks -{"cabal-lib-version":"","compiler":{"flavour":"ghc","compiler-id":"ghc-","path":""},"components":[{"type":"bench","name":"bench:complex-benchmarks","unit-id":"Complex-0.1.0.0-inplace-complex-benchmarks","compiler-args":["-fbuilding-cabal-package","-O","-outputdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build","-odir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build","-hidir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build","-hiedir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build/extra-compilation-artifacts/hie","-stubdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build","-i","-ibenchmark","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build/complex-benchmarks/autogen","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build/complex-benchmarks/autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build","-optP-include","-optPsingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build/complex-benchmarks/autogen/cabal_macros.h","-this-unit-id","Complex-0.1.0.0-inplace-complex-benchmarks","-hide-all-packages","-Wmissing-home-modules","-no-user-package-db","-package-db","/single.dist/home/.cabal/store/ghc-/package.db","-package-db","/single.dist/work/./dist/packagedb/ghc-","-package-id","","-package-id","","-package-id","","-XHaskell2010","-Wall","-rtsopts","-threaded","-with-rtsopts=-N"],"modules":["Paths_Complex"],"src-files":["Main.hs"],"hs-src-dirs":["benchmark"],"src-dir":"/","cabal-file":"Complex.cabal"}]} +{"cabal-lib-version":"","compiler":{"flavour":"ghc","compiler-id":"ghc-","path":""},"components":[{"type":"bench","name":"bench:complex-benchmarks","unit-id":"Complex-0.1.0.0-inplace-complex-benchmarks","compiler-args":["-fbuilding-cabal-package","-O","-outputdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build","-odir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build","-hidir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build","-hiedir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build/extra-compilation-artifacts/hie","-stubdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build","-i","-ibenchmark","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build/complex-benchmarks/autogen","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build/complex-benchmarks/autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build","-optP-include","-optPsingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/b/complex-benchmarks/build/complex-benchmarks/autogen/cabal_macros.h","-this-unit-id","Complex-0.1.0.0-inplace-complex-benchmarks","-hide-all-packages","-Wmissing-home-modules","-no-user-package-db","-package-db","/single.dist/home/.cabal/store/ghc-/package.db","-package-db","/single.dist/work/dist/packagedb/ghc-","-package-id","","-package-id","","-package-id","","-XHaskell2010","-Wall","-rtsopts","-threaded","-with-rtsopts=-N"],"modules":["Paths_Complex"],"src-files":["Main.hs"],"hs-src-dirs":["benchmark"],"src-dir":"/","cabal-file":"Complex.cabal"}]} # cabal build Build profile: -w ghc- -O1 In order, the following will be built: @@ -49,7 +49,7 @@ Warning: [unknown-directory] 'hs-source-dirs: doesnt-exist' specifies a director Preprocessing test suite 'func-test' for Complex-0.1.0.0... Building test suite 'func-test' for Complex-0.1.0.0... # show-build-info Complex test:func-test -{"cabal-lib-version":"","compiler":{"flavour":"ghc","compiler-id":"ghc-","path":""},"components":[{"type":"test","name":"test:func-test","unit-id":"Complex-0.1.0.0-inplace-func-test","compiler-args":["-fbuilding-cabal-package","-O","-outputdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build","-odir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build","-hidir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build","-hiedir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build/extra-compilation-artifacts/hie","-stubdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build","-i","-itest","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build/func-test/autogen","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build/func-test/autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build","-optP-include","-optPsingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build/func-test/autogen/cabal_macros.h","-this-unit-id","Complex-0.1.0.0-inplace-func-test","-hide-all-packages","-Wmissing-home-modules","-no-user-package-db","-package-db","/single.dist/home/.cabal/store/ghc-/package.db","-package-db","/single.dist/work/./dist/packagedb/ghc-","-package-id","","-package-id","","-package-id","","-XHaskell2010"],"modules":[],"src-files":["FuncMain.hs"],"hs-src-dirs":["test"],"src-dir":"/","cabal-file":"Complex.cabal"}]} +{"cabal-lib-version":"","compiler":{"flavour":"ghc","compiler-id":"ghc-","path":""},"components":[{"type":"test","name":"test:func-test","unit-id":"Complex-0.1.0.0-inplace-func-test","compiler-args":["-fbuilding-cabal-package","-O","-outputdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build","-odir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build","-hidir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build","-hiedir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build/extra-compilation-artifacts/hie","-stubdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build","-i","-itest","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build/func-test/autogen","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build/func-test/autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build","-optP-include","-optPsingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/func-test/build/func-test/autogen/cabal_macros.h","-this-unit-id","Complex-0.1.0.0-inplace-func-test","-hide-all-packages","-Wmissing-home-modules","-no-user-package-db","-package-db","/single.dist/home/.cabal/store/ghc-/package.db","-package-db","/single.dist/work/dist/packagedb/ghc-","-package-id","","-package-id","","-package-id","","-XHaskell2010"],"modules":[],"src-files":["FuncMain.hs"],"hs-src-dirs":["test"],"src-dir":"/","cabal-file":"Complex.cabal"}]} # cabal build Build profile: -w ghc- -O1 In order, the following will be built: @@ -64,4 +64,4 @@ Warning: [unknown-directory] 'hs-source-dirs: doesnt-exist' specifies a director Preprocessing test suite 'unit-test' for Complex-0.1.0.0... Building test suite 'unit-test' for Complex-0.1.0.0... # show-build-info Complex test:unit-test -{"cabal-lib-version":"","compiler":{"flavour":"ghc","compiler-id":"ghc-","path":""},"components":[{"type":"test","name":"test:unit-test","unit-id":"Complex-0.1.0.0-inplace-unit-test","compiler-args":["-fbuilding-cabal-package","-O","-outputdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build","-odir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build","-hidir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build","-hiedir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build/extra-compilation-artifacts/hie","-stubdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build","-i","-itest","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build/unit-test/autogen","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build/unit-test/autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build","-optP-include","-optPsingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build/unit-test/autogen/cabal_macros.h","-this-unit-id","Complex-0.1.0.0-inplace-unit-test","-hide-all-packages","-Wmissing-home-modules","-no-user-package-db","-package-db","/single.dist/home/.cabal/store/ghc-/package.db","-package-db","/single.dist/work/./dist/packagedb/ghc-","-package-id","","-package-id","","-XHaskell2010"],"modules":[],"src-files":["UnitMain.hs"],"hs-src-dirs":["test"],"src-dir":"/","cabal-file":"Complex.cabal"}]} +{"cabal-lib-version":"","compiler":{"flavour":"ghc","compiler-id":"ghc-","path":""},"components":[{"type":"test","name":"test:unit-test","unit-id":"Complex-0.1.0.0-inplace-unit-test","compiler-args":["-fbuilding-cabal-package","-O","-outputdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build","-odir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build","-hidir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build","-hiedir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build/extra-compilation-artifacts/hie","-stubdir","single.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build","-i","-itest","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build/unit-test/autogen","-isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build/unit-test/autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build/global-autogen","-Isingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build","-optP-include","-optPsingle.dist/work/./dist/build//ghc-/Complex-0.1.0.0/t/unit-test/build/unit-test/autogen/cabal_macros.h","-this-unit-id","Complex-0.1.0.0-inplace-unit-test","-hide-all-packages","-Wmissing-home-modules","-no-user-package-db","-package-db","/single.dist/home/.cabal/store/ghc-/package.db","-package-db","/single.dist/work/dist/packagedb/ghc-","-package-id","","-package-id","","-XHaskell2010"],"modules":[],"src-files":["UnitMain.hs"],"hs-src-dirs":["test"],"src-dir":"/","cabal-file":"Complex.cabal"}]} diff --git a/cabal-testsuite/Setup.hs b/cabal-testsuite/Setup.hs index ca4ab043b04..b5744198abc 100644 --- a/cabal-testsuite/Setup.hs +++ b/cabal-testsuite/Setup.hs @@ -39,7 +39,7 @@ generateScriptEnvModule lbi verbosity = do , "import Distribution.Backpack (OpenUnitId)" , "import Data.Map (fromList)" , "" - , "lbiPackageDbStack :: PackageDBStack" + , "lbiPackageDbStack :: PackageDBStackCWD" , "lbiPackageDbStack = " ++ show lbiPackageDbStack , "" , "lbiPlatform :: Platform" diff --git a/cabal-testsuite/src/Test/Cabal/Monad.hs b/cabal-testsuite/src/Test/Cabal/Monad.hs index 04eb659696c..db685c45379 100644 --- a/cabal-testsuite/src/Test/Cabal/Monad.hs +++ b/cabal-testsuite/src/Test/Cabal/Monad.hs @@ -68,7 +68,7 @@ import Test.Cabal.TestCode import Distribution.Pretty (prettyShow) import Distribution.Simple.Compiler - ( PackageDBStack, PackageDB(..), compilerFlavor + ( PackageDBStackCWD, PackageDBX(..), compilerFlavor , Compiler, compilerVersion, showCompilerIdWithAbi ) import Distribution.System import Distribution.Simple.Program.Db @@ -660,7 +660,7 @@ data TestEnv = TestEnv -- | Platform we are running tests on , testPlatform :: Platform -- | Package database stack (actually this changes lol) - , testPackageDBStack :: PackageDBStack + , testPackageDBStack :: PackageDBStackCWD -- | How verbose to be , testVerbosity :: Verbosity -- | How long we should 'threadDelay' to make sure the file timestamp is diff --git a/cabal-testsuite/src/Test/Cabal/Prelude.hs b/cabal-testsuite/src/Test/Cabal/Prelude.hs index c9a975e0fb7..64c12b0f04d 100644 --- a/cabal-testsuite/src/Test/Cabal/Prelude.hs +++ b/cabal-testsuite/src/Test/Cabal/Prelude.hs @@ -24,7 +24,7 @@ import Test.Cabal.Monad import Test.Cabal.Plan import Distribution.Compat.Time (calibrateMtimeChangeDelay) -import Distribution.Simple.Compiler (PackageDBStack, PackageDB(..)) +import Distribution.Simple.Compiler (PackageDBStackCWD, PackageDBCWD, PackageDBX(..)) import Distribution.Simple.PackageDescription (readGenericPackageDescription) import Distribution.Simple.Program.Types import Distribution.Simple.Program.Db @@ -264,11 +264,11 @@ setup_install_with_docs args = do setup "register" [] return () -packageDBParams :: PackageDBStack -> [String] +packageDBParams :: PackageDBStackCWD -> [String] packageDBParams dbs = "--package-db=clear" : map (("--package-db=" ++) . convert) dbs where - convert :: PackageDB -> String + convert :: PackageDBCWD -> String convert GlobalPackageDB = "global" convert UserPackageDB = "user" convert (SpecificPackageDB path) = path @@ -438,9 +438,9 @@ ghcPkg' cmd args = do recordHeader ["ghc-pkg", cmd] runProgramM ghcPkgProgram (cmd : extraArgs ++ args) Nothing -ghcPkgPackageDBParams :: Version -> PackageDBStack -> [String] +ghcPkgPackageDBParams :: Version -> PackageDBStackCWD -> [String] ghcPkgPackageDBParams version dbs = concatMap convert dbs where - convert :: PackageDB -> [String] + convert :: PackageDBCWD -> [String] -- Ignoring global/user is dodgy but there's no way good -- way to give ghc-pkg the correct flags in this case. convert GlobalPackageDB = [] diff --git a/cabal-testsuite/src/Test/Cabal/Script.hs b/cabal-testsuite/src/Test/Cabal/Script.hs index 15e17ed2b94..117fd21861c 100644 --- a/cabal-testsuite/src/Test/Cabal/Script.hs +++ b/cabal-testsuite/src/Test/Cabal/Script.hs @@ -35,7 +35,7 @@ import qualified Data.Monoid as M -- parameters for invoking GHC. Mostly subset of 'LocalBuildInfo'. data ScriptEnv = ScriptEnv { runnerProgramDb :: ProgramDb - , runnerPackageDbStack :: PackageDBStack + , runnerPackageDbStack :: PackageDBStackCWD , runnerVerbosity :: Verbosity , runnerPlatform :: Platform , runnerCompiler :: Compiler @@ -97,7 +97,7 @@ runnerGhcArgs :: ScriptEnv -> Maybe FilePath -> [String] runnerGhcArgs senv mb_cwd = renderGhcOptions (runnerCompiler senv) (runnerPlatform senv) ghc_options where - ghc_options = M.mempty { ghcOptPackageDBs = runnerPackageDbStack senv + ghc_options = M.mempty { ghcOptPackageDBs = fmap (fmap makeSymbolicPath) (runnerPackageDbStack senv) , ghcOptPackages = toNubListR (runnerPackages senv) , ghcOptHideAllPackages = Flag True -- Avoid picking stray module files that look From 8b0f2d57e9e10cf6d8e92ddd8029bd695763143b Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Thu, 8 Aug 2024 15:01:08 +0100 Subject: [PATCH 105/207] Introduce AbsolutePath to symbolic path abstraction There are a few places where paths are known to be absolute. This enforces that in the type system by introducing a simple wrapper to `Distribution.Utils.Path`. ``` newtype AbsolutePath (to :: FileOrDir) = AbsolutePath (forall from . SymbolicPath from to) ``` The nice thing about this abstraction is when when a path is unwrapped, due to the universally quantified `from` type, the resulting `SymbolicPath` can be used with any API which expects a path to point `from` a specific directory. --- Cabal-syntax/src/Distribution/Utils/Path.hs | 34 ++++++++++++++++--- .../PackageDescription/Check/Warning.hs | 2 +- Cabal/src/Distribution/Simple/Build.hs | 6 ++-- .../src/Distribution/Simple/LocalBuildInfo.hs | 2 +- Cabal/src/Distribution/Simple/PreProcess.hs | 4 +-- Cabal/src/Distribution/Simple/Register.hs | 5 ++- .../src/Distribution/Simple/ShowBuildInfo.hs | 6 ++-- 7 files changed, 40 insertions(+), 19 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Utils/Path.hs b/Cabal-syntax/src/Distribution/Utils/Path.hs index 62caa220b74..0e1c7c191e4 100644 --- a/Cabal-syntax/src/Distribution/Utils/Path.hs +++ b/Cabal-syntax/src/Distribution/Utils/Path.hs @@ -35,10 +35,12 @@ module Distribution.Utils.Path -- * Symbolic paths , RelativePath , SymbolicPath + , AbsolutePath (..) , SymbolicPathX -- NB: constructor not exposed, to retain type safety. -- ** Symbolic path API , getSymbolicPath + , getAbsolutePath , sameDirectory , makeRelativePathEx , makeSymbolicPath @@ -48,6 +50,7 @@ module Distribution.Utils.Path , relativeSymbolicPath , symbolicPathRelative_maybe , interpretSymbolicPath + , interpretSymbolicPathAbsolute -- ** General filepath API , () @@ -215,6 +218,11 @@ type RelativePath = SymbolicPathX 'OnlyRelative -- until we interpret them (using e.g. 'interpretSymbolicPath'). type SymbolicPath = SymbolicPathX 'AllowAbsolute +newtype AbsolutePath (to :: FileOrDir) = AbsolutePath (forall from. SymbolicPath from to) + +unsafeMakeAbsolutePath :: FilePath -> AbsolutePath to +unsafeMakeAbsolutePath fp = AbsolutePath (makeSymbolicPath fp) + instance Binary (SymbolicPathX allowAbsolute from to) instance (Typeable allowAbsolute, Typeable from, Typeable to) @@ -320,6 +328,12 @@ interpretSymbolicPath mbWorkDir (SymbolicPath p) = interpretSymbolicPathCWD :: SymbolicPathX allowAbsolute from to -> FilePath interpretSymbolicPathCWD (SymbolicPath p) = p +getAbsolutePath :: AbsolutePath to -> FilePath +getAbsolutePath (AbsolutePath p) = getSymbolicPath p + +interpretSymbolicPathAbsolute :: AbsolutePath (Dir Pkg) -> SymbolicPathX allowAbsolute Pkg to -> FilePath +interpretSymbolicPathAbsolute (AbsolutePath p) sym = interpretSymbolicPath (Just p) sym + -- | Change what a symbolic path is pointing to. coerceSymbolicPath :: SymbolicPathX allowAbsolute from to1 -> SymbolicPathX allowAbsolute from to2 coerceSymbolicPath = coerce @@ -343,9 +357,9 @@ symbolicPathRelative_maybe (SymbolicPath fp) = else Just $ SymbolicPath fp -- | Absolute path to the current working directory. -absoluteWorkingDir :: Maybe (SymbolicPath CWD to) -> IO FilePath -absoluteWorkingDir Nothing = Directory.getCurrentDirectory -absoluteWorkingDir (Just wd) = Directory.makeAbsolute $ getSymbolicPath wd +absoluteWorkingDir :: Maybe (SymbolicPath CWD to) -> IO (AbsolutePath to) +absoluteWorkingDir Nothing = unsafeMakeAbsolutePath <$> Directory.getCurrentDirectory +absoluteWorkingDir (Just wd) = unsafeMakeAbsolutePath <$> Directory.makeAbsolute (getSymbolicPath wd) -- | Try to make a symbolic path relative. -- @@ -354,8 +368,8 @@ absoluteWorkingDir (Just wd) = Directory.makeAbsolute $ getSymbolicPath wd -- NB: this function may fail to make the path relative. tryMakeRelative :: Maybe (SymbolicPath CWD (Dir dir)) -> SymbolicPath dir to -> IO (SymbolicPath dir to) tryMakeRelative mbWorkDir (SymbolicPath fp) = do - wd <- absoluteWorkingDir mbWorkDir - return $ SymbolicPath (FilePath.makeRelative wd fp) + AbsolutePath wd <- absoluteWorkingDir mbWorkDir + return $ SymbolicPath (FilePath.makeRelative (getSymbolicPath wd) fp) ------------------------------------------------------------------------------- @@ -425,6 +439,16 @@ instance where SymbolicPath p1 SymbolicPath p2 = SymbolicPath (p1 p2) +instance + (b1 ~ 'Dir b2, c2 ~ c3, midAbsolute ~ OnlyRelative) + => PathLike + (AbsolutePath b1) + (SymbolicPathX midAbsolute b2 c2) + (AbsolutePath c3) + where + AbsolutePath (SymbolicPath p1) SymbolicPath p2 = + unsafeMakeAbsolutePath (p1 p2) + -------------------------------------------------------------------------------- -- Abstract directory locations. diff --git a/Cabal/src/Distribution/PackageDescription/Check/Warning.hs b/Cabal/src/Distribution/PackageDescription/Check/Warning.hs index 778a89ddfbe..8588333c1a5 100644 --- a/Cabal/src/Distribution/PackageDescription/Check/Warning.hs +++ b/Cabal/src/Distribution/PackageDescription/Check/Warning.hs @@ -47,7 +47,7 @@ import Distribution.Types.PackageName (PackageName) import Distribution.Types.TestType (TestType, knownTestTypes) import Distribution.Types.UnqualComponentName import Distribution.Types.Version (Version) -import Distribution.Utils.Path +import Distribution.Utils.Path (FileOrDir (..), Pkg, RelativePath, getSymbolicPath) import Language.Haskell.Extension (Extension) import qualified Data.Either as Either diff --git a/Cabal/src/Distribution/Simple/Build.hs b/Cabal/src/Distribution/Simple/Build.hs index 33b523c6177..e153c25b9d7 100644 --- a/Cabal/src/Distribution/Simple/Build.hs +++ b/Cabal/src/Distribution/Simple/Build.hs @@ -275,7 +275,6 @@ dumpBuildInfo -- ^ Flags that the user passed to build -> IO () dumpBuildInfo verbosity distPref dumpBuildInfoFlag pkg_descr lbi flags = do - let mbWorkDir = flagToMaybe $ buildWorkingDir flags when shouldDumpBuildInfo $ do -- Changing this line might break consumers of the dumped build info. -- Announce changes on mailing lists! @@ -289,13 +288,12 @@ dumpBuildInfo verbosity distPref dumpBuildInfoFlag pkg_descr lbi flags = do activeTargets ) - wdir <- absoluteWorkingDir mbWorkDir - (compilerProg, _) <- case flavorToProgram (compilerFlavor (compiler lbi)) of Nothing -> dieWithException verbosity $ UnknownCompilerFlavor (compilerFlavor (compiler lbi)) Just program -> requireProgram verbosity program (withPrograms lbi) + wdir <- absoluteWorkingDirLBI lbi let (warns, json) = mkBuildInfo wdir pkg_descr lbi flags (compilerProg, compiler lbi) activeTargets buildInfoText = renderJson json unless (null warns) $ @@ -791,7 +789,7 @@ testSuiteLibV09AsLibAndExe -> TestSuite -> ComponentLocalBuildInfo -> LocalBuildInfo - -> FilePath + -> AbsolutePath (Dir Pkg) -- ^ absolute inplace dir -> SymbolicPath Pkg (Dir Dist) -> ( PackageDescription diff --git a/Cabal/src/Distribution/Simple/LocalBuildInfo.hs b/Cabal/src/Distribution/Simple/LocalBuildInfo.hs index dce6ff0f8bb..eb04ba870c6 100644 --- a/Cabal/src/Distribution/Simple/LocalBuildInfo.hs +++ b/Cabal/src/Distribution/Simple/LocalBuildInfo.hs @@ -162,7 +162,7 @@ mbWorkDirLBI = flagToMaybe . setupWorkingDir . configCommonFlags . configFlags -- | Absolute path to the current working directory. -absoluteWorkingDirLBI :: LocalBuildInfo -> IO FilePath +absoluteWorkingDirLBI :: LocalBuildInfo -> IO (AbsolutePath (Dir Pkg)) absoluteWorkingDirLBI lbi = absoluteWorkingDir (mbWorkDirLBI lbi) -- | Perform the action on each enabled 'library' in the package diff --git a/Cabal/src/Distribution/Simple/PreProcess.hs b/Cabal/src/Distribution/Simple/PreProcess.hs index 00e6e68cb5c..d407ccbe2ec 100644 --- a/Cabal/src/Distribution/Simple/PreProcess.hs +++ b/Cabal/src/Distribution/Simple/PreProcess.hs @@ -347,8 +347,8 @@ preprocessFile mbWorkDir searchLoc buildLoc forSDist baseFile verbosity builtinS createDirectoryIfMissingVerbose verbosity True destDir runPreProcessorWithHsBootHack pp - (i psrcLoc, getSymbolicPath $ psrcRelFile) - (i buildLoc, srcStem <.> "hs") + (getSymbolicPath $ psrcLoc, getSymbolicPath $ psrcRelFile) + (getSymbolicPath $ buildLoc, srcStem <.> "hs") where i = interpretSymbolicPath mbWorkDir -- See Note [Symbolic paths] in Distribution.Utils.Path buildAsSrcLoc :: SymbolicPath Pkg (Dir Source) diff --git a/Cabal/src/Distribution/Simple/Register.hs b/Cabal/src/Distribution/Simple/Register.hs index c3328046857..46459b8103f 100644 --- a/Cabal/src/Distribution/Simple/Register.hs +++ b/Cabal/src/Distribution/Simple/Register.hs @@ -609,8 +609,7 @@ generalInstalledPackageInfo adjustRelIncDirs pkg abi_hash lib lbi clbi installDi -- -- This function knows about the layout of in place packages. inplaceInstalledPackageInfo - :: FilePath - -- ^ top of the build tree (absolute path) + :: AbsolutePath (Dir Pkg) -> SymbolicPath Pkg (Dir Dist) -- ^ location of the dist tree -> PackageDescription @@ -629,7 +628,7 @@ inplaceInstalledPackageInfo inplaceDir distPref pkg abi_hash lib lbi clbi = clbi installDirs where - i = interpretSymbolicPath (Just $ makeSymbolicPath inplaceDir) -- See Note [Symbolic paths] in Distribution.Utils.Path + i = interpretSymbolicPathAbsolute inplaceDir -- See Note [Symbolic paths] in Distribution.Utils.Path adjustRelativeIncludeDirs = concatMap $ \d -> [ i $ makeRelativePathEx d -- local include-dir , i $ libTargetDir makeRelativePathEx d -- autogen include-dir diff --git a/Cabal/src/Distribution/Simple/ShowBuildInfo.hs b/Cabal/src/Distribution/Simple/ShowBuildInfo.hs index 493c972ae8a..970b2429d78 100644 --- a/Cabal/src/Distribution/Simple/ShowBuildInfo.hs +++ b/Cabal/src/Distribution/Simple/ShowBuildInfo.hs @@ -91,7 +91,7 @@ import Distribution.Verbosity -- | Construct a JSON document describing the build information for a -- package. mkBuildInfo - :: FilePath + :: AbsolutePath (Dir Pkg) -- ^ The source directory of the package -> PackageDescription -- ^ Mostly information from the .cabal file @@ -139,7 +139,7 @@ mkCompilerInfo compilerProgram compilerInfo = , "path" .= JsonString (programPath compilerProgram) ] -mkComponentInfo :: FilePath -> PackageDescription -> LocalBuildInfo -> ComponentLocalBuildInfo -> ([String], Json) +mkComponentInfo :: AbsolutePath (Dir Pkg) -> PackageDescription -> LocalBuildInfo -> ComponentLocalBuildInfo -> ([String], Json) mkComponentInfo wdir pkg_descr lbi clbi = ( warnings , JsonObject $ @@ -150,7 +150,7 @@ mkComponentInfo wdir pkg_descr lbi clbi = , "modules" .= JsonArray (map (JsonString . display) modules) , "src-files" .= JsonArray (map (JsonString . getSymbolicPath) sourceFiles) , "hs-src-dirs" .= JsonArray (map (JsonString . prettyShow) $ hsSourceDirs bi) - , "src-dir" .= JsonString (addTrailingPathSeparator wdir) + , "src-dir" .= JsonString (addTrailingPathSeparator (getAbsolutePath wdir)) ] <> cabalFile ) From 70e41962063e4635c01ab66d361232efee7759a5 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Tue, 13 Aug 2024 11:08:34 +0100 Subject: [PATCH 106/207] Interpret register script file name relative to working-dir --- Cabal/src/Distribution/Simple/Register.hs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Cabal/src/Distribution/Simple/Register.hs b/Cabal/src/Distribution/Simple/Register.hs index 46459b8103f..90704e68269 100644 --- a/Cabal/src/Distribution/Simple/Register.hs +++ b/Cabal/src/Distribution/Simple/Register.hs @@ -466,14 +466,15 @@ writeHcPkgRegisterScript verbosity mbWorkDir ipis packageDbs hpi = do -- TODO: Do something more robust here regScript = unlines scripts - info verbosity ("Creating package registration script: " ++ regScriptFileName) - writeUTF8File regScriptFileName regScript - setFileExecutable regScriptFileName + let out_file = interpretSymbolicPath mbWorkDir regScriptFileName + info verbosity ("Creating package registration script: " ++ out_file) + writeUTF8File out_file regScript + setFileExecutable out_file -regScriptFileName :: FilePath +regScriptFileName :: SymbolicPath Pkg File regScriptFileName = case buildOS of - Windows -> "register.bat" - _ -> "register.sh" + Windows -> makeSymbolicPath "register.bat" + _ -> makeSymbolicPath "register.sh" -- ----------------------------------------------------------------------------- -- Making the InstalledPackageInfo From 5159042a9d48403b0eeebc72ede4f6b7fb7c0363 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Mon, 19 Aug 2024 10:04:43 +0100 Subject: [PATCH 107/207] Remove last uses of runDbProgram runDbProgram doesn't take into account the working directory (so will normally produce incorrect results when used in `Cabal`). This replaces the last uses which weren't found by testing, they were found by grepping. --- Cabal/src/Distribution/Simple/GHCJS.hs | 2 +- Cabal/src/Distribution/Simple/HaskellSuite.hs | 19 +++++++++--------- Cabal/src/Distribution/Simple/PreProcess.hs | 6 ++++-- Cabal/src/Distribution/Simple/UHC.hs | 20 +++++++++---------- 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/Cabal/src/Distribution/Simple/GHCJS.hs b/Cabal/src/Distribution/Simple/GHCJS.hs index 07ba9d660b1..748855a6bbd 100644 --- a/Cabal/src/Distribution/Simple/GHCJS.hs +++ b/Cabal/src/Distribution/Simple/GHCJS.hs @@ -1850,7 +1850,7 @@ installExe exeFileName = exeName' fixedExeBaseName = progprefix ++ exeName' ++ progsuffix installBinary dest = do - runDbProgram verbosity ghcjsProgram (withPrograms lbi) $ + runDbProgramCwd verbosity (mbWorkDirLBI lbi) ghcjsProgram (withPrograms lbi) $ [ "--install-executable" , buildPref exeName' exeFileName , "-o" diff --git a/Cabal/src/Distribution/Simple/HaskellSuite.hs b/Cabal/src/Distribution/Simple/HaskellSuite.hs index a61dfb8228e..0e66e17e3d7 100644 --- a/Cabal/src/Distribution/Simple/HaskellSuite.hs +++ b/Cabal/src/Distribution/Simple/HaskellSuite.hs @@ -181,23 +181,23 @@ buildLib verbosity pkg_descr lbi lib clbi = do let odir = buildDir lbi bi = libBuildInfo lib - srcDirs = map i (hsSourceDirs bi) ++ [i odir] + srcDirs = map u (hsSourceDirs bi) ++ [u odir] dbStack = withPackageDB lbi language = fromMaybe Haskell98 (defaultLanguage bi) progdb = withPrograms lbi pkgid = packageId pkg_descr - i = interpretSymbolicPathLBI lbi -- See Note [Symbolic paths] in Distribution.Utils.Path - runDbProgram verbosity haskellSuiteProgram progdb $ - ["compile", "--build-dir", i odir] + u = interpretSymbolicPathCWD -- See Note [Symbolic paths] in Distribution.Utils.Path + runDbProgramCwd verbosity (mbWorkDirLBI lbi) haskellSuiteProgram progdb $ + ["compile", "--build-dir", u odir] ++ concat [["-i", d] | d <- srcDirs] ++ concat [ ["-I", d] | d <- - [ i $ autogenComponentModulesDir lbi clbi - , i $ autogenPackageModulesDir lbi - , i odir + [ u $ autogenComponentModulesDir lbi clbi + , u $ autogenPackageModulesDir lbi + , u odir ] - ++ map i (includeDirs bi) + ++ map u (includeDirs bi) ] ++ [packageDbOpt pkgDb | pkgDb <- dbStack] ++ ["--package-name", prettyShow pkgid] @@ -225,7 +225,8 @@ installLib -> IO () installLib verbosity lbi targetDir dynlibTargetDir builtDir pkg lib clbi = do let progdb = withPrograms lbi - runDbProgram verbosity haskellSuitePkgProgram progdb $ + wdir = mbWorkDirLBI lbi + runDbProgramCwd verbosity wdir haskellSuitePkgProgram progdb $ [ "install-library" , "--build-dir" , builtDir diff --git a/Cabal/src/Distribution/Simple/PreProcess.hs b/Cabal/src/Distribution/Simple/PreProcess.hs index d407ccbe2ec..61dd8163733 100644 --- a/Cabal/src/Distribution/Simple/PreProcess.hs +++ b/Cabal/src/Distribution/Simple/PreProcess.hs @@ -390,8 +390,9 @@ ppGreenCard _ lbi _ = { platformIndependent = False , ppOrdering = unsorted , runPreProcessor = mkSimplePreProcessor $ \inFile outFile verbosity -> - runDbProgram + runDbProgramCwd verbosity + (mbWorkDirLBI lbi) greencardProgram (withPrograms lbi) (["-tffi", "-o" ++ outFile, inFile]) @@ -863,8 +864,9 @@ standardPP lbi prog args = { platformIndependent = False , ppOrdering = unsorted , runPreProcessor = mkSimplePreProcessor $ \inFile outFile verbosity -> - runDbProgram + runDbProgramCwd verbosity + (mbWorkDirLBI lbi) prog (withPrograms lbi) (args ++ ["-o", outFile, inFile]) diff --git a/Cabal/src/Distribution/Simple/UHC.hs b/Cabal/src/Distribution/Simple/UHC.hs index 1fde3e35365..aa41388c6d0 100644 --- a/Cabal/src/Distribution/Simple/UHC.hs +++ b/Cabal/src/Distribution/Simple/UHC.hs @@ -251,8 +251,8 @@ buildExe verbosity _pkg_descr lbi exe clbi = do userPkgDir <- getUserPackageDir let mbWorkDir = mbWorkDirLBI lbi srcMainPath <- findFileCwd verbosity mbWorkDir (hsSourceDirs $ buildInfo exe) (modulePath exe) - let runUhcProg = runDbProgram verbosity uhcProgram (withPrograms lbi) - i = interpretSymbolicPathLBI lbi -- See Note [Symbolic paths] in Distribution.Utils.Path + let runUhcProg = runDbProgramCwd verbosity (mbWorkDirLBI lbi) uhcProgram (withPrograms lbi) + u = interpretSymbolicPathCWD uhcArgs = -- common flags lib/exe constructUHCCmdLine @@ -264,9 +264,9 @@ buildExe verbosity _pkg_descr lbi exe clbi = do (buildDir lbi) verbosity -- output file - ++ ["--output", i $ buildDir lbi makeRelativePathEx (prettyShow (exeName exe))] + ++ ["--output", u $ buildDir lbi makeRelativePathEx (prettyShow (exeName exe))] -- main source module - ++ [i $ srcMainPath] + ++ [u $ srcMainPath] runUhcProg uhcArgs constructUHCCmdLine @@ -297,14 +297,14 @@ constructUHCCmdLine user system lbi bi clbi odir verbosity = ++ ["--package=uhcbase"] ++ ["--package=" ++ prettyShow (mungedName pkgid) | (_, pkgid) <- componentPackageDeps clbi] -- search paths - ++ ["-i" ++ i odir] - ++ ["-i" ++ i l | l <- nub (hsSourceDirs bi)] - ++ ["-i" ++ i (autogenComponentModulesDir lbi clbi)] - ++ ["-i" ++ i (autogenPackageModulesDir lbi)] + ++ ["-i" ++ u odir] + ++ ["-i" ++ u l | l <- nub (hsSourceDirs bi)] + ++ ["-i" ++ u (autogenComponentModulesDir lbi clbi)] + ++ ["-i" ++ u (autogenPackageModulesDir lbi)] -- cpp options ++ ["--optP=" ++ opt | opt <- cppOptions bi] -- output path - ++ ["--odir=" ++ i odir] + ++ ["--odir=" ++ u odir] -- optimization ++ ( case withOptimization lbi of NoOptimisation -> ["-O0"] @@ -312,7 +312,7 @@ constructUHCCmdLine user system lbi bi clbi odir verbosity = MaximumOptimisation -> ["-O2"] ) where - i = interpretSymbolicPathCWD -- See Note [Symbolic paths] in Distribution.Utils.Path + u = interpretSymbolicPathCWD -- See Note [Symbolic paths] in Distribution.Utils.Path uhcPackageDbOptions :: FilePath -> FilePath -> PackageDBStack -> [String] uhcPackageDbOptions user system db = From b77e03123912f50b3a290002918b58bfd00ec503 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Thu, 8 Aug 2024 16:42:02 +0100 Subject: [PATCH 108/207] Test --working-dir in the testsuite When testing `./Setup` only, when `withDirectory` is used, instead of changing into that directory when invoking processes, we now use the `--working-dir` flag and keep a fixed CWD. This will therefore passively test that `--working-dir` is working In addition, it makes it possible to test things easily such as `--working-dir` with a relative path as an argument. `cabal-install` will only invoke `--working-dir` with an absolute path and hence is isolated from any double interpretation issues. Testing against these double interpretation issues is very important as it also prevents over-interpretation of relative paths into absolute paths. Passing absolute paths to tools such as hsc2hs can lead to the build directory leaking into an interface file which leads to non-reproducible results. --- .../Includes2/setup-external.cabal.out | 12 +++--- .../Backpack/Includes2/setup-external.out | 12 +++--- .../Includes2/setup-per-component.out | 12 +++--- .../Includes3/setup-external-explicit.out | 4 +- .../Includes3/setup-external-ok.cabal.out | 14 ++++--- .../Backpack/Includes3/setup-external-ok.out | 14 ++++--- .../Backpack/Reexport1/setup.cabal.out | 4 +- .../PackageTests/Backpack/Reexport1/setup.out | 4 +- .../TestNameCollision/setup.cabal.out | 2 +- .../PackageTests/TestNameCollision/setup.out | 2 +- cabal-testsuite/Setup.hs | 10 ++++- cabal-testsuite/src/Test/Cabal/Prelude.hs | 39 ++++++++++++------- 12 files changed, 77 insertions(+), 52 deletions(-) diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.cabal.out b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.cabal.out index 0448dac63ff..127f860bd87 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.cabal.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.cabal.out @@ -8,7 +8,7 @@ for mylib-0.1.0.0... Preprocessing library for mylib-0.1.0.0... Running Haddock on library instantiated with Database = for mylib-0.1.0.0... -Documentation created: ../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib +Documentation created: ./mylib/../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib # Setup copy Installing library in # Setup register @@ -22,7 +22,7 @@ Building library for mysql-0.1.0.0... # Setup haddock Preprocessing library for mysql-0.1.0.0... Running Haddock on library for mysql-0.1.0.0... -Documentation created: ../setup-external.cabal.dist/work/mysql/dist/doc/html/mysql +Documentation created: ./mysql/../setup-external.cabal.dist/work/mysql/dist/doc/html/mysql # Setup copy Installing library in # Setup register @@ -35,7 +35,7 @@ Building library for postgresql-0.1.0.0... # Setup haddock Preprocessing library for postgresql-0.1.0.0... Running Haddock on library for postgresql-0.1.0.0... -Documentation created: ../setup-external.cabal.dist/work/postgresql/dist/doc/html/postgresql +Documentation created: ./postgresql/../setup-external.cabal.dist/work/postgresql/dist/doc/html/postgresql # Setup copy Installing library in # Setup register @@ -51,7 +51,7 @@ Preprocessing library for mylib-0.1.0.0... Running Haddock on library instantiated with Database = mysql-0.1.0.0:Database.MySQL for mylib-0.1.0.0... -Documentation created: ../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib +Documentation created: ./mylib/../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib # Setup copy Installing library in # Setup register @@ -69,7 +69,7 @@ Preprocessing library for mylib-0.1.0.0... Running Haddock on library instantiated with Database = postgresql-0.1.0.0:Database.PostgreSQL for mylib-0.1.0.0... -Documentation created: ../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib +Documentation created: ./mylib/../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib # Setup copy Installing library in # Setup register @@ -84,7 +84,7 @@ Building library for src-0.1.0.0... # Setup haddock Preprocessing library for src-0.1.0.0... Running Haddock on library for src-0.1.0.0... -Documentation created: ../setup-external.cabal.dist/work/src/dist/doc/html/src +Documentation created: ./src/../setup-external.cabal.dist/work/src/dist/doc/html/src # Setup copy Installing library in # Setup register diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.out b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.out index 19a089db14f..f363c456afd 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.out @@ -8,7 +8,7 @@ for mylib-0.1.0.0... Preprocessing library for mylib-0.1.0.0... Running Haddock on library instantiated with Database = for mylib-0.1.0.0... -Documentation created: ../setup-external.dist/work/mylib/dist/doc/html/mylib +Documentation created: ./mylib/../setup-external.dist/work/mylib/dist/doc/html/mylib # Setup copy Installing library in # Setup register @@ -22,7 +22,7 @@ Building library for mysql-0.1.0.0... # Setup haddock Preprocessing library for mysql-0.1.0.0... Running Haddock on library for mysql-0.1.0.0... -Documentation created: ../setup-external.dist/work/mysql/dist/doc/html/mysql +Documentation created: ./mysql/../setup-external.dist/work/mysql/dist/doc/html/mysql # Setup copy Installing library in # Setup register @@ -35,7 +35,7 @@ Building library for postgresql-0.1.0.0... # Setup haddock Preprocessing library for postgresql-0.1.0.0... Running Haddock on library for postgresql-0.1.0.0... -Documentation created: ../setup-external.dist/work/postgresql/dist/doc/html/postgresql +Documentation created: ./postgresql/../setup-external.dist/work/postgresql/dist/doc/html/postgresql # Setup copy Installing library in # Setup register @@ -51,7 +51,7 @@ Preprocessing library for mylib-0.1.0.0... Running Haddock on library instantiated with Database = mysql-0.1.0.0:Database.MySQL for mylib-0.1.0.0... -Documentation created: ../setup-external.dist/work/mylib/dist/doc/html/mylib +Documentation created: ./mylib/../setup-external.dist/work/mylib/dist/doc/html/mylib # Setup copy Installing library in # Setup register @@ -69,7 +69,7 @@ Preprocessing library for mylib-0.1.0.0... Running Haddock on library instantiated with Database = postgresql-0.1.0.0:Database.PostgreSQL for mylib-0.1.0.0... -Documentation created: ../setup-external.dist/work/mylib/dist/doc/html/mylib +Documentation created: ./mylib/../setup-external.dist/work/mylib/dist/doc/html/mylib # Setup copy Installing library in # Setup register @@ -84,7 +84,7 @@ Building library for src-0.1.0.0... # Setup haddock Preprocessing library for src-0.1.0.0... Running Haddock on library for src-0.1.0.0... -Documentation created: ../setup-external.dist/work/src/dist/doc/html/src +Documentation created: ./src/../setup-external.dist/work/src/dist/doc/html/src # Setup copy Installing library in # Setup register diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out index 5fff9a72819..3eaa739df55 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out @@ -8,7 +8,7 @@ for I-0.1.0.0... Preprocessing library 'mylib' for I-0.1.0.0... Running Haddock on library 'mylib' instantiated with Database = for I-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/I/mylib +Documentation created: ./Includes2/../setup-per-component.dist/work/Includes2/dist/doc/html/I/mylib # Setup copy Installing internal library mylib in # Setup register @@ -22,7 +22,7 @@ Building library 'mysql' for I-0.1.0.0... # Setup haddock Preprocessing library 'mysql' for I-0.1.0.0... Running Haddock on library 'mysql' for I-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/I/mysql +Documentation created: ./Includes2/../setup-per-component.dist/work/Includes2/dist/doc/html/I/mysql # Setup copy Installing internal library mysql in # Setup register @@ -35,7 +35,7 @@ Building library 'postgresql' for I-0.1.0.0... # Setup haddock Preprocessing library 'postgresql' for I-0.1.0.0... Running Haddock on library 'postgresql' for I-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/I/postgresql +Documentation created: ./Includes2/../setup-per-component.dist/work/Includes2/dist/doc/html/I/postgresql # Setup copy Installing internal library postgresql in # Setup register @@ -54,7 +54,7 @@ Preprocessing library 'mylib' for I-0.1.0.0... Running Haddock on library 'mylib' instantiated with Database = mysql-0.1.0.0:Database.MySQL for I-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/I/mylib +Documentation created: ./Includes2/../setup-per-component.dist/work/Includes2/dist/doc/html/I/mylib # Setup copy Installing internal library mylib in # Setup register @@ -75,7 +75,7 @@ Preprocessing library 'mylib' for I-0.1.0.0... Running Haddock on library 'mylib' instantiated with Database = postgresql-0.1.0.0:Database.PostgreSQL for I-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/I/mylib +Documentation created: ./Includes2/../setup-per-component.dist/work/Includes2/dist/doc/html/I/mylib # Setup copy Installing internal library mylib in # Setup register @@ -90,7 +90,7 @@ Building library for I-0.1.0.0... # Setup haddock Preprocessing library for I-0.1.0.0... Running Haddock on library for I-0.1.0.0... -Documentation created: ../setup-per-component.dist/work/Includes2/dist/doc/html/I +Documentation created: ./Includes2/../setup-per-component.dist/work/Includes2/dist/doc/html/I # Setup copy Installing library in # Setup register diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-explicit.out b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-explicit.out index 72bf091632d..3697155460a 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-explicit.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-explicit.out @@ -8,7 +8,7 @@ for sigs-0.1.0.0... Preprocessing library for sigs-0.1.0.0... Running Haddock on library instantiated with Data.Map = for sigs-0.1.0.0... -Documentation created: ../../setup-external-explicit.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs +Documentation created: ./repo/sigs-0.1.0.0/../../setup-external-explicit.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs # Setup copy Installing library in # Setup register @@ -24,7 +24,7 @@ for indef-0.1.0.0... Preprocessing library for indef-0.1.0.0... Running Haddock on library instantiated with Data.Map = for indef-0.1.0.0... -Documentation created: ../../setup-external-explicit.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef +Documentation created: ./repo/indef-0.1.0.0/../../setup-external-explicit.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef # Setup copy Installing library in # Setup register diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.cabal.out b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.cabal.out index 34e7a1204b5..e57a01ca56e 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.cabal.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.cabal.out @@ -8,7 +8,7 @@ for sigs-0.1.0.0... Preprocessing library for sigs-0.1.0.0... Running Haddock on library instantiated with Data.Map = for sigs-0.1.0.0... -Documentation created: ../../setup-external-ok.cabal.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs +Documentation created: ./repo/sigs-0.1.0.0/../../setup-external-ok.cabal.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs # Setup copy Installing library in # Setup register @@ -24,7 +24,7 @@ for indef-0.1.0.0... Preprocessing library for indef-0.1.0.0... Running Haddock on library instantiated with Data.Map = for indef-0.1.0.0... -Documentation created: ../../setup-external-ok.cabal.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef +Documentation created: ./repo/indef-0.1.0.0/../../setup-external-ok.cabal.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef # Setup copy Installing library in # Setup register @@ -41,11 +41,12 @@ Preprocessing library for sigs-0.1.0.0... Running Haddock on library instantiated with Data.Map = containers-:Data.Map for sigs-0.1.0.0... -Documentation created: ../../setup-external-ok.cabal.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs +Documentation created: ./repo/sigs-0.1.0.0/../../setup-external-ok.cabal.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs # Setup copy Installing library in # Setup register -Registering library instantiated with Data.Map = containers-:Data.Map +Registering library instantiated with + Data.Map = containers-:Data.Map for sigs-0.1.0.0... # Setup configure Configuring indef-0.1.0.0... @@ -58,11 +59,12 @@ Preprocessing library for indef-0.1.0.0... Running Haddock on library instantiated with Data.Map = containers-:Data.Map for indef-0.1.0.0... -Documentation created: ../../setup-external-ok.cabal.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef +Documentation created: ./repo/indef-0.1.0.0/../../setup-external-ok.cabal.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef # Setup copy Installing library in # Setup register -Registering library instantiated with Data.Map = containers-:Data.Map +Registering library instantiated with + Data.Map = containers-:Data.Map for indef-0.1.0.0... # Setup configure Configuring exe-0.1.0.0... diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.out b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.out index 630edbba1a2..2d4e65cb2cd 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.out +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.out @@ -8,7 +8,7 @@ for sigs-0.1.0.0... Preprocessing library for sigs-0.1.0.0... Running Haddock on library instantiated with Data.Map = for sigs-0.1.0.0... -Documentation created: ../../setup-external-ok.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs +Documentation created: ./repo/sigs-0.1.0.0/../../setup-external-ok.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs # Setup copy Installing library in # Setup register @@ -24,7 +24,7 @@ for indef-0.1.0.0... Preprocessing library for indef-0.1.0.0... Running Haddock on library instantiated with Data.Map = for indef-0.1.0.0... -Documentation created: ../../setup-external-ok.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef +Documentation created: ./repo/indef-0.1.0.0/../../setup-external-ok.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef # Setup copy Installing library in # Setup register @@ -41,11 +41,12 @@ Preprocessing library for sigs-0.1.0.0... Running Haddock on library instantiated with Data.Map = containers-:Data.Map for sigs-0.1.0.0... -Documentation created: ../../setup-external-ok.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs +Documentation created: ./repo/sigs-0.1.0.0/../../setup-external-ok.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs # Setup copy Installing library in # Setup register -Registering library instantiated with Data.Map = containers-:Data.Map +Registering library instantiated with + Data.Map = containers-:Data.Map for sigs-0.1.0.0... # Setup configure Configuring indef-0.1.0.0... @@ -58,11 +59,12 @@ Preprocessing library for indef-0.1.0.0... Running Haddock on library instantiated with Data.Map = containers-:Data.Map for indef-0.1.0.0... -Documentation created: ../../setup-external-ok.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef +Documentation created: ./repo/indef-0.1.0.0/../../setup-external-ok.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef # Setup copy Installing library in # Setup register -Registering library instantiated with Data.Map = containers-:Data.Map +Registering library instantiated with + Data.Map = containers-:Data.Map for indef-0.1.0.0... # Setup configure Configuring exe-0.1.0.0... diff --git a/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.cabal.out b/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.cabal.out index 6cdb5760236..d36358ef31e 100644 --- a/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.cabal.out +++ b/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.cabal.out @@ -6,7 +6,7 @@ Building library for p-0.1.0.0... # Setup haddock Preprocessing library for p-0.1.0.0... Running Haddock on library for p-0.1.0.0... -Documentation created: ../setup.cabal.dist/work/p/dist/doc/html/p +Documentation created: ./p/../setup.cabal.dist/work/p/dist/doc/html/p # Setup copy Installing library in # Setup register @@ -19,4 +19,4 @@ Building library for q-0.1.0.0... # Setup haddock Preprocessing library for q-0.1.0.0... Running Haddock on library for q-0.1.0.0... -Documentation created: ../setup.cabal.dist/work/q/dist/doc/html/q +Documentation created: ./q/../setup.cabal.dist/work/q/dist/doc/html/q diff --git a/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.out b/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.out index ba66136d02a..78312c7bcbb 100644 --- a/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.out +++ b/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.out @@ -6,7 +6,7 @@ Building library for p-0.1.0.0... # Setup haddock Preprocessing library for p-0.1.0.0... Running Haddock on library for p-0.1.0.0... -Documentation created: ../setup.dist/work/p/dist/doc/html/p +Documentation created: ./p/../setup.dist/work/p/dist/doc/html/p # Setup copy Installing library in # Setup register @@ -19,4 +19,4 @@ Building library for q-0.1.0.0... # Setup haddock Preprocessing library for q-0.1.0.0... Running Haddock on library for q-0.1.0.0... -Documentation created: ../setup.dist/work/q/dist/doc/html/q +Documentation created: ./q/../setup.dist/work/q/dist/doc/html/q diff --git a/cabal-testsuite/PackageTests/TestNameCollision/setup.cabal.out b/cabal-testsuite/PackageTests/TestNameCollision/setup.cabal.out index a86a3788e72..9e42bccb4fb 100644 --- a/cabal-testsuite/PackageTests/TestNameCollision/setup.cabal.out +++ b/cabal-testsuite/PackageTests/TestNameCollision/setup.cabal.out @@ -18,5 +18,5 @@ Building test suite 'parent' for child-0.1... Running 1 test suites... Test suite parent: RUNNING... Test suite parent: PASS -Test suite logged to: ../setup.cabal.dist/work/child/dist/test/child-0.1-parent.log +Test suite logged to: ./child/../setup.cabal.dist/work/child/dist/test/child-0.1-parent.log 1 of 1 test suites (1 of 1 test cases) passed. diff --git a/cabal-testsuite/PackageTests/TestNameCollision/setup.out b/cabal-testsuite/PackageTests/TestNameCollision/setup.out index c76a83141c1..70dfb63e581 100644 --- a/cabal-testsuite/PackageTests/TestNameCollision/setup.out +++ b/cabal-testsuite/PackageTests/TestNameCollision/setup.out @@ -18,5 +18,5 @@ Building test suite 'parent' for child-0.1... Running 1 test suites... Test suite parent: RUNNING... Test suite parent: PASS -Test suite logged to: ../setup.dist/work/child/dist/test/child-0.1-parent.log +Test suite logged to: ./child/../setup.dist/work/child/dist/test/child-0.1-parent.log 1 of 1 test suites (1 of 1 test cases) passed. diff --git a/cabal-testsuite/Setup.hs b/cabal-testsuite/Setup.hs index b5744198abc..3a4a335b86e 100644 --- a/cabal-testsuite/Setup.hs +++ b/cabal-testsuite/Setup.hs @@ -30,7 +30,10 @@ generateScriptEnvModule lbi verbosity = do createDirectoryIfMissing True moduledir rewriteFileEx verbosity (moduledir "ScriptEnv0.hs") $ unlines - [ "module Test.Cabal.ScriptEnv0 where" + [ "{-# LANGUAGE OverloadedStrings #-}" + , "{-# LANGUAGE FlexibleInstances #-}" + , "{-# OPTIONS_GHC -Wno-orphans #-}" + , "module Test.Cabal.ScriptEnv0 where" , "" , "import Distribution.Simple" , "import Distribution.System (Platform(..), Arch(..), OS(..))" @@ -38,6 +41,8 @@ generateScriptEnvModule lbi verbosity = do , "import Distribution.Simple.Program.Db" , "import Distribution.Backpack (OpenUnitId)" , "import Data.Map (fromList)" + , "import Data.String (IsString(..))" + , "import Distribution.Utils.Path" , "" , "lbiPackageDbStack :: PackageDBStackCWD" , "lbiPackageDbStack = " ++ show lbiPackageDbStack @@ -56,6 +61,9 @@ generateScriptEnvModule lbi verbosity = do , "" , "lbiWithSharedLib :: Bool" , "lbiWithSharedLib = " ++ show (withSharedLib lbi) + , "" + , "instance IsString (SymbolicPath from to) where" + , " fromString = makeSymbolicPath" ] where moduledir = libAutogenDir "Test" "Cabal" diff --git a/cabal-testsuite/src/Test/Cabal/Prelude.hs b/cabal-testsuite/src/Test/Cabal/Prelude.hs index 64c12b0f04d..7fa82cf8143 100644 --- a/cabal-testsuite/src/Test/Cabal/Prelude.hs +++ b/cabal-testsuite/src/Test/Cabal/Prelude.hs @@ -43,7 +43,7 @@ import Distribution.PackageDescription import Test.Utils.TempTestDir (withTestDir) import Distribution.Verbosity (normal) import Distribution.Utils.Path - ( makeSymbolicPath, relativeSymbolicPath ) + ( makeSymbolicPath, relativeSymbolicPath, interpretSymbolicPathCWD ) import Distribution.Compat.Stack @@ -59,8 +59,6 @@ import qualified Crypto.Hash.SHA256 as SHA256 import qualified Data.ByteString.Base16 as Base16 import qualified Data.ByteString.Char8 as C import Data.List (isInfixOf, stripPrefix, isPrefixOf, intercalate) -import Data.List.NonEmpty (NonEmpty (..)) -import qualified Data.List.NonEmpty as NE import Data.Maybe (mapMaybe, fromMaybe) import System.Exit (ExitCode (..)) import System.FilePath @@ -80,11 +78,17 @@ import System.Posix.Resource ------------------------------------------------------------------------ -- * Utilities + runM :: FilePath -> [String] -> Maybe String -> TestM Result runM path args input = do + env <- getTestEnv + runM' (Just $ testCurrentDir env) path args input + +runM' :: Maybe FilePath -> FilePath -> [String] -> Maybe String -> TestM Result +runM' run_dir path args input = do env <- getTestEnv r <- liftIO $ run (testVerbosity env) - (Just $ testCurrentDir env) + run_dir (testEnvironment env) path args @@ -92,12 +96,17 @@ runM path args input = do recordLog r requireSuccess r -runProgramM :: Program -> [String] -> Maybe String -> TestM Result +runProgramM :: Program -> [String] -> Maybe String -> TestM Result runProgramM prog args input = do + env <- getTestEnv + runProgramM' (Just $ testCurrentDir env) prog args input + +runProgramM' :: Maybe FilePath -> Program -> [String] -> Maybe String -> TestM Result +runProgramM' run_dir prog args input = do configured_prog <- requireProgramM prog -- TODO: Consider also using other information from -- ConfiguredProgram, e.g., env and args - runM (programPath configured_prog) args input + runM' run_dir (programPath configured_prog) args input getLocalBuildInfoM :: TestM LocalBuildInfo getLocalBuildInfoM = do @@ -156,6 +165,7 @@ setup'' -> TestM Result setup'' prefix cmd args = do env <- getTestEnv + let work_dir = if testRelativeCurrentDir env == "." then Nothing else Just (testRelativeCurrentDir env) when ((cmd == "register" || cmd == "copy") && not (testHavePackageDb env)) $ error "Cannot register/copy without using 'withPackageDb'" ghc_path <- programPathM ghcProgram @@ -184,7 +194,10 @@ setup'' prefix cmd args = do ++ args _ -> args let rel_dist_dir = definitelyMakeRelative (testCurrentDir env) (testDistDir env) - full_args = cmd :| [marked_verbose, "--distdir", rel_dist_dir] ++ args' + work_dir_arg = case work_dir of + Nothing -> [] + Just wd -> ["--working-dir", wd] + full_args = work_dir_arg ++ (cmd : [marked_verbose, "--distdir", rel_dist_dir] ++ args') defaultRecordMode RecordMarked $ do recordHeader ["Setup", cmd] @@ -192,23 +205,23 @@ setup'' prefix cmd args = do -- -- `cabal` and `Setup.hs` do have different interface. -- - let pkgDir = makeSymbolicPath $ testCurrentDir env prefix + let pkgDir = makeSymbolicPath $ testTmpDir env testRelativeCurrentDir env prefix pdfile <- liftIO $ tryFindPackageDesc (testVerbosity env) (Just pkgDir) pdesc <- liftIO $ readGenericPackageDescription (testVerbosity env) (Just pkgDir) $ relativeSymbolicPath pdfile if testCabalInstallAsSetup env then if buildType (packageDescription pdesc) == Simple - then runProgramM cabalProgram ("act-as-setup" : "--" : NE.toList full_args) Nothing + then runProgramM' (Just (testTmpDir env)) cabalProgram ("act-as-setup" : "--" : full_args) Nothing else fail "Using act-as-setup for not 'build-type: Simple' package" else do if buildType (packageDescription pdesc) == Simple - then runM (testSetupPath env) (NE.toList full_args) Nothing + then runM' (Just $ testTmpDir env) (testSetupPath env) (full_args) Nothing -- Run the Custom script! else do r <- liftIO $ runghc (testScriptEnv env) - (Just $ testCurrentDir env) + (Just $ testTmpDir env) (testEnvironment env) - (testCurrentDir env prefix "Setup.hs") - (NE.toList full_args) + (testRelativeCurrentDir env prefix "Setup.hs") + (full_args) recordLog r requireSuccess r From fe031d1d5c1feaabe42adfbdd803c6ad158f81f3 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Thu, 8 Aug 2024 14:59:26 +0100 Subject: [PATCH 109/207] Add test for --working-dir and hsc2s Before the previous patches this test failed because an incorrect path was passed to hsc2hs (a preprocessor), it now succeeds :) --- .../WorkingDirRel/WD_NO_MENTION/CHANGELOG.md | 5 +++++ .../WorkingDirRel/WD_NO_MENTION/app/Main.hsc | 3 +++ .../WorkingDirRel/WD_NO_MENTION/n.cabal | 19 +++++++++++++++++++ .../PackageTests/WorkingDirRel/setup.test.hs | 4 ++++ 4 files changed, 31 insertions(+) create mode 100644 cabal-testsuite/PackageTests/WorkingDirRel/WD_NO_MENTION/CHANGELOG.md create mode 100644 cabal-testsuite/PackageTests/WorkingDirRel/WD_NO_MENTION/app/Main.hsc create mode 100644 cabal-testsuite/PackageTests/WorkingDirRel/WD_NO_MENTION/n.cabal create mode 100644 cabal-testsuite/PackageTests/WorkingDirRel/setup.test.hs diff --git a/cabal-testsuite/PackageTests/WorkingDirRel/WD_NO_MENTION/CHANGELOG.md b/cabal-testsuite/PackageTests/WorkingDirRel/WD_NO_MENTION/CHANGELOG.md new file mode 100644 index 00000000000..2959e9a055b --- /dev/null +++ b/cabal-testsuite/PackageTests/WorkingDirRel/WD_NO_MENTION/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for n + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/cabal-testsuite/PackageTests/WorkingDirRel/WD_NO_MENTION/app/Main.hsc b/cabal-testsuite/PackageTests/WorkingDirRel/WD_NO_MENTION/app/Main.hsc new file mode 100644 index 00000000000..918e213f57b --- /dev/null +++ b/cabal-testsuite/PackageTests/WorkingDirRel/WD_NO_MENTION/app/Main.hsc @@ -0,0 +1,3 @@ +module Main where + +main = print () diff --git a/cabal-testsuite/PackageTests/WorkingDirRel/WD_NO_MENTION/n.cabal b/cabal-testsuite/PackageTests/WorkingDirRel/WD_NO_MENTION/n.cabal new file mode 100644 index 00000000000..83acab380b3 --- /dev/null +++ b/cabal-testsuite/PackageTests/WorkingDirRel/WD_NO_MENTION/n.cabal @@ -0,0 +1,19 @@ +cabal-version: 3.0 +name: n +version: 0.1.0.0 +license: NONE +author: Matthew Pickering +maintainer: matthewtpickering@gmail.com +build-type: Simple +extra-doc-files: CHANGELOG.md + +common warnings + ghc-options: -Wall + +executable n + import: warnings + main-is: Main.hs + build-depends: base + hs-source-dirs: app + build-tool-depends: hsc2hs:hsc2hs + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/WorkingDirRel/setup.test.hs b/cabal-testsuite/PackageTests/WorkingDirRel/setup.test.hs new file mode 100644 index 00000000000..01fbfb9795c --- /dev/null +++ b/cabal-testsuite/PackageTests/WorkingDirRel/setup.test.hs @@ -0,0 +1,4 @@ +import Test.Cabal.Prelude + +main = setupTest $ recordMode DoNotRecord $ do + withDirectory "WD_NO_MENTION" $ setup_build [] From 6ddd7e6df1d95b755de893709dfd91e395fa57f8 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Mon, 19 Aug 2024 22:43:55 -0400 Subject: [PATCH 110/207] make sure cabal-install is compatible with Cabal See https://github.com/haskell/cabal/issues/9833 If a ghc ships with a compatible Cabal, it will be preferred by the solver on `cabal install cabal-install`; the new `cabal-install` should in fact be compatible. So we test this on release branches that have had at least one release on Hackage. (Ideally we'd check ghc instead, but we can't do that from GHA. Even checking Hackage is pretty painful.) --- .github/workflows/check-sdist.yml | 82 +++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 .github/workflows/check-sdist.yml diff --git a/.github/workflows/check-sdist.yml b/.github/workflows/check-sdist.yml new file mode 100644 index 00000000000..d295ad0ccca --- /dev/null +++ b/.github/workflows/check-sdist.yml @@ -0,0 +1,82 @@ +name: Check sdist + +# See: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#concurrency. +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +on: + push: + paths-ignore: + - "doc/**" + - "**/README.md" + - "CONTRIBUTING.md" + branches: + - master + pull_request: + paths-ignore: + - "doc/**" + - "**/README.md" + - "CONTRIBUTING.md" + release: + types: + - created + +jobs: + + # Dogfood the generated sdist, to avoid bugs like https://github.com/haskell/cabal/issues/9833 + # No caching, since the point is to verify they can be installed "from scratch" + # Don't run on master or a PR targeting master, because there's never an installable Cabal + dogfood-sdists: + name: Dogfood sdist on ${{ matrix.os }} ghc-${{ matrix.ghc }} + if: github.ref != 'refs/heads/master' && github.base_ref != 'master' + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + # this should be kept up to date with the list in validate.yml, but should be the + # *first* compiler release so we validate against what is hopefully the first + # release of a corresponding Cabal and friends. it can also be short since it's + # highly unlikely that we are releasing really old branches. + ghc: + [ + "9.10.1", + "9.8.1", + "9.6.1", + "9.4.1", + ] + + steps: + + - uses: haskell-actions/setup@v2 + id: setup-haskell + with: + ghc-version: ${{ matrix.ghc }} + cabal-version: latest + + - uses: actions/checkout@v4 + + - name: Make sdist + run: cabal sdist cabal-install + + - name: Install from sdist + run: | + # skip if a suitable Cabal isn't in this ghc's bootlibs, since that's the case + # that causes failures for users (otherwise cabal-install will install a matching + # version itself) + # we only want to test cabal-install, to ensure that it works with existing Cabals + # (don't look at this too closely) + sdist="$(ls dist-newstyle/sdist/cabal-install-*.tar.gz | sed -n '\,^dist-newstyle/sdist/cabal-install-[0-9.]*\.tar\.gz$,{;p;q;}')" + # extract the cabal-install major version + ver="$(echo "$sdist" | sed -n 's,^dist-newstyle/sdist/cabal-install-\([0-9][0-9]*\.[0-9][0-9]*\)\.[0-9.]*$,\1,p')" + # dunno if this will ever be extended to freebsd, but grep -q is a gnu-ism + if ghc-pkg --global --simple-output list Cabal | grep "^Cabal-$cbl\\." >/dev/null; then + # sigh, someone broke installing from tarballs + rm -rf cabal*.project Cabal Cabal-syntax cabal-install-solver cabal-install + tar xfz "$sdist" + cd "cabal-install-$cbl"* + cabal install + else + echo No matching bootlib Cabal version to test against. + exit 0 + fi From 72e6a06d4f1b4bec0f42e3520d5c08094b90c79a Mon Sep 17 00:00:00 2001 From: Artem Pelenitsyn Date: Thu, 29 Aug 2024 08:52:55 -0400 Subject: [PATCH 111/207] CI: validate: the matrix won't fail-fast Which means that if a Windows job fails, all other jobs in the matrix will be allowed to finish (other platforms, as well as other compilers on Windows, etc.) Inspired by the discussion at https://github.com/haskell/cabal/issues/10263 --- .github/workflows/validate.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 9ca6470d2d2..6af58f1ed7c 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -58,6 +58,7 @@ jobs: outputs: GHC_FOR_RELEASE: ${{ format('["{0}"]', env.GHC_FOR_RELEASE) }} strategy: + fail-fast: false matrix: sys: - { os: windows-latest, shell: "C:/msys64/usr/bin/bash.exe -e {0}" } From 0d694ef3158fcef26df684196f3368f9cd744864 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Wed, 28 Aug 2024 13:48:53 +0200 Subject: [PATCH 112/207] Re-enable Windows CI --- .github/workflows/validate.yml | 6 +++++- .../Backpack/Includes3/cabal-external.test.hs | 3 ++- validate.sh | 8 ++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 6af58f1ed7c..432277a9d5c 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -79,6 +79,11 @@ jobs: "8.8.4", ] exclude: + # Throws fatal "cabal-tests.exe: fd:8: hGetLine: end of file" exception + # even with --io-manager=native + - sys: + { os: windows-latest, shell: "C:/msys64/usr/bin/bash.exe -e {0}" } + ghc: "9.0.2" # corrupts GHA cache or the fabric of reality itself, see https://github.com/haskell/cabal/issues/8356 - sys: { os: windows-latest, shell: "C:/msys64/usr/bin/bash.exe -e {0}" } @@ -211,7 +216,6 @@ jobs: run: sh validate.sh $FLAGS -s cli-tests - name: Validate cli-suite - if: runner.os != 'Windows' run: sh validate.sh $FLAGS -s cli-suite - name: Validate solver-benchmarks-tests diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs index 6e6f017ee9f..45a4546819c 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs @@ -3,7 +3,8 @@ import Test.Cabal.Prelude main = cabalTest $ do ghcVer <- isGhcVersion ">= 9.10" skipUnlessGhcVersion ">= 8.1" - expectBrokenIf (isWindows && ghcVer) 10191 $ withProjectFile "cabal.external.project" $ do + skipIf "Windows + 9.10.1 (#10191)" (isWindows && ghcVer) + withProjectFile "cabal.external.project" $ do cabal "v2-build" ["exe"] withPlan $ do r <- runPlanExe' "exe" "exe" [] diff --git a/validate.sh b/validate.sh index ff1c9e139a9..8784f48b4a5 100755 --- a/validate.sh +++ b/validate.sh @@ -324,12 +324,8 @@ CABAL_TESTSUITE_BDIR="$(pwd)/$BUILDDIR/build/$ARCH/$BASEHC/cabal-testsuite-3" CABALNEWBUILD="${CABAL} build $JOBS -w $HC --builddir=$BUILDDIR --project-file=$PROJECTFILE" CABALLISTBIN="${CABAL} list-bin --builddir=$BUILDDIR --project-file=$PROJECTFILE" -# This was needed in some local Windows MSYS2 environments -# but breaks CI for Windows + GHC 9.0.2, thus it is set only on non-CI executions -# of validate.sh -# https://github.com/haskell/cabal/issues/9571 -# https://github.com/haskell/cabal/pull/10114 -RTSOPTS="$([ $ARCH = "x86_64-windows" ] && [ -z "$CI" ] && [ "$($HC --numeric-version)" != "8.10.7" ] && echo "+RTS --io-manager=native" || echo "")" +# See https://github.com/haskell/cabal/issues/9571 for why we set this for Windows +RTSOPTS="$([ $ARCH = "x86_64-windows" ] && [ "$($HC --numeric-version)" != "9.0.2" ] && [ "$(echo -e "$(ghc --numeric-version)\n9.0.2" | sort -V | head -n1)" = "9.0.2" ] && echo "+RTS --io-manager=native" || echo "")" # header ####################################################################### From 63389a0223b94b4ddd98e92d645e11bba6ba8560 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Mon, 2 Sep 2024 02:17:53 +0200 Subject: [PATCH 113/207] Various `cabal-testsuite` improvements (#10225) * Improve bat scripts for CCompilerOverride * Ensure Windows tests can cleanup the temp directory * Implement `flaky` combinator * Remove outdated tests * Remove broken tests These tests were testing for messages that were removed with the `cabal check` rework. * Make `skip` and `broken` messages uniform * Mark flaky tests * Re-enable DeterministicTrivial * Fix MacOS canonical paths * Extend cabal-testsuite readme with `flaky` * Skip non-terminating tests in Windows CI --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- Cabal-tests/lib/Test/Utils/TempTestDir.hs | 23 ++- .../Backpack/Includes2/cabal-internal.test.hs | 2 +- .../Backpack/Includes2/setup-external.test.hs | 3 +- .../Includes2/setup-per-component.test.hs | 3 +- .../Backpack/Includes3/cabal-external.test.hs | 2 +- .../Backpack/Includes3/cabal-internal.test.hs | 2 +- .../Includes3/setup-external-ok.test.hs | 4 +- .../PackageTests/Backpack/T4754/setup.test.hs | 2 +- .../PackageTests/Backpack/T6385/cabal.test.hs | 2 +- .../CCompilerOverride/custom-cc-clang.bat | 14 +- .../CCompilerOverride/custom-cc.bat | 14 +- .../PackageTests/CmmSourcesDyn/setup.test.hs | 2 +- .../PackageTests/CustomDep/cabal.project | 1 - .../PackageTests/CustomDep/cabal.test.hs | 10 -- .../PackageTests/CustomDep/client/B.hs | 2 - .../PackageTests/CustomDep/client/Setup.hs | 2 - .../CustomDep/client/client.cabal | 12 -- .../PackageTests/CustomDep/custom/A.hs | 1 - .../PackageTests/CustomDep/custom/Setup.hs | 2 - .../CustomDep/custom/custom.cabal | 15 -- cabal-testsuite/PackageTests/CustomPlain/A.hs | 1 - .../PackageTests/CustomPlain/Setup.hs | 3 - .../PackageTests/CustomPlain/cabal.project | 1 - .../PackageTests/CustomPlain/cabal.test.hs | 11 -- .../PackageTests/CustomPlain/plain.cabal | 11 -- .../PackageTests/CustomPlain/setup.cabal.out | 7 - .../PackageTests/CustomPlain/setup.out | 6 - .../PackageTests/CustomPlain/setup.test.hs | 4 - .../GHCJS/BuildRunner/cabal.test.hs | 2 +- .../GhcPkgGuess/SameDirectory/setup.test.hs | 2 +- .../SameDirectoryGhcVersion/setup.test.hs | 2 +- .../SameDirectoryVersion/setup.test.hs | 2 +- .../GhcPkgGuess/Symlink/setup.test.hs | 2 +- .../SymlinkGhcVersion/setup.test.hs | 2 +- .../GhcPkgGuess/SymlinkVersion/setup.test.hs | 2 +- .../InternalVersions/BuildDependsExtra/Foo.hs | 1 - .../BuildDependsExtra/Main.hs | 4 - .../build-depends-extra-version.cabal | 17 -- .../BuildDependsExtra/setup.cabal.out | 13 -- .../BuildDependsExtra/setup.out | 13 -- .../BuildDependsExtra/setup.test.hs | 6 - .../BuildToolDependsExtra/Foo.hs | 1 - .../BuildToolDependsExtra/Main.hs | 4 - .../build-tool-depends-extra-version.cabal | 18 -- .../BuildToolDependsExtra/setup.cabal.out | 13 -- .../BuildToolDependsExtra/setup.out | 13 -- .../BuildToolDependsExtra/setup.test.hs | 6 - .../InternalVersions/BuildToolsExtra/Foo.hs | 1 - .../InternalVersions/BuildToolsExtra/Main.hs | 4 - .../build-tools-extra-version.cabal | 18 -- .../BuildToolsExtra/setup.cabal.out | 13 -- .../BuildToolsExtra/setup.out | 13 -- .../BuildToolsExtra/setup.test.hs | 6 - .../PackageTests/NewBuild/T4375/A.hs | 1 - .../PackageTests/NewBuild/T4375/Setup.hs | 2 - .../PackageTests/NewBuild/T4375/a.cabal | 11 -- .../PackageTests/NewBuild/T4375/cabal.out | 7 - .../PackageTests/NewBuild/T4375/cabal.project | 1 - .../PackageTests/NewBuild/T4375/cabal.test.hs | 13 -- .../repo/old-locale-1.0.0.7/System/Locale.hs | 1 - .../repo/old-locale-1.0.0.7/old-locale.cabal | 9 - .../repo/old-time-1.1.0.3/System/Time.hs | 2 - .../repo/old-time-1.1.0.3/old-time.cabal | 9 - .../deterministic.test.hs | 1 - .../RejectFutureIndexStates/cabal.test.hs | 12 +- .../update-index-state.test.hs | 12 +- .../PackageTests/PkgConfigParse/setup.test.hs | 2 +- .../Regression/T4025/setup.test.hs | 8 +- .../Regression/T4270/setup.test.hs | 3 +- .../Regression/T5309/cabal.test.hs | 6 +- .../Regression/T6906/cabal.test.hs | 3 +- .../ExeV10/cabal-with-hpc.multitest.hs | 7 +- .../clean-install-by-copy.test.hs | 10 +- .../clean-install-by-symlink.test.hs | 10 +- .../WarnEarlyOverwrite/dirty-install.test.hs | 18 +- .../postCheckoutCommand/cabal.test.hs | 4 +- cabal-testsuite/README.md | 22 ++- cabal-testsuite/main/cabal-tests.hs | 34 +++- cabal-testsuite/src/Test/Cabal/Monad.hs | 159 ++++++++++++++---- .../src/Test/Cabal/OutputNormalizer.hs | 14 +- cabal-testsuite/src/Test/Cabal/Prelude.hs | 91 +++++++--- cabal-testsuite/src/Test/Cabal/TestCode.hs | 45 ++++- 82 files changed, 365 insertions(+), 492 deletions(-) delete mode 100644 cabal-testsuite/PackageTests/CustomDep/cabal.project delete mode 100644 cabal-testsuite/PackageTests/CustomDep/cabal.test.hs delete mode 100644 cabal-testsuite/PackageTests/CustomDep/client/B.hs delete mode 100644 cabal-testsuite/PackageTests/CustomDep/client/Setup.hs delete mode 100644 cabal-testsuite/PackageTests/CustomDep/client/client.cabal delete mode 100644 cabal-testsuite/PackageTests/CustomDep/custom/A.hs delete mode 100644 cabal-testsuite/PackageTests/CustomDep/custom/Setup.hs delete mode 100644 cabal-testsuite/PackageTests/CustomDep/custom/custom.cabal delete mode 100644 cabal-testsuite/PackageTests/CustomPlain/A.hs delete mode 100644 cabal-testsuite/PackageTests/CustomPlain/Setup.hs delete mode 100644 cabal-testsuite/PackageTests/CustomPlain/cabal.project delete mode 100644 cabal-testsuite/PackageTests/CustomPlain/cabal.test.hs delete mode 100644 cabal-testsuite/PackageTests/CustomPlain/plain.cabal delete mode 100644 cabal-testsuite/PackageTests/CustomPlain/setup.cabal.out delete mode 100644 cabal-testsuite/PackageTests/CustomPlain/setup.out delete mode 100644 cabal-testsuite/PackageTests/CustomPlain/setup.test.hs delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/Foo.hs delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/Main.hs delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/build-depends-extra-version.cabal delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.cabal.out delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.out delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.test.hs delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/Foo.hs delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/Main.hs delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/build-tool-depends-extra-version.cabal delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/setup.cabal.out delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/setup.out delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/setup.test.hs delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/Foo.hs delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/Main.hs delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/build-tools-extra-version.cabal delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/setup.cabal.out delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/setup.out delete mode 100644 cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/setup.test.hs delete mode 100644 cabal-testsuite/PackageTests/NewBuild/T4375/A.hs delete mode 100644 cabal-testsuite/PackageTests/NewBuild/T4375/Setup.hs delete mode 100644 cabal-testsuite/PackageTests/NewBuild/T4375/a.cabal delete mode 100644 cabal-testsuite/PackageTests/NewBuild/T4375/cabal.out delete mode 100644 cabal-testsuite/PackageTests/NewBuild/T4375/cabal.project delete mode 100644 cabal-testsuite/PackageTests/NewBuild/T4375/cabal.test.hs delete mode 100644 cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-locale-1.0.0.7/System/Locale.hs delete mode 100644 cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-locale-1.0.0.7/old-locale.cabal delete mode 100644 cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-time-1.1.0.3/System/Time.hs delete mode 100644 cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-time-1.1.0.3/old-time.cabal diff --git a/Cabal-tests/lib/Test/Utils/TempTestDir.hs b/Cabal-tests/lib/Test/Utils/TempTestDir.hs index a4b0b08cba4..7d1ca76e04f 100644 --- a/Cabal-tests/lib/Test/Utils/TempTestDir.hs +++ b/Cabal-tests/lib/Test/Utils/TempTestDir.hs @@ -2,11 +2,12 @@ module Test.Utils.TempTestDir ( withTestDir + , withTestDir' , removeDirectoryRecursiveHack ) where import Distribution.Compat.Internal.TempFile (createTempDirectory) -import Distribution.Simple.Utils (warn) +import Distribution.Simple.Utils (warn, TempFileOptions (..), defaultTempFileOptions) import Distribution.Verbosity import Control.Concurrent (threadDelay) @@ -23,12 +24,26 @@ import qualified System.Info (os) -- | Much like 'withTemporaryDirectory' but with a number of hacks to make -- sure on windows that we can clean up the directory at the end. withTestDir :: (MonadIO m, MonadMask m) => Verbosity -> String -> (FilePath -> m a) -> m a -withTestDir verbosity template action = do - systmpdir <- liftIO getTemporaryDirectory +withTestDir verbosity template action = withTestDir' verbosity defaultTempFileOptions template action + +withTestDir' :: (MonadIO m, MonadMask m) => Verbosity -> TempFileOptions -> String -> (FilePath -> m a) -> m a +withTestDir' verbosity tempFileOpts template action = do + systmpdir <- + -- MacOS returns /var/folders/... which is a symlink (/var -> /private/var), + -- so the test-suite struggles to make the build cwd-agnostic in particular + -- for the ShowBuildInfo tests. This canonicalizePath call makes it + -- /private/var/folders/... which will work. + liftIO $ canonicalizePath =<< getTemporaryDirectory bracket ( do { tmpRelDir <- liftIO $ createTempDirectory systmpdir template ; return $ systmpdir tmpRelDir } ) - (liftIO . removeDirectoryRecursiveHack verbosity) + (liftIO + -- This ensures that the temp files are not deleted at the end of the test. + -- It replicates the behavior of @withTempDirectoryEx@. + . when (not (optKeepTempFiles tempFileOpts)) + -- This is the bit that helps with Windows deleting all files. + . removeDirectoryRecursiveHack verbosity + ) action -- | On Windows, file locks held by programs we run (in this case VCSs) diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.test.hs index 6a05d9f0e96..e2c42fe43fd 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.test.hs @@ -2,7 +2,7 @@ import Test.Cabal.Prelude main = cabalTest $ do skipUnlessGhcVersion ">= 8.1" - expectBrokenIf isWindows 10191 $ withProjectFile "cabal.internal.project" $ do + expectBrokenIfWindowsCI 10191 $ withProjectFile "cabal.internal.project" $ do cabal "v2-build" ["exe"] withPlan $ do r <- runPlanExe' "I" "exe" [] diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.test.hs index 3e4577aecfa..87ab998b3b0 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.test.hs @@ -1,8 +1,7 @@ import Test.Cabal.Prelude main = setupAndCabalTest $ do skipUnlessGhcVersion ">= 8.1" - ghc <- isGhcVersion "== 9.0.2 || == 9.2.* || == 9.4.* || == 9.6.*" - expectBrokenIf ghc 7987 $ do + expectBrokenIfGhc "== 9.0.2 || == 9.2.* || == 9.4.* || == 9.6.*" 7987 $ do withPackageDb $ do withDirectory "mylib" $ setup_install_with_docs ["--ipid", "mylib-0.1.0.0"] withDirectory "mysql" $ setup_install_with_docs ["--ipid", "mysql-0.1.0.0"] diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs index b6034011a14..80990b1136c 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs @@ -2,8 +2,7 @@ import Test.Cabal.Prelude main = setupTest $ do -- No cabal test because per-component is broken with it skipUnlessGhcVersion ">= 8.1" - ghc <- isGhcVersion "== 9.0.2 || == 9.2.* || == 9.4.* || == 9.6.*" - expectBrokenIf ghc 7987 $ + expectBrokenIfGhc "== 9.0.2 || == 9.2.* || == 9.4.* || == 9.6.*" 7987 $ withPackageDb $ withDirectory "Includes2" $ do let setup_install' args = setup_install_with_docs args diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs index 45a4546819c..a2431cdf389 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs @@ -1,8 +1,8 @@ import Test.Cabal.Prelude main = cabalTest $ do - ghcVer <- isGhcVersion ">= 9.10" skipUnlessGhcVersion ">= 8.1" + ghcVer <- isGhcVersion ">= 9.10" skipIf "Windows + 9.10.1 (#10191)" (isWindows && ghcVer) withProjectFile "cabal.external.project" $ do cabal "v2-build" ["exe"] diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.test.hs index cca3ecf2954..b0d3e21688f 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.test.hs @@ -2,7 +2,7 @@ import Test.Cabal.Prelude main = cabalTest $ do skipUnlessGhcVersion ">= 8.1" - expectBrokenIf isWindows 10191 $ withProjectFile "cabal.internal.project" $ do + expectBrokenIfWindowsCI 10191 $ withProjectFile "cabal.internal.project" $ do cabal "v2-build" ["exe"] withPlan $ do r <- runPlanExe' "I" "exe" [] diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.test.hs index d7ae9a1921d..a905e873cac 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.test.hs @@ -3,8 +3,7 @@ import Data.List import qualified Data.Char as Char main = setupAndCabalTest $ do skipUnlessGhcVersion ">= 8.1" - ghc <- isGhcVersion "== 9.0.2 || == 9.2.* || == 9.4.* || == 9.6.*" - expectBrokenIf ghc 7987 $ + expectBrokenIfGhc "== 9.0.2 || == 9.2.* || == 9.4.* || == 9.6.*" 7987 $ withPackageDb $ do containers_id <- getIPID "containers" withDirectory "repo/sigs-0.1.0.0" $ setup_install_with_docs ["--ipid", "sigs-0.1.0.0"] @@ -21,4 +20,3 @@ main = setupAndCabalTest $ do withDirectory "repo/exe-0.1.0.0" $ do setup_install [] runExe' "exe" [] >>= assertOutputContains "fromList [(0,2),(2,4)]" - diff --git a/cabal-testsuite/PackageTests/Backpack/T4754/setup.test.hs b/cabal-testsuite/PackageTests/Backpack/T4754/setup.test.hs index 97dae2b597c..4931cd33c99 100644 --- a/cabal-testsuite/PackageTests/Backpack/T4754/setup.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/T4754/setup.test.hs @@ -1,6 +1,6 @@ import Test.Cabal.Prelude main = setupAndCabalTest $ do skipUnlessGhcVersion ">= 8.1" - skipUnless "no profiling libs" =<< hasProfiledLibraries + skipIfNoProfiledLibraries setup "configure" ["--enable-profiling"] setup "build" [] diff --git a/cabal-testsuite/PackageTests/Backpack/T6385/cabal.test.hs b/cabal-testsuite/PackageTests/Backpack/T6385/cabal.test.hs index 930a61bb54e..d05327839da 100644 --- a/cabal-testsuite/PackageTests/Backpack/T6385/cabal.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/T6385/cabal.test.hs @@ -1,6 +1,6 @@ import Test.Cabal.Prelude main = - cabalTest $ expectBrokenIf isWindows 10191 $ withShorterPathForNewBuildStore $ do + cabalTest $ expectBrokenIfWindows 10191 $ withShorterPathForNewBuildStore $ do skipUnlessGhcVersion ">= 8.1" withRepo "repo" $ do cabal "v2-build" ["T6385"] diff --git a/cabal-testsuite/PackageTests/CCompilerOverride/custom-cc-clang.bat b/cabal-testsuite/PackageTests/CCompilerOverride/custom-cc-clang.bat index a2e60a9c592..63221f54528 100644 --- a/cabal-testsuite/PackageTests/CCompilerOverride/custom-cc-clang.bat +++ b/cabal-testsuite/PackageTests/CCompilerOverride/custom-cc-clang.bat @@ -1,11 +1,7 @@ @echo OFF -where /q clang.exe - -IF %ERRORLEVEL% EQU 0 ( - call clang.exe -DNOERROR6 %* - EXIT /B %ERRORLEVEL% -) - -ECHO "Cannot find C compiler" -EXIT /B 1 +REM replace the libdir with the path to the compiler +FOR /f "delims=" %%A in ('call ghc.exe --print-libdir') do set "var=%%A" +setlocal EnableDelayedExpansion +CALL !var:lib=mingw\bin\clang.exe! -DNOERROR6 %* +EXIT /B %ERRORLEVEL% diff --git a/cabal-testsuite/PackageTests/CCompilerOverride/custom-cc.bat b/cabal-testsuite/PackageTests/CCompilerOverride/custom-cc.bat index 504f6b800cd..560845174d8 100644 --- a/cabal-testsuite/PackageTests/CCompilerOverride/custom-cc.bat +++ b/cabal-testsuite/PackageTests/CCompilerOverride/custom-cc.bat @@ -1,11 +1,7 @@ @echo OFF -where /q gcc.exe - -IF %ERRORLEVEL% EQU 0 ( - call gcc.exe -DNOERROR6 %* - EXIT /B %ERRORLEVEL% -) - -ECHO "Cannot find C compiler" -EXIT /B 1 +REM replace the libdir with the path to the compiler +FOR /f "delims=" %%A in ('call ghc.exe --print-libdir') do set "var=%%A" +setlocal EnableDelayedExpansion +CALL !var:lib=mingw\bin\gcc.exe! -DNOERROR6 %* +EXIT /B %ERRORLEVEL% diff --git a/cabal-testsuite/PackageTests/CmmSourcesDyn/setup.test.hs b/cabal-testsuite/PackageTests/CmmSourcesDyn/setup.test.hs index 800a540696a..d0d9a11057c 100644 --- a/cabal-testsuite/PackageTests/CmmSourcesDyn/setup.test.hs +++ b/cabal-testsuite/PackageTests/CmmSourcesDyn/setup.test.hs @@ -1,7 +1,7 @@ import Test.Cabal.Prelude main = setupTest $ do - skipIf "ghc < 7.8" =<< isGhcVersion "< 7.8" + skipIfGhcVersion "< 7.8" setup "configure" [] res <- setup' "build" [] assertOutputContains "= Post common block elimination =" res diff --git a/cabal-testsuite/PackageTests/CustomDep/cabal.project b/cabal-testsuite/PackageTests/CustomDep/cabal.project deleted file mode 100644 index d4198c181d9..00000000000 --- a/cabal-testsuite/PackageTests/CustomDep/cabal.project +++ /dev/null @@ -1 +0,0 @@ -packages: client custom diff --git a/cabal-testsuite/PackageTests/CustomDep/cabal.test.hs b/cabal-testsuite/PackageTests/CustomDep/cabal.test.hs deleted file mode 100644 index 9058afe19c0..00000000000 --- a/cabal-testsuite/PackageTests/CustomDep/cabal.test.hs +++ /dev/null @@ -1,10 +0,0 @@ -import Test.Cabal.Prelude -main = cabalTest $ do - -- implicit setup-depends conflict with GHC >= 8.2; c.f. #415 - skipUnlessGhcVersion "< 8.2" - -- This test depends heavily on what packages are in the global - -- database, don't record the output - recordMode DoNotRecord $ do - -- TODO: Hack, delete me - withEnvFilter (`notElem` ["HOME", "CABAL_DIR"]) $ do - cabal "v2-build" ["all"] diff --git a/cabal-testsuite/PackageTests/CustomDep/client/B.hs b/cabal-testsuite/PackageTests/CustomDep/client/B.hs deleted file mode 100644 index af119169669..00000000000 --- a/cabal-testsuite/PackageTests/CustomDep/client/B.hs +++ /dev/null @@ -1,2 +0,0 @@ -module B where -import A diff --git a/cabal-testsuite/PackageTests/CustomDep/client/Setup.hs b/cabal-testsuite/PackageTests/CustomDep/client/Setup.hs deleted file mode 100644 index 9a994af677b..00000000000 --- a/cabal-testsuite/PackageTests/CustomDep/client/Setup.hs +++ /dev/null @@ -1,2 +0,0 @@ -import Distribution.Simple -main = defaultMain diff --git a/cabal-testsuite/PackageTests/CustomDep/client/client.cabal b/cabal-testsuite/PackageTests/CustomDep/client/client.cabal deleted file mode 100644 index 2bb74b34594..00000000000 --- a/cabal-testsuite/PackageTests/CustomDep/client/client.cabal +++ /dev/null @@ -1,12 +0,0 @@ -name: client -version: 0.1.0.0 -license: BSD3 -author: Edward Z. Yang -maintainer: ezyang@cs.stanford.edu -build-type: Simple -cabal-version: >=1.10 - -library - exposed-modules: B - build-depends: base, custom - default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/CustomDep/custom/A.hs b/cabal-testsuite/PackageTests/CustomDep/custom/A.hs deleted file mode 100644 index d843c00b782..00000000000 --- a/cabal-testsuite/PackageTests/CustomDep/custom/A.hs +++ /dev/null @@ -1 +0,0 @@ -module A where diff --git a/cabal-testsuite/PackageTests/CustomDep/custom/Setup.hs b/cabal-testsuite/PackageTests/CustomDep/custom/Setup.hs deleted file mode 100644 index 9a994af677b..00000000000 --- a/cabal-testsuite/PackageTests/CustomDep/custom/Setup.hs +++ /dev/null @@ -1,2 +0,0 @@ -import Distribution.Simple -main = defaultMain diff --git a/cabal-testsuite/PackageTests/CustomDep/custom/custom.cabal b/cabal-testsuite/PackageTests/CustomDep/custom/custom.cabal deleted file mode 100644 index 4f327080098..00000000000 --- a/cabal-testsuite/PackageTests/CustomDep/custom/custom.cabal +++ /dev/null @@ -1,15 +0,0 @@ -name: custom -version: 0.1.0.0 -license: BSD3 -author: Edward Z. Yang -maintainer: ezyang@cs.stanford.edu -build-type: Custom -cabal-version: >=1.10 - -library - exposed-modules: A - build-depends: base - default-language: Haskell2010 - -custom-setup - setup-depends: base, Cabal diff --git a/cabal-testsuite/PackageTests/CustomPlain/A.hs b/cabal-testsuite/PackageTests/CustomPlain/A.hs deleted file mode 100644 index d843c00b782..00000000000 --- a/cabal-testsuite/PackageTests/CustomPlain/A.hs +++ /dev/null @@ -1 +0,0 @@ -module A where diff --git a/cabal-testsuite/PackageTests/CustomPlain/Setup.hs b/cabal-testsuite/PackageTests/CustomPlain/Setup.hs deleted file mode 100644 index 20b960ede90..00000000000 --- a/cabal-testsuite/PackageTests/CustomPlain/Setup.hs +++ /dev/null @@ -1,3 +0,0 @@ -import Distribution.Simple -import System.IO -main = hPutStrLn stderr "ThisIsCustomYeah" >> defaultMain diff --git a/cabal-testsuite/PackageTests/CustomPlain/cabal.project b/cabal-testsuite/PackageTests/CustomPlain/cabal.project deleted file mode 100644 index e6fdbadb439..00000000000 --- a/cabal-testsuite/PackageTests/CustomPlain/cabal.project +++ /dev/null @@ -1 +0,0 @@ -packages: . diff --git a/cabal-testsuite/PackageTests/CustomPlain/cabal.test.hs b/cabal-testsuite/PackageTests/CustomPlain/cabal.test.hs deleted file mode 100644 index 42c64595594..00000000000 --- a/cabal-testsuite/PackageTests/CustomPlain/cabal.test.hs +++ /dev/null @@ -1,11 +0,0 @@ -import Test.Cabal.Prelude -main = cabalTest $ do - -- implicit setup-depends conflict with GHC >= 8.2; c.f. #415 - skipUnlessGhcVersion "< 8.2" - -- Regression test for #4393 - recordMode DoNotRecord $ do - -- TODO: Hack; see also CustomDep/cabal.test.hs - withEnvFilter (`notElem` ["HOME", "CABAL_DIR"]) $ do - -- On -v2, we don't have vQuiet set, which suppressed - -- the error - cabal "v2-build" ["-v1"] diff --git a/cabal-testsuite/PackageTests/CustomPlain/plain.cabal b/cabal-testsuite/PackageTests/CustomPlain/plain.cabal deleted file mode 100644 index d0666a10fd8..00000000000 --- a/cabal-testsuite/PackageTests/CustomPlain/plain.cabal +++ /dev/null @@ -1,11 +0,0 @@ -name: plain -version: 0.1.0.0 -license: BSD3 -author: Edward Z. Yang -maintainer: ezyang@cs.stanford.edu -cabal-version: >=1.10 - -library - exposed-modules: A - build-depends: base - default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/CustomPlain/setup.cabal.out b/cabal-testsuite/PackageTests/CustomPlain/setup.cabal.out deleted file mode 100644 index 2d3ff0f9451..00000000000 --- a/cabal-testsuite/PackageTests/CustomPlain/setup.cabal.out +++ /dev/null @@ -1,7 +0,0 @@ -# Setup configure -Resolving dependencies... -Configuring plain-0.1.0.0... -Warning: No 'build-type' specified. If you do not need a custom Setup.hs or ./configure script then use 'build-type: Simple'. -# Setup build -Preprocessing library for plain-0.1.0.0... -Building library for plain-0.1.0.0... diff --git a/cabal-testsuite/PackageTests/CustomPlain/setup.out b/cabal-testsuite/PackageTests/CustomPlain/setup.out deleted file mode 100644 index 3fdfe2b7f77..00000000000 --- a/cabal-testsuite/PackageTests/CustomPlain/setup.out +++ /dev/null @@ -1,6 +0,0 @@ -# Setup configure -Configuring plain-0.1.0.0... -Warning: [no-build-type] No 'build-type' specified. If you do not need a custom Setup.hs or ./configure script then use 'build-type: Simple'. -# Setup build -Preprocessing library for plain-0.1.0.0... -Building library for plain-0.1.0.0... diff --git a/cabal-testsuite/PackageTests/CustomPlain/setup.test.hs b/cabal-testsuite/PackageTests/CustomPlain/setup.test.hs deleted file mode 100644 index abf668397b8..00000000000 --- a/cabal-testsuite/PackageTests/CustomPlain/setup.test.hs +++ /dev/null @@ -1,4 +0,0 @@ -import Test.Cabal.Prelude -main = setupTest $ do - setup' "configure" [] >>= assertOutputContains "ThisIsCustomYeah" - setup' "build" [] >>= assertOutputContains "ThisIsCustomYeah" diff --git a/cabal-testsuite/PackageTests/GHCJS/BuildRunner/cabal.test.hs b/cabal-testsuite/PackageTests/GHCJS/BuildRunner/cabal.test.hs index 18fa0d364fe..245901c8bef 100644 --- a/cabal-testsuite/PackageTests/GHCJS/BuildRunner/cabal.test.hs +++ b/cabal-testsuite/PackageTests/GHCJS/BuildRunner/cabal.test.hs @@ -1,7 +1,7 @@ import Test.Cabal.Prelude main = do - cabalTest . expectBrokenIf isWindows 10179 . recordMode DoNotRecord $ do + cabalTest . expectBrokenIfWindows 10179 . recordMode DoNotRecord $ do cwd <- fmap testCurrentDir getTestEnv testInvokedWithBuildRunner cwd "test" [] testInvokedWithBuildRunner cwd "run" ["ghcjs-exe"] diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/setup.test.hs index 0f0e86a3c60..86a7cf804ea 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/setup.test.hs @@ -1,6 +1,6 @@ import Test.Cabal.Prelude -main = setupAndCabalTest $ expectBrokenIf isWindows 10179 $ do +main = setupAndCabalTest $ expectBrokenIfWindows 10179 $ do env <- getTestEnv let cwd = testCurrentDir env ghc_path <- programPathM ghcProgram diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/setup.test.hs index 20a661437bf..0b0a37413be 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/setup.test.hs @@ -1,6 +1,6 @@ import Test.Cabal.Prelude -main = setupAndCabalTest $ expectBrokenIf isWindows 10179 $ do +main = setupAndCabalTest $ expectBrokenIfWindows 10179 $ do env <- getTestEnv let cwd = testCurrentDir env ghc_path <- programPathM ghcProgram diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/setup.test.hs index 20a661437bf..0b0a37413be 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/setup.test.hs @@ -1,6 +1,6 @@ import Test.Cabal.Prelude -main = setupAndCabalTest $ expectBrokenIf isWindows 10179 $ do +main = setupAndCabalTest $ expectBrokenIfWindows 10179 $ do env <- getTestEnv let cwd = testCurrentDir env ghc_path <- programPathM ghcProgram diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/setup.test.hs index 18cb32829b1..0b80a76a952 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/setup.test.hs @@ -1,6 +1,6 @@ import Test.Cabal.Prelude -main = setupAndCabalTest $ expectBrokenIf isWindows 10179 $ do +main = setupAndCabalTest $ expectBrokenIfWindows 10179 $ do withSymlink "bin/ghc" "ghc" $ do env <- getTestEnv let cwd = testCurrentDir env diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/setup.test.hs index 7837f5f9f3b..150f2bc8739 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/setup.test.hs @@ -1,6 +1,6 @@ import Test.Cabal.Prelude -main = setupAndCabalTest $ expectBrokenIf isWindows 10179 $ do +main = setupAndCabalTest $ expectBrokenIfWindows 10179 $ do withSymlink "bin/ghc-7.10" "ghc" $ do env <- getTestEnv let cwd = testCurrentDir env diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/setup.test.hs index 7837f5f9f3b..150f2bc8739 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/setup.test.hs @@ -1,6 +1,6 @@ import Test.Cabal.Prelude -main = setupAndCabalTest $ expectBrokenIf isWindows 10179 $ do +main = setupAndCabalTest $ expectBrokenIfWindows 10179 $ do withSymlink "bin/ghc-7.10" "ghc" $ do env <- getTestEnv let cwd = testCurrentDir env diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/Foo.hs b/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/Foo.hs deleted file mode 100644 index efbf93bbde8..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/Foo.hs +++ /dev/null @@ -1 +0,0 @@ -module Foo where diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/Main.hs b/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/Main.hs deleted file mode 100644 index d82a4bd93b7..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/Main.hs +++ /dev/null @@ -1,4 +0,0 @@ -module Main where - -main :: IO () -main = return () diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/build-depends-extra-version.cabal b/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/build-depends-extra-version.cabal deleted file mode 100644 index 01c7b3b5972..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/build-depends-extra-version.cabal +++ /dev/null @@ -1,17 +0,0 @@ -name: build-depends-extra-version -version: 0.1.0.0 -synopsis: Checks build-depends warns for extraneous version -license: BSD3 -category: Testing -build-type: Simple -cabal-version: >=1.10 - -library - exposed-modules: Foo - default-language: Haskell2010 - -executable bar - main-is: Main.hs - build-depends: build-depends-extra-version >=0.0.0.1 - -- ^ internal dependency, extraneous version - default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.cabal.out b/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.cabal.out deleted file mode 100644 index 61f9d97a4ba..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.cabal.out +++ /dev/null @@ -1,13 +0,0 @@ -# Setup configure -Configuring build-depends-extra-version-0.1.0.0... -Warning: The package has an extraneous version range for a dependency on an internal library: build-depends-extra-version >=0.0.0.1. This version range includes the current package but isn't needed as the current package's library will always be used. -# Setup sdist -Distribution quality errors: -The package has an extraneous version range for a dependency on an internal library: build-depends-extra-version >=0.0.0.1. This version range includes the current package but isn't needed as the current package's library will always be used. -Distribution quality warnings: -No 'maintainer' field. -No 'description' field. -A 'license-file' is not specified. -Note: the public hackage server would reject this package. -Building source dist for build-depends-extra-version-0.1.0.0... -Source tarball created: setup.cabal.dist/work/dist/build-depends-extra-version-0.1.0.0.tar.gz diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.out b/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.out deleted file mode 100644 index 2b9987c8544..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.out +++ /dev/null @@ -1,13 +0,0 @@ -# Setup configure -Configuring build-depends-extra-version-0.1.0.0... -Warning: The package has an extraneous version range for a dependency on an internal library: build-depends-extra-version >=0.0.0.1. This version range includes the current package but isn't needed as the current package's library will always be used. -# Setup sdist -Distribution quality errors: -The package has an extraneous version range for a dependency on an internal library: build-depends-extra-version >=0.0.0.1. This version range includes the current package but isn't needed as the current package's library will always be used. -Distribution quality warnings: -No 'maintainer' field. -No 'description' field. -A 'license-file' is not specified. -Note: the public hackage server would reject this package. -Building source dist for build-depends-extra-version-0.1.0.0... -Source tarball created: setup.dist/work/dist/build-depends-extra-version-0.1.0.0.tar.gz diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.test.hs b/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.test.hs deleted file mode 100644 index c006efe6f72..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.test.hs +++ /dev/null @@ -1,6 +0,0 @@ -import Test.Cabal.Prelude --- Test unneed version bound on internal build-tools deps -main = setupAndCabalTest . expectBroken 7470 $ do - setup' "configure" [] - assertOutputContains "extraneous version range" - =<< setup' "sdist" [] diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/Foo.hs b/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/Foo.hs deleted file mode 100644 index efbf93bbde8..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/Foo.hs +++ /dev/null @@ -1 +0,0 @@ -module Foo where diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/Main.hs b/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/Main.hs deleted file mode 100644 index d82a4bd93b7..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/Main.hs +++ /dev/null @@ -1,4 +0,0 @@ -module Main where - -main :: IO () -main = return () diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/build-tool-depends-extra-version.cabal b/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/build-tool-depends-extra-version.cabal deleted file mode 100644 index af43e0cdd02..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/build-tool-depends-extra-version.cabal +++ /dev/null @@ -1,18 +0,0 @@ -name: build-tool-depends-extra-version -version: 0.1.0.0 -synopsis: Checks build-tool-depends warns for extraneous version -license: BSD3 -category: Testing -build-type: Simple -cabal-version: >=1.10 - -library - exposed-modules: Foo - build-tool-depends: build-tool-depends-extra-version:hello-world >=0.0.0.1 - -- ^ internal dependency, extraneous version - default-language: Haskell2010 - -executable hello-world - main-is: Main.hs - build-depends: base - default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/setup.cabal.out b/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/setup.cabal.out deleted file mode 100644 index c247d90f995..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/setup.cabal.out +++ /dev/null @@ -1,13 +0,0 @@ -# Setup configure -Configuring build-tool-depends-extra-version-0.1.0.0... -Warning: The package has an extraneous version range for a dependency on an internal executable: build-tool-depends-extra-version:hello-world >=0.0.0.1. This version range includes the current package but isn't needed as the current package's executable will always be used. -# Setup sdist -Distribution quality errors: -The package has an extraneous version range for a dependency on an internal executable: build-tool-depends-extra-version:hello-world >=0.0.0.1. This version range includes the current package but isn't needed as the current package's executable will always be used. -Distribution quality warnings: -No 'maintainer' field. -No 'description' field. -A 'license-file' is not specified. -Note: the public hackage server would reject this package. -Building source dist for build-tool-depends-extra-version-0.1.0.0... -Source tarball created: setup.cabal.dist/work/dist/build-tool-depends-extra-version-0.1.0.0.tar.gz diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/setup.out b/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/setup.out deleted file mode 100644 index cd0ba1f5e0a..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/setup.out +++ /dev/null @@ -1,13 +0,0 @@ -# Setup configure -Configuring build-tool-depends-extra-version-0.1.0.0... -Warning: The package has an extraneous version range for a dependency on an internal executable: build-tool-depends-extra-version:hello-world >=0.0.0.1. This version range includes the current package but isn't needed as the current package's executable will always be used. -# Setup sdist -Distribution quality errors: -The package has an extraneous version range for a dependency on an internal executable: build-tool-depends-extra-version:hello-world >=0.0.0.1. This version range includes the current package but isn't needed as the current package's executable will always be used. -Distribution quality warnings: -No 'maintainer' field. -No 'description' field. -A 'license-file' is not specified. -Note: the public hackage server would reject this package. -Building source dist for build-tool-depends-extra-version-0.1.0.0... -Source tarball created: setup.dist/work/dist/build-tool-depends-extra-version-0.1.0.0.tar.gz diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/setup.test.hs b/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/setup.test.hs deleted file mode 100644 index c006efe6f72..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/setup.test.hs +++ /dev/null @@ -1,6 +0,0 @@ -import Test.Cabal.Prelude --- Test unneed version bound on internal build-tools deps -main = setupAndCabalTest . expectBroken 7470 $ do - setup' "configure" [] - assertOutputContains "extraneous version range" - =<< setup' "sdist" [] diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/Foo.hs b/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/Foo.hs deleted file mode 100644 index efbf93bbde8..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/Foo.hs +++ /dev/null @@ -1 +0,0 @@ -module Foo where diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/Main.hs b/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/Main.hs deleted file mode 100644 index d82a4bd93b7..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/Main.hs +++ /dev/null @@ -1,4 +0,0 @@ -module Main where - -main :: IO () -main = return () diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/build-tools-extra-version.cabal b/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/build-tools-extra-version.cabal deleted file mode 100644 index c5371bf45ee..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/build-tools-extra-version.cabal +++ /dev/null @@ -1,18 +0,0 @@ -name: build-tools-extra-version -version: 0.1.0.0 -synopsis: Checks build-tools warns for extraneous version -license: BSD3 -category: Testing -build-type: Simple -cabal-version: >=1.10 - -library - exposed-modules: Foo - build-tools: hello-world >=0.0.0.1 - -- ^ internal dependency, extraneous version - default-language: Haskell2010 - -executable hello-world - main-is: Main.hs - build-depends: base - default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/setup.cabal.out b/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/setup.cabal.out deleted file mode 100644 index 58d3172cb43..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/setup.cabal.out +++ /dev/null @@ -1,13 +0,0 @@ -# Setup configure -Configuring build-tools-extra-version-0.1.0.0... -Warning: The package has an extraneous version range for a dependency on an internal executable: build-tools-extra-version:hello-world >=0.0.0.1. This version range includes the current package but isn't needed as the current package's executable will always be used. -# Setup sdist -Distribution quality errors: -The package has an extraneous version range for a dependency on an internal executable: build-tools-extra-version:hello-world >=0.0.0.1. This version range includes the current package but isn't needed as the current package's executable will always be used. -Distribution quality warnings: -No 'maintainer' field. -No 'description' field. -A 'license-file' is not specified. -Note: the public hackage server would reject this package. -Building source dist for build-tools-extra-version-0.1.0.0... -Source tarball created: setup.cabal.dist/work/dist/build-tools-extra-version-0.1.0.0.tar.gz diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/setup.out b/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/setup.out deleted file mode 100644 index 28059d26ccd..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/setup.out +++ /dev/null @@ -1,13 +0,0 @@ -# Setup configure -Configuring build-tools-extra-version-0.1.0.0... -Warning: The package has an extraneous version range for a dependency on an internal executable: build-tools-extra-version:hello-world >=0.0.0.1. This version range includes the current package but isn't needed as the current package's executable will always be used. -# Setup sdist -Distribution quality errors: -The package has an extraneous version range for a dependency on an internal executable: build-tools-extra-version:hello-world >=0.0.0.1. This version range includes the current package but isn't needed as the current package's executable will always be used. -Distribution quality warnings: -No 'maintainer' field. -No 'description' field. -A 'license-file' is not specified. -Note: the public hackage server would reject this package. -Building source dist for build-tools-extra-version-0.1.0.0... -Source tarball created: setup.dist/work/dist/build-tools-extra-version-0.1.0.0.tar.gz diff --git a/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/setup.test.hs b/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/setup.test.hs deleted file mode 100644 index c006efe6f72..00000000000 --- a/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/setup.test.hs +++ /dev/null @@ -1,6 +0,0 @@ -import Test.Cabal.Prelude --- Test unneed version bound on internal build-tools deps -main = setupAndCabalTest . expectBroken 7470 $ do - setup' "configure" [] - assertOutputContains "extraneous version range" - =<< setup' "sdist" [] diff --git a/cabal-testsuite/PackageTests/NewBuild/T4375/A.hs b/cabal-testsuite/PackageTests/NewBuild/T4375/A.hs deleted file mode 100644 index d843c00b782..00000000000 --- a/cabal-testsuite/PackageTests/NewBuild/T4375/A.hs +++ /dev/null @@ -1 +0,0 @@ -module A where diff --git a/cabal-testsuite/PackageTests/NewBuild/T4375/Setup.hs b/cabal-testsuite/PackageTests/NewBuild/T4375/Setup.hs deleted file mode 100644 index 9a994af677b..00000000000 --- a/cabal-testsuite/PackageTests/NewBuild/T4375/Setup.hs +++ /dev/null @@ -1,2 +0,0 @@ -import Distribution.Simple -main = defaultMain diff --git a/cabal-testsuite/PackageTests/NewBuild/T4375/a.cabal b/cabal-testsuite/PackageTests/NewBuild/T4375/a.cabal deleted file mode 100644 index e3c9ed6bca1..00000000000 --- a/cabal-testsuite/PackageTests/NewBuild/T4375/a.cabal +++ /dev/null @@ -1,11 +0,0 @@ -name: a -version: 0.1 -build-type: Custom -cabal-version: >= 1.10 - --- no explicit setup deps - -library - exposed-modules: A - build-depends: base - default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/NewBuild/T4375/cabal.out b/cabal-testsuite/PackageTests/NewBuild/T4375/cabal.out deleted file mode 100644 index ebbf63746ef..00000000000 --- a/cabal-testsuite/PackageTests/NewBuild/T4375/cabal.out +++ /dev/null @@ -1,7 +0,0 @@ -# cabal v2-update -Downloading the latest package list from test-local-repo -# cabal v2-build -Resolving dependencies... -Build profile: -w ghc- -O1 -In order, the following will be built: - - a-0.1 (lib:a) (first run) diff --git a/cabal-testsuite/PackageTests/NewBuild/T4375/cabal.project b/cabal-testsuite/PackageTests/NewBuild/T4375/cabal.project deleted file mode 100644 index e6fdbadb439..00000000000 --- a/cabal-testsuite/PackageTests/NewBuild/T4375/cabal.project +++ /dev/null @@ -1 +0,0 @@ -packages: . diff --git a/cabal-testsuite/PackageTests/NewBuild/T4375/cabal.test.hs b/cabal-testsuite/PackageTests/NewBuild/T4375/cabal.test.hs deleted file mode 100644 index b42f3f28c7a..00000000000 --- a/cabal-testsuite/PackageTests/NewBuild/T4375/cabal.test.hs +++ /dev/null @@ -1,13 +0,0 @@ -import Test.Cabal.Prelude -main = - -- TODO: is this test ever run? - cabalTest $ withShorterPathForNewBuildStore $ do - -- Don't run this test unless the GHC is sufficiently recent - -- to not ship boot old-time/old-locale - skipUnlessGhcVersion ">= 7.11" - -- Don't run this test on GHC 8.2, which ships with Cabal 2.0, - -- which is not eligible for old-style Custom setup (if - -- we had the full Hackage index, we'd try it.) - skipUnlessGhcVersion "< 8.1" - withRepo "repo" $ do - cabal "v2-build" ["a"] diff --git a/cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-locale-1.0.0.7/System/Locale.hs b/cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-locale-1.0.0.7/System/Locale.hs deleted file mode 100644 index 83af47b0ef4..00000000000 --- a/cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-locale-1.0.0.7/System/Locale.hs +++ /dev/null @@ -1 +0,0 @@ -module System.Locale where diff --git a/cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-locale-1.0.0.7/old-locale.cabal b/cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-locale-1.0.0.7/old-locale.cabal deleted file mode 100644 index f6e3dadf6d5..00000000000 --- a/cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-locale-1.0.0.7/old-locale.cabal +++ /dev/null @@ -1,9 +0,0 @@ -name: old-locale -version: 1.0.0.7 -build-type: Simple -cabal-version: >= 1.10 - -library - exposed-modules: System.Locale - build-depends: base - default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-time-1.1.0.3/System/Time.hs b/cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-time-1.1.0.3/System/Time.hs deleted file mode 100644 index f4185b6527a..00000000000 --- a/cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-time-1.1.0.3/System/Time.hs +++ /dev/null @@ -1,2 +0,0 @@ -module System.Time where -import System.Locale diff --git a/cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-time-1.1.0.3/old-time.cabal b/cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-time-1.1.0.3/old-time.cabal deleted file mode 100644 index 11ac6cccc91..00000000000 --- a/cabal-testsuite/PackageTests/NewBuild/T4375/repo/old-time-1.1.0.3/old-time.cabal +++ /dev/null @@ -1,9 +0,0 @@ -name: old-time -version: 1.1.0.3 -build-type: Simple -cabal-version: >= 1.10 - -library - exposed-modules: System.Time - build-depends: base, old-locale == 1.0.* - default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/NewSdist/DeterministicTrivial/deterministic.test.hs b/cabal-testsuite/PackageTests/NewSdist/DeterministicTrivial/deterministic.test.hs index 67c2944b39c..8b260c9e1ba 100644 --- a/cabal-testsuite/PackageTests/NewSdist/DeterministicTrivial/deterministic.test.hs +++ b/cabal-testsuite/PackageTests/NewSdist/DeterministicTrivial/deterministic.test.hs @@ -24,6 +24,5 @@ main = cabalTest $ do known <- liftIO (BS.readFile knownSdist) unknown <- liftIO (BS.readFile mySdist) - skipIf "#8356" True -- bogus, just to indicate that the test is skipped assertEqual "hashes didn't match for sdist" True True -- assertEqual "hashes didn't match for sdist" (BS16.encode $ SHA256.hash known) (BS16.encode $ SHA256.hash unknown) diff --git a/cabal-testsuite/PackageTests/NewUpdate/RejectFutureIndexStates/cabal.test.hs b/cabal-testsuite/PackageTests/NewUpdate/RejectFutureIndexStates/cabal.test.hs index 475a093360d..442d3508849 100644 --- a/cabal-testsuite/PackageTests/NewUpdate/RejectFutureIndexStates/cabal.test.hs +++ b/cabal-testsuite/PackageTests/NewUpdate/RejectFutureIndexStates/cabal.test.hs @@ -1,13 +1,7 @@ import Test.Cabal.Prelude import Data.List (isPrefixOf) -main = cabalTest $ do - - skip "Flaky test failing in `curl`, see #9530" - - testBody - -testBody = withProjectFile "cabal.project" $ withRemoteRepo "repo" $ do +main = skipIfCIAndWindows 10230 >> cabalTest (flakyIfCI 9530 $ withProjectFile "cabal.project" $ withRemoteRepo "repo" $ do output <- last . words @@ -18,9 +12,9 @@ testBody = withProjectFile "cabal.project" $ withRemoteRepo "repo" $ do <$> recordMode DoNotRecord (cabal' "update" []) -- update golden output with actual timestamp shell "cp" ["cabal.out.in", "cabal.out"] - shell "sed" ["-i''", "-e", "s/REPLACEME/" <> output <> "/g", "cabal.out"] + shell "sed" [ "-i" ++ if not isWindows then "''" else "", "-e", "s/REPLACEME/" <> output <> "/g", "cabal.out"] -- This shall fail with an error message as specified in `cabal.out` fails $ cabal "build" ["--index-state=4000-01-01T00:00:00Z", "fake-pkg"] -- This shall fail by not finding the package, what indicates that it -- accepted an older index-state. - fails $ cabal "build" ["--index-state=2023-01-01T00:00:00Z", "fake-pkg"] + fails $ cabal "build" ["--index-state=2023-01-01T00:00:00Z", "fake-pkg"]) diff --git a/cabal-testsuite/PackageTests/NewUpdate/UpdateIndexState/update-index-state.test.hs b/cabal-testsuite/PackageTests/NewUpdate/UpdateIndexState/update-index-state.test.hs index e6485d51f71..eb3bc8daff7 100644 --- a/cabal-testsuite/PackageTests/NewUpdate/UpdateIndexState/update-index-state.test.hs +++ b/cabal-testsuite/PackageTests/NewUpdate/UpdateIndexState/update-index-state.test.hs @@ -1,19 +1,13 @@ import Test.Cabal.Prelude -main = cabalTest $ do - - skip "Flaky test failing in `curl`, see #9530" - - testBody - -testBody = withRemoteRepo "repo" $ do +main = skipIfCIAndWindows 10230 >> cabalTest (flakyIfCI 9530 $ withRemoteRepo "repo" $ do -- The _first_ update call causes a warning about missing mirrors, the warning -- is platform-dependent and it's not part of the test expectations, so we -- check the output manually. res <- recordMode DoNotRecord $ - cabal' "update" ["repository.localhost,2022-01-28T02:36:41Z"] + cabal' "update" ["repository.localhost,2022-01-28T02:36:41Z"] assertOutputContains "The index-state is set to 2022-01-28T02:36:41Z" res assertOutputDoesNotContain "revert" res cabal "update" ["repository.localhost,2016-09-24T17:47:48Z"] - cabal "update" ["repository.localhost,2022-01-28T02:36:41Z"] + cabal "update" ["repository.localhost,2022-01-28T02:36:41Z"]) diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs b/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs index 7ccdfca1655..2528e7459e5 100644 --- a/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs +++ b/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs @@ -1,7 +1,7 @@ import Test.Cabal.Prelude -- Test that invalid unicode in pkg-config output doesn't trip up cabal very much -main = cabalTest $ expectBrokenIf isWindows 10179 $ do +main = cabalTest $ expectBrokenIfWindows 10179 $ do cdir <- testCurrentDir `fmap` getTestEnv res <- cabal' "v2-build" ["--extra-prog-path="++cdir, "-v2"] assertOutputContains "Some pkg-config packages have names containing invalid unicode: or" res diff --git a/cabal-testsuite/PackageTests/Regression/T4025/setup.test.hs b/cabal-testsuite/PackageTests/Regression/T4025/setup.test.hs index d6034c7c3f2..b26afa66701 100644 --- a/cabal-testsuite/PackageTests/Regression/T4025/setup.test.hs +++ b/cabal-testsuite/PackageTests/Regression/T4025/setup.test.hs @@ -1,11 +1,9 @@ import Test.Cabal.Prelude -- Test that we don't accidentally add the inplace directory to -- an executable RPATH. -main = do - skipIfWindows "doesn't support RPATH" - setupAndCabalTest $ do - ghc <- isGhcVersion ">= 8.10.7" - expectBrokenIf (isOSX && ghc) 7610 $ do -- see also issue #7988 +main = setupAndCabalTest $ do + skipIfNoSharedLibraries + expectBrokenIfOSXAndGhc ">= 8.10.7" 7610 $ do -- see also issue #7988 setup "configure" ["--enable-executable-dynamic"] setup "build" [] -- This should fail as it we should NOT be able to find the diff --git a/cabal-testsuite/PackageTests/Regression/T4270/setup.test.hs b/cabal-testsuite/PackageTests/Regression/T4270/setup.test.hs index bd227b75f3e..6dbe57b8ede 100644 --- a/cabal-testsuite/PackageTests/Regression/T4270/setup.test.hs +++ b/cabal-testsuite/PackageTests/Regression/T4270/setup.test.hs @@ -6,7 +6,6 @@ main = setupAndCabalTest $ do skipIfAllCabalVersion "< 2.2" skipIfNoSharedLibraries skipUnless "no shared Cabal" =<< hasCabalShared - ghc <- isGhcVersion "== 8.0.2" - expectBrokenIf (isOSX && ghc) 8028 $ do + expectBrokenIfOSXAndGhc "== 8.0.2" 8028 $ do setup_build ["--enable-tests", "--enable-executable-dynamic"] setup "test" [] diff --git a/cabal-testsuite/PackageTests/Regression/T5309/cabal.test.hs b/cabal-testsuite/PackageTests/Regression/T5309/cabal.test.hs index e64f2e36951..4700f191578 100644 --- a/cabal-testsuite/PackageTests/Regression/T5309/cabal.test.hs +++ b/cabal-testsuite/PackageTests/Regression/T5309/cabal.test.hs @@ -1,8 +1,6 @@ import Test.Cabal.Prelude -main = do - cabalTest $ do - ghcVer <- isGhcVersion ">= 9.4" - expectBrokenIf (isWindows && ghcVer) 10189 $ do +main = cabalTest $ do + expectBrokenIfWindowsCIAndGhc ">= 9.4" 10189 $ do cabal "v2-build" ["all"] cabal "v2-test" ["all"] cabal "v2-bench" ["all"] diff --git a/cabal-testsuite/PackageTests/Regression/T6906/cabal.test.hs b/cabal-testsuite/PackageTests/Regression/T6906/cabal.test.hs index fabfcbdbede..9f71b845736 100644 --- a/cabal-testsuite/PackageTests/Regression/T6906/cabal.test.hs +++ b/cabal-testsuite/PackageTests/Regression/T6906/cabal.test.hs @@ -1,8 +1,7 @@ import Test.Cabal.Prelude main = cabalTest $ do - ghcsWithMaxPathIssue <- isGhcVersion "< 8.6.5" - expectBrokenIf (isWindows && ghcsWithMaxPathIssue) 6271 $ do + expectBrokenIfWindowsAndGhc "< 8.6.5" 6271 $ do res <- recordMode DoNotRecord $ cabalG' ["--config=cabal.config"] "v2-install" ["-v3"] assertOutputContains "creating file with the inputs used to compute the package hash:" res assertOutputContains "extra-lib-dirs: bar" res diff --git a/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/cabal-with-hpc.multitest.hs b/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/cabal-with-hpc.multitest.hs index c62f83385a3..172b48d8c80 100644 --- a/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/cabal-with-hpc.multitest.hs +++ b/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/cabal-with-hpc.multitest.hs @@ -8,10 +8,9 @@ import qualified Distribution.Verbosity as Verbosity import Test.Cabal.Prelude -main = cabalTest $ do - skipIf "osx" isOSX -- TODO: re-enable this once the macOS CI - -- issues are resolved, see discussion in #4902. - +main = do + skipIfCIAndOSX 4902 + cabalTest $ do hasShared <- hasSharedLibraries hasProfiled <- hasProfiledLibraries hpcOk <- correctHpcVersion diff --git a/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-copy.test.hs b/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-copy.test.hs index e05f52953f5..353caa5b5c8 100644 --- a/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-copy.test.hs +++ b/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-copy.test.hs @@ -1,8 +1,6 @@ import Test.Cabal.Prelude -main = do - skipIfWindows "#10180" - cabalTest $ withShorterPathForNewBuildStore $ do - storeDir <- testStoreDir <$> getTestEnv - let options = ["--installdir=" ++ storeDir] - cabalG options "v2-install" ["--install-method=copy"] +main = cabalTest $ expectBrokenIfWindows 10180 $ withShorterPathForNewBuildStore $ do + storeDir <- testStoreDir <$> getTestEnv + let options = ["--installdir=" ++ storeDir] + cabalG options "v2-install" ["--install-method=copy"] diff --git a/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-symlink.test.hs b/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-symlink.test.hs index d25ecb0465e..62f9305d4ee 100644 --- a/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-symlink.test.hs +++ b/cabal-testsuite/PackageTests/WarnEarlyOverwrite/clean-install-by-symlink.test.hs @@ -1,8 +1,6 @@ import Test.Cabal.Prelude -main = do - skipIfWindows "#10180" - cabalTest $ withShorterPathForNewBuildStore $ do - storeDir <- testStoreDir <$> getTestEnv - let options = ["--installdir=" ++ storeDir] - cabalG options "v2-install" [] +main = cabalTest $ expectBrokenIfWindows 10180 $ withShorterPathForNewBuildStore $ do + storeDir <- testStoreDir <$> getTestEnv + let options = ["--installdir=" ++ storeDir] + cabalG options "v2-install" [] diff --git a/cabal-testsuite/PackageTests/WarnEarlyOverwrite/dirty-install.test.hs b/cabal-testsuite/PackageTests/WarnEarlyOverwrite/dirty-install.test.hs index 232d526f983..17008de3f7c 100644 --- a/cabal-testsuite/PackageTests/WarnEarlyOverwrite/dirty-install.test.hs +++ b/cabal-testsuite/PackageTests/WarnEarlyOverwrite/dirty-install.test.hs @@ -2,13 +2,11 @@ import Test.Cabal.Prelude import System.FilePath -main = do - skipIfWindows "#10180" - cabalTest $ withShorterPathForNewBuildStore $ do - storeDir <- testStoreDir <$> getTestEnv - let options = ["--installdir=" ++ storeDir] - -- Touch the target to see if the warning is made early before the build. - _ <- runM "touch" [ (if isWindows then (<.> "exe") else id) - $ storeDir "warn-early-overwrite" ] Nothing - fails $ cabalG options "v2-install" [] - cabalG options "v2-install" ["--overwrite-policy=always"] +main = cabalTest $ expectBrokenIfWindows 10180 $ withShorterPathForNewBuildStore $ do + storeDir <- testStoreDir <$> getTestEnv + let options = ["--installdir=" ++ storeDir] + -- Touch the target to see if the warning is made early before the build. + _ <- runM "touch" [ (if isWindows then (<.> "exe") else id) + $ storeDir "warn-early-overwrite" ] Nothing + fails $ cabalG options "v2-install" [] + cabalG options "v2-install" ["--overwrite-policy=always"] diff --git a/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs b/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs index 65fddd48be5..50e45454ff3 100644 --- a/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs +++ b/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs @@ -1,8 +1,6 @@ import Test.Cabal.Prelude -main = do - skipIfWindows "see #10182" - cabalTest $ do +main = cabalTest $ do withProjectFile "cabal.positive.project" $ do cabal "v2-build" ["-v0"] withProjectFile "cabal.negative.project" $ do diff --git a/cabal-testsuite/README.md b/cabal-testsuite/README.md index 79b9185fecb..73b39d56801 100644 --- a/cabal-testsuite/README.md +++ b/cabal-testsuite/README.md @@ -200,17 +200,29 @@ and stderr. these with include `hasSharedLibraries`, `hasProfiledLibraries`, `hasCabalShared`, `isGhcVersion`, `isWindows`, `isLinux`, `isOSX`. +There are some pre-defined versions of those combinators like `skipIfWindows` +or `skipIfCI`. If possible try to use those as the error message will be uniform +with other tests, allowing for `grep`ing the output more easily. + +Make sure that you only skip tests which cannot be run by fundamental reasons, +like the OS or the capabilities of the GHC version. If a test is failing do not +skip it, mark it as broken instead (see next question). + +**How do I mark a test as broken?** Use `expectBroken`, which takes +the ticket number as its first argument. + +**How do I mark a flaky test?** If a test passes only sometimes for unknown +reasons, it is better to mark it as flaky with the `flaky` and `flakyIf` +combinators. They both take a ticket number so the flaky tests has to be tracked +in an issue. Flaky tests are executed, and the outcome is reported by the +test-suite but even if they fail they won't make the test-suite fail. + **I programmatically modified a file in my test suite, but Cabal/GHC doesn't seem to be picking it up.** You need to sleep sufficiently long before editing a file, in order for file system timestamp resolution to pick it up. Use `withDelay` and `delay` prior to making a modification. -**How do I mark a test as broken?** Use `expectBroken`, which takes -the ticket number as its first argument. Note that this does NOT -handle accept-test brokenness, so you will have to add a manual -string output test, if that is how your test is "failing." - Hermetic tests -------------- diff --git a/cabal-testsuite/main/cabal-tests.hs b/cabal-testsuite/main/cabal-tests.hs index 517416a8773..4ffdadd4352 100644 --- a/cabal-testsuite/main/cabal-tests.hs +++ b/cabal-testsuite/main/cabal-tests.hs @@ -28,7 +28,7 @@ import qualified System.Clock as Clock import System.IO import System.FilePath import System.Exit -import System.Process (callProcess, showCommandForUser) +import System.Process (readProcessWithExitCode, showCommandForUser) import System.Directory import Distribution.Pretty import Data.Maybe @@ -238,7 +238,21 @@ main = do -- Simple runner (real_path, real_args) <- runTest (runnerCommand senv) path hPutStrLn stderr $ showCommandForUser real_path real_args - callProcess real_path real_args + -- If the test was reported flaky, the `runghc` call will exit + -- with exit code 1, and report `TestCodeFlaky` on the stderr output + -- + -- This seems to be the only way to catch this case. + -- + -- Sadly it means that stdout and stderr are not interleaved + -- directly anymore. + (e, out, err) <- readProcessWithExitCode real_path real_args "" + putStrLn "# STDOUT:" + putStrLn out + putStrLn "# STDERR:" + putStrLn err + if "TestCodeFlaky" `isInfixOf` err + then pure () + else throwIO e hPutStrLn stderr "OK" user_paths -> do -- Read out tests from filesystem @@ -263,6 +277,8 @@ main = do unexpected_fails_var <- newMVar [] unexpected_passes_var <- newMVar [] skipped_var <- newMVar [] + flaky_pass_var <- newMVar [] + flaky_fail_var <- newMVar [] chan <- newChan let logAll msg = writeChan chan (ServerLogMsg AllServers msg) @@ -315,7 +331,7 @@ main = do modifyMVar_ unexpected_fails_var $ \paths -> return (path:paths) - when (code == TestCodeUnexpectedOk) $ + when (isJust $ isTestCodeUnexpectedSuccess code) $ modifyMVar_ unexpected_passes_var $ \paths -> return (path:paths) @@ -323,6 +339,12 @@ main = do modifyMVar_ skipped_var $ \paths -> return (path:paths) + case isTestCodeFlaky code of + NotFlaky -> pure () + Flaky b _ -> + modifyMVar_ (if b then flaky_pass_var else flaky_fail_var) $ \paths -> + return (path:paths) + go server -- Start as many threads as requested by -j to spawn @@ -333,13 +355,17 @@ main = do unexpected_fails <- takeMVar unexpected_fails_var unexpected_passes <- takeMVar unexpected_passes_var skipped <- takeMVar skipped_var + flaky_passes <- takeMVar flaky_pass_var + flaky_fails <- takeMVar flaky_fail_var -- print summary let sl = show . length testSummary = sl all_tests ++ " tests, " ++ sl skipped ++ " skipped, " ++ sl unexpected_passes ++ " unexpected passes, " - ++ sl unexpected_fails ++ " unexpected fails." + ++ sl unexpected_fails ++ " unexpected fails, " + ++ sl flaky_passes ++ " flaky passes, " + ++ sl flaky_fails ++ " flaky fails." logAll testSummary -- print failed or unexpected ok diff --git a/cabal-testsuite/src/Test/Cabal/Monad.hs b/cabal-testsuite/src/Test/Cabal/Monad.hs index db685c45379..38534402d26 100644 --- a/cabal-testsuite/src/Test/Cabal/Monad.hs +++ b/cabal-testsuite/src/Test/Cabal/Monad.hs @@ -51,14 +51,19 @@ module Test.Cabal.Monad ( skipUnless, skipUnlessIO, -- * Known broken tests - expectedBroken, - unexpectedSuccess, + expectBroken, + expectBrokenIf, + expectBrokenUnless, + -- * Flaky tests + flaky, + flakyIf, -- * Arguments (TODO: move me) CommonArgs(..), renderCommonArgs, commonArgParser, -- * Version Constants cabalVersionLibrary, + ) where import Test.Cabal.Script @@ -78,10 +83,11 @@ import Distribution.Simple.Configure import qualified Distribution.Simple.Utils as U (cabalVersion) import Distribution.Text -import Test.Utils.TempTestDir (removeDirectoryRecursiveHack) +import Test.Utils.TempTestDir (removeDirectoryRecursiveHack, withTestDir') import Distribution.Verbosity import Distribution.Version +import Control.Concurrent.Async #if !MIN_VERSION_base(4,11,0) import Data.Monoid ((<>)) #endif @@ -178,9 +184,11 @@ testArgParser = TestArgs <*> argument str ( metavar "FILE") <*> commonArgParser +-- * skip tests + skipIO :: String -> IO () skipIO reason = do - putStrLn ("SKIP " ++ reason) + putStrLn $ "SKIP (" <> reason <> ")" E.throwIO (TestCodeSkip reason) skip :: String -> TestM () @@ -198,16 +206,67 @@ skipUnlessIO reason b = unless b (skipIO reason) skipUnless :: String -> Bool -> TestM () skipUnless reason b = unless b (skip reason) -expectedBroken :: Int -> TestM a -expectedBroken t = liftIO $ do - putStrLn "EXPECTED FAIL" - E.throwIO (TestCodeKnownFail t) - -unexpectedSuccess :: TestM a -unexpectedSuccess = liftIO $ do - putStrLn "UNEXPECTED OK" - E.throwIO TestCodeUnexpectedOk +-- * Broken tests +expectBroken :: IssueID -> TestM a -> TestM a +expectBroken ticket m = do + env <- getTestEnv + liftIO . withAsync (runReaderT m env) $ \a -> do + r <- waitCatch a + case r of + Left e -> do + putStrLn $ "This test is known broken, see #" ++ show ticket ++ ":" + print e + throwExpectedBroken ticket + Right _ -> do + throwUnexpectedSuccess ticket + +expectBrokenIf :: Bool -> IssueID -> TestM a -> TestM a +expectBrokenIf True ticket m = expectBroken ticket m +expectBrokenIf False _ m = m + +expectBrokenUnless :: Bool -> IssueID -> TestM a -> TestM a +expectBrokenUnless b = expectBrokenIf (not b) + +throwExpectedBroken :: IssueID -> IO a +throwExpectedBroken ticket = do + putStrLn $ "EXPECTED FAIL (#" <> show ticket <> ")" + E.throwIO (TestCodeKnownFail ticket) + +throwUnexpectedSuccess :: IssueID -> IO a +throwUnexpectedSuccess ticket = do + putStrLn $ "UNEXPECTED OK (#" <> show ticket <> ")" + E.throwIO (TestCodeUnexpectedOk ticket) + +-- * Flaky tests + +flaky :: IssueID -> TestM a -> TestM a +flaky ticket m = do + env <- getTestEnv + liftIO . withAsync (runReaderT m env) $ \a -> do + r <- waitCatch a + case r of + Left e -> do + putStrLn $ "This test is known flaky, and it failed, see #" ++ show ticket ++ ":" + print e + throwFlakyFail ticket + Right _ -> do + putStrLn $ "This test is known flaky, but it passed, see #" ++ show ticket ++ ":" + throwFlakyPass ticket + +flakyIf :: Bool -> IssueID -> TestM a -> TestM a +flakyIf True ticket m = flaky ticket m +flakyIf False _ m = m + +throwFlakyFail :: IssueID -> IO a +throwFlakyFail ticket = do + putStrLn $ "FLAKY FAIL (#" <> show ticket <> ")" + E.throwIO (TestCodeFlakyFailed ticket) + +throwFlakyPass :: IssueID -> IO a +throwFlakyPass ticket = do + putStrLn $ "FLAKY OK (#" <> show ticket <> ")" + E.throwIO (TestCodeFlakyPassed ticket) trySkip :: IO a -> IO (Either String a) trySkip m = fmap Right m `E.catch` \e -> case e of @@ -258,15 +317,10 @@ python3Program :: Program python3Program = simpleProgram "python3" -- | Run a test in the test monad according to program's arguments. -runTestM :: String -> TestM a -> IO a +runTestM :: String -> TestM () -> IO () runTestM mode m = - liftIO $ (canonicalizePath =<< getTemporaryDirectory) >>= \systemTmpDir -> - -- canonicalizePath: cabal-install is inconsistent w.r.t. looking through - -- symlinks. We canonicalize here to avoid such issues when the temporary - -- directory contains symlinks. See #9763. execParser (info testArgParser Data.Monoid.mempty) >>= \args -> - withTempDirectoryEx verbosity (defaultTempFileOptions { optKeepTempFiles = argKeepTmpFiles (testCommonArgs args) }) - systemTmpDir + withTestDir' verbosity (defaultTempFileOptions { optKeepTempFiles = argKeepTmpFiles (testCommonArgs args) }) "cabal-testsuite" $ \tmp_dir -> do let dist_dir = testArgDistDir args (script_dir0, script_filename) = splitFileName (testArgScriptPath args) @@ -368,11 +422,26 @@ runTestM mode m = testRecordUserMode = Nothing, testMaybeStoreDir = Nothing } - let go = do cleanup - r <- withSourceCopy m - check_expect (argAccept (testCommonArgs args)) - return r - runReaderT go env + runReaderT cleanup env + join $ E.catch (runReaderT + (do + withSourceCopy m + check_expect (argAccept (testCommonArgs args)) Nothing + ) + env + ) + (\(e :: TestCode) -> do + -- A test that resulted in unexpected success should check its output + -- because maybe it is the output the one that makes it fail! + case isTestCodeUnexpectedSuccess e of + Just t -> runReaderT (check_expect (argAccept (testCommonArgs args)) (Just (t, False))) env + Nothing -> + -- A test that is reported flaky but passed might fail because of the output + case isTestCodeFlaky e of + Flaky True t -> runReaderT (check_expect (argAccept (testCommonArgs args)) (Just (t, True))) env + _ -> E.throwIO e + ) + where verbosity = normal -- TODO: configurable @@ -388,13 +457,15 @@ runTestM mode m = liftIO $ writeFile (testUserCabalConfigFile env) $ unlines [ "with-compiler: " ++ ghc_path ] - check_expect accept = do + check_expect accept was_expected_to_fail = do env <- getTestEnv actual_raw <- liftIO $ readFileOrEmpty (testActualFile env) expect <- liftIO $ readFileOrEmpty (testExpectFile env) norm_env <- mkNormalizerEnv let actual = normalizeOutput norm_env actual_raw - when (words actual /= words expect) $ do + case (was_expected_to_fail, words actual /= words expect) of + -- normal test, output doesn't match + (Nothing, True) -> do -- First try whitespace insensitive diff let actual_fp = testNormalizedActualFile env expect_fp = testNormalizedExpectFile env @@ -406,7 +477,23 @@ runTestM mode m = if accept then do liftIO $ putStrLn "Accepting new output." liftIO $ writeFileNoCR (testExpectFile env) actual - else liftIO $ exitWith (ExitFailure 1) + pure (pure ()) + else pure (E.throwIO TestCodeFail) + -- normal test, output matches + (Nothing, False) -> pure (pure ()) + -- expected fail, output matches + (Just (t, was_flaky), False) -> pure (E.throwIO $ if was_flaky then TestCodeFlakyPassed t else TestCodeUnexpectedOk t) + -- expected fail, output doesn't match + (Just (t, was_flaky), True) -> do + -- First try whitespace insensitive diff + let actual_fp = testNormalizedActualFile env + expect_fp = testNormalizedExpectFile env + liftIO $ writeFile actual_fp actual + liftIO $ writeFile expect_fp expect + liftIO $ putStrLn "Actual output differs from expected:" + b <- diff ["-uw"] expect_fp actual_fp + unless b . void $ diff ["-u"] expect_fp actual_fp + pure (E.throwIO $ if was_flaky then TestCodeFlakyFailed t else TestCodeKnownFail t) readFileOrEmpty :: FilePath -> IO String readFileOrEmpty f = readFile f `E.catch` \e -> @@ -543,6 +630,7 @@ mkNormalizerEnv = do tmpDir <- liftIO $ getTemporaryDirectory canonicalizedTestTmpDir <- liftIO $ canonicalizePath (testTmpDir env) + canonicalizedGblDir <- liftIO $ canonicalizePath tmpDir -- 'cabal' is configured in the package-db, but doesn't specify how to find the program version -- Thus we find the program location, if it exists, and query for the program version for @@ -555,11 +643,6 @@ mkNormalizerEnv = do liftIO (findProgramVersion "--numeric-version" id (testVerbosity env) (programPath cabalProg)) return NormalizerEnv { - normalizerRoot - = (if buildOS == Windows - then joinDrive "\\" . dropDrive - else id) - $ addTrailingPathSeparator (testSourceDir env), normalizerTmpDir = (if buildOS == Windows then joinDrive "\\" . dropDrive @@ -575,6 +658,11 @@ mkNormalizerEnv = do then joinDrive "\\" . dropDrive else id) $ addTrailingPathSeparator tmpDir, + normalizerCanonicalGblTmpDir + = (if buildOS == Windows + then joinDrive "\\" . dropDrive + else id) + $ addTrailingPathSeparator canonicalizedGblDir, normalizerGhcVersion = compilerVersion (testCompiler env), normalizerGhcPath @@ -791,8 +879,11 @@ testUserCabalConfigFile :: TestEnv -> FilePath testUserCabalConfigFile env = testCabalDir env "config" -- | The file where the expected output of the test lives +-- +-- Pointing to the @testTmpDir@ allows us to modify the expected output if +-- needed, to adapt it to outcomes of previous steps in the test. testExpectFile :: TestEnv -> FilePath -testExpectFile env = testSourceDir env testName env <.> "out" +testExpectFile env = testTmpDir env testName env <.> "out" -- | Where we store the actual output testActualFile :: TestEnv -> FilePath diff --git a/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs b/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs index 3f4dcf5bc5a..33e1522526b 100644 --- a/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs +++ b/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs @@ -38,6 +38,7 @@ normalizeOutput nenv = -- string search-replace. Make sure we do this before backslash -- normalization! . resub (posixRegexEscape (normalizerGblTmpDir nenv) ++ "[a-z0-9\\.-]+") "" + . resub (posixRegexEscape (normalizerCanonicalGblTmpDir nenv) ++ "[a-z0-9\\.-]+") "" -- Munge away .exe suffix on filenames (Windows) . (if buildOS == Windows then resub "([A-Za-z0-9.-]+)\\.exe" "\\1" else id) -- tmp/src-[0-9]+ is tmp\src-[0-9]+ in Windows @@ -123,12 +124,21 @@ normalizeOutput nenv = "\"-package-id\",\"\"" data NormalizerEnv = NormalizerEnv - { normalizerRoot :: FilePath - , normalizerTmpDir :: FilePath + { normalizerTmpDir :: FilePath , normalizerCanonicalTmpDir :: FilePath -- ^ May differ from 'normalizerTmpDir', especially e.g. on macos, where -- `/var` is a symlink for `/private/var`. , normalizerGblTmpDir :: FilePath + -- ^ The global temp directory: @/tmp@ on Linux, @/var/folders/...@ on macos + -- and @\\msys64\\tmp@ on Windows. + -- + -- Note that on windows the actual path would be @C:\\msys64\\tmp@ but we + -- drop the @C:@ prefix because this path appears sometimes + -- twice in the same path in some tests, and the second time it doesn't have a @C:@, so + -- the logic fails to catch it. + , normalizerCanonicalGblTmpDir :: FilePath + -- ^ The canonical version of 'normalizerGblTmpDir', might differ in the same + -- way as above on macos , normalizerGhcVersion :: Version , normalizerGhcPath :: FilePath , normalizerKnownPackages :: [PackageId] diff --git a/cabal-testsuite/src/Test/Cabal/Prelude.hs b/cabal-testsuite/src/Test/Cabal/Prelude.hs index 7fa82cf8143..7a8fbf651e8 100644 --- a/cabal-testsuite/src/Test/Cabal/Prelude.hs +++ b/cabal-testsuite/src/Test/Cabal/Prelude.hs @@ -22,6 +22,7 @@ import Test.Cabal.Script import Test.Cabal.Run import Test.Cabal.Monad import Test.Cabal.Plan +import Test.Cabal.TestCode import Distribution.Compat.Time (calibrateMtimeChangeDelay) import Distribution.Simple.Compiler (PackageDBStackCWD, PackageDBCWD, PackageDBX(..)) @@ -49,7 +50,7 @@ import Distribution.Compat.Stack import Text.Regex.TDFA ((=~)) -import Control.Concurrent.Async (waitCatch, withAsync) +import Control.Concurrent.Async (withAsync) import qualified Data.Aeson as JSON import qualified Data.ByteString.Lazy as BSL import Control.Monad (unless, when, void, forM_, liftM2, liftM4) @@ -59,7 +60,7 @@ import qualified Crypto.Hash.SHA256 as SHA256 import qualified Data.ByteString.Base16 as Base16 import qualified Data.ByteString.Char8 as C import Data.List (isInfixOf, stripPrefix, isPrefixOf, intercalate) -import Data.Maybe (mapMaybe, fromMaybe) +import Data.Maybe (isJust, mapMaybe, fromMaybe) import System.Exit (ExitCode (..)) import System.FilePath import Control.Concurrent (threadDelay) @@ -68,6 +69,7 @@ import System.Directory import Control.Retry (exponentialBackoff, limitRetriesByCumulativeDelay) import Network.Wait (waitTcpVerbose) import System.Environment +import System.Process #ifndef mingw32_HOST_OS import Control.Monad.Catch ( bracket_ ) @@ -690,7 +692,12 @@ withRemoteRepo repoDir m = do -- wait for the python webserver to come up with a exponential -- backoff starting from 50ms, up to a maximum wait of 60s _ <- waitTcpVerbose putStrLn (limitRetriesByCumulativeDelay 60000000 $ exponentialBackoff 50000) "localhost" "8000" - runReaderT m (env { testHaveRepo = True })) + r <- runReaderT m (env { testHaveRepo = True }) + -- Windows fails to kill the python server when the function above + -- is complete, so we kill it directly via CMD. + when (buildOS == Windows) $ void $ createProcess_ "kill python" $ System.Process.shell "taskkill /F /IM python3.exe" + pure r + ) @@ -862,6 +869,9 @@ hasSharedLibraries = testCompilerWithArgs ["-dynamic"] skipIfNoSharedLibraries :: TestM () skipIfNoSharedLibraries = skipUnless "no shared libraries" =<< hasSharedLibraries +skipIfNoProfiledLibraries :: TestM () +skipIfNoProfiledLibraries = skipUnless "no profiled libraries" =<< hasProfiledLibraries + -- | Check if the GHC that is used for compiling package tests has -- a shared library of the cabal library under test in its database. -- @@ -936,6 +946,9 @@ skipIfJavaScript = skipIfIO "incompatible with the JavaScript backend" isJavaScr isWindows :: Bool isWindows = buildOS == Windows +isCI :: IO Bool +isCI = isJust <$> lookupEnv "CI" + isOSX :: Bool isOSX = buildOS == OSX @@ -953,6 +966,55 @@ skipIfWindows why = skipIfIO ("Windows " <> why) isWindows skipUnlessWindows :: IO () skipUnlessWindows = skipIfIO "Only interesting in Windows" (not isWindows) +skipIfOSX :: String -> IO () +skipIfOSX why = skipIfIO ("OSX " <> why) isOSX + +skipIfCI :: IssueID -> IO () +skipIfCI ticket = skipIfIO ("CI, see #" <> show ticket) =<< isCI + +skipIfCIAndWindows :: IssueID -> IO () +skipIfCIAndWindows ticket = skipIfIO ("Windows CI, see #" <> show ticket) . (isWindows &&) =<< isCI + +skipIfCIAndOSX :: IssueID -> IO () +skipIfCIAndOSX ticket = skipIfIO ("OSX CI, see #" <> show ticket) . (isOSX &&) =<< isCI + +expectBrokenIfWindows :: IssueID -> TestM a -> TestM a +expectBrokenIfWindows ticket = expectBrokenIf isWindows ticket + +expectBrokenIfWindowsCI :: IssueID -> TestM a -> TestM a +expectBrokenIfWindowsCI ticket m = do + ci <- liftIO isCI + expectBrokenIf (isWindows && ci) ticket m + +expectBrokenIfWindowsCIAndGhc :: String -> IssueID -> TestM a -> TestM a +expectBrokenIfWindowsCIAndGhc range ticket m = do + ghcVer <- isGhcVersion range + ci <- liftIO isCI + expectBrokenIf (isWindows && ghcVer && ci) ticket m + +expectBrokenIfWindowsAndGhc :: String -> IssueID -> TestM a -> TestM a +expectBrokenIfWindowsAndGhc range ticket m = do + ghcVer <- isGhcVersion range + expectBrokenIf (isWindows && ghcVer) ticket m + +expectBrokenIfOSXAndGhc :: String -> IssueID -> TestM a -> TestM a +expectBrokenIfOSXAndGhc range ticket m = do + ghcVer <- isGhcVersion range + expectBrokenIf (isOSX && ghcVer) ticket m + +expectBrokenIfGhc :: String -> IssueID -> TestM a -> TestM a +expectBrokenIfGhc range ticket m = do + ghcVer <- isGhcVersion range + expectBrokenIf ghcVer ticket m + +flakyIfCI :: IssueID -> TestM a -> TestM a +flakyIfCI ticket m = do + ci <- liftIO isCI + flakyIf ci ticket m + +flakyIfWindows :: IssueID -> TestM a -> TestM a +flakyIfWindows ticket m = flakyIf isWindows ticket m + getOpenFilesLimit :: TestM (Maybe Integer) #ifdef mingw32_HOST_OS -- No MS-specified limit, was determined experimentally on Windows 10 Pro x64, @@ -977,29 +1039,6 @@ getOpenFilesLimit = liftIO $ do hasNewBuildCompatBootCabal :: TestM Bool hasNewBuildCompatBootCabal = isGhcVersion ">= 7.9" ------------------------------------------------------------------------- --- * Broken tests - -expectBroken :: Int -> TestM a -> TestM a -expectBroken ticket m = do - env <- getTestEnv - liftIO . withAsync (runReaderT m env) $ \a -> do - r <- waitCatch a - case r of - Left e -> do - putStrLn $ "This test is known broken, see #" ++ show ticket ++ ":" - print e - runReaderT (expectedBroken ticket) env - Right _ -> do - runReaderT unexpectedSuccess env - -expectBrokenIf :: Bool -> Int -> TestM a -> TestM a -expectBrokenIf False _ m = m -expectBrokenIf True ticket m = expectBroken ticket m - -expectBrokenUnless :: Bool -> Int -> TestM a -> TestM a -expectBrokenUnless b = expectBrokenIf (not b) - -- * Programs git :: String -> [String] -> TestM () diff --git a/cabal-testsuite/src/Test/Cabal/TestCode.hs b/cabal-testsuite/src/Test/Cabal/TestCode.hs index 800269c89d4..fc24b216285 100644 --- a/cabal-testsuite/src/Test/Cabal/TestCode.hs +++ b/cabal-testsuite/src/Test/Cabal/TestCode.hs @@ -1,12 +1,19 @@ -{-# LANGUAGE CPP #-} +{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} + -- | Exception type like 'ExitCode' but with more information -- than just integer. module Test.Cabal.TestCode ( -- * TestCode TestCode (..), + FlakyStatus (..), + IssueID (..), displayTestCode, isTestCodeSkip, + isTestCodeFlaky, + isTestCodeUnexpectedSuccess, ) where import Control.Exception (Exception (..)) @@ -19,9 +26,11 @@ import Data.Typeable (Typeable) data TestCode = TestCodeOk | TestCodeSkip String - | TestCodeKnownFail Int - | TestCodeUnexpectedOk + | TestCodeKnownFail IssueID + | TestCodeUnexpectedOk IssueID | TestCodeFail + | TestCodeFlakyFailed IssueID + | TestCodeFlakyPassed IssueID deriving (Eq, Show, Read, Typeable) instance Exception TestCode @@ -29,12 +38,32 @@ instance Exception TestCode displayException = displayTestCode displayTestCode :: TestCode -> String -displayTestCode TestCodeOk = "OK" -displayTestCode (TestCodeSkip msg) = "SKIP " ++ msg -displayTestCode (TestCodeKnownFail t) = "OK (known failure, see #" <> show t <> ")" -displayTestCode TestCodeUnexpectedOk = "FAIL (unexpected success)" -displayTestCode TestCodeFail = "FAIL" +displayTestCode TestCodeOk = "OK" +displayTestCode (TestCodeSkip msg) = "SKIP " ++ msg +displayTestCode (TestCodeKnownFail t) = "OK (known failure, see #" <> show t <> ")" +displayTestCode (TestCodeUnexpectedOk t) = "FAIL (unexpected success, see #" <> show t <> ")" +displayTestCode TestCodeFail = "FAIL" +displayTestCode (TestCodeFlakyFailed t) = "FLAKY (FAIL, see #" <> show t <> ")" +displayTestCode (TestCodeFlakyPassed t) = "FLAKY (OK, see #" <> show t <> ")" isTestCodeSkip :: TestCode -> Bool isTestCodeSkip (TestCodeSkip _) = True isTestCodeSkip _ = False + +type TestPassed = Bool + +newtype IssueID = IssueID Int + deriving newtype (Eq, Typeable, Num, Show, Read) + +data FlakyStatus + = NotFlaky + | Flaky TestPassed IssueID + +isTestCodeFlaky :: TestCode -> FlakyStatus +isTestCodeFlaky (TestCodeFlakyPassed t) = Flaky True t +isTestCodeFlaky (TestCodeFlakyFailed t) = Flaky False t +isTestCodeFlaky _ = NotFlaky + +isTestCodeUnexpectedSuccess :: TestCode -> Maybe IssueID +isTestCodeUnexpectedSuccess (TestCodeUnexpectedOk t) = Just t +isTestCodeUnexpectedSuccess _ = Nothing From 5fada300c71b2d98db3d24957f57708a78e34165 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Wed, 31 Jul 2024 17:25:34 +0200 Subject: [PATCH 114/207] Enable symlink creation on tests on Windows --- cabal-testsuite/src/Test/Cabal/Prelude.hs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/cabal-testsuite/src/Test/Cabal/Prelude.hs b/cabal-testsuite/src/Test/Cabal/Prelude.hs index 7a8fbf651e8..50f9395d74a 100644 --- a/cabal-testsuite/src/Test/Cabal/Prelude.hs +++ b/cabal-testsuite/src/Test/Cabal/Prelude.hs @@ -54,6 +54,7 @@ import Control.Concurrent.Async (withAsync) import qualified Data.Aeson as JSON import qualified Data.ByteString.Lazy as BSL import Control.Monad (unless, when, void, forM_, liftM2, liftM4) +import Control.Monad.Catch ( bracket_ ) import Control.Monad.Trans.Reader (withReaderT, runReaderT) import Control.Monad.IO.Class (MonadIO (..)) import qualified Crypto.Hash.SHA256 as SHA256 @@ -70,10 +71,9 @@ import Control.Retry (exponentialBackoff, limitRetriesByCumulativeDelay) import Network.Wait (waitTcpVerbose) import System.Environment import System.Process +import System.IO #ifndef mingw32_HOST_OS -import Control.Monad.Catch ( bracket_ ) -import System.Posix.Files ( createSymbolicLink ) import System.Posix.Resource #endif @@ -1123,19 +1123,20 @@ withDelay m = do Just _ -> m -- | Create a symlink for the duration of the provided action. If the symlink --- already exists, it is deleted. Does not work on Windows. +-- already exists, it is deleted. withSymlink :: FilePath -> FilePath -> TestM a -> TestM a -#ifdef mingw32_HOST_OS +#if defined(mingw32_HOST_OS) && !MIN_VERSION_directory(1,3,1) withSymlink _oldpath _newpath _act = - error "PackageTests.PackageTester.withSymlink: does not work on Windows!" + error "Test.Cabal.Prelude.withSymlink: does not work on Windows with directory <1.3.1!" #else withSymlink oldpath newpath0 act = do + liftIO $ hPutStrLn stderr $ "Symlinking " <> oldpath <> " <== " <> newpath0 env <- getTestEnv let newpath = testCurrentDir env newpath0 symlinkExists <- liftIO $ doesFileExist newpath when symlinkExists $ liftIO $ removeFile newpath - bracket_ (liftIO $ createSymbolicLink oldpath newpath) - (liftIO $ removeFile newpath) act + bracket_ (liftIO $ createFileLink oldpath newpath) + (liftIO $ pure ()) act #endif writeSourceFile :: FilePath -> String -> TestM () From 0b0546b75df1dabaec80d123fdd8175bdf5fe5ec Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Wed, 31 Jul 2024 18:36:10 +0200 Subject: [PATCH 115/207] Add shims on tests --- .../GhcPkgGuess/SameDirectory/ghc-pkg.exe | Bin 0 -> 115712 bytes .../GhcPkgGuess/SameDirectory/ghc-pkg.shim | 2 ++ .../GhcPkgGuess/SameDirectory/ghc.exe | Bin 0 -> 115712 bytes .../GhcPkgGuess/SameDirectory/ghc.shim | 2 ++ .../GhcPkgGuess/SameDirectory/setup.test.hs | 14 ++++++++++++-- .../SameDirectoryGhcVersion/ghc-7.10.exe | Bin 0 -> 115712 bytes .../SameDirectoryGhcVersion/ghc-7.10.shim | 2 ++ .../ghc-pkg-ghc-7.10.exe | Bin 0 -> 115712 bytes .../ghc-pkg-ghc-7.10.shim | 2 ++ .../SameDirectoryGhcVersion/setup.test.hs | 14 ++++++++++++-- .../SameDirectoryVersion/ghc-7.10.exe | Bin 0 -> 115712 bytes .../SameDirectoryVersion/ghc-7.10.shim | 2 ++ .../SameDirectoryVersion/ghc-pkg-7.10.exe | Bin 0 -> 115712 bytes .../SameDirectoryVersion/ghc-pkg-7.10.shim | 2 ++ .../SameDirectoryVersion/setup.test.hs | 14 ++++++++++++-- .../GhcPkgGuess/Symlink/bin/ghc-pkg.exe | Bin 0 -> 115712 bytes .../GhcPkgGuess/Symlink/bin/ghc-pkg.shim | 2 ++ .../GhcPkgGuess/Symlink/bin/ghc.exe | Bin 0 -> 115712 bytes .../GhcPkgGuess/Symlink/bin/ghc.shim | 2 ++ .../GhcPkgGuess/Symlink/setup.test.hs | 18 +++++++++++++++--- .../SymlinkGhcVersion/bin/ghc-7.10.exe | Bin 0 -> 115712 bytes .../SymlinkGhcVersion/bin/ghc-7.10.shim | 2 ++ .../SymlinkGhcVersion/bin/ghc-pkg-7.10.exe | Bin 0 -> 115712 bytes .../SymlinkGhcVersion/bin/ghc-pkg-7.10.shim | 2 ++ .../SymlinkGhcVersion/setup.test.hs | 18 +++++++++++++++--- .../SymlinkVersion/bin/ghc-7.10.exe | Bin 0 -> 115712 bytes .../SymlinkVersion/bin/ghc-7.10.shim | 2 ++ .../SymlinkVersion/bin/ghc-pkg-ghc-7.10.exe | Bin 0 -> 115712 bytes .../SymlinkVersion/bin/ghc-pkg-ghc-7.10.shim | 2 ++ .../GhcPkgGuess/SymlinkVersion/setup.test.hs | 18 +++++++++++++++--- 30 files changed, 105 insertions(+), 15 deletions(-) create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc-pkg.exe create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc-pkg.shim create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc.exe create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc.shim create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-7.10.exe create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-7.10.shim create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-pkg-ghc-7.10.exe create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-pkg-ghc-7.10.shim create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-7.10.exe create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-7.10.shim create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-pkg-7.10.exe create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-pkg-7.10.shim create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc-pkg.exe create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc-pkg.shim create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc.exe create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc.shim create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-7.10.exe create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-7.10.shim create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-pkg-7.10.exe create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-pkg-7.10.shim create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-7.10.exe create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-7.10.shim create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-pkg-ghc-7.10.exe create mode 100644 cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-pkg-ghc-7.10.shim diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc-pkg.exe b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc-pkg.exe new file mode 100644 index 0000000000000000000000000000000000000000..537023174dc7a094f693b3d9ef17fa234e6a4bf8 GIT binary patch literal 115712 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 M@bv#5|6v9G1`gwa{r~^~ literal 0 HcmV?d00001 diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc-pkg.shim b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc-pkg.shim new file mode 100644 index 00000000000..0ec39dd3f09 --- /dev/null +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc-pkg.shim @@ -0,0 +1,2 @@ +path = "FINDSH\sh.exe" +args = "ghc-pkg" diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc.exe b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc.exe new file mode 100644 index 0000000000000000000000000000000000000000..537023174dc7a094f693b3d9ef17fa234e6a4bf8 GIT binary patch literal 115712 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 M@bv#5|6v9G1`gwa{r~^~ literal 0 HcmV?d00001 diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc.shim b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc.shim new file mode 100644 index 00000000000..97596f1c171 --- /dev/null +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc.shim @@ -0,0 +1,2 @@ +path = "FINDSH\sh.exe" +args = "ghc" diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/setup.test.hs index 86a7cf804ea..805f56abc9c 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/setup.test.hs @@ -1,9 +1,19 @@ import Test.Cabal.Prelude +import System.Directory -main = setupAndCabalTest $ expectBrokenIfWindows 10179 $ do +main = setupAndCabalTest $ do + when isWindows $ do + sh <- fmap takeDirectory <$> liftIO (findExecutable "sh") + case sh of + Nothing -> skip "no sh" + Just sh' -> do + let sh'' = concatMap (\c -> case c of + '\\' -> "\\\\\\\\" + x -> [x]) sh' + void $ shell "sed" [ "-i", "-e", "s/FINDSH/" <> sh'' <> "/g", "ghc.shim", "ghc-pkg.shim"] env <- getTestEnv let cwd = testCurrentDir env ghc_path <- programPathM ghcProgram r <- withEnv [("WITH_GHC", Just ghc_path)] - . fails $ setup' "configure" ["-w", cwd "ghc"] + . fails $ setup' "configure" ["-w", cwd if isWindows then "ghc.exe" else "ghc" ] assertOutputContains "is version 9999999" r diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-7.10.exe b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-7.10.exe new file mode 100644 index 0000000000000000000000000000000000000000..537023174dc7a094f693b3d9ef17fa234e6a4bf8 GIT binary patch literal 115712 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 M@bv#5|6v9G1`gwa{r~^~ literal 0 HcmV?d00001 diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-7.10.shim b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-7.10.shim new file mode 100644 index 00000000000..16ae1ddead3 --- /dev/null +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-7.10.shim @@ -0,0 +1,2 @@ +path = "FINDSH\sh.exe" +args = "ghc-7.10" diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-pkg-ghc-7.10.exe b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-pkg-ghc-7.10.exe new file mode 100644 index 0000000000000000000000000000000000000000..537023174dc7a094f693b3d9ef17fa234e6a4bf8 GIT binary patch literal 115712 zcmeFaeSB2awKsm|C6h@qVFpMbN|XVDVgni&(8LKk0Vau-;DpFbA|_}HX&kLmI43|$ zAn8doC&y{I&$WHpr}kbc+G=er)s`1+=_J9tAoAL)Sg6Kcsym)kqtIl)nDczsJ~K(M z?Y+I9-{mJzb-ni+JuWY*itL`t~|M0_)i0&_KaBq?xc0cg2d&ON9 z?yo+we#4FF>8Uw!&_i!b-Sp!AhFOWfAD`RdK7j8ZpWEur;qPtkr||CU*y{e@{JqV+ zhrf65_m9tQckjpdi~G0F>c{*2j&1Ij_cDJ(lx?jlOTN8h@E{k-Y)zF5J%LYuvrjnc+tPan@1Ay@XsRnns`RaO9l9Q>_w5n zllx3UArJk7N1sV>qg>$&CL#MDWTEIvr28hO1J6=I^&kAZQQWXqM4G$^nFudxYaH)H z5w{@RcjKn@_lx%n!jy**OKsnXcRt<|{`o+V8;xwjz!W4zk)De8vwxE>dgG=I4?Xf_ zfwxIO+XTx0;@{+3hS>lA-~R^`IB?=rkZM5on?9O~J&Ec$0_3j*N zFchBc+;3i2>+P22Irrab4x1}$TYAN!@Vzy)-eZ!*rzO>TkBf_(`yI=CNRj%rxoVFm zN?~!vcrIJ5e90}Qjb&q{>uNgH6**R!31XJaOyX2}Op=*JOrem~6V)t$(_s}ND{>rx zu#iBP`GBc>*wuO9Oo;Fp5OarU2rDadGJ*m1 zExhNKtNqHoIoWzlxCNmqz`hOORaM<9ax#cz`=?{Xgf~}( z>uQz9SNs70tHKXZkYHCO;=*6$L5ho5{isk_YDGDxoQ|ibH|#@3YagXH=g_O}_oyMH95zf>m~BOB8t2$~#h*I$M5C!Gcu|XUp>l1=%8WaTRq_cw?=+ebs1c zWLvDt`JJdG=G<=!-(Tx(mkKLu3yRIs4nVMq(w1-?ecPmmBPFJ=Il!L1Sr9^zRg+X! zzJ|?5o8-e8%Jv+WX?sq#R#rt2mZPY7lT=6$z9KCNZ#E#zk3*=9Ljb~y%L9yoY`{Mc zaC`vdwsa#QTLs99I5FZxc-I{#fAl%SqDpK`6h z2-}X*~nK>v06sDsQ^8sWYJ`v2* zGu;Sj52{NtDCUi&=g~4}%S)&|T(~X-K)x{8_yf!cpjkHRpsp?im-~Fkqdb(e65+}u zgd^7Fpgh%Gi28hJHVqN|jX>RebfxwH%8S%fVN;#z@}V0GIZ9Gy-7cf6|AM&`T^;?D zx;m^I=w%@jKxPGu&uqdHc&kfX9AAXz>u=zhp}(Qctf;%!0QDmSlmt*f85m}vSA=zI z*b5#o5c-ilgFprQcRba{a|R%SkPjGU)Ksta9A&dXg{H$KtU8$&MUNuMVTlqF4*FwN z4ql>jjXD4^m$`zFk?d$T0(B`?A*yGVA_zjP#H*U}H4Wro(1oY#nE^zhFOtIMs@HGW zv$wZMP||-!&&+4(dCk-GT=En>mp+MS?c&b5? zMe$Po!k%C8w{_0}yd!@5p2PIra&AP|yORWjP58f?68HS3r%32d+KVS4-ktO-gos?- zNzr&HY^{7SDs(p<#y2P<7~g6-$#7+5QVieieS(@U#J}rKpc`1N3fW0iB&d-6 zIVz}S_W!r3a2{0npS2xGDy`IfqiIRJXRjs@h)lgeoZ3oX!QL-n9r?e=uxf5r|c`7(*z)Ztx*E8$orDJ-Q5pHYs`R z42TErtZ9ylo6r7CSLQUG$ge@C;yv_Iw29scMcon*#_eI@?XU_ZuJtN+~YqpxA&?=AAS zJDYDp6zaG`NvFs<5i+B$5)YOEG^jb^nEDc4HM^_-V-bth3_ zVlXYK?Jd-%OXt|{@Lk19fTTL;(F<-9X9U@FibE@1>dm3BIiw!L7zG&p4K|nOL$0Yo z_OXGzXxDFM3vVMRH=r6d#tz($R~~yFuTT(5SKcreF6b!-$OE_!HlLM}*qNmu0+FGL zs;i3QuXbrm)UpB9g#P#UVe-5clBcSwQ{BMW>!=;Y7d1A#F91L*03=HJ`_!_*^-4M# zCseJgS=&p!(SQLIWUnBbF7>f3cpqhZP+7kSNXAX`FDIen1{XzZI`^7tXpqYdc0o$+O8PzWn%F90vlpGzFv+?o zTHVQ9EBHrhSYQVcU#0c$HF3Gvxb#0zL=dg?9aJTI%aE8PkD8<}v9~x6ir2LaNwe$D zAQ#)b3`J41v+g{7t~Wl#+(l6>Pwv%~bjqcqpX1Ly{-lgbI^)j)JiC&pJ`>Qc?hGff zn?SjvVS8QQF9B~gx`LSXK-oQ{exVUQL8{(eh*uL<-9CYqrqarTX<(Atg4Qfbz76y~ zNNKt4fpWGTeZV>QdU+FnGO0d zOwtTmVipprhR;-SIpw$W&Y;pg7;i@OnNl7p4`j$2E@BqBC~t_-oOU0Is{WYAe^K#| z=$ZH8b0GyPjX=adfJ}GuOoNfK5s!bs;~(*~_jVdnMlkfdRqy#;IRs>NtVFCW$E54n z6QmUOc#liT2k%0nHVLt*>60-9xA(cydK4~ehfl7(+Nq0wMORw5MJo48>A*? zu1A&N$Id!h=i_0*NMvuJnGl}|S%%>&9PNM+C59rM?5R&sZK+kZ=P0FC_C6s&UuJv( zenFB0l{ue?b{^@>k17{(9yi{`z?xUQd3zKh3Ml$KpQ^;yDXCNMz>P^8=cY$o`&+y66Q46*bpJ+lr3 z3=5G;efVs||E%JV87;W_Ec$u0)6jDw{ut?Z$O)12SaLu zUA?90wl8n~YM(S$-r=%HGu7gZrS7DEy-K`h=`4CpTRNLw&ZUCy`zF!8j^r8EqUs*-E*Xvl0fb>}OL2GtJ@R!?H5e)H#Fh-B()qt{r=~7Jf zkHlpH(ceF~eh-!7B6hBwP?iUB4Zg@!bvn3Bayx|U1r26}olx%odLPuj*8AT)2 z=M)RjQ8ruCy3_nI<%@Qu!XYgOl(~bq>&~T7n@JGoEWOWW7R2nO8|js~G+?s`;v_`k zm5fM>AWc@6I)J%++@$b;W-}txvh(5ON~LV1z<+W3O`hHf)uK*Rrmd#V0FVE%t;QZ#d5ZnKspai0bmO(xmYMWZa17h4q7&XtTLNTg}aO}NeJi5@0&NLt2Vjc8mYG` z$&sB_L|HaZzTn(3N$$5t>g~18H=L23_Tet54}!SC`SN=fr~E5~Yn_j*x)`aysOkvS zxa9skyo=pat>^+j!)?W;))G@Z z1~jI0Bd)F3+*)Ezb{-g=a>9vM?98y70)t-#q*k;xAEWTd}3J#4-Ul{(U80Mjj*X zina`Q(@+qdcdWXL+GKo69~(nzQ(e=CjYw|#h@R*!8~#?g@Cdr`sL8{l)`!Q#0X*vO z!(+$B3(lR%_`3_)c7~8`=Q?ED`4wc_`3SP@+=6U7cW!LzCz!+SjnFluU1m)D*ejBz+vG zie`a4QM=?m7#E!_|A~sh8t?9G{~%ecjXa%$Z-Mi-jkul0S&#;04Tj^+Wc=Ml3>rcd z+Jg96A07_}@Tk8Jj~yG4@D;?NeRym^9NHJz*9fSQ-_i33RbOSLnzm`;!(!yv&*r3+R4{m@w^N?=G{hjZVG9J~4^ z1hBQG*V$YM27MrE!aw5IN8dpO2B$c`sUkc<+Wr*SSk=p&V52d zxN~x{-0hOzAIv>&fT&-YXo}H*T_7V7pJd3+5;r~a=;5OW5xV3)dTcaEoM0#D(z^7j zHZ~V*zHO{d;<0S-9&u-hOYU}quMoF+V7PrIa1*~2+3xHcOON9}+)kojoYb0J0`ePQ z(kH|1m|z6a4)#OO5C_JHE!~M0@cxC$QDT+5?U)pdbO(LnKp7TfcT}UwM=h`Zq3+Ps#)5~ zboEpD(^09nxmUbVa|0tFBxutK)U|aSkC(w`y80R`MByMbJ$3;R@?pE`zX+W`{WDhI zetT0s*KzZ)Y+GFfQr}cZZ+2#~39A?@7K1a?B^09`3!AW7OV}_}X^=yL%H&W_u!E5N zs^3wt)gewXDhDt3unr@dDpx8UY%}VIRe}n>q26If;*Mzl&y5!KM0k#}*hS@|rKV)*jn&Hb* z?I`V1P37uF`?yi(?<}XWLetkcsyplgZ-he-7hSoqn8g=ho!;F=v2a_r3Uy&i~`tTn3x<>htv z%^zD6B=*7}an>tyiES`k^3+N@a?kf%rEYY{qodB|VoJC>XR&;FRJ40PaXv~5ipb*n z$h|MQ)HJ2kA%DXPy)6nRt23c`i~;s9=+T1+^N*+T(Z3tX>%UD}EBGmkRy9Xajdi%l zYD3fk$}4(Mzg;c0dwN)wMmD9oEPbOx-{{geX0RIp0ISDpo(IiR%m=^&!UP?5O)ylU z!kpwe>pA5a^62`>wHV0b8PpHdkJWaV$S$BZo~;)db^X2gFh}ozWMN@-UD5)dP_Acg z#bOeeCP1uFAIh<>E+?x$dx{UCM5pd1gWl5B*Z2f+=6W@qj8|Yrwec_l-Xi;^ByW+m zJ}I0IyF0gR7@Rt3X$DkfF&UdNGr(Sa(TG(t*0;{)U5n5(d8r$6M3*cuI#ghzhVPXu zp*YwDe@bKOOqKkpE>3SbE78scPhw;N;5J#S=d89Y7@mg~&p`$1AYzBaDZzL?>K2}F zisx)aJZ=|{)2!;-o}nO%!O@|r1{H57La3c z8TGXGXAIoklo9#FNdbd9(|My{ChCMirV!;kLt&xrDX2vuwh92a(L~JDlkP^E+?6GF zXUU^ko6f?PWq@52#g1@LT|((-ko&=|tWe}Y4!(eDD^S(bdC`xupqWV8IL*Cbl+&W!A|zp05?QEi#pXoSPM&xK9XZ0X`U*Lgp=#Csxc9;@Zv%|RX;>o6{6gQ zrn(^C#|0XS)Ku$pcL5l12-dBjQib%O5P0iLd|x2$9Pc`tsquK%mq&+b`Rc z#Rt@Gx$pJ|d-7H5cU;F2y~3VF!z_g~8%)?za(A%{&D7cH%;WBY+NVD@7-$1}t$(HGm;dx+y7RjSn{N8Mm48eOCqk2<6?`V!vE-Nf5- zc^j+Zu)(NC_C{nU_y+SDam_p~oK@$hdAss2K#;7=SIaObi&wKhVLs~?ra^kJs}Y26 zM;)bXe@||331T15^?^rM8qO2TN6@}1rC|hWog(#l&MsG~&v~mI;tWbW4x4M0bAMFv zpIJ)&YtoHg$u6dOqP2<*BOD;&(>%Kl)v4W|pSqDv?lJ?e97`2@muq`q!y>rzsnU3> z%CP5AE@lL=@nGg#37ojq{Xaubhh23( zqN#NN%uPc=%3%LGUhK7noSYk={=(AuXV2N%f|=smwFTEo>FlAgY}z@fq5EeUzGsq&6&K}^@{v)Nw>PHnbO6=YA)9-G=t5)pK}kLY&v15P)z1*m4S z%JKSl!6ky~FGT&+*FjWnXXOM!!!F}_(45*rDrAt|Ozc4<8Dp=1L=sT3kG+irHuf?d zb&Z5WDR3Zw7(&?Vdx6pjDzt0%U8p-(fSvyLDBa-@REZW9C@yo*@E=VTecAa9=VhJa>R?1K_H*PN-zPm~7)RA)}N$xMtF0 zn#@wf$#O$Ry69~4y9&Q7+6y-uyK}UW2O*_?98wQ);5Pu-7G1Jhx-_!|eQ30$f^tMw z`BdIuq?^@CY?LH@wY}65Q+6y?kE_9XEvI%`Th5Akkvny@({oB$HE&pQG~Ns&#inRqk~P_ULM>k0>e5#&R#z?7Ud_Fv?8w)P7n4RvR3@n=4>8SO9l6k7NCm*UgY{uc4x79-Jy}iGY_d}a8o|7;CCmF(5d*+SL3I zdwLB#5L%vuQ;=G0t%^h*M+l=ci6~`@M4qMu0Xt|s1IBHnWfy`0$QnHlMhWg~8R5wR z_5>J`&0dBa!n|a**8ufQ`TX9zG!MR9=m|o7(+ZNdGle&$@s~RTXwO)UI`& z*K62|eJ%1-Z+%U&l&X4LYQ$%1 zwMSN)koOZTvp526W%fu>U*SDlrZ^9^%ginJ?NlAFJ_)@|Gkbc$PZ4Vm#aUnd9^z8dSD8)N8Tp4E9iA z?SjxQ4X486q5{($7#o_PVp2dpn z1e961mKFn?zevbLzC{Cy{Uw!;=oy}~1vM^b3tRvM_H)3CPnCbZflpOfUn@2FN=DF^v8VY@|@vuK2r{#aRHmDockp zMq-e9s!nJG-_ws#d5Vklw6$Ix}g>UL>Gyf=NH2SZe{`&w5mgp|avfPn{S z#W76b7;?pr7Oaii7Jea8K2JEos5R{FF?3(m2{nI3fu3Q)4|iHAx~Q0YKPJ;b-tr%Ux~eLXVWy_;u4FX-Z_78L1$b01*Anco*I*Wg=~{Z3XR41h_GxsPG~2`a)5>x^Rn_UifusAri>; zq|HNs6dr9R0z?*V8gIcvlAT%*wrb|ErBW%HKgJrc5vU(~&W0? z*bh(~Wg!!ev33wv_6pmtQH$N!*g=u;tf*1lM^wQssQacH$;WG+} zrNl%Qf5+!zyBtf~@&)I<#uG)@e$8q54PM+{THSd79f<|@0dy?AXf#!0gTK0S*K^49 z1N{96e|zz_AAf?$ELbf3XphAZR3W(-A_I!p))6cTZ&aapofWUw>*v!95zyDWh%G!p2Kq5tBX9#!Dqqk`kP!b|h7U-6A`D0rfbm zxS;D0)=mWT5L`e>D5^e2IvVCvv)Zi`FGf?af0I$67RAV~q=?jR{|Fl;M=QR7QF~w} zHLLH?ki{NGy`8sDub&qv2jnLKnJPPm`~mnHRRq}dJHZykZu#(hu;*IpWqHRuLBdKB zMHjOO95Jh^s8wHq#3_-cb8Y}1kL7qCi~w~jxEP{sfs_hb_?9XB>jB8BJ3xzvQF4`J zmuua_UBwGGN4{=qOI-%Be<}CPy{2_aFrUvUpk*lDDMS*ZUtR{HU`X^xVZ0YBjCMNr z`$mkG0#WsNfPMNgHK{lsO(%RBP1b%_OBV}73K zFxGHgraZkE1BPpOc4Pf9VKg%L9h|i@*eUlI?NSkhL|j26?}IvDMa$+~dR)WBwo7JK z>6lua^?mGwhOlr#P)XJ%)#6=?KvG+AR%d@&uA3Jb^t4sa93BP9ge`KrvyAPi4I`#|U9U5Sm(mZH1*PVTm)T zzPKF@CTNqq)hbA2p~%pohWYIQ_Dl)Q#~6=rd>UJ{$pfzO6&qj4H|{7D#CxgBb_CTO zi#=yCh@AW3bz~+lw?NnicT~uS!2lDM@UaBst}pNpinD22i4^0+h&0Ia7;_8kQo?d? zO}?~Wn@MV-cGXzE`g}tPBw;cY*|097j`6&{mR)rM3$w&PgZK7W(=y^s!{Q!`XotyE zjm3X;KS~?RXfjBs)fwu^pt5F!HZCLw`}Va+#MhwWfhB}CYHgO+uuOrNRLU-T-x62D zVBm7@v#3V`>=)=`2;1whPFG2|rm_GPFUwF&a{d=2H;@e9&J>BwRDc(Wz1Q8x|0X;VH=>vt;xW) zH`xsQ7m-te2O&%eYX&jT!;>BIDwFNMW{e{~%0^%GU@eQC-1i~9l`^LId(aJv|7gU2 zPVt{Wmnr_=!$la@;E1203wxBZ^LXK}OlRA{NpUMib^q4@*jNLAV`10i)Wuw~5Ajv; zT)WAoE*O$yN!z~;V=FeY8yxbVW`^CBxgEoQm~m>(3Ge02X7$a8W0BhB{a8$Ggb+yb z;k4V3+LL?Cd&Jpt0&sIL!&Bt_K1=M?k3Z`5c8gPA{i|qt^|LplAbqmj?uKLXU(j$E zx@?UF08r%Zk%n@Qy&Bun|1T&m$4uKdjaTmsyZ+hgr8P#?gU(Q|C5D=(IbEh&r`TTW zOjPbdeTuU{Uo84FioBnQldxw|U@|Ch1Qa;d zAEpWP1as0!Orc+n}xU@n4POfBiWA&SqNK^ENn} zZ#T&8Jt7VEWAk07R!rpEf4UXYgNYWP2jsp%OFK1Siqi!rrm?;tpC{l-Z2S+}(9ib* z;|v{HybNbmCX)LYh<4VO0e0fr zan42htNI$ba>0>CP`BAzbZ0Z%mjzi*lCTw}RM~y~F(RLCf*#nT_iIGLVk?v>;0&{= zyv>Ruy2KcfWjT?+Lz+#g#P*s4{=GwLjr{<`K(xTLr9`}~sUU)|cvDlsx9II|D)=_N zCpQ%Uuc+E7ed$0Gz-W~R9;H|L0UDLsod>>2ujL1t=~dWN@W0|f{xuE+hfX<=U*ioR z*Bn4Cn6wX|5$2dd#yVk^2~?Mmjk@2_k-c$GR#Zyb#O20R*cif`PU`-d|9zu~zBNMlS~C zPtDlm`xM(3Y##Pw!qaMSa_)X?U#eaGmqC&c+jbWYk6DrT&u3Y#_= z1(#fW9g2^C5Gr{R<_IZC?SkJ}r0gPg4$5IqR2nXphe83i7tqM{>LOX6=u8>yU%UAP z{{rd@JJu=r+9E?c83};M5$mG?cw7y#dX$9H4=kl=h%em}Lyg#?8{RWQfp@e!X~t}b z1%k|03b<$BL~s^*w?C#`r>==%)1;%|RuRTfYf(Wy4hnQD=>&mRS??&B1Ov-spn#3o zSdje-h15<`Y~yP|s1hJs7IvCkA$g8~!O_i~=E2`+v|Y)QqhNQ(qF(s5HQqj3N^kDn zI~xa;O7N{M(JgQ)NNP)NwH3D|m$dpvorj_Uc1JmCL21W?9uMig*+BmATYD-a6j0M*{Jdl}u=wZYkk*8UvsJfc=X} zc9uCnXW(m*XF;9=)i}**SC4P$-M+a1LIwFer-mh$w`cPgoWCe@wZCUpyM|AA+v{gU ztdnq7o9)N|3xTEBDFncla5*s>2lHrSr@DUxTZy~RpsUf4*#$}G5E8Q(x*8E;3R?&M zMv9GRfdvAtOOzSsY7hp;iz~5wn2tW?V^M+uLtkBEJ^-+F15uP)NbajhB~-w-6yD%58W`Ev$gQVvs!#+aR~vNh zf*n}}bk2}WI4iCSn=05(QA@ljw~*UWMG$8ATc`;8H{_+9QSq9JAX`^Khtkg=J9*cl z^8s7>F<3q|$T|>P1r`GSMh}oNBC^8@n;v{0;*x%iy^4-24a3=Ld_xS9kj@((R`5xU(q8`dBdFd_`}lXR zCL+f7@xK5TNjOV@xR5wk9JQsbWxjh~O@+w8^(g{&69N0Uap@r1DL7lci-It%A7uD^ z%;Y%>v#e_43%2>{Qa;xm$DFu(0LjpwCwpS2kAqRhv98O)^n+cIm`O^j%R!iZ8J6#{ zW5c$BENOCGE4&)(w&D?|a@{V9c$^}h;be!Nf{f{1NrV-QIQA|)uWSx{i*fuEG$6A- zJc;?y<7`;w4gU8;n;Puod5pu3apsT*vdGs*n!<8%BorbOUL$t)7>ZX#{0(rVU!kxmI3%e#vK?q|&1hRnU41Oq}UUM-hJXgnP?&O@x~t7~Ui zo=D{T1|EQq61<)04h1SldkyedLBavV7>JiscajacZsnIqUg?>?K^mB7POxr0VlYb^ z9(W}2;C(Vt%cz0zNT6mR3;FlOg*JF)4|NzkQgCw$M8{u1WDH08B%$(l{FAdZV$6hF zuMwG0mw1PB_j6~hplbJw0Uj!PP@Umuczrc91 zP^}zR*9zASChf+*i8E_g=j^0>+LU;jBc6Zq4FYux`Szh2?ONPpCiTOoeAJUBG( zWRdW@eDY_I&Nq$D$CsFa3jxyLTxGcjnX1SK&8ofo&j^h91Qm14L2{SyJr>``ghdGV zWMFi_%rQ1V$i$5SLav($je+%EhjD;)&|p}oRKG=j14Hd*3`?JUSr4I<6k`&Vc0>MWo>8VUA{9Uj1p4&h ziJ*Tt5%gj(;r|TukEyuPRFGb62jwyK;6|W4S}l^{JHB#JuZ4tGcUV1V)Ox!o<{3PF z{PeNYuX#st1`@UAUf}*(?W1Pz;1;NBk-|LKNiAXbI`8PFYr@u01zT82$_DLnWP^CH z%)!u#A)FJoVuD8cX@3QrYNRJ3DmBo6q6Rj zcafFl@eiO!pLS>#7DJ_oGapX+SEz4=ly60ylHWT09OZ^ z5GEge_8?{tyvajq2|rH6oS0XF>_39^ycaAMWUVmr2iYyy-o!c+M*B|8R$n{{0LC~d zuUm|&$jo{-sIb>W4Wm;Ch-6>F27|sN2SLw}Vnp4=qeyfrJb~TDBLqkTWeG*I1&9DM zDN87h>f>_~DQLKiL$wV$+wD?j=yyU#kpN+uie1c4NxM;QGt|?%*q2DL!GqOvk0_%& zoi7rn#Qn8#Da{{oB!SKtP00QWo;@)Kaua;hySTPOpVLmYKi4-hI3niIgwJQ}-^WEb zbD(;|HsGhd<}U5(a%>$TUkclcJc>%mVu+>NhZX1=ARL;B|)7%ekMl zS#QIUJ7`-;*tnBEUI#gn)|$#HDEn;fxMxT^%}UYbklpt1H1)utK2Nko_HTc zI2os0!lt@RLGZy(|2fPf&|whrW53kEZpd%9N||_?#B4lqGO`IS-h$9rpHB3~2bgc? zmJ5d8CwH@)7b$}V&u%qyubWw_lmU9&D36-A{rK5OD5;&K+p29$};}8VkR- zo%?7bBG&ln0uoKoH)C2-2Uv!1-7R+iFQDY?OUht#T^^_r_m=rUtlU#Oz<6qPhv*CU39VUgYn`F zaS~iZTYhqZfQ`h)@dWapnBek-ZKoiHOCD)K3t>GlHmcH88}_LJbI^(};DSQa4hN0h z)$F?%uUaPNGV--0J-hvj|CeC#3UsMYQO|SJX1Rr;p zX?x;5+}i2fpOQPaZ__j|5BTvZ#zT&*IG&-0j78Y(=#;8(AkxwYa}eF?at9h!XIwdx zhpwfln-OJXz&Ssq(Tp z@#!JRj$v04oqL12_g+vGgrBKPS;k>4gJs4I&zLvCF-T5Ws*%mJgrGq`fus28_yHx1 z_9JXE*ym`%mb44#qjcvLGB^n`7X{W;?5?x-;N;vSW~lr5&)Ge zcJ>ow#`y4V zJAXklr8K=*%V00TO9vEn2iXQ%>>!vK4BPc3Pho+nXCCIgCBCJlvmXEn;~2xZ6_d^x zi3>1Nv09Ip=rQ^?3rF-&07uyP8Os3sPtXfXFCbrct`54w8G29%ip^DgT5xsNU8KkX zdQb=_;dHbZYDs6^;s+2ppB@wnXRtpfQdUyr3VKio6X|R56fVT#XAk>-gh+K}#QMX0 zFo2qeLAVQ4N#nY%j5Mu5&Hmwi>jA|$hFCG-Kp{Gp&WX|)#3fP`;W1>^k8rd0?fWcpmr*)7H~4r1YbyU7k>;+7-Q!Vkv`QpvFL1B1GJiTgu=D97-Z%N)OF1TJD{g+f1KSi3qAoT}WT#%e2IB(_ zc^VBd>?c9?7s%DB$1KpDuHv#O?8debHib?f_i%&PV_vRzCpfZhJrVgndQd2w&F<$t zOiQF8aWc37C)qE@*8^{018Xj}x8lZ2?1Rv>GDw^_K1Av6FJD5{WTPZeD980W&U#{W z=ID}Jm$E-M!pAE3d>S49fN2K2gmxZ9J5hIz;dKzKa}e5Adhp|!7H)1!oL6*m+{Xap zj3u4T9Jjj$>oTY$hry3%;sPq(9HZ%UW7~vA(Y#3KJL#OJp+(naQ*jQ1AJa@?*Z=p$ z>8xhFcn%fkF!)hT8zaG-KpuxJiKOEvErGY4BS7ah;}GT(1P+ED*POzBd?kec_PA!^ zcutUgjl}%_<8C756y0>fpmU;|*o_I`py`#Z(zwm?+pw!+M-dG?NYvC23@YTb)bcBkQ2L`UhS#ZP_i zWgo)mO6R&oi|#+4$SjYY{v6Bq+-2nBUvkb~p;&t|VWPr@1uWR-KW_&HMk--M7VSnt zwfZG=ji1cp-7xJK#vCY8^|)mQaceO$xTd%WW@XwJokaF+Lii*DzOdON(*?>zxF*9A zjU7H4&dkVmJ%P!8WnKRY)!7-IU-uN@auTz+fy=+&8mF4dkGJwOzme=mq1h|a@4Xkq zyJ)kZProI=$eo>Ic#9gct9N0`CeqNSG#rNGky3V4S#tt+o55{~`x~9Z%KI?>&cNB| zeRi3~6WoPh*!$@}gKGuhWK59qfSWEugsp&|0wR-MA7AvJhe0n4g93v!0iI5`7G6P5*jVa80g)Uk_vpNS8qlrwC&VHShOwUh#tNr!@5jYAP} zxe6lXSPIRO4eK^!81~y~2AX(G56d+u0ywDtHHSKFm)gOzmkf18#bs&%&U59);7NAB z9h+D?7KU(hPbWLf*e*j|QA&7}ux#0tx zkoe!AB{nPvTFx3qs-WtLEXT1$%;*OMH=IQVx0~ro@dpZ^al2pysqzl)Kn%91Ftt=+ zzfrZ*YHWpkX;i$u?e3Y@p$?OH^H7IfO2Y*ezei0N$8&IY`M3;Q`Xz2l_m5aIBK%0W zpe)O3TQSqxx@;aml^FY$-cjkN@m(z#;XUwa9Vukhp^szj^zlKehH*HNTn12P2)1z|_K$iNUsj-pBp z&ZmQO0MDo0Ajd3H4uW>=T8ii{&H`a|E>Dm@Rka@I_VMHEC9;mg2q7fW79>ozQ5vxB zUqB;GW*^^-UiHvjzt{k)V6*e_i9U9+Frcv+DD;vEiHSi5n}pDY710$NZk=t_?*r6_ z1PVQgLzL>HL_MG}DZu{EE#S)^(>Ejy30>?s2%G*mCaL)eP`WSzXS?WV@GErm8yiWr zA$CtfI_2SF3nM%#=7iWXgwe(Aqc(O6kM6s@il5{EHC1D2*UV~X7XQ)Z*m4hm-T z%D^;LRJY}=#&5v$`RkscP%$GLHGz;)574ps{%<0GtN$W<7xw`;_my3&l?zLShPfej z&Va8=Q{iHJ5k4wkz#y*Tg|xfE=2rh-Yl4PDN-V(k!)S_iF~Ln|Bhcf!1=b zaD1!;=N!!2r^wM!rNpi}o%>B#ohnW(ImDj27huOXVypYViQeTx0OAPUoymU2;Y|ZP zb{?i?3~vldpKDh_YOS%ioI?_L9j^#(;AU2P(q6+g%c*cK zs~*9eFmwXUd=-qll#P`BPo(j(Y3Sd`UU4pM#ag&s_?2idE?1$6Djcne4pd!lfN2%GN-yPseC{PUPCchhbV zgf5)1)t*{!r{u6)Mi?Ox9<|Q>?Q-mX(JjX|iBs?kB3qm-77WyGn+Yp#&DmW{9$12w z(rrsYKnYqcmw$;3$#80`UvE1DucEftJp_&J-XXS@V-;IAh_ITtoy`a6o2B9MO$fd` znPrJ{aywusW>#m*zX2Nd3A5!%F72kKNsY+*OH==&cm-KD5YV>nH!bSbwqo4Ez3N%S zRB0PfK$9oAUoy45rq#&oZm~>elSChZzlkckR%SLFg(vv80e+Cda4Tr&tAC^Sb=dL- zEHZ^^FB)M7g?}7m=aE~p1=(-$t_r8#)7Aq%9zFxZP@mZngJV)l7I?WCx*c3N!|qC0 z`?}4w1<7Kpnd}X4GEH{2(2BIH*ly}Sg+SO+_c*li5c>&T)ImM!Z22kT_fG z(g7#l8Gl9Z$d~X_BD7HD;Ae`la8lh99L&SUG><`>+Jv2As}N4rZY3WFo*K9^)hysZ zTs9W0dwJ@jvD92DYZAhfDkF|$NDB1?F+_Ug4j^G7j`%BLT2A%fgx0cMACau#vY`ie zx~+rFJFz>1>)e8{3d8P;@w<~RG9nFd{(0t^XBrz~;BYZi*9cnDNqsu@Nmtwi*wB~J zu)`T>Ljn0*B}HkNMd6Wu5xk5T4Bb+C^TCNHMsNlOa~X#12+kAYi#&l6I#`)qH9hO2 zvu@R$a*t2J;f#dTDzm>#7xv=-M2C@{)^TOBYI;tHlKMr3(`nawV!Gc!KIc3Q8W~(O z_L`dRu#&!(sNnDAxZjHH3=*H*s>*Xnb74V5c{LR~!cvy}?&w|gJZQBtareG{(HO)w3&mVpti>O2JRCL_7J;s5s?FPsuepl zt9FwDL7v1ZLyg}<%i!E2>t-o?$af!>c(4P`K=!Z+#!qDJcT$_~k z83rUM3v4Yl9@^piT(x{NUv+TpuxrKSd1TIX1leb}r;XghNY5M7gbgb7ZOKcR?MB{7 znC)Jmr3|J8nC-@la1+dS=K=2XW;;wV{5*(5abYaMK5tegCnh^`h;@~htA{a&`PhV) z6p1OA={mU`9z%^YGWrfTOwi3Y&So;;snssh$tNM$c)K8Fq7oAQ4t#rhYZZIH86h%D zMal-*TFg#ZH8pLu_kRYSomH2CF2;pyFyL&w53r1jq@2q0AbI~DJmdq<;z?j>?^d)q z_a)cDd1k1%zZKEc*@y|S*Vj=efEvqG=_21+xWQXv-F`hTfXCUG??iEwhz==+!YMd} z#2&s5RUzNuEJ&U-WZaYo$5TQ4f?99YJc%-%Au0uIi*c1*ioVg#Zbmty&?MIU0nwNA zE)0W4@{365ICqy`giwD38DTq%lrc8& z3XyvNdU&b5=@KXTd_GQM0q1^yMj)iX1A5VY)G7zyniY#2v+lT^{RD8-JniO!y+nQK zUMQ9s2gxRj-Q)BHq94LZu zfr{PRnvA;s&}{)<2-+!32f%{-t1&ZVgy1&3D?wFFfcz3V z>7RofBM1o*L3%ZQA|||CDJA8)TiA;;i3ljIwAqM2RXC~JS4uR&N3Bx&5P!99LUr(N zz=!7 zFM*^Dv>t9YUhqD8gI^dKpQY`PZz={0AuOhrGY2vdzWT;OCKzFTV;=kKdq&T1T+BX5 z1oPQDiQqi;`$TX)>rDiG>`)@Og1rT}GaH&hZH~`r%}}hU zspIZ0Fi_D?48*fwaY(yX99D}H+f z5_Ae_1GKSMyb`zak(;r66Jkg(!M2f@$ad$U5SaG3xEBpjL)kK~F zUev4rsesd8w;s*IlIAOzL=4|?X*$0plOVCF$W_6fMOu{>4e3jG+Ca1yWk|r{2m>aDPB!{S?!NI4$l6X!_7BPWC!|g!tBWw@F8LG5`Wxh` zVC5XwF|z)I7oAAf?;vKJtVIU4GYo7$M^=NVb@EOheq9Q@x+l&E#wEkFIzW%51eguu zs!G$~<}}7C=>hfvad$cuF&v<tIi0j8?EYVAyo3l zoHZ`B8;%W4e9w)1DhfI6qa(T;24yXQzQLKsbXgGngZ)}y)b6GZO`!r)G|J*`VL|I*a> zuBi>SE`A1nOp}1l09_)xMc;-C2gqgL5h?4z4qK~@{Rj37A|+`Be%F=^_R70p(%Crj z#4h5Z`u=^GO6Y9!7p?f&im4#nT%zMrdPq3MF&~@d*r5wRWsC2>2P@e3sSNG|nFnED z@3IN~UqeKALy$cUgt=NarLD}}_^~PaZc<}=pw-^xv*3J6|DDK&4fCFz>7f3J&BKU1}~YpY44~ax__4gS`M85lCwf=T%DAw%XL?RyA!d z@75k%dr@{#n}ounD6Cn!Yzy&YDw|ALD8To?3PPo;{-a~patW<(Ie*v7&Vh}>c~!NRc67NME2y_v zux*2%BPknj{_Kbq)<#(7+WW0AMBK$sUSpDq!9ud_XTS>Yt)-xBpnP=&y9WaZD`NQd zED7gDiuJW^_Qp%KIL~&eSW0TmD%Czh=Xm|+#HqN~4%%ti`NsBJHS=hDt6j5<`f!)u zj;SF~1!j%mr?}X$45JSG;EQo04wos$+Wh)27t_6b0Z`6@*05~gj{|^1z!FY)=<3|E zi!+8I0W&DQH5Hfq^=`7hl&hrdQ1TFtnU19>k);U3&RXJ?XpY5k_`ia>ZhGCvv5Y|TS< z%A8y>mi1c7n!0H^vZf;I*N}DXF3M=+!YzNTPWpk1SYyNQg_^abhW8{C&u*xl@kNUR zBOn`_5^$+Cd;M9Puz5ol48YIxVgTbgWc&`Vwie`v+t%SM^+Z9Li)0P%U6LCvE`a-X zZVxQ*L(YFk0NsUxs{^F1mwS4R4DIn`%W+FPex@l%J&6^DnADXlXxPr4ha&LnF*dkK z-wo04&61vrn;a8(LZikN0_aAJeOe02(UbzeV@oERiuue?Y*%9bz_oKIg8`XC%PQ+$ zU2j|C25U6q6r5U?4NP<(ik}db3kY>fC#rQ+F#2T}WW?L@jWRS{=G~k$L z2K}xon$?g!p|5o^f=%e_NmuqYNJ}!4dKtsQ(oM7kACwa{y8_I2_jvc(aL*Nd7L4vi zrLJJSV{tqCSjS@hOP8XKv^VCH>Gp6l&y zz-1z_hSWA&F`Z^?Eyk_m7_y&~s=d68-2XCQ z2FB(eW~(${6Lxgr7k+y?n|r}KVtSWpK~a}Upi>^EJ4s0hhMfBvvf#f1V7fePvf$T_ zz3SqYD6FuNVw{#7iDQ>5jd(wq5nXQSv~=r6`s#A_jnjk!KbQ&!#PLIqYu`%nIS_*9 z&vlS(@Z<uhNkT@=|Pmo=})&qD)yLBmT<4MzC^2Y2xzn~aamz~xE z+ooB#GUgiY_sQ+yNOU4`XX^I%3v8Ql4rdXpT#1`1%gagX!K5TjW4UOYVa-^7hU8rT zBCs5tJ*z(t{YVhsChY3ZK$_!9U3s(!+Xth5tYb!tMLV2m< zW~hi(e0}&`3tX*)RryWmnu1E}PRDkfx!Y{(^2bb?rL`KSKNzN6=>AwaOX19s(f=z5 z=r|-7E}OMN6U6Va%kR3=UaJ)GJ0*GY=>0o$#Z>vjB6ur*Xw_zul7tZkQ0_4u2{7$! zJt(HFmp|MfF2im5B770&<9D6^PR34fi{>Rbe*EY~Z7;uKYil znIw~BV1m4b7bTjYXw;$s1qUPu0aT(1k%UwOwyV*NcK;S;z*Yi@lV~Q7Q)&OQtE;rO z>aP9kZfzCB7bKI=B!C41RD*yD}F*j&|RAR~f!jUl(>}dD`gKJ&S4HA082;Bnw(3;;iBGUFR*!VEhtS2QwThv~0 zuSoONK4ftEn(Q9YLr>O93Fn1w83tHF@D^uqF!$t4!ckmx8OcE~)?AW``*Hb+{MWz< zs0|jb5GFaUw~+E;f{)ueKih8EM!C_jbQOT!MO`5-q2XlC>=)x5Q_bSkS6a?pA(OstVC5uOHU)aOG_)G zCCDEEu-q`jB6j`}=7GFWwf>pvsb2mXwg}M3Ztq<8a<{;*J!|Ha8C~Iyu5iWkSQ^X2 z_x8NtT(+BdOZ0eADiHr7IV^gNupS^=rmYu+A?4yNEh3cKe6uI-kT~KyI^Y zWUb6`)n`P+LKa(UbRntrN?l?mt%}!rh_3Zav(^Q&^yAh351pC++T!AP#dR*%d^?xz zd!_BC_)FW9Vy%hO6xOob=|Qbzs@|g)bb4%2+~v%wGBmWX1Aj3poB0bdXGaqmgr`pA*CL>4aR%Yzx$5@6U{rM&1qU#6D?gpnYV;br zNFP24qORixu_D_MTnJa*`(9QLB&^lgV*u~V9?}!D*DvUqC7jAW_NN;t29Ll8jfKa^ z417(b`==ME%Qn+jZ26)EJXBxb^l4OE3f9n|uzny<0Cyn}bP9M1K&?1y+-|&=^S*HA zHmZa|)D5~+`wbc;U||pM^s>m^FjB|~J22%fQYSH9V1J-lOR1DWVsJRzw8iNt;4p=` zNFQ1IUlx%QR$>#4qs8i3`X3q80ptCgCW^g?T&4eMaUOIMKPoTVX$+y8LcyWcfn10+m3ss%uZx*^_TFmq|VK|-{1J_m>&Odt>A@iSG6$N ztaWV&&rZ2b^75Z9i=@F=(a_$&ET^+ny-IMI+@MBkbEBp5PX*dz6|U)ilIhZKIiO7s z^u3EKxb}I75ngw*8WN^`&o^?~9loK{uJd_{O4Xk=A=W;4KQVN)hJ^aMmxw;?I@r^> z3Eno}&;!IsCrh9{qle?enQpql9+I0=he#8kmJ2`UC46YMbwE%0b6VJ6J zV;Y0&9^fG>9Mq0&gLU=11=l^u-}-gp1y`*h&%#ihBr7ac|D-u7cPR8S?{bCC*c4%Q zq5a{q0}elc@Qzstf0hwlFO8G>%{J?2bZB%KqfWwc;FaSFpRfl*A_xtxdrbdbqyLKg z+~7J94F=bVPu==;;zw6&;7}Fm1AZg{KOOR;lJ#DiE;W+cNCwqYuJjK9avRf^%c@UY z=}(-p$nMKDD-~TY?L;-_|MA1j4%Suk!2G^riY^KOmGzQ``d}9W8>*Ama;q`Clhz4! zEMOb7nxU(2q+=+V(-iKrGb)qreedx+{7-|j5pp&Zsxf!#)e{+O<$a!&_bT!>birjt z2bp(}dG#jgblYO7fDDW(lL{CpXPpL`{B||6CN2?1wvBUO4vc%W;Q!d0awRmi(B*Th zLZ)NxZkm&D!?$j;nuKbCR#6SMiMW4ospC5-qGir7TTF|)6o6;gHIy-3p*iR*7AkJ! zgx*0iQv2 zOcjk|C=tj$EC?IMD%aFiPM;_%E)^`jiz}U#PSvqPvkpn>a#~^}nH80-9p7K5B1YPC zt`A4;^c;6=_?vPsicBs>@;-J(F(#0Xu~yR%6uP;I+v%-Tw?p{?OI7QHW{2U ztm;9cR9;kuW=1$R)PilA+c;$=vVeMVeqcF5Fgv5B`|`7?TfQq466>RTMPaT8k}y#( z8vl?Oo74F&4Ppcr3L(r-54><#rhG88mme&nvD+llrPk)(Ka8jdC@X@(2<1W#RjS*x~QFOAv6R2J|EF1OJ;o3}M16w~X$JsriAtF6+0a97q&wO| zIp#{*DX6(#7Z`1OxP|0jafPp$#O!lF=(^60=zoaV^4&)G5!`3GzY-#*kX>@}$ zy;v>3M;2@zN!VW{W`CS}u zgEA#Zj-U31?e&i(Ne@cnwnV1K+Ppnf^sCSfXa|m3ky<@}@Tm0A%uE~uogB3ScM^lE z=Z(t5=LE^=o57NNrg!JkcV#QmXspIh2kb>0A+@cNtPf$)AEz$JQ8bf$%(!tLuKq;F zTo|*`doyX0QU{397ub$&x`1r^)8Eis^zwN}UoiUM(~bo$!G(hi4VQP`qy91KV4J9E zj9}1=qor!bR@RE8wpNXyv_Daed|TEzd+|J$SH{hvzmi__puU;LMDc-nDoxU~ijlAl z{I>jbIJ%M@R5~b8bLfULBR8m{_C%9nYTO*QY?1%K%@O%sEBWCt?;L%E zW_3##wzPWsG+FolX|0KJ3nv-3CJLRJ@JD$Pf|j|3`Zur@YmfqFapgB^2=f^V+ma}$ zQJce}j|cVd9}5w7(QfetD*ADlW1PJf-CAh!5Pb%Wo@f}o!VsV^yi<-Pho?R{u>~4x?a*BUPR#I>kkj|^d zax_Ooxk_kBiP}%8U2`Z;0FcnXHy6LpuSpWf#IQF{Jt__3WQ@34+0Cr{Z&p`*Nt!Qx z7n)4uXwQar&juHWv#b>7Oz*bk$8nD$H!&ZD=8S&h3>B(&x$=Zw^|FH1tylsvzaEi# zVK_3ktAZYyI$cPtr|uPEBMj9J9|lw;-K@xc`G>J?>P zY#1VBXk^VvAzaIbHat3kXs+2KM&01qFf+lsYx#dckbs{B^*aAB<_%~V91cXCOE(tN zLL?`ovZ+_JY{_ZX51SkWG@v-InM77gDhzvQfgRl}R7de-?fO(V&iL4 zfZ*~t1wcds_JB4c`4RgG49rk<#UEpb@ro^sd`m=h&A1K$%g66t>Ji5BSJk@b;RddO z_Y*_uLG0DS!A1Qks+(k$BO-31FB_^plsBynG}6q@0SHrE;sHC%H4I1wJ*w%Sxjo!~ zs3yO!p98DHjLKB!H0}UpHgF42f2Mu~_s|hRkmltp56~U8;)x9oA(8e7~zFKvv$8PnGtnBtQXM#$ltB2WT|%_ z_3q!K(U!%orUKB+3rm27{jt3Q)b6mo!rSWqi$LavhTVkmJ>UHwFUFh6604`h`ZqfK zG+7xvru|QedYO80$Tm7kb3SZ8MTAmyNE4@Q^Q3-Fp$fjolQ}_YKhgODkCc$y zQ!At#`2%Xcg?8^Q&%^KVUISf;&hTj8?3GR~Oa95stWSMkXD04Rq^@#;q8d88;2rf& z-51i2t3$UW#BN`XR3?Px*bAj9n*oZkpdRP2h~X)?>v+SYFOB|1Y>wbM<-2A&+OX8o z;*6|teVLdMT*--7i=YRqd&mSX#ncZiQEj}Ip*mg2uQd&}M@!Z3C0LvR$0b$|Z;lCo ziXeL+9QzXy&~ov!)o7jS@ugtgIy1oT(OZJ#PY^kWkcCy-3d6(QMq#n>A+o8stSe_5 zP2(zvIj#itkNY~{`R4Qz4Y7RtMxgiGasU%EMu&2fO=V@I(MAkVE^ogwNG%%l9D<7&_Wa1)X3@5x=Ui#DrTq`{Scc|9MC{&$JU^_WJN6RgB zK1EP3tbp>=BzhP6wI3-k^NNkqI2yS*^oWg#?(Ol-E~p1 zEyt!Zs74oLnDPGfT^vZ1PRlbs3V)JRtaeDB z;XkS`3CG;h;Fi1z3FH|&Dy$(#5h|W-@foU@i4rX61nh9iqM-i(4jS$}j@K9eX!b-| zPV(X#!i!YiDCi`bqbKs`9Dj$=@>J!NvfdNn&yqrul1=lI9f6N$+_yF6iMd70Pb{y@ z!8=?T#)n;%ke9h#8T>WMWvFYQ1J+QRCwNRp?y<%Z!eN||aReE&gFH1lAPf5kQs)quPg2;=5o-0D@lpH%kLD;2;9hW6 zctT8EW}6??t?~GgS#?_?5Mqt@E%oKYB`q#tTJ1(JVOK3c0{P+! zS`Ig83avy$cZn`D8*U?=BaB$ExPh(}f)CdDc&boVUDYF&FdU^#kTs(@a)dOE1>whWX zd_Hf&;+miI^&x0Nel!GiA=29eKhZWiMW3< zzEZ905Bvp>l1w+J(U&h7=NXU4K6HghPH+!M4C9d}c-~yipPbf0Rjz|%iOAcnIycEc z&E}CKL3D#|-&%soDw7t4e)%jU566SWk{IzB?Caa=rS_Jvr^^UluMoM+2= zqVxLaQp&)i}0nG=hb{<)O$*XB~{IddsBaQ0mKJ}r})BH_#wX7P9TGZJ^>>HRlc z8-*U6Z)kAiI&B%m0UNt|a2uWK&SNB#YnSL`)9hn9^TlhYw@=2QS z5@8yg{!PS8`qo{_nx1BM#bjd&C?42lM6M`-VSQXCBIp0FO4YmYLxI(9Tbch*O;p>; zd{C+c;;t+LQea$$B>9oum^jW_`ZABY=MTacxTzg%!VPkrQHljyTCw_75p6J_E4fj? z*wWFRZzRO>6EfU;X4#OOUQ`4z>12~$CNtKp4~PKT4Nr%%)HOaQ0Bume=D>J)63AJ7 zYLH`AmCIY@_7!o^x`5&a8`~{tt38~mP&9FAWPSeluEd+s#etU7fmPTo4%M-NS?!Ns z7Wk5DTqjbNgBUKHWmq8XMe*Es0T-*{>Qd76yQv|a7Y}}i#bakb>3Z&YY8so{>LR*D zo8gRv(D&nKiS;I@-8}lH(VQ)LGFxh3_%sZYP2B>$H80{OYbaxQ#c{clCGR~u&N&!- z`_Lg1#HNZR3z>=4lJ|HkZ>9nlX`6CXFk_Gae2=XNIl1CU9oN>Z?kW zTx21_X0Bha(zipW@r%=mKttnEi{H`cwIynlkOl@G4+WFpek^Q(`%#aMbc7ysi65KK zf>j3scki{Kl92}V?M*$TXejtBaCe8TCI3_EdD>>o5U5f^>oCfc&>(hub`lH4Eo`_^ zW~|Tul)JVci_P*8rXQzTDw`(wvQ9AP@;lKi2^Q=P-09?#KTo;1^Wl0DXLsrwxj@Qu z2^}OJUoX0E&}T2o@8Lsv7p#B#UmQvr%WNuKLUdG%#3oU&(AO8L+<2syLRFokqc4Ou5N4O%;== zQLqcdgxtn+k7;y}WO$oo$glHPF>=VxVT6kVo#}7c?3ihXI~}FR!!Dmat@(J^=}Xjj z0&+XZlS^Ri6XYo!7fd#Wus1B$Q$%ht+Be&{rOJBWHx92~BfNWjX&@609b~%`{>nYb zmd6hXGvz`S-2Ww6+ZNw0z6NXwz6||qC&4!V5RJT`(HlTv$g7UyD=@uF4pyDse+Ws* z)XCy7(DT^CB*!rMG{UiV5UQ!ki!*$edS2g^^4Te*&_OdU+DSv$fXo9VZj>9?Bcx0>m9==3|&wi)3i zk!cme%QYSk&+uIZa!OW9xYH>;2P!+h=cMp9-lg<5`|+?8-(qzq^^K|M2D;Oq-dEK} zWBNR=w*@{<_#5SeDx5$Cl4`a}i;GJYrcq{D1q{!=ADyNVr)5N_Q{dBt@TX=c?l3!XhuMic>2sSooov;HAah~CG=MWU+QXka1BVifCRsK~ ztXa?NJjPa%U8Nd~Y3aH7%#kf==~|pF(UGx-j)vIh3mi zhGsPeA!x`7z;(nY@_@s}2jNpL&jt)cljII-+Po?(H|xuLD(&?PkJJ}@y(p5#`@){w z#`=OId6fxh#a7^y6^C`G*cG8OAZFc%#g*2d+4V5Ap~KiKhfc}wmP2J{+}0*C5;TWn zSZ`EUb!+5>&X@t5K4*?7i|_w%iMi3YKB2mBnNQ_389nW1Di=m4{pG=WwC<6~H_&V? zllKk%Nn&VmG~&Qy&UD>rD4>-Nt{BT{hiIWDpvP1Y3nr;!y#BqgG@4yAq!K2(1|4SHG%U>^^;|r|2y%h{H5|u;+2x@OQY%; zqLVljTFD#?=07Hedha^LP%pSng7Sjp)sV~sq5Q{KP#X(X{%D!x>A(VbY6aUYvJem% z&pY)}*O~Bv_;r0;;KNpcw-EdpN6~~*Lz6%=YkLp9G>hrrBlI!zvMZ6a}z(-LJip-L*Pc&E&xPYHjOdUI~ z>T(pe={P-3SCOMQBH2i%Y(yGKkLcRxOG#DlMlvcBN_Eqo9`JDjA5jxUBkAy5F5GDU zM#dd|7Jt3^>?6q}ll(=)2uV4>-2Zs-JxonqD2=4_0;>{+AtJS68*+;_2l` zA!&~A;haSEvqxPyi^wX{Zm>oQIvUD9v6fE#9SK)jkJa-Nu5iwYylRn;{1>N`w+T&s zJ0_?@Bh~*Rtew%9`zJ8Wpm=I$ah!~r5-|;|hrW<7NBQY2!u-?TzGX8!uaCp_AYa%b zpwuP=<~Z$vQ>p&pm4j|CR%2t~=}~ZY=eU4%^H!Z+x;=tRv|)5PmPKL{U>(!$VSrbYbmCXF`%HUoXB{y~9RE_>ymB^ANz11%^+;c<*bdy@9OZ}o$2Wex@~ zqKIE7-4yr~Jj3s5sC*pQP$`&(KKh*vy&Ca;tf3jw(5VD`YYfx-$B_L*uQZup#u;-A zhXw1T5XUwMU&tK7myDC%c28i7tkv}r6sjvcK|RhayU_ExhuMp5zCWdM(Dy5X>8Q4W z_r>2(L7z9gbiX+6xpyI~Y$zmipePiQq&eaCzCt5h$T!hnQsw)ZxNN!*qdG-2rg>5B ze*R9TheF+iv?z%k>fp< zBvS(}Po@Uf{qz_&*p0%Oj9z5c0z|qDwf2_`OQuad%dg2(biGOkV6|2MfB7|U7d?ST zrBgoSk~jvMC)c3nU9Wk4_m3s&L2iS}0PGJ|9oC|X*i~?+j=|O7w0Ifn0<&20g2IIY zmP3dJg&7mkN&FfXWq%vU0GHBbM%CdG^{y1qtPa6{NtM6g*Sc38FG1q5_Us#5Emp$# zjm5*AjCpYd1;c}n_}2bCdj?XPO!ads!)J7cqCl(mKBF`2dR#UgK>6TIgjZ{v0;Gj8 zOmim)pc?M5Us{bXXT16VnrDQ2fj#xT!qN8lZ2N>vpGW*LR&sFcouN0(5_O(j4p+ASim8pR(^-Lq#UR+JhE_h%M9&HL~B-@l;H$ghq02_Oh`K+`I10wHjK%?-=m zV<1MG8>BxawuN+r{2igH!)zAZR>7v<&2fNPd|74UViYb$s$zQ28kxyF1}ApCaz>P3 z6L~4?dY)$-`$$U)`mCiXQzVamoH5#Wz8a>JkEIRj_|vpI)7JF>X>#(rMPS;0l#&6( zh_%FR*abux$k}BjYV?cI=w^Xa)_BHa1ju*>@#iq!i~PH{}r@s7{E0>O={rXrTiZsWh|xuH)6Qh2#b@T|8$oZmER`G4O$to7>#^LG{YGhSzj9IzJ6@h}o z+@1WULe?aLLs9-zE%YMS3Io?z2E7c^eD1e@MHkZRVqIaAkTK(p>;hyTt7p-^Mt9R22&TgxT|(GOpTyfd$pJ=o;5U2aI4SIWafQ) zX!hx$N$}L}ij7e#4+F=jR1(Wt)MIp``4%6esk~cbbfy0EzZ@e-_JA>B{hm8U&}zJH z4XFqpVwiSTq_s0>QG_4c@N4#ZN+8d5CV&7-;E*Dj-#LWX58dgq>EVeFVtLoUou(b8 zf}eIzCXZ}XXd-G;B{)yFzUT71J~DK}W-&r>1e!8Eujj&vgyvWQEty7BpxK_&;!ojr zJ5jXjclL`c7$Z&m-hzW${RBPV;1shRaU+E?#N)FV-q=li zV7mB(wfQd*U^4Zvy(`NN0Is#3C_acX- z7}$#uUM%>YCSzfCPly?T``FQo z%e%JRz_FJdU)UibO<2T9_rRYyc-M9Y&{g-{ZUM31G6taW4bd_g=+tuKh#k9d2UAobpvx|+0 zYZq8f(X7~K^;$u9Og7h~dred*H?Va*RY0!(49Xg+CQuC%k>Cf^g1#sV3`SEFQ5z5_ zV^QPi%^$X!I{W_&qb{yd4l{aMk=|k*=__O?sD$3fghOz6*6ucrYHRiT!Q!yuTbo=4 zn_Qr()8-pbq*2CTM9Y0iF|9m(WT?K&HQ@|uO-1iRlFVTjKhz=)?VO?Sp(n8CX|YxP zIP1VYbPiTl8qUO);ZL#Gg+x+7N`n4QI*w$JyLfBB(r%CYX@%r;Dg!*~JZ_%&Q z<=K~y5(LM$58`YvdvRlO@YVr-Fcq6<+|wfH|d;4Al|kcN6F5X=kv%B@NJ3X7gm?=6PitP<39F61pYYyKl_atRq6q zZaEQ-|6HoCk$fxdAYqV0+ax{p)0%v%u>F;g4TNMhu^h+< z8|b4yXR6q`UZH3xX1HsdR@dfEYWf+((|C&5O$2j=M0QV)BJ%N%K{}*epWiniE8lwQ zqv2K|MFYP)jiN)5=bdB`C!Q9@8f5(hKWNxob4rGbBZDg)JWC4}6L&nS^38~pPRqHC z8b8kMJH0@CJ+<>$a*ht}mG@iRtC%zwtLioJo5}plwES$1mxj_U%O5)trZ;kuOk@|9 z{F!O@CId-7yusL;mNgf`b(_FLzVkFVk5I5;FrFoZc_ z-}U^T%>T>zpB+$n6l3czW{OqJXwa)yIT24r(knGo(IV~JR?Y~4iea#X?$$Z!)s$4b z|0j;>!RecAywrW4E$KXF@|bK!vLA2G^re{3u88}1 zb9(Gcx+VRJ85sN+l}A%=#}v64?-?!Dv9oPTsYP2FI48Y0&;L+u<4;y_x{P8Nub#S! zWzc7Q0Ob0X^sMc8{_&4co5-zZifoy_TU0YISjPi2D7Tk1Tac&Kzlf6>ZIdt(IL_0f z0Sbc!{(PDal@;5nt5%|>P(W<;`Tj8Q1QzI?4H0C%hEVd>rcH%v^EWc{(?eBz(UVRp zJNg3PD^vZQ{!!{usu9S9thiA>`kt;+*9VYEHDWjQD|ZJS`t)cwqXlzS8c(e@Iif@` zM@3AzH*j|kQ0p^W^Sim|vIV*`;5ze%g;g@+6s9!pw+$ND%^FNU`hxnU@K~6~WCHb~ z$z6b*a%wv2$D-(uyz;Vuo}J{zA(BC}ST+>&;+ z@-E(xk{j~(y7MBbP*R@!b~l)gxne?64G9=v@y0@aabod8- zBpNEXJJ}FL$AU;pL;e|K8^>%8+4t>^`2wh)J>*iUfwkSX6K+cAWGvIKo;~D>?1YK@ zJ)R$(=O0J)Tx`$Z)$8+J6EYEuzd`Rbn){xou8tQyuB(AJGaVFI1N$0xl49S3&h&sP+N$@t8m_NkD+k#4j zg_ULfC!5%pTBL)@yCtPcCs52Yv&zXa|Jc1ktt8Dvb^Lx=QQUZ*jl6HMp_~xKm{seO zji|=d4Wtgc+_wTrVTbGjEfmKe0oV`}Q1~Y)tWf>abx;l(o*p>qTrrycxdx#nR+ouy ze8Uebj_t*PoYRPzdlnT5Yo_@gw=u(0D?%!qBCtiEgm-VLIBUO`KBg45!an3#?*0;@ zzB@Rg+$vzQW+^#=Qwhs+Yr2Gn-V72{L0?#5qN@O|qWFwVSF)d$#c!$^ILK_^ zPA7QW^#l4NHr0R@L|T~-pyp)HI!=D-v(apfjS#klt_J(G$*a>=&JTb>2-uZBQ84cE z1etdt{(iRldm3(tW)oyWA%b$DVNcKJkaLA^B+M3LiH?dDoTP&{#a+DU^DH9Q5$Y=H zWwQO1*mOfzUZVwaQYv14F)SS@vUOX5g++IQZWd736m^D(IF%m^@Dyjnq3TO{*RCKg z(OE>6fe{*70dVNVh^HYPbXW&0#vdlukC<~~-PYA#z`Hy+Ub9wMv=pi%LQA)#*P_ub zz{wMDX-Jwj)pz_%V|`NfjH~>K(OJ&OII=T#474y5`$GIcBx6&+ip*^U^rpP|-GTq~ zWU1-az!e(X!^lOLUb_@l0eC_KFYx*r@`t>K9*n{vGw;#WtIMI|0FOn9KX5X^|2<u$8jxh{4hhW8V-m6mLMeydCA-4hM zKfyI5~4kDE+0X}XtPN15TyW6n~;5MuY0__|Z4*=O5=tA4@u$&58 z=nc6Dl18;^I2y^WFtp4mNWC_jZe5A`Q=^bSMJ2fhr=D%W>w~kzH3`UQ``r!SJYIg^Kt@`t;E9Bw=JazMOJw|e2} zJzvq+Dz}`56dX(YI<1cz3V*lp{+>?*Rc#JQs# z;R2O=JNcI%xP6V$L9R_4a|G4yM6mqrV16UkZ4iV+1l!9m(+L9234vWvtWTaHnWJy$ z*I40kBKHFo$ibE*NL4_LUQxI-5guv9jfKTf%HFhsZb{vV=s^7g3BB(vy>vyQH~;kV zi$rA8j3M9KWb3HfMFxR|2WW7kKa~uYZ;m*KLFQD0&BaqIw^ByIyU_dNh#D5^A>5*U zQy!p;@Suksb$(;--F=Al^WWyz(eCIo9LCO}UmIs~k0Sv~474T;J)RTB^GmZ6=sgk# ze$kkO_?lc5yk`siXp8eEE9oL^=XEUoI+#W^ z2L+}X7-s~+(O{bYsHkSWXORW2{{Z6GtJ|VWccq-Ic*8yDO5xe^GlF%`@DQqdfWJWf zoyeuF`UU9O&T+HKrj7HbwA4MwSImgaXoboc9)NWX}YH3Z)1A?!1Hfu7hizC(Ky?qWs+f zE+D_*u3<)4yATMpVWXJ4JGkx@f+K@+Q8DFscwwEq8k;1g>6n2Ds>6bt9wTh%*EE;| zKJe9b8+lh(bKdon%>e zJXkl8jgDJ|;QC2C%nXK}B|I3qoR^xDx$Ht{t3XEsFRXzJwzbwhAwSf%weB&VWU|Tj z^&vYCnbr=HSl-$}I@7u~LIYuE-~?t6p@yBOXkD)n2HX1MabcC1b0k>zvM%gN{$fwN zBe?!Gp43kk(YtG<9`gb(NDtDeHT-~4scUUKwpOa=*%bDr_Bw46V>c}m+)RC*xm2c|Jvg;5{$=M{CcsEIf1i;qOB%Li) zAg2`@LO+Sl3vQCpHb=nQ>Z$!X$&9|76CvGYA@>_*4|-27gJvUOk&c&4Lvy3vre#h8 zC6nC7EVCUUX|AzWK4-06!(TR!kd(dWkP(t`!ZlxQNb1Sfq6cQ45CuK@w_4@YNp%pd z>Mn`Yo9$=Or$U1^Nz$V)8M*~#>+$A6XG#YIUeH4s?~Xe;#s=5j!QYZX@Fa<%e(;9b zHQSf~p@tpbF@93nU`QHZj-OOUy-_k?{G^GDpUgHHKfNH%9zPi{89(`D{3Of2XZ+sY zIB@(V6R#e{{_&HZ9WZ`UqrY$bB-3-oPq!l^%{A7_=d87l@mI!AI^*vdKdH{Z@sswS zJATpvbNpKM;K{P9baqW;cmpRVduoTtLi^h*^ax2{@M?#fD|EQILiZCIXmSQlvO;tB z3#+qETBccJqdBJ!M}HvIeCRk5IJ0c|WyR)XF=vOhf`aR0QEBF^P)*bpuj!G3Pze=_ z`euZF8uhlL0b9FP%7fN7<60)gTEM(+4|iPqB+zootMdn)#z5d*W!YT}G zXzo^|(2mBx(#}6x?G&%&f1{mOP5X{^q8X`ION_+H0;Wf)u0`f#T|?&9u7~XJ=K^Gw zp?8Sf-Ib|j!H~>acEtLF6x|C!))Z+QsIq2w?FT~p`z~JYsJwU)*E)4Op2gl|!=$>M z{K5=s(iZ;AUK(;U;CZRee6LXXF zI(Ez6Q=UgfrPA0W4d66*jV9o4Q=wp;v@TTF$TP{MW!8AS{+b?-hGyLtU3O~iJ>}~O zY?1^v-)DwSi4RpxfZ%6ad!Jt~>7nnn`XR8}HpkfJ)jPJolLh#ynFhkK%oBV}7Z%mI zM4lS3qnH&M(A8FjE;cK4b)!aUn5yZj=g|+PT{is+8=EG3%os^ zy2JAJ{Cb%b+LMHi)`hK$(7PQMYKAAM*$J_E`?bVAvCMZDdNv~sy_E)@59!2tjux{F zGuR~ThVx-VSH3s<4~{xvN|-4LwK|2Be77xcW^6+-3o>*a{QrVLYZ8TdYBy0T1rCW7 zB`Q2Rj?t96JD!`gZ|Lrskv5%1D+Pz7AIu8O!P2NM5w6Z$26_gWGiShhV9vbsduuJw zeJc#TqI2{*HCMN%?s5jfFjqL8xgOz=;SAjczih4!rr8f=fS*ACX%@(mz?RHVei~wl463#A8p=>ramL1EO|Kp-7pq*GbWOyk%4`=PmGp<`?>>s;+*p z)|##|Md|*z!LguoUoO#P(sV_HtT0=S@f+AA8E{+u880T6a29!swOMn%R?godZ!bw&-Bw!f z3EWC=LgM;+psPVj)Fquo$RtKkbL%0^ln*3i($W|q6QVAJOsX0uaS$?j|KAfbAqamj zA=Bd^gzOa(YeFWu{5OP5Q=W4P+4<5nezywzYUFb!#+(&_9#UTGCAW6tiKho{LBrr}65&R0(?RB%@X@g38qI_a1T#Y}Z*W+Gm(4cl+}C+vGXBO&9++ z&AHC3Pe^kNtXipgq4sCWMPo>+MOIpq`F*cuXZ#0)nqjGfvP#o^7nvK0?3{sD^$5vkVI?&gH?uA#`)jOS zDW7j}8f)u$z*;X=!ziv^VR!7pA>2G~(^3FV<@m3+nm$kMk~rBAt(PL+kp1=Py2=E2 z)3)tjy>xZ6b!6Ao{lL4^|B=Nq@W{m-MufunRHF=W;1+No^s^rNqM?Zp4RZx zFXOxI9_b^Li~N`7?yuhTAa%n;(>Ew4kGvBJK2V$(#faU5Yn<3U&{Ogc=OrjuC~>!q zVk&V|5KKj<1da`7BMk@_ph)B_0X^$%qyDNM9!$oP-%F$GY9wC_) zp*>i}&cwZ+Th)%D1T>^X3BA|^dz5cOB-fZ~HIM5?lO6?>PVfkIhBh_i zyXpmdB67DJ@5cmAiqd_Pu}y3`Pb6VBVSy1^>eI*bu#RZ1w3n7HP>qB8l}r4;8(4Ad zwMK}Qor}wgJhQ}ky&dADEsjWoj21&yb2uDyJ2qb2iiwjP7Vs$7 z0Fwj{i&g`-y}oI=`?;i^g|khFGN64EOgk}D^?JmaNw)bq0y_(Deh(%nn7rj5^VzT7 z-_R_EWbv#0@~+oJWN+&4Y81Rds_4Gh{E18f{Vv-=zZ?5)#Sx50T@wPGXkDqX@kHu2 z;93Om=qZQHZrpGylgzO zG)$AAFUIg97l%>be(vtyZ>>{gzzpEahy7yDP2=g|#B z@$T?EatS8dT2p{v0hSh_gp`F1f|vA6ctT?PYm5`Gc!YX zM9xk_*T}3o6@Bzh5_bKBb3nT?wtIfpYGxmrHnFrMxT%|xW5_|qdg(b`VM9A7SXB^Q zFI5X}k~Vr)zas zW%oShR&N|=`>~dE`K$L?(R387`^X`v^YnhW^d_r=_xN&h zjv5^efVzC7J)obVS3rmXz z42`bJfZp-_IWjvoX=F)T{TolegLeJx^j0Nx#f)v{9L?FmKPTPBI*HWEde? z@4?xj+ThzEH=WDPkc3!kNfQz8k!7<@^3v7E-GKLNl4&v#^wrhELQ1kcEEy%4UVO}f zLB>u)C+^xT*9rR3OvF{28P`+4Tt1P9@tDrTD&uDoYEeh74z$0VM_cvv(aI3DN25%@ZZoZONiIAouqA>ynb75P)nJ^*vj07SWGNP}}|y*P67 zT_RVtMMYI0H6 zkLdwj!VEV*4qv>}Nwcc3M~^PDq# z*%85;+L9TwO_ob@Z3TeHM07M`nmgU;+SFi}I&xQ>tY6Bbcn*>KS9;()_2>R?gLsT2 zf?>8)EGF_%6%q}zut+ul-#~`{6BO;o-ZXWgYelMOgB>fpQBK^1Lwq+SBIN~DMo&#q>^I@0?NmK%Wv-1q9QQ;@w**M{7Niwoj3#4J_ke2 zYx*1VJ#P~To&VvbWC54Evo$%^iZ7N^tj6ZQxiwk0qE(bbkP7&&lTL$Mfrsmh6*QNE znEvCW_F#tkuPa1FiK=9)FMcWYXI?QcE-zJ8FT?ZY9xqltc`#Z+cXx}PfCf%EI8<0= z?Syq~q_I>LNfbC*S&y(-C?d+td2|x9Ts!wR{RazUK0v3jP#uC3Lih9BS+liS{rkT% zO}BE=ed!xjuZ=-GzC)E)NAA@>-j?O(srCKezkoT26o@hEubyX+M6WCa?r9+y z`;Sl~Q9|m8ToGN7UWi-EdlOLc27d$Ph?z`q=~k>eRYg2I_Ol1hoZIvz127H(-4k(r zRw6b9yMpC=gXJA4;NWYszWgwHRKfD@pdXbN+*tPE-B(Tixrov<$b?G`drYb$2cHRQ ztocDP#%^`Wpga5wvV4O-_jg2xJ7F&ju+`8P1#5RQ6$GC3uni|a{tk7qybg5UAjVz8 z)vxFZi&1=k31!Jqhml}VCJXptbok|DYK@0w$(1JM=lNu!WLwlHrBt<$QCS3i%FgBE z)r~q=(bWd&a0xu_CAaCx`e}*U_n*XL-tI3!4>MNCM3d?6i0sBWS>^_eh3+3kWlTt` zl{iaqy_n~_DKNbn_!66MrdYOuXXdi7=OWi(sU;r6Ae)W8w3;dB%dZ2BXzmW1jk{G~ zyiORn+qGGeMF8O0j9!O4f6F>ZW`2#H#Q#l`;#e%(ypC`eAsj^I|#-^Y|V7S{D6V zWo}13^+Kq;(*=jy6IjQyv6Iso>Uky*(JqYJG3qz1o@b{|Nbs#JRnPsJQPS>HJB$yR zt=h654I>Ltp&)MDza(CqnrYTRyp3B%TBWL-;`DMt{Te>9{6GvYaFEnvPvlDKZKrV-ygUNIDrd!HlXPTVZF`iH13q_Ph4t;YM20@-j1 z`p|_IY6CZJ9{l{CnCACl;+IACaPULf4m*KXU#mRt5Iho2v*3}qbthHdb=8D#;&>wQ z#tQxV;Tg)0)338W6+@5uKNYF(Yvo%XCKRVx?JmKw1)wTmj`P7JXWH(Ya=285d-1EvP(mY?UkwY^z9W>GqA62#)Jzk=t?`i4f0@;qh0#@E#2QJ z7Yc%rKqZN#ii-8Orxws}bg2*9JhgQ^4ea-1`n{lnS&a)A^d2j`3p*k4sboDkauw)C z6cKN5{cXvYSuYjg&t1IcSg&RE^OG+Z-^D$ViIu5~Dy9Mf4KAned_6Ys%k1CZ=&`ZB z`an&QylE<9M5pLs>SFvNS$}nyQix}!$vFye%)sHoZ3v5(KHLPEZ3Q>#xT>u z=wo}s?2%Vwf0No4a*nB=Kk|yjOJWdAa8;tA@8$^C8yYqj6}Lsj0{GK6np^I^LH<#p zGQ0PKW#{Qpb?^mxkh+K|nuy^vUhW;+882oqlx5q}mdI$mq%0BOt~k-0KV*Xa_MBd8 zNVQ{?J7p6K3=u{~BhqE4Go`ebO)Q0$Sew|N>05!NSB0jpAFlr0%JvWZTK1tUOVnmq)4u{-Lmu!(0UbSstkm6R4u2nT&CsXyhIXk{`lSBs z?k}O8e;v368t*C%oRV$5TVm29z5H4|vKpZl$C~;jq78GtxvdxTjH=#tC>TAjX&4wQ zdTW4a2djW%>TI}e%7of>PwgcVw;)}tPUxKs6|{h0U)x~6e;Y4+H zyaZLb5b@kDS+!Mcw^kwxzsq#gZo=wpL9?;Fi+#)6wlqG zGe6J)wA?xHj8X5BwFynG{!>576-U=ylm($;$0}Bf`3~HChInMn{SSQT&mf`FP8L?gC1gb&Ig*Fpdu|?=n|WlB z$2cnkDH@-)4l6x5EkTrVd1|qm*TuYq1^=<+B72=lA~dQ{IeFZrK^n&!zw7HQ>Tk<1u>k?mb@aN;?$yI6h76b@_|1_JkE?O#<_ zb=n9%Q0z-p*_v*;Bmbp_G1QS`W(_M7m%tc~R4>7cnQKXfcnnVInk&p%-;X?X*Yc1X z?Yd5W8Y5%WkN7Uj@4@~guYj+{+KrRXXksJ4yBvh@iIlKe?14+w9Yja#9V6%8Nd{Zo zp*ilrDopoXm3d{ryF`X)V{V>8bA~a>bDT?X(g{{jpu%Na5=@H0KWr2R5DWNcLTVE!TAdkOYuP zd+yfjI(;c`Fa*)1_TGI)`1Zvy>EiR%O;_&b|a)Rr5 zF{x4Hr`ou)SY=~IhRHJ5Xx%Ksl|xp$YNC>GY4S$-5z~o6{3c9(RZkr;$uCxYhP~N6~k-&=!1`7ppP4Uv$Xam6Ht1W*DbJFc#^o#CP6CJV> zdhbVA%#4X5=L$~g0e)WdN4V+v34sW#xBun zX$WU`PHXf#U$I9<^V~D7lV?X{FwcF{P&53RfqTVSpZ^tzrIpEGo0R1MSdjl^!;ik$ zbEu)2mutyXR3+GO7Ls#Lw4wxUS0+c$r_%2CyVMIlfHI z?_8F|w9#fh2zu0|`6@E1A!}ANUo~vWZk$%_U+vkjMOdUmNolAhkU}l}$SCjhHZRM# z>_>-bLxHRNgHI8iOJ9+{Q0ioH*j|!yF;JI2*7Tos=}0m;*49W{5~$Jfhv@v0t6MA zOkTer`K)x+q+>N;janeGTV{K3rjuNQLjv2z6(SZ^4_Pr%)b?jh**Cex$WUOqV(!>{ zR|mS0>)es;G-hWz$5*em*``;I!#35kZ(4SR;mocGbgr%l^sNrvmF@B;cCAkn`szM7 zEL&ZT@sE--8?|o^-IncC2XRoo;As;2=98PdqGnq5Y5;-vU7?`c3CP&JHC(4G~FMb+W&_a z!M~$VJas=ILBw{{vx*L^@JtxqLo4`g<9}a;XW6bv6`oa%6`tD?(|;o$PVTDk?Ai8P znRveW)1&m~%Bl*_(QVVOM*O!rt-|x({A}kz@@lT|Tp4{R`^|26OGL}T+p^up-aykZ z9$fr)1{s4C>JC??qsMA+bQ>jiRCt=gNz=theC7D*S0j;M{fg9~lgfSVSw!XH#T-n` zq+*oTbiR#;B%+-!(TKvd&{^xLTwL;IUNvOoxQI24)~u$`O^qOC`IEJ?fygLkNuIpW zu!#FD8%0)dJ!>~UG+N)V-HG->SkQSgY4#}ac=$;p@lcJ_9&x{8V~iq++J^+HMDNe! zD4o@gO1MhS3WpCR;zNOj&ua>=oeuLkH7ks0uG1dwN=s`J9|>Q%9a{sRC8UMZT9>4? zEKZ9na|lQadq0~+Nhuz{0Y5@wb<$`FAjeW3S3EP z%^_Q($Hr=Iw2{$?@aKbTK9l0jp_oX`hSD}hjP|rd+#AgavQgULc^xDRevPK@Zp}L; zy#G6TDl(^-irn)y(F`u@+Pj!PrbCUiHVI55P)t(f8HWi8GEDl#$xB+e_oFdUoDfhs z>cUK{NNcS~YpO_VUQ)pni)jlnPH*Ze0Yxw(tOjRoLm(O!cLbseW!?^DBEe5C!yc`w z^XN(}J4#?0?*L>U<6+aKl5#W>=CPpW- z73v;7WKV0S_YVmgm-%Ej=W$wl_|V|ACRqhBd3X``t)&8NBXaTAxy=&HlexwbaTHVF7N#q>(TH7HP>uk0 zfMdNq+$E^U*c!ICtK8$TICHXEvfhIPG5pL`=`RAsv5PEj=_~71);F&(BJ#D1$S@mO zEmYXiSecx*3$OQPwYf_O=QhF62B%?-qH7@!-0r0D9jilSZ>RO%d(pWlxat_3jj))}{pO&$ta8X?gdC$dpJQs%t}B^L#Cp z+w}vLDJANk%?~UM`Bu-jvubs9%mZeD)Ji;H-qG&?GlcxjL^hfm_khV+tCv{UP;`kd z1H7JWH8EDa?|fYFmWn&hPPt+w2FJv`YWy5>>f>lq4p{C5A?AR7E>`EsGuYKBmG-Xt zk#j>F?{14mGcSsWC(CG=v?9Xb$}B1Q4Hkwz#xIbuF$+J?4c$KfAwj`$(U3v+dBQpo zsnLA^wA8dtgkOHamJ~E)WK4#Rk$RT(v(6DH{XLq_;)$-f=L)|*!7{(L9`DIxrfBA5 z#5@hp%93n5Vy=l7?=fAobv7p1+F`Dmbs3Y^V`qrdE&!SWc8*}!V-LfAu?)R*JVq5K z*-k`e(KSeTl--2@KczMgG7}nO6MX}q!{iv+=(RHPS7XKnlUdIw2Qdyicrjb+aslr@mMj5 zJvWSYjhUYJ_$lf-H2c5!sa-xDD0RjYZPV6#2gG zbV%8;T@CyP=u2{A>eO1*5D==6_ny7TB;zp_(g?rpM&zVF38|Hj{^8jDM;SUOwbR6 zrFwN(hjjY*5*@^OYJJx*lI{fS9ECsuRte$mcPoFmUS=GO;S^8$iytn*s*Gn?z)X+* zA07!Xm{k65eOGT%S#$dwt|i7{h}X7AZ|8oOw$LS0cm^?;=aA%M6hvmDpUJl7QHaIJZ|*vFD&R z${Eb|l|RzA!!4LpVjiqW3b>1a+m$tSH>)dd2O%w>6Xc3+ErP^gD@xiTE3?}+d@3=J z3292geJt`yDvK&_Tyvd{T3)YgU9+_ae9~0fD{D!km1Pw-8hMpBD(fkWCl!@gcJYqE zp|Yr|T_!Rk9x?<^-;TfUE-6ICxw;1a2D|Rw#QZz@f(Q7u#2~|d->#lxY1E^U!R%a} zWLa&Ie^fsmrgZb$wA)YP=ydvY?!5Nqh7L&u8>d2?+;b+m-#`6KQ)ia+rKVHTvW?S8 z#$ELLSTqb;@g zGO<&PKsyorY=5Z|<6Tm{k(yoQk0q-ZF6R3}Np%J2N@IzbB+-ex_EkJ|b8Q#>K3tN5 z-vGU(pg5tGa#iMspxhF^e>RoP%6ndV>~lk%n5%0ec&-#`Eq$XQ3;3wc@hu*Sa1)#k@RUoS&vpdq1I>pFd!+HTbiboH9b zdKyV8f3L1ADZto;`%v`1{F5&wVSKZwOm(s-f#nJ7JuUdgT~cLUgG`yfAjk|ito1MX z^R_J0YLgOh^6yx~3Wg06L!2x?7FgSEEp1zTqb+E&Wj0RNT%7WcT9Yx0Lud&MW0uYG zz^8h_C=pC$rj;&ElS_EBn?EdPJz;#4={uvt@gAE(8q|%I_?cY7$D}@H=R}sf{G%*a ze0%i|JiR}YcSd8zgD5{kZ!u$gKI8mfd+6I3U*vP=*C7doRGZu2;tkC~W6%5cZW3*w}u`vO-WnOIkhFh|sRO zO4_h@V7}3uzRZh{gseqR#7xUdYZ8s_cArr)9R}&BA^oCje#pM zw}0g`=JUV(NmC(pg_TAqt=j%J)h^%I-FESE-Xp;(Kx1dU2bJ9~-)O4u>be8MVYxNc zk#c|l)m+^Xh~oos>bk)bKpsd`8%7>j#9B)V@&8Uz+}w>brrh82VdR z`)}$?w}{5Rd@g;c%+QAFo{dY&u+C-TA$syRFzmbF0H7o|-PB58kg9k?=Sp2#;+Of(!0(FhV46mZNda4s$$!6KivNXEV zAaT^OPGh`A*WU>Zh>K2FeFF;*LNDcTt zyZCem;)GhVZL7}V3qCP1+g2GyHnQeWA&>^y$HY`uqKJ8etJ>x645Xc|P&hWbisYj- zT)ju@*hhKGEB4_h3w|p5~n@YQ-*rhnNij#qZ<3qlD#9cpbFcz)?$UQ z*@S}GX3J9XNaRl5ouv@5nGqxyuUll?0-_x6^3AKld44Fbc23N%hkF$6fSo^B?!Xw@$T1PwP5j zqrU24()^n5@=Hytr|rR}f0T5^Fw2N>lU6L54^?3$WNw6UB;Pjelc@_l`<(d3IhQca zS6jx!=a3!qbT1vE1zJ* zL8BEK62^yZGQAmgKktf9DAPW=(@OA3Wi#4BeH-2i;kQtSVJg4I#PpwQ6zY_%2)3Uz zG2&U4rEx8^&6LugR1kp>I4QzxRs_osgH?Dwnm*E@KT;x^7UF9?#^K%hdJe=RynfZe z_Lzs-qbo|$NT?qNOVMeN&m?1lIThkmXFtg}5Z)7JSQ~(`!x(fCeKgn}_9;B&Bdyeb z*HSC!-Siv*3)Ay&^}=TD`YsPcr4qe#mc%GW+L-)Xk8W?oX~hG8P$^U+on>b1$^w47 zy%+%xOR&`HEz}X|us&fGd>C3DT!6hHR2m~bX^3J^8ob$)1_wN8h{r?v${(w`p;wyQ zqw%88z8GE?*2pE=g$32QH|NglDR8mOQ^vaNF)>L=HIiMG!^0J*6C)1B8`}ah(9x<&)**M&Je$4`Vv~1-!?V`v3H6mf z=KV_Br7dXV@$7op@Vc4T`K}#ku)@O?=mWiwEtGz^-}DI@Y>h3x=nE6|L)G~OaxA_W ze6nD|gNLE@XkB=IFByK`_%QSVcA~7;ThfEaT=>rafSpun8AJv4X2+0OPcuKdblTUM zdpxVI7>>7-u!=-#TnV!d&d~3)wR{KYUxtsz%Z%BK`xEVuH63r}ilZ~xbXvT#L1tw% z7Bn13!8(fm;8BM66oRqIG5nJbL!=_S0u2AMFzj@SPZLY^^fu37EHo{$ipEF3P4u)N z{_yLd^TW(cXw^HcI2@Q4I2iePE}2pcJV zsV{Jm{S9cF^qmH7$ff>906cVz4_6(#S(hkb_?lPv!C_#Ag# zTY;#<=hf*=Z0N!c4;?%#^KR5UlW=ZyKCGf;`3q$DNC;&RE4zVVzmn!VmC;f@G#0-F z(;V|-V-aLoX<8W_fp;WONT7@#eNC1H%IH!-X{sC3Abgr*L13&Hg>tDjt&WZ`et#D4 zCE|r_T0e)a?Kzr#Qf`*`=)6UK|EJ`mFIxBijeKV0dqh4wEYI)%6Zs@~bkzTw0?C1A zKU2RjrO!!t(PgC%{j|f6!8xxz|C~!!VA1axI$1kXGq(7a68(s1bjZ3Ndv__2@K3(l zP#*N%JATe*aOmBou1kSM-y`f>6w`c6&6nZT6!DgT7Kzak{7@OYwi%rHRX|S5uvKp86XWVLq~@9k zqaHS4cGSmc*U;4{52hWL6T<+p5tW#Lb_)Fkz7!1IlLCz6&eXg@`7)sD*rZ&_%2Ox0!y zJDIvc21r@g7mVr(esj~FVA<|_1a9$5TQvUzHAc^BFdu!krwSkdIeToYeOSmID|(AQih@ z%%{^7L(S2ie)u^Pn^a&zVS-hx(_me~b$(ij?Y^?S8@!GnQcu1(tOwz@&ehw}hja38 ztXh$Wnj$W;ul$jw#B@4sSYXYHK-7!;c{gZb(26_`*Pd4UkwaW)!Q%ow0}S&sEw$Yj zXlJ`G#v;GS-n1AmN_M9O-#TpLkZDyAW@&m>^*GZyD8I;AburV(f5706`OSKooQoCP z$*}9sZV^5f|hBGwBP_oGM-Ox#`*AJDhi!OK`vL~ zMX(Sor$l3?Zw@F60-TDCy&mD4;1c0IAuLZ#Tt?SME`}bXVCMq=FzA4NRVfKP*>?wmr z)kqsvV^1QZ()PS+Dj=ghGOG`_zmAq=MK{Ze%Vmb1vv2Rq3ouC>iQ;j_o;>fFp zSJLR5Hh<90ScAx$Hhl(FHTQ8qR_ENuvMdYR_m5nxDJj6i>)ac?E`Ezs?Qx-`dHAmK zi$9dm27VN76vD@?2zRm^T$+Ew*0i{LS=-{6+XpJ1;)A~ew~ff%3ND?L+qflfety{F zdz1NiJJ9T!jZ<_9ZyBn`4O(Ti7 zQDstIu{r=ZF%=h$9!Cb_+Z^Pl`{KDBFhIA1Q4A~5EQncFQqjW)6XG&5^X2k(Lliej zSVCaC=y$NO=xOd;+b<^AV4cXfmTmE*BmL@qTirFzw#&8scy7h@J%_~}7i$JT_PFq~ zZH8@8XDPp9MBUsBz#p0sl>rwRR1Qn(4Z2N^RK1m;fZ1l3>jA^KYNJo%glC3gf zczwW%aNl~{pkl*aWKdX-&fXUfr+zAeJe(l!0Wh&gFA8ty`>VlD2o1njn~}#Ad~QL1 z$M)bA(<60Xq4IbZTK4SzZah1BREb>xUJ14N9n=YlPa8e0RKyzGCn%_~e+jzFoPmv7 z(9_CkZAS~8p*frJazF`vPeO0!p*8E4TC0Qhc+FXorjAJKs%#Gyn;yaQrK?!>|X(@@v8ViJ~5d?%gQwxYoL@Uy2+ z7h;jeBac(2^`?*W?>)<}f97${<9PlNGhA;Zk~~B2egyi91o&WW9@+SE4M*`R5T2~A z2zrLQ<)A0Z61@VuCH$cLPCsCAt^QklnFp-SU|j*r0<3d&tEbQ4qpt{hio{6zJA)?# zXlmmGbj!;giK!l# zbRPkx6ca&EbejQ6hKHqw_Jwp4f`&jh5}5nY+mfive~$kx4di|);qHGW;l727z(q73 zP6w9@w+?P6+(Edra6iDA?U!&4a6{ny;G*Dka4X@qz9z% z+8>l~J>gv7eBi?2royGeWy39oTLt$4+(Edn;p*Y6A(I1~3!EBmJX|u|Jh-KB>*037 z6~Y~dqr)BgkipS0zDEF$EA1H)ajk0r_b<>=w*aoISs*ucX8;%N6v)S;pW>JRZg*e2 zONa13JED@cvZRz$ZF*dqR+f<@(}UJ!X3WftOOvH!$@Cc+veb<9nefPxU&rRT>xM7?t=Ys-*YJ^s)?{HeHsLoRY?8EKADBlx1q;5|NPNWEfHt zWfYBgP0=WHLV8?$s+NjMK%ibL)23?Y024`~1Z`H9Ql`z!M0WjBQ--w2ONcK-lg&-h zC(9Bt($XNYY(T%%tO2a>7HP7ydc;ZBXJ(`dRm)V#g7ulHuEDZ+ZF1b46qJ+}mjgnU zl0GLcHHE6M2kTzAvOsR@paA5?aj_Ev>3)<;1>#PH(+hMi&r%}aGQWTfh5-+0rv|0LIDp7SOg@!o))kINcyY+ zl3wlr?SN*{jFtkiz@BpgIs!w0J%EV2PQ`Bed_{nP?U{(4}0AUB!i;|L`A{DA#{i9jdda)I6p z91OY!Naa2O%7C&dfxNLJ1n3M}2OI?40HjwJ3W3y)OMxALRX}Q=V!Jd7{3k$)Z$Fjk z%LPdCgaff#VPkx;y@~BfJl|qFNQVBYJ(@v(bUu=i9xo(tGiJocWoZ*hMEDaDwF#*} zU0hZ|Tq@&X?{D~tm@z}2oI(L0X3R*6%hHSfIobq$My3#r@<|nm88ftT@hKEPYi>%C zeg+vVM87-l*Xc7Ap5SF_v-FuM33>`Qq+__4nXXObL@o&^OV`c?aI!=UY2UMm`XkYNcm^RHUk~P7;fBJ|2Zhy0St;}#Fn85Pt+#G8B+P-T1+NONX^JHWHPzvoW^DTd3qs#jP{MmQ}j%~Bve!R z&kb%2XQDqpm)JQenR)|ipO})RON~p=rfJjlxP0iSe%fT&--ysWPLpnAO;R??v+#qAj#JJJhakM zlcrn56LtNkv11c+Fm*z6Pf1VFr=Zu*(`NEh9;&+-hB-`jioRL17GoezW8MC=h{ia7 zD-6}~4?6pcd|UKaeKJ2I6S}Q9{>b|Dks;g0@dzzpM%>)E6by5XJU@RmCyT;3APdoE zC1j@PShwb6LDbcQQ{%F-nuW;X^fKobVS$;MaXHYJ5H&0XT{ANwIj317gi?4$nvO?(sR->3|TUo%4X@%1u4;TTqjE5%%%l$ah#4z!RVQWnX4-| z7yfi$0+)dqtror{aN^<1Hzp0!D zM^}y3`SC1%el#pKD=-!3g>mR3?;Ho-uuQF%X9@Iht$t!$s-XohQsmKflH!eMY?8s5 zXq@Pjko9Fcua z^pojL^ppKf^pm+x^uN~3Plh{@PsTvePxe63Z-cU_Pg%jyxGj#>T5brJ$jeVQh0IV~ zUn7{201Vz7f~I;IGDhX9FZ4y>ET{4~yWfunv+j_N>2`m~3mae`EEj^gcuBe~APQTP=&3Xg#T>0ZblN+JF1Netw#@%2DwZ6K$ED~EGTV%Pm>;Ci@A zaMGE9Tr6B69G8qwlEKluAQ7m8D}?*IIYJ_0=y4_2W3G?}6tDLGbe=$SjMQf7XqMoP zdi-6vshFiCAXX~U&*NoC0f*)^i`U3HO;C1Nu4QuChD8c&1{jDr1?8JXg-$3r%i%9V#%a!($e3jXS2gh zNFb)AGtBhxcV%buHD~RFQnON7>gT7Wa>S9%74_9)Y|erXGf^g!BoVck`;TRzvd{>3s{ z)`N|=ftlK2Fr5eLQnCWaM2_Icaw*c%ZAx6GHj=k`V6H6zkNAIvG`>?fT_Xs?gGa~d z8dEpplX*ou2Ddj+8R5YrLJ*Z7>jQPVh>X;fgdE%z2p7R9ZDv|ZI_xkR>7%v!l7XlXn z7Y#@8W8sqFba2^li{X~Tt%utRw+(J5Tp`?PI6BXCRKQ;YXN0SVYk=d@pg%Y%oD5D5 z7XTLpmkgH;w;XN_+y=Of2c!evFw>9);{@{3Yt!Pj zG(SO}8RSF0B8&2G^aqZ{k|ns&qlYFY4$a~7NyOnI8;wIoo*W!pSeP;`O_`NNz0A%?a_*^L;Rt}A{RE}6*@{^rJESKg(VwwD@>E<`t={+JaEup7uO*}Ts$65Ce2JvnKe5#Ej>f`LS~lUFlTOd&b%p8u@*7*&%Q^!^1|592Gu#%vii%8yPiW;-u)9$xQ!$9{&Fd{d28GKN{u4 z@z41=VSgM2{~Ja?NnYb077G5OLma^f7fG7_OeFv8PfXvuKL4z~%~O!y@;T#wM|{IY zio1HT6g#Z(kaCPGg0(GD_{|jY<8tUvaOW^$);8TBpX}}uszTSBs*h0 zknT?#fMlEFUSexHEP;+5)%78jxZ(ugC4={W#TLY5|+6nYhU_an0V1M9x-~ixeAl*!E1Cs4< z4{$KB5a{M9$-rzN&6sn6 zF9DYVC1?Q4fhNH9KvUpWpc#ZI9{{arAp95718smdKzpDA z&v7{h^9z-XW~FcD}2)BzoU^MNYh8lVINa^eH4i0=b^5e%5IK?7}ok^tz7XrL2e2;?LTgPern zkdrV1{S;_6AN>^Q0Mr4QWrKqSfGihe`;6mJyw?un@5+hK?$yakLI>H0=^!gHL$a6< z&EnDX8#NbwL21gY7efsdeill+Jq~v;B;-Kc0vA7_}LSL;k=E8+Jh^u?sPq;HbMUJ@Kd{R z1sBZ}egphrumrL8L3}EU+6eih;HP%simN}xPlt5mr#S$%4_C|rh)->VWTyP7ow&kB zaj313pYo^nLS<1LYBN+{lAqd*D{4;pWI-dur@B!4afJlvR`65WC_XKTTvJ;V&lj~vSHvbcDclvY>HKE%^r+!ZHC%8`DvaS!1N8~fPyM3F&)OKtN&Q3Qr}5`Pl%LKc^Jg_nOZ|rQMrjjx znTO*{a_ALw9$8;teMwAB^`SmRXE_Ej#lA(k(AnkC!dNYXcr8*proP1Vp2q8R46h^B z4@Yq0_&lf%!F>B;_EIJXjklC@G~%#+6~yb2^%)kQ^%=%b=j$W(8PaKlaL$;-5#Tg$ zL#z+5e%rjA1@m=GrRqQel8yBfcD{pneKkLq&Et#p59Me7;&>Cvw*_|H3FF%-8%yxa z2W7B22l9QF)tTv@)j61N%UOcfsSeG{WAd>&h-F9cS`y0+=g$-?JCc`!l^rgWM{R(W z!O9*k^i9$k(=i)Qf&@9za6J=yfLKNde@PD;Q1`y(fk=;dV7Ap)Qeba5%Z1W&n?TBwON*L z2w$h>d9^$TX?(A0DdSkQT=CqF6#P`jiM+g77*&X3XHG0XMyLxrC)5{3ebE?CX(*&+ z8rBn;%t8El5OqOg4(n$ldHGqKD51?!>9`kYj1$iHeX;IzkIC|3Et%yriof?{aUz8N zO8ErioQY-Oex)((1itODv_Z|{M>OM)6V4^&!$u8OZX`dVFn^eEUMLPdn-*n@;N@?c z&rxq8J!SGp_rjz@x`%fGu75ROgJ_zy`P)Xb&VEI{`lf%7Ht8WMd%B`GGC~k`1X1FdQ`5Fvyl<35*8) z9xxGj2B-t>1kMMR0ha<_1Fiuc0B!~z1MURw1r`Fo1|9{L1IvMQZLb0r0gb?mK(bj` z0Uv-q59D6M=W+oyz$-v|;7Onp@N=LXSPb+7UIK;zw*sSpyMVF4Z-A-5*MZr<8sK8! zm%vrPv%n3&8^CSAYrwt0>%bylCGa%xIFM{meSsCAwLr2hk?pA#bSjW+QT>7Spp$`Q zd$R^U0UZt`ThkDr6*8pX}_kk|J-9R58jX5E}FMtuigFvzwk*#Vf z=%qliJ$Vx!G}(;E#%BZ6gQmFv*|vrPb3yBY0if-H%Rzq(To0sq4%r0T0k?u43nW{b zGjI>+S-@=2y?_Tn#{tQ9*dAC48nml;RsyA<7Xd91zXOnLWE!9&_{)GUz(@)Q-yP@!ItREJ@%sToK+goO z2kium0G$M!3S0>!o8VwzGUzm*9+(d#+nhfz7xce?5ujDT<)9Y>8<0*8Tn~C9a4T>w za1YP`JP4cslp7nfnEZf5Bw0g z6gUUC2DkwjhIHM4n?X;ZaL|2#J3%J`3xS7#rN9zk1#l102rL9P08are*9GE>0njJX zI{@uLPX*Gw{dYho&_{rNz^{N&zz=|_z&C->NY@>>81!4fRlsRLDeBD~#m^CBrh6+k zi%)1ae`g%_n~HGp{*i1Vu8@rKWOe{%C1UqqwBD5XG~b9vDq6wWl$O~FXl5eX3KDqz zP`R$q4xL+OH%R2K=WH%a>4{I}vb8VFPro9cR`xdeX>4G&3tEFoJ&fi(bZ<739|zey zERG*Tm_MGEgZY`YOZ1aW%+KUw{uI7!=AXr%1LjX}mXD5a2aL}wHOx=zal|}X8)E!< z{JCfIHabJ%T#Z(Tiv9%t`p4qXn%5?NQ+!(OD)QOdA{L+No%v_-I%WQ3{+uy?8h>42 z{&Zfa%+D-LqM!6G`kTtt@oj?f=?+nhV`#>oBj}CpF|~r9?$0TeXxB*L>&|RL%wovw z3(QK!?opU!j``X768$tEV1D`){i*!9X8bgMZpiM{S-H$cz}haeJ+XCF%$6bY>AsHI zG{!6B?8^U=pX6s2OlE(H=W(ObpJ^-OU1&;7SKGL=;q<18CE)rPugjs$sS3o z$0W7tYaM@%-blfldcO2e2wdCHw1ey!s3ikQ$p5{j{yqxsf zj9qd-41k-A~`l?xp@=BYor?M{WAkk~6bx4ko$x@*QGo5<0nG!-W?n zjyzIwwGAYFb;vf$;7_;Dcj&z`;Or|uw>^7w@qo5<^GnwB+clyiQU^FxUya&y`fyxK z)s7ugPuPT*|1z`7!Smxk-uK(U6|csw8N`>-+vb%oyKY_i@x+fd4YyEyI%-B``SZ=y`pz*$?LO#nC$(~r z^x`e#CtcEWO5E7=ltC}rJANBsHrTUz=#K*;65f2F?1L`1N3L`pV%aq#eS|}LH_~>1 zd;fr4W)Yb^A74JdX5g1+rX;N!qS|t8!LQn#k=N(Gy+yVs^6}y0JNm5|HTpXo2>27 zW5vvpiLzd6lm!Z_w=Gk2UmeoUk<}gT|Mo`X%+Bdnoi`4?@BTukabbtfZn+sc{w11; zOTWxs^T?z~-+ehZt$vT;__dGh_E&!UO{T3je3bLtE;SF+j;szIcdl&hfC)Rk{d&Ny zZ5uxL#Ge!yFtYs4gZia?Upkg%9i3rzIJjh*YeSf2haVkdHvj5e|KN<~{UO~pzwq_J zmqSt(NYWomH%@fOF>HO6<8FMq-_Njg(d%6_XJ#w+F1!BnJC?&jM>id5;Tgcbj)^6A-VOH+I_AvmSxpj!jFm?S0>4;?0Sjiu=8BrOtVA-MWi&RU>-t zcI`D>=Cf?o_V#OHF2ih{%ZjzRfDpV-*%r} zdFf6Iz=RQt<>-&JVU5+-qW+Sbialb=qNxz_i$7LH=x6S%^{xkC> zuEBd!41--=7Ek&>`ctoRE@0k?oAHIlSxYOVH`kvjJvL#Pbix-g<(Cfq7VWmE(6n1< zxT$a1=x#f?W4*pD3eR~rw@h{3^^@BTebT1Cwan+mif%b)Gv^%7-n9Q_&KT1*wfxY5 zE$we#nwpxip!V(WD^-u*&4`~n&a>dSF=p`f=<9yxqMr@x(|P`+Z83)L`$x{4+cja| zt-2Z3zkiqFYxMBiY`*Q~{caC~ZF}{;7CgCP-7npDZ0V*+HiH5apDs8w)U0gOp1Z%? zxH{(DSF^5J)o%E4?96tXI)C)_=bt}pzs@IX^^p;Er{5SnW39%=_Tgu%Wp>`#=f4R$ zUwplfy7Q!OK7M7!&0ppgoc#X1DdUHl`j7oS$Qt=_(&`7}twN{W2->@Qi05bTWxRJr zlRnRR@1wcJqsmJ!%&ckHwtJ?kY}aQKOHM&?8@Q!@wR9hk?)Tay={>VUnThr`#fq1I+mUTI@Z)h$eBY?+ z*I7O|yls2acU68*oew-&IyXA_ox-iP{#i%v51YR}UjM3X?{3$2fAQXsPwgVMuh`-H zLy+gXH$M928_Cm)KVQf-$=U3U+$C>sh`6__>V(TKe;@DB$Fs_3ru|^C?d@?5_f3y( zxiNmTvaj^YM_Efk4peqLXKMel?rmk&c;om_Z;tt`Yn!1Tj6QVZ$`0$XcjK48cxV6F z-T_IMxctuV-ZFf5`u@P7i}OhQ+OBgGfBWU)3;uI9-yUkWASwKT$B=u4Kd)?O+bLyD zc-A)C{;>g_B!1RQUpU>{^?mQ3%C5e$*X_%o!0^XkrvX4Cmy1`p@(o7X$*7oj{GEYa9$0He{Cw_%_vgOX_t4fwQ?{HQ znkn^qDP-fJ!cIrFjd2ez+vV}j!2?fs&T;P@KE(Y@C-vUdPj!mQsb4O6!!GD|httCv zs(o%Ai0^ej4{}Rl=ZyX8qT^eOVW`uHSb@_8Z#T^>*peD|S|=!Y!%`%d!^Si~Z)x z$>W2+NwM&LxzOpZ#p_9R=_9&jTwC$FVUd2i;;r;!Zu?d#js-cFuFTo(biF;Dq{P7D zx0YUh(Sv*;N_VmX~bedipFQ&N~ZR{6x%~+E%{f5iR#4z7?*LJ9}^^ErGx_8aP zumN99>OX(T)dIujRk^B8UtDut6?QIdp;@idn-P4OCOCzrnE#kraT2q3oW#5%C$X^S zOe}hGCT;q0CfLQ;)Y6MHwNi7YSgvAbJ)SdbI}Iz9QaE!P183fD5og|h6=!a{iLtOY}@ryZk@-3Ad z;ck8DjXc6}^hzF(-o|5mVSa{CE>{Xd7(;V;1152Cq-M-?qkLK(^<-+rQLpi!0TPFZ zjB5I&?Yy6J{Sz3}qV`fgsrC#%riI_?q zz_j|)ODs?-#93d&JnI7((uV2mK$~i8S0uD9V=fn$l|r{HTwFp1e`AyNLMFSR;gg6G zvGgr}Ypu7L&ewE*G|tt>oOVIG{>8>g1sZetZ%?ge`}m_nT;Hu*qv>&DwN3UDUxcey z4!Qc4#zB|<&iU^6ltWR>ql#UdHSc2kf^mboBRt{wqhH_CXnx7N7q75H_)jrCyMCy- z7IjYJ@D;w2&Ydt>rQWXj*TwSENf)qtTR@4chx;x~uaL@yYx9tP^Vhl#&U-X-B0hF5 z_!)HUy*s@&e4@EDA+o2Y2J#hYfA8M;GtJtW%gu7X#kWvmkL3<{eXr){_v6p(Jc^y! za&J%1GXFxeX~DaF&y{pVej``RoxM*pFMV@Iqp2g(*N$oXb)jZa_?Xi-In*b>sn1@I z0~)VMGd*?p6iEMJ)E8^N)SMVI$7y=|f&N_0ZIk{#9MqgTHDuAi^L2jQ=G5Z7L5DQA zN3ZzV_9k|Li=Fj}`HI7u59jXN^8QNf5-0OJ_I6s4CiK@EKd#8bcXYYyJJs!qHM{Hc zPldkH)1NEXch(dZYc4%|{a&}W63}DKpN>1CDVpmXV72q9A6N6hQU2(NCNROF-HBi1 z{#--Nv?e1r7dLkEZZ$26Vd)UMrs(tuvoWy^}=n({Z-J#krc*AGuPQln)jG-sj$ z;mC&+VQc(2=K8ky7m)b<`|9|5KXThmW!UYas^|IRuOq#u85 zA9qTVwLLLBJ;}|hclYC>vpfc=IP+iNq^rFv+0Z`EA`63zAr+)*oEW$yPVb3zCPrB z%0@THZ&Ky*)>+NV_wrW#Qit$WYvx4vI;Y`Qb^W34<2ES&TCdzU&uNm^-G8(o3*RIu zw+fwNU9NelUu54Yv!QR}Z{E3K<(lIi_wRpw7TV*s-V@zkF4ye-`S60PageWYR*x5s zmuuXMsJ0yC5KNl7>wtfE#n#aAiI!hOJ zMt&VWh>yRZ>DbL?h{K+a{#-?H(F^M@XmY&Y*_q;t9SU>X&MCfpL37yB_R#eolxPoM ze)yTqMU8vK7v0``4gL9f<9oB~13xy56RsBm)*G+#Bb$gdxr`REs28I}+LyfpI*e= z1B@1t%V)HR4PzKBVs=*{y@0y!F0lFtSo0~PMXXrJXc5E4Fj~aI9*h=oGukJ$6A_n| zFj_?2I!22aox*4l3pI=uadSsTi^$zB=kph_;s~Qf^m&ufB1*FuEuwA&qeU$0&u9_X zbBq?TW-rDA93tjsFj_>}AV!N=RC|_>FJkN_MvKTzX0(W_x-(it`PXOo^dc6$!Dta9 zVi+xAjRT`ajQ#F3pI*fJt&A2?m&RxjxuJ{}G566aKD~%s5u+QCtI^m&AM|y~9zahZ zS+eK@mh_C6K6%*-sN2P!v1bE&gU$ugZ4G@VlGZxVXCiHZOTnjE%_<<-LFucJ^elHh zXfi8q0Lp-yfn*om3WT+d+Xlj7p}IagXnViKiEO=MHa83`<4MskiW1GBLtM4<4bOd&i+&dtbigG=XTU{V*4 zuo>yvY<*l3c3Y*G;!*!n%Q+&KD~3SpW8t4c;l%6aQWi@{`cKA-`PvtxnAU z!^5ly&-_1T>!!lSwVDY_{tq+#hsn%Nw<_;%(n$y6S-*=A35_n_9ed+rJ5jw;8h<{y z2zZ)-!dLwMs^Ec1YgE{@GKkCMnuEQEp8bPJ3*r_ zw&d~oEpNe#;`3VtUXv_Qe7w!zZJq}CutAAF4*eT#i!YO>owBkSn{RW}_E#o=*flXX+E2Mg;QZ>}|oD%$HNxoEOF79c;m4@ruB!!igKg7wnWxb>8rWgkM)B zoL}m?+)?moJQH{x#H#?WSv&9~9(_CDJ_aZuo`QH>k%ZfWN)8d~wx?9W`N4QFB%bYS z!pCX$LtjrK^0a_NpXe6AU4x@T46kS&-aUZ33ioH>W`hH`j&RMxOPi%9eg}^Lg2w#u zxjtSFvAl54zYd?_)iNC432l+SuvK_-`G-vm;3mS+A(q!XocK8t0tgzzTj#$$=C8wD zr~GyJg~=_$o0q?3MgaE#937&3t@Se|wPkqo^px&OtMI+8^pl^~GJWg%8Fhaho|5&~ z;ZL$#hPRgQ=z_lvzrOIV!-xJ&_~KUKt?Rexoxjfi&YLa6kG9g^gdHuzTc4jrw+?^(aLe?q<&P|F8Qwbmu~RL>Tc_WCp=EgU z^S{snYxdyi5Zia_@xjNkWq9lSZERbHH_t!C4{P$^>@YrxM+p3W<0SkzD)JT`Ksc_i z&pZC}U7P=&@7nB=L?&xfQ$w@02?o73G zvE_ZLmTer)X($%$85^9DsBPRg_MF*xZI%JM>+w6G!}8D1h!?Wt+|027H%XkC#_zk=6f~Dg8=aA8Nagnn9D@z~kk=(4_r`c=usbBQ(RVO* z@6Slp;;X^PQ6T8UG^~o5+$ZJ}(%Hv&5<{~Su+bTI`GdOnIra-A#h(T{kR-u|%uIZo zK&6*Q*(qX%KVfauGw+Ir2XyXkt zXKFJ=NiOnv=;QF=1s!WDFA|4onkfr<9u+!%OsLp=xXWha^{Erm=VE_B&XaW2tgU!T zLa83DHcQ6}6w`2R+#Ky6_?;vn{D(YR2gEn4L94L9^u$PAN;1>qR=9#Q-b@Voi;5uOr{4f1oiPpGzZngSCOadL3acEU6~BM$w752wz=C7O+o zOUXjV650vJU1nNK6gmvo#bOe6hv!=+7bj`Hk@CFO+T?SrY}EttK8Yz#k&bO!AI|%E zVX=<6#ZH)z=5y2VroAmekE0U!GmozaaM_Y!I4yi{<`(k)VJX-piNg7kU*&mYaPvc~ zN!+Vw6VOmfBHxSgr3mhGk}WVeg5%zzoX3WaCjU`h;s|OY+|Qw?#56)sU4;)eSNvC22Epj!h|+Fe;2S=ye7? z)$tiSEBwHL4xpu-liBFSbTyVzkv9@wsKB12{YV<3BQjE`(SyZ}&!3Mn~freRD(DN>)|Ka_ARs)}OI~+3R zR=}5-p5iOzjn9-D>r4Db0v?(9>tqsp?jeyqm;JX)6Qq0oEbgz9QaarB|D!{UNA^Cl zA^h3Vy1u!bwKYAv7Y{K!Ovm2)BYtz)oBPEygbl@k&B^~VEoLS=(Ufm#CdPU_+^i;^ z7*9kWlH&+__fh2idr~X!k!Y>A$zUKWzq5R_>oR z1KGbblmwJ5VamvH!(cUw} zGtzUKr`B_?XOZW5&nuoao=-g6dUf_1?6t*fhu0TgUwM^#UH7W>`oXK->!H^ZFH?oJ zqJzR-(M!=^;i~Xb_$xvc;}nw>GZb1yh9XC?O!21TBgLnRuNAe59~AY9hl(c(6K^YT zsdrcJp5FbuUA#TKRo=ngqr4}2Pw|fPp6zY$Uh2KV`z`NIK7Ky$`JDCn&d2C;*QdR2 zCtsQGWZyjHE@h3wi-E!O(xfQs*>9)n~sM{&Gt8Py2 z-tH6J6Wlv^hIx+ljPi{3oa!0t`Gx0ip4ghu%hJon>wWJ+Z@G`kx5W36?=#;H%AU#q z<%i0ls>`Yys$cyi{)7GH{_+0#{;U1p@c-2Rs{fDv)@nO-PqmABxH?*$sLoYyR_|7S zuKrSeQEjHN*9_EnX+ktpHA^(>HAR|hni|bbl3R{vZ~#u;PTob{T`rTW^( z@;UNc`EvPc`8xSt`62m9`8oL|`7d&Fw1UBIO1Ch#D7RR*bhm|Wue)t`JLC4PTZ5aq zdnfna?k?^@?i1Z-xT`#3JQjI;=27RF;q{8oYd&xKc=;|@ZdU%HTHu%Gx5RIm-wNn_ zt>2q|C_eztJprrS-f%nURs=1Tx}AoWCMePs-z$3h1}KwND)l(^Y;}%$iF&#g_R>wUocthbHNNS}0{188wS`1JD~AT-INI6QGt;|y{Q`RbDRJT?C^1JL;Qlw8vk1VJN^y+9o3`Mv8Yv+dZBu; z`c?H>^?T}K^;PvZ>ISuyroCo?<}D2ui?sx(Q(yTI`BRTOklEDB(<{kquGb>3PrWXC zReAm7)k`rRJ!psG6GgS+JH;;w3-7k*Gcxp;LEcJljdzH5ly{8xbnkrcP2Rh__j@1n zuJr!NyR%OqYO%=YEuZZ^hkQzWN_}qnSosd~o#i{v_a)!OzMFhMLOl+l4PN)X>)YV_ zyRV6|htfsqt@Kj{DrYFul{w0V%6#Qk~?@IYvc?sHXo!riCpqmP(YRxs9@bMJ-zd4YTZEgB zXHSf2eHAf^Sw4Gwy7;>Js(g2&ugaB?%6F9SD|aeCQ=U;)DQ_u%R{pMRr%F)0ttwG{ z>VMhaLET^NgSLE3eO7%zU7@a0f2+Qwu2-9CY%~KjQJRJ5qugdZqefX8d8+(%`E_}g z`(Teb9y@7<8V#b z4e^`qH`8ya-&=k={SNt+`+e*803)Nl{~&)q|1tit(E02B@B8obFZ1uCsiSiVVfBD~ zdAWR>o2|RAdy4xxcT1069vYmUQ@iG*r0e{k>s6$8dP}Kdpr6B`Hc0=R~_-+qCTa52puUjqcD;k*Hme^ zB6dCo%ZJNT$y(pQaq6);2rq~@@jdlT(?-!2%m0Bneu?LOlglR)>M_1-(J6d{xADm zsQqvS>Z6ILw6G{7TV*e0kn&aK1?7vXH*kK-Ro|!-7GtG09Qwsh){Z=$JZ3vyRI7 zf7&^p7uCu*j5{!q!9*_PA~k_rhH^2`Ip=-PIq%P-3keqk8A%*yE*RH^goKgMS`2^mFY6URuwY(KLQBu9@RKjZ`I5oN2Z zAcA+3q14*yy0P!jKzDwB+yFmikQTe>%Ys=nOJ*6bRRv3pt%)_Y&a9a=w-#22gh_i2#wJ=O;Cd} zngUy7K^A#hq-7ecK68V%(0pCmqkRzDh>qzL%r>KQy1-P1?T8(-<95O}Y-XqIjGeW8 zJCBJe+kst0Pd4n9ePDMnKYe>(k3e@*`^=u<`&if^C+tMPc5%$I;V>uVWSp$yJ5^Of zioj2K=m{+Xq;1{Ww;EQ{YFTY~sAC;kJ?jYhdu$D?p*4aor`9=ixqvd4R-P7ch7wLu z!8!JDk{a~irw!V~dD=Kp2WL8@13u&A}4&Y zEApa%{wRsEsGz0yL{-#89X@S{Ci1WiPU(m)61<0Q>x*MC5JNFSCXB^IOp)nlX!V)6 z5Oc8ilq*d04$tvjkWGnKFk3bBNRzjDhad7Iehk%5p!g}&zJSt8 zzAiRIRBVbZumS}uq@jBbnirsV1zOjja}yeOpzjg19YWU$G(Cr&m(X(^T1KJc7Br;L zFAeQ-(5(Q?D$uJ2t(wrOBM;?~JeEUwA}8`xp34h)DVHFQ4HZ?JV2*7?l~QT7qjG9j z6;w%8)E@k}ubQf@I%u{dB*PHQKT)UZTwS2!mTFyZ=&0V*TY6hlv|U>7=$ziw1zpk= z>;yHvubaB9JNi%`>0>=aj!g9Fis>%(5+t$#7T@%?K;sn2o%VLToVN=qFL@O&RQ>1s z3|N)bS%bCM0qY{Q`fLCK8?z}p!wxfN3l`#G9^o-;G6^&|<0+ouS?=>Z(zVP3C5%`%l|awg|; zAww#xBG|6tDglaO*s?Mzt9+GLMO9XTsv;K}s)fC)t9q)h25JP(n1YgLYOWTb#juWm zIN~~iZHMU;*g30xut!msb)c)dt{b|g4|G@ebRT&>(qlaZUC;C!bRF`-Uc`%eaWCN+ z$oQ0(@v_*C@?Oy^djWQ&y4S!qao}~mp4ayV-pCt+#?HJMSZv{il3`3>EEz{17)h2) zB{SGHeC&TkFl>;lChN%tIBjipudkcrHFAr*N&daJnyb$eS+UgG>i>WfbBeBAm{BWc zG4ySK#JrP}Q}jg)9g#yn1n7i5dSF3fNPQm(*+RNck?1j`xR2y+A+4uK=$J#1%RacL z>9m|X*Ak`?%M6_qm~~Kb7n|3KIR+cg@vd=q%S~Y8HeBj5SGg%{5n1dJJ~%UvEGi<6 M@bv#5|6v9G1`gwa{r~^~ literal 0 HcmV?d00001 diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-pkg-ghc-7.10.shim b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-pkg-ghc-7.10.shim new file mode 100644 index 00000000000..9e85ac7f0fb --- /dev/null +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-pkg-ghc-7.10.shim @@ -0,0 +1,2 @@ +path = "FINDSH\sh.exe" +args = "ghc-pkg-ghc-7.10" diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/setup.test.hs index 0b0a37413be..e60d3685863 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/setup.test.hs @@ -1,9 +1,19 @@ import Test.Cabal.Prelude +import System.Directory -main = setupAndCabalTest $ expectBrokenIfWindows 10179 $ do +main = setupAndCabalTest $ do + when isWindows $ do + sh <- fmap takeDirectory <$> liftIO (findExecutable "sh") + case sh of + Nothing -> skip "no sh" + Just sh' -> do + let sh'' = concatMap (\c -> case c of + '\\' -> "\\\\\\\\" + x -> [x]) sh' + void $ shell "sed" [ "-i", "-e", "s/FINDSH/" <> sh'' <> "/g", "ghc-7.10.shim", "ghc-pkg-ghc-7.10.shim"] env <- getTestEnv let cwd = testCurrentDir env ghc_path <- programPathM ghcProgram r <- withEnv [("WITH_GHC", Just ghc_path)] - . fails $ setup' "configure" ["-w", cwd "ghc-7.10"] + . fails $ setup' "configure" ["-w", cwd if isWindows then "ghc-7.10.exe" else "ghc-7.10"] assertOutputContains "is version 9999999" r diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-7.10.exe b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-7.10.exe new file mode 100644 index 0000000000000000000000000000000000000000..537023174dc7a094f693b3d9ef17fa234e6a4bf8 GIT binary patch literal 115712 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 M@bv#5|6v9G1`gwa{r~^~ literal 0 HcmV?d00001 diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-7.10.shim b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-7.10.shim new file mode 100644 index 00000000000..16ae1ddead3 --- /dev/null +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-7.10.shim @@ -0,0 +1,2 @@ +path = "FINDSH\sh.exe" +args = "ghc-7.10" diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-pkg-7.10.exe b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-pkg-7.10.exe new file mode 100644 index 0000000000000000000000000000000000000000..537023174dc7a094f693b3d9ef17fa234e6a4bf8 GIT binary patch literal 115712 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 M@bv#5|6v9G1`gwa{r~^~ literal 0 HcmV?d00001 diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-pkg-7.10.shim b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-pkg-7.10.shim new file mode 100644 index 00000000000..8558f8a0513 --- /dev/null +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-pkg-7.10.shim @@ -0,0 +1,2 @@ +path = "FINDSH\sh.exe" +args = "ghc-pkg-7.10" diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/setup.test.hs index 0b0a37413be..b5f6b4c88d6 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/setup.test.hs @@ -1,9 +1,19 @@ import Test.Cabal.Prelude +import System.Directory -main = setupAndCabalTest $ expectBrokenIfWindows 10179 $ do +main = setupAndCabalTest $ do + when isWindows $ do + sh <- fmap takeDirectory <$> liftIO (findExecutable "sh") + case sh of + Nothing -> skip "no sh" + Just sh' -> do + let sh'' = concatMap (\c -> case c of + '\\' -> "\\\\\\\\" + x -> [x]) sh' + void $ shell "sed" [ "-i", "-e", "s/FINDSH/" <> sh'' <> "/g", "ghc-7.10.shim", "ghc-pkg-7.10.shim"] env <- getTestEnv let cwd = testCurrentDir env ghc_path <- programPathM ghcProgram r <- withEnv [("WITH_GHC", Just ghc_path)] - . fails $ setup' "configure" ["-w", cwd "ghc-7.10"] + . fails $ setup' "configure" ["-w", cwd if isWindows then "ghc-7.10.exe" else "ghc-7.10"] assertOutputContains "is version 9999999" r diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc-pkg.exe b/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc-pkg.exe new file mode 100644 index 0000000000000000000000000000000000000000..537023174dc7a094f693b3d9ef17fa234e6a4bf8 GIT binary patch literal 115712 zcmeFaeSB2awKsm|C6h@qVFpMbN|XVDVgni&(8LKk0Vau-;DpFbA|_}HX&kLmI43|$ zAn8doC&y{I&$WHpr}kbc+G=er)s`1+=_J9tAoAL)Sg6Kcsym)kqtIl)nDczsJ~K(M z?Y+I9-{mJzb-ni+JuWY*itL`t~|M0_)i0&_KaBq?xc0cg2d&ON9 z?yo+we#4FF>8Uw!&_i!b-Sp!AhFOWfAD`RdK7j8ZpWEur;qPtkr||CU*y{e@{JqV+ zhrf65_m9tQckjpdi~G0F>c{*2j&1Ij_cDJ(lx?jlOTN8h@E{k-Y)zF5J%LYuvrjnc+tPan@1Ay@XsRnns`RaO9l9Q>_w5n zllx3UArJk7N1sV>qg>$&CL#MDWTEIvr28hO1J6=I^&kAZQQWXqM4G$^nFudxYaH)H z5w{@RcjKn@_lx%n!jy**OKsnXcRt<|{`o+V8;xwjz!W4zk)De8vwxE>dgG=I4?Xf_ zfwxIO+XTx0;@{+3hS>lA-~R^`IB?=rkZM5on?9O~J&Ec$0_3j*N zFchBc+;3i2>+P22Irrab4x1}$TYAN!@Vzy)-eZ!*rzO>TkBf_(`yI=CNRj%rxoVFm zN?~!vcrIJ5e90}Qjb&q{>uNgH6**R!31XJaOyX2}Op=*JOrem~6V)t$(_s}ND{>rx zu#iBP`GBc>*wuO9Oo;Fp5OarU2rDadGJ*m1 zExhNKtNqHoIoWzlxCNmqz`hOORaM<9ax#cz`=?{Xgf~}( z>uQz9SNs70tHKXZkYHCO;=*6$L5ho5{isk_YDGDxoQ|ibH|#@3YagXH=g_O}_oyMH95zf>m~BOB8t2$~#h*I$M5C!Gcu|XUp>l1=%8WaTRq_cw?=+ebs1c zWLvDt`JJdG=G<=!-(Tx(mkKLu3yRIs4nVMq(w1-?ecPmmBPFJ=Il!L1Sr9^zRg+X! zzJ|?5o8-e8%Jv+WX?sq#R#rt2mZPY7lT=6$z9KCNZ#E#zk3*=9Ljb~y%L9yoY`{Mc zaC`vdwsa#QTLs99I5FZxc-I{#fAl%SqDpK`6h z2-}X*~nK>v06sDsQ^8sWYJ`v2* zGu;Sj52{NtDCUi&=g~4}%S)&|T(~X-K)x{8_yf!cpjkHRpsp?im-~Fkqdb(e65+}u zgd^7Fpgh%Gi28hJHVqN|jX>RebfxwH%8S%fVN;#z@}V0GIZ9Gy-7cf6|AM&`T^;?D zx;m^I=w%@jKxPGu&uqdHc&kfX9AAXz>u=zhp}(Qctf;%!0QDmSlmt*f85m}vSA=zI z*b5#o5c-ilgFprQcRba{a|R%SkPjGU)Ksta9A&dXg{H$KtU8$&MUNuMVTlqF4*FwN z4ql>jjXD4^m$`zFk?d$T0(B`?A*yGVA_zjP#H*U}H4Wro(1oY#nE^zhFOtIMs@HGW zv$wZMP||-!&&+4(dCk-GT=En>mp+MS?c&b5? zMe$Po!k%C8w{_0}yd!@5p2PIra&AP|yORWjP58f?68HS3r%32d+KVS4-ktO-gos?- zNzr&HY^{7SDs(p<#y2P<7~g6-$#7+5QVieieS(@U#J}rKpc`1N3fW0iB&d-6 zIVz}S_W!r3a2{0npS2xGDy`IfqiIRJXRjs@h)lgeoZ3oX!QL-n9r?e=uxf5r|c`7(*z)Ztx*E8$orDJ-Q5pHYs`R z42TErtZ9ylo6r7CSLQUG$ge@C;yv_Iw29scMcon*#_eI@?XU_ZuJtN+~YqpxA&?=AAS zJDYDp6zaG`NvFs<5i+B$5)YOEG^jb^nEDc4HM^_-V-bth3_ zVlXYK?Jd-%OXt|{@Lk19fTTL;(F<-9X9U@FibE@1>dm3BIiw!L7zG&p4K|nOL$0Yo z_OXGzXxDFM3vVMRH=r6d#tz($R~~yFuTT(5SKcreF6b!-$OE_!HlLM}*qNmu0+FGL zs;i3QuXbrm)UpB9g#P#UVe-5clBcSwQ{BMW>!=;Y7d1A#F91L*03=HJ`_!_*^-4M# zCseJgS=&p!(SQLIWUnBbF7>f3cpqhZP+7kSNXAX`FDIen1{XzZI`^7tXpqYdc0o$+O8PzWn%F90vlpGzFv+?o zTHVQ9EBHrhSYQVcU#0c$HF3Gvxb#0zL=dg?9aJTI%aE8PkD8<}v9~x6ir2LaNwe$D zAQ#)b3`J41v+g{7t~Wl#+(l6>Pwv%~bjqcqpX1Ly{-lgbI^)j)JiC&pJ`>Qc?hGff zn?SjvVS8QQF9B~gx`LSXK-oQ{exVUQL8{(eh*uL<-9CYqrqarTX<(Atg4Qfbz76y~ zNNKt4fpWGTeZV>QdU+FnGO0d zOwtTmVipprhR;-SIpw$W&Y;pg7;i@OnNl7p4`j$2E@BqBC~t_-oOU0Is{WYAe^K#| z=$ZH8b0GyPjX=adfJ}GuOoNfK5s!bs;~(*~_jVdnMlkfdRqy#;IRs>NtVFCW$E54n z6QmUOc#liT2k%0nHVLt*>60-9xA(cydK4~ehfl7(+Nq0wMORw5MJo48>A*? zu1A&N$Id!h=i_0*NMvuJnGl}|S%%>&9PNM+C59rM?5R&sZK+kZ=P0FC_C6s&UuJv( zenFB0l{ue?b{^@>k17{(9yi{`z?xUQd3zKh3Ml$KpQ^;yDXCNMz>P^8=cY$o`&+y66Q46*bpJ+lr3 z3=5G;efVs||E%JV87;W_Ec$u0)6jDw{ut?Z$O)12SaLu zUA?90wl8n~YM(S$-r=%HGu7gZrS7DEy-K`h=`4CpTRNLw&ZUCy`zF!8j^r8EqUs*-E*Xvl0fb>}OL2GtJ@R!?H5e)H#Fh-B()qt{r=~7Jf zkHlpH(ceF~eh-!7B6hBwP?iUB4Zg@!bvn3Bayx|U1r26}olx%odLPuj*8AT)2 z=M)RjQ8ruCy3_nI<%@Qu!XYgOl(~bq>&~T7n@JGoEWOWW7R2nO8|js~G+?s`;v_`k zm5fM>AWc@6I)J%++@$b;W-}txvh(5ON~LV1z<+W3O`hHf)uK*Rrmd#V0FVE%t;QZ#d5ZnKspai0bmO(xmYMWZa17h4q7&XtTLNTg}aO}NeJi5@0&NLt2Vjc8mYG` z$&sB_L|HaZzTn(3N$$5t>g~18H=L23_Tet54}!SC`SN=fr~E5~Yn_j*x)`aysOkvS zxa9skyo=pat>^+j!)?W;))G@Z z1~jI0Bd)F3+*)Ezb{-g=a>9vM?98y70)t-#q*k;xAEWTd}3J#4-Ul{(U80Mjj*X zina`Q(@+qdcdWXL+GKo69~(nzQ(e=CjYw|#h@R*!8~#?g@Cdr`sL8{l)`!Q#0X*vO z!(+$B3(lR%_`3_)c7~8`=Q?ED`4wc_`3SP@+=6U7cW!LzCz!+SjnFluU1m)D*ejBz+vG zie`a4QM=?m7#E!_|A~sh8t?9G{~%ecjXa%$Z-Mi-jkul0S&#;04Tj^+Wc=Ml3>rcd z+Jg96A07_}@Tk8Jj~yG4@D;?NeRym^9NHJz*9fSQ-_i33RbOSLnzm`;!(!yv&*r3+R4{m@w^N?=G{hjZVG9J~4^ z1hBQG*V$YM27MrE!aw5IN8dpO2B$c`sUkc<+Wr*SSk=p&V52d zxN~x{-0hOzAIv>&fT&-YXo}H*T_7V7pJd3+5;r~a=;5OW5xV3)dTcaEoM0#D(z^7j zHZ~V*zHO{d;<0S-9&u-hOYU}quMoF+V7PrIa1*~2+3xHcOON9}+)kojoYb0J0`ePQ z(kH|1m|z6a4)#OO5C_JHE!~M0@cxC$QDT+5?U)pdbO(LnKp7TfcT}UwM=h`Zq3+Ps#)5~ zboEpD(^09nxmUbVa|0tFBxutK)U|aSkC(w`y80R`MByMbJ$3;R@?pE`zX+W`{WDhI zetT0s*KzZ)Y+GFfQr}cZZ+2#~39A?@7K1a?B^09`3!AW7OV}_}X^=yL%H&W_u!E5N zs^3wt)gewXDhDt3unr@dDpx8UY%}VIRe}n>q26If;*Mzl&y5!KM0k#}*hS@|rKV)*jn&Hb* z?I`V1P37uF`?yi(?<}XWLetkcsyplgZ-he-7hSoqn8g=ho!;F=v2a_r3Uy&i~`tTn3x<>htv z%^zD6B=*7}an>tyiES`k^3+N@a?kf%rEYY{qodB|VoJC>XR&;FRJ40PaXv~5ipb*n z$h|MQ)HJ2kA%DXPy)6nRt23c`i~;s9=+T1+^N*+T(Z3tX>%UD}EBGmkRy9Xajdi%l zYD3fk$}4(Mzg;c0dwN)wMmD9oEPbOx-{{geX0RIp0ISDpo(IiR%m=^&!UP?5O)ylU z!kpwe>pA5a^62`>wHV0b8PpHdkJWaV$S$BZo~;)db^X2gFh}ozWMN@-UD5)dP_Acg z#bOeeCP1uFAIh<>E+?x$dx{UCM5pd1gWl5B*Z2f+=6W@qj8|Yrwec_l-Xi;^ByW+m zJ}I0IyF0gR7@Rt3X$DkfF&UdNGr(Sa(TG(t*0;{)U5n5(d8r$6M3*cuI#ghzhVPXu zp*YwDe@bKOOqKkpE>3SbE78scPhw;N;5J#S=d89Y7@mg~&p`$1AYzBaDZzL?>K2}F zisx)aJZ=|{)2!;-o}nO%!O@|r1{H57La3c z8TGXGXAIoklo9#FNdbd9(|My{ChCMirV!;kLt&xrDX2vuwh92a(L~JDlkP^E+?6GF zXUU^ko6f?PWq@52#g1@LT|((-ko&=|tWe}Y4!(eDD^S(bdC`xupqWV8IL*Cbl+&W!A|zp05?QEi#pXoSPM&xK9XZ0X`U*Lgp=#Csxc9;@Zv%|RX;>o6{6gQ zrn(^C#|0XS)Ku$pcL5l12-dBjQib%O5P0iLd|x2$9Pc`tsquK%mq&+b`Rc z#Rt@Gx$pJ|d-7H5cU;F2y~3VF!z_g~8%)?za(A%{&D7cH%;WBY+NVD@7-$1}t$(HGm;dx+y7RjSn{N8Mm48eOCqk2<6?`V!vE-Nf5- zc^j+Zu)(NC_C{nU_y+SDam_p~oK@$hdAss2K#;7=SIaObi&wKhVLs~?ra^kJs}Y26 zM;)bXe@||331T15^?^rM8qO2TN6@}1rC|hWog(#l&MsG~&v~mI;tWbW4x4M0bAMFv zpIJ)&YtoHg$u6dOqP2<*BOD;&(>%Kl)v4W|pSqDv?lJ?e97`2@muq`q!y>rzsnU3> z%CP5AE@lL=@nGg#37ojq{Xaubhh23( zqN#NN%uPc=%3%LGUhK7noSYk={=(AuXV2N%f|=smwFTEo>FlAgY}z@fq5EeUzGsq&6&K}^@{v)Nw>PHnbO6=YA)9-G=t5)pK}kLY&v15P)z1*m4S z%JKSl!6ky~FGT&+*FjWnXXOM!!!F}_(45*rDrAt|Ozc4<8Dp=1L=sT3kG+irHuf?d zb&Z5WDR3Zw7(&?Vdx6pjDzt0%U8p-(fSvyLDBa-@REZW9C@yo*@E=VTecAa9=VhJa>R?1K_H*PN-zPm~7)RA)}N$xMtF0 zn#@wf$#O$Ry69~4y9&Q7+6y-uyK}UW2O*_?98wQ);5Pu-7G1Jhx-_!|eQ30$f^tMw z`BdIuq?^@CY?LH@wY}65Q+6y?kE_9XEvI%`Th5Akkvny@({oB$HE&pQG~Ns&#inRqk~P_ULM>k0>e5#&R#z?7Ud_Fv?8w)P7n4RvR3@n=4>8SO9l6k7NCm*UgY{uc4x79-Jy}iGY_d}a8o|7;CCmF(5d*+SL3I zdwLB#5L%vuQ;=G0t%^h*M+l=ci6~`@M4qMu0Xt|s1IBHnWfy`0$QnHlMhWg~8R5wR z_5>J`&0dBa!n|a**8ufQ`TX9zG!MR9=m|o7(+ZNdGle&$@s~RTXwO)UI`& z*K62|eJ%1-Z+%U&l&X4LYQ$%1 zwMSN)koOZTvp526W%fu>U*SDlrZ^9^%ginJ?NlAFJ_)@|Gkbc$PZ4Vm#aUnd9^z8dSD8)N8Tp4E9iA z?SjxQ4X486q5{($7#o_PVp2dpn z1e961mKFn?zevbLzC{Cy{Uw!;=oy}~1vM^b3tRvM_H)3CPnCbZflpOfUn@2FN=DF^v8VY@|@vuK2r{#aRHmDockp zMq-e9s!nJG-_ws#d5Vklw6$Ix}g>UL>Gyf=NH2SZe{`&w5mgp|avfPn{S z#W76b7;?pr7Oaii7Jea8K2JEos5R{FF?3(m2{nI3fu3Q)4|iHAx~Q0YKPJ;b-tr%Ux~eLXVWy_;u4FX-Z_78L1$b01*Anco*I*Wg=~{Z3XR41h_GxsPG~2`a)5>x^Rn_UifusAri>; zq|HNs6dr9R0z?*V8gIcvlAT%*wrb|ErBW%HKgJrc5vU(~&W0? z*bh(~Wg!!ev33wv_6pmtQH$N!*g=u;tf*1lM^wQssQacH$;WG+} zrNl%Qf5+!zyBtf~@&)I<#uG)@e$8q54PM+{THSd79f<|@0dy?AXf#!0gTK0S*K^49 z1N{96e|zz_AAf?$ELbf3XphAZR3W(-A_I!p))6cTZ&aapofWUw>*v!95zyDWh%G!p2Kq5tBX9#!Dqqk`kP!b|h7U-6A`D0rfbm zxS;D0)=mWT5L`e>D5^e2IvVCvv)Zi`FGf?af0I$67RAV~q=?jR{|Fl;M=QR7QF~w} zHLLH?ki{NGy`8sDub&qv2jnLKnJPPm`~mnHRRq}dJHZykZu#(hu;*IpWqHRuLBdKB zMHjOO95Jh^s8wHq#3_-cb8Y}1kL7qCi~w~jxEP{sfs_hb_?9XB>jB8BJ3xzvQF4`J zmuua_UBwGGN4{=qOI-%Be<}CPy{2_aFrUvUpk*lDDMS*ZUtR{HU`X^xVZ0YBjCMNr z`$mkG0#WsNfPMNgHK{lsO(%RBP1b%_OBV}73K zFxGHgraZkE1BPpOc4Pf9VKg%L9h|i@*eUlI?NSkhL|j26?}IvDMa$+~dR)WBwo7JK z>6lua^?mGwhOlr#P)XJ%)#6=?KvG+AR%d@&uA3Jb^t4sa93BP9ge`KrvyAPi4I`#|U9U5Sm(mZH1*PVTm)T zzPKF@CTNqq)hbA2p~%pohWYIQ_Dl)Q#~6=rd>UJ{$pfzO6&qj4H|{7D#CxgBb_CTO zi#=yCh@AW3bz~+lw?NnicT~uS!2lDM@UaBst}pNpinD22i4^0+h&0Ia7;_8kQo?d? zO}?~Wn@MV-cGXzE`g}tPBw;cY*|097j`6&{mR)rM3$w&PgZK7W(=y^s!{Q!`XotyE zjm3X;KS~?RXfjBs)fwu^pt5F!HZCLw`}Va+#MhwWfhB}CYHgO+uuOrNRLU-T-x62D zVBm7@v#3V`>=)=`2;1whPFG2|rm_GPFUwF&a{d=2H;@e9&J>BwRDc(Wz1Q8x|0X;VH=>vt;xW) zH`xsQ7m-te2O&%eYX&jT!;>BIDwFNMW{e{~%0^%GU@eQC-1i~9l`^LId(aJv|7gU2 zPVt{Wmnr_=!$la@;E1203wxBZ^LXK}OlRA{NpUMib^q4@*jNLAV`10i)Wuw~5Ajv; zT)WAoE*O$yN!z~;V=FeY8yxbVW`^CBxgEoQm~m>(3Ge02X7$a8W0BhB{a8$Ggb+yb z;k4V3+LL?Cd&Jpt0&sIL!&Bt_K1=M?k3Z`5c8gPA{i|qt^|LplAbqmj?uKLXU(j$E zx@?UF08r%Zk%n@Qy&Bun|1T&m$4uKdjaTmsyZ+hgr8P#?gU(Q|C5D=(IbEh&r`TTW zOjPbdeTuU{Uo84FioBnQldxw|U@|Ch1Qa;d zAEpWP1as0!Orc+n}xU@n4POfBiWA&SqNK^ENn} zZ#T&8Jt7VEWAk07R!rpEf4UXYgNYWP2jsp%OFK1Siqi!rrm?;tpC{l-Z2S+}(9ib* z;|v{HybNbmCX)LYh<4VO0e0fr zan42htNI$ba>0>CP`BAzbZ0Z%mjzi*lCTw}RM~y~F(RLCf*#nT_iIGLVk?v>;0&{= zyv>Ruy2KcfWjT?+Lz+#g#P*s4{=GwLjr{<`K(xTLr9`}~sUU)|cvDlsx9II|D)=_N zCpQ%Uuc+E7ed$0Gz-W~R9;H|L0UDLsod>>2ujL1t=~dWN@W0|f{xuE+hfX<=U*ioR z*Bn4Cn6wX|5$2dd#yVk^2~?Mmjk@2_k-c$GR#Zyb#O20R*cif`PU`-d|9zu~zBNMlS~C zPtDlm`xM(3Y##Pw!qaMSa_)X?U#eaGmqC&c+jbWYk6DrT&u3Y#_= z1(#fW9g2^C5Gr{R<_IZC?SkJ}r0gPg4$5IqR2nXphe83i7tqM{>LOX6=u8>yU%UAP z{{rd@JJu=r+9E?c83};M5$mG?cw7y#dX$9H4=kl=h%em}Lyg#?8{RWQfp@e!X~t}b z1%k|03b<$BL~s^*w?C#`r>==%)1;%|RuRTfYf(Wy4hnQD=>&mRS??&B1Ov-spn#3o zSdje-h15<`Y~yP|s1hJs7IvCkA$g8~!O_i~=E2`+v|Y)QqhNQ(qF(s5HQqj3N^kDn zI~xa;O7N{M(JgQ)NNP)NwH3D|m$dpvorj_Uc1JmCL21W?9uMig*+BmATYD-a6j0M*{Jdl}u=wZYkk*8UvsJfc=X} zc9uCnXW(m*XF;9=)i}**SC4P$-M+a1LIwFer-mh$w`cPgoWCe@wZCUpyM|AA+v{gU ztdnq7o9)N|3xTEBDFncla5*s>2lHrSr@DUxTZy~RpsUf4*#$}G5E8Q(x*8E;3R?&M zMv9GRfdvAtOOzSsY7hp;iz~5wn2tW?V^M+uLtkBEJ^-+F15uP)NbajhB~-w-6yD%58W`Ev$gQVvs!#+aR~vNh zf*n}}bk2}WI4iCSn=05(QA@ljw~*UWMG$8ATc`;8H{_+9QSq9JAX`^Khtkg=J9*cl z^8s7>F<3q|$T|>P1r`GSMh}oNBC^8@n;v{0;*x%iy^4-24a3=Ld_xS9kj@((R`5xU(q8`dBdFd_`}lXR zCL+f7@xK5TNjOV@xR5wk9JQsbWxjh~O@+w8^(g{&69N0Uap@r1DL7lci-It%A7uD^ z%;Y%>v#e_43%2>{Qa;xm$DFu(0LjpwCwpS2kAqRhv98O)^n+cIm`O^j%R!iZ8J6#{ zW5c$BENOCGE4&)(w&D?|a@{V9c$^}h;be!Nf{f{1NrV-QIQA|)uWSx{i*fuEG$6A- zJc;?y<7`;w4gU8;n;Puod5pu3apsT*vdGs*n!<8%BorbOUL$t)7>ZX#{0(rVU!kxmI3%e#vK?q|&1hRnU41Oq}UUM-hJXgnP?&O@x~t7~Ui zo=D{T1|EQq61<)04h1SldkyedLBavV7>JiscajacZsnIqUg?>?K^mB7POxr0VlYb^ z9(W}2;C(Vt%cz0zNT6mR3;FlOg*JF)4|NzkQgCw$M8{u1WDH08B%$(l{FAdZV$6hF zuMwG0mw1PB_j6~hplbJw0Uj!PP@Umuczrc91 zP^}zR*9zASChf+*i8E_g=j^0>+LU;jBc6Zq4FYux`Szh2?ONPpCiTOoeAJUBG( zWRdW@eDY_I&Nq$D$CsFa3jxyLTxGcjnX1SK&8ofo&j^h91Qm14L2{SyJr>``ghdGV zWMFi_%rQ1V$i$5SLav($je+%EhjD;)&|p}oRKG=j14Hd*3`?JUSr4I<6k`&Vc0>MWo>8VUA{9Uj1p4&h ziJ*Tt5%gj(;r|TukEyuPRFGb62jwyK;6|W4S}l^{JHB#JuZ4tGcUV1V)Ox!o<{3PF z{PeNYuX#st1`@UAUf}*(?W1Pz;1;NBk-|LKNiAXbI`8PFYr@u01zT82$_DLnWP^CH z%)!u#A)FJoVuD8cX@3QrYNRJ3DmBo6q6Rj zcafFl@eiO!pLS>#7DJ_oGapX+SEz4=ly60ylHWT09OZ^ z5GEge_8?{tyvajq2|rH6oS0XF>_39^ycaAMWUVmr2iYyy-o!c+M*B|8R$n{{0LC~d zuUm|&$jo{-sIb>W4Wm;Ch-6>F27|sN2SLw}Vnp4=qeyfrJb~TDBLqkTWeG*I1&9DM zDN87h>f>_~DQLKiL$wV$+wD?j=yyU#kpN+uie1c4NxM;QGt|?%*q2DL!GqOvk0_%& zoi7rn#Qn8#Da{{oB!SKtP00QWo;@)Kaua;hySTPOpVLmYKi4-hI3niIgwJQ}-^WEb zbD(;|HsGhd<}U5(a%>$TUkclcJc>%mVu+>NhZX1=ARL;B|)7%ekMl zS#QIUJ7`-;*tnBEUI#gn)|$#HDEn;fxMxT^%}UYbklpt1H1)utK2Nko_HTc zI2os0!lt@RLGZy(|2fPf&|whrW53kEZpd%9N||_?#B4lqGO`IS-h$9rpHB3~2bgc? zmJ5d8CwH@)7b$}V&u%qyubWw_lmU9&D36-A{rK5OD5;&K+p29$};}8VkR- zo%?7bBG&ln0uoKoH)C2-2Uv!1-7R+iFQDY?OUht#T^^_r_m=rUtlU#Oz<6qPhv*CU39VUgYn`F zaS~iZTYhqZfQ`h)@dWapnBek-ZKoiHOCD)K3t>GlHmcH88}_LJbI^(};DSQa4hN0h z)$F?%uUaPNGV--0J-hvj|CeC#3UsMYQO|SJX1Rr;p zX?x;5+}i2fpOQPaZ__j|5BTvZ#zT&*IG&-0j78Y(=#;8(AkxwYa}eF?at9h!XIwdx zhpwfln-OJXz&Ssq(Tp z@#!JRj$v04oqL12_g+vGgrBKPS;k>4gJs4I&zLvCF-T5Ws*%mJgrGq`fus28_yHx1 z_9JXE*ym`%mb44#qjcvLGB^n`7X{W;?5?x-;N;vSW~lr5&)Ge zcJ>ow#`y4V zJAXklr8K=*%V00TO9vEn2iXQ%>>!vK4BPc3Pho+nXCCIgCBCJlvmXEn;~2xZ6_d^x zi3>1Nv09Ip=rQ^?3rF-&07uyP8Os3sPtXfXFCbrct`54w8G29%ip^DgT5xsNU8KkX zdQb=_;dHbZYDs6^;s+2ppB@wnXRtpfQdUyr3VKio6X|R56fVT#XAk>-gh+K}#QMX0 zFo2qeLAVQ4N#nY%j5Mu5&Hmwi>jA|$hFCG-Kp{Gp&WX|)#3fP`;W1>^k8rd0?fWcpmr*)7H~4r1YbyU7k>;+7-Q!Vkv`QpvFL1B1GJiTgu=D97-Z%N)OF1TJD{g+f1KSi3qAoT}WT#%e2IB(_ zc^VBd>?c9?7s%DB$1KpDuHv#O?8debHib?f_i%&PV_vRzCpfZhJrVgndQd2w&F<$t zOiQF8aWc37C)qE@*8^{018Xj}x8lZ2?1Rv>GDw^_K1Av6FJD5{WTPZeD980W&U#{W z=ID}Jm$E-M!pAE3d>S49fN2K2gmxZ9J5hIz;dKzKa}e5Adhp|!7H)1!oL6*m+{Xap zj3u4T9Jjj$>oTY$hry3%;sPq(9HZ%UW7~vA(Y#3KJL#OJp+(naQ*jQ1AJa@?*Z=p$ z>8xhFcn%fkF!)hT8zaG-KpuxJiKOEvErGY4BS7ah;}GT(1P+ED*POzBd?kec_PA!^ zcutUgjl}%_<8C756y0>fpmU;|*o_I`py`#Z(zwm?+pw!+M-dG?NYvC23@YTb)bcBkQ2L`UhS#ZP_i zWgo)mO6R&oi|#+4$SjYY{v6Bq+-2nBUvkb~p;&t|VWPr@1uWR-KW_&HMk--M7VSnt zwfZG=ji1cp-7xJK#vCY8^|)mQaceO$xTd%WW@XwJokaF+Lii*DzOdON(*?>zxF*9A zjU7H4&dkVmJ%P!8WnKRY)!7-IU-uN@auTz+fy=+&8mF4dkGJwOzme=mq1h|a@4Xkq zyJ)kZProI=$eo>Ic#9gct9N0`CeqNSG#rNGky3V4S#tt+o55{~`x~9Z%KI?>&cNB| zeRi3~6WoPh*!$@}gKGuhWK59qfSWEugsp&|0wR-MA7AvJhe0n4g93v!0iI5`7G6P5*jVa80g)Uk_vpNS8qlrwC&VHShOwUh#tNr!@5jYAP} zxe6lXSPIRO4eK^!81~y~2AX(G56d+u0ywDtHHSKFm)gOzmkf18#bs&%&U59);7NAB z9h+D?7KU(hPbWLf*e*j|QA&7}ux#0tx zkoe!AB{nPvTFx3qs-WtLEXT1$%;*OMH=IQVx0~ro@dpZ^al2pysqzl)Kn%91Ftt=+ zzfrZ*YHWpkX;i$u?e3Y@p$?OH^H7IfO2Y*ezei0N$8&IY`M3;Q`Xz2l_m5aIBK%0W zpe)O3TQSqxx@;aml^FY$-cjkN@m(z#;XUwa9Vukhp^szj^zlKehH*HNTn12P2)1z|_K$iNUsj-pBp z&ZmQO0MDo0Ajd3H4uW>=T8ii{&H`a|E>Dm@Rka@I_VMHEC9;mg2q7fW79>ozQ5vxB zUqB;GW*^^-UiHvjzt{k)V6*e_i9U9+Frcv+DD;vEiHSi5n}pDY710$NZk=t_?*r6_ z1PVQgLzL>HL_MG}DZu{EE#S)^(>Ejy30>?s2%G*mCaL)eP`WSzXS?WV@GErm8yiWr zA$CtfI_2SF3nM%#=7iWXgwe(Aqc(O6kM6s@il5{EHC1D2*UV~X7XQ)Z*m4hm-T z%D^;LRJY}=#&5v$`RkscP%$GLHGz;)574ps{%<0GtN$W<7xw`;_my3&l?zLShPfej z&Va8=Q{iHJ5k4wkz#y*Tg|xfE=2rh-Yl4PDN-V(k!)S_iF~Ln|Bhcf!1=b zaD1!;=N!!2r^wM!rNpi}o%>B#ohnW(ImDj27huOXVypYViQeTx0OAPUoymU2;Y|ZP zb{?i?3~vldpKDh_YOS%ioI?_L9j^#(;AU2P(q6+g%c*cK zs~*9eFmwXUd=-qll#P`BPo(j(Y3Sd`UU4pM#ag&s_?2idE?1$6Djcne4pd!lfN2%GN-yPseC{PUPCchhbV zgf5)1)t*{!r{u6)Mi?Ox9<|Q>?Q-mX(JjX|iBs?kB3qm-77WyGn+Yp#&DmW{9$12w z(rrsYKnYqcmw$;3$#80`UvE1DucEftJp_&J-XXS@V-;IAh_ITtoy`a6o2B9MO$fd` znPrJ{aywusW>#m*zX2Nd3A5!%F72kKNsY+*OH==&cm-KD5YV>nH!bSbwqo4Ez3N%S zRB0PfK$9oAUoy45rq#&oZm~>elSChZzlkckR%SLFg(vv80e+Cda4Tr&tAC^Sb=dL- zEHZ^^FB)M7g?}7m=aE~p1=(-$t_r8#)7Aq%9zFxZP@mZngJV)l7I?WCx*c3N!|qC0 z`?}4w1<7Kpnd}X4GEH{2(2BIH*ly}Sg+SO+_c*li5c>&T)ImM!Z22kT_fG z(g7#l8Gl9Z$d~X_BD7HD;Ae`la8lh99L&SUG><`>+Jv2As}N4rZY3WFo*K9^)hysZ zTs9W0dwJ@jvD92DYZAhfDkF|$NDB1?F+_Ug4j^G7j`%BLT2A%fgx0cMACau#vY`ie zx~+rFJFz>1>)e8{3d8P;@w<~RG9nFd{(0t^XBrz~;BYZi*9cnDNqsu@Nmtwi*wB~J zu)`T>Ljn0*B}HkNMd6Wu5xk5T4Bb+C^TCNHMsNlOa~X#12+kAYi#&l6I#`)qH9hO2 zvu@R$a*t2J;f#dTDzm>#7xv=-M2C@{)^TOBYI;tHlKMr3(`nawV!Gc!KIc3Q8W~(O z_L`dRu#&!(sNnDAxZjHH3=*H*s>*Xnb74V5c{LR~!cvy}?&w|gJZQBtareG{(HO)w3&mVpti>O2JRCL_7J;s5s?FPsuepl zt9FwDL7v1ZLyg}<%i!E2>t-o?$af!>c(4P`K=!Z+#!qDJcT$_~k z83rUM3v4Yl9@^piT(x{NUv+TpuxrKSd1TIX1leb}r;XghNY5M7gbgb7ZOKcR?MB{7 znC)Jmr3|J8nC-@la1+dS=K=2XW;;wV{5*(5abYaMK5tegCnh^`h;@~htA{a&`PhV) z6p1OA={mU`9z%^YGWrfTOwi3Y&So;;snssh$tNM$c)K8Fq7oAQ4t#rhYZZIH86h%D zMal-*TFg#ZH8pLu_kRYSomH2CF2;pyFyL&w53r1jq@2q0AbI~DJmdq<;z?j>?^d)q z_a)cDd1k1%zZKEc*@y|S*Vj=efEvqG=_21+xWQXv-F`hTfXCUG??iEwhz==+!YMd} z#2&s5RUzNuEJ&U-WZaYo$5TQ4f?99YJc%-%Au0uIi*c1*ioVg#Zbmty&?MIU0nwNA zE)0W4@{365ICqy`giwD38DTq%lrc8& z3XyvNdU&b5=@KXTd_GQM0q1^yMj)iX1A5VY)G7zyniY#2v+lT^{RD8-JniO!y+nQK zUMQ9s2gxRj-Q)BHq94LZu zfr{PRnvA;s&}{)<2-+!32f%{-t1&ZVgy1&3D?wFFfcz3V z>7RofBM1o*L3%ZQA|||CDJA8)TiA;;i3ljIwAqM2RXC~JS4uR&N3Bx&5P!99LUr(N zz=!7 zFM*^Dv>t9YUhqD8gI^dKpQY`PZz={0AuOhrGY2vdzWT;OCKzFTV;=kKdq&T1T+BX5 z1oPQDiQqi;`$TX)>rDiG>`)@Og1rT}GaH&hZH~`r%}}hU zspIZ0Fi_D?48*fwaY(yX99D}H+f z5_Ae_1GKSMyb`zak(;r66Jkg(!M2f@$ad$U5SaG3xEBpjL)kK~F zUev4rsesd8w;s*IlIAOzL=4|?X*$0plOVCF$W_6fMOu{>4e3jG+Ca1yWk|r{2m>aDPB!{S?!NI4$l6X!_7BPWC!|g!tBWw@F8LG5`Wxh` zVC5XwF|z)I7oAAf?;vKJtVIU4GYo7$M^=NVb@EOheq9Q@x+l&E#wEkFIzW%51eguu zs!G$~<}}7C=>hfvad$cuF&v<tIi0j8?EYVAyo3l zoHZ`B8;%W4e9w)1DhfI6qa(T;24yXQzQLKsbXgGngZ)}y)b6GZO`!r)G|J*`VL|I*a> zuBi>SE`A1nOp}1l09_)xMc;-C2gqgL5h?4z4qK~@{Rj37A|+`Be%F=^_R70p(%Crj z#4h5Z`u=^GO6Y9!7p?f&im4#nT%zMrdPq3MF&~@d*r5wRWsC2>2P@e3sSNG|nFnED z@3IN~UqeKALy$cUgt=NarLD}}_^~PaZc<}=pw-^xv*3J6|DDK&4fCFz>7f3J&BKU1}~YpY44~ax__4gS`M85lCwf=T%DAw%XL?RyA!d z@75k%dr@{#n}ounD6Cn!Yzy&YDw|ALD8To?3PPo;{-a~patW<(Ie*v7&Vh}>c~!NRc67NME2y_v zux*2%BPknj{_Kbq)<#(7+WW0AMBK$sUSpDq!9ud_XTS>Yt)-xBpnP=&y9WaZD`NQd zED7gDiuJW^_Qp%KIL~&eSW0TmD%Czh=Xm|+#HqN~4%%ti`NsBJHS=hDt6j5<`f!)u zj;SF~1!j%mr?}X$45JSG;EQo04wos$+Wh)27t_6b0Z`6@*05~gj{|^1z!FY)=<3|E zi!+8I0W&DQH5Hfq^=`7hl&hrdQ1TFtnU19>k);U3&RXJ?XpY5k_`ia>ZhGCvv5Y|TS< z%A8y>mi1c7n!0H^vZf;I*N}DXF3M=+!YzNTPWpk1SYyNQg_^abhW8{C&u*xl@kNUR zBOn`_5^$+Cd;M9Puz5ol48YIxVgTbgWc&`Vwie`v+t%SM^+Z9Li)0P%U6LCvE`a-X zZVxQ*L(YFk0NsUxs{^F1mwS4R4DIn`%W+FPex@l%J&6^DnADXlXxPr4ha&LnF*dkK z-wo04&61vrn;a8(LZikN0_aAJeOe02(UbzeV@oERiuue?Y*%9bz_oKIg8`XC%PQ+$ zU2j|C25U6q6r5U?4NP<(ik}db3kY>fC#rQ+F#2T}WW?L@jWRS{=G~k$L z2K}xon$?g!p|5o^f=%e_NmuqYNJ}!4dKtsQ(oM7kACwa{y8_I2_jvc(aL*Nd7L4vi zrLJJSV{tqCSjS@hOP8XKv^VCH>Gp6l&y zz-1z_hSWA&F`Z^?Eyk_m7_y&~s=d68-2XCQ z2FB(eW~(${6Lxgr7k+y?n|r}KVtSWpK~a}Upi>^EJ4s0hhMfBvvf#f1V7fePvf$T_ zz3SqYD6FuNVw{#7iDQ>5jd(wq5nXQSv~=r6`s#A_jnjk!KbQ&!#PLIqYu`%nIS_*9 z&vlS(@Z<uhNkT@=|Pmo=})&qD)yLBmT<4MzC^2Y2xzn~aamz~xE z+ooB#GUgiY_sQ+yNOU4`XX^I%3v8Ql4rdXpT#1`1%gagX!K5TjW4UOYVa-^7hU8rT zBCs5tJ*z(t{YVhsChY3ZK$_!9U3s(!+Xth5tYb!tMLV2m< zW~hi(e0}&`3tX*)RryWmnu1E}PRDkfx!Y{(^2bb?rL`KSKNzN6=>AwaOX19s(f=z5 z=r|-7E}OMN6U6Va%kR3=UaJ)GJ0*GY=>0o$#Z>vjB6ur*Xw_zul7tZkQ0_4u2{7$! zJt(HFmp|MfF2im5B770&<9D6^PR34fi{>Rbe*EY~Z7;uKYil znIw~BV1m4b7bTjYXw;$s1qUPu0aT(1k%UwOwyV*NcK;S;z*Yi@lV~Q7Q)&OQtE;rO z>aP9kZfzCB7bKI=B!C41RD*yD}F*j&|RAR~f!jUl(>}dD`gKJ&S4HA082;Bnw(3;;iBGUFR*!VEhtS2QwThv~0 zuSoONK4ftEn(Q9YLr>O93Fn1w83tHF@D^uqF!$t4!ckmx8OcE~)?AW``*Hb+{MWz< zs0|jb5GFaUw~+E;f{)ueKih8EM!C_jbQOT!MO`5-q2XlC>=)x5Q_bSkS6a?pA(OstVC5uOHU)aOG_)G zCCDEEu-q`jB6j`}=7GFWwf>pvsb2mXwg}M3Ztq<8a<{;*J!|Ha8C~Iyu5iWkSQ^X2 z_x8NtT(+BdOZ0eADiHr7IV^gNupS^=rmYu+A?4yNEh3cKe6uI-kT~KyI^Y zWUb6`)n`P+LKa(UbRntrN?l?mt%}!rh_3Zav(^Q&^yAh351pC++T!AP#dR*%d^?xz zd!_BC_)FW9Vy%hO6xOob=|Qbzs@|g)bb4%2+~v%wGBmWX1Aj3poB0bdXGaqmgr`pA*CL>4aR%Yzx$5@6U{rM&1qU#6D?gpnYV;br zNFP24qORixu_D_MTnJa*`(9QLB&^lgV*u~V9?}!D*DvUqC7jAW_NN;t29Ll8jfKa^ z417(b`==ME%Qn+jZ26)EJXBxb^l4OE3f9n|uzny<0Cyn}bP9M1K&?1y+-|&=^S*HA zHmZa|)D5~+`wbc;U||pM^s>m^FjB|~J22%fQYSH9V1J-lOR1DWVsJRzw8iNt;4p=` zNFQ1IUlx%QR$>#4qs8i3`X3q80ptCgCW^g?T&4eMaUOIMKPoTVX$+y8LcyWcfn10+m3ss%uZx*^_TFmq|VK|-{1J_m>&Odt>A@iSG6$N ztaWV&&rZ2b^75Z9i=@F=(a_$&ET^+ny-IMI+@MBkbEBp5PX*dz6|U)ilIhZKIiO7s z^u3EKxb}I75ngw*8WN^`&o^?~9loK{uJd_{O4Xk=A=W;4KQVN)hJ^aMmxw;?I@r^> z3Eno}&;!IsCrh9{qle?enQpql9+I0=he#8kmJ2`UC46YMbwE%0b6VJ6J zV;Y0&9^fG>9Mq0&gLU=11=l^u-}-gp1y`*h&%#ihBr7ac|D-u7cPR8S?{bCC*c4%Q zq5a{q0}elc@Qzstf0hwlFO8G>%{J?2bZB%KqfWwc;FaSFpRfl*A_xtxdrbdbqyLKg z+~7J94F=bVPu==;;zw6&;7}Fm1AZg{KOOR;lJ#DiE;W+cNCwqYuJjK9avRf^%c@UY z=}(-p$nMKDD-~TY?L;-_|MA1j4%Suk!2G^riY^KOmGzQ``d}9W8>*Ama;q`Clhz4! zEMOb7nxU(2q+=+V(-iKrGb)qreedx+{7-|j5pp&Zsxf!#)e{+O<$a!&_bT!>birjt z2bp(}dG#jgblYO7fDDW(lL{CpXPpL`{B||6CN2?1wvBUO4vc%W;Q!d0awRmi(B*Th zLZ)NxZkm&D!?$j;nuKbCR#6SMiMW4ospC5-qGir7TTF|)6o6;gHIy-3p*iR*7AkJ! zgx*0iQv2 zOcjk|C=tj$EC?IMD%aFiPM;_%E)^`jiz}U#PSvqPvkpn>a#~^}nH80-9p7K5B1YPC zt`A4;^c;6=_?vPsicBs>@;-J(F(#0Xu~yR%6uP;I+v%-Tw?p{?OI7QHW{2U ztm;9cR9;kuW=1$R)PilA+c;$=vVeMVeqcF5Fgv5B`|`7?TfQq466>RTMPaT8k}y#( z8vl?Oo74F&4Ppcr3L(r-54><#rhG88mme&nvD+llrPk)(Ka8jdC@X@(2<1W#RjS*x~QFOAv6R2J|EF1OJ;o3}M16w~X$JsriAtF6+0a97q&wO| zIp#{*DX6(#7Z`1OxP|0jafPp$#O!lF=(^60=zoaV^4&)G5!`3GzY-#*kX>@}$ zy;v>3M;2@zN!VW{W`CS}u zgEA#Zj-U31?e&i(Ne@cnwnV1K+Ppnf^sCSfXa|m3ky<@}@Tm0A%uE~uogB3ScM^lE z=Z(t5=LE^=o57NNrg!JkcV#QmXspIh2kb>0A+@cNtPf$)AEz$JQ8bf$%(!tLuKq;F zTo|*`doyX0QU{397ub$&x`1r^)8Eis^zwN}UoiUM(~bo$!G(hi4VQP`qy91KV4J9E zj9}1=qor!bR@RE8wpNXyv_Daed|TEzd+|J$SH{hvzmi__puU;LMDc-nDoxU~ijlAl z{I>jbIJ%M@R5~b8bLfULBR8m{_C%9nYTO*QY?1%K%@O%sEBWCt?;L%E zW_3##wzPWsG+FolX|0KJ3nv-3CJLRJ@JD$Pf|j|3`Zur@YmfqFapgB^2=f^V+ma}$ zQJce}j|cVd9}5w7(QfetD*ADlW1PJf-CAh!5Pb%Wo@f}o!VsV^yi<-Pho?R{u>~4x?a*BUPR#I>kkj|^d zax_Ooxk_kBiP}%8U2`Z;0FcnXHy6LpuSpWf#IQF{Jt__3WQ@34+0Cr{Z&p`*Nt!Qx z7n)4uXwQar&juHWv#b>7Oz*bk$8nD$H!&ZD=8S&h3>B(&x$=Zw^|FH1tylsvzaEi# zVK_3ktAZYyI$cPtr|uPEBMj9J9|lw;-K@xc`G>J?>P zY#1VBXk^VvAzaIbHat3kXs+2KM&01qFf+lsYx#dckbs{B^*aAB<_%~V91cXCOE(tN zLL?`ovZ+_JY{_ZX51SkWG@v-InM77gDhzvQfgRl}R7de-?fO(V&iL4 zfZ*~t1wcds_JB4c`4RgG49rk<#UEpb@ro^sd`m=h&A1K$%g66t>Ji5BSJk@b;RddO z_Y*_uLG0DS!A1Qks+(k$BO-31FB_^plsBynG}6q@0SHrE;sHC%H4I1wJ*w%Sxjo!~ zs3yO!p98DHjLKB!H0}UpHgF42f2Mu~_s|hRkmltp56~U8;)x9oA(8e7~zFKvv$8PnGtnBtQXM#$ltB2WT|%_ z_3q!K(U!%orUKB+3rm27{jt3Q)b6mo!rSWqi$LavhTVkmJ>UHwFUFh6604`h`ZqfK zG+7xvru|QedYO80$Tm7kb3SZ8MTAmyNE4@Q^Q3-Fp$fjolQ}_YKhgODkCc$y zQ!At#`2%Xcg?8^Q&%^KVUISf;&hTj8?3GR~Oa95stWSMkXD04Rq^@#;q8d88;2rf& z-51i2t3$UW#BN`XR3?Px*bAj9n*oZkpdRP2h~X)?>v+SYFOB|1Y>wbM<-2A&+OX8o z;*6|teVLdMT*--7i=YRqd&mSX#ncZiQEj}Ip*mg2uQd&}M@!Z3C0LvR$0b$|Z;lCo ziXeL+9QzXy&~ov!)o7jS@ugtgIy1oT(OZJ#PY^kWkcCy-3d6(QMq#n>A+o8stSe_5 zP2(zvIj#itkNY~{`R4Qz4Y7RtMxgiGasU%EMu&2fO=V@I(MAkVE^ogwNG%%l9D<7&_Wa1)X3@5x=Ui#DrTq`{Scc|9MC{&$JU^_WJN6RgB zK1EP3tbp>=BzhP6wI3-k^NNkqI2yS*^oWg#?(Ol-E~p1 zEyt!Zs74oLnDPGfT^vZ1PRlbs3V)JRtaeDB z;XkS`3CG;h;Fi1z3FH|&Dy$(#5h|W-@foU@i4rX61nh9iqM-i(4jS$}j@K9eX!b-| zPV(X#!i!YiDCi`bqbKs`9Dj$=@>J!NvfdNn&yqrul1=lI9f6N$+_yF6iMd70Pb{y@ z!8=?T#)n;%ke9h#8T>WMWvFYQ1J+QRCwNRp?y<%Z!eN||aReE&gFH1lAPf5kQs)quPg2;=5o-0D@lpH%kLD;2;9hW6 zctT8EW}6??t?~GgS#?_?5Mqt@E%oKYB`q#tTJ1(JVOK3c0{P+! zS`Ig83avy$cZn`D8*U?=BaB$ExPh(}f)CdDc&boVUDYF&FdU^#kTs(@a)dOE1>whWX zd_Hf&;+miI^&x0Nel!GiA=29eKhZWiMW3< zzEZ905Bvp>l1w+J(U&h7=NXU4K6HghPH+!M4C9d}c-~yipPbf0Rjz|%iOAcnIycEc z&E}CKL3D#|-&%soDw7t4e)%jU566SWk{IzB?Caa=rS_Jvr^^UluMoM+2= zqVxLaQp&)i}0nG=hb{<)O$*XB~{IddsBaQ0mKJ}r})BH_#wX7P9TGZJ^>>HRlc z8-*U6Z)kAiI&B%m0UNt|a2uWK&SNB#YnSL`)9hn9^TlhYw@=2QS z5@8yg{!PS8`qo{_nx1BM#bjd&C?42lM6M`-VSQXCBIp0FO4YmYLxI(9Tbch*O;p>; zd{C+c;;t+LQea$$B>9oum^jW_`ZABY=MTacxTzg%!VPkrQHljyTCw_75p6J_E4fj? z*wWFRZzRO>6EfU;X4#OOUQ`4z>12~$CNtKp4~PKT4Nr%%)HOaQ0Bume=D>J)63AJ7 zYLH`AmCIY@_7!o^x`5&a8`~{tt38~mP&9FAWPSeluEd+s#etU7fmPTo4%M-NS?!Ns z7Wk5DTqjbNgBUKHWmq8XMe*Es0T-*{>Qd76yQv|a7Y}}i#bakb>3Z&YY8so{>LR*D zo8gRv(D&nKiS;I@-8}lH(VQ)LGFxh3_%sZYP2B>$H80{OYbaxQ#c{clCGR~u&N&!- z`_Lg1#HNZR3z>=4lJ|HkZ>9nlX`6CXFk_Gae2=XNIl1CU9oN>Z?kW zTx21_X0Bha(zipW@r%=mKttnEi{H`cwIynlkOl@G4+WFpek^Q(`%#aMbc7ysi65KK zf>j3scki{Kl92}V?M*$TXejtBaCe8TCI3_EdD>>o5U5f^>oCfc&>(hub`lH4Eo`_^ zW~|Tul)JVci_P*8rXQzTDw`(wvQ9AP@;lKi2^Q=P-09?#KTo;1^Wl0DXLsrwxj@Qu z2^}OJUoX0E&}T2o@8Lsv7p#B#UmQvr%WNuKLUdG%#3oU&(AO8L+<2syLRFokqc4Ou5N4O%;== zQLqcdgxtn+k7;y}WO$oo$glHPF>=VxVT6kVo#}7c?3ihXI~}FR!!Dmat@(J^=}Xjj z0&+XZlS^Ri6XYo!7fd#Wus1B$Q$%ht+Be&{rOJBWHx92~BfNWjX&@609b~%`{>nYb zmd6hXGvz`S-2Ww6+ZNw0z6NXwz6||qC&4!V5RJT`(HlTv$g7UyD=@uF4pyDse+Ws* z)XCy7(DT^CB*!rMG{UiV5UQ!ki!*$edS2g^^4Te*&_OdU+DSv$fXo9VZj>9?Bcx0>m9==3|&wi)3i zk!cme%QYSk&+uIZa!OW9xYH>;2P!+h=cMp9-lg<5`|+?8-(qzq^^K|M2D;Oq-dEK} zWBNR=w*@{<_#5SeDx5$Cl4`a}i;GJYrcq{D1q{!=ADyNVr)5N_Q{dBt@TX=c?l3!XhuMic>2sSooov;HAah~CG=MWU+QXka1BVifCRsK~ ztXa?NJjPa%U8Nd~Y3aH7%#kf==~|pF(UGx-j)vIh3mi zhGsPeA!x`7z;(nY@_@s}2jNpL&jt)cljII-+Po?(H|xuLD(&?PkJJ}@y(p5#`@){w z#`=OId6fxh#a7^y6^C`G*cG8OAZFc%#g*2d+4V5Ap~KiKhfc}wmP2J{+}0*C5;TWn zSZ`EUb!+5>&X@t5K4*?7i|_w%iMi3YKB2mBnNQ_389nW1Di=m4{pG=WwC<6~H_&V? zllKk%Nn&VmG~&Qy&UD>rD4>-Nt{BT{hiIWDpvP1Y3nr;!y#BqgG@4yAq!K2(1|4SHG%U>^^;|r|2y%h{H5|u;+2x@OQY%; zqLVljTFD#?=07Hedha^LP%pSng7Sjp)sV~sq5Q{KP#X(X{%D!x>A(VbY6aUYvJem% z&pY)}*O~Bv_;r0;;KNpcw-EdpN6~~*Lz6%=YkLp9G>hrrBlI!zvMZ6a}z(-LJip-L*Pc&E&xPYHjOdUI~ z>T(pe={P-3SCOMQBH2i%Y(yGKkLcRxOG#DlMlvcBN_Eqo9`JDjA5jxUBkAy5F5GDU zM#dd|7Jt3^>?6q}ll(=)2uV4>-2Zs-JxonqD2=4_0;>{+AtJS68*+;_2l` zA!&~A;haSEvqxPyi^wX{Zm>oQIvUD9v6fE#9SK)jkJa-Nu5iwYylRn;{1>N`w+T&s zJ0_?@Bh~*Rtew%9`zJ8Wpm=I$ah!~r5-|;|hrW<7NBQY2!u-?TzGX8!uaCp_AYa%b zpwuP=<~Z$vQ>p&pm4j|CR%2t~=}~ZY=eU4%^H!Z+x;=tRv|)5PmPKL{U>(!$VSrbYbmCXF`%HUoXB{y~9RE_>ymB^ANz11%^+;c<*bdy@9OZ}o$2Wex@~ zqKIE7-4yr~Jj3s5sC*pQP$`&(KKh*vy&Ca;tf3jw(5VD`YYfx-$B_L*uQZup#u;-A zhXw1T5XUwMU&tK7myDC%c28i7tkv}r6sjvcK|RhayU_ExhuMp5zCWdM(Dy5X>8Q4W z_r>2(L7z9gbiX+6xpyI~Y$zmipePiQq&eaCzCt5h$T!hnQsw)ZxNN!*qdG-2rg>5B ze*R9TheF+iv?z%k>fp< zBvS(}Po@Uf{qz_&*p0%Oj9z5c0z|qDwf2_`OQuad%dg2(biGOkV6|2MfB7|U7d?ST zrBgoSk~jvMC)c3nU9Wk4_m3s&L2iS}0PGJ|9oC|X*i~?+j=|O7w0Ifn0<&20g2IIY zmP3dJg&7mkN&FfXWq%vU0GHBbM%CdG^{y1qtPa6{NtM6g*Sc38FG1q5_Us#5Emp$# zjm5*AjCpYd1;c}n_}2bCdj?XPO!ads!)J7cqCl(mKBF`2dR#UgK>6TIgjZ{v0;Gj8 zOmim)pc?M5Us{bXXT16VnrDQ2fj#xT!qN8lZ2N>vpGW*LR&sFcouN0(5_O(j4p+ASim8pR(^-Lq#UR+JhE_h%M9&HL~B-@l;H$ghq02_Oh`K+`I10wHjK%?-=m zV<1MG8>BxawuN+r{2igH!)zAZR>7v<&2fNPd|74UViYb$s$zQ28kxyF1}ApCaz>P3 z6L~4?dY)$-`$$U)`mCiXQzVamoH5#Wz8a>JkEIRj_|vpI)7JF>X>#(rMPS;0l#&6( zh_%FR*abux$k}BjYV?cI=w^Xa)_BHa1ju*>@#iq!i~PH{}r@s7{E0>O={rXrTiZsWh|xuH)6Qh2#b@T|8$oZmER`G4O$to7>#^LG{YGhSzj9IzJ6@h}o z+@1WULe?aLLs9-zE%YMS3Io?z2E7c^eD1e@MHkZRVqIaAkTK(p>;hyTt7p-^Mt9R22&TgxT|(GOpTyfd$pJ=o;5U2aI4SIWafQ) zX!hx$N$}L}ij7e#4+F=jR1(Wt)MIp``4%6esk~cbbfy0EzZ@e-_JA>B{hm8U&}zJH z4XFqpVwiSTq_s0>QG_4c@N4#ZN+8d5CV&7-;E*Dj-#LWX58dgq>EVeFVtLoUou(b8 zf}eIzCXZ}XXd-G;B{)yFzUT71J~DK}W-&r>1e!8Eujj&vgyvWQEty7BpxK_&;!ojr zJ5jXjclL`c7$Z&m-hzW${RBPV;1shRaU+E?#N)FV-q=li zV7mB(wfQd*U^4Zvy(`NN0Is#3C_acX- z7}$#uUM%>YCSzfCPly?T``FQo z%e%JRz_FJdU)UibO<2T9_rRYyc-M9Y&{g-{ZUM31G6taW4bd_g=+tuKh#k9d2UAobpvx|+0 zYZq8f(X7~K^;$u9Og7h~dred*H?Va*RY0!(49Xg+CQuC%k>Cf^g1#sV3`SEFQ5z5_ zV^QPi%^$X!I{W_&qb{yd4l{aMk=|k*=__O?sD$3fghOz6*6ucrYHRiT!Q!yuTbo=4 zn_Qr()8-pbq*2CTM9Y0iF|9m(WT?K&HQ@|uO-1iRlFVTjKhz=)?VO?Sp(n8CX|YxP zIP1VYbPiTl8qUO);ZL#Gg+x+7N`n4QI*w$JyLfBB(r%CYX@%r;Dg!*~JZ_%&Q z<=K~y5(LM$58`YvdvRlO@YVr-Fcq6<+|wfH|d;4Al|kcN6F5X=kv%B@NJ3X7gm?=6PitP<39F61pYYyKl_atRq6q zZaEQ-|6HoCk$fxdAYqV0+ax{p)0%v%u>F;g4TNMhu^h+< z8|b4yXR6q`UZH3xX1HsdR@dfEYWf+((|C&5O$2j=M0QV)BJ%N%K{}*epWiniE8lwQ zqv2K|MFYP)jiN)5=bdB`C!Q9@8f5(hKWNxob4rGbBZDg)JWC4}6L&nS^38~pPRqHC z8b8kMJH0@CJ+<>$a*ht}mG@iRtC%zwtLioJo5}plwES$1mxj_U%O5)trZ;kuOk@|9 z{F!O@CId-7yusL;mNgf`b(_FLzVkFVk5I5;FrFoZc_ z-}U^T%>T>zpB+$n6l3czW{OqJXwa)yIT24r(knGo(IV~JR?Y~4iea#X?$$Z!)s$4b z|0j;>!RecAywrW4E$KXF@|bK!vLA2G^re{3u88}1 zb9(Gcx+VRJ85sN+l}A%=#}v64?-?!Dv9oPTsYP2FI48Y0&;L+u<4;y_x{P8Nub#S! zWzc7Q0Ob0X^sMc8{_&4co5-zZifoy_TU0YISjPi2D7Tk1Tac&Kzlf6>ZIdt(IL_0f z0Sbc!{(PDal@;5nt5%|>P(W<;`Tj8Q1QzI?4H0C%hEVd>rcH%v^EWc{(?eBz(UVRp zJNg3PD^vZQ{!!{usu9S9thiA>`kt;+*9VYEHDWjQD|ZJS`t)cwqXlzS8c(e@Iif@` zM@3AzH*j|kQ0p^W^Sim|vIV*`;5ze%g;g@+6s9!pw+$ND%^FNU`hxnU@K~6~WCHb~ z$z6b*a%wv2$D-(uyz;Vuo}J{zA(BC}ST+>&;+ z@-E(xk{j~(y7MBbP*R@!b~l)gxne?64G9=v@y0@aabod8- zBpNEXJJ}FL$AU;pL;e|K8^>%8+4t>^`2wh)J>*iUfwkSX6K+cAWGvIKo;~D>?1YK@ zJ)R$(=O0J)Tx`$Z)$8+J6EYEuzd`Rbn){xou8tQyuB(AJGaVFI1N$0xl49S3&h&sP+N$@t8m_NkD+k#4j zg_ULfC!5%pTBL)@yCtPcCs52Yv&zXa|Jc1ktt8Dvb^Lx=QQUZ*jl6HMp_~xKm{seO zji|=d4Wtgc+_wTrVTbGjEfmKe0oV`}Q1~Y)tWf>abx;l(o*p>qTrrycxdx#nR+ouy ze8Uebj_t*PoYRPzdlnT5Yo_@gw=u(0D?%!qBCtiEgm-VLIBUO`KBg45!an3#?*0;@ zzB@Rg+$vzQW+^#=Qwhs+Yr2Gn-V72{L0?#5qN@O|qWFwVSF)d$#c!$^ILK_^ zPA7QW^#l4NHr0R@L|T~-pyp)HI!=D-v(apfjS#klt_J(G$*a>=&JTb>2-uZBQ84cE z1etdt{(iRldm3(tW)oyWA%b$DVNcKJkaLA^B+M3LiH?dDoTP&{#a+DU^DH9Q5$Y=H zWwQO1*mOfzUZVwaQYv14F)SS@vUOX5g++IQZWd736m^D(IF%m^@Dyjnq3TO{*RCKg z(OE>6fe{*70dVNVh^HYPbXW&0#vdlukC<~~-PYA#z`Hy+Ub9wMv=pi%LQA)#*P_ub zz{wMDX-Jwj)pz_%V|`NfjH~>K(OJ&OII=T#474y5`$GIcBx6&+ip*^U^rpP|-GTq~ zWU1-az!e(X!^lOLUb_@l0eC_KFYx*r@`t>K9*n{vGw;#WtIMI|0FOn9KX5X^|2<u$8jxh{4hhW8V-m6mLMeydCA-4hM zKfyI5~4kDE+0X}XtPN15TyW6n~;5MuY0__|Z4*=O5=tA4@u$&58 z=nc6Dl18;^I2y^WFtp4mNWC_jZe5A`Q=^bSMJ2fhr=D%W>w~kzH3`UQ``r!SJYIg^Kt@`t;E9Bw=JazMOJw|e2} zJzvq+Dz}`56dX(YI<1cz3V*lp{+>?*Rc#JQs# z;R2O=JNcI%xP6V$L9R_4a|G4yM6mqrV16UkZ4iV+1l!9m(+L9234vWvtWTaHnWJy$ z*I40kBKHFo$ibE*NL4_LUQxI-5guv9jfKTf%HFhsZb{vV=s^7g3BB(vy>vyQH~;kV zi$rA8j3M9KWb3HfMFxR|2WW7kKa~uYZ;m*KLFQD0&BaqIw^ByIyU_dNh#D5^A>5*U zQy!p;@Suksb$(;--F=Al^WWyz(eCIo9LCO}UmIs~k0Sv~474T;J)RTB^GmZ6=sgk# ze$kkO_?lc5yk`siXp8eEE9oL^=XEUoI+#W^ z2L+}X7-s~+(O{bYsHkSWXORW2{{Z6GtJ|VWccq-Ic*8yDO5xe^GlF%`@DQqdfWJWf zoyeuF`UU9O&T+HKrj7HbwA4MwSImgaXoboc9)NWX}YH3Z)1A?!1Hfu7hizC(Ky?qWs+f zE+D_*u3<)4yATMpVWXJ4JGkx@f+K@+Q8DFscwwEq8k;1g>6n2Ds>6bt9wTh%*EE;| zKJe9b8+lh(bKdon%>e zJXkl8jgDJ|;QC2C%nXK}B|I3qoR^xDx$Ht{t3XEsFRXzJwzbwhAwSf%weB&VWU|Tj z^&vYCnbr=HSl-$}I@7u~LIYuE-~?t6p@yBOXkD)n2HX1MabcC1b0k>zvM%gN{$fwN zBe?!Gp43kk(YtG<9`gb(NDtDeHT-~4scUUKwpOa=*%bDr_Bw46V>c}m+)RC*xm2c|Jvg;5{$=M{CcsEIf1i;qOB%Li) zAg2`@LO+Sl3vQCpHb=nQ>Z$!X$&9|76CvGYA@>_*4|-27gJvUOk&c&4Lvy3vre#h8 zC6nC7EVCUUX|AzWK4-06!(TR!kd(dWkP(t`!ZlxQNb1Sfq6cQ45CuK@w_4@YNp%pd z>Mn`Yo9$=Or$U1^Nz$V)8M*~#>+$A6XG#YIUeH4s?~Xe;#s=5j!QYZX@Fa<%e(;9b zHQSf~p@tpbF@93nU`QHZj-OOUy-_k?{G^GDpUgHHKfNH%9zPi{89(`D{3Of2XZ+sY zIB@(V6R#e{{_&HZ9WZ`UqrY$bB-3-oPq!l^%{A7_=d87l@mI!AI^*vdKdH{Z@sswS zJATpvbNpKM;K{P9baqW;cmpRVduoTtLi^h*^ax2{@M?#fD|EQILiZCIXmSQlvO;tB z3#+qETBccJqdBJ!M}HvIeCRk5IJ0c|WyR)XF=vOhf`aR0QEBF^P)*bpuj!G3Pze=_ z`euZF8uhlL0b9FP%7fN7<60)gTEM(+4|iPqB+zootMdn)#z5d*W!YT}G zXzo^|(2mBx(#}6x?G&%&f1{mOP5X{^q8X`ION_+H0;Wf)u0`f#T|?&9u7~XJ=K^Gw zp?8Sf-Ib|j!H~>acEtLF6x|C!))Z+QsIq2w?FT~p`z~JYsJwU)*E)4Op2gl|!=$>M z{K5=s(iZ;AUK(;U;CZRee6LXXF zI(Ez6Q=UgfrPA0W4d66*jV9o4Q=wp;v@TTF$TP{MW!8AS{+b?-hGyLtU3O~iJ>}~O zY?1^v-)DwSi4RpxfZ%6ad!Jt~>7nnn`XR8}HpkfJ)jPJolLh#ynFhkK%oBV}7Z%mI zM4lS3qnH&M(A8FjE;cK4b)!aUn5yZj=g|+PT{is+8=EG3%os^ zy2JAJ{Cb%b+LMHi)`hK$(7PQMYKAAM*$J_E`?bVAvCMZDdNv~sy_E)@59!2tjux{F zGuR~ThVx-VSH3s<4~{xvN|-4LwK|2Be77xcW^6+-3o>*a{QrVLYZ8TdYBy0T1rCW7 zB`Q2Rj?t96JD!`gZ|Lrskv5%1D+Pz7AIu8O!P2NM5w6Z$26_gWGiShhV9vbsduuJw zeJc#TqI2{*HCMN%?s5jfFjqL8xgOz=;SAjczih4!rr8f=fS*ACX%@(mz?RHVei~wl463#A8p=>ramL1EO|Kp-7pq*GbWOyk%4`=PmGp<`?>>s;+*p z)|##|Md|*z!LguoUoO#P(sV_HtT0=S@f+AA8E{+u880T6a29!swOMn%R?godZ!bw&-Bw!f z3EWC=LgM;+psPVj)Fquo$RtKkbL%0^ln*3i($W|q6QVAJOsX0uaS$?j|KAfbAqamj zA=Bd^gzOa(YeFWu{5OP5Q=W4P+4<5nezywzYUFb!#+(&_9#UTGCAW6tiKho{LBrr}65&R0(?RB%@X@g38qI_a1T#Y}Z*W+Gm(4cl+}C+vGXBO&9++ z&AHC3Pe^kNtXipgq4sCWMPo>+MOIpq`F*cuXZ#0)nqjGfvP#o^7nvK0?3{sD^$5vkVI?&gH?uA#`)jOS zDW7j}8f)u$z*;X=!ziv^VR!7pA>2G~(^3FV<@m3+nm$kMk~rBAt(PL+kp1=Py2=E2 z)3)tjy>xZ6b!6Ao{lL4^|B=Nq@W{m-MufunRHF=W;1+No^s^rNqM?Zp4RZx zFXOxI9_b^Li~N`7?yuhTAa%n;(>Ew4kGvBJK2V$(#faU5Yn<3U&{Ogc=OrjuC~>!q zVk&V|5KKj<1da`7BMk@_ph)B_0X^$%qyDNM9!$oP-%F$GY9wC_) zp*>i}&cwZ+Th)%D1T>^X3BA|^dz5cOB-fZ~HIM5?lO6?>PVfkIhBh_i zyXpmdB67DJ@5cmAiqd_Pu}y3`Pb6VBVSy1^>eI*bu#RZ1w3n7HP>qB8l}r4;8(4Ad zwMK}Qor}wgJhQ}ky&dADEsjWoj21&yb2uDyJ2qb2iiwjP7Vs$7 z0Fwj{i&g`-y}oI=`?;i^g|khFGN64EOgk}D^?JmaNw)bq0y_(Deh(%nn7rj5^VzT7 z-_R_EWbv#0@~+oJWN+&4Y81Rds_4Gh{E18f{Vv-=zZ?5)#Sx50T@wPGXkDqX@kHu2 z;93Om=qZQHZrpGylgzO zG)$AAFUIg97l%>be(vtyZ>>{gzzpEahy7yDP2=g|#B z@$T?EatS8dT2p{v0hSh_gp`F1f|vA6ctT?PYm5`Gc!YX zM9xk_*T}3o6@Bzh5_bKBb3nT?wtIfpYGxmrHnFrMxT%|xW5_|qdg(b`VM9A7SXB^Q zFI5X}k~Vr)zas zW%oShR&N|=`>~dE`K$L?(R387`^X`v^YnhW^d_r=_xN&h zjv5^efVzC7J)obVS3rmXz z42`bJfZp-_IWjvoX=F)T{TolegLeJx^j0Nx#f)v{9L?FmKPTPBI*HWEde? z@4?xj+ThzEH=WDPkc3!kNfQz8k!7<@^3v7E-GKLNl4&v#^wrhELQ1kcEEy%4UVO}f zLB>u)C+^xT*9rR3OvF{28P`+4Tt1P9@tDrTD&uDoYEeh74z$0VM_cvv(aI3DN25%@ZZoZONiIAouqA>ynb75P)nJ^*vj07SWGNP}}|y*P67 zT_RVtMMYI0H6 zkLdwj!VEV*4qv>}Nwcc3M~^PDq# z*%85;+L9TwO_ob@Z3TeHM07M`nmgU;+SFi}I&xQ>tY6Bbcn*>KS9;()_2>R?gLsT2 zf?>8)EGF_%6%q}zut+ul-#~`{6BO;o-ZXWgYelMOgB>fpQBK^1Lwq+SBIN~DMo&#q>^I@0?NmK%Wv-1q9QQ;@w**M{7Niwoj3#4J_ke2 zYx*1VJ#P~To&VvbWC54Evo$%^iZ7N^tj6ZQxiwk0qE(bbkP7&&lTL$Mfrsmh6*QNE znEvCW_F#tkuPa1FiK=9)FMcWYXI?QcE-zJ8FT?ZY9xqltc`#Z+cXx}PfCf%EI8<0= z?Syq~q_I>LNfbC*S&y(-C?d+td2|x9Ts!wR{RazUK0v3jP#uC3Lih9BS+liS{rkT% zO}BE=ed!xjuZ=-GzC)E)NAA@>-j?O(srCKezkoT26o@hEubyX+M6WCa?r9+y z`;Sl~Q9|m8ToGN7UWi-EdlOLc27d$Ph?z`q=~k>eRYg2I_Ol1hoZIvz127H(-4k(r zRw6b9yMpC=gXJA4;NWYszWgwHRKfD@pdXbN+*tPE-B(Tixrov<$b?G`drYb$2cHRQ ztocDP#%^`Wpga5wvV4O-_jg2xJ7F&ju+`8P1#5RQ6$GC3uni|a{tk7qybg5UAjVz8 z)vxFZi&1=k31!Jqhml}VCJXptbok|DYK@0w$(1JM=lNu!WLwlHrBt<$QCS3i%FgBE z)r~q=(bWd&a0xu_CAaCx`e}*U_n*XL-tI3!4>MNCM3d?6i0sBWS>^_eh3+3kWlTt` zl{iaqy_n~_DKNbn_!66MrdYOuXXdi7=OWi(sU;r6Ae)W8w3;dB%dZ2BXzmW1jk{G~ zyiORn+qGGeMF8O0j9!O4f6F>ZW`2#H#Q#l`;#e%(ypC`eAsj^I|#-^Y|V7S{D6V zWo}13^+Kq;(*=jy6IjQyv6Iso>Uky*(JqYJG3qz1o@b{|Nbs#JRnPsJQPS>HJB$yR zt=h654I>Ltp&)MDza(CqnrYTRyp3B%TBWL-;`DMt{Te>9{6GvYaFEnvPvlDKZKrV-ygUNIDrd!HlXPTVZF`iH13q_Ph4t;YM20@-j1 z`p|_IY6CZJ9{l{CnCACl;+IACaPULf4m*KXU#mRt5Iho2v*3}qbthHdb=8D#;&>wQ z#tQxV;Tg)0)338W6+@5uKNYF(Yvo%XCKRVx?JmKw1)wTmj`P7JXWH(Ya=285d-1EvP(mY?UkwY^z9W>GqA62#)Jzk=t?`i4f0@;qh0#@E#2QJ z7Yc%rKqZN#ii-8Orxws}bg2*9JhgQ^4ea-1`n{lnS&a)A^d2j`3p*k4sboDkauw)C z6cKN5{cXvYSuYjg&t1IcSg&RE^OG+Z-^D$ViIu5~Dy9Mf4KAned_6Ys%k1CZ=&`ZB z`an&QylE<9M5pLs>SFvNS$}nyQix}!$vFye%)sHoZ3v5(KHLPEZ3Q>#xT>u z=wo}s?2%Vwf0No4a*nB=Kk|yjOJWdAa8;tA@8$^C8yYqj6}Lsj0{GK6np^I^LH<#p zGQ0PKW#{Qpb?^mxkh+K|nuy^vUhW;+882oqlx5q}mdI$mq%0BOt~k-0KV*Xa_MBd8 zNVQ{?J7p6K3=u{~BhqE4Go`ebO)Q0$Sew|N>05!NSB0jpAFlr0%JvWZTK1tUOVnmq)4u{-Lmu!(0UbSstkm6R4u2nT&CsXyhIXk{`lSBs z?k}O8e;v368t*C%oRV$5TVm29z5H4|vKpZl$C~;jq78GtxvdxTjH=#tC>TAjX&4wQ zdTW4a2djW%>TI}e%7of>PwgcVw;)}tPUxKs6|{h0U)x~6e;Y4+H zyaZLb5b@kDS+!Mcw^kwxzsq#gZo=wpL9?;Fi+#)6wlqG zGe6J)wA?xHj8X5BwFynG{!>576-U=ylm($;$0}Bf`3~HChInMn{SSQT&mf`FP8L?gC1gb&Ig*Fpdu|?=n|WlB z$2cnkDH@-)4l6x5EkTrVd1|qm*TuYq1^=<+B72=lA~dQ{IeFZrK^n&!zw7HQ>Tk<1u>k?mb@aN;?$yI6h76b@_|1_JkE?O#<_ zb=n9%Q0z-p*_v*;Bmbp_G1QS`W(_M7m%tc~R4>7cnQKXfcnnVInk&p%-;X?X*Yc1X z?Yd5W8Y5%WkN7Uj@4@~guYj+{+KrRXXksJ4yBvh@iIlKe?14+w9Yja#9V6%8Nd{Zo zp*ilrDopoXm3d{ryF`X)V{V>8bA~a>bDT?X(g{{jpu%Na5=@H0KWr2R5DWNcLTVE!TAdkOYuP zd+yfjI(;c`Fa*)1_TGI)`1Zvy>EiR%O;_&b|a)Rr5 zF{x4Hr`ou)SY=~IhRHJ5Xx%Ksl|xp$YNC>GY4S$-5z~o6{3c9(RZkr;$uCxYhP~N6~k-&=!1`7ppP4Uv$Xam6Ht1W*DbJFc#^o#CP6CJV> zdhbVA%#4X5=L$~g0e)WdN4V+v34sW#xBun zX$WU`PHXf#U$I9<^V~D7lV?X{FwcF{P&53RfqTVSpZ^tzrIpEGo0R1MSdjl^!;ik$ zbEu)2mutyXR3+GO7Ls#Lw4wxUS0+c$r_%2CyVMIlfHI z?_8F|w9#fh2zu0|`6@E1A!}ANUo~vWZk$%_U+vkjMOdUmNolAhkU}l}$SCjhHZRM# z>_>-bLxHRNgHI8iOJ9+{Q0ioH*j|!yF;JI2*7Tos=}0m;*49W{5~$Jfhv@v0t6MA zOkTer`K)x+q+>N;janeGTV{K3rjuNQLjv2z6(SZ^4_Pr%)b?jh**Cex$WUOqV(!>{ zR|mS0>)es;G-hWz$5*em*``;I!#35kZ(4SR;mocGbgr%l^sNrvmF@B;cCAkn`szM7 zEL&ZT@sE--8?|o^-IncC2XRoo;As;2=98PdqGnq5Y5;-vU7?`c3CP&JHC(4G~FMb+W&_a z!M~$VJas=ILBw{{vx*L^@JtxqLo4`g<9}a;XW6bv6`oa%6`tD?(|;o$PVTDk?Ai8P znRveW)1&m~%Bl*_(QVVOM*O!rt-|x({A}kz@@lT|Tp4{R`^|26OGL}T+p^up-aykZ z9$fr)1{s4C>JC??qsMA+bQ>jiRCt=gNz=theC7D*S0j;M{fg9~lgfSVSw!XH#T-n` zq+*oTbiR#;B%+-!(TKvd&{^xLTwL;IUNvOoxQI24)~u$`O^qOC`IEJ?fygLkNuIpW zu!#FD8%0)dJ!>~UG+N)V-HG->SkQSgY4#}ac=$;p@lcJ_9&x{8V~iq++J^+HMDNe! zD4o@gO1MhS3WpCR;zNOj&ua>=oeuLkH7ks0uG1dwN=s`J9|>Q%9a{sRC8UMZT9>4? zEKZ9na|lQadq0~+Nhuz{0Y5@wb<$`FAjeW3S3EP z%^_Q($Hr=Iw2{$?@aKbTK9l0jp_oX`hSD}hjP|rd+#AgavQgULc^xDRevPK@Zp}L; zy#G6TDl(^-irn)y(F`u@+Pj!PrbCUiHVI55P)t(f8HWi8GEDl#$xB+e_oFdUoDfhs z>cUK{NNcS~YpO_VUQ)pni)jlnPH*Ze0Yxw(tOjRoLm(O!cLbseW!?^DBEe5C!yc`w z^XN(}J4#?0?*L>U<6+aKl5#W>=CPpW- z73v;7WKV0S_YVmgm-%Ej=W$wl_|V|ACRqhBd3X``t)&8NBXaTAxy=&HlexwbaTHVF7N#q>(TH7HP>uk0 zfMdNq+$E^U*c!ICtK8$TICHXEvfhIPG5pL`=`RAsv5PEj=_~71);F&(BJ#D1$S@mO zEmYXiSecx*3$OQPwYf_O=QhF62B%?-qH7@!-0r0D9jilSZ>RO%d(pWlxat_3jj))}{pO&$ta8X?gdC$dpJQs%t}B^L#Cp z+w}vLDJANk%?~UM`Bu-jvubs9%mZeD)Ji;H-qG&?GlcxjL^hfm_khV+tCv{UP;`kd z1H7JWH8EDa?|fYFmWn&hPPt+w2FJv`YWy5>>f>lq4p{C5A?AR7E>`EsGuYKBmG-Xt zk#j>F?{14mGcSsWC(CG=v?9Xb$}B1Q4Hkwz#xIbuF$+J?4c$KfAwj`$(U3v+dBQpo zsnLA^wA8dtgkOHamJ~E)WK4#Rk$RT(v(6DH{XLq_;)$-f=L)|*!7{(L9`DIxrfBA5 z#5@hp%93n5Vy=l7?=fAobv7p1+F`Dmbs3Y^V`qrdE&!SWc8*}!V-LfAu?)R*JVq5K z*-k`e(KSeTl--2@KczMgG7}nO6MX}q!{iv+=(RHPS7XKnlUdIw2Qdyicrjb+aslr@mMj5 zJvWSYjhUYJ_$lf-H2c5!sa-xDD0RjYZPV6#2gG zbV%8;T@CyP=u2{A>eO1*5D==6_ny7TB;zp_(g?rpM&zVF38|Hj{^8jDM;SUOwbR6 zrFwN(hjjY*5*@^OYJJx*lI{fS9ECsuRte$mcPoFmUS=GO;S^8$iytn*s*Gn?z)X+* zA07!Xm{k65eOGT%S#$dwt|i7{h}X7AZ|8oOw$LS0cm^?;=aA%M6hvmDpUJl7QHaIJZ|*vFD&R z${Eb|l|RzA!!4LpVjiqW3b>1a+m$tSH>)dd2O%w>6Xc3+ErP^gD@xiTE3?}+d@3=J z3292geJt`yDvK&_Tyvd{T3)YgU9+_ae9~0fD{D!km1Pw-8hMpBD(fkWCl!@gcJYqE zp|Yr|T_!Rk9x?<^-;TfUE-6ICxw;1a2D|Rw#QZz@f(Q7u#2~|d->#lxY1E^U!R%a} zWLa&Ie^fsmrgZb$wA)YP=ydvY?!5Nqh7L&u8>d2?+;b+m-#`6KQ)ia+rKVHTvW?S8 z#$ELLSTqb;@g zGO<&PKsyorY=5Z|<6Tm{k(yoQk0q-ZF6R3}Np%J2N@IzbB+-ex_EkJ|b8Q#>K3tN5 z-vGU(pg5tGa#iMspxhF^e>RoP%6ndV>~lk%n5%0ec&-#`Eq$XQ3;3wc@hu*Sa1)#k@RUoS&vpdq1I>pFd!+HTbiboH9b zdKyV8f3L1ADZto;`%v`1{F5&wVSKZwOm(s-f#nJ7JuUdgT~cLUgG`yfAjk|ito1MX z^R_J0YLgOh^6yx~3Wg06L!2x?7FgSEEp1zTqb+E&Wj0RNT%7WcT9Yx0Lud&MW0uYG zz^8h_C=pC$rj;&ElS_EBn?EdPJz;#4={uvt@gAE(8q|%I_?cY7$D}@H=R}sf{G%*a ze0%i|JiR}YcSd8zgD5{kZ!u$gKI8mfd+6I3U*vP=*C7doRGZu2;tkC~W6%5cZW3*w}u`vO-WnOIkhFh|sRO zO4_h@V7}3uzRZh{gseqR#7xUdYZ8s_cArr)9R}&BA^oCje#pM zw}0g`=JUV(NmC(pg_TAqt=j%J)h^%I-FESE-Xp;(Kx1dU2bJ9~-)O4u>be8MVYxNc zk#c|l)m+^Xh~oos>bk)bKpsd`8%7>j#9B)V@&8Uz+}w>brrh82VdR z`)}$?w}{5Rd@g;c%+QAFo{dY&u+C-TA$syRFzmbF0H7o|-PB58kg9k?=Sp2#;+Of(!0(FhV46mZNda4s$$!6KivNXEV zAaT^OPGh`A*WU>Zh>K2FeFF;*LNDcTt zyZCem;)GhVZL7}V3qCP1+g2GyHnQeWA&>^y$HY`uqKJ8etJ>x645Xc|P&hWbisYj- zT)ju@*hhKGEB4_h3w|p5~n@YQ-*rhnNij#qZ<3qlD#9cpbFcz)?$UQ z*@S}GX3J9XNaRl5ouv@5nGqxyuUll?0-_x6^3AKld44Fbc23N%hkF$6fSo^B?!Xw@$T1PwP5j zqrU24()^n5@=Hytr|rR}f0T5^Fw2N>lU6L54^?3$WNw6UB;Pjelc@_l`<(d3IhQca zS6jx!=a3!qbT1vE1zJ* zL8BEK62^yZGQAmgKktf9DAPW=(@OA3Wi#4BeH-2i;kQtSVJg4I#PpwQ6zY_%2)3Uz zG2&U4rEx8^&6LugR1kp>I4QzxRs_osgH?Dwnm*E@KT;x^7UF9?#^K%hdJe=RynfZe z_Lzs-qbo|$NT?qNOVMeN&m?1lIThkmXFtg}5Z)7JSQ~(`!x(fCeKgn}_9;B&Bdyeb z*HSC!-Siv*3)Ay&^}=TD`YsPcr4qe#mc%GW+L-)Xk8W?oX~hG8P$^U+on>b1$^w47 zy%+%xOR&`HEz}X|us&fGd>C3DT!6hHR2m~bX^3J^8ob$)1_wN8h{r?v${(w`p;wyQ zqw%88z8GE?*2pE=g$32QH|NglDR8mOQ^vaNF)>L=HIiMG!^0J*6C)1B8`}ah(9x<&)**M&Je$4`Vv~1-!?V`v3H6mf z=KV_Br7dXV@$7op@Vc4T`K}#ku)@O?=mWiwEtGz^-}DI@Y>h3x=nE6|L)G~OaxA_W ze6nD|gNLE@XkB=IFByK`_%QSVcA~7;ThfEaT=>rafSpun8AJv4X2+0OPcuKdblTUM zdpxVI7>>7-u!=-#TnV!d&d~3)wR{KYUxtsz%Z%BK`xEVuH63r}ilZ~xbXvT#L1tw% z7Bn13!8(fm;8BM66oRqIG5nJbL!=_S0u2AMFzj@SPZLY^^fu37EHo{$ipEF3P4u)N z{_yLd^TW(cXw^HcI2@Q4I2iePE}2pcJV zsV{Jm{S9cF^qmH7$ff>906cVz4_6(#S(hkb_?lPv!C_#Ag# zTY;#<=hf*=Z0N!c4;?%#^KR5UlW=ZyKCGf;`3q$DNC;&RE4zVVzmn!VmC;f@G#0-F z(;V|-V-aLoX<8W_fp;WONT7@#eNC1H%IH!-X{sC3Abgr*L13&Hg>tDjt&WZ`et#D4 zCE|r_T0e)a?Kzr#Qf`*`=)6UK|EJ`mFIxBijeKV0dqh4wEYI)%6Zs@~bkzTw0?C1A zKU2RjrO!!t(PgC%{j|f6!8xxz|C~!!VA1axI$1kXGq(7a68(s1bjZ3Ndv__2@K3(l zP#*N%JATe*aOmBou1kSM-y`f>6w`c6&6nZT6!DgT7Kzak{7@OYwi%rHRX|S5uvKp86XWVLq~@9k zqaHS4cGSmc*U;4{52hWL6T<+p5tW#Lb_)Fkz7!1IlLCz6&eXg@`7)sD*rZ&_%2Ox0!y zJDIvc21r@g7mVr(esj~FVA<|_1a9$5TQvUzHAc^BFdu!krwSkdIeToYeOSmID|(AQih@ z%%{^7L(S2ie)u^Pn^a&zVS-hx(_me~b$(ij?Y^?S8@!GnQcu1(tOwz@&ehw}hja38 ztXh$Wnj$W;ul$jw#B@4sSYXYHK-7!;c{gZb(26_`*Pd4UkwaW)!Q%ow0}S&sEw$Yj zXlJ`G#v;GS-n1AmN_M9O-#TpLkZDyAW@&m>^*GZyD8I;AburV(f5706`OSKooQoCP z$*}9sZV^5f|hBGwBP_oGM-Ox#`*AJDhi!OK`vL~ zMX(Sor$l3?Zw@F60-TDCy&mD4;1c0IAuLZ#Tt?SME`}bXVCMq=FzA4NRVfKP*>?wmr z)kqsvV^1QZ()PS+Dj=ghGOG`_zmAq=MK{Ze%Vmb1vv2Rq3ouC>iQ;j_o;>fFp zSJLR5Hh<90ScAx$Hhl(FHTQ8qR_ENuvMdYR_m5nxDJj6i>)ac?E`Ezs?Qx-`dHAmK zi$9dm27VN76vD@?2zRm^T$+Ew*0i{LS=-{6+XpJ1;)A~ew~ff%3ND?L+qflfety{F zdz1NiJJ9T!jZ<_9ZyBn`4O(Ti7 zQDstIu{r=ZF%=h$9!Cb_+Z^Pl`{KDBFhIA1Q4A~5EQncFQqjW)6XG&5^X2k(Lliej zSVCaC=y$NO=xOd;+b<^AV4cXfmTmE*BmL@qTirFzw#&8scy7h@J%_~}7i$JT_PFq~ zZH8@8XDPp9MBUsBz#p0sl>rwRR1Qn(4Z2N^RK1m;fZ1l3>jA^KYNJo%glC3gf zczwW%aNl~{pkl*aWKdX-&fXUfr+zAeJe(l!0Wh&gFA8ty`>VlD2o1njn~}#Ad~QL1 z$M)bA(<60Xq4IbZTK4SzZah1BREb>xUJ14N9n=YlPa8e0RKyzGCn%_~e+jzFoPmv7 z(9_CkZAS~8p*frJazF`vPeO0!p*8E4TC0Qhc+FXorjAJKs%#Gyn;yaQrK?!>|X(@@v8ViJ~5d?%gQwxYoL@Uy2+ z7h;jeBac(2^`?*W?>)<}f97${<9PlNGhA;Zk~~B2egyi91o&WW9@+SE4M*`R5T2~A z2zrLQ<)A0Z61@VuCH$cLPCsCAt^QklnFp-SU|j*r0<3d&tEbQ4qpt{hio{6zJA)?# zXlmmGbj!;giK!l# zbRPkx6ca&EbejQ6hKHqw_Jwp4f`&jh5}5nY+mfive~$kx4di|);qHGW;l727z(q73 zP6w9@w+?P6+(Edra6iDA?U!&4a6{ny;G*Dka4X@qz9z% z+8>l~J>gv7eBi?2royGeWy39oTLt$4+(Edn;p*Y6A(I1~3!EBmJX|u|Jh-KB>*037 z6~Y~dqr)BgkipS0zDEF$EA1H)ajk0r_b<>=w*aoISs*ucX8;%N6v)S;pW>JRZg*e2 zONa13JED@cvZRz$ZF*dqR+f<@(}UJ!X3WftOOvH!$@Cc+veb<9nefPxU&rRT>xM7?t=Ys-*YJ^s)?{HeHsLoRY?8EKADBlx1q;5|NPNWEfHt zWfYBgP0=WHLV8?$s+NjMK%ibL)23?Y024`~1Z`H9Ql`z!M0WjBQ--w2ONcK-lg&-h zC(9Bt($XNYY(T%%tO2a>7HP7ydc;ZBXJ(`dRm)V#g7ulHuEDZ+ZF1b46qJ+}mjgnU zl0GLcHHE6M2kTzAvOsR@paA5?aj_Ev>3)<;1>#PH(+hMi&r%}aGQWTfh5-+0rv|0LIDp7SOg@!o))kINcyY+ zl3wlr?SN*{jFtkiz@BpgIs!w0J%EV2PQ`Bed_{nP?U{(4}0AUB!i;|L`A{DA#{i9jdda)I6p z91OY!Naa2O%7C&dfxNLJ1n3M}2OI?40HjwJ3W3y)OMxALRX}Q=V!Jd7{3k$)Z$Fjk z%LPdCgaff#VPkx;y@~BfJl|qFNQVBYJ(@v(bUu=i9xo(tGiJocWoZ*hMEDaDwF#*} zU0hZ|Tq@&X?{D~tm@z}2oI(L0X3R*6%hHSfIobq$My3#r@<|nm88ftT@hKEPYi>%C zeg+vVM87-l*Xc7Ap5SF_v-FuM33>`Qq+__4nXXObL@o&^OV`c?aI!=UY2UMm`XkYNcm^RHUk~P7;fBJ|2Zhy0St;}#Fn85Pt+#G8B+P-T1+NONX^JHWHPzvoW^DTd3qs#jP{MmQ}j%~Bve!R z&kb%2XQDqpm)JQenR)|ipO})RON~p=rfJjlxP0iSe%fT&--ysWPLpnAO;R??v+#qAj#JJJhakM zlcrn56LtNkv11c+Fm*z6Pf1VFr=Zu*(`NEh9;&+-hB-`jioRL17GoezW8MC=h{ia7 zD-6}~4?6pcd|UKaeKJ2I6S}Q9{>b|Dks;g0@dzzpM%>)E6by5XJU@RmCyT;3APdoE zC1j@PShwb6LDbcQQ{%F-nuW;X^fKobVS$;MaXHYJ5H&0XT{ANwIj317gi?4$nvO?(sR->3|TUo%4X@%1u4;TTqjE5%%%l$ah#4z!RVQWnX4-| z7yfi$0+)dqtror{aN^<1Hzp0!D zM^}y3`SC1%el#pKD=-!3g>mR3?;Ho-uuQF%X9@Iht$t!$s-XohQsmKflH!eMY?8s5 zXq@Pjko9Fcua z^pojL^ppKf^pm+x^uN~3Plh{@PsTvePxe63Z-cU_Pg%jyxGj#>T5brJ$jeVQh0IV~ zUn7{201Vz7f~I;IGDhX9FZ4y>ET{4~yWfunv+j_N>2`m~3mae`EEj^gcuBe~APQTP=&3Xg#T>0ZblN+JF1Netw#@%2DwZ6K$ED~EGTV%Pm>;Ci@A zaMGE9Tr6B69G8qwlEKluAQ7m8D}?*IIYJ_0=y4_2W3G?}6tDLGbe=$SjMQf7XqMoP zdi-6vshFiCAXX~U&*NoC0f*)^i`U3HO;C1Nu4QuChD8c&1{jDr1?8JXg-$3r%i%9V#%a!($e3jXS2gh zNFb)AGtBhxcV%buHD~RFQnON7>gT7Wa>S9%74_9)Y|erXGf^g!BoVck`;TRzvd{>3s{ z)`N|=ftlK2Fr5eLQnCWaM2_Icaw*c%ZAx6GHj=k`V6H6zkNAIvG`>?fT_Xs?gGa~d z8dEpplX*ou2Ddj+8R5YrLJ*Z7>jQPVh>X;fgdE%z2p7R9ZDv|ZI_xkR>7%v!l7XlXn z7Y#@8W8sqFba2^li{X~Tt%utRw+(J5Tp`?PI6BXCRKQ;YXN0SVYk=d@pg%Y%oD5D5 z7XTLpmkgH;w;XN_+y=Of2c!evFw>9);{@{3Yt!Pj zG(SO}8RSF0B8&2G^aqZ{k|ns&qlYFY4$a~7NyOnI8;wIoo*W!pSeP;`O_`NNz0A%?a_*^L;Rt}A{RE}6*@{^rJESKg(VwwD@>E<`t={+JaEup7uO*}Ts$65Ce2JvnKe5#Ej>f`LS~lUFlTOd&b%p8u@*7*&%Q^!^1|592Gu#%vii%8yPiW;-u)9$xQ!$9{&Fd{d28GKN{u4 z@z41=VSgM2{~Ja?NnYb077G5OLma^f7fG7_OeFv8PfXvuKL4z~%~O!y@;T#wM|{IY zio1HT6g#Z(kaCPGg0(GD_{|jY<8tUvaOW^$);8TBpX}}uszTSBs*h0 zknT?#fMlEFUSexHEP;+5)%78jxZ(ugC4={W#TLY5|+6nYhU_an0V1M9x-~ixeAl*!E1Cs4< z4{$KB5a{M9$-rzN&6sn6 zF9DYVC1?Q4fhNH9KvUpWpc#ZI9{{arAp95718smdKzpDA z&v7{h^9z-XW~FcD}2)BzoU^MNYh8lVINa^eH4i0=b^5e%5IK?7}ok^tz7XrL2e2;?LTgPern zkdrV1{S;_6AN>^Q0Mr4QWrKqSfGihe`;6mJyw?un@5+hK?$yakLI>H0=^!gHL$a6< z&EnDX8#NbwL21gY7efsdeill+Jq~v;B;-Kc0vA7_}LSL;k=E8+Jh^u?sPq;HbMUJ@Kd{R z1sBZ}egphrumrL8L3}EU+6eih;HP%simN}xPlt5mr#S$%4_C|rh)->VWTyP7ow&kB zaj313pYo^nLS<1LYBN+{lAqd*D{4;pWI-dur@B!4afJlvR`65WC_XKTTvJ;V&lj~vSHvbcDclvY>HKE%^r+!ZHC%8`DvaS!1N8~fPyM3F&)OKtN&Q3Qr}5`Pl%LKc^Jg_nOZ|rQMrjjx znTO*{a_ALw9$8;teMwAB^`SmRXE_Ej#lA(k(AnkC!dNYXcr8*proP1Vp2q8R46h^B z4@Yq0_&lf%!F>B;_EIJXjklC@G~%#+6~yb2^%)kQ^%=%b=j$W(8PaKlaL$;-5#Tg$ zL#z+5e%rjA1@m=GrRqQel8yBfcD{pneKkLq&Et#p59Me7;&>Cvw*_|H3FF%-8%yxa z2W7B22l9QF)tTv@)j61N%UOcfsSeG{WAd>&h-F9cS`y0+=g$-?JCc`!l^rgWM{R(W z!O9*k^i9$k(=i)Qf&@9za6J=yfLKNde@PD;Q1`y(fk=;dV7Ap)Qeba5%Z1W&n?TBwON*L z2w$h>d9^$TX?(A0DdSkQT=CqF6#P`jiM+g77*&X3XHG0XMyLxrC)5{3ebE?CX(*&+ z8rBn;%t8El5OqOg4(n$ldHGqKD51?!>9`kYj1$iHeX;IzkIC|3Et%yriof?{aUz8N zO8ErioQY-Oex)((1itODv_Z|{M>OM)6V4^&!$u8OZX`dVFn^eEUMLPdn-*n@;N@?c z&rxq8J!SGp_rjz@x`%fGu75ROgJ_zy`P)Xb&VEI{`lf%7Ht8WMd%B`GGC~k`1X1FdQ`5Fvyl<35*8) z9xxGj2B-t>1kMMR0ha<_1Fiuc0B!~z1MURw1r`Fo1|9{L1IvMQZLb0r0gb?mK(bj` z0Uv-q59D6M=W+oyz$-v|;7Onp@N=LXSPb+7UIK;zw*sSpyMVF4Z-A-5*MZr<8sK8! zm%vrPv%n3&8^CSAYrwt0>%bylCGa%xIFM{meSsCAwLr2hk?pA#bSjW+QT>7Spp$`Q zd$R^U0UZt`ThkDr6*8pX}_kk|J-9R58jX5E}FMtuigFvzwk*#Vf z=%qliJ$Vx!G}(;E#%BZ6gQmFv*|vrPb3yBY0if-H%Rzq(To0sq4%r0T0k?u43nW{b zGjI>+S-@=2y?_Tn#{tQ9*dAC48nml;RsyA<7Xd91zXOnLWE!9&_{)GUz(@)Q-yP@!ItREJ@%sToK+goO z2kium0G$M!3S0>!o8VwzGUzm*9+(d#+nhfz7xce?5ujDT<)9Y>8<0*8Tn~C9a4T>w za1YP`JP4cslp7nfnEZf5Bw0g z6gUUC2DkwjhIHM4n?X;ZaL|2#J3%J`3xS7#rN9zk1#l102rL9P08are*9GE>0njJX zI{@uLPX*Gw{dYho&_{rNz^{N&zz=|_z&C->NY@>>81!4fRlsRLDeBD~#m^CBrh6+k zi%)1ae`g%_n~HGp{*i1Vu8@rKWOe{%C1UqqwBD5XG~b9vDq6wWl$O~FXl5eX3KDqz zP`R$q4xL+OH%R2K=WH%a>4{I}vb8VFPro9cR`xdeX>4G&3tEFoJ&fi(bZ<739|zey zERG*Tm_MGEgZY`YOZ1aW%+KUw{uI7!=AXr%1LjX}mXD5a2aL}wHOx=zal|}X8)E!< z{JCfIHabJ%T#Z(Tiv9%t`p4qXn%5?NQ+!(OD)QOdA{L+No%v_-I%WQ3{+uy?8h>42 z{&Zfa%+D-LqM!6G`kTtt@oj?f=?+nhV`#>oBj}CpF|~r9?$0TeXxB*L>&|RL%wovw z3(QK!?opU!j``X768$tEV1D`){i*!9X8bgMZpiM{S-H$cz}haeJ+XCF%$6bY>AsHI zG{!6B?8^U=pX6s2OlE(H=W(ObpJ^-OU1&;7SKGL=;q<18CE)rPugjs$sS3o z$0W7tYaM@%-blfldcO2e2wdCHw1ey!s3ikQ$p5{j{yqxsf zj9qd-41k-A~`l?xp@=BYor?M{WAkk~6bx4ko$x@*QGo5<0nG!-W?n zjyzIwwGAYFb;vf$;7_;Dcj&z`;Or|uw>^7w@qo5<^GnwB+clyiQU^FxUya&y`fyxK z)s7ugPuPT*|1z`7!Smxk-uK(U6|csw8N`>-+vb%oyKY_i@x+fd4YyEyI%-B``SZ=y`pz*$?LO#nC$(~r z^x`e#CtcEWO5E7=ltC}rJANBsHrTUz=#K*;65f2F?1L`1N3L`pV%aq#eS|}LH_~>1 zd;fr4W)Yb^A74JdX5g1+rX;N!qS|t8!LQn#k=N(Gy+yVs^6}y0JNm5|HTpXo2>27 zW5vvpiLzd6lm!Z_w=Gk2UmeoUk<}gT|Mo`X%+Bdnoi`4?@BTukabbtfZn+sc{w11; zOTWxs^T?z~-+ehZt$vT;__dGh_E&!UO{T3je3bLtE;SF+j;szIcdl&hfC)Rk{d&Ny zZ5uxL#Ge!yFtYs4gZia?Upkg%9i3rzIJjh*YeSf2haVkdHvj5e|KN<~{UO~pzwq_J zmqSt(NYWomH%@fOF>HO6<8FMq-_Njg(d%6_XJ#w+F1!BnJC?&jM>id5;Tgcbj)^6A-VOH+I_AvmSxpj!jFm?S0>4;?0Sjiu=8BrOtVA-MWi&RU>-t zcI`D>=Cf?o_V#OHF2ih{%ZjzRfDpV-*%r} zdFf6Iz=RQt<>-&JVU5+-qW+Sbialb=qNxz_i$7LH=x6S%^{xkC> zuEBd!41--=7Ek&>`ctoRE@0k?oAHIlSxYOVH`kvjJvL#Pbix-g<(Cfq7VWmE(6n1< zxT$a1=x#f?W4*pD3eR~rw@h{3^^@BTebT1Cwan+mif%b)Gv^%7-n9Q_&KT1*wfxY5 zE$we#nwpxip!V(WD^-u*&4`~n&a>dSF=p`f=<9yxqMr@x(|P`+Z83)L`$x{4+cja| zt-2Z3zkiqFYxMBiY`*Q~{caC~ZF}{;7CgCP-7npDZ0V*+HiH5apDs8w)U0gOp1Z%? zxH{(DSF^5J)o%E4?96tXI)C)_=bt}pzs@IX^^p;Er{5SnW39%=_Tgu%Wp>`#=f4R$ zUwplfy7Q!OK7M7!&0ppgoc#X1DdUHl`j7oS$Qt=_(&`7}twN{W2->@Qi05bTWxRJr zlRnRR@1wcJqsmJ!%&ckHwtJ?kY}aQKOHM&?8@Q!@wR9hk?)Tay={>VUnThr`#fq1I+mUTI@Z)h$eBY?+ z*I7O|yls2acU68*oew-&IyXA_ox-iP{#i%v51YR}UjM3X?{3$2fAQXsPwgVMuh`-H zLy+gXH$M928_Cm)KVQf-$=U3U+$C>sh`6__>V(TKe;@DB$Fs_3ru|^C?d@?5_f3y( zxiNmTvaj^YM_Efk4peqLXKMel?rmk&c;om_Z;tt`Yn!1Tj6QVZ$`0$XcjK48cxV6F z-T_IMxctuV-ZFf5`u@P7i}OhQ+OBgGfBWU)3;uI9-yUkWASwKT$B=u4Kd)?O+bLyD zc-A)C{;>g_B!1RQUpU>{^?mQ3%C5e$*X_%o!0^XkrvX4Cmy1`p@(o7X$*7oj{GEYa9$0He{Cw_%_vgOX_t4fwQ?{HQ znkn^qDP-fJ!cIrFjd2ez+vV}j!2?fs&T;P@KE(Y@C-vUdPj!mQsb4O6!!GD|httCv zs(o%Ai0^ej4{}Rl=ZyX8qT^eOVW`uHSb@_8Z#T^>*peD|S|=!Y!%`%d!^Si~Z)x z$>W2+NwM&LxzOpZ#p_9R=_9&jTwC$FVUd2i;;r;!Zu?d#js-cFuFTo(biF;Dq{P7D zx0YUh(Sv*;N_VmX~bedipFQ&N~ZR{6x%~+E%{f5iR#4z7?*LJ9}^^ErGx_8aP zumN99>OX(T)dIujRk^B8UtDut6?QIdp;@idn-P4OCOCzrnE#kraT2q3oW#5%C$X^S zOe}hGCT;q0CfLQ;)Y6MHwNi7YSgvAbJ)SdbI}Iz9QaE!P183fD5og|h6=!a{iLtOY}@ryZk@-3Ad z;ck8DjXc6}^hzF(-o|5mVSa{CE>{Xd7(;V;1152Cq-M-?qkLK(^<-+rQLpi!0TPFZ zjB5I&?Yy6J{Sz3}qV`fgsrC#%riI_?q zz_j|)ODs?-#93d&JnI7((uV2mK$~i8S0uD9V=fn$l|r{HTwFp1e`AyNLMFSR;gg6G zvGgr}Ypu7L&ewE*G|tt>oOVIG{>8>g1sZetZ%?ge`}m_nT;Hu*qv>&DwN3UDUxcey z4!Qc4#zB|<&iU^6ltWR>ql#UdHSc2kf^mboBRt{wqhH_CXnx7N7q75H_)jrCyMCy- z7IjYJ@D;w2&Ydt>rQWXj*TwSENf)qtTR@4chx;x~uaL@yYx9tP^Vhl#&U-X-B0hF5 z_!)HUy*s@&e4@EDA+o2Y2J#hYfA8M;GtJtW%gu7X#kWvmkL3<{eXr){_v6p(Jc^y! za&J%1GXFxeX~DaF&y{pVej``RoxM*pFMV@Iqp2g(*N$oXb)jZa_?Xi-In*b>sn1@I z0~)VMGd*?p6iEMJ)E8^N)SMVI$7y=|f&N_0ZIk{#9MqgTHDuAi^L2jQ=G5Z7L5DQA zN3ZzV_9k|Li=Fj}`HI7u59jXN^8QNf5-0OJ_I6s4CiK@EKd#8bcXYYyJJs!qHM{Hc zPldkH)1NEXch(dZYc4%|{a&}W63}DKpN>1CDVpmXV72q9A6N6hQU2(NCNROF-HBi1 z{#--Nv?e1r7dLkEZZ$26Vd)UMrs(tuvoWy^}=n({Z-J#krc*AGuPQln)jG-sj$ z;mC&+VQc(2=K8ky7m)b<`|9|5KXThmW!UYas^|IRuOq#u85 zA9qTVwLLLBJ;}|hclYC>vpfc=IP+iNq^rFv+0Z`EA`63zAr+)*oEW$yPVb3zCPrB z%0@THZ&Ky*)>+NV_wrW#Qit$WYvx4vI;Y`Qb^W34<2ES&TCdzU&uNm^-G8(o3*RIu zw+fwNU9NelUu54Yv!QR}Z{E3K<(lIi_wRpw7TV*s-V@zkF4ye-`S60PageWYR*x5s zmuuXMsJ0yC5KNl7>wtfE#n#aAiI!hOJ zMt&VWh>yRZ>DbL?h{K+a{#-?H(F^M@XmY&Y*_q;t9SU>X&MCfpL37yB_R#eolxPoM ze)yTqMU8vK7v0``4gL9f<9oB~13xy56RsBm)*G+#Bb$gdxr`REs28I}+LyfpI*e= z1B@1t%V)HR4PzKBVs=*{y@0y!F0lFtSo0~PMXXrJXc5E4Fj~aI9*h=oGukJ$6A_n| zFj_?2I!22aox*4l3pI=uadSsTi^$zB=kph_;s~Qf^m&ufB1*FuEuwA&qeU$0&u9_X zbBq?TW-rDA93tjsFj_>}AV!N=RC|_>FJkN_MvKTzX0(W_x-(it`PXOo^dc6$!Dta9 zVi+xAjRT`ajQ#F3pI*fJt&A2?m&RxjxuJ{}G566aKD~%s5u+QCtI^m&AM|y~9zahZ zS+eK@mh_C6K6%*-sN2P!v1bE&gU$ugZ4G@VlGZxVXCiHZOTnjE%_<<-LFucJ^elHh zXfi8q0Lp-yfn*om3WT+d+Xlj7p}IagXnViKiEO=MHa83`<4MskiW1GBLtM4<4bOd&i+&dtbigG=XTU{V*4 zuo>yvY<*l3c3Y*G;!*!n%Q+&KD~3SpW8t4c;l%6aQWi@{`cKA-`PvtxnAU z!^5ly&-_1T>!!lSwVDY_{tq+#hsn%Nw<_;%(n$y6S-*=A35_n_9ed+rJ5jw;8h<{y z2zZ)-!dLwMs^Ec1YgE{@GKkCMnuEQEp8bPJ3*r_ zw&d~oEpNe#;`3VtUXv_Qe7w!zZJq}CutAAF4*eT#i!YO>owBkSn{RW}_E#o=*flXX+E2Mg;QZ>}|oD%$HNxoEOF79c;m4@ruB!!igKg7wnWxb>8rWgkM)B zoL}m?+)?moJQH{x#H#?WSv&9~9(_CDJ_aZuo`QH>k%ZfWN)8d~wx?9W`N4QFB%bYS z!pCX$LtjrK^0a_NpXe6AU4x@T46kS&-aUZ33ioH>W`hH`j&RMxOPi%9eg}^Lg2w#u zxjtSFvAl54zYd?_)iNC432l+SuvK_-`G-vm;3mS+A(q!XocK8t0tgzzTj#$$=C8wD zr~GyJg~=_$o0q?3MgaE#937&3t@Se|wPkqo^px&OtMI+8^pl^~GJWg%8Fhaho|5&~ z;ZL$#hPRgQ=z_lvzrOIV!-xJ&_~KUKt?Rexoxjfi&YLa6kG9g^gdHuzTc4jrw+?^(aLe?q<&P|F8Qwbmu~RL>Tc_WCp=EgU z^S{snYxdyi5Zia_@xjNkWq9lSZERbHH_t!C4{P$^>@YrxM+p3W<0SkzD)JT`Ksc_i z&pZC}U7P=&@7nB=L?&xfQ$w@02?o73G zvE_ZLmTer)X($%$85^9DsBPRg_MF*xZI%JM>+w6G!}8D1h!?Wt+|027H%XkC#_zk=6f~Dg8=aA8Nagnn9D@z~kk=(4_r`c=usbBQ(RVO* z@6Slp;;X^PQ6T8UG^~o5+$ZJ}(%Hv&5<{~Su+bTI`GdOnIra-A#h(T{kR-u|%uIZo zK&6*Q*(qX%KVfauGw+Ir2XyXkt zXKFJ=NiOnv=;QF=1s!WDFA|4onkfr<9u+!%OsLp=xXWha^{Erm=VE_B&XaW2tgU!T zLa83DHcQ6}6w`2R+#Ky6_?;vn{D(YR2gEn4L94L9^u$PAN;1>qR=9#Q-b@Voi;5uOr{4f1oiPpGzZngSCOadL3acEU6~BM$w752wz=C7O+o zOUXjV650vJU1nNK6gmvo#bOe6hv!=+7bj`Hk@CFO+T?SrY}EttK8Yz#k&bO!AI|%E zVX=<6#ZH)z=5y2VroAmekE0U!GmozaaM_Y!I4yi{<`(k)VJX-piNg7kU*&mYaPvc~ zN!+Vw6VOmfBHxSgr3mhGk}WVeg5%zzoX3WaCjU`h;s|OY+|Qw?#56)sU4;)eSNvC22Epj!h|+Fe;2S=ye7? z)$tiSEBwHL4xpu-liBFSbTyVzkv9@wsKB12{YV<3BQjE`(SyZ}&!3Mn~freRD(DN>)|Ka_ARs)}OI~+3R zR=}5-p5iOzjn9-D>r4Db0v?(9>tqsp?jeyqm;JX)6Qq0oEbgz9QaarB|D!{UNA^Cl zA^h3Vy1u!bwKYAv7Y{K!Ovm2)BYtz)oBPEygbl@k&B^~VEoLS=(Ufm#CdPU_+^i;^ z7*9kWlH&+__fh2idr~X!k!Y>A$zUKWzq5R_>oR z1KGbblmwJ5VamvH!(cUw} zGtzUKr`B_?XOZW5&nuoao=-g6dUf_1?6t*fhu0TgUwM^#UH7W>`oXK->!H^ZFH?oJ zqJzR-(M!=^;i~Xb_$xvc;}nw>GZb1yh9XC?O!21TBgLnRuNAe59~AY9hl(c(6K^YT zsdrcJp5FbuUA#TKRo=ngqr4}2Pw|fPp6zY$Uh2KV`z`NIK7Ky$`JDCn&d2C;*QdR2 zCtsQGWZyjHE@h3wi-E!O(xfQs*>9)n~sM{&Gt8Py2 z-tH6J6Wlv^hIx+ljPi{3oa!0t`Gx0ip4ghu%hJon>wWJ+Z@G`kx5W36?=#;H%AU#q z<%i0ls>`Yys$cyi{)7GH{_+0#{;U1p@c-2Rs{fDv)@nO-PqmABxH?*$sLoYyR_|7S zuKrSeQEjHN*9_EnX+ktpHA^(>HAR|hni|bbl3R{vZ~#u;PTob{T`rTW^( z@;UNc`EvPc`8xSt`62m9`8oL|`7d&Fw1UBIO1Ch#D7RR*bhm|Wue)t`JLC4PTZ5aq zdnfna?k?^@?i1Z-xT`#3JQjI;=27RF;q{8oYd&xKc=;|@ZdU%HTHu%Gx5RIm-wNn_ zt>2q|C_eztJprrS-f%nURs=1Tx}AoWCMePs-z$3h1}KwND)l(^Y;}%$iF&#g_R>wUocthbHNNS}0{188wS`1JD~AT-INI6QGt;|y{Q`RbDRJT?C^1JL;Qlw8vk1VJN^y+9o3`Mv8Yv+dZBu; z`c?H>^?T}K^;PvZ>ISuyroCo?<}D2ui?sx(Q(yTI`BRTOklEDB(<{kquGb>3PrWXC zReAm7)k`rRJ!psG6GgS+JH;;w3-7k*Gcxp;LEcJljdzH5ly{8xbnkrcP2Rh__j@1n zuJr!NyR%OqYO%=YEuZZ^hkQzWN_}qnSosd~o#i{v_a)!OzMFhMLOl+l4PN)X>)YV_ zyRV6|htfsqt@Kj{DrYFul{w0V%6#Qk~?@IYvc?sHXo!riCpqmP(YRxs9@bMJ-zd4YTZEgB zXHSf2eHAf^Sw4Gwy7;>Js(g2&ugaB?%6F9SD|aeCQ=U;)DQ_u%R{pMRr%F)0ttwG{ z>VMhaLET^NgSLE3eO7%zU7@a0f2+Qwu2-9CY%~KjQJRJ5qugdZqefX8d8+(%`E_}g z`(Teb9y@7<8V#b z4e^`qH`8ya-&=k={SNt+`+e*803)Nl{~&)q|1tit(E02B@B8obFZ1uCsiSiVVfBD~ zdAWR>o2|RAdy4xxcT1069vYmUQ@iG*r0e{k>s6$8dP}Kdpr6B`Hc0=R~_-+qCTa52puUjqcD;k*Hme^ zB6dCo%ZJNT$y(pQaq6);2rq~@@jdlT(?-!2%m0Bneu?LOlglR)>M_1-(J6d{xADm zsQqvS>Z6ILw6G{7TV*e0kn&aK1?7vXH*kK-Ro|!-7GtG09Qwsh){Z=$JZ3vyRI7 zf7&^p7uCu*j5{!q!9*_PA~k_rhH^2`Ip=-PIq%P-3keqk8A%*yE*RH^goKgMS`2^mFY6URuwY(KLQBu9@RKjZ`I5oN2Z zAcA+3q14*yy0P!jKzDwB+yFmikQTe>%Ys=nOJ*6bRRv3pt%)_Y&a9a=w-#22gh_i2#wJ=O;Cd} zngUy7K^A#hq-7ecK68V%(0pCmqkRzDh>qzL%r>KQy1-P1?T8(-<95O}Y-XqIjGeW8 zJCBJe+kst0Pd4n9ePDMnKYe>(k3e@*`^=u<`&if^C+tMPc5%$I;V>uVWSp$yJ5^Of zioj2K=m{+Xq;1{Ww;EQ{YFTY~sAC;kJ?jYhdu$D?p*4aor`9=ixqvd4R-P7ch7wLu z!8!JDk{a~irw!V~dD=Kp2WL8@13u&A}4&Y zEApa%{wRsEsGz0yL{-#89X@S{Ci1WiPU(m)61<0Q>x*MC5JNFSCXB^IOp)nlX!V)6 z5Oc8ilq*d04$tvjkWGnKFk3bBNRzjDhad7Iehk%5p!g}&zJSt8 zzAiRIRBVbZumS}uq@jBbnirsV1zOjja}yeOpzjg19YWU$G(Cr&m(X(^T1KJc7Br;L zFAeQ-(5(Q?D$uJ2t(wrOBM;?~JeEUwA}8`xp34h)DVHFQ4HZ?JV2*7?l~QT7qjG9j z6;w%8)E@k}ubQf@I%u{dB*PHQKT)UZTwS2!mTFyZ=&0V*TY6hlv|U>7=$ziw1zpk= z>;yHvubaB9JNi%`>0>=aj!g9Fis>%(5+t$#7T@%?K;sn2o%VLToVN=qFL@O&RQ>1s z3|N)bS%bCM0qY{Q`fLCK8?z}p!wxfN3l`#G9^o-;G6^&|<0+ouS?=>Z(zVP3C5%`%l|awg|; zAww#xBG|6tDglaO*s?Mzt9+GLMO9XTsv;K}s)fC)t9q)h25JP(n1YgLYOWTb#juWm zIN~~iZHMU;*g30xut!msb)c)dt{b|g4|G@ebRT&>(qlaZUC;C!bRF`-Uc`%eaWCN+ z$oQ0(@v_*C@?Oy^djWQ&y4S!qao}~mp4ayV-pCt+#?HJMSZv{il3`3>EEz{17)h2) zB{SGHeC&TkFl>;lChN%tIBjipudkcrHFAr*N&daJnyb$eS+UgG>i>WfbBeBAm{BWc zG4ySK#JrP}Q}jg)9g#yn1n7i5dSF3fNPQm(*+RNck?1j`xR2y+A+4uK=$J#1%RacL z>9m|X*Ak`?%M6_qm~~Kb7n|3KIR+cg@vd=q%S~Y8HeBj5SGg%{5n1dJJ~%UvEGi<6 M@bv#5|6v9G1`gwa{r~^~ literal 0 HcmV?d00001 diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc-pkg.shim b/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc-pkg.shim new file mode 100644 index 00000000000..1c68332a0a6 --- /dev/null +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc-pkg.shim @@ -0,0 +1,2 @@ +path = "FINDSH\sh.exe" +args = "bin\ghc-pkg" diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc.exe b/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc.exe new file mode 100644 index 0000000000000000000000000000000000000000..537023174dc7a094f693b3d9ef17fa234e6a4bf8 GIT binary patch literal 115712 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 M@bv#5|6v9G1`gwa{r~^~ literal 0 HcmV?d00001 diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc.shim b/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc.shim new file mode 100644 index 00000000000..97596f1c171 --- /dev/null +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc.shim @@ -0,0 +1,2 @@ +path = "FINDSH\sh.exe" +args = "ghc" diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/setup.test.hs index 0b80a76a952..b188acc36d6 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/setup.test.hs @@ -1,10 +1,22 @@ import Test.Cabal.Prelude +import System.Directory -main = setupAndCabalTest $ expectBrokenIfWindows 10179 $ do - withSymlink "bin/ghc" "ghc" $ do +main = setupAndCabalTest $ do + when isWindows $ do + sh <- fmap takeDirectory <$> liftIO (findExecutable "sh") + case sh of + Nothing -> skip "no sh" + Just sh' -> do + let sh'' = concatMap (\c -> case c of + '\\' -> "\\\\\\\\" + x -> [x]) sh' + void $ shell "sed" [ "-i", "-e", "s/FINDSH/" <> sh'' <> "/g", "bin/ghc.shim", "bin/ghc-pkg.shim"] + (if isWindows + then withSymlink "bin/ghc.exe" "ghc.exe" . withSymlink "bin/ghc.shim" "ghc.shim" . withSymlink "bin/ghc" "ghc" + else withSymlink "bin/ghc" "ghc") $ do env <- getTestEnv let cwd = testCurrentDir env ghc_path <- programPathM ghcProgram r <- withEnv [("WITH_GHC", Just ghc_path)] - . fails $ setup' "configure" ["-w", cwd "ghc"] + . fails $ setup' "configure" ["-w", cwd if isWindows then "ghc.exe" else "ghc"] assertOutputContains "is version 9999999" r diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-7.10.exe b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-7.10.exe new file mode 100644 index 0000000000000000000000000000000000000000..537023174dc7a094f693b3d9ef17fa234e6a4bf8 GIT binary patch literal 115712 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 M@bv#5|6v9G1`gwa{r~^~ literal 0 HcmV?d00001 diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-7.10.shim b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-7.10.shim new file mode 100644 index 00000000000..97596f1c171 --- /dev/null +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-7.10.shim @@ -0,0 +1,2 @@ +path = "FINDSH\sh.exe" +args = "ghc" diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-pkg-7.10.exe b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-pkg-7.10.exe new file mode 100644 index 0000000000000000000000000000000000000000..537023174dc7a094f693b3d9ef17fa234e6a4bf8 GIT binary patch literal 115712 zcmeFaeSB2awKsm|C6h@qVFpMbN|XVDVgni&(8LKk0Vau-;DpFbA|_}HX&kLmI43|$ zAn8doC&y{I&$WHpr}kbc+G=er)s`1+=_J9tAoAL)Sg6Kcsym)kqtIl)nDczsJ~K(M z?Y+I9-{mJzb-ni+JuWY*itL`t~|M0_)i0&_KaBq?xc0cg2d&ON9 z?yo+we#4FF>8Uw!&_i!b-Sp!AhFOWfAD`RdK7j8ZpWEur;qPtkr||CU*y{e@{JqV+ zhrf65_m9tQckjpdi~G0F>c{*2j&1Ij_cDJ(lx?jlOTN8h@E{k-Y)zF5J%LYuvrjnc+tPan@1Ay@XsRnns`RaO9l9Q>_w5n zllx3UArJk7N1sV>qg>$&CL#MDWTEIvr28hO1J6=I^&kAZQQWXqM4G$^nFudxYaH)H z5w{@RcjKn@_lx%n!jy**OKsnXcRt<|{`o+V8;xwjz!W4zk)De8vwxE>dgG=I4?Xf_ zfwxIO+XTx0;@{+3hS>lA-~R^`IB?=rkZM5on?9O~J&Ec$0_3j*N zFchBc+;3i2>+P22Irrab4x1}$TYAN!@Vzy)-eZ!*rzO>TkBf_(`yI=CNRj%rxoVFm zN?~!vcrIJ5e90}Qjb&q{>uNgH6**R!31XJaOyX2}Op=*JOrem~6V)t$(_s}ND{>rx zu#iBP`GBc>*wuO9Oo;Fp5OarU2rDadGJ*m1 zExhNKtNqHoIoWzlxCNmqz`hOORaM<9ax#cz`=?{Xgf~}( z>uQz9SNs70tHKXZkYHCO;=*6$L5ho5{isk_YDGDxoQ|ibH|#@3YagXH=g_O}_oyMH95zf>m~BOB8t2$~#h*I$M5C!Gcu|XUp>l1=%8WaTRq_cw?=+ebs1c zWLvDt`JJdG=G<=!-(Tx(mkKLu3yRIs4nVMq(w1-?ecPmmBPFJ=Il!L1Sr9^zRg+X! zzJ|?5o8-e8%Jv+WX?sq#R#rt2mZPY7lT=6$z9KCNZ#E#zk3*=9Ljb~y%L9yoY`{Mc zaC`vdwsa#QTLs99I5FZxc-I{#fAl%SqDpK`6h z2-}X*~nK>v06sDsQ^8sWYJ`v2* zGu;Sj52{NtDCUi&=g~4}%S)&|T(~X-K)x{8_yf!cpjkHRpsp?im-~Fkqdb(e65+}u zgd^7Fpgh%Gi28hJHVqN|jX>RebfxwH%8S%fVN;#z@}V0GIZ9Gy-7cf6|AM&`T^;?D zx;m^I=w%@jKxPGu&uqdHc&kfX9AAXz>u=zhp}(Qctf;%!0QDmSlmt*f85m}vSA=zI z*b5#o5c-ilgFprQcRba{a|R%SkPjGU)Ksta9A&dXg{H$KtU8$&MUNuMVTlqF4*FwN z4ql>jjXD4^m$`zFk?d$T0(B`?A*yGVA_zjP#H*U}H4Wro(1oY#nE^zhFOtIMs@HGW zv$wZMP||-!&&+4(dCk-GT=En>mp+MS?c&b5? zMe$Po!k%C8w{_0}yd!@5p2PIra&AP|yORWjP58f?68HS3r%32d+KVS4-ktO-gos?- zNzr&HY^{7SDs(p<#y2P<7~g6-$#7+5QVieieS(@U#J}rKpc`1N3fW0iB&d-6 zIVz}S_W!r3a2{0npS2xGDy`IfqiIRJXRjs@h)lgeoZ3oX!QL-n9r?e=uxf5r|c`7(*z)Ztx*E8$orDJ-Q5pHYs`R z42TErtZ9ylo6r7CSLQUG$ge@C;yv_Iw29scMcon*#_eI@?XU_ZuJtN+~YqpxA&?=AAS zJDYDp6zaG`NvFs<5i+B$5)YOEG^jb^nEDc4HM^_-V-bth3_ zVlXYK?Jd-%OXt|{@Lk19fTTL;(F<-9X9U@FibE@1>dm3BIiw!L7zG&p4K|nOL$0Yo z_OXGzXxDFM3vVMRH=r6d#tz($R~~yFuTT(5SKcreF6b!-$OE_!HlLM}*qNmu0+FGL zs;i3QuXbrm)UpB9g#P#UVe-5clBcSwQ{BMW>!=;Y7d1A#F91L*03=HJ`_!_*^-4M# zCseJgS=&p!(SQLIWUnBbF7>f3cpqhZP+7kSNXAX`FDIen1{XzZI`^7tXpqYdc0o$+O8PzWn%F90vlpGzFv+?o zTHVQ9EBHrhSYQVcU#0c$HF3Gvxb#0zL=dg?9aJTI%aE8PkD8<}v9~x6ir2LaNwe$D zAQ#)b3`J41v+g{7t~Wl#+(l6>Pwv%~bjqcqpX1Ly{-lgbI^)j)JiC&pJ`>Qc?hGff zn?SjvVS8QQF9B~gx`LSXK-oQ{exVUQL8{(eh*uL<-9CYqrqarTX<(Atg4Qfbz76y~ zNNKt4fpWGTeZV>QdU+FnGO0d zOwtTmVipprhR;-SIpw$W&Y;pg7;i@OnNl7p4`j$2E@BqBC~t_-oOU0Is{WYAe^K#| z=$ZH8b0GyPjX=adfJ}GuOoNfK5s!bs;~(*~_jVdnMlkfdRqy#;IRs>NtVFCW$E54n z6QmUOc#liT2k%0nHVLt*>60-9xA(cydK4~ehfl7(+Nq0wMORw5MJo48>A*? zu1A&N$Id!h=i_0*NMvuJnGl}|S%%>&9PNM+C59rM?5R&sZK+kZ=P0FC_C6s&UuJv( zenFB0l{ue?b{^@>k17{(9yi{`z?xUQd3zKh3Ml$KpQ^;yDXCNMz>P^8=cY$o`&+y66Q46*bpJ+lr3 z3=5G;efVs||E%JV87;W_Ec$u0)6jDw{ut?Z$O)12SaLu zUA?90wl8n~YM(S$-r=%HGu7gZrS7DEy-K`h=`4CpTRNLw&ZUCy`zF!8j^r8EqUs*-E*Xvl0fb>}OL2GtJ@R!?H5e)H#Fh-B()qt{r=~7Jf zkHlpH(ceF~eh-!7B6hBwP?iUB4Zg@!bvn3Bayx|U1r26}olx%odLPuj*8AT)2 z=M)RjQ8ruCy3_nI<%@Qu!XYgOl(~bq>&~T7n@JGoEWOWW7R2nO8|js~G+?s`;v_`k zm5fM>AWc@6I)J%++@$b;W-}txvh(5ON~LV1z<+W3O`hHf)uK*Rrmd#V0FVE%t;QZ#d5ZnKspai0bmO(xmYMWZa17h4q7&XtTLNTg}aO}NeJi5@0&NLt2Vjc8mYG` z$&sB_L|HaZzTn(3N$$5t>g~18H=L23_Tet54}!SC`SN=fr~E5~Yn_j*x)`aysOkvS zxa9skyo=pat>^+j!)?W;))G@Z z1~jI0Bd)F3+*)Ezb{-g=a>9vM?98y70)t-#q*k;xAEWTd}3J#4-Ul{(U80Mjj*X zina`Q(@+qdcdWXL+GKo69~(nzQ(e=CjYw|#h@R*!8~#?g@Cdr`sL8{l)`!Q#0X*vO z!(+$B3(lR%_`3_)c7~8`=Q?ED`4wc_`3SP@+=6U7cW!LzCz!+SjnFluU1m)D*ejBz+vG zie`a4QM=?m7#E!_|A~sh8t?9G{~%ecjXa%$Z-Mi-jkul0S&#;04Tj^+Wc=Ml3>rcd z+Jg96A07_}@Tk8Jj~yG4@D;?NeRym^9NHJz*9fSQ-_i33RbOSLnzm`;!(!yv&*r3+R4{m@w^N?=G{hjZVG9J~4^ z1hBQG*V$YM27MrE!aw5IN8dpO2B$c`sUkc<+Wr*SSk=p&V52d zxN~x{-0hOzAIv>&fT&-YXo}H*T_7V7pJd3+5;r~a=;5OW5xV3)dTcaEoM0#D(z^7j zHZ~V*zHO{d;<0S-9&u-hOYU}quMoF+V7PrIa1*~2+3xHcOON9}+)kojoYb0J0`ePQ z(kH|1m|z6a4)#OO5C_JHE!~M0@cxC$QDT+5?U)pdbO(LnKp7TfcT}UwM=h`Zq3+Ps#)5~ zboEpD(^09nxmUbVa|0tFBxutK)U|aSkC(w`y80R`MByMbJ$3;R@?pE`zX+W`{WDhI zetT0s*KzZ)Y+GFfQr}cZZ+2#~39A?@7K1a?B^09`3!AW7OV}_}X^=yL%H&W_u!E5N zs^3wt)gewXDhDt3unr@dDpx8UY%}VIRe}n>q26If;*Mzl&y5!KM0k#}*hS@|rKV)*jn&Hb* z?I`V1P37uF`?yi(?<}XWLetkcsyplgZ-he-7hSoqn8g=ho!;F=v2a_r3Uy&i~`tTn3x<>htv z%^zD6B=*7}an>tyiES`k^3+N@a?kf%rEYY{qodB|VoJC>XR&;FRJ40PaXv~5ipb*n z$h|MQ)HJ2kA%DXPy)6nRt23c`i~;s9=+T1+^N*+T(Z3tX>%UD}EBGmkRy9Xajdi%l zYD3fk$}4(Mzg;c0dwN)wMmD9oEPbOx-{{geX0RIp0ISDpo(IiR%m=^&!UP?5O)ylU z!kpwe>pA5a^62`>wHV0b8PpHdkJWaV$S$BZo~;)db^X2gFh}ozWMN@-UD5)dP_Acg z#bOeeCP1uFAIh<>E+?x$dx{UCM5pd1gWl5B*Z2f+=6W@qj8|Yrwec_l-Xi;^ByW+m zJ}I0IyF0gR7@Rt3X$DkfF&UdNGr(Sa(TG(t*0;{)U5n5(d8r$6M3*cuI#ghzhVPXu zp*YwDe@bKOOqKkpE>3SbE78scPhw;N;5J#S=d89Y7@mg~&p`$1AYzBaDZzL?>K2}F zisx)aJZ=|{)2!;-o}nO%!O@|r1{H57La3c z8TGXGXAIoklo9#FNdbd9(|My{ChCMirV!;kLt&xrDX2vuwh92a(L~JDlkP^E+?6GF zXUU^ko6f?PWq@52#g1@LT|((-ko&=|tWe}Y4!(eDD^S(bdC`xupqWV8IL*Cbl+&W!A|zp05?QEi#pXoSPM&xK9XZ0X`U*Lgp=#Csxc9;@Zv%|RX;>o6{6gQ zrn(^C#|0XS)Ku$pcL5l12-dBjQib%O5P0iLd|x2$9Pc`tsquK%mq&+b`Rc z#Rt@Gx$pJ|d-7H5cU;F2y~3VF!z_g~8%)?za(A%{&D7cH%;WBY+NVD@7-$1}t$(HGm;dx+y7RjSn{N8Mm48eOCqk2<6?`V!vE-Nf5- zc^j+Zu)(NC_C{nU_y+SDam_p~oK@$hdAss2K#;7=SIaObi&wKhVLs~?ra^kJs}Y26 zM;)bXe@||331T15^?^rM8qO2TN6@}1rC|hWog(#l&MsG~&v~mI;tWbW4x4M0bAMFv zpIJ)&YtoHg$u6dOqP2<*BOD;&(>%Kl)v4W|pSqDv?lJ?e97`2@muq`q!y>rzsnU3> z%CP5AE@lL=@nGg#37ojq{Xaubhh23( zqN#NN%uPc=%3%LGUhK7noSYk={=(AuXV2N%f|=smwFTEo>FlAgY}z@fq5EeUzGsq&6&K}^@{v)Nw>PHnbO6=YA)9-G=t5)pK}kLY&v15P)z1*m4S z%JKSl!6ky~FGT&+*FjWnXXOM!!!F}_(45*rDrAt|Ozc4<8Dp=1L=sT3kG+irHuf?d zb&Z5WDR3Zw7(&?Vdx6pjDzt0%U8p-(fSvyLDBa-@REZW9C@yo*@E=VTecAa9=VhJa>R?1K_H*PN-zPm~7)RA)}N$xMtF0 zn#@wf$#O$Ry69~4y9&Q7+6y-uyK}UW2O*_?98wQ);5Pu-7G1Jhx-_!|eQ30$f^tMw z`BdIuq?^@CY?LH@wY}65Q+6y?kE_9XEvI%`Th5Akkvny@({oB$HE&pQG~Ns&#inRqk~P_ULM>k0>e5#&R#z?7Ud_Fv?8w)P7n4RvR3@n=4>8SO9l6k7NCm*UgY{uc4x79-Jy}iGY_d}a8o|7;CCmF(5d*+SL3I zdwLB#5L%vuQ;=G0t%^h*M+l=ci6~`@M4qMu0Xt|s1IBHnWfy`0$QnHlMhWg~8R5wR z_5>J`&0dBa!n|a**8ufQ`TX9zG!MR9=m|o7(+ZNdGle&$@s~RTXwO)UI`& z*K62|eJ%1-Z+%U&l&X4LYQ$%1 zwMSN)koOZTvp526W%fu>U*SDlrZ^9^%ginJ?NlAFJ_)@|Gkbc$PZ4Vm#aUnd9^z8dSD8)N8Tp4E9iA z?SjxQ4X486q5{($7#o_PVp2dpn z1e961mKFn?zevbLzC{Cy{Uw!;=oy}~1vM^b3tRvM_H)3CPnCbZflpOfUn@2FN=DF^v8VY@|@vuK2r{#aRHmDockp zMq-e9s!nJG-_ws#d5Vklw6$Ix}g>UL>Gyf=NH2SZe{`&w5mgp|avfPn{S z#W76b7;?pr7Oaii7Jea8K2JEos5R{FF?3(m2{nI3fu3Q)4|iHAx~Q0YKPJ;b-tr%Ux~eLXVWy_;u4FX-Z_78L1$b01*Anco*I*Wg=~{Z3XR41h_GxsPG~2`a)5>x^Rn_UifusAri>; zq|HNs6dr9R0z?*V8gIcvlAT%*wrb|ErBW%HKgJrc5vU(~&W0? z*bh(~Wg!!ev33wv_6pmtQH$N!*g=u;tf*1lM^wQssQacH$;WG+} zrNl%Qf5+!zyBtf~@&)I<#uG)@e$8q54PM+{THSd79f<|@0dy?AXf#!0gTK0S*K^49 z1N{96e|zz_AAf?$ELbf3XphAZR3W(-A_I!p))6cTZ&aapofWUw>*v!95zyDWh%G!p2Kq5tBX9#!Dqqk`kP!b|h7U-6A`D0rfbm zxS;D0)=mWT5L`e>D5^e2IvVCvv)Zi`FGf?af0I$67RAV~q=?jR{|Fl;M=QR7QF~w} zHLLH?ki{NGy`8sDub&qv2jnLKnJPPm`~mnHRRq}dJHZykZu#(hu;*IpWqHRuLBdKB zMHjOO95Jh^s8wHq#3_-cb8Y}1kL7qCi~w~jxEP{sfs_hb_?9XB>jB8BJ3xzvQF4`J zmuua_UBwGGN4{=qOI-%Be<}CPy{2_aFrUvUpk*lDDMS*ZUtR{HU`X^xVZ0YBjCMNr z`$mkG0#WsNfPMNgHK{lsO(%RBP1b%_OBV}73K zFxGHgraZkE1BPpOc4Pf9VKg%L9h|i@*eUlI?NSkhL|j26?}IvDMa$+~dR)WBwo7JK z>6lua^?mGwhOlr#P)XJ%)#6=?KvG+AR%d@&uA3Jb^t4sa93BP9ge`KrvyAPi4I`#|U9U5Sm(mZH1*PVTm)T zzPKF@CTNqq)hbA2p~%pohWYIQ_Dl)Q#~6=rd>UJ{$pfzO6&qj4H|{7D#CxgBb_CTO zi#=yCh@AW3bz~+lw?NnicT~uS!2lDM@UaBst}pNpinD22i4^0+h&0Ia7;_8kQo?d? zO}?~Wn@MV-cGXzE`g}tPBw;cY*|097j`6&{mR)rM3$w&PgZK7W(=y^s!{Q!`XotyE zjm3X;KS~?RXfjBs)fwu^pt5F!HZCLw`}Va+#MhwWfhB}CYHgO+uuOrNRLU-T-x62D zVBm7@v#3V`>=)=`2;1whPFG2|rm_GPFUwF&a{d=2H;@e9&J>BwRDc(Wz1Q8x|0X;VH=>vt;xW) zH`xsQ7m-te2O&%eYX&jT!;>BIDwFNMW{e{~%0^%GU@eQC-1i~9l`^LId(aJv|7gU2 zPVt{Wmnr_=!$la@;E1203wxBZ^LXK}OlRA{NpUMib^q4@*jNLAV`10i)Wuw~5Ajv; zT)WAoE*O$yN!z~;V=FeY8yxbVW`^CBxgEoQm~m>(3Ge02X7$a8W0BhB{a8$Ggb+yb z;k4V3+LL?Cd&Jpt0&sIL!&Bt_K1=M?k3Z`5c8gPA{i|qt^|LplAbqmj?uKLXU(j$E zx@?UF08r%Zk%n@Qy&Bun|1T&m$4uKdjaTmsyZ+hgr8P#?gU(Q|C5D=(IbEh&r`TTW zOjPbdeTuU{Uo84FioBnQldxw|U@|Ch1Qa;d zAEpWP1as0!Orc+n}xU@n4POfBiWA&SqNK^ENn} zZ#T&8Jt7VEWAk07R!rpEf4UXYgNYWP2jsp%OFK1Siqi!rrm?;tpC{l-Z2S+}(9ib* z;|v{HybNbmCX)LYh<4VO0e0fr zan42htNI$ba>0>CP`BAzbZ0Z%mjzi*lCTw}RM~y~F(RLCf*#nT_iIGLVk?v>;0&{= zyv>Ruy2KcfWjT?+Lz+#g#P*s4{=GwLjr{<`K(xTLr9`}~sUU)|cvDlsx9II|D)=_N zCpQ%Uuc+E7ed$0Gz-W~R9;H|L0UDLsod>>2ujL1t=~dWN@W0|f{xuE+hfX<=U*ioR z*Bn4Cn6wX|5$2dd#yVk^2~?Mmjk@2_k-c$GR#Zyb#O20R*cif`PU`-d|9zu~zBNMlS~C zPtDlm`xM(3Y##Pw!qaMSa_)X?U#eaGmqC&c+jbWYk6DrT&u3Y#_= z1(#fW9g2^C5Gr{R<_IZC?SkJ}r0gPg4$5IqR2nXphe83i7tqM{>LOX6=u8>yU%UAP z{{rd@JJu=r+9E?c83};M5$mG?cw7y#dX$9H4=kl=h%em}Lyg#?8{RWQfp@e!X~t}b z1%k|03b<$BL~s^*w?C#`r>==%)1;%|RuRTfYf(Wy4hnQD=>&mRS??&B1Ov-spn#3o zSdje-h15<`Y~yP|s1hJs7IvCkA$g8~!O_i~=E2`+v|Y)QqhNQ(qF(s5HQqj3N^kDn zI~xa;O7N{M(JgQ)NNP)NwH3D|m$dpvorj_Uc1JmCL21W?9uMig*+BmATYD-a6j0M*{Jdl}u=wZYkk*8UvsJfc=X} zc9uCnXW(m*XF;9=)i}**SC4P$-M+a1LIwFer-mh$w`cPgoWCe@wZCUpyM|AA+v{gU ztdnq7o9)N|3xTEBDFncla5*s>2lHrSr@DUxTZy~RpsUf4*#$}G5E8Q(x*8E;3R?&M zMv9GRfdvAtOOzSsY7hp;iz~5wn2tW?V^M+uLtkBEJ^-+F15uP)NbajhB~-w-6yD%58W`Ev$gQVvs!#+aR~vNh zf*n}}bk2}WI4iCSn=05(QA@ljw~*UWMG$8ATc`;8H{_+9QSq9JAX`^Khtkg=J9*cl z^8s7>F<3q|$T|>P1r`GSMh}oNBC^8@n;v{0;*x%iy^4-24a3=Ld_xS9kj@((R`5xU(q8`dBdFd_`}lXR zCL+f7@xK5TNjOV@xR5wk9JQsbWxjh~O@+w8^(g{&69N0Uap@r1DL7lci-It%A7uD^ z%;Y%>v#e_43%2>{Qa;xm$DFu(0LjpwCwpS2kAqRhv98O)^n+cIm`O^j%R!iZ8J6#{ zW5c$BENOCGE4&)(w&D?|a@{V9c$^}h;be!Nf{f{1NrV-QIQA|)uWSx{i*fuEG$6A- zJc;?y<7`;w4gU8;n;Puod5pu3apsT*vdGs*n!<8%BorbOUL$t)7>ZX#{0(rVU!kxmI3%e#vK?q|&1hRnU41Oq}UUM-hJXgnP?&O@x~t7~Ui zo=D{T1|EQq61<)04h1SldkyedLBavV7>JiscajacZsnIqUg?>?K^mB7POxr0VlYb^ z9(W}2;C(Vt%cz0zNT6mR3;FlOg*JF)4|NzkQgCw$M8{u1WDH08B%$(l{FAdZV$6hF zuMwG0mw1PB_j6~hplbJw0Uj!PP@Umuczrc91 zP^}zR*9zASChf+*i8E_g=j^0>+LU;jBc6Zq4FYux`Szh2?ONPpCiTOoeAJUBG( zWRdW@eDY_I&Nq$D$CsFa3jxyLTxGcjnX1SK&8ofo&j^h91Qm14L2{SyJr>``ghdGV zWMFi_%rQ1V$i$5SLav($je+%EhjD;)&|p}oRKG=j14Hd*3`?JUSr4I<6k`&Vc0>MWo>8VUA{9Uj1p4&h ziJ*Tt5%gj(;r|TukEyuPRFGb62jwyK;6|W4S}l^{JHB#JuZ4tGcUV1V)Ox!o<{3PF z{PeNYuX#st1`@UAUf}*(?W1Pz;1;NBk-|LKNiAXbI`8PFYr@u01zT82$_DLnWP^CH z%)!u#A)FJoVuD8cX@3QrYNRJ3DmBo6q6Rj zcafFl@eiO!pLS>#7DJ_oGapX+SEz4=ly60ylHWT09OZ^ z5GEge_8?{tyvajq2|rH6oS0XF>_39^ycaAMWUVmr2iYyy-o!c+M*B|8R$n{{0LC~d zuUm|&$jo{-sIb>W4Wm;Ch-6>F27|sN2SLw}Vnp4=qeyfrJb~TDBLqkTWeG*I1&9DM zDN87h>f>_~DQLKiL$wV$+wD?j=yyU#kpN+uie1c4NxM;QGt|?%*q2DL!GqOvk0_%& zoi7rn#Qn8#Da{{oB!SKtP00QWo;@)Kaua;hySTPOpVLmYKi4-hI3niIgwJQ}-^WEb zbD(;|HsGhd<}U5(a%>$TUkclcJc>%mVu+>NhZX1=ARL;B|)7%ekMl zS#QIUJ7`-;*tnBEUI#gn)|$#HDEn;fxMxT^%}UYbklpt1H1)utK2Nko_HTc zI2os0!lt@RLGZy(|2fPf&|whrW53kEZpd%9N||_?#B4lqGO`IS-h$9rpHB3~2bgc? zmJ5d8CwH@)7b$}V&u%qyubWw_lmU9&D36-A{rK5OD5;&K+p29$};}8VkR- zo%?7bBG&ln0uoKoH)C2-2Uv!1-7R+iFQDY?OUht#T^^_r_m=rUtlU#Oz<6qPhv*CU39VUgYn`F zaS~iZTYhqZfQ`h)@dWapnBek-ZKoiHOCD)K3t>GlHmcH88}_LJbI^(};DSQa4hN0h z)$F?%uUaPNGV--0J-hvj|CeC#3UsMYQO|SJX1Rr;p zX?x;5+}i2fpOQPaZ__j|5BTvZ#zT&*IG&-0j78Y(=#;8(AkxwYa}eF?at9h!XIwdx zhpwfln-OJXz&Ssq(Tp z@#!JRj$v04oqL12_g+vGgrBKPS;k>4gJs4I&zLvCF-T5Ws*%mJgrGq`fus28_yHx1 z_9JXE*ym`%mb44#qjcvLGB^n`7X{W;?5?x-;N;vSW~lr5&)Ge zcJ>ow#`y4V zJAXklr8K=*%V00TO9vEn2iXQ%>>!vK4BPc3Pho+nXCCIgCBCJlvmXEn;~2xZ6_d^x zi3>1Nv09Ip=rQ^?3rF-&07uyP8Os3sPtXfXFCbrct`54w8G29%ip^DgT5xsNU8KkX zdQb=_;dHbZYDs6^;s+2ppB@wnXRtpfQdUyr3VKio6X|R56fVT#XAk>-gh+K}#QMX0 zFo2qeLAVQ4N#nY%j5Mu5&Hmwi>jA|$hFCG-Kp{Gp&WX|)#3fP`;W1>^k8rd0?fWcpmr*)7H~4r1YbyU7k>;+7-Q!Vkv`QpvFL1B1GJiTgu=D97-Z%N)OF1TJD{g+f1KSi3qAoT}WT#%e2IB(_ zc^VBd>?c9?7s%DB$1KpDuHv#O?8debHib?f_i%&PV_vRzCpfZhJrVgndQd2w&F<$t zOiQF8aWc37C)qE@*8^{018Xj}x8lZ2?1Rv>GDw^_K1Av6FJD5{WTPZeD980W&U#{W z=ID}Jm$E-M!pAE3d>S49fN2K2gmxZ9J5hIz;dKzKa}e5Adhp|!7H)1!oL6*m+{Xap zj3u4T9Jjj$>oTY$hry3%;sPq(9HZ%UW7~vA(Y#3KJL#OJp+(naQ*jQ1AJa@?*Z=p$ z>8xhFcn%fkF!)hT8zaG-KpuxJiKOEvErGY4BS7ah;}GT(1P+ED*POzBd?kec_PA!^ zcutUgjl}%_<8C756y0>fpmU;|*o_I`py`#Z(zwm?+pw!+M-dG?NYvC23@YTb)bcBkQ2L`UhS#ZP_i zWgo)mO6R&oi|#+4$SjYY{v6Bq+-2nBUvkb~p;&t|VWPr@1uWR-KW_&HMk--M7VSnt zwfZG=ji1cp-7xJK#vCY8^|)mQaceO$xTd%WW@XwJokaF+Lii*DzOdON(*?>zxF*9A zjU7H4&dkVmJ%P!8WnKRY)!7-IU-uN@auTz+fy=+&8mF4dkGJwOzme=mq1h|a@4Xkq zyJ)kZProI=$eo>Ic#9gct9N0`CeqNSG#rNGky3V4S#tt+o55{~`x~9Z%KI?>&cNB| zeRi3~6WoPh*!$@}gKGuhWK59qfSWEugsp&|0wR-MA7AvJhe0n4g93v!0iI5`7G6P5*jVa80g)Uk_vpNS8qlrwC&VHShOwUh#tNr!@5jYAP} zxe6lXSPIRO4eK^!81~y~2AX(G56d+u0ywDtHHSKFm)gOzmkf18#bs&%&U59);7NAB z9h+D?7KU(hPbWLf*e*j|QA&7}ux#0tx zkoe!AB{nPvTFx3qs-WtLEXT1$%;*OMH=IQVx0~ro@dpZ^al2pysqzl)Kn%91Ftt=+ zzfrZ*YHWpkX;i$u?e3Y@p$?OH^H7IfO2Y*ezei0N$8&IY`M3;Q`Xz2l_m5aIBK%0W zpe)O3TQSqxx@;aml^FY$-cjkN@m(z#;XUwa9Vukhp^szj^zlKehH*HNTn12P2)1z|_K$iNUsj-pBp z&ZmQO0MDo0Ajd3H4uW>=T8ii{&H`a|E>Dm@Rka@I_VMHEC9;mg2q7fW79>ozQ5vxB zUqB;GW*^^-UiHvjzt{k)V6*e_i9U9+Frcv+DD;vEiHSi5n}pDY710$NZk=t_?*r6_ z1PVQgLzL>HL_MG}DZu{EE#S)^(>Ejy30>?s2%G*mCaL)eP`WSzXS?WV@GErm8yiWr zA$CtfI_2SF3nM%#=7iWXgwe(Aqc(O6kM6s@il5{EHC1D2*UV~X7XQ)Z*m4hm-T z%D^;LRJY}=#&5v$`RkscP%$GLHGz;)574ps{%<0GtN$W<7xw`;_my3&l?zLShPfej z&Va8=Q{iHJ5k4wkz#y*Tg|xfE=2rh-Yl4PDN-V(k!)S_iF~Ln|Bhcf!1=b zaD1!;=N!!2r^wM!rNpi}o%>B#ohnW(ImDj27huOXVypYViQeTx0OAPUoymU2;Y|ZP zb{?i?3~vldpKDh_YOS%ioI?_L9j^#(;AU2P(q6+g%c*cK zs~*9eFmwXUd=-qll#P`BPo(j(Y3Sd`UU4pM#ag&s_?2idE?1$6Djcne4pd!lfN2%GN-yPseC{PUPCchhbV zgf5)1)t*{!r{u6)Mi?Ox9<|Q>?Q-mX(JjX|iBs?kB3qm-77WyGn+Yp#&DmW{9$12w z(rrsYKnYqcmw$;3$#80`UvE1DucEftJp_&J-XXS@V-;IAh_ITtoy`a6o2B9MO$fd` znPrJ{aywusW>#m*zX2Nd3A5!%F72kKNsY+*OH==&cm-KD5YV>nH!bSbwqo4Ez3N%S zRB0PfK$9oAUoy45rq#&oZm~>elSChZzlkckR%SLFg(vv80e+Cda4Tr&tAC^Sb=dL- zEHZ^^FB)M7g?}7m=aE~p1=(-$t_r8#)7Aq%9zFxZP@mZngJV)l7I?WCx*c3N!|qC0 z`?}4w1<7Kpnd}X4GEH{2(2BIH*ly}Sg+SO+_c*li5c>&T)ImM!Z22kT_fG z(g7#l8Gl9Z$d~X_BD7HD;Ae`la8lh99L&SUG><`>+Jv2As}N4rZY3WFo*K9^)hysZ zTs9W0dwJ@jvD92DYZAhfDkF|$NDB1?F+_Ug4j^G7j`%BLT2A%fgx0cMACau#vY`ie zx~+rFJFz>1>)e8{3d8P;@w<~RG9nFd{(0t^XBrz~;BYZi*9cnDNqsu@Nmtwi*wB~J zu)`T>Ljn0*B}HkNMd6Wu5xk5T4Bb+C^TCNHMsNlOa~X#12+kAYi#&l6I#`)qH9hO2 zvu@R$a*t2J;f#dTDzm>#7xv=-M2C@{)^TOBYI;tHlKMr3(`nawV!Gc!KIc3Q8W~(O z_L`dRu#&!(sNnDAxZjHH3=*H*s>*Xnb74V5c{LR~!cvy}?&w|gJZQBtareG{(HO)w3&mVpti>O2JRCL_7J;s5s?FPsuepl zt9FwDL7v1ZLyg}<%i!E2>t-o?$af!>c(4P`K=!Z+#!qDJcT$_~k z83rUM3v4Yl9@^piT(x{NUv+TpuxrKSd1TIX1leb}r;XghNY5M7gbgb7ZOKcR?MB{7 znC)Jmr3|J8nC-@la1+dS=K=2XW;;wV{5*(5abYaMK5tegCnh^`h;@~htA{a&`PhV) z6p1OA={mU`9z%^YGWrfTOwi3Y&So;;snssh$tNM$c)K8Fq7oAQ4t#rhYZZIH86h%D zMal-*TFg#ZH8pLu_kRYSomH2CF2;pyFyL&w53r1jq@2q0AbI~DJmdq<;z?j>?^d)q z_a)cDd1k1%zZKEc*@y|S*Vj=efEvqG=_21+xWQXv-F`hTfXCUG??iEwhz==+!YMd} z#2&s5RUzNuEJ&U-WZaYo$5TQ4f?99YJc%-%Au0uIi*c1*ioVg#Zbmty&?MIU0nwNA zE)0W4@{365ICqy`giwD38DTq%lrc8& z3XyvNdU&b5=@KXTd_GQM0q1^yMj)iX1A5VY)G7zyniY#2v+lT^{RD8-JniO!y+nQK zUMQ9s2gxRj-Q)BHq94LZu zfr{PRnvA;s&}{)<2-+!32f%{-t1&ZVgy1&3D?wFFfcz3V z>7RofBM1o*L3%ZQA|||CDJA8)TiA;;i3ljIwAqM2RXC~JS4uR&N3Bx&5P!99LUr(N zz=!7 zFM*^Dv>t9YUhqD8gI^dKpQY`PZz={0AuOhrGY2vdzWT;OCKzFTV;=kKdq&T1T+BX5 z1oPQDiQqi;`$TX)>rDiG>`)@Og1rT}GaH&hZH~`r%}}hU zspIZ0Fi_D?48*fwaY(yX99D}H+f z5_Ae_1GKSMyb`zak(;r66Jkg(!M2f@$ad$U5SaG3xEBpjL)kK~F zUev4rsesd8w;s*IlIAOzL=4|?X*$0plOVCF$W_6fMOu{>4e3jG+Ca1yWk|r{2m>aDPB!{S?!NI4$l6X!_7BPWC!|g!tBWw@F8LG5`Wxh` zVC5XwF|z)I7oAAf?;vKJtVIU4GYo7$M^=NVb@EOheq9Q@x+l&E#wEkFIzW%51eguu zs!G$~<}}7C=>hfvad$cuF&v<tIi0j8?EYVAyo3l zoHZ`B8;%W4e9w)1DhfI6qa(T;24yXQzQLKsbXgGngZ)}y)b6GZO`!r)G|J*`VL|I*a> zuBi>SE`A1nOp}1l09_)xMc;-C2gqgL5h?4z4qK~@{Rj37A|+`Be%F=^_R70p(%Crj z#4h5Z`u=^GO6Y9!7p?f&im4#nT%zMrdPq3MF&~@d*r5wRWsC2>2P@e3sSNG|nFnED z@3IN~UqeKALy$cUgt=NarLD}}_^~PaZc<}=pw-^xv*3J6|DDK&4fCFz>7f3J&BKU1}~YpY44~ax__4gS`M85lCwf=T%DAw%XL?RyA!d z@75k%dr@{#n}ounD6Cn!Yzy&YDw|ALD8To?3PPo;{-a~patW<(Ie*v7&Vh}>c~!NRc67NME2y_v zux*2%BPknj{_Kbq)<#(7+WW0AMBK$sUSpDq!9ud_XTS>Yt)-xBpnP=&y9WaZD`NQd zED7gDiuJW^_Qp%KIL~&eSW0TmD%Czh=Xm|+#HqN~4%%ti`NsBJHS=hDt6j5<`f!)u zj;SF~1!j%mr?}X$45JSG;EQo04wos$+Wh)27t_6b0Z`6@*05~gj{|^1z!FY)=<3|E zi!+8I0W&DQH5Hfq^=`7hl&hrdQ1TFtnU19>k);U3&RXJ?XpY5k_`ia>ZhGCvv5Y|TS< z%A8y>mi1c7n!0H^vZf;I*N}DXF3M=+!YzNTPWpk1SYyNQg_^abhW8{C&u*xl@kNUR zBOn`_5^$+Cd;M9Puz5ol48YIxVgTbgWc&`Vwie`v+t%SM^+Z9Li)0P%U6LCvE`a-X zZVxQ*L(YFk0NsUxs{^F1mwS4R4DIn`%W+FPex@l%J&6^DnADXlXxPr4ha&LnF*dkK z-wo04&61vrn;a8(LZikN0_aAJeOe02(UbzeV@oERiuue?Y*%9bz_oKIg8`XC%PQ+$ zU2j|C25U6q6r5U?4NP<(ik}db3kY>fC#rQ+F#2T}WW?L@jWRS{=G~k$L z2K}xon$?g!p|5o^f=%e_NmuqYNJ}!4dKtsQ(oM7kACwa{y8_I2_jvc(aL*Nd7L4vi zrLJJSV{tqCSjS@hOP8XKv^VCH>Gp6l&y zz-1z_hSWA&F`Z^?Eyk_m7_y&~s=d68-2XCQ z2FB(eW~(${6Lxgr7k+y?n|r}KVtSWpK~a}Upi>^EJ4s0hhMfBvvf#f1V7fePvf$T_ zz3SqYD6FuNVw{#7iDQ>5jd(wq5nXQSv~=r6`s#A_jnjk!KbQ&!#PLIqYu`%nIS_*9 z&vlS(@Z<uhNkT@=|Pmo=})&qD)yLBmT<4MzC^2Y2xzn~aamz~xE z+ooB#GUgiY_sQ+yNOU4`XX^I%3v8Ql4rdXpT#1`1%gagX!K5TjW4UOYVa-^7hU8rT zBCs5tJ*z(t{YVhsChY3ZK$_!9U3s(!+Xth5tYb!tMLV2m< zW~hi(e0}&`3tX*)RryWmnu1E}PRDkfx!Y{(^2bb?rL`KSKNzN6=>AwaOX19s(f=z5 z=r|-7E}OMN6U6Va%kR3=UaJ)GJ0*GY=>0o$#Z>vjB6ur*Xw_zul7tZkQ0_4u2{7$! zJt(HFmp|MfF2im5B770&<9D6^PR34fi{>Rbe*EY~Z7;uKYil znIw~BV1m4b7bTjYXw;$s1qUPu0aT(1k%UwOwyV*NcK;S;z*Yi@lV~Q7Q)&OQtE;rO z>aP9kZfzCB7bKI=B!C41RD*yD}F*j&|RAR~f!jUl(>}dD`gKJ&S4HA082;Bnw(3;;iBGUFR*!VEhtS2QwThv~0 zuSoONK4ftEn(Q9YLr>O93Fn1w83tHF@D^uqF!$t4!ckmx8OcE~)?AW``*Hb+{MWz< zs0|jb5GFaUw~+E;f{)ueKih8EM!C_jbQOT!MO`5-q2XlC>=)x5Q_bSkS6a?pA(OstVC5uOHU)aOG_)G zCCDEEu-q`jB6j`}=7GFWwf>pvsb2mXwg}M3Ztq<8a<{;*J!|Ha8C~Iyu5iWkSQ^X2 z_x8NtT(+BdOZ0eADiHr7IV^gNupS^=rmYu+A?4yNEh3cKe6uI-kT~KyI^Y zWUb6`)n`P+LKa(UbRntrN?l?mt%}!rh_3Zav(^Q&^yAh351pC++T!AP#dR*%d^?xz zd!_BC_)FW9Vy%hO6xOob=|Qbzs@|g)bb4%2+~v%wGBmWX1Aj3poB0bdXGaqmgr`pA*CL>4aR%Yzx$5@6U{rM&1qU#6D?gpnYV;br zNFP24qORixu_D_MTnJa*`(9QLB&^lgV*u~V9?}!D*DvUqC7jAW_NN;t29Ll8jfKa^ z417(b`==ME%Qn+jZ26)EJXBxb^l4OE3f9n|uzny<0Cyn}bP9M1K&?1y+-|&=^S*HA zHmZa|)D5~+`wbc;U||pM^s>m^FjB|~J22%fQYSH9V1J-lOR1DWVsJRzw8iNt;4p=` zNFQ1IUlx%QR$>#4qs8i3`X3q80ptCgCW^g?T&4eMaUOIMKPoTVX$+y8LcyWcfn10+m3ss%uZx*^_TFmq|VK|-{1J_m>&Odt>A@iSG6$N ztaWV&&rZ2b^75Z9i=@F=(a_$&ET^+ny-IMI+@MBkbEBp5PX*dz6|U)ilIhZKIiO7s z^u3EKxb}I75ngw*8WN^`&o^?~9loK{uJd_{O4Xk=A=W;4KQVN)hJ^aMmxw;?I@r^> z3Eno}&;!IsCrh9{qle?enQpql9+I0=he#8kmJ2`UC46YMbwE%0b6VJ6J zV;Y0&9^fG>9Mq0&gLU=11=l^u-}-gp1y`*h&%#ihBr7ac|D-u7cPR8S?{bCC*c4%Q zq5a{q0}elc@Qzstf0hwlFO8G>%{J?2bZB%KqfWwc;FaSFpRfl*A_xtxdrbdbqyLKg z+~7J94F=bVPu==;;zw6&;7}Fm1AZg{KOOR;lJ#DiE;W+cNCwqYuJjK9avRf^%c@UY z=}(-p$nMKDD-~TY?L;-_|MA1j4%Suk!2G^riY^KOmGzQ``d}9W8>*Ama;q`Clhz4! zEMOb7nxU(2q+=+V(-iKrGb)qreedx+{7-|j5pp&Zsxf!#)e{+O<$a!&_bT!>birjt z2bp(}dG#jgblYO7fDDW(lL{CpXPpL`{B||6CN2?1wvBUO4vc%W;Q!d0awRmi(B*Th zLZ)NxZkm&D!?$j;nuKbCR#6SMiMW4ospC5-qGir7TTF|)6o6;gHIy-3p*iR*7AkJ! zgx*0iQv2 zOcjk|C=tj$EC?IMD%aFiPM;_%E)^`jiz}U#PSvqPvkpn>a#~^}nH80-9p7K5B1YPC zt`A4;^c;6=_?vPsicBs>@;-J(F(#0Xu~yR%6uP;I+v%-Tw?p{?OI7QHW{2U ztm;9cR9;kuW=1$R)PilA+c;$=vVeMVeqcF5Fgv5B`|`7?TfQq466>RTMPaT8k}y#( z8vl?Oo74F&4Ppcr3L(r-54><#rhG88mme&nvD+llrPk)(Ka8jdC@X@(2<1W#RjS*x~QFOAv6R2J|EF1OJ;o3}M16w~X$JsriAtF6+0a97q&wO| zIp#{*DX6(#7Z`1OxP|0jafPp$#O!lF=(^60=zoaV^4&)G5!`3GzY-#*kX>@}$ zy;v>3M;2@zN!VW{W`CS}u zgEA#Zj-U31?e&i(Ne@cnwnV1K+Ppnf^sCSfXa|m3ky<@}@Tm0A%uE~uogB3ScM^lE z=Z(t5=LE^=o57NNrg!JkcV#QmXspIh2kb>0A+@cNtPf$)AEz$JQ8bf$%(!tLuKq;F zTo|*`doyX0QU{397ub$&x`1r^)8Eis^zwN}UoiUM(~bo$!G(hi4VQP`qy91KV4J9E zj9}1=qor!bR@RE8wpNXyv_Daed|TEzd+|J$SH{hvzmi__puU;LMDc-nDoxU~ijlAl z{I>jbIJ%M@R5~b8bLfULBR8m{_C%9nYTO*QY?1%K%@O%sEBWCt?;L%E zW_3##wzPWsG+FolX|0KJ3nv-3CJLRJ@JD$Pf|j|3`Zur@YmfqFapgB^2=f^V+ma}$ zQJce}j|cVd9}5w7(QfetD*ADlW1PJf-CAh!5Pb%Wo@f}o!VsV^yi<-Pho?R{u>~4x?a*BUPR#I>kkj|^d zax_Ooxk_kBiP}%8U2`Z;0FcnXHy6LpuSpWf#IQF{Jt__3WQ@34+0Cr{Z&p`*Nt!Qx z7n)4uXwQar&juHWv#b>7Oz*bk$8nD$H!&ZD=8S&h3>B(&x$=Zw^|FH1tylsvzaEi# zVK_3ktAZYyI$cPtr|uPEBMj9J9|lw;-K@xc`G>J?>P zY#1VBXk^VvAzaIbHat3kXs+2KM&01qFf+lsYx#dckbs{B^*aAB<_%~V91cXCOE(tN zLL?`ovZ+_JY{_ZX51SkWG@v-InM77gDhzvQfgRl}R7de-?fO(V&iL4 zfZ*~t1wcds_JB4c`4RgG49rk<#UEpb@ro^sd`m=h&A1K$%g66t>Ji5BSJk@b;RddO z_Y*_uLG0DS!A1Qks+(k$BO-31FB_^plsBynG}6q@0SHrE;sHC%H4I1wJ*w%Sxjo!~ zs3yO!p98DHjLKB!H0}UpHgF42f2Mu~_s|hRkmltp56~U8;)x9oA(8e7~zFKvv$8PnGtnBtQXM#$ltB2WT|%_ z_3q!K(U!%orUKB+3rm27{jt3Q)b6mo!rSWqi$LavhTVkmJ>UHwFUFh6604`h`ZqfK zG+7xvru|QedYO80$Tm7kb3SZ8MTAmyNE4@Q^Q3-Fp$fjolQ}_YKhgODkCc$y zQ!At#`2%Xcg?8^Q&%^KVUISf;&hTj8?3GR~Oa95stWSMkXD04Rq^@#;q8d88;2rf& z-51i2t3$UW#BN`XR3?Px*bAj9n*oZkpdRP2h~X)?>v+SYFOB|1Y>wbM<-2A&+OX8o z;*6|teVLdMT*--7i=YRqd&mSX#ncZiQEj}Ip*mg2uQd&}M@!Z3C0LvR$0b$|Z;lCo ziXeL+9QzXy&~ov!)o7jS@ugtgIy1oT(OZJ#PY^kWkcCy-3d6(QMq#n>A+o8stSe_5 zP2(zvIj#itkNY~{`R4Qz4Y7RtMxgiGasU%EMu&2fO=V@I(MAkVE^ogwNG%%l9D<7&_Wa1)X3@5x=Ui#DrTq`{Scc|9MC{&$JU^_WJN6RgB zK1EP3tbp>=BzhP6wI3-k^NNkqI2yS*^oWg#?(Ol-E~p1 zEyt!Zs74oLnDPGfT^vZ1PRlbs3V)JRtaeDB z;XkS`3CG;h;Fi1z3FH|&Dy$(#5h|W-@foU@i4rX61nh9iqM-i(4jS$}j@K9eX!b-| zPV(X#!i!YiDCi`bqbKs`9Dj$=@>J!NvfdNn&yqrul1=lI9f6N$+_yF6iMd70Pb{y@ z!8=?T#)n;%ke9h#8T>WMWvFYQ1J+QRCwNRp?y<%Z!eN||aReE&gFH1lAPf5kQs)quPg2;=5o-0D@lpH%kLD;2;9hW6 zctT8EW}6??t?~GgS#?_?5Mqt@E%oKYB`q#tTJ1(JVOK3c0{P+! zS`Ig83avy$cZn`D8*U?=BaB$ExPh(}f)CdDc&boVUDYF&FdU^#kTs(@a)dOE1>whWX zd_Hf&;+miI^&x0Nel!GiA=29eKhZWiMW3< zzEZ905Bvp>l1w+J(U&h7=NXU4K6HghPH+!M4C9d}c-~yipPbf0Rjz|%iOAcnIycEc z&E}CKL3D#|-&%soDw7t4e)%jU566SWk{IzB?Caa=rS_Jvr^^UluMoM+2= zqVxLaQp&)i}0nG=hb{<)O$*XB~{IddsBaQ0mKJ}r})BH_#wX7P9TGZJ^>>HRlc z8-*U6Z)kAiI&B%m0UNt|a2uWK&SNB#YnSL`)9hn9^TlhYw@=2QS z5@8yg{!PS8`qo{_nx1BM#bjd&C?42lM6M`-VSQXCBIp0FO4YmYLxI(9Tbch*O;p>; zd{C+c;;t+LQea$$B>9oum^jW_`ZABY=MTacxTzg%!VPkrQHljyTCw_75p6J_E4fj? z*wWFRZzRO>6EfU;X4#OOUQ`4z>12~$CNtKp4~PKT4Nr%%)HOaQ0Bume=D>J)63AJ7 zYLH`AmCIY@_7!o^x`5&a8`~{tt38~mP&9FAWPSeluEd+s#etU7fmPTo4%M-NS?!Ns z7Wk5DTqjbNgBUKHWmq8XMe*Es0T-*{>Qd76yQv|a7Y}}i#bakb>3Z&YY8so{>LR*D zo8gRv(D&nKiS;I@-8}lH(VQ)LGFxh3_%sZYP2B>$H80{OYbaxQ#c{clCGR~u&N&!- z`_Lg1#HNZR3z>=4lJ|HkZ>9nlX`6CXFk_Gae2=XNIl1CU9oN>Z?kW zTx21_X0Bha(zipW@r%=mKttnEi{H`cwIynlkOl@G4+WFpek^Q(`%#aMbc7ysi65KK zf>j3scki{Kl92}V?M*$TXejtBaCe8TCI3_EdD>>o5U5f^>oCfc&>(hub`lH4Eo`_^ zW~|Tul)JVci_P*8rXQzTDw`(wvQ9AP@;lKi2^Q=P-09?#KTo;1^Wl0DXLsrwxj@Qu z2^}OJUoX0E&}T2o@8Lsv7p#B#UmQvr%WNuKLUdG%#3oU&(AO8L+<2syLRFokqc4Ou5N4O%;== zQLqcdgxtn+k7;y}WO$oo$glHPF>=VxVT6kVo#}7c?3ihXI~}FR!!Dmat@(J^=}Xjj z0&+XZlS^Ri6XYo!7fd#Wus1B$Q$%ht+Be&{rOJBWHx92~BfNWjX&@609b~%`{>nYb zmd6hXGvz`S-2Ww6+ZNw0z6NXwz6||qC&4!V5RJT`(HlTv$g7UyD=@uF4pyDse+Ws* z)XCy7(DT^CB*!rMG{UiV5UQ!ki!*$edS2g^^4Te*&_OdU+DSv$fXo9VZj>9?Bcx0>m9==3|&wi)3i zk!cme%QYSk&+uIZa!OW9xYH>;2P!+h=cMp9-lg<5`|+?8-(qzq^^K|M2D;Oq-dEK} zWBNR=w*@{<_#5SeDx5$Cl4`a}i;GJYrcq{D1q{!=ADyNVr)5N_Q{dBt@TX=c?l3!XhuMic>2sSooov;HAah~CG=MWU+QXka1BVifCRsK~ ztXa?NJjPa%U8Nd~Y3aH7%#kf==~|pF(UGx-j)vIh3mi zhGsPeA!x`7z;(nY@_@s}2jNpL&jt)cljII-+Po?(H|xuLD(&?PkJJ}@y(p5#`@){w z#`=OId6fxh#a7^y6^C`G*cG8OAZFc%#g*2d+4V5Ap~KiKhfc}wmP2J{+}0*C5;TWn zSZ`EUb!+5>&X@t5K4*?7i|_w%iMi3YKB2mBnNQ_389nW1Di=m4{pG=WwC<6~H_&V? zllKk%Nn&VmG~&Qy&UD>rD4>-Nt{BT{hiIWDpvP1Y3nr;!y#BqgG@4yAq!K2(1|4SHG%U>^^;|r|2y%h{H5|u;+2x@OQY%; zqLVljTFD#?=07Hedha^LP%pSng7Sjp)sV~sq5Q{KP#X(X{%D!x>A(VbY6aUYvJem% z&pY)}*O~Bv_;r0;;KNpcw-EdpN6~~*Lz6%=YkLp9G>hrrBlI!zvMZ6a}z(-LJip-L*Pc&E&xPYHjOdUI~ z>T(pe={P-3SCOMQBH2i%Y(yGKkLcRxOG#DlMlvcBN_Eqo9`JDjA5jxUBkAy5F5GDU zM#dd|7Jt3^>?6q}ll(=)2uV4>-2Zs-JxonqD2=4_0;>{+AtJS68*+;_2l` zA!&~A;haSEvqxPyi^wX{Zm>oQIvUD9v6fE#9SK)jkJa-Nu5iwYylRn;{1>N`w+T&s zJ0_?@Bh~*Rtew%9`zJ8Wpm=I$ah!~r5-|;|hrW<7NBQY2!u-?TzGX8!uaCp_AYa%b zpwuP=<~Z$vQ>p&pm4j|CR%2t~=}~ZY=eU4%^H!Z+x;=tRv|)5PmPKL{U>(!$VSrbYbmCXF`%HUoXB{y~9RE_>ymB^ANz11%^+;c<*bdy@9OZ}o$2Wex@~ zqKIE7-4yr~Jj3s5sC*pQP$`&(KKh*vy&Ca;tf3jw(5VD`YYfx-$B_L*uQZup#u;-A zhXw1T5XUwMU&tK7myDC%c28i7tkv}r6sjvcK|RhayU_ExhuMp5zCWdM(Dy5X>8Q4W z_r>2(L7z9gbiX+6xpyI~Y$zmipePiQq&eaCzCt5h$T!hnQsw)ZxNN!*qdG-2rg>5B ze*R9TheF+iv?z%k>fp< zBvS(}Po@Uf{qz_&*p0%Oj9z5c0z|qDwf2_`OQuad%dg2(biGOkV6|2MfB7|U7d?ST zrBgoSk~jvMC)c3nU9Wk4_m3s&L2iS}0PGJ|9oC|X*i~?+j=|O7w0Ifn0<&20g2IIY zmP3dJg&7mkN&FfXWq%vU0GHBbM%CdG^{y1qtPa6{NtM6g*Sc38FG1q5_Us#5Emp$# zjm5*AjCpYd1;c}n_}2bCdj?XPO!ads!)J7cqCl(mKBF`2dR#UgK>6TIgjZ{v0;Gj8 zOmim)pc?M5Us{bXXT16VnrDQ2fj#xT!qN8lZ2N>vpGW*LR&sFcouN0(5_O(j4p+ASim8pR(^-Lq#UR+JhE_h%M9&HL~B-@l;H$ghq02_Oh`K+`I10wHjK%?-=m zV<1MG8>BxawuN+r{2igH!)zAZR>7v<&2fNPd|74UViYb$s$zQ28kxyF1}ApCaz>P3 z6L~4?dY)$-`$$U)`mCiXQzVamoH5#Wz8a>JkEIRj_|vpI)7JF>X>#(rMPS;0l#&6( zh_%FR*abux$k}BjYV?cI=w^Xa)_BHa1ju*>@#iq!i~PH{}r@s7{E0>O={rXrTiZsWh|xuH)6Qh2#b@T|8$oZmER`G4O$to7>#^LG{YGhSzj9IzJ6@h}o z+@1WULe?aLLs9-zE%YMS3Io?z2E7c^eD1e@MHkZRVqIaAkTK(p>;hyTt7p-^Mt9R22&TgxT|(GOpTyfd$pJ=o;5U2aI4SIWafQ) zX!hx$N$}L}ij7e#4+F=jR1(Wt)MIp``4%6esk~cbbfy0EzZ@e-_JA>B{hm8U&}zJH z4XFqpVwiSTq_s0>QG_4c@N4#ZN+8d5CV&7-;E*Dj-#LWX58dgq>EVeFVtLoUou(b8 zf}eIzCXZ}XXd-G;B{)yFzUT71J~DK}W-&r>1e!8Eujj&vgyvWQEty7BpxK_&;!ojr zJ5jXjclL`c7$Z&m-hzW${RBPV;1shRaU+E?#N)FV-q=li zV7mB(wfQd*U^4Zvy(`NN0Is#3C_acX- z7}$#uUM%>YCSzfCPly?T``FQo z%e%JRz_FJdU)UibO<2T9_rRYyc-M9Y&{g-{ZUM31G6taW4bd_g=+tuKh#k9d2UAobpvx|+0 zYZq8f(X7~K^;$u9Og7h~dred*H?Va*RY0!(49Xg+CQuC%k>Cf^g1#sV3`SEFQ5z5_ zV^QPi%^$X!I{W_&qb{yd4l{aMk=|k*=__O?sD$3fghOz6*6ucrYHRiT!Q!yuTbo=4 zn_Qr()8-pbq*2CTM9Y0iF|9m(WT?K&HQ@|uO-1iRlFVTjKhz=)?VO?Sp(n8CX|YxP zIP1VYbPiTl8qUO);ZL#Gg+x+7N`n4QI*w$JyLfBB(r%CYX@%r;Dg!*~JZ_%&Q z<=K~y5(LM$58`YvdvRlO@YVr-Fcq6<+|wfH|d;4Al|kcN6F5X=kv%B@NJ3X7gm?=6PitP<39F61pYYyKl_atRq6q zZaEQ-|6HoCk$fxdAYqV0+ax{p)0%v%u>F;g4TNMhu^h+< z8|b4yXR6q`UZH3xX1HsdR@dfEYWf+((|C&5O$2j=M0QV)BJ%N%K{}*epWiniE8lwQ zqv2K|MFYP)jiN)5=bdB`C!Q9@8f5(hKWNxob4rGbBZDg)JWC4}6L&nS^38~pPRqHC z8b8kMJH0@CJ+<>$a*ht}mG@iRtC%zwtLioJo5}plwES$1mxj_U%O5)trZ;kuOk@|9 z{F!O@CId-7yusL;mNgf`b(_FLzVkFVk5I5;FrFoZc_ z-}U^T%>T>zpB+$n6l3czW{OqJXwa)yIT24r(knGo(IV~JR?Y~4iea#X?$$Z!)s$4b z|0j;>!RecAywrW4E$KXF@|bK!vLA2G^re{3u88}1 zb9(Gcx+VRJ85sN+l}A%=#}v64?-?!Dv9oPTsYP2FI48Y0&;L+u<4;y_x{P8Nub#S! zWzc7Q0Ob0X^sMc8{_&4co5-zZifoy_TU0YISjPi2D7Tk1Tac&Kzlf6>ZIdt(IL_0f z0Sbc!{(PDal@;5nt5%|>P(W<;`Tj8Q1QzI?4H0C%hEVd>rcH%v^EWc{(?eBz(UVRp zJNg3PD^vZQ{!!{usu9S9thiA>`kt;+*9VYEHDWjQD|ZJS`t)cwqXlzS8c(e@Iif@` zM@3AzH*j|kQ0p^W^Sim|vIV*`;5ze%g;g@+6s9!pw+$ND%^FNU`hxnU@K~6~WCHb~ z$z6b*a%wv2$D-(uyz;Vuo}J{zA(BC}ST+>&;+ z@-E(xk{j~(y7MBbP*R@!b~l)gxne?64G9=v@y0@aabod8- zBpNEXJJ}FL$AU;pL;e|K8^>%8+4t>^`2wh)J>*iUfwkSX6K+cAWGvIKo;~D>?1YK@ zJ)R$(=O0J)Tx`$Z)$8+J6EYEuzd`Rbn){xou8tQyuB(AJGaVFI1N$0xl49S3&h&sP+N$@t8m_NkD+k#4j zg_ULfC!5%pTBL)@yCtPcCs52Yv&zXa|Jc1ktt8Dvb^Lx=QQUZ*jl6HMp_~xKm{seO zji|=d4Wtgc+_wTrVTbGjEfmKe0oV`}Q1~Y)tWf>abx;l(o*p>qTrrycxdx#nR+ouy ze8Uebj_t*PoYRPzdlnT5Yo_@gw=u(0D?%!qBCtiEgm-VLIBUO`KBg45!an3#?*0;@ zzB@Rg+$vzQW+^#=Qwhs+Yr2Gn-V72{L0?#5qN@O|qWFwVSF)d$#c!$^ILK_^ zPA7QW^#l4NHr0R@L|T~-pyp)HI!=D-v(apfjS#klt_J(G$*a>=&JTb>2-uZBQ84cE z1etdt{(iRldm3(tW)oyWA%b$DVNcKJkaLA^B+M3LiH?dDoTP&{#a+DU^DH9Q5$Y=H zWwQO1*mOfzUZVwaQYv14F)SS@vUOX5g++IQZWd736m^D(IF%m^@Dyjnq3TO{*RCKg z(OE>6fe{*70dVNVh^HYPbXW&0#vdlukC<~~-PYA#z`Hy+Ub9wMv=pi%LQA)#*P_ub zz{wMDX-Jwj)pz_%V|`NfjH~>K(OJ&OII=T#474y5`$GIcBx6&+ip*^U^rpP|-GTq~ zWU1-az!e(X!^lOLUb_@l0eC_KFYx*r@`t>K9*n{vGw;#WtIMI|0FOn9KX5X^|2<u$8jxh{4hhW8V-m6mLMeydCA-4hM zKfyI5~4kDE+0X}XtPN15TyW6n~;5MuY0__|Z4*=O5=tA4@u$&58 z=nc6Dl18;^I2y^WFtp4mNWC_jZe5A`Q=^bSMJ2fhr=D%W>w~kzH3`UQ``r!SJYIg^Kt@`t;E9Bw=JazMOJw|e2} zJzvq+Dz}`56dX(YI<1cz3V*lp{+>?*Rc#JQs# z;R2O=JNcI%xP6V$L9R_4a|G4yM6mqrV16UkZ4iV+1l!9m(+L9234vWvtWTaHnWJy$ z*I40kBKHFo$ibE*NL4_LUQxI-5guv9jfKTf%HFhsZb{vV=s^7g3BB(vy>vyQH~;kV zi$rA8j3M9KWb3HfMFxR|2WW7kKa~uYZ;m*KLFQD0&BaqIw^ByIyU_dNh#D5^A>5*U zQy!p;@Suksb$(;--F=Al^WWyz(eCIo9LCO}UmIs~k0Sv~474T;J)RTB^GmZ6=sgk# ze$kkO_?lc5yk`siXp8eEE9oL^=XEUoI+#W^ z2L+}X7-s~+(O{bYsHkSWXORW2{{Z6GtJ|VWccq-Ic*8yDO5xe^GlF%`@DQqdfWJWf zoyeuF`UU9O&T+HKrj7HbwA4MwSImgaXoboc9)NWX}YH3Z)1A?!1Hfu7hizC(Ky?qWs+f zE+D_*u3<)4yATMpVWXJ4JGkx@f+K@+Q8DFscwwEq8k;1g>6n2Ds>6bt9wTh%*EE;| zKJe9b8+lh(bKdon%>e zJXkl8jgDJ|;QC2C%nXK}B|I3qoR^xDx$Ht{t3XEsFRXzJwzbwhAwSf%weB&VWU|Tj z^&vYCnbr=HSl-$}I@7u~LIYuE-~?t6p@yBOXkD)n2HX1MabcC1b0k>zvM%gN{$fwN zBe?!Gp43kk(YtG<9`gb(NDtDeHT-~4scUUKwpOa=*%bDr_Bw46V>c}m+)RC*xm2c|Jvg;5{$=M{CcsEIf1i;qOB%Li) zAg2`@LO+Sl3vQCpHb=nQ>Z$!X$&9|76CvGYA@>_*4|-27gJvUOk&c&4Lvy3vre#h8 zC6nC7EVCUUX|AzWK4-06!(TR!kd(dWkP(t`!ZlxQNb1Sfq6cQ45CuK@w_4@YNp%pd z>Mn`Yo9$=Or$U1^Nz$V)8M*~#>+$A6XG#YIUeH4s?~Xe;#s=5j!QYZX@Fa<%e(;9b zHQSf~p@tpbF@93nU`QHZj-OOUy-_k?{G^GDpUgHHKfNH%9zPi{89(`D{3Of2XZ+sY zIB@(V6R#e{{_&HZ9WZ`UqrY$bB-3-oPq!l^%{A7_=d87l@mI!AI^*vdKdH{Z@sswS zJATpvbNpKM;K{P9baqW;cmpRVduoTtLi^h*^ax2{@M?#fD|EQILiZCIXmSQlvO;tB z3#+qETBccJqdBJ!M}HvIeCRk5IJ0c|WyR)XF=vOhf`aR0QEBF^P)*bpuj!G3Pze=_ z`euZF8uhlL0b9FP%7fN7<60)gTEM(+4|iPqB+zootMdn)#z5d*W!YT}G zXzo^|(2mBx(#}6x?G&%&f1{mOP5X{^q8X`ION_+H0;Wf)u0`f#T|?&9u7~XJ=K^Gw zp?8Sf-Ib|j!H~>acEtLF6x|C!))Z+QsIq2w?FT~p`z~JYsJwU)*E)4Op2gl|!=$>M z{K5=s(iZ;AUK(;U;CZRee6LXXF zI(Ez6Q=UgfrPA0W4d66*jV9o4Q=wp;v@TTF$TP{MW!8AS{+b?-hGyLtU3O~iJ>}~O zY?1^v-)DwSi4RpxfZ%6ad!Jt~>7nnn`XR8}HpkfJ)jPJolLh#ynFhkK%oBV}7Z%mI zM4lS3qnH&M(A8FjE;cK4b)!aUn5yZj=g|+PT{is+8=EG3%os^ zy2JAJ{Cb%b+LMHi)`hK$(7PQMYKAAM*$J_E`?bVAvCMZDdNv~sy_E)@59!2tjux{F zGuR~ThVx-VSH3s<4~{xvN|-4LwK|2Be77xcW^6+-3o>*a{QrVLYZ8TdYBy0T1rCW7 zB`Q2Rj?t96JD!`gZ|Lrskv5%1D+Pz7AIu8O!P2NM5w6Z$26_gWGiShhV9vbsduuJw zeJc#TqI2{*HCMN%?s5jfFjqL8xgOz=;SAjczih4!rr8f=fS*ACX%@(mz?RHVei~wl463#A8p=>ramL1EO|Kp-7pq*GbWOyk%4`=PmGp<`?>>s;+*p z)|##|Md|*z!LguoUoO#P(sV_HtT0=S@f+AA8E{+u880T6a29!swOMn%R?godZ!bw&-Bw!f z3EWC=LgM;+psPVj)Fquo$RtKkbL%0^ln*3i($W|q6QVAJOsX0uaS$?j|KAfbAqamj zA=Bd^gzOa(YeFWu{5OP5Q=W4P+4<5nezywzYUFb!#+(&_9#UTGCAW6tiKho{LBrr}65&R0(?RB%@X@g38qI_a1T#Y}Z*W+Gm(4cl+}C+vGXBO&9++ z&AHC3Pe^kNtXipgq4sCWMPo>+MOIpq`F*cuXZ#0)nqjGfvP#o^7nvK0?3{sD^$5vkVI?&gH?uA#`)jOS zDW7j}8f)u$z*;X=!ziv^VR!7pA>2G~(^3FV<@m3+nm$kMk~rBAt(PL+kp1=Py2=E2 z)3)tjy>xZ6b!6Ao{lL4^|B=Nq@W{m-MufunRHF=W;1+No^s^rNqM?Zp4RZx zFXOxI9_b^Li~N`7?yuhTAa%n;(>Ew4kGvBJK2V$(#faU5Yn<3U&{Ogc=OrjuC~>!q zVk&V|5KKj<1da`7BMk@_ph)B_0X^$%qyDNM9!$oP-%F$GY9wC_) zp*>i}&cwZ+Th)%D1T>^X3BA|^dz5cOB-fZ~HIM5?lO6?>PVfkIhBh_i zyXpmdB67DJ@5cmAiqd_Pu}y3`Pb6VBVSy1^>eI*bu#RZ1w3n7HP>qB8l}r4;8(4Ad zwMK}Qor}wgJhQ}ky&dADEsjWoj21&yb2uDyJ2qb2iiwjP7Vs$7 z0Fwj{i&g`-y}oI=`?;i^g|khFGN64EOgk}D^?JmaNw)bq0y_(Deh(%nn7rj5^VzT7 z-_R_EWbv#0@~+oJWN+&4Y81Rds_4Gh{E18f{Vv-=zZ?5)#Sx50T@wPGXkDqX@kHu2 z;93Om=qZQHZrpGylgzO zG)$AAFUIg97l%>be(vtyZ>>{gzzpEahy7yDP2=g|#B z@$T?EatS8dT2p{v0hSh_gp`F1f|vA6ctT?PYm5`Gc!YX zM9xk_*T}3o6@Bzh5_bKBb3nT?wtIfpYGxmrHnFrMxT%|xW5_|qdg(b`VM9A7SXB^Q zFI5X}k~Vr)zas zW%oShR&N|=`>~dE`K$L?(R387`^X`v^YnhW^d_r=_xN&h zjv5^efVzC7J)obVS3rmXz z42`bJfZp-_IWjvoX=F)T{TolegLeJx^j0Nx#f)v{9L?FmKPTPBI*HWEde? z@4?xj+ThzEH=WDPkc3!kNfQz8k!7<@^3v7E-GKLNl4&v#^wrhELQ1kcEEy%4UVO}f zLB>u)C+^xT*9rR3OvF{28P`+4Tt1P9@tDrTD&uDoYEeh74z$0VM_cvv(aI3DN25%@ZZoZONiIAouqA>ynb75P)nJ^*vj07SWGNP}}|y*P67 zT_RVtMMYI0H6 zkLdwj!VEV*4qv>}Nwcc3M~^PDq# z*%85;+L9TwO_ob@Z3TeHM07M`nmgU;+SFi}I&xQ>tY6Bbcn*>KS9;()_2>R?gLsT2 zf?>8)EGF_%6%q}zut+ul-#~`{6BO;o-ZXWgYelMOgB>fpQBK^1Lwq+SBIN~DMo&#q>^I@0?NmK%Wv-1q9QQ;@w**M{7Niwoj3#4J_ke2 zYx*1VJ#P~To&VvbWC54Evo$%^iZ7N^tj6ZQxiwk0qE(bbkP7&&lTL$Mfrsmh6*QNE znEvCW_F#tkuPa1FiK=9)FMcWYXI?QcE-zJ8FT?ZY9xqltc`#Z+cXx}PfCf%EI8<0= z?Syq~q_I>LNfbC*S&y(-C?d+td2|x9Ts!wR{RazUK0v3jP#uC3Lih9BS+liS{rkT% zO}BE=ed!xjuZ=-GzC)E)NAA@>-j?O(srCKezkoT26o@hEubyX+M6WCa?r9+y z`;Sl~Q9|m8ToGN7UWi-EdlOLc27d$Ph?z`q=~k>eRYg2I_Ol1hoZIvz127H(-4k(r zRw6b9yMpC=gXJA4;NWYszWgwHRKfD@pdXbN+*tPE-B(Tixrov<$b?G`drYb$2cHRQ ztocDP#%^`Wpga5wvV4O-_jg2xJ7F&ju+`8P1#5RQ6$GC3uni|a{tk7qybg5UAjVz8 z)vxFZi&1=k31!Jqhml}VCJXptbok|DYK@0w$(1JM=lNu!WLwlHrBt<$QCS3i%FgBE z)r~q=(bWd&a0xu_CAaCx`e}*U_n*XL-tI3!4>MNCM3d?6i0sBWS>^_eh3+3kWlTt` zl{iaqy_n~_DKNbn_!66MrdYOuXXdi7=OWi(sU;r6Ae)W8w3;dB%dZ2BXzmW1jk{G~ zyiORn+qGGeMF8O0j9!O4f6F>ZW`2#H#Q#l`;#e%(ypC`eAsj^I|#-^Y|V7S{D6V zWo}13^+Kq;(*=jy6IjQyv6Iso>Uky*(JqYJG3qz1o@b{|Nbs#JRnPsJQPS>HJB$yR zt=h654I>Ltp&)MDza(CqnrYTRyp3B%TBWL-;`DMt{Te>9{6GvYaFEnvPvlDKZKrV-ygUNIDrd!HlXPTVZF`iH13q_Ph4t;YM20@-j1 z`p|_IY6CZJ9{l{CnCACl;+IACaPULf4m*KXU#mRt5Iho2v*3}qbthHdb=8D#;&>wQ z#tQxV;Tg)0)338W6+@5uKNYF(Yvo%XCKRVx?JmKw1)wTmj`P7JXWH(Ya=285d-1EvP(mY?UkwY^z9W>GqA62#)Jzk=t?`i4f0@;qh0#@E#2QJ z7Yc%rKqZN#ii-8Orxws}bg2*9JhgQ^4ea-1`n{lnS&a)A^d2j`3p*k4sboDkauw)C z6cKN5{cXvYSuYjg&t1IcSg&RE^OG+Z-^D$ViIu5~Dy9Mf4KAned_6Ys%k1CZ=&`ZB z`an&QylE<9M5pLs>SFvNS$}nyQix}!$vFye%)sHoZ3v5(KHLPEZ3Q>#xT>u z=wo}s?2%Vwf0No4a*nB=Kk|yjOJWdAa8;tA@8$^C8yYqj6}Lsj0{GK6np^I^LH<#p zGQ0PKW#{Qpb?^mxkh+K|nuy^vUhW;+882oqlx5q}mdI$mq%0BOt~k-0KV*Xa_MBd8 zNVQ{?J7p6K3=u{~BhqE4Go`ebO)Q0$Sew|N>05!NSB0jpAFlr0%JvWZTK1tUOVnmq)4u{-Lmu!(0UbSstkm6R4u2nT&CsXyhIXk{`lSBs z?k}O8e;v368t*C%oRV$5TVm29z5H4|vKpZl$C~;jq78GtxvdxTjH=#tC>TAjX&4wQ zdTW4a2djW%>TI}e%7of>PwgcVw;)}tPUxKs6|{h0U)x~6e;Y4+H zyaZLb5b@kDS+!Mcw^kwxzsq#gZo=wpL9?;Fi+#)6wlqG zGe6J)wA?xHj8X5BwFynG{!>576-U=ylm($;$0}Bf`3~HChInMn{SSQT&mf`FP8L?gC1gb&Ig*Fpdu|?=n|WlB z$2cnkDH@-)4l6x5EkTrVd1|qm*TuYq1^=<+B72=lA~dQ{IeFZrK^n&!zw7HQ>Tk<1u>k?mb@aN;?$yI6h76b@_|1_JkE?O#<_ zb=n9%Q0z-p*_v*;Bmbp_G1QS`W(_M7m%tc~R4>7cnQKXfcnnVInk&p%-;X?X*Yc1X z?Yd5W8Y5%WkN7Uj@4@~guYj+{+KrRXXksJ4yBvh@iIlKe?14+w9Yja#9V6%8Nd{Zo zp*ilrDopoXm3d{ryF`X)V{V>8bA~a>bDT?X(g{{jpu%Na5=@H0KWr2R5DWNcLTVE!TAdkOYuP zd+yfjI(;c`Fa*)1_TGI)`1Zvy>EiR%O;_&b|a)Rr5 zF{x4Hr`ou)SY=~IhRHJ5Xx%Ksl|xp$YNC>GY4S$-5z~o6{3c9(RZkr;$uCxYhP~N6~k-&=!1`7ppP4Uv$Xam6Ht1W*DbJFc#^o#CP6CJV> zdhbVA%#4X5=L$~g0e)WdN4V+v34sW#xBun zX$WU`PHXf#U$I9<^V~D7lV?X{FwcF{P&53RfqTVSpZ^tzrIpEGo0R1MSdjl^!;ik$ zbEu)2mutyXR3+GO7Ls#Lw4wxUS0+c$r_%2CyVMIlfHI z?_8F|w9#fh2zu0|`6@E1A!}ANUo~vWZk$%_U+vkjMOdUmNolAhkU}l}$SCjhHZRM# z>_>-bLxHRNgHI8iOJ9+{Q0ioH*j|!yF;JI2*7Tos=}0m;*49W{5~$Jfhv@v0t6MA zOkTer`K)x+q+>N;janeGTV{K3rjuNQLjv2z6(SZ^4_Pr%)b?jh**Cex$WUOqV(!>{ zR|mS0>)es;G-hWz$5*em*``;I!#35kZ(4SR;mocGbgr%l^sNrvmF@B;cCAkn`szM7 zEL&ZT@sE--8?|o^-IncC2XRoo;As;2=98PdqGnq5Y5;-vU7?`c3CP&JHC(4G~FMb+W&_a z!M~$VJas=ILBw{{vx*L^@JtxqLo4`g<9}a;XW6bv6`oa%6`tD?(|;o$PVTDk?Ai8P znRveW)1&m~%Bl*_(QVVOM*O!rt-|x({A}kz@@lT|Tp4{R`^|26OGL}T+p^up-aykZ z9$fr)1{s4C>JC??qsMA+bQ>jiRCt=gNz=theC7D*S0j;M{fg9~lgfSVSw!XH#T-n` zq+*oTbiR#;B%+-!(TKvd&{^xLTwL;IUNvOoxQI24)~u$`O^qOC`IEJ?fygLkNuIpW zu!#FD8%0)dJ!>~UG+N)V-HG->SkQSgY4#}ac=$;p@lcJ_9&x{8V~iq++J^+HMDNe! zD4o@gO1MhS3WpCR;zNOj&ua>=oeuLkH7ks0uG1dwN=s`J9|>Q%9a{sRC8UMZT9>4? zEKZ9na|lQadq0~+Nhuz{0Y5@wb<$`FAjeW3S3EP z%^_Q($Hr=Iw2{$?@aKbTK9l0jp_oX`hSD}hjP|rd+#AgavQgULc^xDRevPK@Zp}L; zy#G6TDl(^-irn)y(F`u@+Pj!PrbCUiHVI55P)t(f8HWi8GEDl#$xB+e_oFdUoDfhs z>cUK{NNcS~YpO_VUQ)pni)jlnPH*Ze0Yxw(tOjRoLm(O!cLbseW!?^DBEe5C!yc`w z^XN(}J4#?0?*L>U<6+aKl5#W>=CPpW- z73v;7WKV0S_YVmgm-%Ej=W$wl_|V|ACRqhBd3X``t)&8NBXaTAxy=&HlexwbaTHVF7N#q>(TH7HP>uk0 zfMdNq+$E^U*c!ICtK8$TICHXEvfhIPG5pL`=`RAsv5PEj=_~71);F&(BJ#D1$S@mO zEmYXiSecx*3$OQPwYf_O=QhF62B%?-qH7@!-0r0D9jilSZ>RO%d(pWlxat_3jj))}{pO&$ta8X?gdC$dpJQs%t}B^L#Cp z+w}vLDJANk%?~UM`Bu-jvubs9%mZeD)Ji;H-qG&?GlcxjL^hfm_khV+tCv{UP;`kd z1H7JWH8EDa?|fYFmWn&hPPt+w2FJv`YWy5>>f>lq4p{C5A?AR7E>`EsGuYKBmG-Xt zk#j>F?{14mGcSsWC(CG=v?9Xb$}B1Q4Hkwz#xIbuF$+J?4c$KfAwj`$(U3v+dBQpo zsnLA^wA8dtgkOHamJ~E)WK4#Rk$RT(v(6DH{XLq_;)$-f=L)|*!7{(L9`DIxrfBA5 z#5@hp%93n5Vy=l7?=fAobv7p1+F`Dmbs3Y^V`qrdE&!SWc8*}!V-LfAu?)R*JVq5K z*-k`e(KSeTl--2@KczMgG7}nO6MX}q!{iv+=(RHPS7XKnlUdIw2Qdyicrjb+aslr@mMj5 zJvWSYjhUYJ_$lf-H2c5!sa-xDD0RjYZPV6#2gG zbV%8;T@CyP=u2{A>eO1*5D==6_ny7TB;zp_(g?rpM&zVF38|Hj{^8jDM;SUOwbR6 zrFwN(hjjY*5*@^OYJJx*lI{fS9ECsuRte$mcPoFmUS=GO;S^8$iytn*s*Gn?z)X+* zA07!Xm{k65eOGT%S#$dwt|i7{h}X7AZ|8oOw$LS0cm^?;=aA%M6hvmDpUJl7QHaIJZ|*vFD&R z${Eb|l|RzA!!4LpVjiqW3b>1a+m$tSH>)dd2O%w>6Xc3+ErP^gD@xiTE3?}+d@3=J z3292geJt`yDvK&_Tyvd{T3)YgU9+_ae9~0fD{D!km1Pw-8hMpBD(fkWCl!@gcJYqE zp|Yr|T_!Rk9x?<^-;TfUE-6ICxw;1a2D|Rw#QZz@f(Q7u#2~|d->#lxY1E^U!R%a} zWLa&Ie^fsmrgZb$wA)YP=ydvY?!5Nqh7L&u8>d2?+;b+m-#`6KQ)ia+rKVHTvW?S8 z#$ELLSTqb;@g zGO<&PKsyorY=5Z|<6Tm{k(yoQk0q-ZF6R3}Np%J2N@IzbB+-ex_EkJ|b8Q#>K3tN5 z-vGU(pg5tGa#iMspxhF^e>RoP%6ndV>~lk%n5%0ec&-#`Eq$XQ3;3wc@hu*Sa1)#k@RUoS&vpdq1I>pFd!+HTbiboH9b zdKyV8f3L1ADZto;`%v`1{F5&wVSKZwOm(s-f#nJ7JuUdgT~cLUgG`yfAjk|ito1MX z^R_J0YLgOh^6yx~3Wg06L!2x?7FgSEEp1zTqb+E&Wj0RNT%7WcT9Yx0Lud&MW0uYG zz^8h_C=pC$rj;&ElS_EBn?EdPJz;#4={uvt@gAE(8q|%I_?cY7$D}@H=R}sf{G%*a ze0%i|JiR}YcSd8zgD5{kZ!u$gKI8mfd+6I3U*vP=*C7doRGZu2;tkC~W6%5cZW3*w}u`vO-WnOIkhFh|sRO zO4_h@V7}3uzRZh{gseqR#7xUdYZ8s_cArr)9R}&BA^oCje#pM zw}0g`=JUV(NmC(pg_TAqt=j%J)h^%I-FESE-Xp;(Kx1dU2bJ9~-)O4u>be8MVYxNc zk#c|l)m+^Xh~oos>bk)bKpsd`8%7>j#9B)V@&8Uz+}w>brrh82VdR z`)}$?w}{5Rd@g;c%+QAFo{dY&u+C-TA$syRFzmbF0H7o|-PB58kg9k?=Sp2#;+Of(!0(FhV46mZNda4s$$!6KivNXEV zAaT^OPGh`A*WU>Zh>K2FeFF;*LNDcTt zyZCem;)GhVZL7}V3qCP1+g2GyHnQeWA&>^y$HY`uqKJ8etJ>x645Xc|P&hWbisYj- zT)ju@*hhKGEB4_h3w|p5~n@YQ-*rhnNij#qZ<3qlD#9cpbFcz)?$UQ z*@S}GX3J9XNaRl5ouv@5nGqxyuUll?0-_x6^3AKld44Fbc23N%hkF$6fSo^B?!Xw@$T1PwP5j zqrU24()^n5@=Hytr|rR}f0T5^Fw2N>lU6L54^?3$WNw6UB;Pjelc@_l`<(d3IhQca zS6jx!=a3!qbT1vE1zJ* zL8BEK62^yZGQAmgKktf9DAPW=(@OA3Wi#4BeH-2i;kQtSVJg4I#PpwQ6zY_%2)3Uz zG2&U4rEx8^&6LugR1kp>I4QzxRs_osgH?Dwnm*E@KT;x^7UF9?#^K%hdJe=RynfZe z_Lzs-qbo|$NT?qNOVMeN&m?1lIThkmXFtg}5Z)7JSQ~(`!x(fCeKgn}_9;B&Bdyeb z*HSC!-Siv*3)Ay&^}=TD`YsPcr4qe#mc%GW+L-)Xk8W?oX~hG8P$^U+on>b1$^w47 zy%+%xOR&`HEz}X|us&fGd>C3DT!6hHR2m~bX^3J^8ob$)1_wN8h{r?v${(w`p;wyQ zqw%88z8GE?*2pE=g$32QH|NglDR8mOQ^vaNF)>L=HIiMG!^0J*6C)1B8`}ah(9x<&)**M&Je$4`Vv~1-!?V`v3H6mf z=KV_Br7dXV@$7op@Vc4T`K}#ku)@O?=mWiwEtGz^-}DI@Y>h3x=nE6|L)G~OaxA_W ze6nD|gNLE@XkB=IFByK`_%QSVcA~7;ThfEaT=>rafSpun8AJv4X2+0OPcuKdblTUM zdpxVI7>>7-u!=-#TnV!d&d~3)wR{KYUxtsz%Z%BK`xEVuH63r}ilZ~xbXvT#L1tw% z7Bn13!8(fm;8BM66oRqIG5nJbL!=_S0u2AMFzj@SPZLY^^fu37EHo{$ipEF3P4u)N z{_yLd^TW(cXw^HcI2@Q4I2iePE}2pcJV zsV{Jm{S9cF^qmH7$ff>906cVz4_6(#S(hkb_?lPv!C_#Ag# zTY;#<=hf*=Z0N!c4;?%#^KR5UlW=ZyKCGf;`3q$DNC;&RE4zVVzmn!VmC;f@G#0-F z(;V|-V-aLoX<8W_fp;WONT7@#eNC1H%IH!-X{sC3Abgr*L13&Hg>tDjt&WZ`et#D4 zCE|r_T0e)a?Kzr#Qf`*`=)6UK|EJ`mFIxBijeKV0dqh4wEYI)%6Zs@~bkzTw0?C1A zKU2RjrO!!t(PgC%{j|f6!8xxz|C~!!VA1axI$1kXGq(7a68(s1bjZ3Ndv__2@K3(l zP#*N%JATe*aOmBou1kSM-y`f>6w`c6&6nZT6!DgT7Kzak{7@OYwi%rHRX|S5uvKp86XWVLq~@9k zqaHS4cGSmc*U;4{52hWL6T<+p5tW#Lb_)Fkz7!1IlLCz6&eXg@`7)sD*rZ&_%2Ox0!y zJDIvc21r@g7mVr(esj~FVA<|_1a9$5TQvUzHAc^BFdu!krwSkdIeToYeOSmID|(AQih@ z%%{^7L(S2ie)u^Pn^a&zVS-hx(_me~b$(ij?Y^?S8@!GnQcu1(tOwz@&ehw}hja38 ztXh$Wnj$W;ul$jw#B@4sSYXYHK-7!;c{gZb(26_`*Pd4UkwaW)!Q%ow0}S&sEw$Yj zXlJ`G#v;GS-n1AmN_M9O-#TpLkZDyAW@&m>^*GZyD8I;AburV(f5706`OSKooQoCP z$*}9sZV^5f|hBGwBP_oGM-Ox#`*AJDhi!OK`vL~ zMX(Sor$l3?Zw@F60-TDCy&mD4;1c0IAuLZ#Tt?SME`}bXVCMq=FzA4NRVfKP*>?wmr z)kqsvV^1QZ()PS+Dj=ghGOG`_zmAq=MK{Ze%Vmb1vv2Rq3ouC>iQ;j_o;>fFp zSJLR5Hh<90ScAx$Hhl(FHTQ8qR_ENuvMdYR_m5nxDJj6i>)ac?E`Ezs?Qx-`dHAmK zi$9dm27VN76vD@?2zRm^T$+Ew*0i{LS=-{6+XpJ1;)A~ew~ff%3ND?L+qflfety{F zdz1NiJJ9T!jZ<_9ZyBn`4O(Ti7 zQDstIu{r=ZF%=h$9!Cb_+Z^Pl`{KDBFhIA1Q4A~5EQncFQqjW)6XG&5^X2k(Lliej zSVCaC=y$NO=xOd;+b<^AV4cXfmTmE*BmL@qTirFzw#&8scy7h@J%_~}7i$JT_PFq~ zZH8@8XDPp9MBUsBz#p0sl>rwRR1Qn(4Z2N^RK1m;fZ1l3>jA^KYNJo%glC3gf zczwW%aNl~{pkl*aWKdX-&fXUfr+zAeJe(l!0Wh&gFA8ty`>VlD2o1njn~}#Ad~QL1 z$M)bA(<60Xq4IbZTK4SzZah1BREb>xUJ14N9n=YlPa8e0RKyzGCn%_~e+jzFoPmv7 z(9_CkZAS~8p*frJazF`vPeO0!p*8E4TC0Qhc+FXorjAJKs%#Gyn;yaQrK?!>|X(@@v8ViJ~5d?%gQwxYoL@Uy2+ z7h;jeBac(2^`?*W?>)<}f97${<9PlNGhA;Zk~~B2egyi91o&WW9@+SE4M*`R5T2~A z2zrLQ<)A0Z61@VuCH$cLPCsCAt^QklnFp-SU|j*r0<3d&tEbQ4qpt{hio{6zJA)?# zXlmmGbj!;giK!l# zbRPkx6ca&EbejQ6hKHqw_Jwp4f`&jh5}5nY+mfive~$kx4di|);qHGW;l727z(q73 zP6w9@w+?P6+(Edra6iDA?U!&4a6{ny;G*Dka4X@qz9z% z+8>l~J>gv7eBi?2royGeWy39oTLt$4+(Edn;p*Y6A(I1~3!EBmJX|u|Jh-KB>*037 z6~Y~dqr)BgkipS0zDEF$EA1H)ajk0r_b<>=w*aoISs*ucX8;%N6v)S;pW>JRZg*e2 zONa13JED@cvZRz$ZF*dqR+f<@(}UJ!X3WftOOvH!$@Cc+veb<9nefPxU&rRT>xM7?t=Ys-*YJ^s)?{HeHsLoRY?8EKADBlx1q;5|NPNWEfHt zWfYBgP0=WHLV8?$s+NjMK%ibL)23?Y024`~1Z`H9Ql`z!M0WjBQ--w2ONcK-lg&-h zC(9Bt($XNYY(T%%tO2a>7HP7ydc;ZBXJ(`dRm)V#g7ulHuEDZ+ZF1b46qJ+}mjgnU zl0GLcHHE6M2kTzAvOsR@paA5?aj_Ev>3)<;1>#PH(+hMi&r%}aGQWTfh5-+0rv|0LIDp7SOg@!o))kINcyY+ zl3wlr?SN*{jFtkiz@BpgIs!w0J%EV2PQ`Bed_{nP?U{(4}0AUB!i;|L`A{DA#{i9jdda)I6p z91OY!Naa2O%7C&dfxNLJ1n3M}2OI?40HjwJ3W3y)OMxALRX}Q=V!Jd7{3k$)Z$Fjk z%LPdCgaff#VPkx;y@~BfJl|qFNQVBYJ(@v(bUu=i9xo(tGiJocWoZ*hMEDaDwF#*} zU0hZ|Tq@&X?{D~tm@z}2oI(L0X3R*6%hHSfIobq$My3#r@<|nm88ftT@hKEPYi>%C zeg+vVM87-l*Xc7Ap5SF_v-FuM33>`Qq+__4nXXObL@o&^OV`c?aI!=UY2UMm`XkYNcm^RHUk~P7;fBJ|2Zhy0St;}#Fn85Pt+#G8B+P-T1+NONX^JHWHPzvoW^DTd3qs#jP{MmQ}j%~Bve!R z&kb%2XQDqpm)JQenR)|ipO})RON~p=rfJjlxP0iSe%fT&--ysWPLpnAO;R??v+#qAj#JJJhakM zlcrn56LtNkv11c+Fm*z6Pf1VFr=Zu*(`NEh9;&+-hB-`jioRL17GoezW8MC=h{ia7 zD-6}~4?6pcd|UKaeKJ2I6S}Q9{>b|Dks;g0@dzzpM%>)E6by5XJU@RmCyT;3APdoE zC1j@PShwb6LDbcQQ{%F-nuW;X^fKobVS$;MaXHYJ5H&0XT{ANwIj317gi?4$nvO?(sR->3|TUo%4X@%1u4;TTqjE5%%%l$ah#4z!RVQWnX4-| z7yfi$0+)dqtror{aN^<1Hzp0!D zM^}y3`SC1%el#pKD=-!3g>mR3?;Ho-uuQF%X9@Iht$t!$s-XohQsmKflH!eMY?8s5 zXq@Pjko9Fcua z^pojL^ppKf^pm+x^uN~3Plh{@PsTvePxe63Z-cU_Pg%jyxGj#>T5brJ$jeVQh0IV~ zUn7{201Vz7f~I;IGDhX9FZ4y>ET{4~yWfunv+j_N>2`m~3mae`EEj^gcuBe~APQTP=&3Xg#T>0ZblN+JF1Netw#@%2DwZ6K$ED~EGTV%Pm>;Ci@A zaMGE9Tr6B69G8qwlEKluAQ7m8D}?*IIYJ_0=y4_2W3G?}6tDLGbe=$SjMQf7XqMoP zdi-6vshFiCAXX~U&*NoC0f*)^i`U3HO;C1Nu4QuChD8c&1{jDr1?8JXg-$3r%i%9V#%a!($e3jXS2gh zNFb)AGtBhxcV%buHD~RFQnON7>gT7Wa>S9%74_9)Y|erXGf^g!BoVck`;TRzvd{>3s{ z)`N|=ftlK2Fr5eLQnCWaM2_Icaw*c%ZAx6GHj=k`V6H6zkNAIvG`>?fT_Xs?gGa~d z8dEpplX*ou2Ddj+8R5YrLJ*Z7>jQPVh>X;fgdE%z2p7R9ZDv|ZI_xkR>7%v!l7XlXn z7Y#@8W8sqFba2^li{X~Tt%utRw+(J5Tp`?PI6BXCRKQ;YXN0SVYk=d@pg%Y%oD5D5 z7XTLpmkgH;w;XN_+y=Of2c!evFw>9);{@{3Yt!Pj zG(SO}8RSF0B8&2G^aqZ{k|ns&qlYFY4$a~7NyOnI8;wIoo*W!pSeP;`O_`NNz0A%?a_*^L;Rt}A{RE}6*@{^rJESKg(VwwD@>E<`t={+JaEup7uO*}Ts$65Ce2JvnKe5#Ej>f`LS~lUFlTOd&b%p8u@*7*&%Q^!^1|592Gu#%vii%8yPiW;-u)9$xQ!$9{&Fd{d28GKN{u4 z@z41=VSgM2{~Ja?NnYb077G5OLma^f7fG7_OeFv8PfXvuKL4z~%~O!y@;T#wM|{IY zio1HT6g#Z(kaCPGg0(GD_{|jY<8tUvaOW^$);8TBpX}}uszTSBs*h0 zknT?#fMlEFUSexHEP;+5)%78jxZ(ugC4={W#TLY5|+6nYhU_an0V1M9x-~ixeAl*!E1Cs4< z4{$KB5a{M9$-rzN&6sn6 zF9DYVC1?Q4fhNH9KvUpWpc#ZI9{{arAp95718smdKzpDA z&v7{h^9z-XW~FcD}2)BzoU^MNYh8lVINa^eH4i0=b^5e%5IK?7}ok^tz7XrL2e2;?LTgPern zkdrV1{S;_6AN>^Q0Mr4QWrKqSfGihe`;6mJyw?un@5+hK?$yakLI>H0=^!gHL$a6< z&EnDX8#NbwL21gY7efsdeill+Jq~v;B;-Kc0vA7_}LSL;k=E8+Jh^u?sPq;HbMUJ@Kd{R z1sBZ}egphrumrL8L3}EU+6eih;HP%simN}xPlt5mr#S$%4_C|rh)->VWTyP7ow&kB zaj313pYo^nLS<1LYBN+{lAqd*D{4;pWI-dur@B!4afJlvR`65WC_XKTTvJ;V&lj~vSHvbcDclvY>HKE%^r+!ZHC%8`DvaS!1N8~fPyM3F&)OKtN&Q3Qr}5`Pl%LKc^Jg_nOZ|rQMrjjx znTO*{a_ALw9$8;teMwAB^`SmRXE_Ej#lA(k(AnkC!dNYXcr8*proP1Vp2q8R46h^B z4@Yq0_&lf%!F>B;_EIJXjklC@G~%#+6~yb2^%)kQ^%=%b=j$W(8PaKlaL$;-5#Tg$ zL#z+5e%rjA1@m=GrRqQel8yBfcD{pneKkLq&Et#p59Me7;&>Cvw*_|H3FF%-8%yxa z2W7B22l9QF)tTv@)j61N%UOcfsSeG{WAd>&h-F9cS`y0+=g$-?JCc`!l^rgWM{R(W z!O9*k^i9$k(=i)Qf&@9za6J=yfLKNde@PD;Q1`y(fk=;dV7Ap)Qeba5%Z1W&n?TBwON*L z2w$h>d9^$TX?(A0DdSkQT=CqF6#P`jiM+g77*&X3XHG0XMyLxrC)5{3ebE?CX(*&+ z8rBn;%t8El5OqOg4(n$ldHGqKD51?!>9`kYj1$iHeX;IzkIC|3Et%yriof?{aUz8N zO8ErioQY-Oex)((1itODv_Z|{M>OM)6V4^&!$u8OZX`dVFn^eEUMLPdn-*n@;N@?c z&rxq8J!SGp_rjz@x`%fGu75ROgJ_zy`P)Xb&VEI{`lf%7Ht8WMd%B`GGC~k`1X1FdQ`5Fvyl<35*8) z9xxGj2B-t>1kMMR0ha<_1Fiuc0B!~z1MURw1r`Fo1|9{L1IvMQZLb0r0gb?mK(bj` z0Uv-q59D6M=W+oyz$-v|;7Onp@N=LXSPb+7UIK;zw*sSpyMVF4Z-A-5*MZr<8sK8! zm%vrPv%n3&8^CSAYrwt0>%bylCGa%xIFM{meSsCAwLr2hk?pA#bSjW+QT>7Spp$`Q zd$R^U0UZt`ThkDr6*8pX}_kk|J-9R58jX5E}FMtuigFvzwk*#Vf z=%qliJ$Vx!G}(;E#%BZ6gQmFv*|vrPb3yBY0if-H%Rzq(To0sq4%r0T0k?u43nW{b zGjI>+S-@=2y?_Tn#{tQ9*dAC48nml;RsyA<7Xd91zXOnLWE!9&_{)GUz(@)Q-yP@!ItREJ@%sToK+goO z2kium0G$M!3S0>!o8VwzGUzm*9+(d#+nhfz7xce?5ujDT<)9Y>8<0*8Tn~C9a4T>w za1YP`JP4cslp7nfnEZf5Bw0g z6gUUC2DkwjhIHM4n?X;ZaL|2#J3%J`3xS7#rN9zk1#l102rL9P08are*9GE>0njJX zI{@uLPX*Gw{dYho&_{rNz^{N&zz=|_z&C->NY@>>81!4fRlsRLDeBD~#m^CBrh6+k zi%)1ae`g%_n~HGp{*i1Vu8@rKWOe{%C1UqqwBD5XG~b9vDq6wWl$O~FXl5eX3KDqz zP`R$q4xL+OH%R2K=WH%a>4{I}vb8VFPro9cR`xdeX>4G&3tEFoJ&fi(bZ<739|zey zERG*Tm_MGEgZY`YOZ1aW%+KUw{uI7!=AXr%1LjX}mXD5a2aL}wHOx=zal|}X8)E!< z{JCfIHabJ%T#Z(Tiv9%t`p4qXn%5?NQ+!(OD)QOdA{L+No%v_-I%WQ3{+uy?8h>42 z{&Zfa%+D-LqM!6G`kTtt@oj?f=?+nhV`#>oBj}CpF|~r9?$0TeXxB*L>&|RL%wovw z3(QK!?opU!j``X768$tEV1D`){i*!9X8bgMZpiM{S-H$cz}haeJ+XCF%$6bY>AsHI zG{!6B?8^U=pX6s2OlE(H=W(ObpJ^-OU1&;7SKGL=;q<18CE)rPugjs$sS3o z$0W7tYaM@%-blfldcO2e2wdCHw1ey!s3ikQ$p5{j{yqxsf zj9qd-41k-A~`l?xp@=BYor?M{WAkk~6bx4ko$x@*QGo5<0nG!-W?n zjyzIwwGAYFb;vf$;7_;Dcj&z`;Or|uw>^7w@qo5<^GnwB+clyiQU^FxUya&y`fyxK z)s7ugPuPT*|1z`7!Smxk-uK(U6|csw8N`>-+vb%oyKY_i@x+fd4YyEyI%-B``SZ=y`pz*$?LO#nC$(~r z^x`e#CtcEWO5E7=ltC}rJANBsHrTUz=#K*;65f2F?1L`1N3L`pV%aq#eS|}LH_~>1 zd;fr4W)Yb^A74JdX5g1+rX;N!qS|t8!LQn#k=N(Gy+yVs^6}y0JNm5|HTpXo2>27 zW5vvpiLzd6lm!Z_w=Gk2UmeoUk<}gT|Mo`X%+Bdnoi`4?@BTukabbtfZn+sc{w11; zOTWxs^T?z~-+ehZt$vT;__dGh_E&!UO{T3je3bLtE;SF+j;szIcdl&hfC)Rk{d&Ny zZ5uxL#Ge!yFtYs4gZia?Upkg%9i3rzIJjh*YeSf2haVkdHvj5e|KN<~{UO~pzwq_J zmqSt(NYWomH%@fOF>HO6<8FMq-_Njg(d%6_XJ#w+F1!BnJC?&jM>id5;Tgcbj)^6A-VOH+I_AvmSxpj!jFm?S0>4;?0Sjiu=8BrOtVA-MWi&RU>-t zcI`D>=Cf?o_V#OHF2ih{%ZjzRfDpV-*%r} zdFf6Iz=RQt<>-&JVU5+-qW+Sbialb=qNxz_i$7LH=x6S%^{xkC> zuEBd!41--=7Ek&>`ctoRE@0k?oAHIlSxYOVH`kvjJvL#Pbix-g<(Cfq7VWmE(6n1< zxT$a1=x#f?W4*pD3eR~rw@h{3^^@BTebT1Cwan+mif%b)Gv^%7-n9Q_&KT1*wfxY5 zE$we#nwpxip!V(WD^-u*&4`~n&a>dSF=p`f=<9yxqMr@x(|P`+Z83)L`$x{4+cja| zt-2Z3zkiqFYxMBiY`*Q~{caC~ZF}{;7CgCP-7npDZ0V*+HiH5apDs8w)U0gOp1Z%? zxH{(DSF^5J)o%E4?96tXI)C)_=bt}pzs@IX^^p;Er{5SnW39%=_Tgu%Wp>`#=f4R$ zUwplfy7Q!OK7M7!&0ppgoc#X1DdUHl`j7oS$Qt=_(&`7}twN{W2->@Qi05bTWxRJr zlRnRR@1wcJqsmJ!%&ckHwtJ?kY}aQKOHM&?8@Q!@wR9hk?)Tay={>VUnThr`#fq1I+mUTI@Z)h$eBY?+ z*I7O|yls2acU68*oew-&IyXA_ox-iP{#i%v51YR}UjM3X?{3$2fAQXsPwgVMuh`-H zLy+gXH$M928_Cm)KVQf-$=U3U+$C>sh`6__>V(TKe;@DB$Fs_3ru|^C?d@?5_f3y( zxiNmTvaj^YM_Efk4peqLXKMel?rmk&c;om_Z;tt`Yn!1Tj6QVZ$`0$XcjK48cxV6F z-T_IMxctuV-ZFf5`u@P7i}OhQ+OBgGfBWU)3;uI9-yUkWASwKT$B=u4Kd)?O+bLyD zc-A)C{;>g_B!1RQUpU>{^?mQ3%C5e$*X_%o!0^XkrvX4Cmy1`p@(o7X$*7oj{GEYa9$0He{Cw_%_vgOX_t4fwQ?{HQ znkn^qDP-fJ!cIrFjd2ez+vV}j!2?fs&T;P@KE(Y@C-vUdPj!mQsb4O6!!GD|httCv zs(o%Ai0^ej4{}Rl=ZyX8qT^eOVW`uHSb@_8Z#T^>*peD|S|=!Y!%`%d!^Si~Z)x z$>W2+NwM&LxzOpZ#p_9R=_9&jTwC$FVUd2i;;r;!Zu?d#js-cFuFTo(biF;Dq{P7D zx0YUh(Sv*;N_VmX~bedipFQ&N~ZR{6x%~+E%{f5iR#4z7?*LJ9}^^ErGx_8aP zumN99>OX(T)dIujRk^B8UtDut6?QIdp;@idn-P4OCOCzrnE#kraT2q3oW#5%C$X^S zOe}hGCT;q0CfLQ;)Y6MHwNi7YSgvAbJ)SdbI}Iz9QaE!P183fD5og|h6=!a{iLtOY}@ryZk@-3Ad z;ck8DjXc6}^hzF(-o|5mVSa{CE>{Xd7(;V;1152Cq-M-?qkLK(^<-+rQLpi!0TPFZ zjB5I&?Yy6J{Sz3}qV`fgsrC#%riI_?q zz_j|)ODs?-#93d&JnI7((uV2mK$~i8S0uD9V=fn$l|r{HTwFp1e`AyNLMFSR;gg6G zvGgr}Ypu7L&ewE*G|tt>oOVIG{>8>g1sZetZ%?ge`}m_nT;Hu*qv>&DwN3UDUxcey z4!Qc4#zB|<&iU^6ltWR>ql#UdHSc2kf^mboBRt{wqhH_CXnx7N7q75H_)jrCyMCy- z7IjYJ@D;w2&Ydt>rQWXj*TwSENf)qtTR@4chx;x~uaL@yYx9tP^Vhl#&U-X-B0hF5 z_!)HUy*s@&e4@EDA+o2Y2J#hYfA8M;GtJtW%gu7X#kWvmkL3<{eXr){_v6p(Jc^y! za&J%1GXFxeX~DaF&y{pVej``RoxM*pFMV@Iqp2g(*N$oXb)jZa_?Xi-In*b>sn1@I z0~)VMGd*?p6iEMJ)E8^N)SMVI$7y=|f&N_0ZIk{#9MqgTHDuAi^L2jQ=G5Z7L5DQA zN3ZzV_9k|Li=Fj}`HI7u59jXN^8QNf5-0OJ_I6s4CiK@EKd#8bcXYYyJJs!qHM{Hc zPldkH)1NEXch(dZYc4%|{a&}W63}DKpN>1CDVpmXV72q9A6N6hQU2(NCNROF-HBi1 z{#--Nv?e1r7dLkEZZ$26Vd)UMrs(tuvoWy^}=n({Z-J#krc*AGuPQln)jG-sj$ z;mC&+VQc(2=K8ky7m)b<`|9|5KXThmW!UYas^|IRuOq#u85 zA9qTVwLLLBJ;}|hclYC>vpfc=IP+iNq^rFv+0Z`EA`63zAr+)*oEW$yPVb3zCPrB z%0@THZ&Ky*)>+NV_wrW#Qit$WYvx4vI;Y`Qb^W34<2ES&TCdzU&uNm^-G8(o3*RIu zw+fwNU9NelUu54Yv!QR}Z{E3K<(lIi_wRpw7TV*s-V@zkF4ye-`S60PageWYR*x5s zmuuXMsJ0yC5KNl7>wtfE#n#aAiI!hOJ zMt&VWh>yRZ>DbL?h{K+a{#-?H(F^M@XmY&Y*_q;t9SU>X&MCfpL37yB_R#eolxPoM ze)yTqMU8vK7v0``4gL9f<9oB~13xy56RsBm)*G+#Bb$gdxr`REs28I}+LyfpI*e= z1B@1t%V)HR4PzKBVs=*{y@0y!F0lFtSo0~PMXXrJXc5E4Fj~aI9*h=oGukJ$6A_n| zFj_?2I!22aox*4l3pI=uadSsTi^$zB=kph_;s~Qf^m&ufB1*FuEuwA&qeU$0&u9_X zbBq?TW-rDA93tjsFj_>}AV!N=RC|_>FJkN_MvKTzX0(W_x-(it`PXOo^dc6$!Dta9 zVi+xAjRT`ajQ#F3pI*fJt&A2?m&RxjxuJ{}G566aKD~%s5u+QCtI^m&AM|y~9zahZ zS+eK@mh_C6K6%*-sN2P!v1bE&gU$ugZ4G@VlGZxVXCiHZOTnjE%_<<-LFucJ^elHh zXfi8q0Lp-yfn*om3WT+d+Xlj7p}IagXnViKiEO=MHa83`<4MskiW1GBLtM4<4bOd&i+&dtbigG=XTU{V*4 zuo>yvY<*l3c3Y*G;!*!n%Q+&KD~3SpW8t4c;l%6aQWi@{`cKA-`PvtxnAU z!^5ly&-_1T>!!lSwVDY_{tq+#hsn%Nw<_;%(n$y6S-*=A35_n_9ed+rJ5jw;8h<{y z2zZ)-!dLwMs^Ec1YgE{@GKkCMnuEQEp8bPJ3*r_ zw&d~oEpNe#;`3VtUXv_Qe7w!zZJq}CutAAF4*eT#i!YO>owBkSn{RW}_E#o=*flXX+E2Mg;QZ>}|oD%$HNxoEOF79c;m4@ruB!!igKg7wnWxb>8rWgkM)B zoL}m?+)?moJQH{x#H#?WSv&9~9(_CDJ_aZuo`QH>k%ZfWN)8d~wx?9W`N4QFB%bYS z!pCX$LtjrK^0a_NpXe6AU4x@T46kS&-aUZ33ioH>W`hH`j&RMxOPi%9eg}^Lg2w#u zxjtSFvAl54zYd?_)iNC432l+SuvK_-`G-vm;3mS+A(q!XocK8t0tgzzTj#$$=C8wD zr~GyJg~=_$o0q?3MgaE#937&3t@Se|wPkqo^px&OtMI+8^pl^~GJWg%8Fhaho|5&~ z;ZL$#hPRgQ=z_lvzrOIV!-xJ&_~KUKt?Rexoxjfi&YLa6kG9g^gdHuzTc4jrw+?^(aLe?q<&P|F8Qwbmu~RL>Tc_WCp=EgU z^S{snYxdyi5Zia_@xjNkWq9lSZERbHH_t!C4{P$^>@YrxM+p3W<0SkzD)JT`Ksc_i z&pZC}U7P=&@7nB=L?&xfQ$w@02?o73G zvE_ZLmTer)X($%$85^9DsBPRg_MF*xZI%JM>+w6G!}8D1h!?Wt+|027H%XkC#_zk=6f~Dg8=aA8Nagnn9D@z~kk=(4_r`c=usbBQ(RVO* z@6Slp;;X^PQ6T8UG^~o5+$ZJ}(%Hv&5<{~Su+bTI`GdOnIra-A#h(T{kR-u|%uIZo zK&6*Q*(qX%KVfauGw+Ir2XyXkt zXKFJ=NiOnv=;QF=1s!WDFA|4onkfr<9u+!%OsLp=xXWha^{Erm=VE_B&XaW2tgU!T zLa83DHcQ6}6w`2R+#Ky6_?;vn{D(YR2gEn4L94L9^u$PAN;1>qR=9#Q-b@Voi;5uOr{4f1oiPpGzZngSCOadL3acEU6~BM$w752wz=C7O+o zOUXjV650vJU1nNK6gmvo#bOe6hv!=+7bj`Hk@CFO+T?SrY}EttK8Yz#k&bO!AI|%E zVX=<6#ZH)z=5y2VroAmekE0U!GmozaaM_Y!I4yi{<`(k)VJX-piNg7kU*&mYaPvc~ zN!+Vw6VOmfBHxSgr3mhGk}WVeg5%zzoX3WaCjU`h;s|OY+|Qw?#56)sU4;)eSNvC22Epj!h|+Fe;2S=ye7? z)$tiSEBwHL4xpu-liBFSbTyVzkv9@wsKB12{YV<3BQjE`(SyZ}&!3Mn~freRD(DN>)|Ka_ARs)}OI~+3R zR=}5-p5iOzjn9-D>r4Db0v?(9>tqsp?jeyqm;JX)6Qq0oEbgz9QaarB|D!{UNA^Cl zA^h3Vy1u!bwKYAv7Y{K!Ovm2)BYtz)oBPEygbl@k&B^~VEoLS=(Ufm#CdPU_+^i;^ z7*9kWlH&+__fh2idr~X!k!Y>A$zUKWzq5R_>oR z1KGbblmwJ5VamvH!(cUw} zGtzUKr`B_?XOZW5&nuoao=-g6dUf_1?6t*fhu0TgUwM^#UH7W>`oXK->!H^ZFH?oJ zqJzR-(M!=^;i~Xb_$xvc;}nw>GZb1yh9XC?O!21TBgLnRuNAe59~AY9hl(c(6K^YT zsdrcJp5FbuUA#TKRo=ngqr4}2Pw|fPp6zY$Uh2KV`z`NIK7Ky$`JDCn&d2C;*QdR2 zCtsQGWZyjHE@h3wi-E!O(xfQs*>9)n~sM{&Gt8Py2 z-tH6J6Wlv^hIx+ljPi{3oa!0t`Gx0ip4ghu%hJon>wWJ+Z@G`kx5W36?=#;H%AU#q z<%i0ls>`Yys$cyi{)7GH{_+0#{;U1p@c-2Rs{fDv)@nO-PqmABxH?*$sLoYyR_|7S zuKrSeQEjHN*9_EnX+ktpHA^(>HAR|hni|bbl3R{vZ~#u;PTob{T`rTW^( z@;UNc`EvPc`8xSt`62m9`8oL|`7d&Fw1UBIO1Ch#D7RR*bhm|Wue)t`JLC4PTZ5aq zdnfna?k?^@?i1Z-xT`#3JQjI;=27RF;q{8oYd&xKc=;|@ZdU%HTHu%Gx5RIm-wNn_ zt>2q|C_eztJprrS-f%nURs=1Tx}AoWCMePs-z$3h1}KwND)l(^Y;}%$iF&#g_R>wUocthbHNNS}0{188wS`1JD~AT-INI6QGt;|y{Q`RbDRJT?C^1JL;Qlw8vk1VJN^y+9o3`Mv8Yv+dZBu; z`c?H>^?T}K^;PvZ>ISuyroCo?<}D2ui?sx(Q(yTI`BRTOklEDB(<{kquGb>3PrWXC zReAm7)k`rRJ!psG6GgS+JH;;w3-7k*Gcxp;LEcJljdzH5ly{8xbnkrcP2Rh__j@1n zuJr!NyR%OqYO%=YEuZZ^hkQzWN_}qnSosd~o#i{v_a)!OzMFhMLOl+l4PN)X>)YV_ zyRV6|htfsqt@Kj{DrYFul{w0V%6#Qk~?@IYvc?sHXo!riCpqmP(YRxs9@bMJ-zd4YTZEgB zXHSf2eHAf^Sw4Gwy7;>Js(g2&ugaB?%6F9SD|aeCQ=U;)DQ_u%R{pMRr%F)0ttwG{ z>VMhaLET^NgSLE3eO7%zU7@a0f2+Qwu2-9CY%~KjQJRJ5qugdZqefX8d8+(%`E_}g z`(Teb9y@7<8V#b z4e^`qH`8ya-&=k={SNt+`+e*803)Nl{~&)q|1tit(E02B@B8obFZ1uCsiSiVVfBD~ zdAWR>o2|RAdy4xxcT1069vYmUQ@iG*r0e{k>s6$8dP}Kdpr6B`Hc0=R~_-+qCTa52puUjqcD;k*Hme^ zB6dCo%ZJNT$y(pQaq6);2rq~@@jdlT(?-!2%m0Bneu?LOlglR)>M_1-(J6d{xADm zsQqvS>Z6ILw6G{7TV*e0kn&aK1?7vXH*kK-Ro|!-7GtG09Qwsh){Z=$JZ3vyRI7 zf7&^p7uCu*j5{!q!9*_PA~k_rhH^2`Ip=-PIq%P-3keqk8A%*yE*RH^goKgMS`2^mFY6URuwY(KLQBu9@RKjZ`I5oN2Z zAcA+3q14*yy0P!jKzDwB+yFmikQTe>%Ys=nOJ*6bRRv3pt%)_Y&a9a=w-#22gh_i2#wJ=O;Cd} zngUy7K^A#hq-7ecK68V%(0pCmqkRzDh>qzL%r>KQy1-P1?T8(-<95O}Y-XqIjGeW8 zJCBJe+kst0Pd4n9ePDMnKYe>(k3e@*`^=u<`&if^C+tMPc5%$I;V>uVWSp$yJ5^Of zioj2K=m{+Xq;1{Ww;EQ{YFTY~sAC;kJ?jYhdu$D?p*4aor`9=ixqvd4R-P7ch7wLu z!8!JDk{a~irw!V~dD=Kp2WL8@13u&A}4&Y zEApa%{wRsEsGz0yL{-#89X@S{Ci1WiPU(m)61<0Q>x*MC5JNFSCXB^IOp)nlX!V)6 z5Oc8ilq*d04$tvjkWGnKFk3bBNRzjDhad7Iehk%5p!g}&zJSt8 zzAiRIRBVbZumS}uq@jBbnirsV1zOjja}yeOpzjg19YWU$G(Cr&m(X(^T1KJc7Br;L zFAeQ-(5(Q?D$uJ2t(wrOBM;?~JeEUwA}8`xp34h)DVHFQ4HZ?JV2*7?l~QT7qjG9j z6;w%8)E@k}ubQf@I%u{dB*PHQKT)UZTwS2!mTFyZ=&0V*TY6hlv|U>7=$ziw1zpk= z>;yHvubaB9JNi%`>0>=aj!g9Fis>%(5+t$#7T@%?K;sn2o%VLToVN=qFL@O&RQ>1s z3|N)bS%bCM0qY{Q`fLCK8?z}p!wxfN3l`#G9^o-;G6^&|<0+ouS?=>Z(zVP3C5%`%l|awg|; zAww#xBG|6tDglaO*s?Mzt9+GLMO9XTsv;K}s)fC)t9q)h25JP(n1YgLYOWTb#juWm zIN~~iZHMU;*g30xut!msb)c)dt{b|g4|G@ebRT&>(qlaZUC;C!bRF`-Uc`%eaWCN+ z$oQ0(@v_*C@?Oy^djWQ&y4S!qao}~mp4ayV-pCt+#?HJMSZv{il3`3>EEz{17)h2) zB{SGHeC&TkFl>;lChN%tIBjipudkcrHFAr*N&daJnyb$eS+UgG>i>WfbBeBAm{BWc zG4ySK#JrP}Q}jg)9g#yn1n7i5dSF3fNPQm(*+RNck?1j`xR2y+A+4uK=$J#1%RacL z>9m|X*Ak`?%M6_qm~~Kb7n|3KIR+cg@vd=q%S~Y8HeBj5SGg%{5n1dJJ~%UvEGi<6 M@bv#5|6v9G1`gwa{r~^~ literal 0 HcmV?d00001 diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-pkg-7.10.shim b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-pkg-7.10.shim new file mode 100644 index 00000000000..5c1d58caf88 --- /dev/null +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-pkg-7.10.shim @@ -0,0 +1,2 @@ +path = "FINDSH\sh.exe" +args = "bin\ghc-pkg-7.10" diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/setup.test.hs index 150f2bc8739..bf9b16fa195 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/setup.test.hs @@ -1,10 +1,22 @@ import Test.Cabal.Prelude +import System.Directory -main = setupAndCabalTest $ expectBrokenIfWindows 10179 $ do - withSymlink "bin/ghc-7.10" "ghc" $ do +main = setupAndCabalTest $ do + when isWindows $ do + sh <- fmap takeDirectory <$> liftIO (findExecutable "sh") + case sh of + Nothing -> skip "no sh" + Just sh' -> do + let sh'' = concatMap (\c -> case c of + '\\' -> "\\\\\\\\" + x -> [x]) sh' + void $ shell "sed" [ "-i", "-e", "s/FINDSH/" <> sh'' <> "/g", "bin/ghc-7.10.shim", "bin/ghc-pkg-7.10.shim"] + (if isWindows + then withSymlink "bin/ghc-7.10.exe" "ghc.exe" . withSymlink "bin/ghc-7.10.shim" "ghc.shim" . withSymlink "bin/ghc-7.10" "ghc" + else withSymlink "bin/ghc-7.10" "ghc") $ do env <- getTestEnv let cwd = testCurrentDir env ghc_path <- programPathM ghcProgram r <- withEnv [("WITH_GHC", Just ghc_path)] - . fails $ setup' "configure" ["-w", cwd "ghc"] + . fails $ setup' "configure" ["-w", cwd if isWindows then "ghc.exe" else "ghc"] assertOutputContains "is version 9999999" r diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-7.10.exe b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-7.10.exe new file mode 100644 index 0000000000000000000000000000000000000000..537023174dc7a094f693b3d9ef17fa234e6a4bf8 GIT binary patch literal 115712 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 M@bv#5|6v9G1`gwa{r~^~ literal 0 HcmV?d00001 diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-7.10.shim b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-7.10.shim new file mode 100644 index 00000000000..97596f1c171 --- /dev/null +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-7.10.shim @@ -0,0 +1,2 @@ +path = "FINDSH\sh.exe" +args = "ghc" diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-pkg-ghc-7.10.exe b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-pkg-ghc-7.10.exe new file mode 100644 index 0000000000000000000000000000000000000000..537023174dc7a094f693b3d9ef17fa234e6a4bf8 GIT binary patch literal 115712 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 M@bv#5|6v9G1`gwa{r~^~ literal 0 HcmV?d00001 diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-pkg-ghc-7.10.shim b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-pkg-ghc-7.10.shim new file mode 100644 index 00000000000..7e9ba24d98b --- /dev/null +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-pkg-ghc-7.10.shim @@ -0,0 +1,2 @@ +path = "FINDSH\sh.exe" +args = "bin\ghc-pkg-ghc-7.10" diff --git a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/setup.test.hs b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/setup.test.hs index 150f2bc8739..2f406ce6226 100644 --- a/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/setup.test.hs +++ b/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/setup.test.hs @@ -1,10 +1,22 @@ import Test.Cabal.Prelude +import System.Directory -main = setupAndCabalTest $ expectBrokenIfWindows 10179 $ do - withSymlink "bin/ghc-7.10" "ghc" $ do +main = setupAndCabalTest $ do + when isWindows $ do + sh <- fmap takeDirectory <$> liftIO (findExecutable "sh") + case sh of + Nothing -> skip "no sh" + Just sh' -> do + let sh'' = concatMap (\c -> case c of + '\\' -> "\\\\\\\\" + x -> [x]) sh' + void $ shell "sed" [ "-i", "-e", "s/FINDSH/" <> sh'' <> "/g", "bin/ghc-7.10.shim", "bin/ghc-pkg-ghc-7.10.shim"] + (if isWindows + then withSymlink "bin/ghc-7.10.exe" "ghc.exe" . withSymlink "bin/ghc-7.10.shim" "ghc.shim" . withSymlink "bin/ghc-7.10" "ghc" + else withSymlink "bin/ghc-7.10" "ghc") $ do env <- getTestEnv let cwd = testCurrentDir env ghc_path <- programPathM ghcProgram r <- withEnv [("WITH_GHC", Just ghc_path)] - . fails $ setup' "configure" ["-w", cwd "ghc"] + . fails $ setup' "configure" ["-w", cwd if isWindows then "ghc.exe" else "ghc"] assertOutputContains "is version 9999999" r From f8cef653994f0c1d358b5b3e4a993947f6612ecc Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Wed, 31 Jul 2024 22:16:56 +0200 Subject: [PATCH 116/207] Enable autoreconf tests on Windows --- .../PackageTests/Configure/cabal.test.hs | 25 +++++++++++++++--- .../PackageTests/Configure/setup.test.hs | 26 +++++++++++++++---- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/cabal-testsuite/PackageTests/Configure/cabal.test.hs b/cabal-testsuite/PackageTests/Configure/cabal.test.hs index afcc00cbf7a..cd419e8cee2 100644 --- a/cabal-testsuite/PackageTests/Configure/cabal.test.hs +++ b/cabal-testsuite/PackageTests/Configure/cabal.test.hs @@ -2,9 +2,26 @@ import Test.Cabal.Prelude import Control.Monad.IO.Class import Data.Maybe import System.Directory +import System.Environment +import Data.List (isSuffixOf) + -- Test for 'build-type: Configure' example from the setup manual. main = cabalTest $ do - hasAutoreconf <- liftIO $ fmap isJust $ findExecutable "autoreconf" - skipUnless "no autoreconf" hasAutoreconf - _ <- shell "autoreconf" ["-i"] - cabal "v2-build" [] + if isWindows + then do + (mCI, mSh) <- liftIO $ (,) <$> lookupEnv "CI" <*> lookupEnv "SHELL" + case (mCI, mSh) of + (Nothing, Nothing) -> skip "Missing $SHELL" + (Nothing, Just sh) -> do + env <- getTestEnv + void $ shell sh [ "-l", "-c", "cd $(cygpath -m '" <> testTmpDir env <> "') && autoreconf -i"] + cabal "v2-build" [] + (Just{}, _) -> do + env <- getTestEnv + void $ shell "C:\\msys64\\usr\\bin\\bash.exe" [ "-l", "-c", "cd $(cygpath -m '" <> testTmpDir env <> "') && autoreconf -i"] + cabal "v2-build" [] + else do + hasAutoreconf <- liftIO $ fmap isJust $ findExecutable "autoreconf" + skipUnless "no autoreconf" hasAutoreconf + _ <- shell "autoreconf" ["-i"] + cabal "v2-build" [] diff --git a/cabal-testsuite/PackageTests/Configure/setup.test.hs b/cabal-testsuite/PackageTests/Configure/setup.test.hs index 559b88c6ff2..5eaea387fe6 100644 --- a/cabal-testsuite/PackageTests/Configure/setup.test.hs +++ b/cabal-testsuite/PackageTests/Configure/setup.test.hs @@ -2,9 +2,25 @@ import Test.Cabal.Prelude import Control.Monad.IO.Class import Data.Maybe import System.Directory +import System.Environment + -- Test for 'build-type: Configure' example from the setup manual. -main = setupTest $ do - hasAutoreconf <- liftIO $ fmap isJust $ findExecutable "autoreconf" - skipUnless "no autoreconf" hasAutoreconf - _ <- shell "autoreconf" ["-i"] - setup_build [] +main = setupTest $ + if isWindows + then do + (mCI, mSh) <- liftIO $ (,) <$> lookupEnv "CI" <*> lookupEnv "SHELL" + case (mCI, mSh) of + (Nothing, Nothing) -> skip "Missing $SHELL" + (Nothing, Just sh) -> do + env <- getTestEnv + void $ shell sh [ "-l", "-c", "cd $(cygpath -m '" <> testTmpDir env <> "') && autoreconf -i"] + setup_build [] + (Just{}, _) -> do + env <- getTestEnv + void $ shell "C:\\msys64\\usr\\bin\\bash.exe" [ "-l", "-c", "cd $(cygpath -m '" <> testTmpDir env <> "') && autoreconf -i"] + setup_build [] + else do + hasAutoreconf <- liftIO $ fmap isJust $ findExecutable "autoreconf" + skipUnless "no autoreconf" hasAutoreconf + _ <- shell "autoreconf" ["-i"] + setup_build [] From 6e58a778374fb5dd230571e24688f128998e5408 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Wed, 31 Jul 2024 23:09:43 +0200 Subject: [PATCH 117/207] Fix GHCJS BuildRunner test on Windows --- .../GHCJS/BuildRunner/cabal.test.hs | 6 ++- .../GHCJS/BuildRunner/scripts/cc.bat | 45 ++++++++++++++++++ .../GHCJS/BuildRunner/scripts/fake-ghcjs.exe | Bin 0 -> 115712 bytes .../GHCJS/BuildRunner/scripts/fake-ghcjs.shim | 2 + .../GHCJS/BuildRunner/scripts/ghcjs-pkg.exe | Bin 0 -> 115712 bytes .../GHCJS/BuildRunner/scripts/ghcjs-pkg.shim | 2 + 6 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/cc.bat create mode 100644 cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/fake-ghcjs.exe create mode 100644 cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/fake-ghcjs.shim create mode 100644 cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/ghcjs-pkg.exe create mode 100644 cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/ghcjs-pkg.shim diff --git a/cabal-testsuite/PackageTests/GHCJS/BuildRunner/cabal.test.hs b/cabal-testsuite/PackageTests/GHCJS/BuildRunner/cabal.test.hs index 245901c8bef..da8afae103e 100644 --- a/cabal-testsuite/PackageTests/GHCJS/BuildRunner/cabal.test.hs +++ b/cabal-testsuite/PackageTests/GHCJS/BuildRunner/cabal.test.hs @@ -1,7 +1,7 @@ import Test.Cabal.Prelude main = do - cabalTest . expectBrokenIfWindows 10179 . recordMode DoNotRecord $ do + cabalTest . recordMode DoNotRecord $ do cwd <- fmap testCurrentDir getTestEnv testInvokedWithBuildRunner cwd "test" [] testInvokedWithBuildRunner cwd "run" ["ghcjs-exe"] @@ -14,6 +14,8 @@ testInvokedWithBuildRunner cwd cabalCmd extraArgs = do [ "--ghcjs" , "--with-compiler", cwd fakeGhcjsPath ] + -- On windows point cabal to the right cc + ++ if isWindows then ["--with-gcc", "scripts/cc.bat"] else [] assertOutputContains magicString output where - fakeGhcjsPath = "scripts/fake-ghcjs.sh" + fakeGhcjsPath = if isWindows then "scripts/fake-ghcjs.exe" else "scripts/fake-ghcjs.sh" diff --git a/cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/cc.bat b/cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/cc.bat new file mode 100644 index 00000000000..b2300d2fd6b --- /dev/null +++ b/cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/cc.bat @@ -0,0 +1,45 @@ +@ECHO off + +FOR /f "delims=" %%A in ('call ghc.exe --print-libdir') do set "libdir=%%A" +FOR /f "delims=" %%A in ('call ghc.exe --numeric-version') do set "numVersion=%%A" +setlocal EnableDelayedExpansion + +call :compareVersions 9.4.1 %numVersion% +if %errorlevel% == 1 (set "cc=gcc.exe") else (set "cc=clang.exe") +CALL !libdir:lib=mingw\bin\!%cc% %* +EXIT /B %ERRORLEVEL% + +REM taken from https://stackoverflow.com/questions/15807762/compare-version-numbers-in-batch-file + +:compareVersions version1 version2 +:: +:: Compares two version numbers and returns the result in the ERRORLEVEL +:: +:: Returns 1 if version1 > version2 +:: 0 if version1 = version2 +:: -1 if version1 < version2 +:: +:: The nodes must be delimited by . or , or - +:: +:: Nodes are normally strictly numeric, without a 0 prefix. A letter suffix +:: is treated as a separate node +:: +setlocal enableDelayedExpansion +set "v1=%~1" +set "v2=%~2" +:loop +call :parseNode "%v1%" n1 v1 +call :parseNode "%v2%" n2 v2 +if %n1% gtr %n2% exit /b 1 +if %n1% lss %n2% exit /b -1 +if not defined v1 if not defined v2 exit /b 0 +if not defined v1 exit /b -1 +if not defined v2 exit /b 1 +goto :loop + + +:parseNode version nodeVar remainderVar +for /f "tokens=1* delims=." %%A in ("%~1") do ( + set "%~2=%%A" + set "%~3=%%B" +) diff --git a/cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/fake-ghcjs.exe b/cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/fake-ghcjs.exe new file mode 100644 index 0000000000000000000000000000000000000000..537023174dc7a094f693b3d9ef17fa234e6a4bf8 GIT binary patch literal 115712 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 M@bv#5|6v9G1`gwa{r~^~ literal 0 HcmV?d00001 diff --git a/cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/fake-ghcjs.shim b/cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/fake-ghcjs.shim new file mode 100644 index 00000000000..725429e82d7 --- /dev/null +++ b/cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/fake-ghcjs.shim @@ -0,0 +1,2 @@ +path = "sh.exe" +args = "scripts/fake-ghcjs.sh" diff --git a/cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/ghcjs-pkg.exe b/cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/ghcjs-pkg.exe new file mode 100644 index 0000000000000000000000000000000000000000..537023174dc7a094f693b3d9ef17fa234e6a4bf8 GIT binary patch literal 115712 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 M@bv#5|6v9G1`gwa{r~^~ literal 0 HcmV?d00001 diff --git a/cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/ghcjs-pkg.shim b/cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/ghcjs-pkg.shim new file mode 100644 index 00000000000..d330fc23e3e --- /dev/null +++ b/cabal-testsuite/PackageTests/GHCJS/BuildRunner/scripts/ghcjs-pkg.shim @@ -0,0 +1,2 @@ +path = "sh.exe" +args = "scripts/ghcjs-pkg" From 38652560ebdb31d382b4ac79e71f8b8b8ef3f51a Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Tue, 27 Aug 2024 23:34:35 +0200 Subject: [PATCH 118/207] Install autotools on Windows too --- .github/workflows/validate.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 432277a9d5c..2d8be7f02a3 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -133,7 +133,7 @@ jobs: key: ${{ runner.os }}-${{ matrix.ghc }}-${{ github.sha }} restore-keys: ${{ runner.os }}-${{ matrix.ghc }}- - - name: Work around git problem https://bugs.launchpad.net/ubuntu/+source/git/+bug/1993586 (cabal PR #8546) + - name: "Work around git problem https://bugs.launchpad.net/ubuntu/+source/git/+bug/1993586 (cabal PR #8546)" run: git config --global protocol.file.allow always # The tool is not essential to the rest of the test suite. If @@ -146,10 +146,15 @@ jobs: run: cabal install --ignore-project hackage-repo-tool # Needed by cabal-testsuite/PackageTests/Configure/setup.test.hs - - name: Install Autotools + - name: "MAC: Install Autotools" if: runner.os == 'macOS' run: brew install automake + # Needed by cabal-testsuite/PackageTests/Configure/setup.test.hs + - name: "WIN: Install Autotools" + if: runner.os == 'Windows' + run: /usr/bin/pacman --noconfirm -S autotools + - name: Set validate inputs run: | FLAGS="${{ env.COMMON_FLAGS }}" From 2e17ab121cfdad87c75cd37382e73f9ddb287bc6 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Wed, 28 Aug 2024 00:27:31 +0200 Subject: [PATCH 119/207] Reenable PkgConfigParse on Windows --- .../PackageTests/PkgConfigParse/pkg-config.exe | Bin 0 -> 115712 bytes .../PkgConfigParse/pkg-config.shim | 2 ++ .../PackageTests/PkgConfigParse/setup.test.hs | 12 +++++++++++- 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 cabal-testsuite/PackageTests/PkgConfigParse/pkg-config.exe create mode 100644 cabal-testsuite/PackageTests/PkgConfigParse/pkg-config.shim diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config.exe b/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config.exe new file mode 100644 index 0000000000000000000000000000000000000000..537023174dc7a094f693b3d9ef17fa234e6a4bf8 GIT binary patch literal 115712 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 M@bv#5|6v9G1`gwa{r~^~ literal 0 HcmV?d00001 diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config.shim b/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config.shim new file mode 100644 index 00000000000..2c187de462e --- /dev/null +++ b/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config.shim @@ -0,0 +1,2 @@ +path = "FINDSH\sh.exe" +args = "pkg-config" \ No newline at end of file diff --git a/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs b/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs index 2528e7459e5..edebd2d131c 100644 --- a/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs +++ b/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs @@ -1,7 +1,17 @@ +import System.Directory import Test.Cabal.Prelude -- Test that invalid unicode in pkg-config output doesn't trip up cabal very much -main = cabalTest $ expectBrokenIfWindows 10179 $ do +main = cabalTest $ do + when isWindows $ do + sh <- fmap takeDirectory <$> liftIO (findExecutable "sh") + case sh of + Nothing -> skip "no sh" + Just sh' -> do + let sh'' = concatMap (\c -> case c of + '\\' -> "\\\\\\\\" + x -> [x]) sh' + void $ shell "sed" [ "-i", "-e", "s/FINDSH/" <> sh'' <> "/g", "pkg-config.shim"] cdir <- testCurrentDir `fmap` getTestEnv res <- cabal' "v2-build" ["--extra-prog-path="++cdir, "-v2"] assertOutputContains "Some pkg-config packages have names containing invalid unicode: or" res From d2a6ddbacbef966d88dd2a48a85c46cb4d47cbac Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Sun, 1 Sep 2024 23:11:57 +0200 Subject: [PATCH 120/207] Do not advertise `git://` in docs --- doc/version-control-fields.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/version-control-fields.rst b/doc/version-control-fields.rst index 71dd59c4953..739905d4b8a 100644 --- a/doc/version-control-fields.rst +++ b/doc/version-control-fields.rst @@ -64,7 +64,7 @@ The location of the repository, usually a URL but the exact form of this field depends on the repository type. For example: - for Darcs: ``http://code.haskell.org/foo/`` -- for Git: ``git://github.com/foo/bar.git`` +- for Git: ``https://github.com/foo/bar.git`` - for CVS: ``anoncvs@cvs.foo.org:/cvs`` VCS branch From 43c6cd2c052faee624c6067f2891a86cd7570f58 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Thu, 29 Aug 2024 16:23:58 -0700 Subject: [PATCH 121/207] Support ARM / M1 macOS in `validate.sh` --- validate.sh | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/validate.sh b/validate.sh index 8784f48b4a5..fc8586a3778 100755 --- a/validate.sh +++ b/validate.sh @@ -299,15 +299,35 @@ JOBS="-j$JOBS" # assume compiler is GHC RUNHASKELL=$(echo "$HC" | sed -E 's/ghc(-[0-9.]*)$/runghc\1/') -case "$(uname)" in +ARCH=$(uname -m) + +case "$ARCH" in + arm64) + ARCH=aarch64 + ;; + x86_64) + ARCH=x86_64 + ;; + *) + echo "Warning: Unknown architecture '$ARCH'" + ;; +esac + +OS=$(uname) + +case "$OS" in MINGW64*) - ARCH="x86_64-windows" + ARCH="$ARCH-windows" + ;; + Linux) + ARCH="$ARCH-linux" ;; - Linux ) - ARCH="x86_64-linux" + Darwin) + ARCH="$ARCH-osx" ;; *) - ARCH="x86_64-osx" + echo "Warning: Unknown operating system '$OS'" + ARCH="$ARCH-$OS" ;; esac From b3fecbb6c70bdd7fd631150394f7b75403aaf01d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 01:17:57 +0000 Subject: [PATCH 122/207] Bump actions/cache from 3 to 4 (#9646) Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: brandon s allbery kf8nh Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .github/workflows/bootstrap.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bootstrap.yml b/.github/workflows/bootstrap.yml index e74d355360f..5a4ed59dfc5 100644 --- a/.github/workflows/bootstrap.yml +++ b/.github/workflows/bootstrap.yml @@ -43,7 +43,7 @@ jobs: rm -rf ~/.config/cabal rm -rf ~/.cache/cabal - - uses: actions/cache@v3 + - uses: actions/cache@v4 name: Cache the downloads id: bootstrap-cache with: From 0621118ca2dd8d1267901775195c579be7cc1ec9 Mon Sep 17 00:00:00 2001 From: Rodrigo Mesquita Date: Tue, 3 Sep 2024 16:31:59 +0100 Subject: [PATCH 123/207] Custom-build: Document breaking change on built comps. As mentioned by e8c9d19, Cabal 3.12 introduced a breaking change where an unnecessary (not requested) component of a package with a "Custom" build-type is no longer built. This caused breakage for Agda, and was undocumented. The behaviour, despite breaking, is the desired one -- a package shouldn't assume the executable will be built if only the library was requested. This commit documents the breaking change to make sure it is more visible. In the meantime, we've also patched Agda to no longer expect the executable to be built when only the library is installed. Closes #9777 and #10235 --- release-notes/Cabal-3.12.0.0.md | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/release-notes/Cabal-3.12.0.0.md b/release-notes/Cabal-3.12.0.0.md index 4c4ff805ce9..23c416aab75 100644 --- a/release-notes/Cabal-3.12.0.0.md +++ b/release-notes/Cabal-3.12.0.0.md @@ -83,6 +83,42 @@ Cabal and Cabal-syntax 3.12.0.0 changelog and release notes ### Other changes +- Installing a library with a Custom setup no longer requires building the executable [#9777](https://github.com/haskell/cabal/issues/9777) [#9650](https://github.com/haskell/cabal/pull/9650) [#10311](https://github.com/haskell/cabal/pull/10311) + + For example, if we have `pkg-a.cabal`: + + ``` + library + build-depends: pkg-b + ``` + + and `pkg-b.cabal`: + + ``` + library + exposed-modules: ... + + executable pkg-b-exe + main-is: ... + ``` + + + An invocation `cabal build pkg-a` will build `lib:pkg-a` and `lib:pkg-b`, but + not `exe:pkg-b-exe` because it is not needed for building `pkg-a`! Previously the executable would be built unnecessarily. + + If the invocation were `cabal build pkg-a exe:pkg-b-exe` then all `lib:pkg-a`, `lib:pkg-b`, and `exe:pkg-b-exe` would be built. + + Note: There may be a package whose Custom setup expects the executable to be + built together with the library always. Unfortunately, this is a breaking + change for them. To migrate, packages should no longer assume the executable is + built when only the library is requested (e.g. `cabal install --lib Agda` will + *not* build the `Agda` executable, while `cabal install Agda` will). + + Agda is an example of a package which expected in its `Setup.hs` copy hook the + executable to already be built. This was fixed by inspecting the copy arguments + and making sure we only use the executable when it is built, since it is only + needed when the executable too is needed. + - `cabal init` should not suggest Cabal < 2.0 [#8680](https://github.com/haskell/cabal/issues/8680) [#8700](https://github.com/haskell/cabal/pull/8700) 'cabal init' no longer suggests users to set cabal-version to less than From 9394c350abd6ffae951a61f2f85e2c107b1cef8f Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Wed, 4 Sep 2024 18:30:14 -0700 Subject: [PATCH 124/207] validate.sh: `--jobs` should default to `nproc` If `nproc` is available and `--jobs` is not given, this will use the output of `nproc` as the value for `--jobs`. Otherwise, the old default value of 4 will be used and a warning will be printed. The default value of 4 has remained unchanged since it was added in 6a9a101ca5e1731b9f099a94579a84d2e19667f8 in 2018; that may have been a reasonable number of cores then, but my development machine today has 20 cores, so setting the parallelism to 4 leaves a lot of performance on the table! --- validate.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/validate.sh b/validate.sh index fc8586a3778..f0203dc2ede 100755 --- a/validate.sh +++ b/validate.sh @@ -12,7 +12,7 @@ # See https://github.com/haskell/cabal/issues/8049 HC=ghc CABAL=cabal -JOBS=4 +JOBS="" LIBTESTS=true CLITESTS=true CABALSUITETESTS=true @@ -293,6 +293,15 @@ fi # Adjust runtime configuration ####################################################################### +if [ -z "$JOBS" ]; then + if command -v nproc >/dev/null; then + JOBS=$(nproc) + else + echo "Warning: \`nproc\` not found, setting \`--jobs\` to default of 4." + JOBS=4 + fi +fi + TESTSUITEJOBS="-j$JOBS" JOBS="-j$JOBS" From ecca683ebe593a4733295c84ee5e4e54527ac292 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Thu, 5 Sep 2024 09:59:25 -0700 Subject: [PATCH 125/207] validate.sh: Use Bash explicitly We were already relying on Bash features like `echo -e`, so let's make it official. --- validate.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validate.sh b/validate.sh index f0203dc2ede..b22e033f86e 100755 --- a/validate.sh +++ b/validate.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash # shellcheck disable=SC2086 # default config From 7f2156aed5df7c8d7f53279c6b92d2bd405f121e Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Fri, 6 Sep 2024 12:22:57 -0700 Subject: [PATCH 126/207] Fix `cabal-install:long-tests` with Git >=2.38.1 Closes #10312. Git 2.38.1 and newer fails to clone from local paths with `fatal: transport 'file' not allowed` unless `protocol.file.allow=always` is set. This is not safe in general, but it's fine in the test suite. See: https://github.blog/open-source/git/git-security-vulnerabilities-announced/#fn-67904-1 See: https://git-scm.com/docs/git-config#Documentation/git-config.txt-protocolallow --- .github/workflows/validate.yml | 3 --- .../UnitTests/Distribution/Client/VCS.hs | 24 ++++++++++++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 2d8be7f02a3..d29ff811fd7 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -133,9 +133,6 @@ jobs: key: ${{ runner.os }}-${{ matrix.ghc }}-${{ github.sha }} restore-keys: ${{ runner.os }}-${{ matrix.ghc }}- - - name: "Work around git problem https://bugs.launchpad.net/ubuntu/+source/git/+bug/1993586 (cabal PR #8546)" - run: git config --global protocol.file.allow always - # The tool is not essential to the rest of the test suite. If # hackage-repo-tool is not present, any test that requires it will # be skipped. diff --git a/cabal-install/tests/UnitTests/Distribution/Client/VCS.hs b/cabal-install/tests/UnitTests/Distribution/Client/VCS.hs index 0bd49355913..a76dd39b082 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/VCS.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/VCS.hs @@ -847,7 +847,7 @@ vcsTestDriverGit -> VCSTestDriver vcsTestDriverGit verbosity vcs submoduleDir repoRoot = VCSTestDriver - { vcsVCS = vcs + { vcsVCS = vcs' , vcsRepoRoot = repoRoot , vcsIgnoreFiles = Set.empty , vcsInit = @@ -872,7 +872,7 @@ vcsTestDriverGit verbosity vcs submoduleDir repoRoot = , vcsTagState = \_ tagname -> git ["tag", "--force", "--no-sign", tagname] , vcsSubmoduleDriver = - pure . vcsTestDriverGit verbosity vcs submoduleDir . (submoduleDir ) + pure . vcsTestDriverGit verbosity vcs' submoduleDir . (submoduleDir ) , vcsAddSubmodule = \_ source dest -> do destExists <- (||) @@ -897,8 +897,26 @@ vcsTestDriverGit verbosity vcs submoduleDir repoRoot = updateSubmodulesAndCleanup } where + -- Git 2.38.1 and newer fails to clone from local paths with `fatal: transport 'file' + -- not allowed` unless `protocol.file.allow=always` is set. + -- + -- This is not safe in general, but it's fine in the test suite. + -- + -- See: https://github.blog/open-source/git/git-security-vulnerabilities-announced/#fn-67904-1 + -- See: https://git-scm.com/docs/git-config#Documentation/git-config.txt-protocolallow + vcs' = + vcs + { vcsProgram = + (vcsProgram vcs) + { programDefaultArgs = + programDefaultArgs (vcsProgram vcs) + ++ [ "-c" + , "protocol.file.allow=always" + ] + } + } gitInvocation args = - (programInvocation (vcsProgram vcs) args) + (programInvocation (vcsProgram vcs') args) { progInvokeCwd = Just repoRoot } git = runProgramInvocation verbosity . gitInvocation From e367cc31d803948623fdd27195cdbceba6c85aec Mon Sep 17 00:00:00 2001 From: ffaf1 Date: Mon, 9 Sep 2024 15:12:59 +0200 Subject: [PATCH 127/207] Bump version numbers to 3.15 (#10309) * Bump version numbers to 3.15 * Bump GHC 9.6.6 for workflows * Update index-state * Bump bootstrap boundaries * Regenerate bootstrap files --- .github/workflows/bootstrap.yml | 2 +- .github/workflows/validate.yml | 2 +- Cabal-QuickCheck/Cabal-QuickCheck.cabal | 6 +- Cabal-described/Cabal-described.cabal | 6 +- Cabal-hooks/Cabal-hooks.cabal | 4 +- Cabal-syntax/Cabal-syntax.cabal | 2 +- Cabal-tree-diff/Cabal-tree-diff.cabal | 6 +- Cabal/Cabal.cabal | 4 +- Cabal/Makefile | 2 +- Makefile | 2 +- bootstrap/cabal-bootstrap-gen.cabal | 8 +- bootstrap/linux-9.0.2.json | 60 +-- bootstrap/linux-9.2.8.json | 68 +-- bootstrap/linux-9.4.8.json | 68 +-- bootstrap/linux-9.6.6.json | 494 ++++++++++++++++++ bootstrap/linux-9.8.2.json | 53 +- .../cabal-install-solver.cabal | 6 +- cabal-install/cabal-install.cabal | 8 +- cabal-testsuite/cabal-testsuite.cabal | 2 +- cabal.bootstrap.project | 2 +- cabal.release.project | 2 +- solver-benchmarks/solver-benchmarks.cabal | 2 +- 22 files changed, 651 insertions(+), 158 deletions(-) create mode 100644 bootstrap/linux-9.6.6.json diff --git a/.github/workflows/bootstrap.yml b/.github/workflows/bootstrap.yml index 5a4ed59dfc5..956fc7ce570 100644 --- a/.github/workflows/bootstrap.yml +++ b/.github/workflows/bootstrap.yml @@ -30,7 +30,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - ghc: ["9.0.2", "9.2.8", "9.4.8", "9.6.4", "9.8.2"] + ghc: ["9.0.2", "9.2.8", "9.4.8", "9.6.6", "9.8.2"] include: - os: macos-latest ghc: "9.2.8" diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index d29ff811fd7..eb48485d001 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -71,7 +71,7 @@ jobs: [ "9.10.1", "9.8.2", - "9.6.4", + "9.6.6", "9.4.8", "9.2.8", "9.0.2", diff --git a/Cabal-QuickCheck/Cabal-QuickCheck.cabal b/Cabal-QuickCheck/Cabal-QuickCheck.cabal index 37c0f88fc4e..0fbccd53d91 100644 --- a/Cabal-QuickCheck/Cabal-QuickCheck.cabal +++ b/Cabal-QuickCheck/Cabal-QuickCheck.cabal @@ -1,6 +1,6 @@ cabal-version: 2.2 name: Cabal-QuickCheck -version: 3.13.0.0 +version: 3.15.0.0 synopsis: QuickCheck instances for types in Cabal category: Testing build-type: Simple @@ -14,8 +14,8 @@ library build-depends: , base , bytestring - , Cabal ^>=3.13.0.0 - , Cabal-syntax ^>=3.13.0.0 + , Cabal ^>=3.15.0.0 + , Cabal-syntax ^>=3.15.0.0 , QuickCheck ^>=2.13.2 || ^>=2.14 exposed-modules: diff --git a/Cabal-described/Cabal-described.cabal b/Cabal-described/Cabal-described.cabal index 86b516d94ef..e8fd71a49fa 100644 --- a/Cabal-described/Cabal-described.cabal +++ b/Cabal-described/Cabal-described.cabal @@ -1,6 +1,6 @@ cabal-version: 2.2 name: Cabal-described -version: 3.13.0.0 +version: 3.15.0.0 synopsis: Described functionality for types in Cabal category: Testing, Parsec description: Provides rere bindings @@ -12,8 +12,8 @@ library ghc-options: -Wall build-depends: , base - , Cabal ^>=3.13.0.0 - , Cabal-syntax ^>=3.13.0.0 + , Cabal ^>=3.15.0.0 + , Cabal-syntax ^>=3.15.0.0 , containers , pretty , QuickCheck diff --git a/Cabal-hooks/Cabal-hooks.cabal b/Cabal-hooks/Cabal-hooks.cabal index db309369330..57abca7726d 100644 --- a/Cabal-hooks/Cabal-hooks.cabal +++ b/Cabal-hooks/Cabal-hooks.cabal @@ -27,8 +27,8 @@ library hs-source-dirs: src build-depends: - Cabal-syntax >= 3.13 && < 3.15, - Cabal >= 3.13 && < 3.15, + Cabal-syntax >= 3.15 && < 3.17, + Cabal >= 3.15 && < 3.17, base >= 4.13 && < 5, containers >= 0.5.0.0 && < 0.8, transformers >= 0.5.6.0 && < 0.7 diff --git a/Cabal-syntax/Cabal-syntax.cabal b/Cabal-syntax/Cabal-syntax.cabal index 1bc8bcabeb2..7d1d117b0a7 100644 --- a/Cabal-syntax/Cabal-syntax.cabal +++ b/Cabal-syntax/Cabal-syntax.cabal @@ -1,6 +1,6 @@ cabal-version: 2.2 name: Cabal-syntax -version: 3.13.0.0 +version: 3.15.0.0 copyright: 2003-2024, Cabal Development Team (see AUTHORS file) license: BSD-3-Clause license-file: LICENSE diff --git a/Cabal-tree-diff/Cabal-tree-diff.cabal b/Cabal-tree-diff/Cabal-tree-diff.cabal index a6f65532b1c..d7703621f8d 100644 --- a/Cabal-tree-diff/Cabal-tree-diff.cabal +++ b/Cabal-tree-diff/Cabal-tree-diff.cabal @@ -1,6 +1,6 @@ cabal-version: 2.2 name: Cabal-tree-diff -version: 3.13.0.0 +version: 3.15.0.0 synopsis: QuickCheck instances for types in Cabal category: Testing description: Provides tree-diff ToExpr instances for some types in Cabal @@ -11,8 +11,8 @@ library ghc-options: -Wall build-depends: , base - , Cabal-syntax ^>=3.13.0.0 - , Cabal ^>=3.13.0.0 + , Cabal-syntax ^>=3.15.0.0 + , Cabal ^>=3.15.0.0 , tree-diff ^>=0.1 || ^>=0.2 || ^>=0.3 exposed-modules: Data.TreeDiff.Instances.Cabal diff --git a/Cabal/Cabal.cabal b/Cabal/Cabal.cabal index 14e7050c5db..777e078af1a 100644 --- a/Cabal/Cabal.cabal +++ b/Cabal/Cabal.cabal @@ -1,6 +1,6 @@ cabal-version: 3.0 name: Cabal -version: 3.13.0.0 +version: 3.15.0.0 copyright: 2003-2024, Cabal Development Team (see AUTHORS file) license: BSD-3-Clause license-file: LICENSE @@ -34,7 +34,7 @@ library hs-source-dirs: src build-depends: - Cabal-syntax ^>= 3.13, + Cabal-syntax ^>= 3.15, array >= 0.4.0.1 && < 0.6, base >= 4.13 && < 5, bytestring >= 0.10.0.0 && < 0.13, diff --git a/Cabal/Makefile b/Cabal/Makefile index a99f4edaeb5..e74ee82079d 100644 --- a/Cabal/Makefile +++ b/Cabal/Makefile @@ -1,4 +1,4 @@ -VERSION=3.13.0.0 +VERSION=3.15.0.0 #KIND=devel KIND=rc diff --git a/Makefile b/Makefile index 835c73b8ff9..0912773d368 100644 --- a/Makefile +++ b/Makefile @@ -226,7 +226,7 @@ bootstrap-json-%: phony cd bootstrap && cabal run -v0 cabal-bootstrap-gen -- linux-$*.plan.json \ | python3 -m json.tool > linux-$*.json -BOOTSTRAP_GHC_VERSIONS := 9.0.2 9.2.8 9.4.8 9.6.4 9.8.2 +BOOTSTRAP_GHC_VERSIONS := 9.0.2 9.2.8 9.4.8 9.6.6 9.8.2 .PHONY: bootstrap-jsons bootstrap-jsons: $(BOOTSTRAP_GHC_VERSIONS:%=bootstrap-json-%) diff --git a/bootstrap/cabal-bootstrap-gen.cabal b/bootstrap/cabal-bootstrap-gen.cabal index 0b73a1de23e..b2caa03c493 100644 --- a/bootstrap/cabal-bootstrap-gen.cabal +++ b/bootstrap/cabal-bootstrap-gen.cabal @@ -8,11 +8,11 @@ executable cabal-bootstrap-gen ghc-options: -Wall main-is: Main.hs build-depends: - , aeson ^>=1.5.2.0 || ^>=2.0.3.0 || ^>=2.1.0.0 - , base ^>=4.12.0.0 || ^>=4.13.0.0 || ^>=4.14.0.0 || ^>=4.15.0.0 || ^>=4.16.0.0 || ^>=4.17.0.0 || ^>=4.18.0.0 + , aeson ^>=1.5.2.0 || ^>=2.0.3.0 || ^>=2.1.0.0 || ^>=2.2.0.0 + , base ^>=4.12.0.0 || ^>=4.13.0.0 || ^>=4.14.0.0 || ^>=4.15.0.0 || ^>=4.16.0.0 || ^>=4.17.0.0 || ^>=4.18.0.0 || ^>=4.19.0.0 , bytestring ^>=0.10.8.2 || ^>=0.11.0.0 - , Cabal ^>=3.4.1.0 || ^>=3.6.3.0 || ^>=3.10.1.0 || ^>=3.12.1.0 - , Cabal-syntax ^>=3.8.1.0 || ^>=3.10.1.0 || ^>=3.12.1.0 + , Cabal ^>=3.12.1.0 || ^>=3.14.0.0 + , Cabal-syntax ^>=3.12.1.0 || ^>=3.14.0.0 -- For the release process, we need the last *two* Cabal-syntax -- versions here: one to make CI green when release Cabal-syntax is -- not yet on Hackage and we are bumping versions. The second for diff --git a/bootstrap/linux-9.0.2.json b/bootstrap/linux-9.0.2.json index d260767f667..77f026b442b 100644 --- a/bootstrap/linux-9.0.2.json +++ b/bootstrap/linux-9.0.2.json @@ -172,17 +172,17 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { - "cabal_sha256": "2a9393de33f18415fb8f4826957a87a94ffe8840ca8472a9b69dca6de45aca03", + "cabal_sha256": "684028fb5ac3d1c7657fe516f2a442d95a53ae2fcf6f6151544f3ed5289f6320", "component": "lib:process", "flags": [], "package": "process", - "revision": 1, + "revision": 0, "source": "hackage", - "src_sha256": "cefda221c3009fa2316b5cf148215cb340dad7eb8503f22e49e33722559df99a", - "version": "1.6.20.0" + "src_sha256": "a816655978c2527d8d7a6ebfd6f1ca79027f27ac4f2f28888f1581b2d558aea5", + "version": "1.6.23.0" }, { "cabal_sha256": null, @@ -192,7 +192,7 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { "cabal_sha256": null, @@ -217,7 +217,7 @@ "version": "0.68.10" }, { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", + "cabal_sha256": "17b834d2b75df8a8aef05de523280f613bb9c9aa9c31f269d5b90c1431a3749b", "component": "lib:network", "flags": [ "-devel" @@ -225,8 +225,8 @@ "package": "network", "revision": 0, "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" + "src_sha256": "efb04947946f52cccba802c2a8fc2f4259f0bdfd0bce95094c84e71583647f0c", + "version": "3.2.2.0" }, { "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", @@ -274,7 +274,7 @@ "version": "0.9.2" }, { - "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", + "cabal_sha256": "573f3ab242f75465a0d67ce9d84202650a1606575e6dbd6d31ffcf4767a9a379", "component": "lib:hashable", "flags": [ "-arch-native", @@ -284,17 +284,17 @@ "package": "hashable", "revision": 0, "source": "hackage", - "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", - "version": "1.4.6.0" + "src_sha256": "3baee4c9027a08830d148ec524cbc0471de645e1e8426d46780ef2758df0e8da", + "version": "1.4.7.0" }, { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", + "cabal_sha256": "cf9e6afba8e01830ca0d32a12b98d481cf389688762c80d1870a1db2061ebf35", "component": "lib:async", "flags": [ "-bench" ], "package": "async", - "revision": 1, + "revision": 2, "source": "hackage", "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", "version": "2.2.5" @@ -362,17 +362,17 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", + "cabal_sha256": "acb64f2af52d81b0bb92c266f11d43def726a7a7b74a2c23d219e160b54edec7", "component": "lib:cryptohash-sha256", "flags": [ "-exe", "+use-cbits" ], "package": "cryptohash-sha256", - "revision": 4, + "revision": 5, "source": "hackage", "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", "version": "0.11.102.1" @@ -417,37 +417,37 @@ "version": "0.1.2" }, { - "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", + "cabal_sha256": "7699e7ae9bf74d056a62f384ceef8dfb2aa660f3f7c8016e9703f3b995e5e030", "component": "lib:os-string", "flags": [], "package": "os-string", "revision": 0, "source": "hackage", - "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", - "version": "2.0.3" + "src_sha256": "22fcc7d5fc66676b5dfc57b714d2caf93cce2d5a79d242168352f9eb0fe2f18a", + "version": "2.0.6" }, { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "cabal_sha256": "e9f151d9999be8953443e730524b2792e9c0a4fb5b1463097fa1a8230870fd8a", "component": "lib:tar-internal", "flags": [], "package": "tar", - "revision": 0, + "revision": 1, "source": "hackage", "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", "version": "0.6.3.0" }, { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "cabal_sha256": "e9f151d9999be8953443e730524b2792e9c0a4fb5b1463097fa1a8230870fd8a", "component": "lib:tar", "flags": [], "package": "tar", - "revision": 0, + "revision": 1, "source": "hackage", "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", "version": "0.6.3.0" }, { - "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", + "cabal_sha256": "bae1c5a6092d65c5e763246f91e04fef3f43e37cb055130725c9a973c88a250f", "component": "lib:zlib", "flags": [ "-bundled-c-zlib", @@ -455,20 +455,20 @@ "+pkg-config" ], "package": "zlib", - "revision": 0, + "revision": 1, "source": "hackage", "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", "version": "0.7.1.0" }, { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", + "cabal_sha256": "a7311a70ce2cc820ee430c389f57f82a082f148230b37526c34eac72b7b3ff34", "component": "lib:hackage-security", "flags": [ "+cabal-syntax", "+lukko" ], "package": "hackage-security", - "revision": 1, + "revision": 4, "source": "hackage", "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", "version": "0.6.2.6" @@ -546,7 +546,7 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { "cabal_sha256": null, @@ -559,7 +559,7 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", diff --git a/bootstrap/linux-9.2.8.json b/bootstrap/linux-9.2.8.json index 8a19bb40027..53a81294887 100644 --- a/bootstrap/linux-9.2.8.json +++ b/bootstrap/linux-9.2.8.json @@ -79,26 +79,26 @@ ], "dependencies": [ { - "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", + "cabal_sha256": "7699e7ae9bf74d056a62f384ceef8dfb2aa660f3f7c8016e9703f3b995e5e030", "component": "lib:os-string", "flags": [], "package": "os-string", "revision": 0, "source": "hackage", - "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", - "version": "2.0.3" + "src_sha256": "22fcc7d5fc66676b5dfc57b714d2caf93cce2d5a79d242168352f9eb0fe2f18a", + "version": "2.0.6" }, { - "cabal_sha256": "8af7a843cba7eddc8d44ae94002b766ee8c23cbcd3ecdb2cc79ee6e0a694419a", + "cabal_sha256": "0c64bc9a4f5946c86a8f0527bf40c8ba51e2c02d36eea0e20ea558c8d94166e8", "component": "lib:filepath", "flags": [ "-cpphs" ], "package": "filepath", - "revision": 1, + "revision": 0, "source": "hackage", - "src_sha256": "d2606db4fa8517932a2d9ea6415c365da4d1794afcb264a5b3c10110123978a7", - "version": "1.5.2.0" + "src_sha256": "d807ec44fe53de7c7e0eeb41c9ee9185a09163821cf50549d73d875197931a5a", + "version": "1.5.3.0" }, { "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", @@ -142,17 +142,17 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { - "cabal_sha256": "2a9393de33f18415fb8f4826957a87a94ffe8840ca8472a9b69dca6de45aca03", + "cabal_sha256": "684028fb5ac3d1c7657fe516f2a442d95a53ae2fcf6f6151544f3ed5289f6320", "component": "lib:process", "flags": [], "package": "process", - "revision": 1, + "revision": 0, "source": "hackage", - "src_sha256": "cefda221c3009fa2316b5cf148215cb340dad7eb8503f22e49e33722559df99a", - "version": "1.6.20.0" + "src_sha256": "a816655978c2527d8d7a6ebfd6f1ca79027f27ac4f2f28888f1581b2d558aea5", + "version": "1.6.23.0" }, { "cabal_sha256": null, @@ -162,7 +162,7 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { "cabal_sha256": null, @@ -187,7 +187,7 @@ "version": "0.68.10" }, { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", + "cabal_sha256": "17b834d2b75df8a8aef05de523280f613bb9c9aa9c31f269d5b90c1431a3749b", "component": "lib:network", "flags": [ "-devel" @@ -195,8 +195,8 @@ "package": "network", "revision": 0, "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" + "src_sha256": "efb04947946f52cccba802c2a8fc2f4259f0bdfd0bce95094c84e71583647f0c", + "version": "3.2.2.0" }, { "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", @@ -244,7 +244,7 @@ "version": "0.1.0.1" }, { - "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", + "cabal_sha256": "573f3ab242f75465a0d67ce9d84202650a1606575e6dbd6d31ffcf4767a9a379", "component": "lib:hashable", "flags": [ "-arch-native", @@ -254,17 +254,17 @@ "package": "hashable", "revision": 0, "source": "hackage", - "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", - "version": "1.4.6.0" + "src_sha256": "3baee4c9027a08830d148ec524cbc0471de645e1e8426d46780ef2758df0e8da", + "version": "1.4.7.0" }, { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", + "cabal_sha256": "cf9e6afba8e01830ca0d32a12b98d481cf389688762c80d1870a1db2061ebf35", "component": "lib:async", "flags": [ "-bench" ], "package": "async", - "revision": 1, + "revision": 2, "source": "hackage", "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", "version": "2.2.5" @@ -332,17 +332,17 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", + "cabal_sha256": "acb64f2af52d81b0bb92c266f11d43def726a7a7b74a2c23d219e160b54edec7", "component": "lib:cryptohash-sha256", "flags": [ "-exe", "+use-cbits" ], "package": "cryptohash-sha256", - "revision": 4, + "revision": 5, "source": "hackage", "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", "version": "0.11.102.1" @@ -387,27 +387,27 @@ "version": "0.1.2" }, { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "cabal_sha256": "e9f151d9999be8953443e730524b2792e9c0a4fb5b1463097fa1a8230870fd8a", "component": "lib:tar-internal", "flags": [], "package": "tar", - "revision": 0, + "revision": 1, "source": "hackage", "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", "version": "0.6.3.0" }, { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "cabal_sha256": "e9f151d9999be8953443e730524b2792e9c0a4fb5b1463097fa1a8230870fd8a", "component": "lib:tar", "flags": [], "package": "tar", - "revision": 0, + "revision": 1, "source": "hackage", "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", "version": "0.6.3.0" }, { - "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", + "cabal_sha256": "bae1c5a6092d65c5e763246f91e04fef3f43e37cb055130725c9a973c88a250f", "component": "lib:zlib", "flags": [ "-bundled-c-zlib", @@ -415,20 +415,20 @@ "+pkg-config" ], "package": "zlib", - "revision": 0, + "revision": 1, "source": "hackage", "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", "version": "0.7.1.0" }, { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", + "cabal_sha256": "a7311a70ce2cc820ee430c389f57f82a082f148230b37526c34eac72b7b3ff34", "component": "lib:hackage-security", "flags": [ "+cabal-syntax", "+lukko" ], "package": "hackage-security", - "revision": 1, + "revision": 4, "source": "hackage", "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", "version": "0.6.2.6" @@ -506,7 +506,7 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { "cabal_sha256": null, @@ -519,7 +519,7 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", diff --git a/bootstrap/linux-9.4.8.json b/bootstrap/linux-9.4.8.json index aa97cbabe35..c538160f393 100644 --- a/bootstrap/linux-9.4.8.json +++ b/bootstrap/linux-9.4.8.json @@ -79,26 +79,26 @@ ], "dependencies": [ { - "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", + "cabal_sha256": "7699e7ae9bf74d056a62f384ceef8dfb2aa660f3f7c8016e9703f3b995e5e030", "component": "lib:os-string", "flags": [], "package": "os-string", "revision": 0, "source": "hackage", - "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", - "version": "2.0.3" + "src_sha256": "22fcc7d5fc66676b5dfc57b714d2caf93cce2d5a79d242168352f9eb0fe2f18a", + "version": "2.0.6" }, { - "cabal_sha256": "8af7a843cba7eddc8d44ae94002b766ee8c23cbcd3ecdb2cc79ee6e0a694419a", + "cabal_sha256": "0c64bc9a4f5946c86a8f0527bf40c8ba51e2c02d36eea0e20ea558c8d94166e8", "component": "lib:filepath", "flags": [ "-cpphs" ], "package": "filepath", - "revision": 1, + "revision": 0, "source": "hackage", - "src_sha256": "d2606db4fa8517932a2d9ea6415c365da4d1794afcb264a5b3c10110123978a7", - "version": "1.5.2.0" + "src_sha256": "d807ec44fe53de7c7e0eeb41c9ee9185a09163821cf50549d73d875197931a5a", + "version": "1.5.3.0" }, { "cabal_sha256": "3f702a252a313a7bcb56e3908a14e7f9f1b40e41b7bdc8ae8a9605a1a8686f06", @@ -142,17 +142,17 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { - "cabal_sha256": "2a9393de33f18415fb8f4826957a87a94ffe8840ca8472a9b69dca6de45aca03", + "cabal_sha256": "684028fb5ac3d1c7657fe516f2a442d95a53ae2fcf6f6151544f3ed5289f6320", "component": "lib:process", "flags": [], "package": "process", - "revision": 1, + "revision": 0, "source": "hackage", - "src_sha256": "cefda221c3009fa2316b5cf148215cb340dad7eb8503f22e49e33722559df99a", - "version": "1.6.20.0" + "src_sha256": "a816655978c2527d8d7a6ebfd6f1ca79027f27ac4f2f28888f1581b2d558aea5", + "version": "1.6.23.0" }, { "cabal_sha256": null, @@ -162,7 +162,7 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { "cabal_sha256": null, @@ -187,7 +187,7 @@ "version": "0.68.10" }, { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", + "cabal_sha256": "17b834d2b75df8a8aef05de523280f613bb9c9aa9c31f269d5b90c1431a3749b", "component": "lib:network", "flags": [ "-devel" @@ -195,8 +195,8 @@ "package": "network", "revision": 0, "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" + "src_sha256": "efb04947946f52cccba802c2a8fc2f4259f0bdfd0bce95094c84e71583647f0c", + "version": "3.2.2.0" }, { "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", @@ -234,7 +234,7 @@ "version": "4000.4.1" }, { - "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", + "cabal_sha256": "573f3ab242f75465a0d67ce9d84202650a1606575e6dbd6d31ffcf4767a9a379", "component": "lib:hashable", "flags": [ "-arch-native", @@ -244,17 +244,17 @@ "package": "hashable", "revision": 0, "source": "hackage", - "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", - "version": "1.4.6.0" + "src_sha256": "3baee4c9027a08830d148ec524cbc0471de645e1e8426d46780ef2758df0e8da", + "version": "1.4.7.0" }, { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", + "cabal_sha256": "cf9e6afba8e01830ca0d32a12b98d481cf389688762c80d1870a1db2061ebf35", "component": "lib:async", "flags": [ "-bench" ], "package": "async", - "revision": 1, + "revision": 2, "source": "hackage", "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", "version": "2.2.5" @@ -322,17 +322,17 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", + "cabal_sha256": "acb64f2af52d81b0bb92c266f11d43def726a7a7b74a2c23d219e160b54edec7", "component": "lib:cryptohash-sha256", "flags": [ "-exe", "+use-cbits" ], "package": "cryptohash-sha256", - "revision": 4, + "revision": 5, "source": "hackage", "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", "version": "0.11.102.1" @@ -377,27 +377,27 @@ "version": "0.1.2" }, { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "cabal_sha256": "e9f151d9999be8953443e730524b2792e9c0a4fb5b1463097fa1a8230870fd8a", "component": "lib:tar-internal", "flags": [], "package": "tar", - "revision": 0, + "revision": 1, "source": "hackage", "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", "version": "0.6.3.0" }, { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "cabal_sha256": "e9f151d9999be8953443e730524b2792e9c0a4fb5b1463097fa1a8230870fd8a", "component": "lib:tar", "flags": [], "package": "tar", - "revision": 0, + "revision": 1, "source": "hackage", "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", "version": "0.6.3.0" }, { - "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", + "cabal_sha256": "bae1c5a6092d65c5e763246f91e04fef3f43e37cb055130725c9a973c88a250f", "component": "lib:zlib", "flags": [ "-bundled-c-zlib", @@ -405,20 +405,20 @@ "+pkg-config" ], "package": "zlib", - "revision": 0, + "revision": 1, "source": "hackage", "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", "version": "0.7.1.0" }, { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", + "cabal_sha256": "a7311a70ce2cc820ee430c389f57f82a082f148230b37526c34eac72b7b3ff34", "component": "lib:hackage-security", "flags": [ "+cabal-syntax", "+lukko" ], "package": "hackage-security", - "revision": 1, + "revision": 4, "source": "hackage", "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", "version": "0.6.2.6" @@ -496,7 +496,7 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { "cabal_sha256": null, @@ -509,7 +509,7 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", diff --git a/bootstrap/linux-9.6.6.json b/bootstrap/linux-9.6.6.json new file mode 100644 index 00000000000..10227f50ec8 --- /dev/null +++ b/bootstrap/linux-9.6.6.json @@ -0,0 +1,494 @@ +{ + "builtin": [ + { + "package": "rts", + "version": "1.0.2" + }, + { + "package": "ghc-prim", + "version": "0.10.0" + }, + { + "package": "ghc-bignum", + "version": "1.3" + }, + { + "package": "base", + "version": "4.18.2.1" + }, + { + "package": "array", + "version": "0.5.6.0" + }, + { + "package": "deepseq", + "version": "1.4.8.1" + }, + { + "package": "ghc-boot-th", + "version": "9.6.6" + }, + { + "package": "pretty", + "version": "1.1.3.6" + }, + { + "package": "template-haskell", + "version": "2.20.0.0" + }, + { + "package": "containers", + "version": "0.6.7" + }, + { + "package": "bytestring", + "version": "0.11.5.3" + }, + { + "package": "transformers", + "version": "0.6.1.0" + }, + { + "package": "mtl", + "version": "2.3.1" + }, + { + "package": "stm", + "version": "2.5.1.0" + }, + { + "package": "exceptions", + "version": "0.10.7" + }, + { + "package": "filepath", + "version": "1.4.300.1" + }, + { + "package": "time", + "version": "1.12.2" + }, + { + "package": "unix", + "version": "2.8.4.0" + }, + { + "package": "directory", + "version": "1.3.8.5" + }, + { + "package": "binary", + "version": "0.8.9.1" + }, + { + "package": "text", + "version": "2.0.2" + }, + { + "package": "parsec", + "version": "3.1.16.1" + }, + { + "package": "process", + "version": "1.6.19.0" + } + ], + "dependencies": [ + { + "cabal_sha256": "de553eefe0b6548a560e9d8100486310548470a403c1fa21108dd03713da5fc7", + "component": "exe:alex", + "flags": [], + "package": "alex", + "revision": 0, + "source": "hackage", + "src_sha256": "c92efe86f8eb959ee03be6c04ee57ebc7e4abc75a6c4b26551215d7443e92a07", + "version": "3.5.1.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-syntax", + "flags": [], + "package": "Cabal-syntax", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.15.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal", + "flags": [], + "package": "Cabal", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.15.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:Cabal-hooks", + "flags": [], + "package": "Cabal-hooks", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "0.1" + }, + { + "cabal_sha256": "60e78b6c60dc32a77ce6c37ed5ca4e838fc5f76f02836ef64d93cd21cc002325", + "component": "exe:hsc2hs", + "flags": [ + "-in-ghc-tree" + ], + "package": "hsc2hs", + "revision": 2, + "source": "hackage", + "src_sha256": "6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76", + "version": "0.68.10" + }, + { + "cabal_sha256": "17b834d2b75df8a8aef05de523280f613bb9c9aa9c31f269d5b90c1431a3749b", + "component": "lib:network", + "flags": [ + "-devel" + ], + "package": "network", + "revision": 0, + "source": "hackage", + "src_sha256": "efb04947946f52cccba802c2a8fc2f4259f0bdfd0bce95094c84e71583647f0c", + "version": "3.2.2.0" + }, + { + "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", + "component": "lib:th-compat", + "flags": [], + "package": "th-compat", + "revision": 2, + "source": "hackage", + "src_sha256": "81f55fafc7afad7763c09cb8b7b4165ca3765edcf70ffa42c7393043a1382a1e", + "version": "0.1.5" + }, + { + "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588", + "component": "lib:network-uri", + "flags": [], + "package": "network-uri", + "revision": 1, + "source": "hackage", + "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228", + "version": "2.6.4.2" + }, + { + "cabal_sha256": "b90ce97917703f6613ed5a8cfe1a51525b990244f5610509baa15c8499eadca3", + "component": "lib:HTTP", + "flags": [ + "-conduit10", + "+network-uri", + "-warn-as-error", + "-warp-tests" + ], + "package": "HTTP", + "revision": 4, + "source": "hackage", + "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453", + "version": "4000.4.1" + }, + { + "cabal_sha256": "7699e7ae9bf74d056a62f384ceef8dfb2aa660f3f7c8016e9703f3b995e5e030", + "component": "lib:os-string", + "flags": [], + "package": "os-string", + "revision": 0, + "source": "hackage", + "src_sha256": "22fcc7d5fc66676b5dfc57b714d2caf93cce2d5a79d242168352f9eb0fe2f18a", + "version": "2.0.6" + }, + { + "cabal_sha256": "fc68b07d957ade5a0a0beadd560a8d093ceac30b2f35c85eed3bcf7889a25975", + "component": "lib:hashable", + "flags": [ + "-arch-native", + "-random-initial-seed" + ], + "package": "hashable", + "revision": 0, + "source": "hackage", + "src_sha256": "e58b3a8e18da5f6cd7e937e5fd683e500bb1f8276b3768269759119ca0cddb6a", + "version": "1.5.0.0" + }, + { + "cabal_sha256": "cf9e6afba8e01830ca0d32a12b98d481cf389688762c80d1870a1db2061ebf35", + "component": "lib:async", + "flags": [ + "-bench" + ], + "package": "async", + "revision": 2, + "source": "hackage", + "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", + "version": "2.2.5" + }, + { + "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd", + "component": "lib:base16-bytestring", + "flags": [], + "package": "base16-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784", + "version": "1.0.2.0" + }, + { + "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803", + "component": "lib:base64-bytestring", + "flags": [], + "package": "base64-bytestring", + "revision": 1, + "source": "hackage", + "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9", + "version": "1.2.1.0" + }, + { + "cabal_sha256": "caa9b4a92abf1496c7f6a3c0f4e357426a54880077cb9f04e260a8bfa034b77b", + "component": "lib:splitmix", + "flags": [ + "-optimised-mixer" + ], + "package": "splitmix", + "revision": 1, + "source": "hackage", + "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002", + "version": "0.1.0.5" + }, + { + "cabal_sha256": "32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867", + "component": "lib:random", + "flags": [], + "package": "random", + "revision": 0, + "source": "hackage", + "src_sha256": "790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4", + "version": "1.2.1.2" + }, + { + "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee", + "component": "lib:edit-distance", + "flags": [], + "package": "edit-distance", + "revision": 1, + "source": "hackage", + "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a", + "version": "0.2.2.1" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install-solver", + "flags": [ + "-debug-expensive-assertions", + "-debug-tracetree" + ], + "package": "cabal-install-solver", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.15.0.0" + }, + { + "cabal_sha256": "acb64f2af52d81b0bb92c266f11d43def726a7a7b74a2c23d219e160b54edec7", + "component": "lib:cryptohash-sha256", + "flags": [ + "-exe", + "+use-cbits" + ], + "package": "cryptohash-sha256", + "revision": 5, + "source": "hackage", + "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", + "version": "0.11.102.1" + }, + { + "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42", + "component": "lib:echo", + "flags": [ + "-example" + ], + "package": "echo", + "revision": 0, + "source": "hackage", + "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43", + "version": "0.1.4" + }, + { + "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75", + "component": "lib:ed25519", + "flags": [ + "+no-donna", + "+test-doctests", + "+test-hlint", + "+test-properties" + ], + "package": "ed25519", + "revision": 8, + "source": "hackage", + "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d", + "version": "0.0.5.0" + }, + { + "cabal_sha256": "8a3004c2de2a0b5ef0634d3da6eae62ba8d8a734bab9ed8c6cfd749e7ca08997", + "component": "lib:lukko", + "flags": [ + "+ofd-locking" + ], + "package": "lukko", + "revision": 0, + "source": "hackage", + "src_sha256": "72d86f8aa625b461f4397f737346f78a1700a7ffbff55cf6375c5e18916e986d", + "version": "0.1.2" + }, + { + "cabal_sha256": "e9f151d9999be8953443e730524b2792e9c0a4fb5b1463097fa1a8230870fd8a", + "component": "lib:tar-internal", + "flags": [], + "package": "tar", + "revision": 1, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "e9f151d9999be8953443e730524b2792e9c0a4fb5b1463097fa1a8230870fd8a", + "component": "lib:tar", + "flags": [], + "package": "tar", + "revision": 1, + "source": "hackage", + "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", + "version": "0.6.3.0" + }, + { + "cabal_sha256": "bae1c5a6092d65c5e763246f91e04fef3f43e37cb055130725c9a973c88a250f", + "component": "lib:zlib", + "flags": [ + "-bundled-c-zlib", + "+non-blocking-ffi", + "+pkg-config" + ], + "package": "zlib", + "revision": 1, + "source": "hackage", + "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", + "version": "0.7.1.0" + }, + { + "cabal_sha256": "a7311a70ce2cc820ee430c389f57f82a082f148230b37526c34eac72b7b3ff34", + "component": "lib:hackage-security", + "flags": [ + "+cabal-syntax", + "+lukko" + ], + "package": "hackage-security", + "revision": 4, + "source": "hackage", + "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", + "version": "0.6.2.6" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "lib:open-browser", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + }, + { + "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27", + "component": "lib:regex-base", + "flags": [], + "package": "regex-base", + "revision": 4, + "source": "hackage", + "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1", + "version": "0.94.0.2" + }, + { + "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd", + "component": "lib:regex-posix", + "flags": [ + "-_regex-posix-clib" + ], + "package": "regex-posix", + "revision": 3, + "source": "hackage", + "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c", + "version": "0.96.0.1" + }, + { + "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045", + "component": "lib:resolv", + "flags": [], + "package": "resolv", + "revision": 3, + "source": "hackage", + "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b", + "version": "0.2.0.2" + }, + { + "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1", + "component": "lib:safe-exceptions", + "flags": [], + "package": "safe-exceptions", + "revision": 1, + "source": "hackage", + "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6", + "version": "0.1.7.4" + }, + { + "cabal_sha256": "2de5218cef72b8ef090bd7d0fd930ffa143242a120c62e013b5cf039858f1855", + "component": "lib:semaphore-compat", + "flags": [], + "package": "semaphore-compat", + "revision": 3, + "source": "hackage", + "src_sha256": "1c6e6fab021c2ccee5d86112fb1c0bd016d15e0cf70c489dae5fb5ec156ed9e2", + "version": "1.0.0" + }, + { + "cabal_sha256": null, + "component": "lib:cabal-install", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.15.0.0" + }, + { + "cabal_sha256": null, + "component": "exe:cabal", + "flags": [ + "+lukko", + "+native-dns" + ], + "package": "cabal-install", + "revision": null, + "source": "local", + "src_sha256": null, + "version": "3.15.0.0" + }, + { + "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", + "component": "exe:example", + "flags": [], + "package": "open-browser", + "revision": 0, + "source": "hackage", + "src_sha256": "0bed2e63800f738e78a4803ed22902accb50ac02068b96c17ce83a267244ca66", + "version": "0.2.1.0" + } + ] +} diff --git a/bootstrap/linux-9.8.2.json b/bootstrap/linux-9.8.2.json index 638ae20adb4..16d252dc833 100644 --- a/bootstrap/linux-9.8.2.json +++ b/bootstrap/linux-9.8.2.json @@ -116,7 +116,7 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { "cabal_sha256": null, @@ -126,7 +126,7 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { "cabal_sha256": null, @@ -151,7 +151,7 @@ "version": "0.68.10" }, { - "cabal_sha256": "25440c1bbd5772fdbbeec068f20138121131e1a56453db0adc113dcdf9044105", + "cabal_sha256": "17b834d2b75df8a8aef05de523280f613bb9c9aa9c31f269d5b90c1431a3749b", "component": "lib:network", "flags": [ "-devel" @@ -159,8 +159,8 @@ "package": "network", "revision": 0, "source": "hackage", - "src_sha256": "c45696744dc437d93a56871a3dd869965b7b50eda3fe3c1a90a35e2fbb9cb9ca", - "version": "3.2.0.0" + "src_sha256": "efb04947946f52cccba802c2a8fc2f4259f0bdfd0bce95094c84e71583647f0c", + "version": "3.2.2.0" }, { "cabal_sha256": "129a59ba3ccfcd06192fd6da899e2711ae276a466915a047bd6727e4a0321d2e", @@ -198,37 +198,36 @@ "version": "4000.4.1" }, { - "cabal_sha256": "4d4186bb8d711435765253c7dc076c44a1d52896300689507ba135706ab35866", + "cabal_sha256": "7699e7ae9bf74d056a62f384ceef8dfb2aa660f3f7c8016e9703f3b995e5e030", "component": "lib:os-string", "flags": [], "package": "os-string", "revision": 0, "source": "hackage", - "src_sha256": "f6b388b9f9002622901d3f71437b98f95f54fbf7fe10490d319cb801c2a061ea", - "version": "2.0.3" + "src_sha256": "22fcc7d5fc66676b5dfc57b714d2caf93cce2d5a79d242168352f9eb0fe2f18a", + "version": "2.0.6" }, { - "cabal_sha256": "82503a1ef0a625c210e118f2785c4138f8502aacbbfd4e5d987f6baffbb87115", + "cabal_sha256": "fc68b07d957ade5a0a0beadd560a8d093ceac30b2f35c85eed3bcf7889a25975", "component": "lib:hashable", "flags": [ "-arch-native", - "+integer-gmp", "-random-initial-seed" ], "package": "hashable", "revision": 0, "source": "hackage", - "src_sha256": "34652a7a1d2fc9e3d764b150bd35bcd2220761c1d4c6b446b0cfac5ad5b778cb", - "version": "1.4.6.0" + "src_sha256": "e58b3a8e18da5f6cd7e937e5fd683e500bb1f8276b3768269759119ca0cddb6a", + "version": "1.5.0.0" }, { - "cabal_sha256": "9d5d9e605f52958d099e13a8b8f30ee56cb137c9192996245e3c533adb682cf8", + "cabal_sha256": "cf9e6afba8e01830ca0d32a12b98d481cf389688762c80d1870a1db2061ebf35", "component": "lib:async", "flags": [ "-bench" ], "package": "async", - "revision": 1, + "revision": 2, "source": "hackage", "src_sha256": "1818473ebab9212afad2ed76297aefde5fae8b5d4404daf36939aece6a8f16f7", "version": "2.2.5" @@ -296,17 +295,17 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { - "cabal_sha256": "200d756a7b3bab7ca2bac6eb50ed8252f26de77ac8def490a3ad743f2933acbd", + "cabal_sha256": "acb64f2af52d81b0bb92c266f11d43def726a7a7b74a2c23d219e160b54edec7", "component": "lib:cryptohash-sha256", "flags": [ "-exe", "+use-cbits" ], "package": "cryptohash-sha256", - "revision": 4, + "revision": 5, "source": "hackage", "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6", "version": "0.11.102.1" @@ -351,27 +350,27 @@ "version": "0.1.2" }, { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "cabal_sha256": "e9f151d9999be8953443e730524b2792e9c0a4fb5b1463097fa1a8230870fd8a", "component": "lib:tar-internal", "flags": [], "package": "tar", - "revision": 0, + "revision": 1, "source": "hackage", "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", "version": "0.6.3.0" }, { - "cabal_sha256": "b853b4296cb23386feda17dc0d9065af6709d22d684ec734aab65403d59ed547", + "cabal_sha256": "e9f151d9999be8953443e730524b2792e9c0a4fb5b1463097fa1a8230870fd8a", "component": "lib:tar", "flags": [], "package": "tar", - "revision": 0, + "revision": 1, "source": "hackage", "src_sha256": "50bb660feec8a524416d6934251b996eaa7e39d49ae107ad505ab700d43f6814", "version": "0.6.3.0" }, { - "cabal_sha256": "d6696f2b55ab4a50b8de57947abca308604eb7cf8287c40bf69cfa26133e24d3", + "cabal_sha256": "bae1c5a6092d65c5e763246f91e04fef3f43e37cb055130725c9a973c88a250f", "component": "lib:zlib", "flags": [ "-bundled-c-zlib", @@ -379,20 +378,20 @@ "+pkg-config" ], "package": "zlib", - "revision": 0, + "revision": 1, "source": "hackage", "src_sha256": "6edd38b6b81df8d274952aa85affa6968ae86b2231e1d429ce8bc9083e6a55bc", "version": "0.7.1.0" }, { - "cabal_sha256": "8ff70524314f9ad706f8e5051d7150ee44cb82170147879b245bdab279604b16", + "cabal_sha256": "a7311a70ce2cc820ee430c389f57f82a082f148230b37526c34eac72b7b3ff34", "component": "lib:hackage-security", "flags": [ "+cabal-syntax", "+lukko" ], "package": "hackage-security", - "revision": 1, + "revision": 4, "source": "hackage", "src_sha256": "2e4261576b3e11b9f5175392947f56a638cc1a3584b8acbb962b809d7c69db69", "version": "0.6.2.6" @@ -460,7 +459,7 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { "cabal_sha256": null, @@ -473,7 +472,7 @@ "revision": null, "source": "local", "src_sha256": null, - "version": "3.13.0.0" + "version": "3.15.0.0" }, { "cabal_sha256": "e4be4a206f5ab6ddb5ae4fbb39101529196e20af5670c5d33326fea6eff886fd", diff --git a/cabal-install-solver/cabal-install-solver.cabal b/cabal-install-solver/cabal-install-solver.cabal index 2cb276e910a..edd8f9246db 100644 --- a/cabal-install-solver/cabal-install-solver.cabal +++ b/cabal-install-solver/cabal-install-solver.cabal @@ -1,6 +1,6 @@ cabal-version: 2.2 name: cabal-install-solver -version: 3.13.0.0 +version: 3.15.0.0 synopsis: The solver component of cabal-install description: The solver component used in the cabal-install command-line program. @@ -101,8 +101,8 @@ library , array >=0.4 && <0.6 , base >=4.13 && <4.21 , bytestring >=0.10.6.0 && <0.13 - , Cabal ^>=3.13 - , Cabal-syntax ^>=3.13 + , Cabal ^>=3.15 + , Cabal-syntax ^>=3.15 , containers >=0.5.6.2 && <0.8 , edit-distance ^>= 0.2.2 , directory >= 1.3.7.0 && < 1.4 diff --git a/cabal-install/cabal-install.cabal b/cabal-install/cabal-install.cabal index db6d1452ae3..94b97d9f0a3 100644 --- a/cabal-install/cabal-install.cabal +++ b/cabal-install/cabal-install.cabal @@ -1,7 +1,7 @@ Cabal-Version: 3.0 Name: cabal-install -Version: 3.13.0.0 +Version: 3.15.0.0 Synopsis: The command-line interface for Cabal and Hackage. Description: The \'cabal\' command-line program simplifies the process of managing @@ -55,13 +55,13 @@ common base-dep build-depends: base >=4.13 && <4.21 common cabal-dep - build-depends: Cabal ^>=3.13 + build-depends: Cabal ^>=3.15 common cabal-syntax-dep - build-depends: Cabal-syntax ^>=3.13 + build-depends: Cabal-syntax ^>=3.15 common cabal-install-solver-dep - build-depends: cabal-install-solver ^>=3.13 + build-depends: cabal-install-solver ^>=3.15 library import: warnings, base-dep, cabal-dep, cabal-syntax-dep, cabal-install-solver-dep diff --git a/cabal-testsuite/cabal-testsuite.cabal b/cabal-testsuite/cabal-testsuite.cabal index 479b372b8ca..4c114082d43 100644 --- a/cabal-testsuite/cabal-testsuite.cabal +++ b/cabal-testsuite/cabal-testsuite.cabal @@ -28,7 +28,7 @@ common shared build-depends: , base >= 4.11 && < 4.21 -- this needs to match the in-tree lib:Cabal version - , Cabal ^>= 3.13.0.0 + , Cabal ^>= 3.15.0.0 ghc-options: -Wall diff --git a/cabal.bootstrap.project b/cabal.bootstrap.project index 00e676c24ad..a700ac72b7c 100644 --- a/cabal.bootstrap.project +++ b/cabal.bootstrap.project @@ -14,4 +14,4 @@ benchmarks: False constraints: hashable -arch-native -index-state: hackage.haskell.org 2024-07-15T21:05:18Z +index-state: hackage.haskell.org 2024-09-06T14:16:40Z diff --git a/cabal.release.project b/cabal.release.project index ee061449efc..74a2632797b 100644 --- a/cabal.release.project +++ b/cabal.release.project @@ -5,4 +5,4 @@ import: project-cabal/pkgs/tests.config constraints: hashable -arch-native -index-state: hackage.haskell.org 2024-07-15T21:05:18Z +index-state: hackage.haskell.org 2024-09-06T14:16:40Z diff --git a/solver-benchmarks/solver-benchmarks.cabal b/solver-benchmarks/solver-benchmarks.cabal index 42ebd616f9a..0595a5bd229 100644 --- a/solver-benchmarks/solver-benchmarks.cabal +++ b/solver-benchmarks/solver-benchmarks.cabal @@ -31,7 +31,7 @@ library base, bytestring, containers, - Cabal-syntax ^>= 3.13, + Cabal-syntax ^>= 3.15, directory, filepath, optparse-applicative, From 0befd1d78d4959abc2cb49d32a69936dbe83c9c7 Mon Sep 17 00:00:00 2001 From: Francesco Ariis Date: Sun, 8 Sep 2024 20:42:32 +0200 Subject: [PATCH 128/207] Bump deepseq bounds to allow 1.6 --- Cabal-syntax/Cabal-syntax.cabal | 2 +- Cabal/Cabal.cabal | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cabal-syntax/Cabal-syntax.cabal b/Cabal-syntax/Cabal-syntax.cabal index 7d1d117b0a7..0893f4f2588 100644 --- a/Cabal-syntax/Cabal-syntax.cabal +++ b/Cabal-syntax/Cabal-syntax.cabal @@ -33,7 +33,7 @@ library binary >= 0.7 && < 0.9, bytestring >= 0.10.0.0 && < 0.13, containers >= 0.5.0.0 && < 0.8, - deepseq >= 1.3.0.1 && < 1.6, + deepseq >= 1.3.0.1 && < 1.7, directory >= 1.2 && < 1.4, filepath >= 1.3.0.1 && < 1.6, mtl >= 2.1 && < 2.4, diff --git a/Cabal/Cabal.cabal b/Cabal/Cabal.cabal index 777e078af1a..b9a7e0838ab 100644 --- a/Cabal/Cabal.cabal +++ b/Cabal/Cabal.cabal @@ -39,7 +39,7 @@ library base >= 4.13 && < 5, bytestring >= 0.10.0.0 && < 0.13, containers >= 0.5.0.0 && < 0.8, - deepseq >= 1.3.0.1 && < 1.6, + deepseq >= 1.3.0.1 && < 1.7, directory >= 1.2 && < 1.4, filepath >= 1.3.0.1 && < 1.6, pretty >= 1.1.1 && < 1.2, From cd3a42e32b9b16bb111fb4a0a6aba7e944f6eace Mon Sep 17 00:00:00 2001 From: Phil de Joux Date: Fri, 6 Sep 2024 12:26:39 -0400 Subject: [PATCH 129/207] Warn that scripts cannot be package executables --- doc/getting-started.rst | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/doc/getting-started.rst b/doc/getting-started.rst index 056c4a85ebd..f420c2b6f6f 100644 --- a/doc/getting-started.rst +++ b/doc/getting-started.rst @@ -198,8 +198,8 @@ the following file named ``myscript``: main :: IO () main = haskellSay "Hello, Haskell!" -The necessary sections of a ``.cabal`` file are placed -directly into the script as a comment. +The necessary sections of a package description that would otherwise be in a +``.cabal`` file are placed directly into the script as a comment. Use the familiar ``cabal run`` command to execute this script: @@ -222,6 +222,36 @@ can be run directly after setting the execute permission (+x): See more in the documentation for :ref:`cabal run`. +.. warning:: + + Single-file scripts cannot also be part of a package, as an executable or + listed as a module. + + .. code-block:: console + + $ cat script-exclusivity.cabal + cabal-version: 3.0 + name: script-exclusitivity + version: 1 + + executable my-script-exe + build-depends: + base, + haskell-say + main-is: myscript.hs + + $ ./myscript.hs + Error: [Cabal-7070] + The run command can only run an executable as a whole, not files or modules + within them, but the target 'myscript.hs' refers to the file myscript.hs in the + executable my-script-exe. + + $ cabal run myscript.hs + Error: [Cabal-7070] + The run command can only run an executable as a whole, not files or modules + within them, but the target 'myscript.hs' refers to the file myscript.hs in the + executable my-script-exe. + What Next? ---------- From 20ba4ebab461b9b26ca6de56e6b635b40ccb42d1 Mon Sep 17 00:00:00 2001 From: Phil de Joux Date: Mon, 9 Sep 2024 09:25:15 -0400 Subject: [PATCH 130/207] Link to error index --- doc/getting-started.rst | 30 ++++-------------------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/doc/getting-started.rst b/doc/getting-started.rst index f420c2b6f6f..921a5ada6ce 100644 --- a/doc/getting-started.rst +++ b/doc/getting-started.rst @@ -225,32 +225,8 @@ See more in the documentation for :ref:`cabal run`. .. warning:: Single-file scripts cannot also be part of a package, as an executable or - listed as a module. - - .. code-block:: console - - $ cat script-exclusivity.cabal - cabal-version: 3.0 - name: script-exclusitivity - version: 1 - - executable my-script-exe - build-depends: - base, - haskell-say - main-is: myscript.hs - - $ ./myscript.hs - Error: [Cabal-7070] - The run command can only run an executable as a whole, not files or modules - within them, but the target 'myscript.hs' refers to the file myscript.hs in the - executable my-script-exe. - - $ cabal run myscript.hs - Error: [Cabal-7070] - The run command can only run an executable as a whole, not files or modules - within them, but the target 'myscript.hs' refers to the file myscript.hs in the - executable my-script-exe. + listed as a module. Trying to run a module that is included in a package + will error with `Cabal-7070`_. What Next? ---------- @@ -259,3 +235,5 @@ Now that you know how to set up a simple Haskell package using Cabal, check out some of the resources on the Haskell website's `documentation page `__ or read more about packages and Cabal on the :doc:`What Cabal does ` page. + +.. _Cabal-7070: https://errors.haskell.org/messages/Cabal-7070/ From 659ebbea08dd8c7e65e5db3772e28e87e05421e7 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Fri, 13 Sep 2024 01:01:36 +0200 Subject: [PATCH 131/207] Remove read-only and force-remove on Windows Some git files are marked as read-only. To ensure we delete the folders we are supposed to, we first remove the read-only attribute via `CMD.exe`, then we forcibly delete the relevant directory. --- .../src/Distribution/Client/CmdClean.hs | 25 ++++++++++++++++++- cabal-install/src/Distribution/Client/VCS.hs | 21 +++++++++++++++- .../CleanSourceRepositoryPackage/a.cabal | 6 +++++ .../CleanSourceRepositoryPackage/cabal.out | 6 +++++ .../cabal.project | 5 ++++ .../cabal.test.hs | 5 ++++ changelog.d/pr-10190 | 11 ++++++++ 7 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/a.cabal create mode 100644 cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/cabal.out create mode 100644 cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/cabal.project create mode 100644 cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/cabal.test.hs create mode 100644 changelog.d/pr-10190 diff --git a/cabal-install/src/Distribution/Client/CmdClean.hs b/cabal-install/src/Distribution/Client/CmdClean.hs index 2ffda4dce6a..a738f38336a 100644 --- a/cabal-install/src/Distribution/Client/CmdClean.hs +++ b/cabal-install/src/Distribution/Client/CmdClean.hs @@ -52,6 +52,10 @@ import Distribution.Simple.Utils , info , wrapText ) +import Distribution.System + ( OS (Windows) + , buildOS + ) import Distribution.Utils.Path hiding ( (<.>) , () @@ -60,6 +64,9 @@ import Distribution.Verbosity ( normal ) +import Control.Exception + ( throw + ) import Control.Monad ( forM , forM_ @@ -74,10 +81,15 @@ import System.Directory , listDirectory , removeDirectoryRecursive , removeFile + , removePathForcibly ) import System.FilePath ( () ) +import System.IO.Error + ( isPermissionError + ) +import qualified System.Process as Process data CleanFlags = CleanFlags { cleanSaveConfig :: Flag Bool @@ -168,7 +180,18 @@ cleanAction (ProjectFlags{..}, CleanFlags{..}) extraArgs _ = do let distRoot = distDirectory distLayout info verbosity ("Deleting dist-newstyle (" ++ distRoot ++ ")") - handleDoesNotExist () $ removeDirectoryRecursive distRoot + handleDoesNotExist () $ do + if buildOS == Windows + then do + -- Windows can't delete some git files #10182 + void $ + Process.createProcess_ "attrib" $ + Process.shell $ + "attrib -s -h -r " <> distRoot <> "\\*.* /s /d" + catch + (removePathForcibly distRoot) + (\e -> if isPermissionError e then removePathForcibly distRoot else throw e) + else removeDirectoryRecursive distRoot removeEnvFiles $ distProjectRootDirectory distLayout diff --git a/cabal-install/src/Distribution/Client/VCS.hs b/cabal-install/src/Distribution/Client/VCS.hs index 2f2686c6ae2..57c0a82376e 100644 --- a/cabal-install/src/Distribution/Client/VCS.hs +++ b/cabal-install/src/Distribution/Client/VCS.hs @@ -64,6 +64,10 @@ import Distribution.Simple.Program import Distribution.Simple.Program.Db ( prependProgramSearchPath ) +import Distribution.System + ( OS (Windows) + , buildOS + ) import Distribution.Types.SourceRepo ( KnownRepoType (..) , RepoType (..) @@ -93,6 +97,7 @@ import qualified Data.Map as Map import System.Directory ( doesDirectoryExist , removeDirectoryRecursive + , removePathForcibly ) import System.FilePath ( takeDirectory @@ -100,7 +105,9 @@ import System.FilePath ) import System.IO.Error ( isDoesNotExistError + , isPermissionError ) +import qualified System.Process as Process -- | A driver for a version control system, e.g. git, darcs etc. data VCS program = VCS @@ -509,7 +516,19 @@ vcsGit = git localDir ["submodule", "deinit", "--force", "--all"] let gitModulesDir = localDir ".git" "modules" gitModulesExists <- doesDirectoryExist gitModulesDir - when gitModulesExists $ removeDirectoryRecursive gitModulesDir + when gitModulesExists $ + if buildOS == Windows + then do + -- Windows can't delete some git files #10182 + void $ + Process.createProcess_ "attrib" $ + Process.shell $ + "attrib -s -h -r " <> gitModulesDir <> "\\*.* /s /d" + + catch + (removePathForcibly gitModulesDir) + (\e -> if isPermissionError e then removePathForcibly gitModulesDir else throw e) + else removeDirectoryRecursive gitModulesDir git localDir resetArgs git localDir $ ["submodule", "sync", "--recursive"] ++ verboseArg git localDir $ ["submodule", "update", "--force", "--init", "--recursive"] ++ verboseArg diff --git a/cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/a.cabal b/cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/a.cabal new file mode 100644 index 00000000000..77f47fbbcf5 --- /dev/null +++ b/cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/a.cabal @@ -0,0 +1,6 @@ +cabal-version: 3.0 +name: aa +version: 0.1.0.0 +build-type: Simple + +library diff --git a/cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/cabal.out b/cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/cabal.out new file mode 100644 index 00000000000..e4f538647f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/cabal.out @@ -0,0 +1,6 @@ +# cabal build +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following would be built: + - aa-0.1.0.0 (lib) (first run) +# cabal clean diff --git a/cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/cabal.project b/cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/cabal.project new file mode 100644 index 00000000000..60739ea84dd --- /dev/null +++ b/cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/cabal.project @@ -0,0 +1,5 @@ +packages: . + +source-repository-package + type: git + location: https://github.com/haskell-hvr/Only diff --git a/cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/cabal.test.hs b/cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/cabal.test.hs new file mode 100644 index 00000000000..9e93c607ce4 --- /dev/null +++ b/cabal-testsuite/PackageTests/NewBuild/CmdClean/CleanSourceRepositoryPackage/cabal.test.hs @@ -0,0 +1,5 @@ +import Test.Cabal.Prelude + +main = cabalTest $ withProjectFile "cabal.project" $ do + void $ cabal' "build" ["--dry-run"] + void $ cabal' "clean" [] diff --git a/changelog.d/pr-10190 b/changelog.d/pr-10190 new file mode 100644 index 00000000000..d9e4f009b94 --- /dev/null +++ b/changelog.d/pr-10190 @@ -0,0 +1,11 @@ +synopsis: Fix `cabal clean` permissions on Windows +packages: cabal-install +prs: #10190 +issues: #10182 +significance: + +description: { + +- `cabal clean` now removes the read-only mark recursively in the `dist-newstyle` folder on Windows before attempting to delete it. + +} From 555fc8198d80f50217b268d4108c48d9774fbb31 Mon Sep 17 00:00:00 2001 From: ffaf1 Date: Sun, 15 Sep 2024 19:43:01 +0200 Subject: [PATCH 132/207] Add OrPatterns extensions (#10339) * Add OrPatterns extension * Add changelog * Add missing full stop * Add missing NoMultilineStrings in vim syntax file * Make test happy * Remove changelog entry We don't need it, changes have been manually incorporated in 3.14 release notes (#10338) --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- Cabal-syntax/src/Language/Haskell/Extension.hs | 5 ++++- Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs | 4 ++-- editors/vim/syntax/cabal.vim | 3 +++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cabal-syntax/src/Language/Haskell/Extension.hs b/Cabal-syntax/src/Language/Haskell/Extension.hs index 13796c80666..dce34560586 100644 --- a/Cabal-syntax/src/Language/Haskell/Extension.hs +++ b/Cabal-syntax/src/Language/Haskell/Extension.hs @@ -551,8 +551,11 @@ data KnownExtension | -- | Allow the use of built-in syntax for list, tuple and sum type constructors -- rather than being exclusive to data constructors. ListTuplePuns - | -- | Support multiline strings + | -- | Support multiline strings. MultilineStrings + | -- | Allow use of or-pattern syntax, condensing multiple patterns + -- into a single one. + OrPatterns deriving (Generic, Show, Read, Eq, Ord, Enum, Bounded, Typeable, Data) instance Binary KnownExtension diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs index 3bdf0465244..025440c3598 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs @@ -30,8 +30,8 @@ md5Check proxy md5Int = structureHash proxy @?= md5FromInteger md5Int md5CheckGenericPackageDescription :: Proxy GenericPackageDescription -> Assertion md5CheckGenericPackageDescription proxy = md5Check proxy - 0xe40d8d67b85712f245354657d7a80165 + 0x09251b46ffc5178a7526d31e794d9c62 md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion md5CheckLocalBuildInfo proxy = md5Check proxy - 0x94827844fdb1afedee525061749fb16f + 0x93b7e8ebb5b9f879fa5fe49b1708b43b diff --git a/editors/vim/syntax/cabal.vim b/editors/vim/syntax/cabal.vim index db08e8e0d92..2e578307a7e 100644 --- a/editors/vim/syntax/cabal.vim +++ b/editors/vim/syntax/cabal.vim @@ -232,6 +232,7 @@ syn keyword cabalExtension contained \ NullaryTypeClasses \ NumDecimals \ NumericUnderscores + \ OrPatterns \ OverlappingInstances \ OverloadedLabels \ OverloadedLists @@ -362,6 +363,7 @@ syn keyword cabalExtension contained \ NoMonoLocalBinds \ NoMonoPatBinds \ NoMonomorphismRestriction + \ NoMultilineStrings \ NoMultiParamTypeClasses \ NoMultiWayIf \ NoNPlusKPatterns @@ -379,6 +381,7 @@ syn keyword cabalExtension contained \ NoOverloadedLists \ NoOverloadedRecordDot \ NoOverloadedStrings + \ NoOrPatterns \ NoPackageImports \ NoParallelArrays \ NoParallelListComp From 81186ac8aa26982a599041ff7dfdd78fd3354004 Mon Sep 17 00:00:00 2001 From: ffaf1 Date: Mon, 16 Sep 2024 18:22:13 +0200 Subject: [PATCH 133/207] Update SPDX license list to version 3.25 (#10341) * Handle 3D Slicer licence * Update SPDX license list to version 3.25 * Remove changelog entry We don't need it, changes have been manually incorporated in 3.14 release notes (#10338) --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .../Distribution/SPDX/LicenseExceptionId.hs | 150 +- .../src/Distribution/SPDX/LicenseId.hs | 941 +- .../Distribution/SPDX/LicenseListVersion.hs | 3 +- Makefile | 2 +- cabal-dev-scripts/src/GenSPDX.hs | 1 + cabal-dev-scripts/src/GenSPDXExc.hs | 1 + cabal-dev-scripts/src/GenUtils.hs | 22 +- doc/file-format-changelog.rst | 2 + license-list-data/exceptions-3.25.json | 836 ++ license-list-data/licenses-3.25.json | 8360 +++++++++++++++++ templates/SPDX.LicenseExceptionId.template.hs | 10 +- templates/SPDX.LicenseId.template.hs | 10 +- 12 files changed, 10014 insertions(+), 324 deletions(-) create mode 100644 license-list-data/exceptions-3.25.json create mode 100644 license-list-data/licenses-3.25.json diff --git a/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs b/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs index 6246d8df41d..2ab6eb9eeff 100644 --- a/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs +++ b/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs @@ -30,75 +30,80 @@ import qualified Text.PrettyPrint as Disp -- LicenseExceptionId ------------------------------------------------------------------------------- --- | SPDX License Exceptions identifiers list v3.23 +-- | SPDX License Exceptions identifiers list v3.25 data LicenseExceptionId = DS389_exception -- ^ @389-exception@, 389 Directory Server Exception - | Asterisk_exception -- ^ @Asterisk-exception@, Asterisk exception, SPDX License List 3.23 + | Asterisk_exception -- ^ @Asterisk-exception@, Asterisk exception, SPDX License List 3.23, SPDX License List 3.25 + | Asterisk_linking_protocols_exception -- ^ @Asterisk-linking-protocols-exception@, Asterisk linking protocols exception, SPDX License List 3.25 | Autoconf_exception_2_0 -- ^ @Autoconf-exception-2.0@, Autoconf exception 2.0 | Autoconf_exception_3_0 -- ^ @Autoconf-exception-3.0@, Autoconf exception 3.0 - | Autoconf_exception_generic_3_0 -- ^ @Autoconf-exception-generic-3.0@, Autoconf generic exception for GPL-3.0, SPDX License List 3.23 - | Autoconf_exception_generic -- ^ @Autoconf-exception-generic@, Autoconf generic exception, SPDX License List 3.23 - | Autoconf_exception_macro -- ^ @Autoconf-exception-macro@, Autoconf macro exception, SPDX License List 3.23 - | Bison_exception_1_24 -- ^ @Bison-exception-1.24@, Bison exception 1.24, SPDX License List 3.23 + | Autoconf_exception_generic_3_0 -- ^ @Autoconf-exception-generic-3.0@, Autoconf generic exception for GPL-3.0, SPDX License List 3.23, SPDX License List 3.25 + | Autoconf_exception_generic -- ^ @Autoconf-exception-generic@, Autoconf generic exception, SPDX License List 3.23, SPDX License List 3.25 + | Autoconf_exception_macro -- ^ @Autoconf-exception-macro@, Autoconf macro exception, SPDX License List 3.23, SPDX License List 3.25 + | Bison_exception_1_24 -- ^ @Bison-exception-1.24@, Bison exception 1.24, SPDX License List 3.23, SPDX License List 3.25 | Bison_exception_2_2 -- ^ @Bison-exception-2.2@, Bison exception 2.2 | Bootloader_exception -- ^ @Bootloader-exception@, Bootloader Distribution Exception | Classpath_exception_2_0 -- ^ @Classpath-exception-2.0@, Classpath exception 2.0 | CLISP_exception_2_0 -- ^ @CLISP-exception-2.0@, CLISP exception 2.0 - | Cryptsetup_OpenSSL_exception -- ^ @cryptsetup-OpenSSL-exception@, cryptsetup OpenSSL exception, SPDX License List 3.23 + | Cryptsetup_OpenSSL_exception -- ^ @cryptsetup-OpenSSL-exception@, cryptsetup OpenSSL exception, SPDX License List 3.23, SPDX License List 3.25 | DigiRule_FOSS_exception -- ^ @DigiRule-FOSS-exception@, DigiRule FOSS License Exception | ECos_exception_2_0 -- ^ @eCos-exception-2.0@, eCos exception 2.0 + | Erlang_otp_linking_exception -- ^ @erlang-otp-linking-exception@, Erlang/OTP Linking Exception, SPDX License List 3.25 | Fawkes_Runtime_exception -- ^ @Fawkes-Runtime-exception@, Fawkes Runtime Exception | FLTK_exception -- ^ @FLTK-exception@, FLTK exception - | Fmt_exception -- ^ @fmt-exception@, fmt exception, SPDX License List 3.23 + | Fmt_exception -- ^ @fmt-exception@, fmt exception, SPDX License List 3.23, SPDX License List 3.25 | Font_exception_2_0 -- ^ @Font-exception-2.0@, Font exception 2.0 | Freertos_exception_2_0 -- ^ @freertos-exception-2.0@, FreeRTOS Exception 2.0 - | GCC_exception_2_0_note -- ^ @GCC-exception-2.0-note@, GCC Runtime Library exception 2.0 - note variant, SPDX License List 3.23 + | GCC_exception_2_0_note -- ^ @GCC-exception-2.0-note@, GCC Runtime Library exception 2.0 - note variant, SPDX License List 3.23, SPDX License List 3.25 | GCC_exception_2_0 -- ^ @GCC-exception-2.0@, GCC Runtime Library exception 2.0 | GCC_exception_3_1 -- ^ @GCC-exception-3.1@, GCC Runtime Library exception 3.1 - | Gmsh_exception -- ^ @Gmsh-exception@, Gmsh exception>, SPDX License List 3.23 - | GNAT_exception -- ^ @GNAT-exception@, GNAT exception, SPDX License List 3.23 - | GNOME_examples_exception -- ^ @GNOME-examples-exception@, GNOME examples exception, SPDX License List 3.23 - | GNU_compiler_exception -- ^ @GNU-compiler-exception@, GNU Compiler Exception, SPDX License List 3.23 + | Gmsh_exception -- ^ @Gmsh-exception@, Gmsh exception>, SPDX License List 3.23, SPDX License List 3.25 + | GNAT_exception -- ^ @GNAT-exception@, GNAT exception, SPDX License List 3.23, SPDX License List 3.25 + | GNOME_examples_exception -- ^ @GNOME-examples-exception@, GNOME examples exception, SPDX License List 3.23, SPDX License List 3.25 + | GNU_compiler_exception -- ^ @GNU-compiler-exception@, GNU Compiler Exception, SPDX License List 3.23, SPDX License List 3.25 | Gnu_javamail_exception -- ^ @gnu-javamail-exception@, GNU JavaMail exception - | GPL_3_0_interface_exception -- ^ @GPL-3.0-interface-exception@, GPL-3.0 Interface Exception, SPDX License List 3.23 - | GPL_3_0_linking_exception -- ^ @GPL-3.0-linking-exception@, GPL-3.0 Linking Exception, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | GPL_3_0_linking_source_exception -- ^ @GPL-3.0-linking-source-exception@, GPL-3.0 Linking Exception (with Corresponding Source), SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | GPL_CC_1_0 -- ^ @GPL-CC-1.0@, GPL Cooperation Commitment 1.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | GStreamer_exception_2005 -- ^ @GStreamer-exception-2005@, GStreamer Exception (2005), SPDX License List 3.23 - | GStreamer_exception_2008 -- ^ @GStreamer-exception-2008@, GStreamer Exception (2008), SPDX License List 3.23 + | GPL_3_0_interface_exception -- ^ @GPL-3.0-interface-exception@, GPL-3.0 Interface Exception, SPDX License List 3.23, SPDX License List 3.25 + | GPL_3_0_linking_exception -- ^ @GPL-3.0-linking-exception@, GPL-3.0 Linking Exception, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | GPL_3_0_linking_source_exception -- ^ @GPL-3.0-linking-source-exception@, GPL-3.0 Linking Exception (with Corresponding Source), SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | GPL_CC_1_0 -- ^ @GPL-CC-1.0@, GPL Cooperation Commitment 1.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | GStreamer_exception_2005 -- ^ @GStreamer-exception-2005@, GStreamer Exception (2005), SPDX License List 3.23, SPDX License List 3.25 + | GStreamer_exception_2008 -- ^ @GStreamer-exception-2008@, GStreamer Exception (2008), SPDX License List 3.23, SPDX License List 3.25 | I2p_gpl_java_exception -- ^ @i2p-gpl-java-exception@, i2p GPL+Java Exception - | KiCad_libraries_exception -- ^ @KiCad-libraries-exception@, KiCad Libraries Exception, SPDX License List 3.23 - | LGPL_3_0_linking_exception -- ^ @LGPL-3.0-linking-exception@, LGPL-3.0 Linking Exception, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | Libpri_OpenH323_exception -- ^ @libpri-OpenH323-exception@, libpri OpenH323 exception, SPDX License List 3.23 + | KiCad_libraries_exception -- ^ @KiCad-libraries-exception@, KiCad Libraries Exception, SPDX License List 3.23, SPDX License List 3.25 + | LGPL_3_0_linking_exception -- ^ @LGPL-3.0-linking-exception@, LGPL-3.0 Linking Exception, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Libpri_OpenH323_exception -- ^ @libpri-OpenH323-exception@, libpri OpenH323 exception, SPDX License List 3.23, SPDX License List 3.25 | Libtool_exception -- ^ @Libtool-exception@, Libtool Exception | Linux_syscall_note -- ^ @Linux-syscall-note@, Linux Syscall Note - | LLGPL -- ^ @LLGPL@, LLGPL Preamble, SPDX License List 3.23 - | LLVM_exception -- ^ @LLVM-exception@, LLVM Exception, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | LLGPL -- ^ @LLGPL@, LLGPL Preamble, SPDX License List 3.23, SPDX License List 3.25 + | LLVM_exception -- ^ @LLVM-exception@, LLVM Exception, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | LZMA_exception -- ^ @LZMA-exception@, LZMA exception | Mif_exception -- ^ @mif-exception@, Macros and Inline Functions Exception | Nokia_Qt_exception_1_1 -- ^ @Nokia-Qt-exception-1.1@, Nokia Qt LGPL exception 1.1, SPDX License List 3.0, SPDX License List 3.2 - | OCaml_LGPL_linking_exception -- ^ @OCaml-LGPL-linking-exception@, OCaml LGPL Linking Exception, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | OCaml_LGPL_linking_exception -- ^ @OCaml-LGPL-linking-exception@, OCaml LGPL Linking Exception, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | OCCT_exception_1_0 -- ^ @OCCT-exception-1.0@, Open CASCADE Exception 1.0 - | OpenJDK_assembly_exception_1_0 -- ^ @OpenJDK-assembly-exception-1.0@, OpenJDK Assembly exception 1.0, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | OpenJDK_assembly_exception_1_0 -- ^ @OpenJDK-assembly-exception-1.0@, OpenJDK Assembly exception 1.0, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | Openvpn_openssl_exception -- ^ @openvpn-openssl-exception@, OpenVPN OpenSSL Exception - | PS_or_PDF_font_exception_20170817 -- ^ @PS-or-PDF-font-exception-20170817@, PS/PDF font exception (2017-08-17), SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | QPL_1_0_INRIA_2004_exception -- ^ @QPL-1.0-INRIA-2004-exception@, INRIA QPL 1.0 2004 variant exception, SPDX License List 3.23 - | Qt_GPL_exception_1_0 -- ^ @Qt-GPL-exception-1.0@, Qt GPL exception 1.0, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | Qt_LGPL_exception_1_1 -- ^ @Qt-LGPL-exception-1.1@, Qt LGPL exception 1.1, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | PCRE2_exception -- ^ @PCRE2-exception@, PCRE2 exception, SPDX License List 3.25 + | PS_or_PDF_font_exception_20170817 -- ^ @PS-or-PDF-font-exception-20170817@, PS/PDF font exception (2017-08-17), SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | QPL_1_0_INRIA_2004_exception -- ^ @QPL-1.0-INRIA-2004-exception@, INRIA QPL 1.0 2004 variant exception, SPDX License List 3.23, SPDX License List 3.25 + | Qt_GPL_exception_1_0 -- ^ @Qt-GPL-exception-1.0@, Qt GPL exception 1.0, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Qt_LGPL_exception_1_1 -- ^ @Qt-LGPL-exception-1.1@, Qt LGPL exception 1.1, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | Qwt_exception_1_0 -- ^ @Qwt-exception-1.0@, Qwt exception 1.0 - | SANE_exception -- ^ @SANE-exception@, SANE Exception, SPDX License List 3.23 - | SHL_2_0 -- ^ @SHL-2.0@, Solderpad Hardware License v2.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | SHL_2_1 -- ^ @SHL-2.1@, Solderpad Hardware License v2.1, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | Stunnel_exception -- ^ @stunnel-exception@, stunnel Exception, SPDX License List 3.23 - | SWI_exception -- ^ @SWI-exception@, SWI exception, SPDX License List 3.23 - | Swift_exception -- ^ @Swift-exception@, Swift Exception, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | Texinfo_exception -- ^ @Texinfo-exception@, Texinfo exception, SPDX License List 3.23 + | Romic_exception -- ^ @romic-exception@, Romic Exception, SPDX License List 3.25 + | RRDtool_FLOSS_exception_2_0 -- ^ @RRDtool-FLOSS-exception-2.0@, RRDtool FLOSS exception 2.0, SPDX License List 3.25 + | SANE_exception -- ^ @SANE-exception@, SANE Exception, SPDX License List 3.23, SPDX License List 3.25 + | SHL_2_0 -- ^ @SHL-2.0@, Solderpad Hardware License v2.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | SHL_2_1 -- ^ @SHL-2.1@, Solderpad Hardware License v2.1, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Stunnel_exception -- ^ @stunnel-exception@, stunnel Exception, SPDX License List 3.23, SPDX License List 3.25 + | SWI_exception -- ^ @SWI-exception@, SWI exception, SPDX License List 3.23, SPDX License List 3.25 + | Swift_exception -- ^ @Swift-exception@, Swift Exception, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Texinfo_exception -- ^ @Texinfo-exception@, Texinfo exception, SPDX License List 3.23, SPDX License List 3.25 | U_boot_exception_2_0 -- ^ @u-boot-exception-2.0@, U-Boot exception 2.0 - | UBDL_exception -- ^ @UBDL-exception@, Unmodified Binary Distribution exception, SPDX License List 3.23 - | Universal_FOSS_exception_1_0 -- ^ @Universal-FOSS-exception-1.0@, Universal FOSS Exception, Version 1.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | Vsftpd_openssl_exception -- ^ @vsftpd-openssl-exception@, vsftpd OpenSSL exception, SPDX License List 3.23 + | UBDL_exception -- ^ @UBDL-exception@, Unmodified Binary Distribution exception, SPDX License List 3.23, SPDX License List 3.25 + | Universal_FOSS_exception_1_0 -- ^ @Universal-FOSS-exception-1.0@, Universal FOSS Exception, Version 1.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Vsftpd_openssl_exception -- ^ @vsftpd-openssl-exception@, vsftpd OpenSSL exception, SPDX License List 3.23, SPDX License List 3.25 | WxWindows_exception_3_1 -- ^ @WxWindows-exception-3.1@, WxWindows Library Exception 3.1 - | X11vnc_openssl_exception -- ^ @x11vnc-openssl-exception@, x11vnc OpenSSL Exception, SPDX License List 3.23 + | X11vnc_openssl_exception -- ^ @x11vnc-openssl-exception@, x11vnc OpenSSL Exception, SPDX License List 3.23, SPDX License List 3.25 deriving (Eq, Ord, Enum, Bounded, Show, Read, Typeable, Data, Generic) instance Binary LicenseExceptionId where @@ -134,6 +139,7 @@ instance NFData LicenseExceptionId where licenseExceptionId :: LicenseExceptionId -> String licenseExceptionId DS389_exception = "389-exception" licenseExceptionId Asterisk_exception = "Asterisk-exception" +licenseExceptionId Asterisk_linking_protocols_exception = "Asterisk-linking-protocols-exception" licenseExceptionId Autoconf_exception_2_0 = "Autoconf-exception-2.0" licenseExceptionId Autoconf_exception_3_0 = "Autoconf-exception-3.0" licenseExceptionId Autoconf_exception_generic_3_0 = "Autoconf-exception-generic-3.0" @@ -147,6 +153,7 @@ licenseExceptionId CLISP_exception_2_0 = "CLISP-exception-2.0" licenseExceptionId Cryptsetup_OpenSSL_exception = "cryptsetup-OpenSSL-exception" licenseExceptionId DigiRule_FOSS_exception = "DigiRule-FOSS-exception" licenseExceptionId ECos_exception_2_0 = "eCos-exception-2.0" +licenseExceptionId Erlang_otp_linking_exception = "erlang-otp-linking-exception" licenseExceptionId Fawkes_Runtime_exception = "Fawkes-Runtime-exception" licenseExceptionId FLTK_exception = "FLTK-exception" licenseExceptionId Fmt_exception = "fmt-exception" @@ -181,11 +188,14 @@ licenseExceptionId OCaml_LGPL_linking_exception = "OCaml-LGPL-linking-exception" licenseExceptionId OCCT_exception_1_0 = "OCCT-exception-1.0" licenseExceptionId OpenJDK_assembly_exception_1_0 = "OpenJDK-assembly-exception-1.0" licenseExceptionId Openvpn_openssl_exception = "openvpn-openssl-exception" +licenseExceptionId PCRE2_exception = "PCRE2-exception" licenseExceptionId PS_or_PDF_font_exception_20170817 = "PS-or-PDF-font-exception-20170817" licenseExceptionId QPL_1_0_INRIA_2004_exception = "QPL-1.0-INRIA-2004-exception" licenseExceptionId Qt_GPL_exception_1_0 = "Qt-GPL-exception-1.0" licenseExceptionId Qt_LGPL_exception_1_1 = "Qt-LGPL-exception-1.1" licenseExceptionId Qwt_exception_1_0 = "Qwt-exception-1.0" +licenseExceptionId Romic_exception = "romic-exception" +licenseExceptionId RRDtool_FLOSS_exception_2_0 = "RRDtool-FLOSS-exception-2.0" licenseExceptionId SANE_exception = "SANE-exception" licenseExceptionId SHL_2_0 = "SHL-2.0" licenseExceptionId SHL_2_1 = "SHL-2.1" @@ -204,6 +214,7 @@ licenseExceptionId X11vnc_openssl_exception = "x11vnc-openssl-exception" licenseExceptionName :: LicenseExceptionId -> String licenseExceptionName DS389_exception = "389 Directory Server Exception" licenseExceptionName Asterisk_exception = "Asterisk exception" +licenseExceptionName Asterisk_linking_protocols_exception = "Asterisk linking protocols exception" licenseExceptionName Autoconf_exception_2_0 = "Autoconf exception 2.0" licenseExceptionName Autoconf_exception_3_0 = "Autoconf exception 3.0" licenseExceptionName Autoconf_exception_generic_3_0 = "Autoconf generic exception for GPL-3.0" @@ -217,6 +228,7 @@ licenseExceptionName CLISP_exception_2_0 = "CLISP exception 2.0" licenseExceptionName Cryptsetup_OpenSSL_exception = "cryptsetup OpenSSL exception" licenseExceptionName DigiRule_FOSS_exception = "DigiRule FOSS License Exception" licenseExceptionName ECos_exception_2_0 = "eCos exception 2.0" +licenseExceptionName Erlang_otp_linking_exception = "Erlang/OTP Linking Exception" licenseExceptionName Fawkes_Runtime_exception = "Fawkes Runtime Exception" licenseExceptionName FLTK_exception = "FLTK exception" licenseExceptionName Fmt_exception = "fmt exception" @@ -251,11 +263,14 @@ licenseExceptionName OCaml_LGPL_linking_exception = "OCaml LGPL Linking Exceptio licenseExceptionName OCCT_exception_1_0 = "Open CASCADE Exception 1.0" licenseExceptionName OpenJDK_assembly_exception_1_0 = "OpenJDK Assembly exception 1.0" licenseExceptionName Openvpn_openssl_exception = "OpenVPN OpenSSL Exception" +licenseExceptionName PCRE2_exception = "PCRE2 exception" licenseExceptionName PS_or_PDF_font_exception_20170817 = "PS/PDF font exception (2017-08-17)" licenseExceptionName QPL_1_0_INRIA_2004_exception = "INRIA QPL 1.0 2004 variant exception" licenseExceptionName Qt_GPL_exception_1_0 = "Qt GPL exception 1.0" licenseExceptionName Qt_LGPL_exception_1_1 = "Qt LGPL exception 1.1" licenseExceptionName Qwt_exception_1_0 = "Qwt exception 1.0" +licenseExceptionName Romic_exception = "Romic Exception" +licenseExceptionName RRDtool_FLOSS_exception_2_0 = "RRDtool FLOSS exception 2.0" licenseExceptionName SANE_exception = "SANE Exception" licenseExceptionName SHL_2_0 = "Solderpad Hardware License v2.0" licenseExceptionName SHL_2_1 = "Solderpad Hardware License v2.1" @@ -394,6 +409,54 @@ licenseExceptionIdList LicenseListVersion_3_23 = , X11vnc_openssl_exception ] ++ bulkOfLicenses +licenseExceptionIdList LicenseListVersion_3_25 = + [ Asterisk_exception + , Asterisk_linking_protocols_exception + , Autoconf_exception_generic_3_0 + , Autoconf_exception_generic + , Autoconf_exception_macro + , Bison_exception_1_24 + , Cryptsetup_OpenSSL_exception + , Erlang_otp_linking_exception + , Fmt_exception + , GCC_exception_2_0_note + , Gmsh_exception + , GNAT_exception + , GNOME_examples_exception + , GNU_compiler_exception + , GPL_3_0_interface_exception + , GPL_3_0_linking_exception + , GPL_3_0_linking_source_exception + , GPL_CC_1_0 + , GStreamer_exception_2005 + , GStreamer_exception_2008 + , KiCad_libraries_exception + , LGPL_3_0_linking_exception + , Libpri_OpenH323_exception + , LLGPL + , LLVM_exception + , OCaml_LGPL_linking_exception + , OpenJDK_assembly_exception_1_0 + , PCRE2_exception + , PS_or_PDF_font_exception_20170817 + , QPL_1_0_INRIA_2004_exception + , Qt_GPL_exception_1_0 + , Qt_LGPL_exception_1_1 + , Romic_exception + , RRDtool_FLOSS_exception_2_0 + , SANE_exception + , SHL_2_0 + , SHL_2_1 + , Stunnel_exception + , SWI_exception + , Swift_exception + , Texinfo_exception + , UBDL_exception + , Universal_FOSS_exception_1_0 + , Vsftpd_openssl_exception + , X11vnc_openssl_exception + ] + ++ bulkOfLicenses -- | Create a 'LicenseExceptionId' from a 'String'. mkLicenseExceptionId :: LicenseListVersion -> String -> Maybe LicenseExceptionId @@ -404,6 +467,7 @@ mkLicenseExceptionId LicenseListVersion_3_9 s = Map.lookup s stringLookup_3_9 mkLicenseExceptionId LicenseListVersion_3_10 s = Map.lookup s stringLookup_3_10 mkLicenseExceptionId LicenseListVersion_3_16 s = Map.lookup s stringLookup_3_16 mkLicenseExceptionId LicenseListVersion_3_23 s = Map.lookup s stringLookup_3_23 +mkLicenseExceptionId LicenseListVersion_3_25 s = Map.lookup s stringLookup_3_25 stringLookup_3_0 :: Map String LicenseExceptionId stringLookup_3_0 = Map.fromList $ map (\i -> (licenseExceptionId i, i)) $ @@ -433,6 +497,10 @@ stringLookup_3_23 :: Map String LicenseExceptionId stringLookup_3_23 = Map.fromList $ map (\i -> (licenseExceptionId i, i)) $ licenseExceptionIdList LicenseListVersion_3_23 +stringLookup_3_25 :: Map String LicenseExceptionId +stringLookup_3_25 = Map.fromList $ map (\i -> (licenseExceptionId i, i)) $ + licenseExceptionIdList LicenseListVersion_3_25 + -- | License exceptions in all SPDX License lists bulkOfLicenses :: [LicenseExceptionId] bulkOfLicenses = diff --git a/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs b/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs index 5af7fd86e8b..16421e475f9 100644 --- a/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs +++ b/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs @@ -33,16 +33,17 @@ import qualified Text.PrettyPrint as Disp -- LicenseId ------------------------------------------------------------------------------- --- | SPDX License identifiers list v3.23 +-- | SPDX License identifiers list v3.25 data LicenseId = NullBSD -- ^ @0BSD@, BSD Zero Clause License + | X3D_Slicer_1_0 -- ^ @3D-Slicer-1.0@, 3D Slicer License v1.0, SPDX License List 3.25 | AAL -- ^ @AAL@, Attribution Assurance License | Abstyles -- ^ @Abstyles@, Abstyles License - | AdaCore_doc -- ^ @AdaCore-doc@, AdaCore Doc License, SPDX License List 3.23 + | AdaCore_doc -- ^ @AdaCore-doc@, AdaCore Doc License, SPDX License List 3.23, SPDX License List 3.25 | Adobe_2006 -- ^ @Adobe-2006@, Adobe Systems Incorporated Source Code License Agreement - | Adobe_Display_PostScript -- ^ @Adobe-Display-PostScript@, Adobe Display PostScript License, SPDX License List 3.23 + | Adobe_Display_PostScript -- ^ @Adobe-Display-PostScript@, Adobe Display PostScript License, SPDX License List 3.23, SPDX License List 3.25 | Adobe_Glyph -- ^ @Adobe-Glyph@, Adobe Glyph List License - | Adobe_Utopia -- ^ @Adobe-Utopia@, Adobe Utopia Font License, SPDX License List 3.23 + | Adobe_Utopia -- ^ @Adobe-Utopia@, Adobe Utopia Font License, SPDX License List 3.23, SPDX License List 3.25 | ADSL -- ^ @ADSL@, Amazon Digital Services License | AFL_1_1 -- ^ @AFL-1.1@, Academic Free License v1.1 | AFL_1_2 -- ^ @AFL-1.2@, Academic Free License v1.2 @@ -51,151 +52,155 @@ data LicenseId | AFL_3_0 -- ^ @AFL-3.0@, Academic Free License v3.0 | Afmparse -- ^ @Afmparse@, Afmparse License | AGPL_1_0 -- ^ @AGPL-1.0@, Affero General Public License v1.0, SPDX License List 3.0 - | AGPL_1_0_only -- ^ @AGPL-1.0-only@, Affero General Public License v1.0 only, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | AGPL_1_0_or_later -- ^ @AGPL-1.0-or-later@, Affero General Public License v1.0 or later, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | AGPL_1_0_only -- ^ @AGPL-1.0-only@, Affero General Public License v1.0 only, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | AGPL_1_0_or_later -- ^ @AGPL-1.0-or-later@, Affero General Public License v1.0 or later, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | AGPL_3_0_only -- ^ @AGPL-3.0-only@, GNU Affero General Public License v3.0 only | AGPL_3_0_or_later -- ^ @AGPL-3.0-or-later@, GNU Affero General Public License v3.0 or later | Aladdin -- ^ @Aladdin@, Aladdin Free Public License + | AMD_newlib -- ^ @AMD-newlib@, AMD newlib License, SPDX License List 3.25 | AMDPLPA -- ^ @AMDPLPA@, AMD's plpa_map.c License - | AML_glslang -- ^ @AML-glslang@, AML glslang variant License, SPDX License List 3.23 + | AML_glslang -- ^ @AML-glslang@, AML glslang variant License, SPDX License List 3.23, SPDX License List 3.25 | AML -- ^ @AML@, Apple MIT License | AMPAS -- ^ @AMPAS@, Academy of Motion Picture Arts and Sciences BSD - | ANTLR_PD_fallback -- ^ @ANTLR-PD-fallback@, ANTLR Software Rights Notice with license fallback, SPDX License List 3.16, SPDX License List 3.23 + | ANTLR_PD_fallback -- ^ @ANTLR-PD-fallback@, ANTLR Software Rights Notice with license fallback, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | ANTLR_PD -- ^ @ANTLR-PD@, ANTLR Software Rights Notice + | Any_OSI -- ^ @any-OSI@, Any OSI License, SPDX License List 3.25 | Apache_1_0 -- ^ @Apache-1.0@, Apache License 1.0 | Apache_1_1 -- ^ @Apache-1.1@, Apache License 1.1 | Apache_2_0 -- ^ @Apache-2.0@, Apache License 2.0 | APAFML -- ^ @APAFML@, Adobe Postscript AFM License | APL_1_0 -- ^ @APL-1.0@, Adaptive Public License 1.0 - | App_s2p -- ^ @App-s2p@, App::s2p License, SPDX License List 3.16, SPDX License List 3.23 + | App_s2p -- ^ @App-s2p@, App::s2p License, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | APSL_1_0 -- ^ @APSL-1.0@, Apple Public Source License 1.0 | APSL_1_1 -- ^ @APSL-1.1@, Apple Public Source License 1.1 | APSL_1_2 -- ^ @APSL-1.2@, Apple Public Source License 1.2 | APSL_2_0 -- ^ @APSL-2.0@, Apple Public Source License 2.0 - | Arphic_1999 -- ^ @Arphic-1999@, Arphic Public License, SPDX License List 3.23 + | Arphic_1999 -- ^ @Arphic-1999@, Arphic Public License, SPDX License List 3.23, SPDX License List 3.25 | Artistic_1_0_cl8 -- ^ @Artistic-1.0-cl8@, Artistic License 1.0 w/clause 8 | Artistic_1_0_Perl -- ^ @Artistic-1.0-Perl@, Artistic License 1.0 (Perl) | Artistic_1_0 -- ^ @Artistic-1.0@, Artistic License 1.0 | Artistic_2_0 -- ^ @Artistic-2.0@, Artistic License 2.0 - | ASWF_Digital_Assets_1_0 -- ^ @ASWF-Digital-Assets-1.0@, ASWF Digital Assets License version 1.0, SPDX License List 3.23 - | ASWF_Digital_Assets_1_1 -- ^ @ASWF-Digital-Assets-1.1@, ASWF Digital Assets License 1.1, SPDX License List 3.23 - | Baekmuk -- ^ @Baekmuk@, Baekmuk License, SPDX License List 3.23 + | ASWF_Digital_Assets_1_0 -- ^ @ASWF-Digital-Assets-1.0@, ASWF Digital Assets License version 1.0, SPDX License List 3.23, SPDX License List 3.25 + | ASWF_Digital_Assets_1_1 -- ^ @ASWF-Digital-Assets-1.1@, ASWF Digital Assets License 1.1, SPDX License List 3.23, SPDX License List 3.25 + | Baekmuk -- ^ @Baekmuk@, Baekmuk License, SPDX License List 3.23, SPDX License List 3.25 | Bahyph -- ^ @Bahyph@, Bahyph License | Barr -- ^ @Barr@, Barr License - | Bcrypt_Solar_Designer -- ^ @bcrypt-Solar-Designer@, bcrypt Solar Designer License, SPDX License List 3.23 + | Bcrypt_Solar_Designer -- ^ @bcrypt-Solar-Designer@, bcrypt Solar Designer License, SPDX License List 3.23, SPDX License List 3.25 | Beerware -- ^ @Beerware@, Beerware License - | Bitstream_Charter -- ^ @Bitstream-Charter@, Bitstream Charter Font License, SPDX License List 3.23 - | Bitstream_Vera -- ^ @Bitstream-Vera@, Bitstream Vera Font License, SPDX License List 3.23 + | Bitstream_Charter -- ^ @Bitstream-Charter@, Bitstream Charter Font License, SPDX License List 3.23, SPDX License List 3.25 + | Bitstream_Vera -- ^ @Bitstream-Vera@, Bitstream Vera Font License, SPDX License List 3.23, SPDX License List 3.25 | BitTorrent_1_0 -- ^ @BitTorrent-1.0@, BitTorrent Open Source License v1.0 | BitTorrent_1_1 -- ^ @BitTorrent-1.1@, BitTorrent Open Source License v1.1 - | Blessing -- ^ @blessing@, SQLite Blessing, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | BlueOak_1_0_0 -- ^ @BlueOak-1.0.0@, Blue Oak Model License 1.0.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | Boehm_GC -- ^ @Boehm-GC@, Boehm-Demers-Weiser GC License, SPDX License List 3.23 + | Blessing -- ^ @blessing@, SQLite Blessing, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | BlueOak_1_0_0 -- ^ @BlueOak-1.0.0@, Blue Oak Model License 1.0.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Boehm_GC -- ^ @Boehm-GC@, Boehm-Demers-Weiser GC License, SPDX License List 3.23, SPDX License List 3.25 | Borceux -- ^ @Borceux@, Borceux license - | Brian_Gladman_2_Clause -- ^ @Brian-Gladman-2-Clause@, Brian Gladman 2-Clause License, SPDX License List 3.23 - | Brian_Gladman_3_Clause -- ^ @Brian-Gladman-3-Clause@, Brian Gladman 3-Clause License, SPDX License List 3.23 + | Brian_Gladman_2_Clause -- ^ @Brian-Gladman-2-Clause@, Brian Gladman 2-Clause License, SPDX License List 3.23, SPDX License List 3.25 + | Brian_Gladman_3_Clause -- ^ @Brian-Gladman-3-Clause@, Brian Gladman 3-Clause License, SPDX License List 3.23, SPDX License List 3.25 | BSD_1_Clause -- ^ @BSD-1-Clause@, BSD 1-Clause License | BSD_2_Clause_FreeBSD -- ^ @BSD-2-Clause-FreeBSD@, BSD 2-Clause FreeBSD License, SPDX License List 3.0, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9 | BSD_2_Clause_NetBSD -- ^ @BSD-2-Clause-NetBSD@, BSD 2-Clause NetBSD License, SPDX License List 3.0, SPDX License List 3.2, SPDX License List 3.6 - | BSD_2_Clause_Darwin -- ^ @BSD-2-Clause-Darwin@, BSD 2-Clause - Ian Darwin variant, SPDX License List 3.23 + | BSD_2_Clause_Darwin -- ^ @BSD-2-Clause-Darwin@, BSD 2-Clause - Ian Darwin variant, SPDX License List 3.23, SPDX License List 3.25 + | BSD_2_Clause_first_lines -- ^ @BSD-2-Clause-first-lines@, BSD 2-Clause - first lines requirement, SPDX License List 3.25 | BSD_2_Clause_Patent -- ^ @BSD-2-Clause-Patent@, BSD-2-Clause Plus Patent License - | BSD_2_Clause_Views -- ^ @BSD-2-Clause-Views@, BSD 2-Clause with views sentence, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | BSD_2_Clause_Views -- ^ @BSD-2-Clause-Views@, BSD 2-Clause with views sentence, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | BSD_2_Clause -- ^ @BSD-2-Clause@, BSD 2-Clause "Simplified" License - | BSD_3_Clause_acpica -- ^ @BSD-3-Clause-acpica@, BSD 3-Clause acpica variant, SPDX License List 3.23 + | BSD_3_Clause_acpica -- ^ @BSD-3-Clause-acpica@, BSD 3-Clause acpica variant, SPDX License List 3.23, SPDX License List 3.25 | BSD_3_Clause_Attribution -- ^ @BSD-3-Clause-Attribution@, BSD with attribution | BSD_3_Clause_Clear -- ^ @BSD-3-Clause-Clear@, BSD 3-Clause Clear License - | BSD_3_Clause_flex -- ^ @BSD-3-Clause-flex@, BSD 3-Clause Flex variant, SPDX License List 3.23 - | BSD_3_Clause_HP -- ^ @BSD-3-Clause-HP@, Hewlett-Packard BSD variant license, SPDX License List 3.23 + | BSD_3_Clause_flex -- ^ @BSD-3-Clause-flex@, BSD 3-Clause Flex variant, SPDX License List 3.23, SPDX License List 3.25 + | BSD_3_Clause_HP -- ^ @BSD-3-Clause-HP@, Hewlett-Packard BSD variant license, SPDX License List 3.23, SPDX License List 3.25 | BSD_3_Clause_LBNL -- ^ @BSD-3-Clause-LBNL@, Lawrence Berkeley National Labs BSD variant license - | BSD_3_Clause_Modification -- ^ @BSD-3-Clause-Modification@, BSD 3-Clause Modification, SPDX License List 3.16, SPDX License List 3.23 - | BSD_3_Clause_No_Military_License -- ^ @BSD-3-Clause-No-Military-License@, BSD 3-Clause No Military License, SPDX License List 3.16, SPDX License List 3.23 + | BSD_3_Clause_Modification -- ^ @BSD-3-Clause-Modification@, BSD 3-Clause Modification, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | BSD_3_Clause_No_Military_License -- ^ @BSD-3-Clause-No-Military-License@, BSD 3-Clause No Military License, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | BSD_3_Clause_No_Nuclear_License_2014 -- ^ @BSD-3-Clause-No-Nuclear-License-2014@, BSD 3-Clause No Nuclear License 2014 | BSD_3_Clause_No_Nuclear_License -- ^ @BSD-3-Clause-No-Nuclear-License@, BSD 3-Clause No Nuclear License | BSD_3_Clause_No_Nuclear_Warranty -- ^ @BSD-3-Clause-No-Nuclear-Warranty@, BSD 3-Clause No Nuclear Warranty - | BSD_3_Clause_Open_MPI -- ^ @BSD-3-Clause-Open-MPI@, BSD 3-Clause Open MPI variant, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | BSD_3_Clause_Sun -- ^ @BSD-3-Clause-Sun@, BSD 3-Clause Sun Microsystems, SPDX License List 3.23 + | BSD_3_Clause_Open_MPI -- ^ @BSD-3-Clause-Open-MPI@, BSD 3-Clause Open MPI variant, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | BSD_3_Clause_Sun -- ^ @BSD-3-Clause-Sun@, BSD 3-Clause Sun Microsystems, SPDX License List 3.23, SPDX License List 3.25 | BSD_3_Clause -- ^ @BSD-3-Clause@, BSD 3-Clause "New" or "Revised" License - | BSD_4_Clause_Shortened -- ^ @BSD-4-Clause-Shortened@, BSD 4 Clause Shortened, SPDX License List 3.16, SPDX License List 3.23 + | BSD_4_Clause_Shortened -- ^ @BSD-4-Clause-Shortened@, BSD 4 Clause Shortened, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | BSD_4_Clause_UC -- ^ @BSD-4-Clause-UC@, BSD-4-Clause (University of California-Specific) | BSD_4_Clause -- ^ @BSD-4-Clause@, BSD 4-Clause "Original" or "Old" License - | BSD_4_3RENO -- ^ @BSD-4.3RENO@, BSD 4.3 RENO License, SPDX License List 3.23 - | BSD_4_3TAHOE -- ^ @BSD-4.3TAHOE@, BSD 4.3 TAHOE License, SPDX License List 3.23 - | BSD_Advertising_Acknowledgement -- ^ @BSD-Advertising-Acknowledgement@, BSD Advertising Acknowledgement License, SPDX License List 3.23 - | BSD_Attribution_HPND_disclaimer -- ^ @BSD-Attribution-HPND-disclaimer@, BSD with Attribution and HPND disclaimer, SPDX License List 3.23 - | BSD_Inferno_Nettverk -- ^ @BSD-Inferno-Nettverk@, BSD-Inferno-Nettverk, SPDX License List 3.23 + | BSD_4_3RENO -- ^ @BSD-4.3RENO@, BSD 4.3 RENO License, SPDX License List 3.23, SPDX License List 3.25 + | BSD_4_3TAHOE -- ^ @BSD-4.3TAHOE@, BSD 4.3 TAHOE License, SPDX License List 3.23, SPDX License List 3.25 + | BSD_Advertising_Acknowledgement -- ^ @BSD-Advertising-Acknowledgement@, BSD Advertising Acknowledgement License, SPDX License List 3.23, SPDX License List 3.25 + | BSD_Attribution_HPND_disclaimer -- ^ @BSD-Attribution-HPND-disclaimer@, BSD with Attribution and HPND disclaimer, SPDX License List 3.23, SPDX License List 3.25 + | BSD_Inferno_Nettverk -- ^ @BSD-Inferno-Nettverk@, BSD-Inferno-Nettverk, SPDX License List 3.23, SPDX License List 3.25 | BSD_Protection -- ^ @BSD-Protection@, BSD Protection License - | BSD_Source_beginning_file -- ^ @BSD-Source-beginning-file@, BSD Source Code Attribution - beginning of file variant, SPDX License List 3.23 + | BSD_Source_beginning_file -- ^ @BSD-Source-beginning-file@, BSD Source Code Attribution - beginning of file variant, SPDX License List 3.23, SPDX License List 3.25 | BSD_Source_Code -- ^ @BSD-Source-Code@, BSD Source Code Attribution - | BSD_Systemics_W3Works -- ^ @BSD-Systemics-W3Works@, Systemics W3Works BSD variant license, SPDX License List 3.23 - | BSD_Systemics -- ^ @BSD-Systemics@, Systemics BSD variant license, SPDX License List 3.23 + | BSD_Systemics_W3Works -- ^ @BSD-Systemics-W3Works@, Systemics W3Works BSD variant license, SPDX License List 3.23, SPDX License List 3.25 + | BSD_Systemics -- ^ @BSD-Systemics@, Systemics BSD variant license, SPDX License List 3.23, SPDX License List 3.25 | BSL_1_0 -- ^ @BSL-1.0@, Boost Software License 1.0 | Bzip2_1_0_5 -- ^ @bzip2-1.0.5@, bzip2 and libbzip2 License v1.0.5, SPDX License List 3.0, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10 - | BUSL_1_1 -- ^ @BUSL-1.1@, Business Source License 1.1, SPDX License List 3.16, SPDX License List 3.23 + | BUSL_1_1 -- ^ @BUSL-1.1@, Business Source License 1.1, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | Bzip2_1_0_6 -- ^ @bzip2-1.0.6@, bzip2 and libbzip2 License v1.0.6 - | C_UDA_1_0 -- ^ @C-UDA-1.0@, Computational Use of Data Agreement v1.0, SPDX License List 3.16, SPDX License List 3.23 - | CAL_1_0_Combined_Work_Exception -- ^ @CAL-1.0-Combined-Work-Exception@, Cryptographic Autonomy License 1.0 (Combined Work Exception), SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | CAL_1_0 -- ^ @CAL-1.0@, Cryptographic Autonomy License 1.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | Caldera_no_preamble -- ^ @Caldera-no-preamble@, Caldera License (without preamble), SPDX License List 3.23 + | C_UDA_1_0 -- ^ @C-UDA-1.0@, Computational Use of Data Agreement v1.0, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | CAL_1_0_Combined_Work_Exception -- ^ @CAL-1.0-Combined-Work-Exception@, Cryptographic Autonomy License 1.0 (Combined Work Exception), SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | CAL_1_0 -- ^ @CAL-1.0@, Cryptographic Autonomy License 1.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Caldera_no_preamble -- ^ @Caldera-no-preamble@, Caldera License (without preamble), SPDX License List 3.23, SPDX License List 3.25 | Caldera -- ^ @Caldera@, Caldera License + | Catharon -- ^ @Catharon@, Catharon License, SPDX License List 3.25 | CATOSL_1_1 -- ^ @CATOSL-1.1@, Computer Associates Trusted Open Source License 1.1 | CC_BY_1_0 -- ^ @CC-BY-1.0@, Creative Commons Attribution 1.0 Generic | CC_BY_2_0 -- ^ @CC-BY-2.0@, Creative Commons Attribution 2.0 Generic - | CC_BY_2_5_AU -- ^ @CC-BY-2.5-AU@, Creative Commons Attribution 2.5 Australia, SPDX License List 3.16, SPDX License List 3.23 + | CC_BY_2_5_AU -- ^ @CC-BY-2.5-AU@, Creative Commons Attribution 2.5 Australia, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | CC_BY_2_5 -- ^ @CC-BY-2.5@, Creative Commons Attribution 2.5 Generic - | CC_BY_3_0_AT -- ^ @CC-BY-3.0-AT@, Creative Commons Attribution 3.0 Austria, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | CC_BY_3_0_AU -- ^ @CC-BY-3.0-AU@, Creative Commons Attribution 3.0 Australia, SPDX License List 3.23 - | CC_BY_3_0_DE -- ^ @CC-BY-3.0-DE@, Creative Commons Attribution 3.0 Germany, SPDX License List 3.16, SPDX License List 3.23 - | CC_BY_3_0_IGO -- ^ @CC-BY-3.0-IGO@, Creative Commons Attribution 3.0 IGO, SPDX License List 3.23 - | CC_BY_3_0_NL -- ^ @CC-BY-3.0-NL@, Creative Commons Attribution 3.0 Netherlands, SPDX License List 3.16, SPDX License List 3.23 - | CC_BY_3_0_US -- ^ @CC-BY-3.0-US@, Creative Commons Attribution 3.0 United States, SPDX License List 3.16, SPDX License List 3.23 + | CC_BY_3_0_AT -- ^ @CC-BY-3.0-AT@, Creative Commons Attribution 3.0 Austria, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | CC_BY_3_0_AU -- ^ @CC-BY-3.0-AU@, Creative Commons Attribution 3.0 Australia, SPDX License List 3.23, SPDX License List 3.25 + | CC_BY_3_0_DE -- ^ @CC-BY-3.0-DE@, Creative Commons Attribution 3.0 Germany, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | CC_BY_3_0_IGO -- ^ @CC-BY-3.0-IGO@, Creative Commons Attribution 3.0 IGO, SPDX License List 3.23, SPDX License List 3.25 + | CC_BY_3_0_NL -- ^ @CC-BY-3.0-NL@, Creative Commons Attribution 3.0 Netherlands, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | CC_BY_3_0_US -- ^ @CC-BY-3.0-US@, Creative Commons Attribution 3.0 United States, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | CC_BY_3_0 -- ^ @CC-BY-3.0@, Creative Commons Attribution 3.0 Unported | CC_BY_4_0 -- ^ @CC-BY-4.0@, Creative Commons Attribution 4.0 International | CC_BY_NC_1_0 -- ^ @CC-BY-NC-1.0@, Creative Commons Attribution Non Commercial 1.0 Generic | CC_BY_NC_2_0 -- ^ @CC-BY-NC-2.0@, Creative Commons Attribution Non Commercial 2.0 Generic | CC_BY_NC_2_5 -- ^ @CC-BY-NC-2.5@, Creative Commons Attribution Non Commercial 2.5 Generic - | CC_BY_NC_3_0_DE -- ^ @CC-BY-NC-3.0-DE@, Creative Commons Attribution Non Commercial 3.0 Germany, SPDX License List 3.16, SPDX License List 3.23 + | CC_BY_NC_3_0_DE -- ^ @CC-BY-NC-3.0-DE@, Creative Commons Attribution Non Commercial 3.0 Germany, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | CC_BY_NC_3_0 -- ^ @CC-BY-NC-3.0@, Creative Commons Attribution Non Commercial 3.0 Unported | CC_BY_NC_4_0 -- ^ @CC-BY-NC-4.0@, Creative Commons Attribution Non Commercial 4.0 International | CC_BY_NC_ND_1_0 -- ^ @CC-BY-NC-ND-1.0@, Creative Commons Attribution Non Commercial No Derivatives 1.0 Generic | CC_BY_NC_ND_2_0 -- ^ @CC-BY-NC-ND-2.0@, Creative Commons Attribution Non Commercial No Derivatives 2.0 Generic | CC_BY_NC_ND_2_5 -- ^ @CC-BY-NC-ND-2.5@, Creative Commons Attribution Non Commercial No Derivatives 2.5 Generic - | CC_BY_NC_ND_3_0_DE -- ^ @CC-BY-NC-ND-3.0-DE@, Creative Commons Attribution Non Commercial No Derivatives 3.0 Germany, SPDX License List 3.16, SPDX License List 3.23 - | CC_BY_NC_ND_3_0_IGO -- ^ @CC-BY-NC-ND-3.0-IGO@, Creative Commons Attribution Non Commercial No Derivatives 3.0 IGO, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | CC_BY_NC_ND_3_0_DE -- ^ @CC-BY-NC-ND-3.0-DE@, Creative Commons Attribution Non Commercial No Derivatives 3.0 Germany, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | CC_BY_NC_ND_3_0_IGO -- ^ @CC-BY-NC-ND-3.0-IGO@, Creative Commons Attribution Non Commercial No Derivatives 3.0 IGO, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | CC_BY_NC_ND_3_0 -- ^ @CC-BY-NC-ND-3.0@, Creative Commons Attribution Non Commercial No Derivatives 3.0 Unported | CC_BY_NC_ND_4_0 -- ^ @CC-BY-NC-ND-4.0@, Creative Commons Attribution Non Commercial No Derivatives 4.0 International | CC_BY_NC_SA_1_0 -- ^ @CC-BY-NC-SA-1.0@, Creative Commons Attribution Non Commercial Share Alike 1.0 Generic - | CC_BY_NC_SA_2_0_DE -- ^ @CC-BY-NC-SA-2.0-DE@, Creative Commons Attribution Non Commercial Share Alike 2.0 Germany, SPDX License List 3.23 - | CC_BY_NC_SA_2_0_FR -- ^ @CC-BY-NC-SA-2.0-FR@, Creative Commons Attribution-NonCommercial-ShareAlike 2.0 France, SPDX License List 3.16, SPDX License List 3.23 - | CC_BY_NC_SA_2_0_UK -- ^ @CC-BY-NC-SA-2.0-UK@, Creative Commons Attribution Non Commercial Share Alike 2.0 England and Wales, SPDX License List 3.16, SPDX License List 3.23 + | CC_BY_NC_SA_2_0_DE -- ^ @CC-BY-NC-SA-2.0-DE@, Creative Commons Attribution Non Commercial Share Alike 2.0 Germany, SPDX License List 3.23, SPDX License List 3.25 + | CC_BY_NC_SA_2_0_FR -- ^ @CC-BY-NC-SA-2.0-FR@, Creative Commons Attribution-NonCommercial-ShareAlike 2.0 France, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | CC_BY_NC_SA_2_0_UK -- ^ @CC-BY-NC-SA-2.0-UK@, Creative Commons Attribution Non Commercial Share Alike 2.0 England and Wales, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | CC_BY_NC_SA_2_0 -- ^ @CC-BY-NC-SA-2.0@, Creative Commons Attribution Non Commercial Share Alike 2.0 Generic | CC_BY_NC_SA_2_5 -- ^ @CC-BY-NC-SA-2.5@, Creative Commons Attribution Non Commercial Share Alike 2.5 Generic - | CC_BY_NC_SA_3_0_DE -- ^ @CC-BY-NC-SA-3.0-DE@, Creative Commons Attribution Non Commercial Share Alike 3.0 Germany, SPDX License List 3.16, SPDX License List 3.23 - | CC_BY_NC_SA_3_0_IGO -- ^ @CC-BY-NC-SA-3.0-IGO@, Creative Commons Attribution Non Commercial Share Alike 3.0 IGO, SPDX License List 3.16, SPDX License List 3.23 + | CC_BY_NC_SA_3_0_DE -- ^ @CC-BY-NC-SA-3.0-DE@, Creative Commons Attribution Non Commercial Share Alike 3.0 Germany, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | CC_BY_NC_SA_3_0_IGO -- ^ @CC-BY-NC-SA-3.0-IGO@, Creative Commons Attribution Non Commercial Share Alike 3.0 IGO, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | CC_BY_NC_SA_3_0 -- ^ @CC-BY-NC-SA-3.0@, Creative Commons Attribution Non Commercial Share Alike 3.0 Unported | CC_BY_NC_SA_4_0 -- ^ @CC-BY-NC-SA-4.0@, Creative Commons Attribution Non Commercial Share Alike 4.0 International | CC_BY_ND_1_0 -- ^ @CC-BY-ND-1.0@, Creative Commons Attribution No Derivatives 1.0 Generic | CC_BY_ND_2_0 -- ^ @CC-BY-ND-2.0@, Creative Commons Attribution No Derivatives 2.0 Generic | CC_BY_ND_2_5 -- ^ @CC-BY-ND-2.5@, Creative Commons Attribution No Derivatives 2.5 Generic - | CC_BY_ND_3_0_DE -- ^ @CC-BY-ND-3.0-DE@, Creative Commons Attribution No Derivatives 3.0 Germany, SPDX License List 3.16, SPDX License List 3.23 + | CC_BY_ND_3_0_DE -- ^ @CC-BY-ND-3.0-DE@, Creative Commons Attribution No Derivatives 3.0 Germany, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | CC_BY_ND_3_0 -- ^ @CC-BY-ND-3.0@, Creative Commons Attribution No Derivatives 3.0 Unported | CC_BY_ND_4_0 -- ^ @CC-BY-ND-4.0@, Creative Commons Attribution No Derivatives 4.0 International | CC_BY_SA_1_0 -- ^ @CC-BY-SA-1.0@, Creative Commons Attribution Share Alike 1.0 Generic - | CC_BY_SA_2_0_UK -- ^ @CC-BY-SA-2.0-UK@, Creative Commons Attribution Share Alike 2.0 England and Wales, SPDX License List 3.16, SPDX License List 3.23 + | CC_BY_SA_2_0_UK -- ^ @CC-BY-SA-2.0-UK@, Creative Commons Attribution Share Alike 2.0 England and Wales, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | CC_BY_SA_2_0 -- ^ @CC-BY-SA-2.0@, Creative Commons Attribution Share Alike 2.0 Generic - | CC_BY_SA_2_1_JP -- ^ @CC-BY-SA-2.1-JP@, Creative Commons Attribution Share Alike 2.1 Japan, SPDX License List 3.16, SPDX License List 3.23 + | CC_BY_SA_2_1_JP -- ^ @CC-BY-SA-2.1-JP@, Creative Commons Attribution Share Alike 2.1 Japan, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | CC_BY_SA_2_5 -- ^ @CC-BY-SA-2.5@, Creative Commons Attribution Share Alike 2.5 Generic - | CC_BY_SA_3_0_AT -- ^ @CC-BY-SA-3.0-AT@, Creative Commons Attribution Share Alike 3.0 Austria, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | CC_BY_SA_3_0_DE -- ^ @CC-BY-SA-3.0-DE@, Creative Commons Attribution Share Alike 3.0 Germany, SPDX License List 3.16, SPDX License List 3.23 - | CC_BY_SA_3_0_IGO -- ^ @CC-BY-SA-3.0-IGO@, Creative Commons Attribution-ShareAlike 3.0 IGO, SPDX License List 3.23 + | CC_BY_SA_3_0_AT -- ^ @CC-BY-SA-3.0-AT@, Creative Commons Attribution Share Alike 3.0 Austria, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | CC_BY_SA_3_0_DE -- ^ @CC-BY-SA-3.0-DE@, Creative Commons Attribution Share Alike 3.0 Germany, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | CC_BY_SA_3_0_IGO -- ^ @CC-BY-SA-3.0-IGO@, Creative Commons Attribution-ShareAlike 3.0 IGO, SPDX License List 3.23, SPDX License List 3.25 | CC_BY_SA_3_0 -- ^ @CC-BY-SA-3.0@, Creative Commons Attribution Share Alike 3.0 Unported | CC_BY_SA_4_0 -- ^ @CC-BY-SA-4.0@, Creative Commons Attribution Share Alike 4.0 International - | CC_PDDC -- ^ @CC-PDDC@, Creative Commons Public Domain Dedication and Certification, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | CC_PDDC -- ^ @CC-PDDC@, Creative Commons Public Domain Dedication and Certification, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | CC0_1_0 -- ^ @CC0-1.0@, Creative Commons Zero v1.0 Universal | CDDL_1_0 -- ^ @CDDL-1.0@, Common Development and Distribution License 1.0 | CDDL_1_1 -- ^ @CDDL-1.1@, Common Development and Distribution License 1.1 - | CDL_1_0 -- ^ @CDL-1.0@, Common Documentation License 1.0, SPDX License List 3.16, SPDX License List 3.23 + | CDL_1_0 -- ^ @CDL-1.0@, Common Documentation License 1.0, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | CDLA_Permissive_1_0 -- ^ @CDLA-Permissive-1.0@, Community Data License Agreement Permissive 1.0 - | CDLA_Permissive_2_0 -- ^ @CDLA-Permissive-2.0@, Community Data License Agreement Permissive 2.0, SPDX License List 3.16, SPDX License List 3.23 + | CDLA_Permissive_2_0 -- ^ @CDLA-Permissive-2.0@, Community Data License Agreement Permissive 2.0, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | CDLA_Sharing_1_0 -- ^ @CDLA-Sharing-1.0@, Community Data License Agreement Sharing 1.0 | CECILL_1_0 -- ^ @CECILL-1.0@, CeCILL Free Software License Agreement v1.0 | CECILL_1_1 -- ^ @CECILL-1.1@, CeCILL Free Software License Agreement v1.1 @@ -203,105 +208,108 @@ data LicenseId | CECILL_2_1 -- ^ @CECILL-2.1@, CeCILL Free Software License Agreement v2.1 | CECILL_B -- ^ @CECILL-B@, CeCILL-B Free Software License Agreement | CECILL_C -- ^ @CECILL-C@, CeCILL-C Free Software License Agreement - | CERN_OHL_1_1 -- ^ @CERN-OHL-1.1@, CERN Open Hardware Licence v1.1, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | CERN_OHL_1_2 -- ^ @CERN-OHL-1.2@, CERN Open Hardware Licence v1.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | CERN_OHL_P_2_0 -- ^ @CERN-OHL-P-2.0@, CERN Open Hardware Licence Version 2 - Permissive, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | CERN_OHL_S_2_0 -- ^ @CERN-OHL-S-2.0@, CERN Open Hardware Licence Version 2 - Strongly Reciprocal, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | CERN_OHL_W_2_0 -- ^ @CERN-OHL-W-2.0@, CERN Open Hardware Licence Version 2 - Weakly Reciprocal, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | CFITSIO -- ^ @CFITSIO@, CFITSIO License, SPDX License List 3.23 - | Check_cvs -- ^ @check-cvs@, check-cvs License, SPDX License List 3.23 - | Checkmk -- ^ @checkmk@, Checkmk License, SPDX License List 3.23 + | CERN_OHL_1_1 -- ^ @CERN-OHL-1.1@, CERN Open Hardware Licence v1.1, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | CERN_OHL_1_2 -- ^ @CERN-OHL-1.2@, CERN Open Hardware Licence v1.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | CERN_OHL_P_2_0 -- ^ @CERN-OHL-P-2.0@, CERN Open Hardware Licence Version 2 - Permissive, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | CERN_OHL_S_2_0 -- ^ @CERN-OHL-S-2.0@, CERN Open Hardware Licence Version 2 - Strongly Reciprocal, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | CERN_OHL_W_2_0 -- ^ @CERN-OHL-W-2.0@, CERN Open Hardware Licence Version 2 - Weakly Reciprocal, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | CFITSIO -- ^ @CFITSIO@, CFITSIO License, SPDX License List 3.23, SPDX License List 3.25 + | Check_cvs -- ^ @check-cvs@, check-cvs License, SPDX License List 3.23, SPDX License List 3.25 + | Checkmk -- ^ @checkmk@, Checkmk License, SPDX License List 3.23, SPDX License List 3.25 | ClArtistic -- ^ @ClArtistic@, Clarified Artistic License - | Clips -- ^ @Clips@, Clips License, SPDX License List 3.23 - | CMU_Mach_nodoc -- ^ @CMU-Mach-nodoc@, CMU Mach - no notices-in-documentation variant, SPDX License List 3.23 - | CMU_Mach -- ^ @CMU-Mach@, CMU Mach License, SPDX License List 3.23 + | Clips -- ^ @Clips@, Clips License, SPDX License List 3.23, SPDX License List 3.25 + | CMU_Mach_nodoc -- ^ @CMU-Mach-nodoc@, CMU Mach - no notices-in-documentation variant, SPDX License List 3.23, SPDX License List 3.25 + | CMU_Mach -- ^ @CMU-Mach@, CMU Mach License, SPDX License List 3.23, SPDX License List 3.25 | CNRI_Jython -- ^ @CNRI-Jython@, CNRI Jython License | CNRI_Python_GPL_Compatible -- ^ @CNRI-Python-GPL-Compatible@, CNRI Python Open Source GPL Compatible License Agreement | CNRI_Python -- ^ @CNRI-Python@, CNRI Python License - | COIL_1_0 -- ^ @COIL-1.0@, Copyfree Open Innovation License, SPDX License List 3.16, SPDX License List 3.23 - | Community_Spec_1_0 -- ^ @Community-Spec-1.0@, Community Specification License 1.0, SPDX License List 3.16, SPDX License List 3.23 + | COIL_1_0 -- ^ @COIL-1.0@, Copyfree Open Innovation License, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Community_Spec_1_0 -- ^ @Community-Spec-1.0@, Community Specification License 1.0, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | Condor_1_1 -- ^ @Condor-1.1@, Condor Public License v1.1 - | Copyleft_next_0_3_0 -- ^ @copyleft-next-0.3.0@, copyleft-next 0.3.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | Copyleft_next_0_3_1 -- ^ @copyleft-next-0.3.1@, copyleft-next 0.3.1, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | Cornell_Lossless_JPEG -- ^ @Cornell-Lossless-JPEG@, Cornell Lossless JPEG License, SPDX License List 3.23 + | Copyleft_next_0_3_0 -- ^ @copyleft-next-0.3.0@, copyleft-next 0.3.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Copyleft_next_0_3_1 -- ^ @copyleft-next-0.3.1@, copyleft-next 0.3.1, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Cornell_Lossless_JPEG -- ^ @Cornell-Lossless-JPEG@, Cornell Lossless JPEG License, SPDX License List 3.23, SPDX License List 3.25 | CPAL_1_0 -- ^ @CPAL-1.0@, Common Public Attribution License 1.0 | CPL_1_0 -- ^ @CPL-1.0@, Common Public License 1.0 | CPOL_1_02 -- ^ @CPOL-1.02@, Code Project Open License 1.02 - | Cronyx -- ^ @Cronyx@, Cronyx License, SPDX License List 3.23 + | Cronyx -- ^ @Cronyx@, Cronyx License, SPDX License List 3.23, SPDX License List 3.25 | Crossword -- ^ @Crossword@, Crossword License | CrystalStacker -- ^ @CrystalStacker@, CrystalStacker License | CUA_OPL_1_0 -- ^ @CUA-OPL-1.0@, CUA Office Public License v1.0 | Cube -- ^ @Cube@, Cube License | Curl -- ^ @curl@, curl License + | Cve_tou -- ^ @cve-tou@, Common Vulnerability Enumeration ToU License, SPDX License List 3.25 | D_FSL_1_0 -- ^ @D-FSL-1.0@, Deutsche Freie Software Lizenz - | DEC_3_Clause -- ^ @DEC-3-Clause@, DEC 3-Clause License, SPDX License List 3.23 + | DEC_3_Clause -- ^ @DEC-3-Clause@, DEC 3-Clause License, SPDX License List 3.23, SPDX License List 3.25 | Diffmark -- ^ @diffmark@, diffmark license - | DL_DE_BY_2_0 -- ^ @DL-DE-BY-2.0@, Data licence Germany – attribution – version 2.0, SPDX License List 3.16, SPDX License List 3.23 - | DL_DE_ZERO_2_0 -- ^ @DL-DE-ZERO-2.0@, Data licence Germany – zero – version 2.0, SPDX License List 3.23 + | DL_DE_BY_2_0 -- ^ @DL-DE-BY-2.0@, Data licence Germany – attribution – version 2.0, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | DL_DE_ZERO_2_0 -- ^ @DL-DE-ZERO-2.0@, Data licence Germany – zero – version 2.0, SPDX License List 3.23, SPDX License List 3.25 + | DocBook_Schema -- ^ @DocBook-Schema@, DocBook Schema License, SPDX License List 3.25 + | DocBook_XML -- ^ @DocBook-XML@, DocBook XML License, SPDX License List 3.25 | DOC -- ^ @DOC@, DOC License | Dotseqn -- ^ @Dotseqn@, Dotseqn License - | DRL_1_0 -- ^ @DRL-1.0@, Detection Rule License 1.0, SPDX License List 3.16, SPDX License List 3.23 - | DRL_1_1 -- ^ @DRL-1.1@, Detection Rule License 1.1, SPDX License List 3.23 + | DRL_1_0 -- ^ @DRL-1.0@, Detection Rule License 1.0, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | DRL_1_1 -- ^ @DRL-1.1@, Detection Rule License 1.1, SPDX License List 3.23, SPDX License List 3.25 | DSDP -- ^ @DSDP@, DSDP License - | Dtoa -- ^ @dtoa@, David M. Gay dtoa License, SPDX License List 3.23 + | Dtoa -- ^ @dtoa@, David M. Gay dtoa License, SPDX License List 3.23, SPDX License List 3.25 | Dvipdfm -- ^ @dvipdfm@, dvipdfm License | ECL_1_0 -- ^ @ECL-1.0@, Educational Community License v1.0 | ECL_2_0 -- ^ @ECL-2.0@, Educational Community License v2.0 | EFL_1_0 -- ^ @EFL-1.0@, Eiffel Forum License v1.0 | EFL_2_0 -- ^ @EFL-2.0@, Eiffel Forum License v2.0 | EGenix -- ^ @eGenix@, eGenix.com Public License 1.1.0 - | Elastic_2_0 -- ^ @Elastic-2.0@, Elastic License 2.0, SPDX License List 3.16, SPDX License List 3.23 + | Elastic_2_0 -- ^ @Elastic-2.0@, Elastic License 2.0, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | Entessa -- ^ @Entessa@, Entessa Public License v1.0 - | EPICS -- ^ @EPICS@, EPICS Open License, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | EPICS -- ^ @EPICS@, EPICS Open License, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | EPL_1_0 -- ^ @EPL-1.0@, Eclipse Public License 1.0 | EPL_2_0 -- ^ @EPL-2.0@, Eclipse Public License 2.0 | ErlPL_1_1 -- ^ @ErlPL-1.1@, Erlang Public License v1.1 - | Etalab_2_0 -- ^ @etalab-2.0@, Etalab Open License 2.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | Etalab_2_0 -- ^ @etalab-2.0@, Etalab Open License 2.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | EUDatagrid -- ^ @EUDatagrid@, EU DataGrid Software License | EUPL_1_0 -- ^ @EUPL-1.0@, European Union Public License 1.0 | EUPL_1_1 -- ^ @EUPL-1.1@, European Union Public License 1.1 | EUPL_1_2 -- ^ @EUPL-1.2@, European Union Public License 1.2 | Eurosym -- ^ @Eurosym@, Eurosym License | Fair -- ^ @Fair@, Fair License - | FBM -- ^ @FBM@, Fuzzy Bitmap License, SPDX License List 3.23 - | FDK_AAC -- ^ @FDK-AAC@, Fraunhofer FDK AAC Codec Library, SPDX License List 3.16, SPDX License List 3.23 - | Ferguson_Twofish -- ^ @Ferguson-Twofish@, Ferguson Twofish License, SPDX License List 3.23 + | FBM -- ^ @FBM@, Fuzzy Bitmap License, SPDX License List 3.23, SPDX License List 3.25 + | FDK_AAC -- ^ @FDK-AAC@, Fraunhofer FDK AAC Codec Library, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Ferguson_Twofish -- ^ @Ferguson-Twofish@, Ferguson Twofish License, SPDX License List 3.23, SPDX License List 3.25 | Frameworx_1_0 -- ^ @Frameworx-1.0@, Frameworx Open License 1.0 - | FreeBSD_DOC -- ^ @FreeBSD-DOC@, FreeBSD Documentation License, SPDX License List 3.16, SPDX License List 3.23 + | FreeBSD_DOC -- ^ @FreeBSD-DOC@, FreeBSD Documentation License, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | FreeImage -- ^ @FreeImage@, FreeImage Public License v1.0 - | FSFAP_no_warranty_disclaimer -- ^ @FSFAP-no-warranty-disclaimer@, FSF All Permissive License (without Warranty), SPDX License List 3.23 + | FSFAP_no_warranty_disclaimer -- ^ @FSFAP-no-warranty-disclaimer@, FSF All Permissive License (without Warranty), SPDX License List 3.23, SPDX License List 3.25 | FSFAP -- ^ @FSFAP@, FSF All Permissive License - | FSFULLRWD -- ^ @FSFULLRWD@, FSF Unlimited License (With License Retention and Warranty Disclaimer), SPDX License List 3.23 + | FSFULLRWD -- ^ @FSFULLRWD@, FSF Unlimited License (With License Retention and Warranty Disclaimer), SPDX License List 3.23, SPDX License List 3.25 | FSFULLR -- ^ @FSFULLR@, FSF Unlimited License (with License Retention) | FSFUL -- ^ @FSFUL@, FSF Unlimited License | FTL -- ^ @FTL@, Freetype Project License - | Furuseth -- ^ @Furuseth@, Furuseth License, SPDX License List 3.23 - | Fwlw -- ^ @fwlw@, fwlw License, SPDX License List 3.23 - | GCR_docs -- ^ @GCR-docs@, Gnome GCR Documentation License, SPDX License List 3.23 - | GD -- ^ @GD@, GD License, SPDX License List 3.16, SPDX License List 3.23 - | GFDL_1_1_invariants_only -- ^ @GFDL-1.1-invariants-only@, GNU Free Documentation License v1.1 only - invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | GFDL_1_1_invariants_or_later -- ^ @GFDL-1.1-invariants-or-later@, GNU Free Documentation License v1.1 or later - invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | GFDL_1_1_no_invariants_only -- ^ @GFDL-1.1-no-invariants-only@, GNU Free Documentation License v1.1 only - no invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | GFDL_1_1_no_invariants_or_later -- ^ @GFDL-1.1-no-invariants-or-later@, GNU Free Documentation License v1.1 or later - no invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | Furuseth -- ^ @Furuseth@, Furuseth License, SPDX License List 3.23, SPDX License List 3.25 + | Fwlw -- ^ @fwlw@, fwlw License, SPDX License List 3.23, SPDX License List 3.25 + | GCR_docs -- ^ @GCR-docs@, Gnome GCR Documentation License, SPDX License List 3.23, SPDX License List 3.25 + | GD -- ^ @GD@, GD License, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | GFDL_1_1_invariants_only -- ^ @GFDL-1.1-invariants-only@, GNU Free Documentation License v1.1 only - invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | GFDL_1_1_invariants_or_later -- ^ @GFDL-1.1-invariants-or-later@, GNU Free Documentation License v1.1 or later - invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | GFDL_1_1_no_invariants_only -- ^ @GFDL-1.1-no-invariants-only@, GNU Free Documentation License v1.1 only - no invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | GFDL_1_1_no_invariants_or_later -- ^ @GFDL-1.1-no-invariants-or-later@, GNU Free Documentation License v1.1 or later - no invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | GFDL_1_1_only -- ^ @GFDL-1.1-only@, GNU Free Documentation License v1.1 only | GFDL_1_1_or_later -- ^ @GFDL-1.1-or-later@, GNU Free Documentation License v1.1 or later - | GFDL_1_2_invariants_only -- ^ @GFDL-1.2-invariants-only@, GNU Free Documentation License v1.2 only - invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | GFDL_1_2_invariants_or_later -- ^ @GFDL-1.2-invariants-or-later@, GNU Free Documentation License v1.2 or later - invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | GFDL_1_2_no_invariants_only -- ^ @GFDL-1.2-no-invariants-only@, GNU Free Documentation License v1.2 only - no invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | GFDL_1_2_no_invariants_or_later -- ^ @GFDL-1.2-no-invariants-or-later@, GNU Free Documentation License v1.2 or later - no invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | GFDL_1_2_invariants_only -- ^ @GFDL-1.2-invariants-only@, GNU Free Documentation License v1.2 only - invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | GFDL_1_2_invariants_or_later -- ^ @GFDL-1.2-invariants-or-later@, GNU Free Documentation License v1.2 or later - invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | GFDL_1_2_no_invariants_only -- ^ @GFDL-1.2-no-invariants-only@, GNU Free Documentation License v1.2 only - no invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | GFDL_1_2_no_invariants_or_later -- ^ @GFDL-1.2-no-invariants-or-later@, GNU Free Documentation License v1.2 or later - no invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | GFDL_1_2_only -- ^ @GFDL-1.2-only@, GNU Free Documentation License v1.2 only | GFDL_1_2_or_later -- ^ @GFDL-1.2-or-later@, GNU Free Documentation License v1.2 or later - | GFDL_1_3_invariants_only -- ^ @GFDL-1.3-invariants-only@, GNU Free Documentation License v1.3 only - invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | GFDL_1_3_invariants_or_later -- ^ @GFDL-1.3-invariants-or-later@, GNU Free Documentation License v1.3 or later - invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | GFDL_1_3_no_invariants_only -- ^ @GFDL-1.3-no-invariants-only@, GNU Free Documentation License v1.3 only - no invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | GFDL_1_3_no_invariants_or_later -- ^ @GFDL-1.3-no-invariants-or-later@, GNU Free Documentation License v1.3 or later - no invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | GFDL_1_3_invariants_only -- ^ @GFDL-1.3-invariants-only@, GNU Free Documentation License v1.3 only - invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | GFDL_1_3_invariants_or_later -- ^ @GFDL-1.3-invariants-or-later@, GNU Free Documentation License v1.3 or later - invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | GFDL_1_3_no_invariants_only -- ^ @GFDL-1.3-no-invariants-only@, GNU Free Documentation License v1.3 only - no invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | GFDL_1_3_no_invariants_or_later -- ^ @GFDL-1.3-no-invariants-or-later@, GNU Free Documentation License v1.3 or later - no invariants, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | GFDL_1_3_only -- ^ @GFDL-1.3-only@, GNU Free Documentation License v1.3 only | GFDL_1_3_or_later -- ^ @GFDL-1.3-or-later@, GNU Free Documentation License v1.3 or later | Giftware -- ^ @Giftware@, Giftware License | GL2PS -- ^ @GL2PS@, GL2PS License | Glide -- ^ @Glide@, 3dfx Glide License | Glulxe -- ^ @Glulxe@, Glulxe License - | GLWTPL -- ^ @GLWTPL@, Good Luck With That Public License, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | GLWTPL -- ^ @GLWTPL@, Good Luck With That Public License, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | Gnuplot -- ^ @gnuplot@, gnuplot License | GPL_1_0_only -- ^ @GPL-1.0-only@, GNU General Public License v1.0 only | GPL_1_0_or_later -- ^ @GPL-1.0-or-later@, GNU General Public License v1.0 or later @@ -309,60 +317,69 @@ data LicenseId | GPL_2_0_or_later -- ^ @GPL-2.0-or-later@, GNU General Public License v2.0 or later | GPL_3_0_only -- ^ @GPL-3.0-only@, GNU General Public License v3.0 only | GPL_3_0_or_later -- ^ @GPL-3.0-or-later@, GNU General Public License v3.0 or later - | Graphics_Gems -- ^ @Graphics-Gems@, Graphics Gems License, SPDX License List 3.23 + | Graphics_Gems -- ^ @Graphics-Gems@, Graphics Gems License, SPDX License List 3.23, SPDX License List 3.25 | GSOAP_1_3b -- ^ @gSOAP-1.3b@, gSOAP Public License v1.3b - | Gtkbook -- ^ @gtkbook@, gtkbook License, SPDX License List 3.23 + | Gtkbook -- ^ @gtkbook@, gtkbook License, SPDX License List 3.23, SPDX License List 3.25 + | Gutmann -- ^ @Gutmann@, Gutmann License, SPDX License List 3.25 | HaskellReport -- ^ @HaskellReport@, Haskell Language Report License - | Hdparm -- ^ @hdparm@, hdparm License, SPDX License List 3.23 - | Hippocratic_2_1 -- ^ @Hippocratic-2.1@, Hippocratic License 2.1, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | HP_1986 -- ^ @HP-1986@, Hewlett-Packard 1986 License, SPDX License List 3.23 - | HP_1989 -- ^ @HP-1989@, Hewlett-Packard 1989 License, SPDX License List 3.23 - | HPND_DEC -- ^ @HPND-DEC@, Historical Permission Notice and Disclaimer - DEC variant, SPDX License List 3.23 - | HPND_doc_sell -- ^ @HPND-doc-sell@, Historical Permission Notice and Disclaimer - documentation sell variant, SPDX License List 3.23 - | HPND_doc -- ^ @HPND-doc@, Historical Permission Notice and Disclaimer - documentation variant, SPDX License List 3.23 - | HPND_export_US_modify -- ^ @HPND-export-US-modify@, HPND with US Government export control warning and modification rqmt, SPDX License List 3.23 - | HPND_export_US -- ^ @HPND-export-US@, HPND with US Government export control warning, SPDX License List 3.23 - | HPND_Fenneberg_Livingston -- ^ @HPND-Fenneberg-Livingston@, Historical Permission Notice and Disclaimer - Fenneberg-Livingston variant, SPDX License List 3.23 - | HPND_INRIA_IMAG -- ^ @HPND-INRIA-IMAG@, Historical Permission Notice and Disclaimer - INRIA-IMAG variant, SPDX License List 3.23 - | HPND_Kevlin_Henney -- ^ @HPND-Kevlin-Henney@, Historical Permission Notice and Disclaimer - Kevlin Henney variant, SPDX License List 3.23 - | HPND_Markus_Kuhn -- ^ @HPND-Markus-Kuhn@, Historical Permission Notice and Disclaimer - Markus Kuhn variant, SPDX License List 3.23 - | HPND_MIT_disclaimer -- ^ @HPND-MIT-disclaimer@, Historical Permission Notice and Disclaimer with MIT disclaimer, SPDX License List 3.23 - | HPND_Pbmplus -- ^ @HPND-Pbmplus@, Historical Permission Notice and Disclaimer - Pbmplus variant, SPDX License List 3.23 - | HPND_sell_MIT_disclaimer_xserver -- ^ @HPND-sell-MIT-disclaimer-xserver@, Historical Permission Notice and Disclaimer - sell xserver variant with MIT disclaimer, SPDX License List 3.23 - | HPND_sell_regexpr -- ^ @HPND-sell-regexpr@, Historical Permission Notice and Disclaimer - sell regexpr variant, SPDX License List 3.23 - | HPND_sell_variant_MIT_disclaimer -- ^ @HPND-sell-variant-MIT-disclaimer@, HPND sell variant with MIT disclaimer, SPDX License List 3.23 - | HPND_sell_variant -- ^ @HPND-sell-variant@, Historical Permission Notice and Disclaimer - sell variant, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | HPND_UC -- ^ @HPND-UC@, Historical Permission Notice and Disclaimer - University of California variant, SPDX License List 3.23 + | Hdparm -- ^ @hdparm@, hdparm License, SPDX License List 3.23, SPDX License List 3.25 + | HIDAPI -- ^ @HIDAPI@, HIDAPI License, SPDX License List 3.25 + | Hippocratic_2_1 -- ^ @Hippocratic-2.1@, Hippocratic License 2.1, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | HP_1986 -- ^ @HP-1986@, Hewlett-Packard 1986 License, SPDX License List 3.23, SPDX License List 3.25 + | HP_1989 -- ^ @HP-1989@, Hewlett-Packard 1989 License, SPDX License List 3.23, SPDX License List 3.25 + | HPND_DEC -- ^ @HPND-DEC@, Historical Permission Notice and Disclaimer - DEC variant, SPDX License List 3.23, SPDX License List 3.25 + | HPND_doc_sell -- ^ @HPND-doc-sell@, Historical Permission Notice and Disclaimer - documentation sell variant, SPDX License List 3.23, SPDX License List 3.25 + | HPND_doc -- ^ @HPND-doc@, Historical Permission Notice and Disclaimer - documentation variant, SPDX License List 3.23, SPDX License List 3.25 + | HPND_export_US_acknowledgement -- ^ @HPND-export-US-acknowledgement@, HPND with US Government export control warning and acknowledgment, SPDX License List 3.25 + | HPND_export_US_modify -- ^ @HPND-export-US-modify@, HPND with US Government export control warning and modification rqmt, SPDX License List 3.23, SPDX License List 3.25 + | HPND_export_US -- ^ @HPND-export-US@, HPND with US Government export control warning, SPDX License List 3.23, SPDX License List 3.25 + | HPND_export2_US -- ^ @HPND-export2-US@, HPND with US Government export control and 2 disclaimers, SPDX License List 3.25 + | HPND_Fenneberg_Livingston -- ^ @HPND-Fenneberg-Livingston@, Historical Permission Notice and Disclaimer - Fenneberg-Livingston variant, SPDX License List 3.23, SPDX License List 3.25 + | HPND_INRIA_IMAG -- ^ @HPND-INRIA-IMAG@, Historical Permission Notice and Disclaimer - INRIA-IMAG variant, SPDX License List 3.23, SPDX License List 3.25 + | HPND_Intel -- ^ @HPND-Intel@, Historical Permission Notice and Disclaimer - Intel variant, SPDX License List 3.25 + | HPND_Kevlin_Henney -- ^ @HPND-Kevlin-Henney@, Historical Permission Notice and Disclaimer - Kevlin Henney variant, SPDX License List 3.23, SPDX License List 3.25 + | HPND_Markus_Kuhn -- ^ @HPND-Markus-Kuhn@, Historical Permission Notice and Disclaimer - Markus Kuhn variant, SPDX License List 3.23, SPDX License List 3.25 + | HPND_merchantability_variant -- ^ @HPND-merchantability-variant@, Historical Permission Notice and Disclaimer - merchantability variant, SPDX License List 3.25 + | HPND_MIT_disclaimer -- ^ @HPND-MIT-disclaimer@, Historical Permission Notice and Disclaimer with MIT disclaimer, SPDX License List 3.23, SPDX License List 3.25 + | HPND_Netrek -- ^ @HPND-Netrek@, Historical Permission Notice and Disclaimer - Netrek variant, SPDX License List 3.25 + | HPND_Pbmplus -- ^ @HPND-Pbmplus@, Historical Permission Notice and Disclaimer - Pbmplus variant, SPDX License List 3.23, SPDX License List 3.25 + | HPND_sell_MIT_disclaimer_xserver -- ^ @HPND-sell-MIT-disclaimer-xserver@, Historical Permission Notice and Disclaimer - sell xserver variant with MIT disclaimer, SPDX License List 3.23, SPDX License List 3.25 + | HPND_sell_regexpr -- ^ @HPND-sell-regexpr@, Historical Permission Notice and Disclaimer - sell regexpr variant, SPDX License List 3.23, SPDX License List 3.25 + | HPND_sell_variant_MIT_disclaimer_rev -- ^ @HPND-sell-variant-MIT-disclaimer-rev@, HPND sell variant with MIT disclaimer - reverse, SPDX License List 3.25 + | HPND_sell_variant_MIT_disclaimer -- ^ @HPND-sell-variant-MIT-disclaimer@, HPND sell variant with MIT disclaimer, SPDX License List 3.23, SPDX License List 3.25 + | HPND_sell_variant -- ^ @HPND-sell-variant@, Historical Permission Notice and Disclaimer - sell variant, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | HPND_UC_export_US -- ^ @HPND-UC-export-US@, Historical Permission Notice and Disclaimer - University of California, US export warning, SPDX License List 3.25 + | HPND_UC -- ^ @HPND-UC@, Historical Permission Notice and Disclaimer - University of California variant, SPDX License List 3.23, SPDX License List 3.25 | HPND -- ^ @HPND@, Historical Permission Notice and Disclaimer - | HTMLTIDY -- ^ @HTMLTIDY@, HTML Tidy License, SPDX License List 3.16, SPDX License List 3.23 + | HTMLTIDY -- ^ @HTMLTIDY@, HTML Tidy License, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | IBM_pibs -- ^ @IBM-pibs@, IBM PowerPC Initialization and Boot Software | ICU -- ^ @ICU@, ICU License - | IEC_Code_Components_EULA -- ^ @IEC-Code-Components-EULA@, IEC Code Components End-user licence agreement, SPDX License List 3.23 - | IJG_short -- ^ @IJG-short@, Independent JPEG Group License - short, SPDX License List 3.23 + | IEC_Code_Components_EULA -- ^ @IEC-Code-Components-EULA@, IEC Code Components End-user licence agreement, SPDX License List 3.23, SPDX License List 3.25 + | IJG_short -- ^ @IJG-short@, Independent JPEG Group License - short, SPDX License List 3.23, SPDX License List 3.25 | IJG -- ^ @IJG@, Independent JPEG Group License | ImageMagick -- ^ @ImageMagick@, ImageMagick License | IMatix -- ^ @iMatix@, iMatix Standard Function Library Agreement | Imlib2 -- ^ @Imlib2@, Imlib2 License | Info_ZIP -- ^ @Info-ZIP@, Info-ZIP License - | Inner_Net_2_0 -- ^ @Inner-Net-2.0@, Inner Net License v2.0, SPDX License List 3.23 + | Inner_Net_2_0 -- ^ @Inner-Net-2.0@, Inner Net License v2.0, SPDX License List 3.23, SPDX License List 3.25 | Intel_ACPI -- ^ @Intel-ACPI@, Intel ACPI Software License Agreement | Intel -- ^ @Intel@, Intel Open Source License | Interbase_1_0 -- ^ @Interbase-1.0@, Interbase Public License v1.0 | IPA -- ^ @IPA@, IPA Font License | IPL_1_0 -- ^ @IPL-1.0@, IBM Public License v1.0 - | ISC_Veillard -- ^ @ISC-Veillard@, ISC Veillard variant, SPDX License List 3.23 + | ISC_Veillard -- ^ @ISC-Veillard@, ISC Veillard variant, SPDX License List 3.23, SPDX License List 3.25 | ISC -- ^ @ISC@, ISC License - | Jam -- ^ @Jam@, Jam License, SPDX License List 3.16, SPDX License List 3.23 + | Jam -- ^ @Jam@, Jam License, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | JasPer_2_0 -- ^ @JasPer-2.0@, JasPer License - | JPL_image -- ^ @JPL-image@, JPL Image Use Policy, SPDX License List 3.23 - | JPNIC -- ^ @JPNIC@, Japan Network Information Center License, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | JPL_image -- ^ @JPL-image@, JPL Image Use Policy, SPDX License List 3.23, SPDX License List 3.25 + | JPNIC -- ^ @JPNIC@, Japan Network Information Center License, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | JSON -- ^ @JSON@, JSON License - | Kastrup -- ^ @Kastrup@, Kastrup License, SPDX License List 3.23 - | Kazlib -- ^ @Kazlib@, Kazlib License, SPDX License List 3.23 - | Knuth_CTAN -- ^ @Knuth-CTAN@, Knuth CTAN License, SPDX License List 3.23 + | Kastrup -- ^ @Kastrup@, Kastrup License, SPDX License List 3.23, SPDX License List 3.25 + | Kazlib -- ^ @Kazlib@, Kazlib License, SPDX License List 3.23, SPDX License List 3.25 + | Knuth_CTAN -- ^ @Knuth-CTAN@, Knuth CTAN License, SPDX License List 3.23, SPDX License List 3.25 | LAL_1_2 -- ^ @LAL-1.2@, Licence Art Libre 1.2 | LAL_1_3 -- ^ @LAL-1.3@, Licence Art Libre 1.3 - | Latex2e_translated_notice -- ^ @Latex2e-translated-notice@, Latex2e with translated notice permission, SPDX License List 3.23 + | Latex2e_translated_notice -- ^ @Latex2e-translated-notice@, Latex2e with translated notice permission, SPDX License List 3.23, SPDX License List 3.25 | Latex2e -- ^ @Latex2e@, Latex2e License | Leptonica -- ^ @Leptonica@, Leptonica License | LGPL_2_0_only -- ^ @LGPL-2.0-only@, GNU Library General Public License v2 only @@ -372,21 +389,21 @@ data LicenseId | LGPL_3_0_only -- ^ @LGPL-3.0-only@, GNU Lesser General Public License v3.0 only | LGPL_3_0_or_later -- ^ @LGPL-3.0-or-later@, GNU Lesser General Public License v3.0 or later | LGPLLR -- ^ @LGPLLR@, Lesser General Public License For Linguistic Resources - | Libpng_2_0 -- ^ @libpng-2.0@, PNG Reference Library version 2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | Libpng_2_0 -- ^ @libpng-2.0@, PNG Reference Library version 2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | Libpng -- ^ @Libpng@, libpng License - | Libselinux_1_0 -- ^ @libselinux-1.0@, libselinux public domain notice, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | Libselinux_1_0 -- ^ @libselinux-1.0@, libselinux public domain notice, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | Libtiff -- ^ @libtiff@, libtiff License - | Libutil_David_Nugent -- ^ @libutil-David-Nugent@, libutil David Nugent License, SPDX License List 3.23 + | Libutil_David_Nugent -- ^ @libutil-David-Nugent@, libutil David Nugent License, SPDX License List 3.23, SPDX License List 3.25 | LiLiQ_P_1_1 -- ^ @LiLiQ-P-1.1@, Licence Libre du Québec – Permissive version 1.1 | LiLiQ_R_1_1 -- ^ @LiLiQ-R-1.1@, Licence Libre du Québec – Réciprocité version 1.1 | LiLiQ_Rplus_1_1 -- ^ @LiLiQ-Rplus-1.1@, Licence Libre du Québec – Réciprocité forte version 1.1 - | Linux_man_pages_1_para -- ^ @Linux-man-pages-1-para@, Linux man-pages - 1 paragraph, SPDX License List 3.23 - | Linux_man_pages_copyleft_2_para -- ^ @Linux-man-pages-copyleft-2-para@, Linux man-pages Copyleft - 2 paragraphs, SPDX License List 3.23 - | Linux_man_pages_copyleft_var -- ^ @Linux-man-pages-copyleft-var@, Linux man-pages Copyleft Variant, SPDX License List 3.23 - | Linux_man_pages_copyleft -- ^ @Linux-man-pages-copyleft@, Linux man-pages Copyleft, SPDX License List 3.16, SPDX License List 3.23 - | Linux_OpenIB -- ^ @Linux-OpenIB@, Linux Kernel Variant of OpenIB.org license, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | LOOP -- ^ @LOOP@, Common Lisp LOOP License, SPDX License List 3.23 - | LPD_document -- ^ @LPD-document@, LPD Documentation License, SPDX License List 3.23 + | Linux_man_pages_1_para -- ^ @Linux-man-pages-1-para@, Linux man-pages - 1 paragraph, SPDX License List 3.23, SPDX License List 3.25 + | Linux_man_pages_copyleft_2_para -- ^ @Linux-man-pages-copyleft-2-para@, Linux man-pages Copyleft - 2 paragraphs, SPDX License List 3.23, SPDX License List 3.25 + | Linux_man_pages_copyleft_var -- ^ @Linux-man-pages-copyleft-var@, Linux man-pages Copyleft Variant, SPDX License List 3.23, SPDX License List 3.25 + | Linux_man_pages_copyleft -- ^ @Linux-man-pages-copyleft@, Linux man-pages Copyleft, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Linux_OpenIB -- ^ @Linux-OpenIB@, Linux Kernel Variant of OpenIB.org license, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | LOOP -- ^ @LOOP@, Common Lisp LOOP License, SPDX License List 3.23, SPDX License List 3.25 + | LPD_document -- ^ @LPD-document@, LPD Documentation License, SPDX License List 3.23, SPDX License List 3.25 | LPL_1_02 -- ^ @LPL-1.02@, Lucent Public License v1.02 | LPL_1_0 -- ^ @LPL-1.0@, Lucent Public License Version 1.0 | LPPL_1_0 -- ^ @LPPL-1.0@, LaTeX Project Public License v1.0 @@ -394,66 +411,69 @@ data LicenseId | LPPL_1_2 -- ^ @LPPL-1.2@, LaTeX Project Public License v1.2 | LPPL_1_3a -- ^ @LPPL-1.3a@, LaTeX Project Public License v1.3a | LPPL_1_3c -- ^ @LPPL-1.3c@, LaTeX Project Public License v1.3c - | Lsof -- ^ @lsof@, lsof License, SPDX License List 3.23 - | Lucida_Bitmap_Fonts -- ^ @Lucida-Bitmap-Fonts@, Lucida Bitmap Fonts License, SPDX License List 3.23 - | LZMA_SDK_9_11_to_9_20 -- ^ @LZMA-SDK-9.11-to-9.20@, LZMA SDK License (versions 9.11 to 9.20), SPDX License List 3.23 - | LZMA_SDK_9_22 -- ^ @LZMA-SDK-9.22@, LZMA SDK License (versions 9.22 and beyond), SPDX License List 3.23 - | Mackerras_3_Clause_acknowledgment -- ^ @Mackerras-3-Clause-acknowledgment@, Mackerras 3-Clause - acknowledgment variant, SPDX License List 3.23 - | Mackerras_3_Clause -- ^ @Mackerras-3-Clause@, Mackerras 3-Clause License, SPDX License List 3.23 - | Magaz -- ^ @magaz@, magaz License, SPDX License List 3.23 - | Mailprio -- ^ @mailprio@, mailprio License, SPDX License List 3.23 + | Lsof -- ^ @lsof@, lsof License, SPDX License List 3.23, SPDX License List 3.25 + | Lucida_Bitmap_Fonts -- ^ @Lucida-Bitmap-Fonts@, Lucida Bitmap Fonts License, SPDX License List 3.23, SPDX License List 3.25 + | LZMA_SDK_9_11_to_9_20 -- ^ @LZMA-SDK-9.11-to-9.20@, LZMA SDK License (versions 9.11 to 9.20), SPDX License List 3.23, SPDX License List 3.25 + | LZMA_SDK_9_22 -- ^ @LZMA-SDK-9.22@, LZMA SDK License (versions 9.22 and beyond), SPDX License List 3.23, SPDX License List 3.25 + | Mackerras_3_Clause_acknowledgment -- ^ @Mackerras-3-Clause-acknowledgment@, Mackerras 3-Clause - acknowledgment variant, SPDX License List 3.23, SPDX License List 3.25 + | Mackerras_3_Clause -- ^ @Mackerras-3-Clause@, Mackerras 3-Clause License, SPDX License List 3.23, SPDX License List 3.25 + | Magaz -- ^ @magaz@, magaz License, SPDX License List 3.23, SPDX License List 3.25 + | Mailprio -- ^ @mailprio@, mailprio License, SPDX License List 3.23, SPDX License List 3.25 | MakeIndex -- ^ @MakeIndex@, MakeIndex License - | Martin_Birgmeier -- ^ @Martin-Birgmeier@, Martin Birgmeier License, SPDX License List 3.23 - | McPhee_slideshow -- ^ @McPhee-slideshow@, McPhee Slideshow License, SPDX License List 3.23 - | Metamail -- ^ @metamail@, metamail License, SPDX License List 3.23 - | Minpack -- ^ @Minpack@, Minpack License, SPDX License List 3.23 + | Martin_Birgmeier -- ^ @Martin-Birgmeier@, Martin Birgmeier License, SPDX License List 3.23, SPDX License List 3.25 + | McPhee_slideshow -- ^ @McPhee-slideshow@, McPhee Slideshow License, SPDX License List 3.23, SPDX License List 3.25 + | Metamail -- ^ @metamail@, metamail License, SPDX License List 3.23, SPDX License List 3.25 + | Minpack -- ^ @Minpack@, Minpack License, SPDX License List 3.23, SPDX License List 3.25 | MirOS -- ^ @MirOS@, The MirOS Licence - | MIT_0 -- ^ @MIT-0@, MIT No Attribution, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | MIT_0 -- ^ @MIT-0@, MIT No Attribution, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | MIT_advertising -- ^ @MIT-advertising@, Enlightenment License (e16) | MIT_CMU -- ^ @MIT-CMU@, CMU License | MIT_enna -- ^ @MIT-enna@, enna License | MIT_feh -- ^ @MIT-feh@, feh License - | MIT_Festival -- ^ @MIT-Festival@, MIT Festival Variant, SPDX License List 3.23 - | MIT_Modern_Variant -- ^ @MIT-Modern-Variant@, MIT License Modern Variant, SPDX License List 3.16, SPDX License List 3.23 - | MIT_open_group -- ^ @MIT-open-group@, MIT Open Group variant, SPDX License List 3.16, SPDX License List 3.23 - | MIT_testregex -- ^ @MIT-testregex@, MIT testregex Variant, SPDX License List 3.23 - | MIT_Wu -- ^ @MIT-Wu@, MIT Tom Wu Variant, SPDX License List 3.23 + | MIT_Festival -- ^ @MIT-Festival@, MIT Festival Variant, SPDX License List 3.23, SPDX License List 3.25 + | MIT_Khronos_old -- ^ @MIT-Khronos-old@, MIT Khronos - old variant, SPDX License List 3.25 + | MIT_Modern_Variant -- ^ @MIT-Modern-Variant@, MIT License Modern Variant, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | MIT_open_group -- ^ @MIT-open-group@, MIT Open Group variant, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | MIT_testregex -- ^ @MIT-testregex@, MIT testregex Variant, SPDX License List 3.23, SPDX License List 3.25 + | MIT_Wu -- ^ @MIT-Wu@, MIT Tom Wu Variant, SPDX License List 3.23, SPDX License List 3.25 | MITNFA -- ^ @MITNFA@, MIT +no-false-attribs license | MIT -- ^ @MIT@, MIT License - | MMIXware -- ^ @MMIXware@, MMIXware License, SPDX License List 3.23 + | MMIXware -- ^ @MMIXware@, MMIXware License, SPDX License List 3.23, SPDX License List 3.25 | Motosoto -- ^ @Motosoto@, Motosoto License - | MPEG_SSG -- ^ @MPEG-SSG@, MPEG Software Simulation, SPDX License List 3.23 - | Mpi_permissive -- ^ @mpi-permissive@, mpi Permissive License, SPDX License List 3.23 + | MPEG_SSG -- ^ @MPEG-SSG@, MPEG Software Simulation, SPDX License List 3.23, SPDX License List 3.25 + | Mpi_permissive -- ^ @mpi-permissive@, mpi Permissive License, SPDX License List 3.23, SPDX License List 3.25 | Mpich2 -- ^ @mpich2@, mpich2 License | MPL_1_0 -- ^ @MPL-1.0@, Mozilla Public License 1.0 | MPL_1_1 -- ^ @MPL-1.1@, Mozilla Public License 1.1 | MPL_2_0_no_copyleft_exception -- ^ @MPL-2.0-no-copyleft-exception@, Mozilla Public License 2.0 (no copyleft exception) | MPL_2_0 -- ^ @MPL-2.0@, Mozilla Public License 2.0 - | Mplus -- ^ @mplus@, mplus Font License, SPDX License List 3.23 - | MS_LPL -- ^ @MS-LPL@, Microsoft Limited Public License, SPDX License List 3.23 + | Mplus -- ^ @mplus@, mplus Font License, SPDX License List 3.23, SPDX License List 3.25 + | MS_LPL -- ^ @MS-LPL@, Microsoft Limited Public License, SPDX License List 3.23, SPDX License List 3.25 | MS_PL -- ^ @MS-PL@, Microsoft Public License | MS_RL -- ^ @MS-RL@, Microsoft Reciprocal License | MTLL -- ^ @MTLL@, Matrix Template Library License - | MulanPSL_1_0 -- ^ @MulanPSL-1.0@, Mulan Permissive Software License, Version 1, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | MulanPSL_2_0 -- ^ @MulanPSL-2.0@, Mulan Permissive Software License, Version 2, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | MulanPSL_1_0 -- ^ @MulanPSL-1.0@, Mulan Permissive Software License, Version 1, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | MulanPSL_2_0 -- ^ @MulanPSL-2.0@, Mulan Permissive Software License, Version 2, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | Multics -- ^ @Multics@, Multics License | Mup -- ^ @Mup@, Mup License - | NAIST_2003 -- ^ @NAIST-2003@, Nara Institute of Science and Technology License (2003), SPDX License List 3.16, SPDX License List 3.23 + | NAIST_2003 -- ^ @NAIST-2003@, Nara Institute of Science and Technology License (2003), SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | NASA_1_3 -- ^ @NASA-1.3@, NASA Open Source Agreement 1.3 | Naumen -- ^ @Naumen@, Naumen Public License | NBPL_1_0 -- ^ @NBPL-1.0@, Net Boolean Public License v1 - | NCGL_UK_2_0 -- ^ @NCGL-UK-2.0@, Non-Commercial Government Licence, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | NCBI_PD -- ^ @NCBI-PD@, NCBI Public Domain Notice, SPDX License List 3.25 + | NCGL_UK_2_0 -- ^ @NCGL-UK-2.0@, Non-Commercial Government Licence, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | NCL -- ^ @NCL@, NCL Source Code License, SPDX License List 3.25 | NCSA -- ^ @NCSA@, University of Illinois/NCSA Open Source License - | Net_SNMP -- ^ @Net-SNMP@, Net-SNMP License + | Net_SNMP -- ^ @Net-SNMP@, Net-SNMP License, SPDX License List 3.0, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 | NetCDF -- ^ @NetCDF@, NetCDF license | Newsletr -- ^ @Newsletr@, Newsletr License | NGPL -- ^ @NGPL@, Nethack General Public License - | NICTA_1_0 -- ^ @NICTA-1.0@, NICTA Public Software License, Version 1.0, SPDX License List 3.23 - | NIST_PD_fallback -- ^ @NIST-PD-fallback@, NIST Public Domain Notice with license fallback, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | NIST_PD -- ^ @NIST-PD@, NIST Public Domain Notice, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | NIST_Software -- ^ @NIST-Software@, NIST Software License, SPDX License List 3.23 + | NICTA_1_0 -- ^ @NICTA-1.0@, NICTA Public Software License, Version 1.0, SPDX License List 3.23, SPDX License List 3.25 + | NIST_PD_fallback -- ^ @NIST-PD-fallback@, NIST Public Domain Notice with license fallback, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | NIST_PD -- ^ @NIST-PD@, NIST Public Domain Notice, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | NIST_Software -- ^ @NIST-Software@, NIST Software License, SPDX License List 3.23, SPDX License List 3.25 | NLOD_1_0 -- ^ @NLOD-1.0@, Norwegian Licence for Open Government Data (NLOD) 1.0 - | NLOD_2_0 -- ^ @NLOD-2.0@, Norwegian Licence for Open Government Data (NLOD) 2.0, SPDX License List 3.16, SPDX License List 3.23 + | NLOD_2_0 -- ^ @NLOD-2.0@, Norwegian Licence for Open Government Data (NLOD) 2.0, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | NLPL -- ^ @NLPL@, No Limit Public License | Nokia -- ^ @Nokia@, Nokia Open Source License | NOSL -- ^ @NOSL@, Netizen Open Source License @@ -462,26 +482,27 @@ data LicenseId | NPL_1_1 -- ^ @NPL-1.1@, Netscape Public License v1.1 | NPOSL_3_0 -- ^ @NPOSL-3.0@, Non-Profit Open Software License 3.0 | NRL -- ^ @NRL@, NRL License - | NTP_0 -- ^ @NTP-0@, NTP No Attribution, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | NTP_0 -- ^ @NTP-0@, NTP No Attribution, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | NTP -- ^ @NTP@, NTP License - | O_UDA_1_0 -- ^ @O-UDA-1.0@, Open Use of Data Agreement v1.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | O_UDA_1_0 -- ^ @O-UDA-1.0@, Open Use of Data Agreement v1.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | OAR -- ^ @OAR@, OAR License, SPDX License List 3.25 | OCCT_PL -- ^ @OCCT-PL@, Open CASCADE Technology Public License | OCLC_2_0 -- ^ @OCLC-2.0@, OCLC Research Public License 2.0 | ODbL_1_0 -- ^ @ODbL-1.0@, Open Data Commons Open Database License v1.0 - | ODC_By_1_0 -- ^ @ODC-By-1.0@, Open Data Commons Attribution License v1.0, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | OFFIS -- ^ @OFFIS@, OFFIS License, SPDX License List 3.23 - | OFL_1_0_no_RFN -- ^ @OFL-1.0-no-RFN@, SIL Open Font License 1.0 with no Reserved Font Name, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | OFL_1_0_RFN -- ^ @OFL-1.0-RFN@, SIL Open Font License 1.0 with Reserved Font Name, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | ODC_By_1_0 -- ^ @ODC-By-1.0@, Open Data Commons Attribution License v1.0, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | OFFIS -- ^ @OFFIS@, OFFIS License, SPDX License List 3.23, SPDX License List 3.25 + | OFL_1_0_no_RFN -- ^ @OFL-1.0-no-RFN@, SIL Open Font License 1.0 with no Reserved Font Name, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | OFL_1_0_RFN -- ^ @OFL-1.0-RFN@, SIL Open Font License 1.0 with Reserved Font Name, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | OFL_1_0 -- ^ @OFL-1.0@, SIL Open Font License 1.0 - | OFL_1_1_no_RFN -- ^ @OFL-1.1-no-RFN@, SIL Open Font License 1.1 with no Reserved Font Name, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | OFL_1_1_RFN -- ^ @OFL-1.1-RFN@, SIL Open Font License 1.1 with Reserved Font Name, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | OFL_1_1_no_RFN -- ^ @OFL-1.1-no-RFN@, SIL Open Font License 1.1 with no Reserved Font Name, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | OFL_1_1_RFN -- ^ @OFL-1.1-RFN@, SIL Open Font License 1.1 with Reserved Font Name, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | OFL_1_1 -- ^ @OFL-1.1@, SIL Open Font License 1.1 - | OGC_1_0 -- ^ @OGC-1.0@, OGC Software License, Version 1.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | OGDL_Taiwan_1_0 -- ^ @OGDL-Taiwan-1.0@, Taiwan Open Government Data License, version 1.0, SPDX License List 3.16, SPDX License List 3.23 - | OGL_Canada_2_0 -- ^ @OGL-Canada-2.0@, Open Government Licence - Canada, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | OGL_UK_1_0 -- ^ @OGL-UK-1.0@, Open Government Licence v1.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | OGL_UK_2_0 -- ^ @OGL-UK-2.0@, Open Government Licence v2.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | OGL_UK_3_0 -- ^ @OGL-UK-3.0@, Open Government Licence v3.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | OGC_1_0 -- ^ @OGC-1.0@, OGC Software License, Version 1.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | OGDL_Taiwan_1_0 -- ^ @OGDL-Taiwan-1.0@, Taiwan Open Government Data License, version 1.0, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | OGL_Canada_2_0 -- ^ @OGL-Canada-2.0@, Open Government Licence - Canada, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | OGL_UK_1_0 -- ^ @OGL-UK-1.0@, Open Government Licence v1.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | OGL_UK_2_0 -- ^ @OGL-UK-2.0@, Open Government Licence v2.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | OGL_UK_3_0 -- ^ @OGL-UK-3.0@, Open Government Licence v3.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | OGTSL -- ^ @OGTSL@, Open Group Test Suite License | OLDAP_1_1 -- ^ @OLDAP-1.1@, Open LDAP Public License v1.1 | OLDAP_1_2 -- ^ @OLDAP-1.2@, Open LDAP Public License v1.2 @@ -499,43 +520,45 @@ data LicenseId | OLDAP_2_6 -- ^ @OLDAP-2.6@, Open LDAP Public License v2.6 | OLDAP_2_7 -- ^ @OLDAP-2.7@, Open LDAP Public License v2.7 | OLDAP_2_8 -- ^ @OLDAP-2.8@, Open LDAP Public License v2.8 - | OLFL_1_3 -- ^ @OLFL-1.3@, Open Logistics Foundation License Version 1.3, SPDX License List 3.23 + | OLFL_1_3 -- ^ @OLFL-1.3@, Open Logistics Foundation License Version 1.3, SPDX License List 3.23, SPDX License List 3.25 | OML -- ^ @OML@, Open Market License - | OpenPBS_2_3 -- ^ @OpenPBS-2.3@, OpenPBS v2.3 Software License, SPDX License List 3.23 - | OpenSSL_standalone -- ^ @OpenSSL-standalone@, OpenSSL License - standalone, SPDX License List 3.23 + | OpenPBS_2_3 -- ^ @OpenPBS-2.3@, OpenPBS v2.3 Software License, SPDX License List 3.23, SPDX License List 3.25 + | OpenSSL_standalone -- ^ @OpenSSL-standalone@, OpenSSL License - standalone, SPDX License List 3.23, SPDX License List 3.25 | OpenSSL -- ^ @OpenSSL@, OpenSSL License - | OpenVision -- ^ @OpenVision@, OpenVision License, SPDX License List 3.23 + | OpenVision -- ^ @OpenVision@, OpenVision License, SPDX License List 3.23, SPDX License List 3.25 | OPL_1_0 -- ^ @OPL-1.0@, Open Public License v1.0 - | OPL_UK_3_0 -- ^ @OPL-UK-3.0@, United Kingdom Open Parliament Licence v3.0, SPDX License List 3.23 - | OPUBL_1_0 -- ^ @OPUBL-1.0@, Open Publication License v1.0, SPDX License List 3.16, SPDX License List 3.23 + | OPL_UK_3_0 -- ^ @OPL-UK-3.0@, United Kingdom Open Parliament Licence v3.0, SPDX License List 3.23, SPDX License List 3.25 + | OPUBL_1_0 -- ^ @OPUBL-1.0@, Open Publication License v1.0, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | OSET_PL_2_1 -- ^ @OSET-PL-2.1@, OSET Public License version 2.1 | OSL_1_0 -- ^ @OSL-1.0@, Open Software License 1.0 | OSL_1_1 -- ^ @OSL-1.1@, Open Software License 1.1 | OSL_2_0 -- ^ @OSL-2.0@, Open Software License 2.0 | OSL_2_1 -- ^ @OSL-2.1@, Open Software License 2.1 | OSL_3_0 -- ^ @OSL-3.0@, Open Software License 3.0 - | PADL -- ^ @PADL@, PADL License, SPDX License List 3.23 - | Parity_6_0_0 -- ^ @Parity-6.0.0@, The Parity Public License 6.0.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | Parity_7_0_0 -- ^ @Parity-7.0.0@, The Parity Public License 7.0.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | PADL -- ^ @PADL@, PADL License, SPDX License List 3.23, SPDX License List 3.25 + | Parity_6_0_0 -- ^ @Parity-6.0.0@, The Parity Public License 6.0.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Parity_7_0_0 -- ^ @Parity-7.0.0@, The Parity Public License 7.0.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | PDDL_1_0 -- ^ @PDDL-1.0@, Open Data Commons Public Domain Dedication & License 1.0 | PHP_3_01 -- ^ @PHP-3.01@, PHP License v3.01 | PHP_3_0 -- ^ @PHP-3.0@, PHP License v3.0 - | Pixar -- ^ @Pixar@, Pixar License, SPDX License List 3.23 + | Pixar -- ^ @Pixar@, Pixar License, SPDX License List 3.23, SPDX License List 3.25 + | Pkgconf -- ^ @pkgconf@, pkgconf License, SPDX License List 3.25 | Plexus -- ^ @Plexus@, Plexus Classworlds License - | Pnmstitch -- ^ @pnmstitch@, pnmstitch License, SPDX License List 3.23 - | PolyForm_Noncommercial_1_0_0 -- ^ @PolyForm-Noncommercial-1.0.0@, PolyForm Noncommercial License 1.0.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | PolyForm_Small_Business_1_0_0 -- ^ @PolyForm-Small-Business-1.0.0@, PolyForm Small Business License 1.0.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | Pnmstitch -- ^ @pnmstitch@, pnmstitch License, SPDX License List 3.23, SPDX License List 3.25 + | PolyForm_Noncommercial_1_0_0 -- ^ @PolyForm-Noncommercial-1.0.0@, PolyForm Noncommercial License 1.0.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | PolyForm_Small_Business_1_0_0 -- ^ @PolyForm-Small-Business-1.0.0@, PolyForm Small Business License 1.0.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | PostgreSQL -- ^ @PostgreSQL@, PostgreSQL License - | PSF_2_0 -- ^ @PSF-2.0@, Python Software Foundation License 2.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | PPL -- ^ @PPL@, Peer Production License, SPDX License List 3.25 + | PSF_2_0 -- ^ @PSF-2.0@, Python Software Foundation License 2.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | Psfrag -- ^ @psfrag@, psfrag License | Psutils -- ^ @psutils@, psutils License - | Python_2_0_1 -- ^ @Python-2.0.1@, Python License 2.0.1, SPDX License List 3.23 + | Python_2_0_1 -- ^ @Python-2.0.1@, Python License 2.0.1, SPDX License List 3.23, SPDX License List 3.25 | Python_2_0 -- ^ @Python-2.0@, Python License 2.0 - | Python_ldap -- ^ @python-ldap@, Python ldap License, SPDX License List 3.23 + | Python_ldap -- ^ @python-ldap@, Python ldap License, SPDX License List 3.23, SPDX License List 3.25 | Qhull -- ^ @Qhull@, Qhull License - | QPL_1_0_INRIA_2004 -- ^ @QPL-1.0-INRIA-2004@, Q Public License 1.0 - INRIA 2004 variant, SPDX License List 3.23 + | QPL_1_0_INRIA_2004 -- ^ @QPL-1.0-INRIA-2004@, Q Public License 1.0 - INRIA 2004 variant, SPDX License List 3.23, SPDX License List 3.25 | QPL_1_0 -- ^ @QPL-1.0@, Q Public License 1.0 - | Radvd -- ^ @radvd@, radvd License, SPDX License List 3.23 + | Radvd -- ^ @radvd@, radvd License, SPDX License List 3.23, SPDX License List 3.25 | Rdisc -- ^ @Rdisc@, Rdisc License | RHeCos_1_1 -- ^ @RHeCos-1.1@, Red Hat eCos Public License v1.1 | RPL_1_1 -- ^ @RPL-1.1@, Reciprocal Public License 1.1 @@ -543,100 +566,106 @@ data LicenseId | RPSL_1_0 -- ^ @RPSL-1.0@, RealNetworks Public Source License v1.0 | RSA_MD -- ^ @RSA-MD@, RSA Message-Digest License | RSCPL -- ^ @RSCPL@, Ricoh Source Code Public License + | Ruby_pty -- ^ @Ruby-pty@, Ruby pty extension license, SPDX License List 3.25 | Ruby -- ^ @Ruby@, Ruby License - | SAX_PD_2_0 -- ^ @SAX-PD-2.0@, Sax Public Domain Notice 2.0, SPDX License List 3.23 + | SAX_PD_2_0 -- ^ @SAX-PD-2.0@, Sax Public Domain Notice 2.0, SPDX License List 3.23, SPDX License List 3.25 | SAX_PD -- ^ @SAX-PD@, Sax Public Domain Notice | Saxpath -- ^ @Saxpath@, Saxpath License | SCEA -- ^ @SCEA@, SCEA Shared Source License - | SchemeReport -- ^ @SchemeReport@, Scheme Language Report License, SPDX License List 3.16, SPDX License List 3.23 - | Sendmail_8_23 -- ^ @Sendmail-8.23@, Sendmail License 8.23, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | SchemeReport -- ^ @SchemeReport@, Scheme Language Report License, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Sendmail_8_23 -- ^ @Sendmail-8.23@, Sendmail License 8.23, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | Sendmail -- ^ @Sendmail@, Sendmail License | SGI_B_1_0 -- ^ @SGI-B-1.0@, SGI Free Software License B v1.0 | SGI_B_1_1 -- ^ @SGI-B-1.1@, SGI Free Software License B v1.1 | SGI_B_2_0 -- ^ @SGI-B-2.0@, SGI Free Software License B v2.0 - | SGI_OpenGL -- ^ @SGI-OpenGL@, SGI OpenGL License, SPDX License List 3.23 - | SGP4 -- ^ @SGP4@, SGP4 Permission Notice, SPDX License List 3.23 - | SHL_0_51 -- ^ @SHL-0.51@, Solderpad Hardware License, Version 0.51, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | SHL_0_5 -- ^ @SHL-0.5@, Solderpad Hardware License v0.5, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | SGI_OpenGL -- ^ @SGI-OpenGL@, SGI OpenGL License, SPDX License List 3.23, SPDX License List 3.25 + | SGP4 -- ^ @SGP4@, SGP4 Permission Notice, SPDX License List 3.23, SPDX License List 3.25 + | SHL_0_51 -- ^ @SHL-0.51@, Solderpad Hardware License, Version 0.51, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | SHL_0_5 -- ^ @SHL-0.5@, Solderpad Hardware License v0.5, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | SimPL_2_0 -- ^ @SimPL-2.0@, Simple Public License 2.0 | SISSL_1_2 -- ^ @SISSL-1.2@, Sun Industry Standards Source License v1.2 | SISSL -- ^ @SISSL@, Sun Industry Standards Source License v1.1 | Sleepycat -- ^ @Sleepycat@, Sleepycat License - | SL -- ^ @SL@, SL License, SPDX License List 3.23 + | SL -- ^ @SL@, SL License, SPDX License List 3.23, SPDX License List 3.25 | SMLNJ -- ^ @SMLNJ@, Standard ML of New Jersey License | SMPPL -- ^ @SMPPL@, Secure Messaging Protocol Public License | SNIA -- ^ @SNIA@, SNIA Public License 1.1 - | Snprintf -- ^ @snprintf@, snprintf License, SPDX License List 3.23 - | SoftSurfer -- ^ @softSurfer@, softSurfer License, SPDX License List 3.23 - | Soundex -- ^ @Soundex@, Soundex License, SPDX License List 3.23 + | Snprintf -- ^ @snprintf@, snprintf License, SPDX License List 3.23, SPDX License List 3.25 + | SoftSurfer -- ^ @softSurfer@, softSurfer License, SPDX License List 3.23, SPDX License List 3.25 + | Soundex -- ^ @Soundex@, Soundex License, SPDX License List 3.23, SPDX License List 3.25 | Spencer_86 -- ^ @Spencer-86@, Spencer License 86 | Spencer_94 -- ^ @Spencer-94@, Spencer License 94 | Spencer_99 -- ^ @Spencer-99@, Spencer License 99 | SPL_1_0 -- ^ @SPL-1.0@, Sun Public License v1.0 - | Ssh_keyscan -- ^ @ssh-keyscan@, ssh-keyscan License, SPDX License List 3.23 - | SSH_OpenSSH -- ^ @SSH-OpenSSH@, SSH OpenSSH license, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | SSH_short -- ^ @SSH-short@, SSH short notice, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | SSLeay_standalone -- ^ @SSLeay-standalone@, SSLeay License - standalone, SPDX License List 3.23 - | SSPL_1_0 -- ^ @SSPL-1.0@, Server Side Public License, v 1, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | Ssh_keyscan -- ^ @ssh-keyscan@, ssh-keyscan License, SPDX License List 3.23, SPDX License List 3.25 + | SSH_OpenSSH -- ^ @SSH-OpenSSH@, SSH OpenSSH license, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | SSH_short -- ^ @SSH-short@, SSH short notice, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | SSLeay_standalone -- ^ @SSLeay-standalone@, SSLeay License - standalone, SPDX License List 3.23, SPDX License List 3.25 + | SSPL_1_0 -- ^ @SSPL-1.0@, Server Side Public License, v 1, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | SugarCRM_1_1_3 -- ^ @SugarCRM-1.1.3@, SugarCRM Public License v1.1.3 - | Sun_PPP -- ^ @Sun-PPP@, Sun PPP License, SPDX License List 3.23 - | SunPro -- ^ @SunPro@, SunPro License, SPDX License List 3.23 + | Sun_PPP_2000 -- ^ @Sun-PPP-2000@, Sun PPP License (2000), SPDX License List 3.25 + | Sun_PPP -- ^ @Sun-PPP@, Sun PPP License, SPDX License List 3.23, SPDX License List 3.25 + | SunPro -- ^ @SunPro@, SunPro License, SPDX License List 3.23, SPDX License List 3.25 | SWL -- ^ @SWL@, Scheme Widget Library (SWL) Software License Agreement - | Swrule -- ^ @swrule@, swrule License, SPDX License List 3.23 - | Symlinks -- ^ @Symlinks@, Symlinks License, SPDX License List 3.23 - | TAPR_OHL_1_0 -- ^ @TAPR-OHL-1.0@, TAPR Open Hardware License v1.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 + | Swrule -- ^ @swrule@, swrule License, SPDX License List 3.23, SPDX License List 3.25 + | Symlinks -- ^ @Symlinks@, Symlinks License, SPDX License List 3.23, SPDX License List 3.25 + | TAPR_OHL_1_0 -- ^ @TAPR-OHL-1.0@, TAPR Open Hardware License v1.0, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 | TCL -- ^ @TCL@, TCL/TK License | TCP_wrappers -- ^ @TCP-wrappers@, TCP Wrappers License - | TermReadKey -- ^ @TermReadKey@, TermReadKey License, SPDX License List 3.23 - | TGPPL_1_0 -- ^ @TGPPL-1.0@, Transitive Grace Period Public Licence 1.0, SPDX License List 3.23 + | TermReadKey -- ^ @TermReadKey@, TermReadKey License, SPDX License List 3.23, SPDX License List 3.25 + | TGPPL_1_0 -- ^ @TGPPL-1.0@, Transitive Grace Period Public Licence 1.0, SPDX License List 3.23, SPDX License List 3.25 + | Threeparttable -- ^ @threeparttable@, threeparttable License, SPDX License List 3.25 | TMate -- ^ @TMate@, TMate Open Source License | TORQUE_1_1 -- ^ @TORQUE-1.1@, TORQUE v2.5+ Software License v1.1 | TOSL -- ^ @TOSL@, Trusster Open Source License - | TPDL -- ^ @TPDL@, Time::ParseDate License, SPDX License List 3.23 - | TPL_1_0 -- ^ @TPL-1.0@, THOR Public License 1.0, SPDX License List 3.23 - | TTWL -- ^ @TTWL@, Text-Tabs+Wrap License, SPDX License List 3.23 - | TTYP0 -- ^ @TTYP0@, TTYP0 License, SPDX License List 3.23 - | TU_Berlin_1_0 -- ^ @TU-Berlin-1.0@, Technische Universitaet Berlin License 1.0, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | TU_Berlin_2_0 -- ^ @TU-Berlin-2.0@, Technische Universitaet Berlin License 2.0, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | UCAR -- ^ @UCAR@, UCAR License, SPDX License List 3.23 - | UCL_1_0 -- ^ @UCL-1.0@, Upstream Compatibility License v1.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23 - | Ulem -- ^ @ulem@, ulem License, SPDX License List 3.23 - | UMich_Merit -- ^ @UMich-Merit@, Michigan/Merit Networks License, SPDX License List 3.23 - | Unicode_3_0 -- ^ @Unicode-3.0@, Unicode License v3, SPDX License List 3.23 + | TPDL -- ^ @TPDL@, Time::ParseDate License, SPDX License List 3.23, SPDX License List 3.25 + | TPL_1_0 -- ^ @TPL-1.0@, THOR Public License 1.0, SPDX License List 3.23, SPDX License List 3.25 + | TTWL -- ^ @TTWL@, Text-Tabs+Wrap License, SPDX License List 3.23, SPDX License List 3.25 + | TTYP0 -- ^ @TTYP0@, TTYP0 License, SPDX License List 3.23, SPDX License List 3.25 + | TU_Berlin_1_0 -- ^ @TU-Berlin-1.0@, Technische Universitaet Berlin License 1.0, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | TU_Berlin_2_0 -- ^ @TU-Berlin-2.0@, Technische Universitaet Berlin License 2.0, SPDX License List 3.2, SPDX License List 3.6, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Ubuntu_font_1_0 -- ^ @Ubuntu-font-1.0@, Ubuntu Font Licence v1.0, SPDX License List 3.25 + | UCAR -- ^ @UCAR@, UCAR License, SPDX License List 3.23, SPDX License List 3.25 + | UCL_1_0 -- ^ @UCL-1.0@, Upstream Compatibility License v1.0, SPDX License List 3.9, SPDX License List 3.10, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | Ulem -- ^ @ulem@, ulem License, SPDX License List 3.23, SPDX License List 3.25 + | UMich_Merit -- ^ @UMich-Merit@, Michigan/Merit Networks License, SPDX License List 3.23, SPDX License List 3.25 + | Unicode_3_0 -- ^ @Unicode-3.0@, Unicode License v3, SPDX License List 3.23, SPDX License List 3.25 | Unicode_DFS_2015 -- ^ @Unicode-DFS-2015@, Unicode License Agreement - Data Files and Software (2015) | Unicode_DFS_2016 -- ^ @Unicode-DFS-2016@, Unicode License Agreement - Data Files and Software (2016) | Unicode_TOU -- ^ @Unicode-TOU@, Unicode Terms of Use - | UnixCrypt -- ^ @UnixCrypt@, UnixCrypt License, SPDX License List 3.23 + | UnixCrypt -- ^ @UnixCrypt@, UnixCrypt License, SPDX License List 3.23, SPDX License List 3.25 | Unlicense -- ^ @Unlicense@, The Unlicense | UPL_1_0 -- ^ @UPL-1.0@, Universal Permissive License v1.0 - | URT_RLE -- ^ @URT-RLE@, Utah Raster Toolkit Run Length Encoded License, SPDX License List 3.23 + | URT_RLE -- ^ @URT-RLE@, Utah Raster Toolkit Run Length Encoded License, SPDX License List 3.23, SPDX License List 3.25 | Vim -- ^ @Vim@, Vim License | VOSTROM -- ^ @VOSTROM@, VOSTROM Public License for Open Source | VSL_1_0 -- ^ @VSL-1.0@, Vovida Software License v1.0 | W3C_19980720 -- ^ @W3C-19980720@, W3C Software Notice and License (1998-07-20) | W3C_20150513 -- ^ @W3C-20150513@, W3C Software Notice and Document License (2015-05-13) | W3C -- ^ @W3C@, W3C Software Notice and License (2002-12-31) - | W3m -- ^ @w3m@, w3m License, SPDX License List 3.23 + | W3m -- ^ @w3m@, w3m License, SPDX License List 3.23, SPDX License List 3.25 | Watcom_1_0 -- ^ @Watcom-1.0@, Sybase Open Watcom Public License 1.0 - | Widget_Workshop -- ^ @Widget-Workshop@, Widget Workshop License, SPDX License List 3.23 + | Widget_Workshop -- ^ @Widget-Workshop@, Widget Workshop License, SPDX License List 3.23, SPDX License List 3.25 | Wsuipa -- ^ @Wsuipa@, Wsuipa License | WTFPL -- ^ @WTFPL@, Do What The F*ck You Want To Public License - | X11_distribute_modifications_variant -- ^ @X11-distribute-modifications-variant@, X11 License Distribution Modification Variant, SPDX License List 3.16, SPDX License List 3.23 + | X11_distribute_modifications_variant -- ^ @X11-distribute-modifications-variant@, X11 License Distribution Modification Variant, SPDX License List 3.16, SPDX License List 3.23, SPDX License List 3.25 + | X11_swapped -- ^ @X11-swapped@, X11 swapped final paragraphs, SPDX License List 3.25 | X11 -- ^ @X11@, X11 License - | Xdebug_1_03 -- ^ @Xdebug-1.03@, Xdebug License v 1.03, SPDX License List 3.23 + | Xdebug_1_03 -- ^ @Xdebug-1.03@, Xdebug License v 1.03, SPDX License List 3.23, SPDX License List 3.25 | Xerox -- ^ @Xerox@, Xerox License - | Xfig -- ^ @Xfig@, Xfig License, SPDX License List 3.23 + | Xfig -- ^ @Xfig@, Xfig License, SPDX License List 3.23, SPDX License List 3.25 | XFree86_1_1 -- ^ @XFree86-1.1@, XFree86 License 1.1 | Xinetd -- ^ @xinetd@, xinetd License - | Xkeyboard_config_Zinoviev -- ^ @xkeyboard-config-Zinoviev@, xkeyboard-config Zinoviev License, SPDX License List 3.23 - | Xlock -- ^ @xlock@, xlock License, SPDX License List 3.23 + | Xkeyboard_config_Zinoviev -- ^ @xkeyboard-config-Zinoviev@, xkeyboard-config Zinoviev License, SPDX License List 3.23, SPDX License List 3.25 + | Xlock -- ^ @xlock@, xlock License, SPDX License List 3.23, SPDX License List 3.25 | Xnet -- ^ @Xnet@, X.Net License | Xpp -- ^ @xpp@, XPP License | XSkat -- ^ @XSkat@, XSkat License + | Xzoom -- ^ @xzoom@, xzoom License, SPDX License List 3.25 | YPL_1_0 -- ^ @YPL-1.0@, Yahoo! Public License v1.0 | YPL_1_1 -- ^ @YPL-1.1@, Yahoo! Public License v1.1 | Zed -- ^ @Zed@, Zed License - | Zeeff -- ^ @Zeeff@, Zeeff License, SPDX License List 3.23 + | Zeeff -- ^ @Zeeff@, Zeeff License, SPDX License List 3.23, SPDX License List 3.25 | Zend_2_0 -- ^ @Zend-2.0@, Zend License v2.0 | Zimbra_1_3 -- ^ @Zimbra-1.3@, Zimbra Public License v1.3 | Zimbra_1_4 -- ^ @Zimbra-1.4@, Zimbra Public License v1.4 @@ -728,6 +757,7 @@ licenseIdMigrationMessage = go where -- | License SPDX identifier, e.g. @"BSD-3-Clause"@. licenseId :: LicenseId -> String licenseId NullBSD = "0BSD" +licenseId X3D_Slicer_1_0 = "3D-Slicer-1.0" licenseId AAL = "AAL" licenseId Abstyles = "Abstyles" licenseId AdaCore_doc = "AdaCore-doc" @@ -748,12 +778,14 @@ licenseId AGPL_1_0_or_later = "AGPL-1.0-or-later" licenseId AGPL_3_0_only = "AGPL-3.0-only" licenseId AGPL_3_0_or_later = "AGPL-3.0-or-later" licenseId Aladdin = "Aladdin" +licenseId AMD_newlib = "AMD-newlib" licenseId AMDPLPA = "AMDPLPA" licenseId AML_glslang = "AML-glslang" licenseId AML = "AML" licenseId AMPAS = "AMPAS" licenseId ANTLR_PD_fallback = "ANTLR-PD-fallback" licenseId ANTLR_PD = "ANTLR-PD" +licenseId Any_OSI = "any-OSI" licenseId Apache_1_0 = "Apache-1.0" licenseId Apache_1_1 = "Apache-1.1" licenseId Apache_2_0 = "Apache-2.0" @@ -790,6 +822,7 @@ licenseId BSD_1_Clause = "BSD-1-Clause" licenseId BSD_2_Clause_FreeBSD = "BSD-2-Clause-FreeBSD" licenseId BSD_2_Clause_NetBSD = "BSD-2-Clause-NetBSD" licenseId BSD_2_Clause_Darwin = "BSD-2-Clause-Darwin" +licenseId BSD_2_Clause_first_lines = "BSD-2-Clause-first-lines" licenseId BSD_2_Clause_Patent = "BSD-2-Clause-Patent" licenseId BSD_2_Clause_Views = "BSD-2-Clause-Views" licenseId BSD_2_Clause = "BSD-2-Clause" @@ -829,6 +862,7 @@ licenseId CAL_1_0_Combined_Work_Exception = "CAL-1.0-Combined-Work-Exception" licenseId CAL_1_0 = "CAL-1.0" licenseId Caldera_no_preamble = "Caldera-no-preamble" licenseId Caldera = "Caldera" +licenseId Catharon = "Catharon" licenseId CATOSL_1_1 = "CATOSL-1.1" licenseId CC_BY_1_0 = "CC-BY-1.0" licenseId CC_BY_2_0 = "CC-BY-2.0" @@ -925,11 +959,14 @@ licenseId CrystalStacker = "CrystalStacker" licenseId CUA_OPL_1_0 = "CUA-OPL-1.0" licenseId Cube = "Cube" licenseId Curl = "curl" +licenseId Cve_tou = "cve-tou" licenseId D_FSL_1_0 = "D-FSL-1.0" licenseId DEC_3_Clause = "DEC-3-Clause" licenseId Diffmark = "diffmark" licenseId DL_DE_BY_2_0 = "DL-DE-BY-2.0" licenseId DL_DE_ZERO_2_0 = "DL-DE-ZERO-2.0" +licenseId DocBook_Schema = "DocBook-Schema" +licenseId DocBook_XML = "DocBook-XML" licenseId DOC = "DOC" licenseId Dotseqn = "Dotseqn" licenseId DRL_1_0 = "DRL-1.0" @@ -1004,26 +1041,35 @@ licenseId GPL_3_0_or_later = "GPL-3.0-or-later" licenseId Graphics_Gems = "Graphics-Gems" licenseId GSOAP_1_3b = "gSOAP-1.3b" licenseId Gtkbook = "gtkbook" +licenseId Gutmann = "Gutmann" licenseId HaskellReport = "HaskellReport" licenseId Hdparm = "hdparm" +licenseId HIDAPI = "HIDAPI" licenseId Hippocratic_2_1 = "Hippocratic-2.1" licenseId HP_1986 = "HP-1986" licenseId HP_1989 = "HP-1989" licenseId HPND_DEC = "HPND-DEC" licenseId HPND_doc_sell = "HPND-doc-sell" licenseId HPND_doc = "HPND-doc" +licenseId HPND_export_US_acknowledgement = "HPND-export-US-acknowledgement" licenseId HPND_export_US_modify = "HPND-export-US-modify" licenseId HPND_export_US = "HPND-export-US" +licenseId HPND_export2_US = "HPND-export2-US" licenseId HPND_Fenneberg_Livingston = "HPND-Fenneberg-Livingston" licenseId HPND_INRIA_IMAG = "HPND-INRIA-IMAG" +licenseId HPND_Intel = "HPND-Intel" licenseId HPND_Kevlin_Henney = "HPND-Kevlin-Henney" licenseId HPND_Markus_Kuhn = "HPND-Markus-Kuhn" +licenseId HPND_merchantability_variant = "HPND-merchantability-variant" licenseId HPND_MIT_disclaimer = "HPND-MIT-disclaimer" +licenseId HPND_Netrek = "HPND-Netrek" licenseId HPND_Pbmplus = "HPND-Pbmplus" licenseId HPND_sell_MIT_disclaimer_xserver = "HPND-sell-MIT-disclaimer-xserver" licenseId HPND_sell_regexpr = "HPND-sell-regexpr" +licenseId HPND_sell_variant_MIT_disclaimer_rev = "HPND-sell-variant-MIT-disclaimer-rev" licenseId HPND_sell_variant_MIT_disclaimer = "HPND-sell-variant-MIT-disclaimer" licenseId HPND_sell_variant = "HPND-sell-variant" +licenseId HPND_UC_export_US = "HPND-UC-export-US" licenseId HPND_UC = "HPND-UC" licenseId HPND = "HPND" licenseId HTMLTIDY = "HTMLTIDY" @@ -1106,6 +1152,7 @@ licenseId MIT_CMU = "MIT-CMU" licenseId MIT_enna = "MIT-enna" licenseId MIT_feh = "MIT-feh" licenseId MIT_Festival = "MIT-Festival" +licenseId MIT_Khronos_old = "MIT-Khronos-old" licenseId MIT_Modern_Variant = "MIT-Modern-Variant" licenseId MIT_open_group = "MIT-open-group" licenseId MIT_testregex = "MIT-testregex" @@ -1134,7 +1181,9 @@ licenseId NAIST_2003 = "NAIST-2003" licenseId NASA_1_3 = "NASA-1.3" licenseId Naumen = "Naumen" licenseId NBPL_1_0 = "NBPL-1.0" +licenseId NCBI_PD = "NCBI-PD" licenseId NCGL_UK_2_0 = "NCGL-UK-2.0" +licenseId NCL = "NCL" licenseId NCSA = "NCSA" licenseId Net_SNMP = "Net-SNMP" licenseId NetCDF = "NetCDF" @@ -1157,6 +1206,7 @@ licenseId NRL = "NRL" licenseId NTP_0 = "NTP-0" licenseId NTP = "NTP" licenseId O_UDA_1_0 = "O-UDA-1.0" +licenseId OAR = "OAR" licenseId OCCT_PL = "OCCT-PL" licenseId OCLC_2_0 = "OCLC-2.0" licenseId ODbL_1_0 = "ODbL-1.0" @@ -1213,11 +1263,13 @@ licenseId PDDL_1_0 = "PDDL-1.0" licenseId PHP_3_01 = "PHP-3.01" licenseId PHP_3_0 = "PHP-3.0" licenseId Pixar = "Pixar" +licenseId Pkgconf = "pkgconf" licenseId Plexus = "Plexus" licenseId Pnmstitch = "pnmstitch" licenseId PolyForm_Noncommercial_1_0_0 = "PolyForm-Noncommercial-1.0.0" licenseId PolyForm_Small_Business_1_0_0 = "PolyForm-Small-Business-1.0.0" licenseId PostgreSQL = "PostgreSQL" +licenseId PPL = "PPL" licenseId PSF_2_0 = "PSF-2.0" licenseId Psfrag = "psfrag" licenseId Psutils = "psutils" @@ -1235,6 +1287,7 @@ licenseId RPL_1_5 = "RPL-1.5" licenseId RPSL_1_0 = "RPSL-1.0" licenseId RSA_MD = "RSA-MD" licenseId RSCPL = "RSCPL" +licenseId Ruby_pty = "Ruby-pty" licenseId Ruby = "Ruby" licenseId SAX_PD_2_0 = "SAX-PD-2.0" licenseId SAX_PD = "SAX-PD" @@ -1271,6 +1324,7 @@ licenseId SSH_short = "SSH-short" licenseId SSLeay_standalone = "SSLeay-standalone" licenseId SSPL_1_0 = "SSPL-1.0" licenseId SugarCRM_1_1_3 = "SugarCRM-1.1.3" +licenseId Sun_PPP_2000 = "Sun-PPP-2000" licenseId Sun_PPP = "Sun-PPP" licenseId SunPro = "SunPro" licenseId SWL = "SWL" @@ -1281,6 +1335,7 @@ licenseId TCL = "TCL" licenseId TCP_wrappers = "TCP-wrappers" licenseId TermReadKey = "TermReadKey" licenseId TGPPL_1_0 = "TGPPL-1.0" +licenseId Threeparttable = "threeparttable" licenseId TMate = "TMate" licenseId TORQUE_1_1 = "TORQUE-1.1" licenseId TOSL = "TOSL" @@ -1290,6 +1345,7 @@ licenseId TTWL = "TTWL" licenseId TTYP0 = "TTYP0" licenseId TU_Berlin_1_0 = "TU-Berlin-1.0" licenseId TU_Berlin_2_0 = "TU-Berlin-2.0" +licenseId Ubuntu_font_1_0 = "Ubuntu-font-1.0" licenseId UCAR = "UCAR" licenseId UCL_1_0 = "UCL-1.0" licenseId Ulem = "ulem" @@ -1314,6 +1370,7 @@ licenseId Widget_Workshop = "Widget-Workshop" licenseId Wsuipa = "Wsuipa" licenseId WTFPL = "WTFPL" licenseId X11_distribute_modifications_variant = "X11-distribute-modifications-variant" +licenseId X11_swapped = "X11-swapped" licenseId X11 = "X11" licenseId Xdebug_1_03 = "Xdebug-1.03" licenseId Xerox = "Xerox" @@ -1325,6 +1382,7 @@ licenseId Xlock = "xlock" licenseId Xnet = "Xnet" licenseId Xpp = "xpp" licenseId XSkat = "XSkat" +licenseId Xzoom = "xzoom" licenseId YPL_1_0 = "YPL-1.0" licenseId YPL_1_1 = "YPL-1.1" licenseId Zed = "Zed" @@ -1341,6 +1399,7 @@ licenseId ZPL_2_1 = "ZPL-2.1" -- | License name, e.g. @"GNU General Public License v2.0 only"@ licenseName :: LicenseId -> String licenseName NullBSD = "BSD Zero Clause License" +licenseName X3D_Slicer_1_0 = "3D Slicer License v1.0" licenseName AAL = "Attribution Assurance License" licenseName Abstyles = "Abstyles License" licenseName AdaCore_doc = "AdaCore Doc License" @@ -1361,12 +1420,14 @@ licenseName AGPL_1_0_or_later = "Affero General Public License v1.0 or later" licenseName AGPL_3_0_only = "GNU Affero General Public License v3.0 only" licenseName AGPL_3_0_or_later = "GNU Affero General Public License v3.0 or later" licenseName Aladdin = "Aladdin Free Public License" +licenseName AMD_newlib = "AMD newlib License" licenseName AMDPLPA = "AMD's plpa_map.c License" licenseName AML_glslang = "AML glslang variant License" licenseName AML = "Apple MIT License" licenseName AMPAS = "Academy of Motion Picture Arts and Sciences BSD" licenseName ANTLR_PD_fallback = "ANTLR Software Rights Notice with license fallback" licenseName ANTLR_PD = "ANTLR Software Rights Notice" +licenseName Any_OSI = "Any OSI License" licenseName Apache_1_0 = "Apache License 1.0" licenseName Apache_1_1 = "Apache License 1.1" licenseName Apache_2_0 = "Apache License 2.0" @@ -1403,6 +1464,7 @@ licenseName BSD_1_Clause = "BSD 1-Clause License" licenseName BSD_2_Clause_FreeBSD = "BSD 2-Clause FreeBSD License" licenseName BSD_2_Clause_NetBSD = "BSD 2-Clause NetBSD License" licenseName BSD_2_Clause_Darwin = "BSD 2-Clause - Ian Darwin variant" +licenseName BSD_2_Clause_first_lines = "BSD 2-Clause - first lines requirement" licenseName BSD_2_Clause_Patent = "BSD-2-Clause Plus Patent License" licenseName BSD_2_Clause_Views = "BSD 2-Clause with views sentence" licenseName BSD_2_Clause = "BSD 2-Clause \"Simplified\" License" @@ -1442,6 +1504,7 @@ licenseName CAL_1_0_Combined_Work_Exception = "Cryptographic Autonomy License 1. licenseName CAL_1_0 = "Cryptographic Autonomy License 1.0" licenseName Caldera_no_preamble = "Caldera License (without preamble)" licenseName Caldera = "Caldera License" +licenseName Catharon = "Catharon License" licenseName CATOSL_1_1 = "Computer Associates Trusted Open Source License 1.1" licenseName CC_BY_1_0 = "Creative Commons Attribution 1.0 Generic" licenseName CC_BY_2_0 = "Creative Commons Attribution 2.0 Generic" @@ -1538,11 +1601,14 @@ licenseName CrystalStacker = "CrystalStacker License" licenseName CUA_OPL_1_0 = "CUA Office Public License v1.0" licenseName Cube = "Cube License" licenseName Curl = "curl License" +licenseName Cve_tou = "Common Vulnerability Enumeration ToU License" licenseName D_FSL_1_0 = "Deutsche Freie Software Lizenz" licenseName DEC_3_Clause = "DEC 3-Clause License" licenseName Diffmark = "diffmark license" licenseName DL_DE_BY_2_0 = "Data licence Germany \8211 attribution \8211 version 2.0" licenseName DL_DE_ZERO_2_0 = "Data licence Germany \8211 zero \8211 version 2.0" +licenseName DocBook_Schema = "DocBook Schema License" +licenseName DocBook_XML = "DocBook XML License" licenseName DOC = "DOC License" licenseName Dotseqn = "Dotseqn License" licenseName DRL_1_0 = "Detection Rule License 1.0" @@ -1617,26 +1683,35 @@ licenseName GPL_3_0_or_later = "GNU General Public License v3.0 or later" licenseName Graphics_Gems = "Graphics Gems License" licenseName GSOAP_1_3b = "gSOAP Public License v1.3b" licenseName Gtkbook = "gtkbook License" +licenseName Gutmann = "Gutmann License" licenseName HaskellReport = "Haskell Language Report License" licenseName Hdparm = "hdparm License" +licenseName HIDAPI = "HIDAPI License" licenseName Hippocratic_2_1 = "Hippocratic License 2.1" licenseName HP_1986 = "Hewlett-Packard 1986 License" licenseName HP_1989 = "Hewlett-Packard 1989 License" licenseName HPND_DEC = "Historical Permission Notice and Disclaimer - DEC variant" licenseName HPND_doc_sell = "Historical Permission Notice and Disclaimer - documentation sell variant" licenseName HPND_doc = "Historical Permission Notice and Disclaimer - documentation variant" +licenseName HPND_export_US_acknowledgement = "HPND with US Government export control warning and acknowledgment" licenseName HPND_export_US_modify = "HPND with US Government export control warning and modification rqmt" licenseName HPND_export_US = "HPND with US Government export control warning" +licenseName HPND_export2_US = "HPND with US Government export control and 2 disclaimers" licenseName HPND_Fenneberg_Livingston = "Historical Permission Notice and Disclaimer - Fenneberg-Livingston variant" licenseName HPND_INRIA_IMAG = "Historical Permission Notice and Disclaimer - INRIA-IMAG variant" +licenseName HPND_Intel = "Historical Permission Notice and Disclaimer - Intel variant" licenseName HPND_Kevlin_Henney = "Historical Permission Notice and Disclaimer - Kevlin Henney variant" licenseName HPND_Markus_Kuhn = "Historical Permission Notice and Disclaimer - Markus Kuhn variant" +licenseName HPND_merchantability_variant = "Historical Permission Notice and Disclaimer - merchantability variant" licenseName HPND_MIT_disclaimer = "Historical Permission Notice and Disclaimer with MIT disclaimer" +licenseName HPND_Netrek = "Historical Permission Notice and Disclaimer - Netrek variant" licenseName HPND_Pbmplus = "Historical Permission Notice and Disclaimer - Pbmplus variant" licenseName HPND_sell_MIT_disclaimer_xserver = "Historical Permission Notice and Disclaimer - sell xserver variant with MIT disclaimer" licenseName HPND_sell_regexpr = "Historical Permission Notice and Disclaimer - sell regexpr variant" +licenseName HPND_sell_variant_MIT_disclaimer_rev = "HPND sell variant with MIT disclaimer - reverse" licenseName HPND_sell_variant_MIT_disclaimer = "HPND sell variant with MIT disclaimer" licenseName HPND_sell_variant = "Historical Permission Notice and Disclaimer - sell variant" +licenseName HPND_UC_export_US = "Historical Permission Notice and Disclaimer - University of California, US export warning" licenseName HPND_UC = "Historical Permission Notice and Disclaimer - University of California variant" licenseName HPND = "Historical Permission Notice and Disclaimer" licenseName HTMLTIDY = "HTML Tidy License" @@ -1719,6 +1794,7 @@ licenseName MIT_CMU = "CMU License" licenseName MIT_enna = "enna License" licenseName MIT_feh = "feh License" licenseName MIT_Festival = "MIT Festival Variant" +licenseName MIT_Khronos_old = "MIT Khronos - old variant" licenseName MIT_Modern_Variant = "MIT License Modern Variant" licenseName MIT_open_group = "MIT Open Group variant" licenseName MIT_testregex = "MIT testregex Variant" @@ -1747,7 +1823,9 @@ licenseName NAIST_2003 = "Nara Institute of Science and Technology License (2003 licenseName NASA_1_3 = "NASA Open Source Agreement 1.3" licenseName Naumen = "Naumen Public License" licenseName NBPL_1_0 = "Net Boolean Public License v1" +licenseName NCBI_PD = "NCBI Public Domain Notice" licenseName NCGL_UK_2_0 = "Non-Commercial Government Licence" +licenseName NCL = "NCL Source Code License" licenseName NCSA = "University of Illinois/NCSA Open Source License" licenseName Net_SNMP = "Net-SNMP License" licenseName NetCDF = "NetCDF license" @@ -1770,6 +1848,7 @@ licenseName NRL = "NRL License" licenseName NTP_0 = "NTP No Attribution" licenseName NTP = "NTP License" licenseName O_UDA_1_0 = "Open Use of Data Agreement v1.0" +licenseName OAR = "OAR License" licenseName OCCT_PL = "Open CASCADE Technology Public License" licenseName OCLC_2_0 = "OCLC Research Public License 2.0" licenseName ODbL_1_0 = "Open Data Commons Open Database License v1.0" @@ -1826,11 +1905,13 @@ licenseName PDDL_1_0 = "Open Data Commons Public Domain Dedication & License 1.0 licenseName PHP_3_01 = "PHP License v3.01" licenseName PHP_3_0 = "PHP License v3.0" licenseName Pixar = "Pixar License" +licenseName Pkgconf = "pkgconf License" licenseName Plexus = "Plexus Classworlds License" licenseName Pnmstitch = "pnmstitch License" licenseName PolyForm_Noncommercial_1_0_0 = "PolyForm Noncommercial License 1.0.0" licenseName PolyForm_Small_Business_1_0_0 = "PolyForm Small Business License 1.0.0" licenseName PostgreSQL = "PostgreSQL License" +licenseName PPL = "Peer Production License" licenseName PSF_2_0 = "Python Software Foundation License 2.0" licenseName Psfrag = "psfrag License" licenseName Psutils = "psutils License" @@ -1848,6 +1929,7 @@ licenseName RPL_1_5 = "Reciprocal Public License 1.5" licenseName RPSL_1_0 = "RealNetworks Public Source License v1.0" licenseName RSA_MD = "RSA Message-Digest License" licenseName RSCPL = "Ricoh Source Code Public License" +licenseName Ruby_pty = "Ruby pty extension license" licenseName Ruby = "Ruby License" licenseName SAX_PD_2_0 = "Sax Public Domain Notice 2.0" licenseName SAX_PD = "Sax Public Domain Notice" @@ -1884,6 +1966,7 @@ licenseName SSH_short = "SSH short notice" licenseName SSLeay_standalone = "SSLeay License - standalone" licenseName SSPL_1_0 = "Server Side Public License, v 1" licenseName SugarCRM_1_1_3 = "SugarCRM Public License v1.1.3" +licenseName Sun_PPP_2000 = "Sun PPP License (2000)" licenseName Sun_PPP = "Sun PPP License" licenseName SunPro = "SunPro License" licenseName SWL = "Scheme Widget Library (SWL) Software License Agreement" @@ -1894,6 +1977,7 @@ licenseName TCL = "TCL/TK License" licenseName TCP_wrappers = "TCP Wrappers License" licenseName TermReadKey = "TermReadKey License" licenseName TGPPL_1_0 = "Transitive Grace Period Public Licence 1.0" +licenseName Threeparttable = "threeparttable License" licenseName TMate = "TMate Open Source License" licenseName TORQUE_1_1 = "TORQUE v2.5+ Software License v1.1" licenseName TOSL = "Trusster Open Source License" @@ -1903,6 +1987,7 @@ licenseName TTWL = "Text-Tabs+Wrap License" licenseName TTYP0 = "TTYP0 License" licenseName TU_Berlin_1_0 = "Technische Universitaet Berlin License 1.0" licenseName TU_Berlin_2_0 = "Technische Universitaet Berlin License 2.0" +licenseName Ubuntu_font_1_0 = "Ubuntu Font Licence v1.0" licenseName UCAR = "UCAR License" licenseName UCL_1_0 = "Upstream Compatibility License v1.0" licenseName Ulem = "ulem License" @@ -1927,6 +2012,7 @@ licenseName Widget_Workshop = "Widget Workshop License" licenseName Wsuipa = "Wsuipa License" licenseName WTFPL = "Do What The F*ck You Want To Public License" licenseName X11_distribute_modifications_variant = "X11 License Distribution Modification Variant" +licenseName X11_swapped = "X11 swapped final paragraphs" licenseName X11 = "X11 License" licenseName Xdebug_1_03 = "Xdebug License v 1.03" licenseName Xerox = "Xerox License" @@ -1938,6 +2024,7 @@ licenseName Xlock = "xlock License" licenseName Xnet = "X.Net License" licenseName Xpp = "XPP License" licenseName XSkat = "XSkat License" +licenseName Xzoom = "xzoom License" licenseName YPL_1_0 = "Yahoo! Public License v1.0" licenseName YPL_1_1 = "Yahoo! Public License v1.1" licenseName Zed = "Zed License" @@ -2080,6 +2167,7 @@ licenseIsOsiApproved Unicode_DFS_2016 = True licenseIsOsiApproved Unlicense = True licenseIsOsiApproved UPL_1_0 = True licenseIsOsiApproved VSL_1_0 = True +licenseIsOsiApproved W3C_20150513 = True licenseIsOsiApproved W3C = True licenseIsOsiApproved Watcom_1_0 = True licenseIsOsiApproved Xnet = True @@ -2218,6 +2306,7 @@ licenseIdList LicenseListVersion_3_0 = , BSD_2_Clause_FreeBSD , BSD_2_Clause_NetBSD , Bzip2_1_0_5 + , Net_SNMP ] ++ bulkOfLicenses licenseIdList LicenseListVersion_3_2 = @@ -2228,6 +2317,7 @@ licenseIdList LicenseListVersion_3_2 = , Bzip2_1_0_5 , Linux_OpenIB , MIT_0 + , Net_SNMP , ODC_By_1_0 , TU_Berlin_1_0 , TU_Berlin_2_0 @@ -2252,6 +2342,7 @@ licenseIdList LicenseListVersion_3_6 = , Libpng_2_0 , Linux_OpenIB , MIT_0 + , Net_SNMP , ODC_By_1_0 , OGL_UK_1_0 , OGL_UK_2_0 @@ -2295,6 +2386,7 @@ licenseIdList LicenseListVersion_3_9 = , MulanPSL_1_0 , MulanPSL_2_0 , NCGL_UK_2_0 + , Net_SNMP , NTP_0 , O_UDA_1_0 , ODC_By_1_0 @@ -2370,6 +2462,7 @@ licenseIdList LicenseListVersion_3_10 = , MulanPSL_1_0 , MulanPSL_2_0 , NCGL_UK_2_0 + , Net_SNMP , NIST_PD_fallback , NIST_PD , NTP_0 @@ -2483,6 +2576,7 @@ licenseIdList LicenseListVersion_3_16 = , MulanPSL_2_0 , NAIST_2003 , NCGL_UK_2_0 + , Net_SNMP , NIST_PD_fallback , NIST_PD , NLOD_2_0 @@ -2707,6 +2801,298 @@ licenseIdList LicenseListVersion_3_23 = , MulanPSL_2_0 , NAIST_2003 , NCGL_UK_2_0 + , Net_SNMP + , NICTA_1_0 + , NIST_PD_fallback + , NIST_PD + , NIST_Software + , NLOD_2_0 + , NTP_0 + , O_UDA_1_0 + , ODC_By_1_0 + , OFFIS + , OFL_1_0_no_RFN + , OFL_1_0_RFN + , OFL_1_1_no_RFN + , OFL_1_1_RFN + , OGC_1_0 + , OGDL_Taiwan_1_0 + , OGL_Canada_2_0 + , OGL_UK_1_0 + , OGL_UK_2_0 + , OGL_UK_3_0 + , OLFL_1_3 + , OpenPBS_2_3 + , OpenSSL_standalone + , OpenVision + , OPL_UK_3_0 + , OPUBL_1_0 + , PADL + , Parity_6_0_0 + , Parity_7_0_0 + , Pixar + , Pnmstitch + , PolyForm_Noncommercial_1_0_0 + , PolyForm_Small_Business_1_0_0 + , PSF_2_0 + , Python_2_0_1 + , Python_ldap + , QPL_1_0_INRIA_2004 + , Radvd + , SAX_PD_2_0 + , SchemeReport + , Sendmail_8_23 + , SGI_OpenGL + , SGP4 + , SHL_0_51 + , SHL_0_5 + , SL + , Snprintf + , SoftSurfer + , Soundex + , Ssh_keyscan + , SSH_OpenSSH + , SSH_short + , SSLeay_standalone + , SSPL_1_0 + , Sun_PPP + , SunPro + , Swrule + , Symlinks + , TAPR_OHL_1_0 + , TermReadKey + , TGPPL_1_0 + , TPDL + , TPL_1_0 + , TTWL + , TTYP0 + , TU_Berlin_1_0 + , TU_Berlin_2_0 + , UCAR + , UCL_1_0 + , Ulem + , UMich_Merit + , Unicode_3_0 + , UnixCrypt + , URT_RLE + , W3m + , Widget_Workshop + , X11_distribute_modifications_variant + , Xdebug_1_03 + , Xfig + , Xkeyboard_config_Zinoviev + , Xlock + , Zeeff + ] + ++ bulkOfLicenses +licenseIdList LicenseListVersion_3_25 = + [ X3D_Slicer_1_0 + , AdaCore_doc + , Adobe_Display_PostScript + , Adobe_Utopia + , AGPL_1_0_only + , AGPL_1_0_or_later + , AMD_newlib + , AML_glslang + , ANTLR_PD_fallback + , Any_OSI + , App_s2p + , Arphic_1999 + , ASWF_Digital_Assets_1_0 + , ASWF_Digital_Assets_1_1 + , Baekmuk + , Bcrypt_Solar_Designer + , Bitstream_Charter + , Bitstream_Vera + , Blessing + , BlueOak_1_0_0 + , Boehm_GC + , Brian_Gladman_2_Clause + , Brian_Gladman_3_Clause + , BSD_2_Clause_Darwin + , BSD_2_Clause_first_lines + , BSD_2_Clause_Views + , BSD_3_Clause_acpica + , BSD_3_Clause_flex + , BSD_3_Clause_HP + , BSD_3_Clause_Modification + , BSD_3_Clause_No_Military_License + , BSD_3_Clause_Open_MPI + , BSD_3_Clause_Sun + , BSD_4_Clause_Shortened + , BSD_4_3RENO + , BSD_4_3TAHOE + , BSD_Advertising_Acknowledgement + , BSD_Attribution_HPND_disclaimer + , BSD_Inferno_Nettverk + , BSD_Source_beginning_file + , BSD_Systemics_W3Works + , BSD_Systemics + , BUSL_1_1 + , C_UDA_1_0 + , CAL_1_0_Combined_Work_Exception + , CAL_1_0 + , Caldera_no_preamble + , Catharon + , CC_BY_2_5_AU + , CC_BY_3_0_AT + , CC_BY_3_0_AU + , CC_BY_3_0_DE + , CC_BY_3_0_IGO + , CC_BY_3_0_NL + , CC_BY_3_0_US + , CC_BY_NC_3_0_DE + , CC_BY_NC_ND_3_0_DE + , CC_BY_NC_ND_3_0_IGO + , CC_BY_NC_SA_2_0_DE + , CC_BY_NC_SA_2_0_FR + , CC_BY_NC_SA_2_0_UK + , CC_BY_NC_SA_3_0_DE + , CC_BY_NC_SA_3_0_IGO + , CC_BY_ND_3_0_DE + , CC_BY_SA_2_0_UK + , CC_BY_SA_2_1_JP + , CC_BY_SA_3_0_AT + , CC_BY_SA_3_0_DE + , CC_BY_SA_3_0_IGO + , CC_PDDC + , CDL_1_0 + , CDLA_Permissive_2_0 + , CERN_OHL_1_1 + , CERN_OHL_1_2 + , CERN_OHL_P_2_0 + , CERN_OHL_S_2_0 + , CERN_OHL_W_2_0 + , CFITSIO + , Check_cvs + , Checkmk + , Clips + , CMU_Mach_nodoc + , CMU_Mach + , COIL_1_0 + , Community_Spec_1_0 + , Copyleft_next_0_3_0 + , Copyleft_next_0_3_1 + , Cornell_Lossless_JPEG + , Cronyx + , Cve_tou + , DEC_3_Clause + , DL_DE_BY_2_0 + , DL_DE_ZERO_2_0 + , DocBook_Schema + , DocBook_XML + , DRL_1_0 + , DRL_1_1 + , Dtoa + , Elastic_2_0 + , EPICS + , Etalab_2_0 + , FBM + , FDK_AAC + , Ferguson_Twofish + , FreeBSD_DOC + , FSFAP_no_warranty_disclaimer + , FSFULLRWD + , Furuseth + , Fwlw + , GCR_docs + , GD + , GFDL_1_1_invariants_only + , GFDL_1_1_invariants_or_later + , GFDL_1_1_no_invariants_only + , GFDL_1_1_no_invariants_or_later + , GFDL_1_2_invariants_only + , GFDL_1_2_invariants_or_later + , GFDL_1_2_no_invariants_only + , GFDL_1_2_no_invariants_or_later + , GFDL_1_3_invariants_only + , GFDL_1_3_invariants_or_later + , GFDL_1_3_no_invariants_only + , GFDL_1_3_no_invariants_or_later + , GLWTPL + , Graphics_Gems + , Gtkbook + , Gutmann + , Hdparm + , HIDAPI + , Hippocratic_2_1 + , HP_1986 + , HP_1989 + , HPND_DEC + , HPND_doc_sell + , HPND_doc + , HPND_export_US_acknowledgement + , HPND_export_US_modify + , HPND_export_US + , HPND_export2_US + , HPND_Fenneberg_Livingston + , HPND_INRIA_IMAG + , HPND_Intel + , HPND_Kevlin_Henney + , HPND_Markus_Kuhn + , HPND_merchantability_variant + , HPND_MIT_disclaimer + , HPND_Netrek + , HPND_Pbmplus + , HPND_sell_MIT_disclaimer_xserver + , HPND_sell_regexpr + , HPND_sell_variant_MIT_disclaimer_rev + , HPND_sell_variant_MIT_disclaimer + , HPND_sell_variant + , HPND_UC_export_US + , HPND_UC + , HTMLTIDY + , IEC_Code_Components_EULA + , IJG_short + , Inner_Net_2_0 + , ISC_Veillard + , Jam + , JPL_image + , JPNIC + , Kastrup + , Kazlib + , Knuth_CTAN + , Latex2e_translated_notice + , Libpng_2_0 + , Libselinux_1_0 + , Libutil_David_Nugent + , Linux_man_pages_1_para + , Linux_man_pages_copyleft_2_para + , Linux_man_pages_copyleft_var + , Linux_man_pages_copyleft + , Linux_OpenIB + , LOOP + , LPD_document + , Lsof + , Lucida_Bitmap_Fonts + , LZMA_SDK_9_11_to_9_20 + , LZMA_SDK_9_22 + , Mackerras_3_Clause_acknowledgment + , Mackerras_3_Clause + , Magaz + , Mailprio + , Martin_Birgmeier + , McPhee_slideshow + , Metamail + , Minpack + , MIT_0 + , MIT_Festival + , MIT_Khronos_old + , MIT_Modern_Variant + , MIT_open_group + , MIT_testregex + , MIT_Wu + , MMIXware + , MPEG_SSG + , Mpi_permissive + , Mplus + , MS_LPL + , MulanPSL_1_0 + , MulanPSL_2_0 + , NAIST_2003 + , NCBI_PD + , NCGL_UK_2_0 + , NCL , NICTA_1_0 , NIST_PD_fallback , NIST_PD @@ -2714,6 +3100,7 @@ licenseIdList LicenseListVersion_3_23 = , NLOD_2_0 , NTP_0 , O_UDA_1_0 + , OAR , ODC_By_1_0 , OFFIS , OFL_1_0_no_RFN @@ -2736,14 +3123,17 @@ licenseIdList LicenseListVersion_3_23 = , Parity_6_0_0 , Parity_7_0_0 , Pixar + , Pkgconf , Pnmstitch , PolyForm_Noncommercial_1_0_0 , PolyForm_Small_Business_1_0_0 + , PPL , PSF_2_0 , Python_2_0_1 , Python_ldap , QPL_1_0_INRIA_2004 , Radvd + , Ruby_pty , SAX_PD_2_0 , SchemeReport , Sendmail_8_23 @@ -2760,6 +3150,7 @@ licenseIdList LicenseListVersion_3_23 = , SSH_short , SSLeay_standalone , SSPL_1_0 + , Sun_PPP_2000 , Sun_PPP , SunPro , Swrule @@ -2767,12 +3158,14 @@ licenseIdList LicenseListVersion_3_23 = , TAPR_OHL_1_0 , TermReadKey , TGPPL_1_0 + , Threeparttable , TPDL , TPL_1_0 , TTWL , TTYP0 , TU_Berlin_1_0 , TU_Berlin_2_0 + , Ubuntu_font_1_0 , UCAR , UCL_1_0 , Ulem @@ -2783,10 +3176,12 @@ licenseIdList LicenseListVersion_3_23 = , W3m , Widget_Workshop , X11_distribute_modifications_variant + , X11_swapped , Xdebug_1_03 , Xfig , Xkeyboard_config_Zinoviev , Xlock + , Xzoom , Zeeff ] ++ bulkOfLicenses @@ -2800,6 +3195,7 @@ mkLicenseId LicenseListVersion_3_9 s = Map.lookup s stringLookup_3_9 mkLicenseId LicenseListVersion_3_10 s = Map.lookup s stringLookup_3_10 mkLicenseId LicenseListVersion_3_16 s = Map.lookup s stringLookup_3_16 mkLicenseId LicenseListVersion_3_23 s = Map.lookup s stringLookup_3_23 +mkLicenseId LicenseListVersion_3_25 s = Map.lookup s stringLookup_3_25 stringLookup_3_0 :: Map String LicenseId stringLookup_3_0 = Map.fromList $ map (\i -> (licenseId i, i)) $ @@ -2829,6 +3225,10 @@ stringLookup_3_23 :: Map String LicenseId stringLookup_3_23 = Map.fromList $ map (\i -> (licenseId i, i)) $ licenseIdList LicenseListVersion_3_23 +stringLookup_3_25 :: Map String LicenseId +stringLookup_3_25 = Map.fromList $ map (\i -> (licenseId i, i)) $ + licenseIdList LicenseListVersion_3_25 + -- | Licenses in all SPDX License lists bulkOfLicenses :: [LicenseId] bulkOfLicenses = @@ -3050,7 +3450,6 @@ bulkOfLicenses = , Naumen , NBPL_1_0 , NCSA - , Net_SNMP , NetCDF , Newsletr , NGPL diff --git a/Cabal-syntax/src/Distribution/SPDX/LicenseListVersion.hs b/Cabal-syntax/src/Distribution/SPDX/LicenseListVersion.hs index 88280ca56f9..cf12323d275 100644 --- a/Cabal-syntax/src/Distribution/SPDX/LicenseListVersion.hs +++ b/Cabal-syntax/src/Distribution/SPDX/LicenseListVersion.hs @@ -14,10 +14,11 @@ data LicenseListVersion | LicenseListVersion_3_10 | LicenseListVersion_3_16 | LicenseListVersion_3_23 + | LicenseListVersion_3_25 deriving (Eq, Ord, Show, Enum, Bounded) cabalSpecVersionToSPDXListVersion :: CabalSpecVersion -> LicenseListVersion -cabalSpecVersionToSPDXListVersion CabalSpecV3_14 = LicenseListVersion_3_23 +cabalSpecVersionToSPDXListVersion CabalSpecV3_14 = LicenseListVersion_3_25 cabalSpecVersionToSPDXListVersion CabalSpecV3_12 = LicenseListVersion_3_23 cabalSpecVersionToSPDXListVersion CabalSpecV3_8 = LicenseListVersion_3_16 cabalSpecVersionToSPDXListVersion CabalSpecV3_6 = LicenseListVersion_3_10 diff --git a/Makefile b/Makefile index 0912773d368..7b272c55e09 100644 --- a/Makefile +++ b/Makefile @@ -52,7 +52,7 @@ SPDX_EXCEPTION_HS:=Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs .PHONY: spdx spdx : $(SPDX_LICENSE_HS) $(SPDX_EXCEPTION_HS) -SPDX_LICENSE_VERSIONS:=3.0 3.2 3.6 3.9 3.10 3.16 3.23 +SPDX_LICENSE_VERSIONS:=3.0 3.2 3.6 3.9 3.10 3.16 3.23 3.25 $(SPDX_LICENSE_HS) : templates/SPDX.LicenseId.template.hs cabal-dev-scripts/src/GenUtils.hs cabal-dev-scripts/src/GenSPDX.hs license-list-data/licenses-3.0.json license-list-data/licenses-3.2.json cabal run --builddir=dist-newstyle-meta --project-file=cabal.meta.project gen-spdx -- templates/SPDX.LicenseId.template.hs $(SPDX_LICENSE_VERSIONS:%=license-list-data/licenses-%.json) $(SPDX_LICENSE_HS) diff --git a/cabal-dev-scripts/src/GenSPDX.hs b/cabal-dev-scripts/src/GenSPDX.hs index adb3276a1bd..083dbf7c951 100644 --- a/cabal-dev-scripts/src/GenSPDX.hs +++ b/cabal-dev-scripts/src/GenSPDX.hs @@ -36,6 +36,7 @@ main = generate =<< O.execParser opts where <*> licenses "3.10" <*> licenses "3.16" <*> licenses "3.23" + <*> licenses "3.25" template = O.strArgument $ mconcat [ O.metavar "SPDX.LicenseId.template.hs" diff --git a/cabal-dev-scripts/src/GenSPDXExc.hs b/cabal-dev-scripts/src/GenSPDXExc.hs index c85438a828b..a9a08717818 100644 --- a/cabal-dev-scripts/src/GenSPDXExc.hs +++ b/cabal-dev-scripts/src/GenSPDXExc.hs @@ -35,6 +35,7 @@ main = generate =<< O.execParser opts where <*> licenses "3.10" <*> licenses "3.16" <*> licenses "3.23" + <*> licenses "3.25" template = O.strArgument $ mconcat [ O.metavar "SPDX.LicenseExceptionId.template.hs" diff --git a/cabal-dev-scripts/src/GenUtils.hs b/cabal-dev-scripts/src/GenUtils.hs index 7d7b39c2add..f64388463da 100644 --- a/cabal-dev-scripts/src/GenUtils.hs +++ b/cabal-dev-scripts/src/GenUtils.hs @@ -33,12 +33,14 @@ data SPDXLicenseListVersion | SPDXLicenseListVersion_3_10 | SPDXLicenseListVersion_3_16 | SPDXLicenseListVersion_3_23 + | SPDXLicenseListVersion_3_25 deriving (Eq, Ord, Show, Enum, Bounded) allVers :: Set.Set SPDXLicenseListVersion allVers = Set.fromList [minBound .. maxBound] prettyVer :: SPDXLicenseListVersion -> Text +prettyVer SPDXLicenseListVersion_3_25 = "SPDX License List 3.25" prettyVer SPDXLicenseListVersion_3_23 = "SPDX License List 3.23" prettyVer SPDXLicenseListVersion_3_16 = "SPDX License List 3.16" prettyVer SPDXLicenseListVersion_3_10 = "SPDX License List 3.10" @@ -48,6 +50,7 @@ prettyVer SPDXLicenseListVersion_3_2 = "SPDX License List 3.2" prettyVer SPDXLicenseListVersion_3_0 = "SPDX License List 3.0" suffixVer :: SPDXLicenseListVersion -> String +suffixVer SPDXLicenseListVersion_3_25 = "_3_25" suffixVer SPDXLicenseListVersion_3_23 = "_3_23" suffixVer SPDXLicenseListVersion_3_16 = "_3_16" suffixVer SPDXLicenseListVersion_3_10 = "_3_10" @@ -60,7 +63,7 @@ suffixVer SPDXLicenseListVersion_3_0 = "_3_0" -- Per version ------------------------------------------------------------------------------- -data PerV a = PerV a a a a a a a +data PerV a = PerV a a a a a a a a deriving (Show, Functor, Foldable, Traversable) class Functor f => Representable i f | f -> i where @@ -68,13 +71,14 @@ class Functor f => Representable i f | f -> i where tabulate :: (i -> a) -> f a instance Representable SPDXLicenseListVersion PerV where - index SPDXLicenseListVersion_3_0 (PerV x _ _ _ _ _ _) = x - index SPDXLicenseListVersion_3_2 (PerV _ x _ _ _ _ _) = x - index SPDXLicenseListVersion_3_6 (PerV _ _ x _ _ _ _) = x - index SPDXLicenseListVersion_3_9 (PerV _ _ _ x _ _ _) = x - index SPDXLicenseListVersion_3_10 (PerV _ _ _ _ x _ _) = x - index SPDXLicenseListVersion_3_16 (PerV _ _ _ _ _ x _) = x - index SPDXLicenseListVersion_3_23 (PerV _ _ _ _ _ _ x) = x + index SPDXLicenseListVersion_3_0 (PerV x _ _ _ _ _ _ _) = x + index SPDXLicenseListVersion_3_2 (PerV _ x _ _ _ _ _ _) = x + index SPDXLicenseListVersion_3_6 (PerV _ _ x _ _ _ _ _) = x + index SPDXLicenseListVersion_3_9 (PerV _ _ _ x _ _ _ _) = x + index SPDXLicenseListVersion_3_10 (PerV _ _ _ _ x _ _ _) = x + index SPDXLicenseListVersion_3_16 (PerV _ _ _ _ _ x _ _) = x + index SPDXLicenseListVersion_3_23 (PerV _ _ _ _ _ _ x _) = x + index SPDXLicenseListVersion_3_25 (PerV _ _ _ _ _ _ _ x) = x tabulate f = PerV (f SPDXLicenseListVersion_3_0) @@ -84,6 +88,7 @@ instance Representable SPDXLicenseListVersion PerV where (f SPDXLicenseListVersion_3_10) (f SPDXLicenseListVersion_3_16) (f SPDXLicenseListVersion_3_23) + (f SPDXLicenseListVersion_3_25) ------------------------------------------------------------------------------- -- Sorting @@ -162,6 +167,7 @@ toConstructorName t = t special :: Text -> Text special "0BSD" = "NullBSD" special "389_exception" = "DS389_exception" + special "3D_Slicer_1_0" = "X3D_Slicer_1_0" special u = u mkList :: [Text] -> Text diff --git a/doc/file-format-changelog.rst b/doc/file-format-changelog.rst index e57eb2508fc..174cb3c3189 100644 --- a/doc/file-format-changelog.rst +++ b/doc/file-format-changelog.rst @@ -25,6 +25,8 @@ relative to the respective preceding *published* version. * Added field ``extra-files`` for specifying extra files to be included in ``sdist`` without adding any other semantics (cf. ``extra-source-files`` is tracked by ``cabal build``). +* License fields use identifiers from SPDX License List version + ``3.25 2024-08-19``. ``cabal-version: 3.12`` ----------------------- diff --git a/license-list-data/exceptions-3.25.json b/license-list-data/exceptions-3.25.json new file mode 100644 index 00000000000..9d20ee4866a --- /dev/null +++ b/license-list-data/exceptions-3.25.json @@ -0,0 +1,836 @@ +{ + "licenseListVersion": "3.25.0", + "exceptions": [ + { + "reference": "./389-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./389-exception.html", + "referenceNumber": 53, + "name": "389 Directory Server Exception", + "licenseExceptionId": "389-exception", + "seeAlso": [ + "http://directory.fedoraproject.org/wiki/GPL_Exception_License_Text", + "https://web.archive.org/web/20080828121337/http://directory.fedoraproject.org/wiki/GPL_Exception_License_Text" + ] + }, + { + "reference": "./Asterisk-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Asterisk-exception.html", + "referenceNumber": 60, + "name": "Asterisk exception", + "licenseExceptionId": "Asterisk-exception", + "seeAlso": [ + "https://github.com/asterisk/libpri/blob/7f91151e6bd10957c746c031c1f4a030e8146e9a/pri.c#L22", + "https://github.com/asterisk/libss7/blob/03e81bcd0d28ff25d4c77c78351ddadc82ff5c3f/ss7.c#L24" + ] + }, + { + "reference": "./Asterisk-linking-protocols-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Asterisk-linking-protocols-exception.html", + "referenceNumber": 24, + "name": "Asterisk linking protocols exception", + "licenseExceptionId": "Asterisk-linking-protocols-exception", + "seeAlso": [ + "https://github.com/asterisk/asterisk/blob/115d7c01e32ccf4566a99e9d74e2b88830985a0b/LICENSE#L27" + ] + }, + { + "reference": "./Autoconf-exception-2.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Autoconf-exception-2.0.html", + "referenceNumber": 72, + "name": "Autoconf exception 2.0", + "licenseExceptionId": "Autoconf-exception-2.0", + "seeAlso": [ + "http://ac-archive.sourceforge.net/doc/copyright.html", + "http://ftp.gnu.org/gnu/autoconf/autoconf-2.59.tar.gz" + ] + }, + { + "reference": "./Autoconf-exception-3.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Autoconf-exception-3.0.html", + "referenceNumber": 17, + "name": "Autoconf exception 3.0", + "licenseExceptionId": "Autoconf-exception-3.0", + "seeAlso": [ + "http://www.gnu.org/licenses/autoconf-exception-3.0.html" + ] + }, + { + "reference": "./Autoconf-exception-generic.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Autoconf-exception-generic.html", + "referenceNumber": 48, + "name": "Autoconf generic exception", + "licenseExceptionId": "Autoconf-exception-generic", + "seeAlso": [ + "https://launchpad.net/ubuntu/precise/+source/xmltooling/+copyright", + "https://tracker.debian.org/media/packages/s/sipwitch/copyright-1.9.15-3", + "https://opensource.apple.com/source/launchd/launchd-258.1/launchd/compile.auto.html", + "https://git.savannah.gnu.org/gitweb/?p\u003dgnulib.git;a\u003dblob;f\u003dgnulib-tool;h\u003d029a8cf377ad8d8f2d9e54061bf2f20496ad2eef;hb\u003d73c74ba0197e6566da6882c87b1adee63e24d75c#l407" + ] + }, + { + "reference": "./Autoconf-exception-generic-3.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Autoconf-exception-generic-3.0.html", + "referenceNumber": 64, + "name": "Autoconf generic exception for GPL-3.0", + "licenseExceptionId": "Autoconf-exception-generic-3.0", + "seeAlso": [ + "https://src.fedoraproject.org/rpms/redhat-rpm-config/blob/rawhide/f/config.guess" + ] + }, + { + "reference": "./Autoconf-exception-macro.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Autoconf-exception-macro.html", + "referenceNumber": 51, + "name": "Autoconf macro exception", + "licenseExceptionId": "Autoconf-exception-macro", + "seeAlso": [ + "https://github.com/freedesktop/xorg-macros/blob/39f07f7db58ebbf3dcb64a2bf9098ed5cf3d1223/xorg-macros.m4.in", + "https://www.gnu.org/software/autoconf-archive/ax_pthread.html", + "https://launchpad.net/ubuntu/precise/+source/xmltooling/+copyright" + ] + }, + { + "reference": "./Bison-exception-1.24.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Bison-exception-1.24.html", + "referenceNumber": 59, + "name": "Bison exception 1.24", + "licenseExceptionId": "Bison-exception-1.24", + "seeAlso": [ + "https://github.com/arineng/rwhoisd/blob/master/rwhoisd/mkdb/y.tab.c#L180" + ] + }, + { + "reference": "./Bison-exception-2.2.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Bison-exception-2.2.html", + "referenceNumber": 21, + "name": "Bison exception 2.2", + "licenseExceptionId": "Bison-exception-2.2", + "seeAlso": [ + "http://git.savannah.gnu.org/cgit/bison.git/tree/data/yacc.c?id\u003d193d7c7054ba7197b0789e14965b739162319b5e#n141" + ] + }, + { + "reference": "./Bootloader-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Bootloader-exception.html", + "referenceNumber": 40, + "name": "Bootloader Distribution Exception", + "licenseExceptionId": "Bootloader-exception", + "seeAlso": [ + "https://github.com/pyinstaller/pyinstaller/blob/develop/COPYING.txt" + ] + }, + { + "reference": "./Classpath-exception-2.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Classpath-exception-2.0.html", + "referenceNumber": 34, + "name": "Classpath exception 2.0", + "licenseExceptionId": "Classpath-exception-2.0", + "seeAlso": [ + "http://www.gnu.org/software/classpath/license.html", + "https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception" + ] + }, + { + "reference": "./CLISP-exception-2.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./CLISP-exception-2.0.html", + "referenceNumber": 71, + "name": "CLISP exception 2.0", + "licenseExceptionId": "CLISP-exception-2.0", + "seeAlso": [ + "http://sourceforge.net/p/clisp/clisp/ci/default/tree/COPYRIGHT" + ] + }, + { + "reference": "./cryptsetup-OpenSSL-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./cryptsetup-OpenSSL-exception.html", + "referenceNumber": 5, + "name": "cryptsetup OpenSSL exception", + "licenseExceptionId": "cryptsetup-OpenSSL-exception", + "seeAlso": [ + "https://gitlab.com/cryptsetup/cryptsetup/-/blob/main/COPYING", + "https://gitlab.nic.cz/datovka/datovka/-/blob/develop/COPYING", + "https://github.com/nbs-system/naxsi/blob/951123ad456bdf5ac94e8d8819342fe3d49bc002/naxsi_src/naxsi_raw.c", + "http://web.mit.edu/jgross/arch/amd64_deb60/bin/mosh", + "https://sourceforge.net/p/linux-ima/ima-evm-utils/ci/master/tree/src/evmctl.c#l30" + ] + }, + { + "reference": "./DigiRule-FOSS-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./DigiRule-FOSS-exception.html", + "referenceNumber": 66, + "name": "DigiRule FOSS License Exception", + "licenseExceptionId": "DigiRule-FOSS-exception", + "seeAlso": [ + "http://www.digirulesolutions.com/drupal/foss" + ] + }, + { + "reference": "./eCos-exception-2.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./eCos-exception-2.0.html", + "referenceNumber": 35, + "name": "eCos exception 2.0", + "licenseExceptionId": "eCos-exception-2.0", + "seeAlso": [ + "http://ecos.sourceware.org/license-overview.html" + ] + }, + { + "reference": "./erlang-otp-linking-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./erlang-otp-linking-exception.html", + "referenceNumber": 46, + "name": "Erlang/OTP Linking Exception", + "licenseExceptionId": "erlang-otp-linking-exception", + "seeAlso": [ + "https://www.gnu.org/licenses/gpl-faq.en.html#GPLIncompatibleLibs", + "https://erlang.org/pipermail/erlang-questions/2012-May/066355.html", + "https://gitea.osmocom.org/erlang/osmo_ss7/src/commit/2286c1b8738d715950026650bf53f19a69d6ed0e/src/ss7_links.erl#L20" + ] + }, + { + "reference": "./Fawkes-Runtime-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Fawkes-Runtime-exception.html", + "referenceNumber": 23, + "name": "Fawkes Runtime Exception", + "licenseExceptionId": "Fawkes-Runtime-exception", + "seeAlso": [ + "http://www.fawkesrobotics.org/about/license/" + ] + }, + { + "reference": "./FLTK-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./FLTK-exception.html", + "referenceNumber": 9, + "name": "FLTK exception", + "licenseExceptionId": "FLTK-exception", + "seeAlso": [ + "http://www.fltk.org/COPYING.php" + ] + }, + { + "reference": "./fmt-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./fmt-exception.html", + "referenceNumber": 69, + "name": "fmt exception", + "licenseExceptionId": "fmt-exception", + "seeAlso": [ + "https://github.com/fmtlib/fmt/blob/master/LICENSE", + "https://github.com/fmtlib/fmt/blob/2eb363297b24cd71a68ccfb20ff755430f17e60f/LICENSE#L22C1-L27C62" + ] + }, + { + "reference": "./Font-exception-2.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Font-exception-2.0.html", + "referenceNumber": 19, + "name": "Font exception 2.0", + "licenseExceptionId": "Font-exception-2.0", + "seeAlso": [ + "http://www.gnu.org/licenses/gpl-faq.html#FontException" + ] + }, + { + "reference": "./freertos-exception-2.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./freertos-exception-2.0.html", + "referenceNumber": 54, + "name": "FreeRTOS Exception 2.0", + "licenseExceptionId": "freertos-exception-2.0", + "seeAlso": [ + "https://web.archive.org/web/20060809182744/http://www.freertos.org/a00114.html" + ] + }, + { + "reference": "./GCC-exception-2.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./GCC-exception-2.0.html", + "referenceNumber": 14, + "name": "GCC Runtime Library exception 2.0", + "licenseExceptionId": "GCC-exception-2.0", + "seeAlso": [ + "https://gcc.gnu.org/git/?p\u003dgcc.git;a\u003dblob;f\u003dgcc/libgcc1.c;h\u003d762f5143fc6eed57b6797c82710f3538aa52b40b;hb\u003dcb143a3ce4fb417c68f5fa2691a1b1b1053dfba9#l10", + "https://sourceware.org/git/?p\u003dglibc.git;a\u003dblob;f\u003dcsu/abi-note.c;h\u003dc2ec208e94fbe91f63d3c375bd254b884695d190;hb\u003dHEAD" + ] + }, + { + "reference": "./GCC-exception-2.0-note.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./GCC-exception-2.0-note.html", + "referenceNumber": 55, + "name": "GCC Runtime Library exception 2.0 - note variant", + "licenseExceptionId": "GCC-exception-2.0-note", + "seeAlso": [ + "https://sourceware.org/git/?p\u003dglibc.git;a\u003dblob;f\u003dsysdeps/x86_64/start.S" + ] + }, + { + "reference": "./GCC-exception-3.1.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./GCC-exception-3.1.html", + "referenceNumber": 6, + "name": "GCC Runtime Library exception 3.1", + "licenseExceptionId": "GCC-exception-3.1", + "seeAlso": [ + "http://www.gnu.org/licenses/gcc-exception-3.1.html" + ] + }, + { + "reference": "./Gmsh-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Gmsh-exception.html", + "referenceNumber": 58, + "name": "Gmsh exception\u003e", + "licenseExceptionId": "Gmsh-exception", + "seeAlso": [ + "https://gitlab.onelab.info/gmsh/gmsh/-/raw/master/LICENSE.txt" + ] + }, + { + "reference": "./GNAT-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./GNAT-exception.html", + "referenceNumber": 26, + "name": "GNAT exception", + "licenseExceptionId": "GNAT-exception", + "seeAlso": [ + "https://github.com/AdaCore/florist/blob/master/libsrc/posix-configurable_file_limits.adb" + ] + }, + { + "reference": "./GNOME-examples-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./GNOME-examples-exception.html", + "referenceNumber": 12, + "name": "GNOME examples exception", + "licenseExceptionId": "GNOME-examples-exception", + "seeAlso": [ + "https://gitlab.gnome.org/Archive/gnome-devel-docs/-/blob/master/platform-demos/C/legal.xml?ref_type\u003dheads", + "http://meldmerge.org/help/" + ] + }, + { + "reference": "./GNU-compiler-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./GNU-compiler-exception.html", + "referenceNumber": 18, + "name": "GNU Compiler Exception", + "licenseExceptionId": "GNU-compiler-exception", + "seeAlso": [ + "https://sourceware.org/git?p\u003dbinutils-gdb.git;a\u003dblob;f\u003dlibiberty/unlink-if-ordinary.c;h\u003de49f2f2f67bfdb10d6b2bd579b0e01cad0fd708e;hb\u003dHEAD#l19" + ] + }, + { + "reference": "./gnu-javamail-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./gnu-javamail-exception.html", + "referenceNumber": 43, + "name": "GNU JavaMail exception", + "licenseExceptionId": "gnu-javamail-exception", + "seeAlso": [ + "http://www.gnu.org/software/classpathx/javamail/javamail.html" + ] + }, + { + "reference": "./GPL-3.0-interface-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./GPL-3.0-interface-exception.html", + "referenceNumber": 28, + "name": "GPL-3.0 Interface Exception", + "licenseExceptionId": "GPL-3.0-interface-exception", + "seeAlso": [ + "https://www.gnu.org/licenses/gpl-faq.en.html#LinkingOverControlledInterface" + ] + }, + { + "reference": "./GPL-3.0-linking-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./GPL-3.0-linking-exception.html", + "referenceNumber": 45, + "name": "GPL-3.0 Linking Exception", + "licenseExceptionId": "GPL-3.0-linking-exception", + "seeAlso": [ + "https://www.gnu.org/licenses/gpl-faq.en.html#GPLIncompatibleLibs" + ] + }, + { + "reference": "./GPL-3.0-linking-source-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./GPL-3.0-linking-source-exception.html", + "referenceNumber": 39, + "name": "GPL-3.0 Linking Exception (with Corresponding Source)", + "licenseExceptionId": "GPL-3.0-linking-source-exception", + "seeAlso": [ + "https://www.gnu.org/licenses/gpl-faq.en.html#GPLIncompatibleLibs", + "https://github.com/mirror/wget/blob/master/src/http.c#L20" + ] + }, + { + "reference": "./GPL-CC-1.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./GPL-CC-1.0.html", + "referenceNumber": 27, + "name": "GPL Cooperation Commitment 1.0", + "licenseExceptionId": "GPL-CC-1.0", + "seeAlso": [ + "https://github.com/gplcc/gplcc/blob/master/Project/COMMITMENT", + "https://gplcc.github.io/gplcc/Project/README-PROJECT.html" + ] + }, + { + "reference": "./GStreamer-exception-2005.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./GStreamer-exception-2005.html", + "referenceNumber": 63, + "name": "GStreamer Exception (2005)", + "licenseExceptionId": "GStreamer-exception-2005", + "seeAlso": [ + "https://gstreamer.freedesktop.org/documentation/frequently-asked-questions/licensing.html?gi-language\u003dc#licensing-of-applications-using-gstreamer" + ] + }, + { + "reference": "./GStreamer-exception-2008.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./GStreamer-exception-2008.html", + "referenceNumber": 30, + "name": "GStreamer Exception (2008)", + "licenseExceptionId": "GStreamer-exception-2008", + "seeAlso": [ + "https://gstreamer.freedesktop.org/documentation/frequently-asked-questions/licensing.html?gi-language\u003dc#licensing-of-applications-using-gstreamer" + ] + }, + { + "reference": "./i2p-gpl-java-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./i2p-gpl-java-exception.html", + "referenceNumber": 36, + "name": "i2p GPL+Java Exception", + "licenseExceptionId": "i2p-gpl-java-exception", + "seeAlso": [ + "http://geti2p.net/en/get-involved/develop/licenses#java_exception" + ] + }, + { + "reference": "./KiCad-libraries-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./KiCad-libraries-exception.html", + "referenceNumber": 10, + "name": "KiCad Libraries Exception", + "licenseExceptionId": "KiCad-libraries-exception", + "seeAlso": [ + "https://www.kicad.org/libraries/license/" + ] + }, + { + "reference": "./LGPL-3.0-linking-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./LGPL-3.0-linking-exception.html", + "referenceNumber": 31, + "name": "LGPL-3.0 Linking Exception", + "licenseExceptionId": "LGPL-3.0-linking-exception", + "seeAlso": [ + "https://raw.githubusercontent.com/go-xmlpath/xmlpath/v2/LICENSE", + "https://github.com/goamz/goamz/blob/master/LICENSE", + "https://github.com/juju/errors/blob/master/LICENSE" + ] + }, + { + "reference": "./libpri-OpenH323-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./libpri-OpenH323-exception.html", + "referenceNumber": 15, + "name": "libpri OpenH323 exception", + "licenseExceptionId": "libpri-OpenH323-exception", + "seeAlso": [ + "https://github.com/asterisk/libpri/blob/1.6.0/README#L19-L22" + ] + }, + { + "reference": "./Libtool-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Libtool-exception.html", + "referenceNumber": 20, + "name": "Libtool Exception", + "licenseExceptionId": "Libtool-exception", + "seeAlso": [ + "http://git.savannah.gnu.org/cgit/libtool.git/tree/m4/libtool.m4", + "https://git.savannah.gnu.org/cgit/libtool.git/tree/libltdl/lt__alloc.c#n15" + ] + }, + { + "reference": "./Linux-syscall-note.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Linux-syscall-note.html", + "referenceNumber": 52, + "name": "Linux Syscall Note", + "licenseExceptionId": "Linux-syscall-note", + "seeAlso": [ + "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/COPYING" + ] + }, + { + "reference": "./LLGPL.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./LLGPL.html", + "referenceNumber": 37, + "name": "LLGPL Preamble", + "licenseExceptionId": "LLGPL", + "seeAlso": [ + "http://opensource.franz.com/preamble.html" + ] + }, + { + "reference": "./LLVM-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./LLVM-exception.html", + "referenceNumber": 1, + "name": "LLVM Exception", + "licenseExceptionId": "LLVM-exception", + "seeAlso": [ + "http://llvm.org/foundation/relicensing/LICENSE.txt" + ] + }, + { + "reference": "./LZMA-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./LZMA-exception.html", + "referenceNumber": 61, + "name": "LZMA exception", + "licenseExceptionId": "LZMA-exception", + "seeAlso": [ + "http://nsis.sourceforge.net/Docs/AppendixI.html#I.6" + ] + }, + { + "reference": "./mif-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./mif-exception.html", + "referenceNumber": 7, + "name": "Macros and Inline Functions Exception", + "licenseExceptionId": "mif-exception", + "seeAlso": [ + "http://www.scs.stanford.edu/histar/src/lib/cppsup/exception", + "http://dev.bertos.org/doxygen/", + "https://www.threadingbuildingblocks.org/licensing" + ] + }, + { + "reference": "./Nokia-Qt-exception-1.1.json", + "isDeprecatedLicenseId": true, + "detailsUrl": "./Nokia-Qt-exception-1.1.html", + "referenceNumber": 13, + "name": "Nokia Qt LGPL exception 1.1", + "licenseExceptionId": "Nokia-Qt-exception-1.1", + "seeAlso": [ + "https://www.keepassx.org/dev/projects/keepassx/repository/revisions/b8dfb9cc4d5133e0f09cd7533d15a4f1c19a40f2/entry/LICENSE.NOKIA-LGPL-EXCEPTION" + ] + }, + { + "reference": "./OCaml-LGPL-linking-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./OCaml-LGPL-linking-exception.html", + "referenceNumber": 2, + "name": "OCaml LGPL Linking Exception", + "licenseExceptionId": "OCaml-LGPL-linking-exception", + "seeAlso": [ + "https://caml.inria.fr/ocaml/license.en.html" + ] + }, + { + "reference": "./OCCT-exception-1.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./OCCT-exception-1.0.html", + "referenceNumber": 49, + "name": "Open CASCADE Exception 1.0", + "licenseExceptionId": "OCCT-exception-1.0", + "seeAlso": [ + "http://www.opencascade.com/content/licensing" + ] + }, + { + "reference": "./OpenJDK-assembly-exception-1.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./OpenJDK-assembly-exception-1.0.html", + "referenceNumber": 44, + "name": "OpenJDK Assembly exception 1.0", + "licenseExceptionId": "OpenJDK-assembly-exception-1.0", + "seeAlso": [ + "http://openjdk.java.net/legal/assembly-exception.html" + ] + }, + { + "reference": "./openvpn-openssl-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./openvpn-openssl-exception.html", + "referenceNumber": 29, + "name": "OpenVPN OpenSSL Exception", + "licenseExceptionId": "openvpn-openssl-exception", + "seeAlso": [ + "http://openvpn.net/index.php/license.html", + "https://github.com/psycopg/psycopg2/blob/2_9_3/LICENSE#L14" + ] + }, + { + "reference": "./PCRE2-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./PCRE2-exception.html", + "referenceNumber": 8, + "name": "PCRE2 exception", + "licenseExceptionId": "PCRE2-exception", + "seeAlso": [ + "https://www.pcre.org/licence.txt" + ] + }, + { + "reference": "./PS-or-PDF-font-exception-20170817.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./PS-or-PDF-font-exception-20170817.html", + "referenceNumber": 16, + "name": "PS/PDF font exception (2017-08-17)", + "licenseExceptionId": "PS-or-PDF-font-exception-20170817", + "seeAlso": [ + "https://github.com/ArtifexSoftware/urw-base35-fonts/blob/65962e27febc3883a17e651cdb23e783668c996f/LICENSE" + ] + }, + { + "reference": "./QPL-1.0-INRIA-2004-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./QPL-1.0-INRIA-2004-exception.html", + "referenceNumber": 68, + "name": "INRIA QPL 1.0 2004 variant exception", + "licenseExceptionId": "QPL-1.0-INRIA-2004-exception", + "seeAlso": [ + "https://git.frama-c.com/pub/frama-c/-/blob/master/licenses/Q_MODIFIED_LICENSE", + "https://github.com/maranget/hevea/blob/master/LICENSE" + ] + }, + { + "reference": "./Qt-GPL-exception-1.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Qt-GPL-exception-1.0.html", + "referenceNumber": 50, + "name": "Qt GPL exception 1.0", + "licenseExceptionId": "Qt-GPL-exception-1.0", + "seeAlso": [ + "http://code.qt.io/cgit/qt/qtbase.git/tree/LICENSE.GPL3-EXCEPT" + ] + }, + { + "reference": "./Qt-LGPL-exception-1.1.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Qt-LGPL-exception-1.1.html", + "referenceNumber": 38, + "name": "Qt LGPL exception 1.1", + "licenseExceptionId": "Qt-LGPL-exception-1.1", + "seeAlso": [ + "http://code.qt.io/cgit/qt/qtbase.git/tree/LGPL_EXCEPTION.txt" + ] + }, + { + "reference": "./Qwt-exception-1.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Qwt-exception-1.0.html", + "referenceNumber": 25, + "name": "Qwt exception 1.0", + "licenseExceptionId": "Qwt-exception-1.0", + "seeAlso": [ + "http://qwt.sourceforge.net/qwtlicense.html" + ] + }, + { + "reference": "./romic-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./romic-exception.html", + "referenceNumber": 22, + "name": "Romic Exception", + "licenseExceptionId": "romic-exception", + "seeAlso": [ + "https://web.archive.org/web/20210124015834/http://mo.morsi.org/blog/2009/08/13/lesser_affero_gplv3/", + "https://sourceforge.net/p/romic/code/ci/3ab2856180cf0d8b007609af53154cf092efc58f/tree/COPYING", + "https://github.com/moll/node-mitm/blob/bbf24b8bd7596dc6e091e625363161ce91984fc7/LICENSE#L8-L11", + "https://github.com/zenbones/SmallMind/blob/3c62b5995fe7f27c453f140ff9b60560a0893f2a/COPYRIGHT#L25-L30", + "https://github.com/CubeArtisan/cubeartisan/blob/2c6ab53455237b88a3ea07be02a838a135c4ab79/LICENSE.LESSER#L10-L15", + "https://github.com/savearray2/py.js/blob/b781273c08c8afa89f4954de4ecf42ec01429bae/README.md#license" + ] + }, + { + "reference": "./RRDtool-FLOSS-exception-2.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./RRDtool-FLOSS-exception-2.0.html", + "referenceNumber": 4, + "name": "RRDtool FLOSS exception 2.0", + "licenseExceptionId": "RRDtool-FLOSS-exception-2.0", + "seeAlso": [ + "https://github.com/oetiker/rrdtool-1.x/blob/master/COPYRIGHT#L25-L90", + "https://oss.oetiker.ch/rrdtool/license.en.html" + ] + }, + { + "reference": "./SANE-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./SANE-exception.html", + "referenceNumber": 11, + "name": "SANE Exception", + "licenseExceptionId": "SANE-exception", + "seeAlso": [ + "https://github.com/alexpevzner/sane-airscan/blob/master/LICENSE", + "https://gitlab.com/sane-project/backends/-/blob/master/sanei/sanei_pp.c?ref_type\u003dheads", + "https://gitlab.com/sane-project/frontends/-/blob/master/sanei/sanei_codec_ascii.c?ref_type\u003dheads" + ] + }, + { + "reference": "./SHL-2.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./SHL-2.0.html", + "referenceNumber": 56, + "name": "Solderpad Hardware License v2.0", + "licenseExceptionId": "SHL-2.0", + "seeAlso": [ + "https://solderpad.org/licenses/SHL-2.0/" + ] + }, + { + "reference": "./SHL-2.1.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./SHL-2.1.html", + "referenceNumber": 65, + "name": "Solderpad Hardware License v2.1", + "licenseExceptionId": "SHL-2.1", + "seeAlso": [ + "https://solderpad.org/licenses/SHL-2.1/" + ] + }, + { + "reference": "./stunnel-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./stunnel-exception.html", + "referenceNumber": 70, + "name": "stunnel Exception", + "licenseExceptionId": "stunnel-exception", + "seeAlso": [ + "https://github.com/mtrojnar/stunnel/blob/master/COPYING.md" + ] + }, + { + "reference": "./SWI-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./SWI-exception.html", + "referenceNumber": 41, + "name": "SWI exception", + "licenseExceptionId": "SWI-exception", + "seeAlso": [ + "https://github.com/SWI-Prolog/packages-clpqr/blob/bfa80b9270274f0800120d5b8e6fef42ac2dc6a5/clpqr/class.pl" + ] + }, + { + "reference": "./Swift-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Swift-exception.html", + "referenceNumber": 33, + "name": "Swift Exception", + "licenseExceptionId": "Swift-exception", + "seeAlso": [ + "https://swift.org/LICENSE.txt", + "https://github.com/apple/swift-package-manager/blob/7ab2275f447a5eb37497ed63a9340f8a6d1e488b/LICENSE.txt#L205" + ] + }, + { + "reference": "./Texinfo-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Texinfo-exception.html", + "referenceNumber": 67, + "name": "Texinfo exception", + "licenseExceptionId": "Texinfo-exception", + "seeAlso": [ + "https://git.savannah.gnu.org/cgit/automake.git/tree/lib/texinfo.tex?h\u003dv1.16.5#n23" + ] + }, + { + "reference": "./u-boot-exception-2.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./u-boot-exception-2.0.html", + "referenceNumber": 3, + "name": "U-Boot exception 2.0", + "licenseExceptionId": "u-boot-exception-2.0", + "seeAlso": [ + "http://git.denx.de/?p\u003du-boot.git;a\u003dblob;f\u003dLicenses/Exceptions" + ] + }, + { + "reference": "./UBDL-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./UBDL-exception.html", + "referenceNumber": 62, + "name": "Unmodified Binary Distribution exception", + "licenseExceptionId": "UBDL-exception", + "seeAlso": [ + "https://github.com/ipxe/ipxe/blob/master/COPYING.UBDL" + ] + }, + { + "reference": "./Universal-FOSS-exception-1.0.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./Universal-FOSS-exception-1.0.html", + "referenceNumber": 42, + "name": "Universal FOSS Exception, Version 1.0", + "licenseExceptionId": "Universal-FOSS-exception-1.0", + "seeAlso": [ + "https://oss.oracle.com/licenses/universal-foss-exception/" + ] + }, + { + "reference": "./vsftpd-openssl-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./vsftpd-openssl-exception.html", + "referenceNumber": 32, + "name": "vsftpd OpenSSL exception", + "licenseExceptionId": "vsftpd-openssl-exception", + "seeAlso": [ + "https://git.stg.centos.org/source-git/vsftpd/blob/f727873674d9c9cd7afcae6677aa782eb54c8362/f/LICENSE", + "https://launchpad.net/debian/squeeze/+source/vsftpd/+copyright", + "https://github.com/richardcochran/vsftpd/blob/master/COPYING" + ] + }, + { + "reference": "./WxWindows-exception-3.1.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./WxWindows-exception-3.1.html", + "referenceNumber": 57, + "name": "WxWindows Library Exception 3.1", + "licenseExceptionId": "WxWindows-exception-3.1", + "seeAlso": [ + "http://www.opensource.org/licenses/WXwindows" + ] + }, + { + "reference": "./x11vnc-openssl-exception.json", + "isDeprecatedLicenseId": false, + "detailsUrl": "./x11vnc-openssl-exception.html", + "referenceNumber": 47, + "name": "x11vnc OpenSSL Exception", + "licenseExceptionId": "x11vnc-openssl-exception", + "seeAlso": [ + "https://github.com/LibVNC/x11vnc/blob/master/src/8to24.c#L22" + ] + } + ], + "releaseDate": "2024-08-19" +} diff --git a/license-list-data/licenses-3.25.json b/license-list-data/licenses-3.25.json new file mode 100644 index 00000000000..5db03b48941 --- /dev/null +++ b/license-list-data/licenses-3.25.json @@ -0,0 +1,8360 @@ +{ + "licenseListVersion": "3.25.0", + "licenses": [ + { + "reference": "https://spdx.org/licenses/0BSD.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/0BSD.json", + "referenceNumber": 582, + "name": "BSD Zero Clause License", + "licenseId": "0BSD", + "seeAlso": [ + "http://landley.net/toybox/license.html", + "https://opensource.org/licenses/0BSD" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/3D-Slicer-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/3D-Slicer-1.0.json", + "referenceNumber": 466, + "name": "3D Slicer License v1.0", + "licenseId": "3D-Slicer-1.0", + "seeAlso": [ + "https://slicer.org/LICENSE", + "https://github.com/Slicer/Slicer/blob/main/License.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/AAL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AAL.json", + "referenceNumber": 252, + "name": "Attribution Assurance License", + "licenseId": "AAL", + "seeAlso": [ + "https://opensource.org/licenses/attribution" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/Abstyles.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Abstyles.json", + "referenceNumber": 456, + "name": "Abstyles License", + "licenseId": "Abstyles", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Abstyles" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/AdaCore-doc.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AdaCore-doc.json", + "referenceNumber": 355, + "name": "AdaCore Doc License", + "licenseId": "AdaCore-doc", + "seeAlso": [ + "https://github.com/AdaCore/xmlada/blob/master/docs/index.rst", + "https://github.com/AdaCore/gnatcoll-core/blob/master/docs/index.rst", + "https://github.com/AdaCore/gnatcoll-db/blob/master/docs/index.rst" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Adobe-2006.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Adobe-2006.json", + "referenceNumber": 128, + "name": "Adobe Systems Incorporated Source Code License Agreement", + "licenseId": "Adobe-2006", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/AdobeLicense" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Adobe-Display-PostScript.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Adobe-Display-PostScript.json", + "referenceNumber": 433, + "name": "Adobe Display PostScript License", + "licenseId": "Adobe-Display-PostScript", + "seeAlso": [ + "https://gitlab.freedesktop.org/xorg/xserver/-/blob/master/COPYING?ref_type\u003dheads#L752" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Adobe-Glyph.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Adobe-Glyph.json", + "referenceNumber": 125, + "name": "Adobe Glyph List License", + "licenseId": "Adobe-Glyph", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/MIT#AdobeGlyph" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Adobe-Utopia.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Adobe-Utopia.json", + "referenceNumber": 495, + "name": "Adobe Utopia Font License", + "licenseId": "Adobe-Utopia", + "seeAlso": [ + "https://gitlab.freedesktop.org/xorg/font/adobe-utopia-100dpi/-/blob/master/COPYING?ref_type\u003dheads" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/ADSL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ADSL.json", + "referenceNumber": 560, + "name": "Amazon Digital Services License", + "licenseId": "ADSL", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/AmazonDigitalServicesLicense" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/AFL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AFL-1.1.json", + "referenceNumber": 14, + "name": "Academic Free License v1.1", + "licenseId": "AFL-1.1", + "seeAlso": [ + "http://opensource.linux-mirror.org/licenses/afl-1.1.txt", + "http://wayback.archive.org/web/20021004124254/http://www.opensource.org/licenses/academic.php" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/AFL-1.2.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AFL-1.2.json", + "referenceNumber": 622, + "name": "Academic Free License v1.2", + "licenseId": "AFL-1.2", + "seeAlso": [ + "http://opensource.linux-mirror.org/licenses/afl-1.2.txt", + "http://wayback.archive.org/web/20021204204652/http://www.opensource.org/licenses/academic.php" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/AFL-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AFL-2.0.json", + "referenceNumber": 559, + "name": "Academic Free License v2.0", + "licenseId": "AFL-2.0", + "seeAlso": [ + "http://wayback.archive.org/web/20060924134533/http://www.opensource.org/licenses/afl-2.0.txt" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/AFL-2.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AFL-2.1.json", + "referenceNumber": 570, + "name": "Academic Free License v2.1", + "licenseId": "AFL-2.1", + "seeAlso": [ + "http://opensource.linux-mirror.org/licenses/afl-2.1.txt" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/AFL-3.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AFL-3.0.json", + "referenceNumber": 332, + "name": "Academic Free License v3.0", + "licenseId": "AFL-3.0", + "seeAlso": [ + "http://www.rosenlaw.com/AFL3.0.htm", + "https://opensource.org/licenses/afl-3.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Afmparse.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Afmparse.json", + "referenceNumber": 163, + "name": "Afmparse License", + "licenseId": "Afmparse", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Afmparse" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/AGPL-1.0.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/AGPL-1.0.json", + "referenceNumber": 657, + "name": "Affero General Public License v1.0", + "licenseId": "AGPL-1.0", + "seeAlso": [ + "http://www.affero.org/oagpl.html" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/AGPL-1.0-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AGPL-1.0-only.json", + "referenceNumber": 142, + "name": "Affero General Public License v1.0 only", + "licenseId": "AGPL-1.0-only", + "seeAlso": [ + "http://www.affero.org/oagpl.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/AGPL-1.0-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AGPL-1.0-or-later.json", + "referenceNumber": 155, + "name": "Affero General Public License v1.0 or later", + "licenseId": "AGPL-1.0-or-later", + "seeAlso": [ + "http://www.affero.org/oagpl.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/AGPL-3.0.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/AGPL-3.0.json", + "referenceNumber": 70, + "name": "GNU Affero General Public License v3.0", + "licenseId": "AGPL-3.0", + "seeAlso": [ + "https://www.gnu.org/licenses/agpl.txt", + "https://opensource.org/licenses/AGPL-3.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/AGPL-3.0-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AGPL-3.0-only.json", + "referenceNumber": 330, + "name": "GNU Affero General Public License v3.0 only", + "licenseId": "AGPL-3.0-only", + "seeAlso": [ + "https://www.gnu.org/licenses/agpl.txt", + "https://opensource.org/licenses/AGPL-3.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/AGPL-3.0-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AGPL-3.0-or-later.json", + "referenceNumber": 366, + "name": "GNU Affero General Public License v3.0 or later", + "licenseId": "AGPL-3.0-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/agpl.txt", + "https://opensource.org/licenses/AGPL-3.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Aladdin.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Aladdin.json", + "referenceNumber": 557, + "name": "Aladdin Free Public License", + "licenseId": "Aladdin", + "seeAlso": [ + "http://pages.cs.wisc.edu/~ghost/doc/AFPL/6.01/Public.htm" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/AMD-newlib.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AMD-newlib.json", + "referenceNumber": 340, + "name": "AMD newlib License", + "licenseId": "AMD-newlib", + "seeAlso": [ + "https://sourceware.org/git/?p\u003dnewlib-cygwin.git;a\u003dblob;f\u003dnewlib/libc/sys/a29khif/_close.S;h\u003d04f52ae00de1dafbd9055ad8d73c5c697a3aae7f;hb\u003dHEAD" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/AMDPLPA.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AMDPLPA.json", + "referenceNumber": 467, + "name": "AMD\u0027s plpa_map.c License", + "licenseId": "AMDPLPA", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/AMD_plpa_map_License" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/AML.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AML.json", + "referenceNumber": 299, + "name": "Apple MIT License", + "licenseId": "AML", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Apple_MIT_License" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/AML-glslang.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AML-glslang.json", + "referenceNumber": 567, + "name": "AML glslang variant License", + "licenseId": "AML-glslang", + "seeAlso": [ + "https://github.com/KhronosGroup/glslang/blob/main/LICENSE.txt#L949", + "https://docs.omniverse.nvidia.com/install-guide/latest/common/licenses.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/AMPAS.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/AMPAS.json", + "referenceNumber": 414, + "name": "Academy of Motion Picture Arts and Sciences BSD", + "licenseId": "AMPAS", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/BSD#AMPASBSD" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/ANTLR-PD.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ANTLR-PD.json", + "referenceNumber": 460, + "name": "ANTLR Software Rights Notice", + "licenseId": "ANTLR-PD", + "seeAlso": [ + "http://www.antlr2.org/license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/ANTLR-PD-fallback.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ANTLR-PD-fallback.json", + "referenceNumber": 65, + "name": "ANTLR Software Rights Notice with license fallback", + "licenseId": "ANTLR-PD-fallback", + "seeAlso": [ + "http://www.antlr2.org/license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/any-OSI.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/any-OSI.json", + "referenceNumber": 310, + "name": "Any OSI License", + "licenseId": "any-OSI", + "seeAlso": [ + "https://metacpan.org/pod/Exporter::Tidy#LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Apache-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Apache-1.0.json", + "referenceNumber": 250, + "name": "Apache License 1.0", + "licenseId": "Apache-1.0", + "seeAlso": [ + "http://www.apache.org/licenses/LICENSE-1.0" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Apache-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Apache-1.1.json", + "referenceNumber": 288, + "name": "Apache License 1.1", + "licenseId": "Apache-1.1", + "seeAlso": [ + "http://apache.org/licenses/LICENSE-1.1", + "https://opensource.org/licenses/Apache-1.1" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Apache-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Apache-2.0.json", + "referenceNumber": 143, + "name": "Apache License 2.0", + "licenseId": "Apache-2.0", + "seeAlso": [ + "https://www.apache.org/licenses/LICENSE-2.0", + "https://opensource.org/licenses/Apache-2.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/APAFML.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/APAFML.json", + "referenceNumber": 636, + "name": "Adobe Postscript AFM License", + "licenseId": "APAFML", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/AdobePostscriptAFM" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/APL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/APL-1.0.json", + "referenceNumber": 85, + "name": "Adaptive Public License 1.0", + "licenseId": "APL-1.0", + "seeAlso": [ + "https://opensource.org/licenses/APL-1.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/App-s2p.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/App-s2p.json", + "referenceNumber": 238, + "name": "App::s2p License", + "licenseId": "App-s2p", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/App-s2p" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/APSL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/APSL-1.0.json", + "referenceNumber": 335, + "name": "Apple Public Source License 1.0", + "licenseId": "APSL-1.0", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Apple_Public_Source_License_1.0" + ], + "isOsiApproved": true, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/APSL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/APSL-1.1.json", + "referenceNumber": 308, + "name": "Apple Public Source License 1.1", + "licenseId": "APSL-1.1", + "seeAlso": [ + "http://www.opensource.apple.com/source/IOSerialFamily/IOSerialFamily-7/APPLE_LICENSE" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/APSL-1.2.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/APSL-1.2.json", + "referenceNumber": 280, + "name": "Apple Public Source License 1.2", + "licenseId": "APSL-1.2", + "seeAlso": [ + "http://www.samurajdata.se/opensource/mirror/licenses/apsl.php" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/APSL-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/APSL-2.0.json", + "referenceNumber": 592, + "name": "Apple Public Source License 2.0", + "licenseId": "APSL-2.0", + "seeAlso": [ + "http://www.opensource.apple.com/license/apsl/" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Arphic-1999.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Arphic-1999.json", + "referenceNumber": 32, + "name": "Arphic Public License", + "licenseId": "Arphic-1999", + "seeAlso": [ + "http://ftp.gnu.org/gnu/non-gnu/chinese-fonts-truetype/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Artistic-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Artistic-1.0.json", + "referenceNumber": 138, + "name": "Artistic License 1.0", + "licenseId": "Artistic-1.0", + "seeAlso": [ + "https://opensource.org/licenses/Artistic-1.0" + ], + "isOsiApproved": true, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/Artistic-1.0-cl8.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Artistic-1.0-cl8.json", + "referenceNumber": 353, + "name": "Artistic License 1.0 w/clause 8", + "licenseId": "Artistic-1.0-cl8", + "seeAlso": [ + "https://opensource.org/licenses/Artistic-1.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/Artistic-1.0-Perl.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Artistic-1.0-Perl.json", + "referenceNumber": 660, + "name": "Artistic License 1.0 (Perl)", + "licenseId": "Artistic-1.0-Perl", + "seeAlso": [ + "http://dev.perl.org/licenses/artistic.html" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/Artistic-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Artistic-2.0.json", + "referenceNumber": 277, + "name": "Artistic License 2.0", + "licenseId": "Artistic-2.0", + "seeAlso": [ + "http://www.perlfoundation.org/artistic_license_2_0", + "https://www.perlfoundation.org/artistic-license-20.html", + "https://opensource.org/licenses/artistic-license-2.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/ASWF-Digital-Assets-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ASWF-Digital-Assets-1.0.json", + "referenceNumber": 166, + "name": "ASWF Digital Assets License version 1.0", + "licenseId": "ASWF-Digital-Assets-1.0", + "seeAlso": [ + "https://github.com/AcademySoftwareFoundation/foundation/blob/main/digital_assets/aswf_digital_assets_license_v1.0.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/ASWF-Digital-Assets-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ASWF-Digital-Assets-1.1.json", + "referenceNumber": 29, + "name": "ASWF Digital Assets License 1.1", + "licenseId": "ASWF-Digital-Assets-1.1", + "seeAlso": [ + "https://github.com/AcademySoftwareFoundation/foundation/blob/main/digital_assets/aswf_digital_assets_license_v1.1.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Baekmuk.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Baekmuk.json", + "referenceNumber": 380, + "name": "Baekmuk License", + "licenseId": "Baekmuk", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing:Baekmuk?rd\u003dLicensing/Baekmuk" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Bahyph.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Bahyph.json", + "referenceNumber": 368, + "name": "Bahyph License", + "licenseId": "Bahyph", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Bahyph" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Barr.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Barr.json", + "referenceNumber": 195, + "name": "Barr License", + "licenseId": "Barr", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Barr" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/bcrypt-Solar-Designer.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/bcrypt-Solar-Designer.json", + "referenceNumber": 478, + "name": "bcrypt Solar Designer License", + "licenseId": "bcrypt-Solar-Designer", + "seeAlso": [ + "https://github.com/bcrypt-ruby/bcrypt-ruby/blob/master/ext/mri/crypt_blowfish.c" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Beerware.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Beerware.json", + "referenceNumber": 616, + "name": "Beerware License", + "licenseId": "Beerware", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Beerware", + "https://people.freebsd.org/~phk/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Bitstream-Charter.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Bitstream-Charter.json", + "referenceNumber": 455, + "name": "Bitstream Charter Font License", + "licenseId": "Bitstream-Charter", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Charter#License_Text", + "https://raw.githubusercontent.com/blackhole89/notekit/master/data/fonts/Charter%20license.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Bitstream-Vera.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Bitstream-Vera.json", + "referenceNumber": 370, + "name": "Bitstream Vera Font License", + "licenseId": "Bitstream-Vera", + "seeAlso": [ + "https://web.archive.org/web/20080207013128/http://www.gnome.org/fonts/", + "https://docubrain.com/sites/default/files/licenses/bitstream-vera.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BitTorrent-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BitTorrent-1.0.json", + "referenceNumber": 106, + "name": "BitTorrent Open Source License v1.0", + "licenseId": "BitTorrent-1.0", + "seeAlso": [ + "http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/licenses/BitTorrent?r1\u003d1.1\u0026r2\u003d1.1.1.1\u0026diff_format\u003ds" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BitTorrent-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BitTorrent-1.1.json", + "referenceNumber": 541, + "name": "BitTorrent Open Source License v1.1", + "licenseId": "BitTorrent-1.1", + "seeAlso": [ + "http://directory.fsf.org/wiki/License:BitTorrentOSL1.1" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/blessing.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/blessing.json", + "referenceNumber": 359, + "name": "SQLite Blessing", + "licenseId": "blessing", + "seeAlso": [ + "https://www.sqlite.org/src/artifact/e33a4df7e32d742a?ln\u003d4-9", + "https://sqlite.org/src/artifact/df5091916dbb40e6" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BlueOak-1.0.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BlueOak-1.0.0.json", + "referenceNumber": 606, + "name": "Blue Oak Model License 1.0.0", + "licenseId": "BlueOak-1.0.0", + "seeAlso": [ + "https://blueoakcouncil.org/license/1.0.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/Boehm-GC.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Boehm-GC.json", + "referenceNumber": 127, + "name": "Boehm-Demers-Weiser GC License", + "licenseId": "Boehm-GC", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing:MIT#Another_Minimal_variant_(found_in_libatomic_ops)", + "https://github.com/uim/libgcroots/blob/master/COPYING", + "https://github.com/ivmai/libatomic_ops/blob/master/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Borceux.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Borceux.json", + "referenceNumber": 571, + "name": "Borceux license", + "licenseId": "Borceux", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Borceux" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Brian-Gladman-2-Clause.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Brian-Gladman-2-Clause.json", + "referenceNumber": 416, + "name": "Brian Gladman 2-Clause License", + "licenseId": "Brian-Gladman-2-Clause", + "seeAlso": [ + "https://github.com/krb5/krb5/blob/krb5-1.21.2-final/NOTICE#L140-L156", + "https://web.mit.edu/kerberos/krb5-1.21/doc/mitK5license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Brian-Gladman-3-Clause.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Brian-Gladman-3-Clause.json", + "referenceNumber": 290, + "name": "Brian Gladman 3-Clause License", + "licenseId": "Brian-Gladman-3-Clause", + "seeAlso": [ + "https://github.com/SWI-Prolog/packages-clib/blob/master/sha1/brg_endian.h" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-1-Clause.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-1-Clause.json", + "referenceNumber": 419, + "name": "BSD 1-Clause License", + "licenseId": "BSD-1-Clause", + "seeAlso": [ + "https://svnweb.freebsd.org/base/head/include/ifaddrs.h?revision\u003d326823" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/BSD-2-Clause.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause.json", + "referenceNumber": 229, + "name": "BSD 2-Clause \"Simplified\" License", + "licenseId": "BSD-2-Clause", + "seeAlso": [ + "https://opensource.org/licenses/BSD-2-Clause" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/BSD-2-Clause-Darwin.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause-Darwin.json", + "referenceNumber": 296, + "name": "BSD 2-Clause - Ian Darwin variant", + "licenseId": "BSD-2-Clause-Darwin", + "seeAlso": [ + "https://github.com/file/file/blob/master/COPYING" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-2-Clause-first-lines.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause-first-lines.json", + "referenceNumber": 217, + "name": "BSD 2-Clause - first lines requirement", + "licenseId": "BSD-2-Clause-first-lines", + "seeAlso": [ + "https://github.com/krb5/krb5/blob/krb5-1.21.2-final/NOTICE#L664-L690", + "https://web.mit.edu/kerberos/krb5-1.21/doc/mitK5license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-2-Clause-FreeBSD.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause-FreeBSD.json", + "referenceNumber": 564, + "name": "BSD 2-Clause FreeBSD License", + "licenseId": "BSD-2-Clause-FreeBSD", + "seeAlso": [ + "http://www.freebsd.org/copyright/freebsd-license.html" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/BSD-2-Clause-NetBSD.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause-NetBSD.json", + "referenceNumber": 376, + "name": "BSD 2-Clause NetBSD License", + "licenseId": "BSD-2-Clause-NetBSD", + "seeAlso": [ + "http://www.netbsd.org/about/redistribution.html#default" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/BSD-2-Clause-Patent.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause-Patent.json", + "referenceNumber": 4, + "name": "BSD-2-Clause Plus Patent License", + "licenseId": "BSD-2-Clause-Patent", + "seeAlso": [ + "https://opensource.org/licenses/BSDplusPatent" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/BSD-2-Clause-Views.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause-Views.json", + "referenceNumber": 514, + "name": "BSD 2-Clause with views sentence", + "licenseId": "BSD-2-Clause-Views", + "seeAlso": [ + "http://www.freebsd.org/copyright/freebsd-license.html", + "https://people.freebsd.org/~ivoras/wine/patch-wine-nvidia.sh", + "https://github.com/protegeproject/protege/blob/master/license.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-3-Clause.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause.json", + "referenceNumber": 584, + "name": "BSD 3-Clause \"New\" or \"Revised\" License", + "licenseId": "BSD-3-Clause", + "seeAlso": [ + "https://opensource.org/licenses/BSD-3-Clause", + "https://www.eclipse.org/org/documents/edl-v10.php" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/BSD-3-Clause-acpica.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-acpica.json", + "referenceNumber": 341, + "name": "BSD 3-Clause acpica variant", + "licenseId": "BSD-3-Clause-acpica", + "seeAlso": [ + "https://github.com/acpica/acpica/blob/master/source/common/acfileio.c#L119" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-3-Clause-Attribution.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-Attribution.json", + "referenceNumber": 71, + "name": "BSD with attribution", + "licenseId": "BSD-3-Clause-Attribution", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/BSD_with_Attribution" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-3-Clause-Clear.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-Clear.json", + "referenceNumber": 253, + "name": "BSD 3-Clause Clear License", + "licenseId": "BSD-3-Clause-Clear", + "seeAlso": [ + "http://labs.metacarta.com/license-explanation.html#license" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/BSD-3-Clause-flex.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-flex.json", + "referenceNumber": 52, + "name": "BSD 3-Clause Flex variant", + "licenseId": "BSD-3-Clause-flex", + "seeAlso": [ + "https://github.com/westes/flex/blob/master/COPYING" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-3-Clause-HP.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-HP.json", + "referenceNumber": 215, + "name": "Hewlett-Packard BSD variant license", + "licenseId": "BSD-3-Clause-HP", + "seeAlso": [ + "https://github.com/zdohnal/hplip/blob/master/COPYING#L939" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-3-Clause-LBNL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-LBNL.json", + "referenceNumber": 301, + "name": "Lawrence Berkeley National Labs BSD variant license", + "licenseId": "BSD-3-Clause-LBNL", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/LBNLBSD" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/BSD-3-Clause-Modification.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-Modification.json", + "referenceNumber": 47, + "name": "BSD 3-Clause Modification", + "licenseId": "BSD-3-Clause-Modification", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing:BSD#Modification_Variant" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-3-Clause-No-Military-License.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-No-Military-License.json", + "referenceNumber": 615, + "name": "BSD 3-Clause No Military License", + "licenseId": "BSD-3-Clause-No-Military-License", + "seeAlso": [ + "https://gitlab.syncad.com/hive/dhive/-/blob/master/LICENSE", + "https://github.com/greymass/swift-eosio/blob/master/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-3-Clause-No-Nuclear-License.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-No-Nuclear-License.json", + "referenceNumber": 647, + "name": "BSD 3-Clause No Nuclear License", + "licenseId": "BSD-3-Clause-No-Nuclear-License", + "seeAlso": [ + "http://download.oracle.com/otn-pub/java/licenses/bsd.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-3-Clause-No-Nuclear-License-2014.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-No-Nuclear-License-2014.json", + "referenceNumber": 377, + "name": "BSD 3-Clause No Nuclear License 2014", + "licenseId": "BSD-3-Clause-No-Nuclear-License-2014", + "seeAlso": [ + "https://java.net/projects/javaeetutorial/pages/BerkeleyLicense" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-3-Clause-No-Nuclear-Warranty.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-No-Nuclear-Warranty.json", + "referenceNumber": 54, + "name": "BSD 3-Clause No Nuclear Warranty", + "licenseId": "BSD-3-Clause-No-Nuclear-Warranty", + "seeAlso": [ + "https://jogamp.org/git/?p\u003dgluegen.git;a\u003dblob_plain;f\u003dLICENSE.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-3-Clause-Open-MPI.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-Open-MPI.json", + "referenceNumber": 633, + "name": "BSD 3-Clause Open MPI variant", + "licenseId": "BSD-3-Clause-Open-MPI", + "seeAlso": [ + "https://www.open-mpi.org/community/license.php", + "http://www.netlib.org/lapack/LICENSE.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-3-Clause-Sun.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-Sun.json", + "referenceNumber": 270, + "name": "BSD 3-Clause Sun Microsystems", + "licenseId": "BSD-3-Clause-Sun", + "seeAlso": [ + "https://github.com/xmlark/msv/blob/b9316e2f2270bc1606952ea4939ec87fbba157f3/xsdlib/src/main/java/com/sun/msv/datatype/regexp/InternalImpl.java" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-4-Clause.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-4-Clause.json", + "referenceNumber": 470, + "name": "BSD 4-Clause \"Original\" or \"Old\" License", + "licenseId": "BSD-4-Clause", + "seeAlso": [ + "http://directory.fsf.org/wiki/License:BSD_4Clause" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/BSD-4-Clause-Shortened.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-4-Clause-Shortened.json", + "referenceNumber": 220, + "name": "BSD 4 Clause Shortened", + "licenseId": "BSD-4-Clause-Shortened", + "seeAlso": [ + "https://metadata.ftp-master.debian.org/changelogs//main/a/arpwatch/arpwatch_2.1a15-7_copyright" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-4-Clause-UC.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-4-Clause-UC.json", + "referenceNumber": 175, + "name": "BSD-4-Clause (University of California-Specific)", + "licenseId": "BSD-4-Clause-UC", + "seeAlso": [ + "http://www.freebsd.org/copyright/license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-4.3RENO.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-4.3RENO.json", + "referenceNumber": 361, + "name": "BSD 4.3 RENO License", + "licenseId": "BSD-4.3RENO", + "seeAlso": [ + "https://sourceware.org/git/?p\u003dbinutils-gdb.git;a\u003dblob;f\u003dlibiberty/strcasecmp.c;h\u003d131d81c2ce7881fa48c363dc5bf5fb302c61ce0b;hb\u003dHEAD", + "https://git.openldap.org/openldap/openldap/-/blob/master/COPYRIGHT#L55-63" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-4.3TAHOE.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-4.3TAHOE.json", + "referenceNumber": 46, + "name": "BSD 4.3 TAHOE License", + "licenseId": "BSD-4.3TAHOE", + "seeAlso": [ + "https://github.com/389ds/389-ds-base/blob/main/ldap/include/sysexits-compat.h#L15", + "https://git.savannah.gnu.org/cgit/indent.git/tree/doc/indent.texi?id\u003da74c6b4ee49397cf330b333da1042bffa60ed14f#n1788" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-Advertising-Acknowledgement.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-Advertising-Acknowledgement.json", + "referenceNumber": 297, + "name": "BSD Advertising Acknowledgement License", + "licenseId": "BSD-Advertising-Acknowledgement", + "seeAlso": [ + "https://github.com/python-excel/xlrd/blob/master/LICENSE#L33" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-Attribution-HPND-disclaimer.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-Attribution-HPND-disclaimer.json", + "referenceNumber": 86, + "name": "BSD with Attribution and HPND disclaimer", + "licenseId": "BSD-Attribution-HPND-disclaimer", + "seeAlso": [ + "https://github.com/cyrusimap/cyrus-sasl/blob/master/COPYING" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-Inferno-Nettverk.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-Inferno-Nettverk.json", + "referenceNumber": 89, + "name": "BSD-Inferno-Nettverk", + "licenseId": "BSD-Inferno-Nettverk", + "seeAlso": [ + "https://www.inet.no/dante/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-Protection.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-Protection.json", + "referenceNumber": 394, + "name": "BSD Protection License", + "licenseId": "BSD-Protection", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/BSD_Protection_License" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-Source-beginning-file.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-Source-beginning-file.json", + "referenceNumber": 378, + "name": "BSD Source Code Attribution - beginning of file variant", + "licenseId": "BSD-Source-beginning-file", + "seeAlso": [ + "https://github.com/lattera/freebsd/blob/master/sys/cam/cam.c#L4" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-Source-Code.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-Source-Code.json", + "referenceNumber": 605, + "name": "BSD Source Code Attribution", + "licenseId": "BSD-Source-Code", + "seeAlso": [ + "https://github.com/robbiehanson/CocoaHTTPServer/blob/master/LICENSE.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-Systemics.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-Systemics.json", + "referenceNumber": 327, + "name": "Systemics BSD variant license", + "licenseId": "BSD-Systemics", + "seeAlso": [ + "https://metacpan.org/release/DPARIS/Crypt-DES-2.07/source/COPYRIGHT" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSD-Systemics-W3Works.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSD-Systemics-W3Works.json", + "referenceNumber": 427, + "name": "Systemics W3Works BSD variant license", + "licenseId": "BSD-Systemics-W3Works", + "seeAlso": [ + "https://metacpan.org/release/DPARIS/Crypt-Blowfish-2.14/source/COPYRIGHT#L7" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/BSL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BSL-1.0.json", + "referenceNumber": 334, + "name": "Boost Software License 1.0", + "licenseId": "BSL-1.0", + "seeAlso": [ + "http://www.boost.org/LICENSE_1_0.txt", + "https://opensource.org/licenses/BSL-1.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/BUSL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/BUSL-1.1.json", + "referenceNumber": 285, + "name": "Business Source License 1.1", + "licenseId": "BUSL-1.1", + "seeAlso": [ + "https://mariadb.com/bsl11/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/bzip2-1.0.5.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/bzip2-1.0.5.json", + "referenceNumber": 574, + "name": "bzip2 and libbzip2 License v1.0.5", + "licenseId": "bzip2-1.0.5", + "seeAlso": [ + "https://sourceware.org/bzip2/1.0.5/bzip2-manual-1.0.5.html", + "http://bzip.org/1.0.5/bzip2-manual-1.0.5.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/bzip2-1.0.6.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/bzip2-1.0.6.json", + "referenceNumber": 534, + "name": "bzip2 and libbzip2 License v1.0.6", + "licenseId": "bzip2-1.0.6", + "seeAlso": [ + "https://sourceware.org/git/?p\u003dbzip2.git;a\u003dblob;f\u003dLICENSE;hb\u003dbzip2-1.0.6", + "http://bzip.org/1.0.5/bzip2-manual-1.0.5.html", + "https://sourceware.org/cgit/valgrind/tree/mpi/libmpiwrap.c" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/C-UDA-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/C-UDA-1.0.json", + "referenceNumber": 162, + "name": "Computational Use of Data Agreement v1.0", + "licenseId": "C-UDA-1.0", + "seeAlso": [ + "https://github.com/microsoft/Computational-Use-of-Data-Agreement/blob/master/C-UDA-1.0.md", + "https://cdla.dev/computational-use-of-data-agreement-v1-0/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CAL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CAL-1.0.json", + "referenceNumber": 99, + "name": "Cryptographic Autonomy License 1.0", + "licenseId": "CAL-1.0", + "seeAlso": [ + "http://cryptographicautonomylicense.com/license-text.html", + "https://opensource.org/licenses/CAL-1.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/CAL-1.0-Combined-Work-Exception.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CAL-1.0-Combined-Work-Exception.json", + "referenceNumber": 333, + "name": "Cryptographic Autonomy License 1.0 (Combined Work Exception)", + "licenseId": "CAL-1.0-Combined-Work-Exception", + "seeAlso": [ + "http://cryptographicautonomylicense.com/license-text.html", + "https://opensource.org/licenses/CAL-1.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/Caldera.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Caldera.json", + "referenceNumber": 528, + "name": "Caldera License", + "licenseId": "Caldera", + "seeAlso": [ + "http://www.lemis.com/grog/UNIX/ancient-source-all.pdf" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Caldera-no-preamble.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Caldera-no-preamble.json", + "referenceNumber": 233, + "name": "Caldera License (without preamble)", + "licenseId": "Caldera-no-preamble", + "seeAlso": [ + "https://github.com/apache/apr/blob/trunk/LICENSE#L298C6-L298C29" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Catharon.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Catharon.json", + "referenceNumber": 337, + "name": "Catharon License", + "licenseId": "Catharon", + "seeAlso": [ + "https://github.com/scummvm/scummvm/blob/v2.8.0/LICENSES/CatharonLicense.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CATOSL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CATOSL-1.1.json", + "referenceNumber": 134, + "name": "Computer Associates Trusted Open Source License 1.1", + "licenseId": "CATOSL-1.1", + "seeAlso": [ + "https://opensource.org/licenses/CATOSL-1.1" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/CC-BY-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-1.0.json", + "referenceNumber": 415, + "name": "Creative Commons Attribution 1.0 Generic", + "licenseId": "CC-BY-1.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by/1.0/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-2.0.json", + "referenceNumber": 428, + "name": "Creative Commons Attribution 2.0 Generic", + "licenseId": "CC-BY-2.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by/2.0/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-2.5.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-2.5.json", + "referenceNumber": 573, + "name": "Creative Commons Attribution 2.5 Generic", + "licenseId": "CC-BY-2.5", + "seeAlso": [ + "https://creativecommons.org/licenses/by/2.5/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-2.5-AU.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-2.5-AU.json", + "referenceNumber": 388, + "name": "Creative Commons Attribution 2.5 Australia", + "licenseId": "CC-BY-2.5-AU", + "seeAlso": [ + "https://creativecommons.org/licenses/by/2.5/au/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-3.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-3.0.json", + "referenceNumber": 132, + "name": "Creative Commons Attribution 3.0 Unported", + "licenseId": "CC-BY-3.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by/3.0/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-3.0-AT.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-3.0-AT.json", + "referenceNumber": 25, + "name": "Creative Commons Attribution 3.0 Austria", + "licenseId": "CC-BY-3.0-AT", + "seeAlso": [ + "https://creativecommons.org/licenses/by/3.0/at/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-3.0-AU.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-3.0-AU.json", + "referenceNumber": 392, + "name": "Creative Commons Attribution 3.0 Australia", + "licenseId": "CC-BY-3.0-AU", + "seeAlso": [ + "https://creativecommons.org/licenses/by/3.0/au/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-3.0-DE.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-3.0-DE.json", + "referenceNumber": 21, + "name": "Creative Commons Attribution 3.0 Germany", + "licenseId": "CC-BY-3.0-DE", + "seeAlso": [ + "https://creativecommons.org/licenses/by/3.0/de/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-3.0-IGO.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-3.0-IGO.json", + "referenceNumber": 596, + "name": "Creative Commons Attribution 3.0 IGO", + "licenseId": "CC-BY-3.0-IGO", + "seeAlso": [ + "https://creativecommons.org/licenses/by/3.0/igo/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-3.0-NL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-3.0-NL.json", + "referenceNumber": 157, + "name": "Creative Commons Attribution 3.0 Netherlands", + "licenseId": "CC-BY-3.0-NL", + "seeAlso": [ + "https://creativecommons.org/licenses/by/3.0/nl/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-3.0-US.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-3.0-US.json", + "referenceNumber": 395, + "name": "Creative Commons Attribution 3.0 United States", + "licenseId": "CC-BY-3.0-US", + "seeAlso": [ + "https://creativecommons.org/licenses/by/3.0/us/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-4.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-4.0.json", + "referenceNumber": 435, + "name": "Creative Commons Attribution 4.0 International", + "licenseId": "CC-BY-4.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by/4.0/legalcode" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-1.0.json", + "referenceNumber": 641, + "name": "Creative Commons Attribution Non Commercial 1.0 Generic", + "licenseId": "CC-BY-NC-1.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc/1.0/legalcode" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-2.0.json", + "referenceNumber": 91, + "name": "Creative Commons Attribution Non Commercial 2.0 Generic", + "licenseId": "CC-BY-NC-2.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc/2.0/legalcode" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-2.5.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-2.5.json", + "referenceNumber": 465, + "name": "Creative Commons Attribution Non Commercial 2.5 Generic", + "licenseId": "CC-BY-NC-2.5", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc/2.5/legalcode" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-3.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-3.0.json", + "referenceNumber": 234, + "name": "Creative Commons Attribution Non Commercial 3.0 Unported", + "licenseId": "CC-BY-NC-3.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc/3.0/legalcode" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-3.0-DE.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-3.0-DE.json", + "referenceNumber": 354, + "name": "Creative Commons Attribution Non Commercial 3.0 Germany", + "licenseId": "CC-BY-NC-3.0-DE", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc/3.0/de/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-4.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-4.0.json", + "referenceNumber": 53, + "name": "Creative Commons Attribution Non Commercial 4.0 International", + "licenseId": "CC-BY-NC-4.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc/4.0/legalcode" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-ND-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-ND-1.0.json", + "referenceNumber": 88, + "name": "Creative Commons Attribution Non Commercial No Derivatives 1.0 Generic", + "licenseId": "CC-BY-NC-ND-1.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nd-nc/1.0/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-ND-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-ND-2.0.json", + "referenceNumber": 426, + "name": "Creative Commons Attribution Non Commercial No Derivatives 2.0 Generic", + "licenseId": "CC-BY-NC-ND-2.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-nd/2.0/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-ND-2.5.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-ND-2.5.json", + "referenceNumber": 441, + "name": "Creative Commons Attribution Non Commercial No Derivatives 2.5 Generic", + "licenseId": "CC-BY-NC-ND-2.5", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-nd/2.5/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-ND-3.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-ND-3.0.json", + "referenceNumber": 304, + "name": "Creative Commons Attribution Non Commercial No Derivatives 3.0 Unported", + "licenseId": "CC-BY-NC-ND-3.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-nd/3.0/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-ND-3.0-DE.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-ND-3.0-DE.json", + "referenceNumber": 121, + "name": "Creative Commons Attribution Non Commercial No Derivatives 3.0 Germany", + "licenseId": "CC-BY-NC-ND-3.0-DE", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-nd/3.0/de/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-ND-3.0-IGO.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-ND-3.0-IGO.json", + "referenceNumber": 171, + "name": "Creative Commons Attribution Non Commercial No Derivatives 3.0 IGO", + "licenseId": "CC-BY-NC-ND-3.0-IGO", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-nd/3.0/igo/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-ND-4.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-ND-4.0.json", + "referenceNumber": 183, + "name": "Creative Commons Attribution Non Commercial No Derivatives 4.0 International", + "licenseId": "CC-BY-NC-ND-4.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-SA-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-1.0.json", + "referenceNumber": 501, + "name": "Creative Commons Attribution Non Commercial Share Alike 1.0 Generic", + "licenseId": "CC-BY-NC-SA-1.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-sa/1.0/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-SA-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-2.0.json", + "referenceNumber": 358, + "name": "Creative Commons Attribution Non Commercial Share Alike 2.0 Generic", + "licenseId": "CC-BY-NC-SA-2.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-sa/2.0/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-SA-2.0-DE.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-2.0-DE.json", + "referenceNumber": 260, + "name": "Creative Commons Attribution Non Commercial Share Alike 2.0 Germany", + "licenseId": "CC-BY-NC-SA-2.0-DE", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-sa/2.0/de/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-SA-2.0-FR.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-2.0-FR.json", + "referenceNumber": 158, + "name": "Creative Commons Attribution-NonCommercial-ShareAlike 2.0 France", + "licenseId": "CC-BY-NC-SA-2.0-FR", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-sa/2.0/fr/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-SA-2.0-UK.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-2.0-UK.json", + "referenceNumber": 33, + "name": "Creative Commons Attribution Non Commercial Share Alike 2.0 England and Wales", + "licenseId": "CC-BY-NC-SA-2.0-UK", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-sa/2.0/uk/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-SA-2.5.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-2.5.json", + "referenceNumber": 222, + "name": "Creative Commons Attribution Non Commercial Share Alike 2.5 Generic", + "licenseId": "CC-BY-NC-SA-2.5", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-sa/2.5/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-SA-3.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-3.0.json", + "referenceNumber": 255, + "name": "Creative Commons Attribution Non Commercial Share Alike 3.0 Unported", + "licenseId": "CC-BY-NC-SA-3.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-sa/3.0/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-SA-3.0-DE.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-3.0-DE.json", + "referenceNumber": 525, + "name": "Creative Commons Attribution Non Commercial Share Alike 3.0 Germany", + "licenseId": "CC-BY-NC-SA-3.0-DE", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-sa/3.0/de/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-SA-3.0-IGO.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-3.0-IGO.json", + "referenceNumber": 244, + "name": "Creative Commons Attribution Non Commercial Share Alike 3.0 IGO", + "licenseId": "CC-BY-NC-SA-3.0-IGO", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-sa/3.0/igo/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-NC-SA-4.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-4.0.json", + "referenceNumber": 513, + "name": "Creative Commons Attribution Non Commercial Share Alike 4.0 International", + "licenseId": "CC-BY-NC-SA-4.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-ND-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-ND-1.0.json", + "referenceNumber": 474, + "name": "Creative Commons Attribution No Derivatives 1.0 Generic", + "licenseId": "CC-BY-ND-1.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nd/1.0/legalcode" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-ND-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-ND-2.0.json", + "referenceNumber": 356, + "name": "Creative Commons Attribution No Derivatives 2.0 Generic", + "licenseId": "CC-BY-ND-2.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nd/2.0/legalcode" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-ND-2.5.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-ND-2.5.json", + "referenceNumber": 259, + "name": "Creative Commons Attribution No Derivatives 2.5 Generic", + "licenseId": "CC-BY-ND-2.5", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nd/2.5/legalcode" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-ND-3.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-ND-3.0.json", + "referenceNumber": 527, + "name": "Creative Commons Attribution No Derivatives 3.0 Unported", + "licenseId": "CC-BY-ND-3.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nd/3.0/legalcode" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-ND-3.0-DE.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-ND-3.0-DE.json", + "referenceNumber": 214, + "name": "Creative Commons Attribution No Derivatives 3.0 Germany", + "licenseId": "CC-BY-ND-3.0-DE", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nd/3.0/de/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-ND-4.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-ND-4.0.json", + "referenceNumber": 481, + "name": "Creative Commons Attribution No Derivatives 4.0 International", + "licenseId": "CC-BY-ND-4.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-nd/4.0/legalcode" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-SA-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-1.0.json", + "referenceNumber": 588, + "name": "Creative Commons Attribution Share Alike 1.0 Generic", + "licenseId": "CC-BY-SA-1.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-sa/1.0/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-SA-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-2.0.json", + "referenceNumber": 180, + "name": "Creative Commons Attribution Share Alike 2.0 Generic", + "licenseId": "CC-BY-SA-2.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-sa/2.0/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-SA-2.0-UK.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-2.0-UK.json", + "referenceNumber": 385, + "name": "Creative Commons Attribution Share Alike 2.0 England and Wales", + "licenseId": "CC-BY-SA-2.0-UK", + "seeAlso": [ + "https://creativecommons.org/licenses/by-sa/2.0/uk/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-SA-2.1-JP.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-2.1-JP.json", + "referenceNumber": 17, + "name": "Creative Commons Attribution Share Alike 2.1 Japan", + "licenseId": "CC-BY-SA-2.1-JP", + "seeAlso": [ + "https://creativecommons.org/licenses/by-sa/2.1/jp/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-SA-2.5.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-2.5.json", + "referenceNumber": 607, + "name": "Creative Commons Attribution Share Alike 2.5 Generic", + "licenseId": "CC-BY-SA-2.5", + "seeAlso": [ + "https://creativecommons.org/licenses/by-sa/2.5/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-SA-3.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-3.0.json", + "referenceNumber": 26, + "name": "Creative Commons Attribution Share Alike 3.0 Unported", + "licenseId": "CC-BY-SA-3.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-sa/3.0/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-SA-3.0-AT.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-3.0-AT.json", + "referenceNumber": 398, + "name": "Creative Commons Attribution Share Alike 3.0 Austria", + "licenseId": "CC-BY-SA-3.0-AT", + "seeAlso": [ + "https://creativecommons.org/licenses/by-sa/3.0/at/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-SA-3.0-DE.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-3.0-DE.json", + "referenceNumber": 120, + "name": "Creative Commons Attribution Share Alike 3.0 Germany", + "licenseId": "CC-BY-SA-3.0-DE", + "seeAlso": [ + "https://creativecommons.org/licenses/by-sa/3.0/de/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-SA-3.0-IGO.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-3.0-IGO.json", + "referenceNumber": 519, + "name": "Creative Commons Attribution-ShareAlike 3.0 IGO", + "licenseId": "CC-BY-SA-3.0-IGO", + "seeAlso": [ + "https://creativecommons.org/licenses/by-sa/3.0/igo/legalcode" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC-BY-SA-4.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-4.0.json", + "referenceNumber": 13, + "name": "Creative Commons Attribution Share Alike 4.0 International", + "licenseId": "CC-BY-SA-4.0", + "seeAlso": [ + "https://creativecommons.org/licenses/by-sa/4.0/legalcode" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/CC-PDDC.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC-PDDC.json", + "referenceNumber": 169, + "name": "Creative Commons Public Domain Dedication and Certification", + "licenseId": "CC-PDDC", + "seeAlso": [ + "https://creativecommons.org/licenses/publicdomain/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CC0-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CC0-1.0.json", + "referenceNumber": 491, + "name": "Creative Commons Zero v1.0 Universal", + "licenseId": "CC0-1.0", + "seeAlso": [ + "https://creativecommons.org/publicdomain/zero/1.0/legalcode" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/CDDL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CDDL-1.0.json", + "referenceNumber": 185, + "name": "Common Development and Distribution License 1.0", + "licenseId": "CDDL-1.0", + "seeAlso": [ + "https://opensource.org/licenses/cddl1" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/CDDL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CDDL-1.1.json", + "referenceNumber": 476, + "name": "Common Development and Distribution License 1.1", + "licenseId": "CDDL-1.1", + "seeAlso": [ + "http://glassfish.java.net/public/CDDL+GPL_1_1.html", + "https://javaee.github.io/glassfish/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CDL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CDL-1.0.json", + "referenceNumber": 305, + "name": "Common Documentation License 1.0", + "licenseId": "CDL-1.0", + "seeAlso": [ + "http://www.opensource.apple.com/cdl/", + "https://fedoraproject.org/wiki/Licensing/Common_Documentation_License", + "https://www.gnu.org/licenses/license-list.html#ACDL" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CDLA-Permissive-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CDLA-Permissive-1.0.json", + "referenceNumber": 386, + "name": "Community Data License Agreement Permissive 1.0", + "licenseId": "CDLA-Permissive-1.0", + "seeAlso": [ + "https://cdla.io/permissive-1-0" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CDLA-Permissive-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CDLA-Permissive-2.0.json", + "referenceNumber": 590, + "name": "Community Data License Agreement Permissive 2.0", + "licenseId": "CDLA-Permissive-2.0", + "seeAlso": [ + "https://cdla.dev/permissive-2-0" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CDLA-Sharing-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CDLA-Sharing-1.0.json", + "referenceNumber": 190, + "name": "Community Data License Agreement Sharing 1.0", + "licenseId": "CDLA-Sharing-1.0", + "seeAlso": [ + "https://cdla.io/sharing-1-0" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CECILL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CECILL-1.0.json", + "referenceNumber": 625, + "name": "CeCILL Free Software License Agreement v1.0", + "licenseId": "CECILL-1.0", + "seeAlso": [ + "http://www.cecill.info/licences/Licence_CeCILL_V1-fr.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CECILL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CECILL-1.1.json", + "referenceNumber": 326, + "name": "CeCILL Free Software License Agreement v1.1", + "licenseId": "CECILL-1.1", + "seeAlso": [ + "http://www.cecill.info/licences/Licence_CeCILL_V1.1-US.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CECILL-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CECILL-2.0.json", + "referenceNumber": 463, + "name": "CeCILL Free Software License Agreement v2.0", + "licenseId": "CECILL-2.0", + "seeAlso": [ + "http://www.cecill.info/licences/Licence_CeCILL_V2-en.html" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/CECILL-2.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CECILL-2.1.json", + "referenceNumber": 170, + "name": "CeCILL Free Software License Agreement v2.1", + "licenseId": "CECILL-2.1", + "seeAlso": [ + "http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.html" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/CECILL-B.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CECILL-B.json", + "referenceNumber": 196, + "name": "CeCILL-B Free Software License Agreement", + "licenseId": "CECILL-B", + "seeAlso": [ + "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/CECILL-C.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CECILL-C.json", + "referenceNumber": 178, + "name": "CeCILL-C Free Software License Agreement", + "licenseId": "CECILL-C", + "seeAlso": [ + "http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/CERN-OHL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CERN-OHL-1.1.json", + "referenceNumber": 148, + "name": "CERN Open Hardware Licence v1.1", + "licenseId": "CERN-OHL-1.1", + "seeAlso": [ + "https://www.ohwr.org/project/licenses/wikis/cern-ohl-v1.1" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CERN-OHL-1.2.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CERN-OHL-1.2.json", + "referenceNumber": 651, + "name": "CERN Open Hardware Licence v1.2", + "licenseId": "CERN-OHL-1.2", + "seeAlso": [ + "https://www.ohwr.org/project/licenses/wikis/cern-ohl-v1.2" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CERN-OHL-P-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CERN-OHL-P-2.0.json", + "referenceNumber": 543, + "name": "CERN Open Hardware Licence Version 2 - Permissive", + "licenseId": "CERN-OHL-P-2.0", + "seeAlso": [ + "https://www.ohwr.org/project/cernohl/wikis/Documents/CERN-OHL-version-2" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/CERN-OHL-S-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CERN-OHL-S-2.0.json", + "referenceNumber": 396, + "name": "CERN Open Hardware Licence Version 2 - Strongly Reciprocal", + "licenseId": "CERN-OHL-S-2.0", + "seeAlso": [ + "https://www.ohwr.org/project/cernohl/wikis/Documents/CERN-OHL-version-2" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/CERN-OHL-W-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CERN-OHL-W-2.0.json", + "referenceNumber": 614, + "name": "CERN Open Hardware Licence Version 2 - Weakly Reciprocal", + "licenseId": "CERN-OHL-W-2.0", + "seeAlso": [ + "https://www.ohwr.org/project/cernohl/wikis/Documents/CERN-OHL-version-2" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/CFITSIO.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CFITSIO.json", + "referenceNumber": 568, + "name": "CFITSIO License", + "licenseId": "CFITSIO", + "seeAlso": [ + "https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/f_user/node9.html", + "https://heasarc.gsfc.nasa.gov/docs/software/ftools/fv/doc/license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/check-cvs.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/check-cvs.json", + "referenceNumber": 324, + "name": "check-cvs License", + "licenseId": "check-cvs", + "seeAlso": [ + "http://cvs.savannah.gnu.org/viewvc/cvs/ccvs/contrib/check_cvs.in?revision\u003d1.1.4.3\u0026view\u003dmarkup\u0026pathrev\u003dcvs1-11-23#l2" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/checkmk.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/checkmk.json", + "referenceNumber": 464, + "name": "Checkmk License", + "licenseId": "checkmk", + "seeAlso": [ + "https://github.com/libcheck/check/blob/master/checkmk/checkmk.in" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/ClArtistic.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ClArtistic.json", + "referenceNumber": 230, + "name": "Clarified Artistic License", + "licenseId": "ClArtistic", + "seeAlso": [ + "http://gianluca.dellavedova.org/2011/01/03/clarified-artistic-license/", + "http://www.ncftp.com/ncftp/doc/LICENSE.txt" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Clips.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Clips.json", + "referenceNumber": 424, + "name": "Clips License", + "licenseId": "Clips", + "seeAlso": [ + "https://github.com/DrItanium/maya/blob/master/LICENSE.CLIPS" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CMU-Mach.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CMU-Mach.json", + "referenceNumber": 73, + "name": "CMU Mach License", + "licenseId": "CMU-Mach", + "seeAlso": [ + "https://www.cs.cmu.edu/~410/licenses.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CMU-Mach-nodoc.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CMU-Mach-nodoc.json", + "referenceNumber": 8, + "name": "CMU Mach - no notices-in-documentation variant", + "licenseId": "CMU-Mach-nodoc", + "seeAlso": [ + "https://github.com/krb5/krb5/blob/krb5-1.21.2-final/NOTICE#L718-L728", + "https://web.mit.edu/kerberos/krb5-1.21/doc/mitK5license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CNRI-Jython.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CNRI-Jython.json", + "referenceNumber": 293, + "name": "CNRI Jython License", + "licenseId": "CNRI-Jython", + "seeAlso": [ + "http://www.jython.org/license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CNRI-Python.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CNRI-Python.json", + "referenceNumber": 402, + "name": "CNRI Python License", + "licenseId": "CNRI-Python", + "seeAlso": [ + "https://opensource.org/licenses/CNRI-Python" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/CNRI-Python-GPL-Compatible.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CNRI-Python-GPL-Compatible.json", + "referenceNumber": 224, + "name": "CNRI Python Open Source GPL Compatible License Agreement", + "licenseId": "CNRI-Python-GPL-Compatible", + "seeAlso": [ + "http://www.python.org/download/releases/1.6.1/download_win/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/COIL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/COIL-1.0.json", + "referenceNumber": 345, + "name": "Copyfree Open Innovation License", + "licenseId": "COIL-1.0", + "seeAlso": [ + "https://coil.apotheon.org/plaintext/01.0.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Community-Spec-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Community-Spec-1.0.json", + "referenceNumber": 56, + "name": "Community Specification License 1.0", + "licenseId": "Community-Spec-1.0", + "seeAlso": [ + "https://github.com/CommunitySpecification/1.0/blob/master/1._Community_Specification_License-v1.md" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Condor-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Condor-1.1.json", + "referenceNumber": 77, + "name": "Condor Public License v1.1", + "licenseId": "Condor-1.1", + "seeAlso": [ + "http://research.cs.wisc.edu/condor/license.html#condor", + "http://web.archive.org/web/20111123062036/http://research.cs.wisc.edu/condor/license.html#condor" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/copyleft-next-0.3.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/copyleft-next-0.3.0.json", + "referenceNumber": 322, + "name": "copyleft-next 0.3.0", + "licenseId": "copyleft-next-0.3.0", + "seeAlso": [ + "https://github.com/copyleft-next/copyleft-next/blob/master/Releases/copyleft-next-0.3.0" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/copyleft-next-0.3.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/copyleft-next-0.3.1.json", + "referenceNumber": 403, + "name": "copyleft-next 0.3.1", + "licenseId": "copyleft-next-0.3.1", + "seeAlso": [ + "https://github.com/copyleft-next/copyleft-next/blob/master/Releases/copyleft-next-0.3.1" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Cornell-Lossless-JPEG.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Cornell-Lossless-JPEG.json", + "referenceNumber": 98, + "name": "Cornell Lossless JPEG License", + "licenseId": "Cornell-Lossless-JPEG", + "seeAlso": [ + "https://android.googlesource.com/platform/external/dng_sdk/+/refs/heads/master/source/dng_lossless_jpeg.cpp#16", + "https://www.mssl.ucl.ac.uk/~mcrw/src/20050920/proto.h", + "https://gitlab.freedesktop.org/libopenraw/libopenraw/blob/master/lib/ljpegdecompressor.cpp#L32" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CPAL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CPAL-1.0.json", + "referenceNumber": 548, + "name": "Common Public Attribution License 1.0", + "licenseId": "CPAL-1.0", + "seeAlso": [ + "https://opensource.org/licenses/CPAL-1.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/CPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CPL-1.0.json", + "referenceNumber": 114, + "name": "Common Public License 1.0", + "licenseId": "CPL-1.0", + "seeAlso": [ + "https://opensource.org/licenses/CPL-1.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/CPOL-1.02.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CPOL-1.02.json", + "referenceNumber": 6, + "name": "Code Project Open License 1.02", + "licenseId": "CPOL-1.02", + "seeAlso": [ + "http://www.codeproject.com/info/cpol10.aspx" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/Cronyx.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Cronyx.json", + "referenceNumber": 649, + "name": "Cronyx License", + "licenseId": "Cronyx", + "seeAlso": [ + "https://gitlab.freedesktop.org/xorg/font/alias/-/blob/master/COPYING", + "https://gitlab.freedesktop.org/xorg/font/cronyx-cyrillic/-/blob/master/COPYING", + "https://gitlab.freedesktop.org/xorg/font/misc-cyrillic/-/blob/master/COPYING", + "https://gitlab.freedesktop.org/xorg/font/screen-cyrillic/-/blob/master/COPYING" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Crossword.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Crossword.json", + "referenceNumber": 593, + "name": "Crossword License", + "licenseId": "Crossword", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Crossword" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CrystalStacker.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CrystalStacker.json", + "referenceNumber": 241, + "name": "CrystalStacker License", + "licenseId": "CrystalStacker", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing:CrystalStacker?rd\u003dLicensing/CrystalStacker" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/CUA-OPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/CUA-OPL-1.0.json", + "referenceNumber": 409, + "name": "CUA Office Public License v1.0", + "licenseId": "CUA-OPL-1.0", + "seeAlso": [ + "https://opensource.org/licenses/CUA-OPL-1.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/Cube.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Cube.json", + "referenceNumber": 141, + "name": "Cube License", + "licenseId": "Cube", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Cube" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/curl.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/curl.json", + "referenceNumber": 602, + "name": "curl License", + "licenseId": "curl", + "seeAlso": [ + "https://github.com/bagder/curl/blob/master/COPYING" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/cve-tou.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/cve-tou.json", + "referenceNumber": 656, + "name": "Common Vulnerability Enumeration ToU License", + "licenseId": "cve-tou", + "seeAlso": [ + "https://www.cve.org/Legal/TermsOfUse" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/D-FSL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/D-FSL-1.0.json", + "referenceNumber": 116, + "name": "Deutsche Freie Software Lizenz", + "licenseId": "D-FSL-1.0", + "seeAlso": [ + "http://www.dipp.nrw.de/d-fsl/lizenzen/", + "http://www.dipp.nrw.de/d-fsl/index_html/lizenzen/de/D-FSL-1_0_de.txt", + "http://www.dipp.nrw.de/d-fsl/index_html/lizenzen/en/D-FSL-1_0_en.txt", + "https://www.hbz-nrw.de/produkte/open-access/lizenzen/dfsl", + "https://www.hbz-nrw.de/produkte/open-access/lizenzen/dfsl/deutsche-freie-software-lizenz", + "https://www.hbz-nrw.de/produkte/open-access/lizenzen/dfsl/german-free-software-license", + "https://www.hbz-nrw.de/produkte/open-access/lizenzen/dfsl/D-FSL-1_0_de.txt/at_download/file", + "https://www.hbz-nrw.de/produkte/open-access/lizenzen/dfsl/D-FSL-1_0_en.txt/at_download/file" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/DEC-3-Clause.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/DEC-3-Clause.json", + "referenceNumber": 512, + "name": "DEC 3-Clause License", + "licenseId": "DEC-3-Clause", + "seeAlso": [ + "https://gitlab.freedesktop.org/xorg/xserver/-/blob/master/COPYING?ref_type\u003dheads#L239" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/diffmark.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/diffmark.json", + "referenceNumber": 480, + "name": "diffmark license", + "licenseId": "diffmark", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/diffmark" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/DL-DE-BY-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/DL-DE-BY-2.0.json", + "referenceNumber": 84, + "name": "Data licence Germany – attribution – version 2.0", + "licenseId": "DL-DE-BY-2.0", + "seeAlso": [ + "https://www.govdata.de/dl-de/by-2-0" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/DL-DE-ZERO-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/DL-DE-ZERO-2.0.json", + "referenceNumber": 522, + "name": "Data licence Germany – zero – version 2.0", + "licenseId": "DL-DE-ZERO-2.0", + "seeAlso": [ + "https://www.govdata.de/dl-de/zero-2-0" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/DOC.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/DOC.json", + "referenceNumber": 646, + "name": "DOC License", + "licenseId": "DOC", + "seeAlso": [ + "http://www.cs.wustl.edu/~schmidt/ACE-copying.html", + "https://www.dre.vanderbilt.edu/~schmidt/ACE-copying.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/DocBook-Schema.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/DocBook-Schema.json", + "referenceNumber": 153, + "name": "DocBook Schema License", + "licenseId": "DocBook-Schema", + "seeAlso": [ + "https://github.com/docbook/xslt10-stylesheets/blob/efd62655c11cc8773708df7a843613fa1e932bf8/xsl/assembly/schema/docbook51b7.rnc" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/DocBook-XML.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/DocBook-XML.json", + "referenceNumber": 493, + "name": "DocBook XML License", + "licenseId": "DocBook-XML", + "seeAlso": [ + "https://github.com/docbook/xslt10-stylesheets/blob/efd62655c11cc8773708df7a843613fa1e932bf8/xsl/COPYING#L27" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Dotseqn.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Dotseqn.json", + "referenceNumber": 533, + "name": "Dotseqn License", + "licenseId": "Dotseqn", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Dotseqn" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/DRL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/DRL-1.0.json", + "referenceNumber": 410, + "name": "Detection Rule License 1.0", + "licenseId": "DRL-1.0", + "seeAlso": [ + "https://github.com/Neo23x0/sigma/blob/master/LICENSE.Detection.Rules.md" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/DRL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/DRL-1.1.json", + "referenceNumber": 268, + "name": "Detection Rule License 1.1", + "licenseId": "DRL-1.1", + "seeAlso": [ + "https://github.com/SigmaHQ/Detection-Rule-License/blob/6ec7fbde6101d101b5b5d1fcb8f9b69fbc76c04a/LICENSE.Detection.Rules.md" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/DSDP.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/DSDP.json", + "referenceNumber": 164, + "name": "DSDP License", + "licenseId": "DSDP", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/DSDP" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/dtoa.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/dtoa.json", + "referenceNumber": 263, + "name": "David M. Gay dtoa License", + "licenseId": "dtoa", + "seeAlso": [ + "https://github.com/SWI-Prolog/swipl-devel/blob/master/src/os/dtoa.c", + "https://sourceware.org/git/?p\u003dnewlib-cygwin.git;a\u003dblob;f\u003dnewlib/libc/stdlib/mprec.h;hb\u003dHEAD" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/dvipdfm.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/dvipdfm.json", + "referenceNumber": 61, + "name": "dvipdfm License", + "licenseId": "dvipdfm", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/dvipdfm" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/ECL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ECL-1.0.json", + "referenceNumber": 264, + "name": "Educational Community License v1.0", + "licenseId": "ECL-1.0", + "seeAlso": [ + "https://opensource.org/licenses/ECL-1.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/ECL-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ECL-2.0.json", + "referenceNumber": 363, + "name": "Educational Community License v2.0", + "licenseId": "ECL-2.0", + "seeAlso": [ + "https://opensource.org/licenses/ECL-2.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/eCos-2.0.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/eCos-2.0.json", + "referenceNumber": 298, + "name": "eCos license version 2.0", + "licenseId": "eCos-2.0", + "seeAlso": [ + "https://www.gnu.org/licenses/ecos-license.html" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/EFL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/EFL-1.0.json", + "referenceNumber": 137, + "name": "Eiffel Forum License v1.0", + "licenseId": "EFL-1.0", + "seeAlso": [ + "http://www.eiffel-nice.org/license/forum.txt", + "https://opensource.org/licenses/EFL-1.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/EFL-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/EFL-2.0.json", + "referenceNumber": 447, + "name": "Eiffel Forum License v2.0", + "licenseId": "EFL-2.0", + "seeAlso": [ + "http://www.eiffel-nice.org/license/eiffel-forum-license-2.html", + "https://opensource.org/licenses/EFL-2.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/eGenix.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/eGenix.json", + "referenceNumber": 348, + "name": "eGenix.com Public License 1.1.0", + "licenseId": "eGenix", + "seeAlso": [ + "http://www.egenix.com/products/eGenix.com-Public-License-1.1.0.pdf", + "https://fedoraproject.org/wiki/Licensing/eGenix.com_Public_License_1.1.0" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Elastic-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Elastic-2.0.json", + "referenceNumber": 404, + "name": "Elastic License 2.0", + "licenseId": "Elastic-2.0", + "seeAlso": [ + "https://www.elastic.co/licensing/elastic-license", + "https://github.com/elastic/elasticsearch/blob/master/licenses/ELASTIC-LICENSE-2.0.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Entessa.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Entessa.json", + "referenceNumber": 198, + "name": "Entessa Public License v1.0", + "licenseId": "Entessa", + "seeAlso": [ + "https://opensource.org/licenses/Entessa" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/EPICS.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/EPICS.json", + "referenceNumber": 532, + "name": "EPICS Open License", + "licenseId": "EPICS", + "seeAlso": [ + "https://epics.anl.gov/license/open.php" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/EPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/EPL-1.0.json", + "referenceNumber": 115, + "name": "Eclipse Public License 1.0", + "licenseId": "EPL-1.0", + "seeAlso": [ + "http://www.eclipse.org/legal/epl-v10.html", + "https://opensource.org/licenses/EPL-1.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/EPL-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/EPL-2.0.json", + "referenceNumber": 282, + "name": "Eclipse Public License 2.0", + "licenseId": "EPL-2.0", + "seeAlso": [ + "https://www.eclipse.org/legal/epl-2.0", + "https://www.opensource.org/licenses/EPL-2.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/ErlPL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ErlPL-1.1.json", + "referenceNumber": 530, + "name": "Erlang Public License v1.1", + "licenseId": "ErlPL-1.1", + "seeAlso": [ + "http://www.erlang.org/EPLICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/etalab-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/etalab-2.0.json", + "referenceNumber": 129, + "name": "Etalab Open License 2.0", + "licenseId": "etalab-2.0", + "seeAlso": [ + "https://github.com/DISIC/politique-de-contribution-open-source/blob/master/LICENSE.pdf", + "https://raw.githubusercontent.com/DISIC/politique-de-contribution-open-source/master/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/EUDatagrid.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/EUDatagrid.json", + "referenceNumber": 393, + "name": "EU DataGrid Software License", + "licenseId": "EUDatagrid", + "seeAlso": [ + "http://eu-datagrid.web.cern.ch/eu-datagrid/license.html", + "https://opensource.org/licenses/EUDatagrid" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/EUPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/EUPL-1.0.json", + "referenceNumber": 389, + "name": "European Union Public License 1.0", + "licenseId": "EUPL-1.0", + "seeAlso": [ + "http://ec.europa.eu/idabc/en/document/7330.html", + "http://ec.europa.eu/idabc/servlets/Doc027f.pdf?id\u003d31096" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/EUPL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/EUPL-1.1.json", + "referenceNumber": 503, + "name": "European Union Public License 1.1", + "licenseId": "EUPL-1.1", + "seeAlso": [ + "https://joinup.ec.europa.eu/software/page/eupl/licence-eupl", + "https://joinup.ec.europa.eu/sites/default/files/custom-page/attachment/eupl1.1.-licence-en_0.pdf", + "https://opensource.org/licenses/EUPL-1.1" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/EUPL-1.2.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/EUPL-1.2.json", + "referenceNumber": 12, + "name": "European Union Public License 1.2", + "licenseId": "EUPL-1.2", + "seeAlso": [ + "https://joinup.ec.europa.eu/page/eupl-text-11-12", + "https://joinup.ec.europa.eu/sites/default/files/custom-page/attachment/eupl_v1.2_en.pdf", + "https://joinup.ec.europa.eu/sites/default/files/custom-page/attachment/2020-03/EUPL-1.2%20EN.txt", + "https://joinup.ec.europa.eu/sites/default/files/inline-files/EUPL%20v1_2%20EN(1).txt", + "http://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri\u003dCELEX:32017D0863", + "https://opensource.org/licenses/EUPL-1.2" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Eurosym.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Eurosym.json", + "referenceNumber": 621, + "name": "Eurosym License", + "licenseId": "Eurosym", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Eurosym" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Fair.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Fair.json", + "referenceNumber": 258, + "name": "Fair License", + "licenseId": "Fair", + "seeAlso": [ + "https://web.archive.org/web/20150926120323/http://fairlicense.org/", + "https://opensource.org/licenses/Fair" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/FBM.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/FBM.json", + "referenceNumber": 626, + "name": "Fuzzy Bitmap License", + "licenseId": "FBM", + "seeAlso": [ + "https://github.com/SWI-Prolog/packages-xpce/blob/161a40cd82004f731ba48024f9d30af388a7edf5/src/img/gifwrite.c#L21-L26" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/FDK-AAC.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/FDK-AAC.json", + "referenceNumber": 344, + "name": "Fraunhofer FDK AAC Codec Library", + "licenseId": "FDK-AAC", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/FDK-AAC", + "https://directory.fsf.org/wiki/License:Fdk" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Ferguson-Twofish.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Ferguson-Twofish.json", + "referenceNumber": 362, + "name": "Ferguson Twofish License", + "licenseId": "Ferguson-Twofish", + "seeAlso": [ + "https://github.com/wernerd/ZRTPCPP/blob/6b3cd8e6783642292bad0c21e3e5e5ce45ff3e03/cryptcommon/twofish.c#L113C3-L127" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Frameworx-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Frameworx-1.0.json", + "referenceNumber": 188, + "name": "Frameworx Open License 1.0", + "licenseId": "Frameworx-1.0", + "seeAlso": [ + "https://opensource.org/licenses/Frameworx-1.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/FreeBSD-DOC.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/FreeBSD-DOC.json", + "referenceNumber": 151, + "name": "FreeBSD Documentation License", + "licenseId": "FreeBSD-DOC", + "seeAlso": [ + "https://www.freebsd.org/copyright/freebsd-doc-license/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/FreeImage.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/FreeImage.json", + "referenceNumber": 232, + "name": "FreeImage Public License v1.0", + "licenseId": "FreeImage", + "seeAlso": [ + "http://freeimage.sourceforge.net/freeimage-license.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/FSFAP.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/FSFAP.json", + "referenceNumber": 436, + "name": "FSF All Permissive License", + "licenseId": "FSFAP", + "seeAlso": [ + "https://www.gnu.org/prep/maintain/html_node/License-Notices-for-Other-Files.html" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/FSFAP-no-warranty-disclaimer.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/FSFAP-no-warranty-disclaimer.json", + "referenceNumber": 547, + "name": "FSF All Permissive License (without Warranty)", + "licenseId": "FSFAP-no-warranty-disclaimer", + "seeAlso": [ + "https://git.savannah.gnu.org/cgit/wget.git/tree/util/trunc.c?h\u003dv1.21.3\u0026id\u003d40747a11e44ced5a8ac628a41f879ced3e2ebce9#n6" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/FSFUL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/FSFUL.json", + "referenceNumber": 2, + "name": "FSF Unlimited License", + "licenseId": "FSFUL", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/FSF_Unlimited_License" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/FSFULLR.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/FSFULLR.json", + "referenceNumber": 508, + "name": "FSF Unlimited License (with License Retention)", + "licenseId": "FSFULLR", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/FSF_Unlimited_License#License_Retention_Variant" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/FSFULLRWD.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/FSFULLRWD.json", + "referenceNumber": 640, + "name": "FSF Unlimited License (With License Retention and Warranty Disclaimer)", + "licenseId": "FSFULLRWD", + "seeAlso": [ + "https://lists.gnu.org/archive/html/autoconf/2012-04/msg00061.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/FTL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/FTL.json", + "referenceNumber": 249, + "name": "Freetype Project License", + "licenseId": "FTL", + "seeAlso": [ + "http://freetype.fis.uniroma2.it/FTL.TXT", + "http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/docs/FTL.TXT", + "http://gitlab.freedesktop.org/freetype/freetype/-/raw/master/docs/FTL.TXT" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Furuseth.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Furuseth.json", + "referenceNumber": 273, + "name": "Furuseth License", + "licenseId": "Furuseth", + "seeAlso": [ + "https://git.openldap.org/openldap/openldap/-/blob/master/COPYRIGHT?ref_type\u003dheads#L39-51" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/fwlw.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/fwlw.json", + "referenceNumber": 50, + "name": "fwlw License", + "licenseId": "fwlw", + "seeAlso": [ + "https://mirrors.nic.cz/tex-archive/macros/latex/contrib/fwlw/README" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GCR-docs.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GCR-docs.json", + "referenceNumber": 272, + "name": "Gnome GCR Documentation License", + "licenseId": "GCR-docs", + "seeAlso": [ + "https://github.com/GNOME/gcr/blob/master/docs/COPYING" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GD.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GD.json", + "referenceNumber": 624, + "name": "GD License", + "licenseId": "GD", + "seeAlso": [ + "https://libgd.github.io/manuals/2.3.0/files/license-txt.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.1.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.1.json", + "referenceNumber": 177, + "name": "GNU Free Documentation License v1.1", + "licenseId": "GFDL-1.1", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/fdl-1.1.txt" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.1-invariants-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.1-invariants-only.json", + "referenceNumber": 216, + "name": "GNU Free Documentation License v1.1 only - invariants", + "licenseId": "GFDL-1.1-invariants-only", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/fdl-1.1.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.1-invariants-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.1-invariants-or-later.json", + "referenceNumber": 57, + "name": "GNU Free Documentation License v1.1 or later - invariants", + "licenseId": "GFDL-1.1-invariants-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/fdl-1.1.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.1-no-invariants-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.1-no-invariants-only.json", + "referenceNumber": 38, + "name": "GNU Free Documentation License v1.1 only - no invariants", + "licenseId": "GFDL-1.1-no-invariants-only", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/fdl-1.1.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.1-no-invariants-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.1-no-invariants-or-later.json", + "referenceNumber": 289, + "name": "GNU Free Documentation License v1.1 or later - no invariants", + "licenseId": "GFDL-1.1-no-invariants-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/fdl-1.1.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.1-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.1-only.json", + "referenceNumber": 654, + "name": "GNU Free Documentation License v1.1 only", + "licenseId": "GFDL-1.1-only", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/fdl-1.1.txt" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.1-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.1-or-later.json", + "referenceNumber": 569, + "name": "GNU Free Documentation License v1.1 or later", + "licenseId": "GFDL-1.1-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/fdl-1.1.txt" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.2.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.2.json", + "referenceNumber": 235, + "name": "GNU Free Documentation License v1.2", + "licenseId": "GFDL-1.2", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/fdl-1.2.txt" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.2-invariants-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.2-invariants-only.json", + "referenceNumber": 461, + "name": "GNU Free Documentation License v1.2 only - invariants", + "licenseId": "GFDL-1.2-invariants-only", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/fdl-1.2.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.2-invariants-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.2-invariants-or-later.json", + "referenceNumber": 391, + "name": "GNU Free Documentation License v1.2 or later - invariants", + "licenseId": "GFDL-1.2-invariants-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/fdl-1.2.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.2-no-invariants-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.2-no-invariants-only.json", + "referenceNumber": 187, + "name": "GNU Free Documentation License v1.2 only - no invariants", + "licenseId": "GFDL-1.2-no-invariants-only", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/fdl-1.2.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.2-no-invariants-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.2-no-invariants-or-later.json", + "referenceNumber": 240, + "name": "GNU Free Documentation License v1.2 or later - no invariants", + "licenseId": "GFDL-1.2-no-invariants-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/fdl-1.2.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.2-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.2-only.json", + "referenceNumber": 302, + "name": "GNU Free Documentation License v1.2 only", + "licenseId": "GFDL-1.2-only", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/fdl-1.2.txt" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.2-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.2-or-later.json", + "referenceNumber": 562, + "name": "GNU Free Documentation License v1.2 or later", + "licenseId": "GFDL-1.2-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/fdl-1.2.txt" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.3.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.3.json", + "referenceNumber": 60, + "name": "GNU Free Documentation License v1.3", + "licenseId": "GFDL-1.3", + "seeAlso": [ + "https://www.gnu.org/licenses/fdl-1.3.txt" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.3-invariants-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.3-invariants-only.json", + "referenceNumber": 184, + "name": "GNU Free Documentation License v1.3 only - invariants", + "licenseId": "GFDL-1.3-invariants-only", + "seeAlso": [ + "https://www.gnu.org/licenses/fdl-1.3.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.3-invariants-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.3-invariants-or-later.json", + "referenceNumber": 346, + "name": "GNU Free Documentation License v1.3 or later - invariants", + "licenseId": "GFDL-1.3-invariants-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/fdl-1.3.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.3-no-invariants-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.3-no-invariants-only.json", + "referenceNumber": 59, + "name": "GNU Free Documentation License v1.3 only - no invariants", + "licenseId": "GFDL-1.3-no-invariants-only", + "seeAlso": [ + "https://www.gnu.org/licenses/fdl-1.3.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.3-no-invariants-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.3-no-invariants-or-later.json", + "referenceNumber": 281, + "name": "GNU Free Documentation License v1.3 or later - no invariants", + "licenseId": "GFDL-1.3-no-invariants-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/fdl-1.3.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.3-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.3-only.json", + "referenceNumber": 642, + "name": "GNU Free Documentation License v1.3 only", + "licenseId": "GFDL-1.3-only", + "seeAlso": [ + "https://www.gnu.org/licenses/fdl-1.3.txt" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GFDL-1.3-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GFDL-1.3-or-later.json", + "referenceNumber": 494, + "name": "GNU Free Documentation License v1.3 or later", + "licenseId": "GFDL-1.3-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/fdl-1.3.txt" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Giftware.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Giftware.json", + "referenceNumber": 618, + "name": "Giftware License", + "licenseId": "Giftware", + "seeAlso": [ + "http://liballeg.org/license.html#allegro-4-the-giftware-license" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GL2PS.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GL2PS.json", + "referenceNumber": 231, + "name": "GL2PS License", + "licenseId": "GL2PS", + "seeAlso": [ + "http://www.geuz.org/gl2ps/COPYING.GL2PS" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Glide.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Glide.json", + "referenceNumber": 620, + "name": "3dfx Glide License", + "licenseId": "Glide", + "seeAlso": [ + "http://www.users.on.net/~triforce/glidexp/COPYING.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Glulxe.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Glulxe.json", + "referenceNumber": 429, + "name": "Glulxe License", + "licenseId": "Glulxe", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Glulxe" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GLWTPL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GLWTPL.json", + "referenceNumber": 154, + "name": "Good Luck With That Public License", + "licenseId": "GLWTPL", + "seeAlso": [ + "https://github.com/me-shaon/GLWTPL/commit/da5f6bc734095efbacb442c0b31e33a65b9d6e85" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/gnuplot.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/gnuplot.json", + "referenceNumber": 271, + "name": "gnuplot License", + "licenseId": "gnuplot", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Gnuplot" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GPL-1.0.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GPL-1.0.json", + "referenceNumber": 365, + "name": "GNU General Public License v1.0 only", + "licenseId": "GPL-1.0", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GPL-1.0+.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GPL-1.0+.json", + "referenceNumber": 66, + "name": "GNU General Public License v1.0 or later", + "licenseId": "GPL-1.0+", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GPL-1.0-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GPL-1.0-only.json", + "referenceNumber": 563, + "name": "GNU General Public License v1.0 only", + "licenseId": "GPL-1.0-only", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GPL-1.0-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GPL-1.0-or-later.json", + "referenceNumber": 558, + "name": "GNU General Public License v1.0 or later", + "licenseId": "GPL-1.0-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GPL-2.0.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GPL-2.0.json", + "referenceNumber": 613, + "name": "GNU General Public License v2.0 only", + "licenseId": "GPL-2.0", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html", + "https://opensource.org/licenses/GPL-2.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GPL-2.0+.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GPL-2.0+.json", + "referenceNumber": 83, + "name": "GNU General Public License v2.0 or later", + "licenseId": "GPL-2.0+", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html", + "https://opensource.org/licenses/GPL-2.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GPL-2.0-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GPL-2.0-only.json", + "referenceNumber": 483, + "name": "GNU General Public License v2.0 only", + "licenseId": "GPL-2.0-only", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html", + "https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt", + "https://opensource.org/licenses/GPL-2.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GPL-2.0-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GPL-2.0-or-later.json", + "referenceNumber": 349, + "name": "GNU General Public License v2.0 or later", + "licenseId": "GPL-2.0-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html", + "https://opensource.org/licenses/GPL-2.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GPL-2.0-with-autoconf-exception.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GPL-2.0-with-autoconf-exception.json", + "referenceNumber": 475, + "name": "GNU General Public License v2.0 w/Autoconf exception", + "licenseId": "GPL-2.0-with-autoconf-exception", + "seeAlso": [ + "http://ac-archive.sourceforge.net/doc/copyright.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GPL-2.0-with-bison-exception.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GPL-2.0-with-bison-exception.json", + "referenceNumber": 492, + "name": "GNU General Public License v2.0 w/Bison exception", + "licenseId": "GPL-2.0-with-bison-exception", + "seeAlso": [ + "http://git.savannah.gnu.org/cgit/bison.git/tree/data/yacc.c?id\u003d193d7c7054ba7197b0789e14965b739162319b5e#n141" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GPL-2.0-with-classpath-exception.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GPL-2.0-with-classpath-exception.json", + "referenceNumber": 144, + "name": "GNU General Public License v2.0 w/Classpath exception", + "licenseId": "GPL-2.0-with-classpath-exception", + "seeAlso": [ + "https://www.gnu.org/software/classpath/license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GPL-2.0-with-font-exception.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GPL-2.0-with-font-exception.json", + "referenceNumber": 579, + "name": "GNU General Public License v2.0 w/Font exception", + "licenseId": "GPL-2.0-with-font-exception", + "seeAlso": [ + "https://www.gnu.org/licenses/gpl-faq.html#FontException" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GPL-2.0-with-GCC-exception.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GPL-2.0-with-GCC-exception.json", + "referenceNumber": 449, + "name": "GNU General Public License v2.0 w/GCC Runtime Library exception", + "licenseId": "GPL-2.0-with-GCC-exception", + "seeAlso": [ + "https://gcc.gnu.org/git/?p\u003dgcc.git;a\u003dblob;f\u003dgcc/libgcc1.c;h\u003d762f5143fc6eed57b6797c82710f3538aa52b40b;hb\u003dcb143a3ce4fb417c68f5fa2691a1b1b1053dfba9#l10" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GPL-3.0.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GPL-3.0.json", + "referenceNumber": 434, + "name": "GNU General Public License v3.0 only", + "licenseId": "GPL-3.0", + "seeAlso": [ + "https://www.gnu.org/licenses/gpl-3.0-standalone.html", + "https://opensource.org/licenses/GPL-3.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GPL-3.0+.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GPL-3.0+.json", + "referenceNumber": 586, + "name": "GNU General Public License v3.0 or later", + "licenseId": "GPL-3.0+", + "seeAlso": [ + "https://www.gnu.org/licenses/gpl-3.0-standalone.html", + "https://opensource.org/licenses/GPL-3.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GPL-3.0-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GPL-3.0-only.json", + "referenceNumber": 42, + "name": "GNU General Public License v3.0 only", + "licenseId": "GPL-3.0-only", + "seeAlso": [ + "https://www.gnu.org/licenses/gpl-3.0-standalone.html", + "https://opensource.org/licenses/GPL-3.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GPL-3.0-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/GPL-3.0-or-later.json", + "referenceNumber": 269, + "name": "GNU General Public License v3.0 or later", + "licenseId": "GPL-3.0-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/gpl-3.0-standalone.html", + "https://opensource.org/licenses/GPL-3.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/GPL-3.0-with-autoconf-exception.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GPL-3.0-with-autoconf-exception.json", + "referenceNumber": 200, + "name": "GNU General Public License v3.0 w/Autoconf exception", + "licenseId": "GPL-3.0-with-autoconf-exception", + "seeAlso": [ + "https://www.gnu.org/licenses/autoconf-exception-3.0.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/GPL-3.0-with-GCC-exception.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/GPL-3.0-with-GCC-exception.json", + "referenceNumber": 546, + "name": "GNU General Public License v3.0 w/GCC Runtime Library exception", + "licenseId": "GPL-3.0-with-GCC-exception", + "seeAlso": [ + "https://www.gnu.org/licenses/gcc-exception-3.1.html" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/Graphics-Gems.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Graphics-Gems.json", + "referenceNumber": 437, + "name": "Graphics Gems License", + "licenseId": "Graphics-Gems", + "seeAlso": [ + "https://github.com/erich666/GraphicsGems/blob/master/LICENSE.md" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/gSOAP-1.3b.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/gSOAP-1.3b.json", + "referenceNumber": 658, + "name": "gSOAP Public License v1.3b", + "licenseId": "gSOAP-1.3b", + "seeAlso": [ + "http://www.cs.fsu.edu/~engelen/license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/gtkbook.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/gtkbook.json", + "referenceNumber": 397, + "name": "gtkbook License", + "licenseId": "gtkbook", + "seeAlso": [ + "https://github.com/slogan621/gtkbook", + "https://github.com/oetiker/rrdtool-1.x/blob/master/src/plbasename.c#L8-L11" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Gutmann.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Gutmann.json", + "referenceNumber": 103, + "name": "Gutmann License", + "licenseId": "Gutmann", + "seeAlso": [ + "https://www.cs.auckland.ac.nz/~pgut001/dumpasn1.c" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HaskellReport.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HaskellReport.json", + "referenceNumber": 357, + "name": "Haskell Language Report License", + "licenseId": "HaskellReport", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Haskell_Language_Report_License" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/hdparm.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/hdparm.json", + "referenceNumber": 351, + "name": "hdparm License", + "licenseId": "hdparm", + "seeAlso": [ + "https://github.com/Distrotech/hdparm/blob/4517550db29a91420fb2b020349523b1b4512df2/LICENSE.TXT" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HIDAPI.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HIDAPI.json", + "referenceNumber": 318, + "name": "HIDAPI License", + "licenseId": "HIDAPI", + "seeAlso": [ + "https://github.com/signal11/hidapi/blob/master/LICENSE-orig.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Hippocratic-2.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Hippocratic-2.1.json", + "referenceNumber": 425, + "name": "Hippocratic License 2.1", + "licenseId": "Hippocratic-2.1", + "seeAlso": [ + "https://firstdonoharm.dev/version/2/1/license.html", + "https://github.com/EthicalSource/hippocratic-license/blob/58c0e646d64ff6fbee275bfe2b9492f914e3ab2a/LICENSE.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HP-1986.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HP-1986.json", + "referenceNumber": 477, + "name": "Hewlett-Packard 1986 License", + "licenseId": "HP-1986", + "seeAlso": [ + "https://sourceware.org/git/?p\u003dnewlib-cygwin.git;a\u003dblob;f\u003dnewlib/libc/machine/hppa/memchr.S;h\u003d1cca3e5e8867aa4bffef1f75a5c1bba25c0c441e;hb\u003dHEAD#l2" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HP-1989.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HP-1989.json", + "referenceNumber": 653, + "name": "Hewlett-Packard 1989 License", + "licenseId": "HP-1989", + "seeAlso": [ + "https://github.com/bleargh45/Data-UUID/blob/master/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND.json", + "referenceNumber": 75, + "name": "Historical Permission Notice and Disclaimer", + "licenseId": "HPND", + "seeAlso": [ + "https://opensource.org/licenses/HPND", + "http://lists.opensource.org/pipermail/license-discuss_lists.opensource.org/2002-November/006304.html" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/HPND-DEC.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-DEC.json", + "referenceNumber": 597, + "name": "Historical Permission Notice and Disclaimer - DEC variant", + "licenseId": "HPND-DEC", + "seeAlso": [ + "https://gitlab.freedesktop.org/xorg/app/xkbcomp/-/blob/master/COPYING?ref_type\u003dheads#L69" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-doc.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-doc.json", + "referenceNumber": 384, + "name": "Historical Permission Notice and Disclaimer - documentation variant", + "licenseId": "HPND-doc", + "seeAlso": [ + "https://gitlab.freedesktop.org/xorg/lib/libxext/-/blob/master/COPYING?ref_type\u003dheads#L185-197", + "https://gitlab.freedesktop.org/xorg/lib/libxtst/-/blob/master/COPYING?ref_type\u003dheads#L70-77" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-doc-sell.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-doc-sell.json", + "referenceNumber": 648, + "name": "Historical Permission Notice and Disclaimer - documentation sell variant", + "licenseId": "HPND-doc-sell", + "seeAlso": [ + "https://gitlab.freedesktop.org/xorg/lib/libxtst/-/blob/master/COPYING?ref_type\u003dheads#L108-117", + "https://gitlab.freedesktop.org/xorg/lib/libxext/-/blob/master/COPYING?ref_type\u003dheads#L153-162" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-export-US.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-export-US.json", + "referenceNumber": 551, + "name": "HPND with US Government export control warning", + "licenseId": "HPND-export-US", + "seeAlso": [ + "https://www.kermitproject.org/ck90.html#source" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-export-US-acknowledgement.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-export-US-acknowledgement.json", + "referenceNumber": 661, + "name": "HPND with US Government export control warning and acknowledgment", + "licenseId": "HPND-export-US-acknowledgement", + "seeAlso": [ + "https://github.com/krb5/krb5/blob/krb5-1.21.2-final/NOTICE#L831-L852", + "https://web.mit.edu/kerberos/krb5-1.21/doc/mitK5license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-export-US-modify.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-export-US-modify.json", + "referenceNumber": 119, + "name": "HPND with US Government export control warning and modification rqmt", + "licenseId": "HPND-export-US-modify", + "seeAlso": [ + "https://github.com/krb5/krb5/blob/krb5-1.21.2-final/NOTICE#L1157-L1182", + "https://github.com/pythongssapi/k5test/blob/v0.10.3/K5TEST-LICENSE.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-export2-US.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-export2-US.json", + "referenceNumber": 450, + "name": "HPND with US Government export control and 2 disclaimers", + "licenseId": "HPND-export2-US", + "seeAlso": [ + "https://github.com/krb5/krb5/blob/krb5-1.21.2-final/NOTICE#L111-L133", + "https://web.mit.edu/kerberos/krb5-1.21/doc/mitK5license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-Fenneberg-Livingston.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-Fenneberg-Livingston.json", + "referenceNumber": 643, + "name": "Historical Permission Notice and Disclaimer - Fenneberg-Livingston variant", + "licenseId": "HPND-Fenneberg-Livingston", + "seeAlso": [ + "https://github.com/FreeRADIUS/freeradius-client/blob/master/COPYRIGHT#L32", + "https://github.com/radcli/radcli/blob/master/COPYRIGHT#L34" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-INRIA-IMAG.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-INRIA-IMAG.json", + "referenceNumber": 583, + "name": "Historical Permission Notice and Disclaimer - INRIA-IMAG variant", + "licenseId": "HPND-INRIA-IMAG", + "seeAlso": [ + "https://github.com/ppp-project/ppp/blob/master/pppd/ipv6cp.c#L75-L83" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-Intel.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-Intel.json", + "referenceNumber": 20, + "name": "Historical Permission Notice and Disclaimer - Intel variant", + "licenseId": "HPND-Intel", + "seeAlso": [ + "https://sourceware.org/git/?p\u003dnewlib-cygwin.git;a\u003dblob;f\u003dnewlib/libc/machine/i960/memcpy.S;hb\u003dHEAD" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-Kevlin-Henney.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-Kevlin-Henney.json", + "referenceNumber": 637, + "name": "Historical Permission Notice and Disclaimer - Kevlin Henney variant", + "licenseId": "HPND-Kevlin-Henney", + "seeAlso": [ + "https://github.com/mruby/mruby/blob/83d12f8d52522cdb7c8cc46fad34821359f453e6/mrbgems/mruby-dir/src/Win/dirent.c#L127-L140" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-Markus-Kuhn.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-Markus-Kuhn.json", + "referenceNumber": 172, + "name": "Historical Permission Notice and Disclaimer - Markus Kuhn variant", + "licenseId": "HPND-Markus-Kuhn", + "seeAlso": [ + "https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c", + "https://sourceware.org/git/?p\u003dbinutils-gdb.git;a\u003dblob;f\u003dreadline/readline/support/wcwidth.c;h\u003d0f5ec995796f4813abbcf4972aec0378ab74722a;hb\u003dHEAD#l55" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-merchantability-variant.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-merchantability-variant.json", + "referenceNumber": 572, + "name": "Historical Permission Notice and Disclaimer - merchantability variant", + "licenseId": "HPND-merchantability-variant", + "seeAlso": [ + "https://sourceware.org/git/?p\u003dnewlib-cygwin.git;a\u003dblob;f\u003dnewlib/libc/misc/fini.c;hb\u003dHEAD" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-MIT-disclaimer.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-MIT-disclaimer.json", + "referenceNumber": 609, + "name": "Historical Permission Notice and Disclaimer with MIT disclaimer", + "licenseId": "HPND-MIT-disclaimer", + "seeAlso": [ + "https://metacpan.org/release/NLNETLABS/Net-DNS-SEC-1.22/source/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-Netrek.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-Netrek.json", + "referenceNumber": 126, + "name": "Historical Permission Notice and Disclaimer - Netrek variant", + "licenseId": "HPND-Netrek", + "seeAlso": [], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-Pbmplus.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-Pbmplus.json", + "referenceNumber": 242, + "name": "Historical Permission Notice and Disclaimer - Pbmplus variant", + "licenseId": "HPND-Pbmplus", + "seeAlso": [ + "https://sourceforge.net/p/netpbm/code/HEAD/tree/super_stable/netpbm.c#l8" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-sell-MIT-disclaimer-xserver.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-sell-MIT-disclaimer-xserver.json", + "referenceNumber": 160, + "name": "Historical Permission Notice and Disclaimer - sell xserver variant with MIT disclaimer", + "licenseId": "HPND-sell-MIT-disclaimer-xserver", + "seeAlso": [ + "https://gitlab.freedesktop.org/xorg/xserver/-/blob/master/COPYING?ref_type\u003dheads#L1781" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-sell-regexpr.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-sell-regexpr.json", + "referenceNumber": 44, + "name": "Historical Permission Notice and Disclaimer - sell regexpr variant", + "licenseId": "HPND-sell-regexpr", + "seeAlso": [ + "https://gitlab.com/bacula-org/bacula/-/blob/Branch-11.0/bacula/LICENSE-FOSS?ref_type\u003dheads#L245" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-sell-variant.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-sell-variant.json", + "referenceNumber": 485, + "name": "Historical Permission Notice and Disclaimer - sell variant", + "licenseId": "HPND-sell-variant", + "seeAlso": [ + "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/sunrpc/auth_gss/gss_generic_token.c?h\u003dv4.19" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-sell-variant-MIT-disclaimer.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-sell-variant-MIT-disclaimer.json", + "referenceNumber": 430, + "name": "HPND sell variant with MIT disclaimer", + "licenseId": "HPND-sell-variant-MIT-disclaimer", + "seeAlso": [ + "https://github.com/sigmavirus24/x11-ssh-askpass/blob/master/README" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-sell-variant-MIT-disclaimer-rev.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-sell-variant-MIT-disclaimer-rev.json", + "referenceNumber": 10, + "name": "HPND sell variant with MIT disclaimer - reverse", + "licenseId": "HPND-sell-variant-MIT-disclaimer-rev", + "seeAlso": [ + "https://github.com/sigmavirus24/x11-ssh-askpass/blob/master/dynlist.c" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-UC.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-UC.json", + "referenceNumber": 423, + "name": "Historical Permission Notice and Disclaimer - University of California variant", + "licenseId": "HPND-UC", + "seeAlso": [ + "https://core.tcl-lang.org/tk/file?name\u003dcompat/unistd.h" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HPND-UC-export-US.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HPND-UC-export-US.json", + "referenceNumber": 82, + "name": "Historical Permission Notice and Disclaimer - University of California, US export warning", + "licenseId": "HPND-UC-export-US", + "seeAlso": [ + "https://github.com/RTimothyEdwards/magic/blob/master/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/HTMLTIDY.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/HTMLTIDY.json", + "referenceNumber": 439, + "name": "HTML Tidy License", + "licenseId": "HTMLTIDY", + "seeAlso": [ + "https://github.com/htacg/tidy-html5/blob/next/README/LICENSE.md" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/IBM-pibs.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/IBM-pibs.json", + "referenceNumber": 604, + "name": "IBM PowerPC Initialization and Boot Software", + "licenseId": "IBM-pibs", + "seeAlso": [ + "http://git.denx.de/?p\u003du-boot.git;a\u003dblob;f\u003darch/powerpc/cpu/ppc4xx/miiphy.c;h\u003d297155fdafa064b955e53e9832de93bfb0cfb85b;hb\u003d9fab4bf4cc077c21e43941866f3f2c196f28670d" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/ICU.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ICU.json", + "referenceNumber": 375, + "name": "ICU License", + "licenseId": "ICU", + "seeAlso": [ + "http://source.icu-project.org/repos/icu/icu/trunk/license.html" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/IEC-Code-Components-EULA.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/IEC-Code-Components-EULA.json", + "referenceNumber": 18, + "name": "IEC Code Components End-user licence agreement", + "licenseId": "IEC-Code-Components-EULA", + "seeAlso": [ + "https://www.iec.ch/webstore/custserv/pdf/CC-EULA.pdf", + "https://www.iec.ch/CCv1", + "https://www.iec.ch/copyright" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/IJG.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/IJG.json", + "referenceNumber": 374, + "name": "Independent JPEG Group License", + "licenseId": "IJG", + "seeAlso": [ + "http://dev.w3.org/cvsweb/Amaya/libjpeg/Attic/README?rev\u003d1.2" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/IJG-short.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/IJG-short.json", + "referenceNumber": 152, + "name": "Independent JPEG Group License - short", + "licenseId": "IJG-short", + "seeAlso": [ + "https://sourceforge.net/p/xmedcon/code/ci/master/tree/libs/ljpg/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/ImageMagick.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ImageMagick.json", + "referenceNumber": 608, + "name": "ImageMagick License", + "licenseId": "ImageMagick", + "seeAlso": [ + "http://www.imagemagick.org/script/license.php" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/iMatix.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/iMatix.json", + "referenceNumber": 645, + "name": "iMatix Standard Function Library Agreement", + "licenseId": "iMatix", + "seeAlso": [ + "http://legacy.imatix.com/html/sfl/sfl4.htm#license" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Imlib2.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Imlib2.json", + "referenceNumber": 96, + "name": "Imlib2 License", + "licenseId": "Imlib2", + "seeAlso": [ + "http://trac.enlightenment.org/e/browser/trunk/imlib2/COPYING", + "https://git.enlightenment.org/legacy/imlib2.git/tree/COPYING" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Info-ZIP.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Info-ZIP.json", + "referenceNumber": 451, + "name": "Info-ZIP License", + "licenseId": "Info-ZIP", + "seeAlso": [ + "http://www.info-zip.org/license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Inner-Net-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Inner-Net-2.0.json", + "referenceNumber": 58, + "name": "Inner Net License v2.0", + "licenseId": "Inner-Net-2.0", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Inner_Net_License", + "https://sourceware.org/git/?p\u003dglibc.git;a\u003dblob;f\u003dLICENSES;h\u003d530893b1dc9ea00755603c68fb36bd4fc38a7be8;hb\u003dHEAD#l207" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Intel.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Intel.json", + "referenceNumber": 316, + "name": "Intel Open Source License", + "licenseId": "Intel", + "seeAlso": [ + "https://opensource.org/licenses/Intel" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Intel-ACPI.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Intel-ACPI.json", + "referenceNumber": 309, + "name": "Intel ACPI Software License Agreement", + "licenseId": "Intel-ACPI", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Intel_ACPI_Software_License_Agreement" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Interbase-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Interbase-1.0.json", + "referenceNumber": 665, + "name": "Interbase Public License v1.0", + "licenseId": "Interbase-1.0", + "seeAlso": [ + "https://web.archive.org/web/20060319014854/http://info.borland.com/devsupport/interbase/opensource/IPL.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/IPA.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/IPA.json", + "referenceNumber": 237, + "name": "IPA Font License", + "licenseId": "IPA", + "seeAlso": [ + "https://opensource.org/licenses/IPA" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/IPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/IPL-1.0.json", + "referenceNumber": 443, + "name": "IBM Public License v1.0", + "licenseId": "IPL-1.0", + "seeAlso": [ + "https://opensource.org/licenses/IPL-1.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/ISC.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ISC.json", + "referenceNumber": 131, + "name": "ISC License", + "licenseId": "ISC", + "seeAlso": [ + "https://www.isc.org/licenses/", + "https://www.isc.org/downloads/software-support-policy/isc-license/", + "https://opensource.org/licenses/ISC" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/ISC-Veillard.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ISC-Veillard.json", + "referenceNumber": 554, + "name": "ISC Veillard variant", + "licenseId": "ISC-Veillard", + "seeAlso": [ + "https://raw.githubusercontent.com/GNOME/libxml2/4c2e7c651f6c2f0d1a74f350cbda95f7df3e7017/hash.c", + "https://github.com/GNOME/libxml2/blob/master/dict.c", + "https://sourceforge.net/p/ctrio/git/ci/master/tree/README" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Jam.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Jam.json", + "referenceNumber": 338, + "name": "Jam License", + "licenseId": "Jam", + "seeAlso": [ + "https://www.boost.org/doc/libs/1_35_0/doc/html/jam.html", + "https://web.archive.org/web/20160330173339/https://swarm.workshop.perforce.com/files/guest/perforce_software/jam/src/README" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/JasPer-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/JasPer-2.0.json", + "referenceNumber": 591, + "name": "JasPer License", + "licenseId": "JasPer-2.0", + "seeAlso": [ + "http://www.ece.uvic.ca/~mdadams/jasper/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/JPL-image.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/JPL-image.json", + "referenceNumber": 343, + "name": "JPL Image Use Policy", + "licenseId": "JPL-image", + "seeAlso": [ + "https://www.jpl.nasa.gov/jpl-image-use-policy" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/JPNIC.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/JPNIC.json", + "referenceNumber": 117, + "name": "Japan Network Information Center License", + "licenseId": "JPNIC", + "seeAlso": [ + "https://gitlab.isc.org/isc-projects/bind9/blob/master/COPYRIGHT#L366" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/JSON.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/JSON.json", + "referenceNumber": 174, + "name": "JSON License", + "licenseId": "JSON", + "seeAlso": [ + "http://www.json.org/license.html" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/Kastrup.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Kastrup.json", + "referenceNumber": 181, + "name": "Kastrup License", + "licenseId": "Kastrup", + "seeAlso": [ + "https://ctan.math.utah.edu/ctan/tex-archive/macros/generic/kastrup/binhex.dtx" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Kazlib.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Kazlib.json", + "referenceNumber": 197, + "name": "Kazlib License", + "licenseId": "Kazlib", + "seeAlso": [ + "http://git.savannah.gnu.org/cgit/kazlib.git/tree/except.c?id\u003d0062df360c2d17d57f6af19b0e444c51feb99036" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Knuth-CTAN.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Knuth-CTAN.json", + "referenceNumber": 22, + "name": "Knuth CTAN License", + "licenseId": "Knuth-CTAN", + "seeAlso": [ + "https://ctan.org/license/knuth" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/LAL-1.2.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LAL-1.2.json", + "referenceNumber": 261, + "name": "Licence Art Libre 1.2", + "licenseId": "LAL-1.2", + "seeAlso": [ + "http://artlibre.org/licence/lal/licence-art-libre-12/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/LAL-1.3.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LAL-1.3.json", + "referenceNumber": 526, + "name": "Licence Art Libre 1.3", + "licenseId": "LAL-1.3", + "seeAlso": [ + "https://artlibre.org/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Latex2e.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Latex2e.json", + "referenceNumber": 3, + "name": "Latex2e License", + "licenseId": "Latex2e", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Latex2e" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Latex2e-translated-notice.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Latex2e-translated-notice.json", + "referenceNumber": 104, + "name": "Latex2e with translated notice permission", + "licenseId": "Latex2e-translated-notice", + "seeAlso": [ + "https://git.savannah.gnu.org/cgit/indent.git/tree/doc/indent.texi?id\u003da74c6b4ee49397cf330b333da1042bffa60ed14f#n74" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Leptonica.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Leptonica.json", + "referenceNumber": 221, + "name": "Leptonica License", + "licenseId": "Leptonica", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Leptonica" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/LGPL-2.0.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/LGPL-2.0.json", + "referenceNumber": 81, + "name": "GNU Library General Public License v2 only", + "licenseId": "LGPL-2.0", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/lgpl-2.0-standalone.html" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/LGPL-2.0+.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/LGPL-2.0+.json", + "referenceNumber": 265, + "name": "GNU Library General Public License v2 or later", + "licenseId": "LGPL-2.0+", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/lgpl-2.0-standalone.html" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/LGPL-2.0-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LGPL-2.0-only.json", + "referenceNumber": 517, + "name": "GNU Library General Public License v2 only", + "licenseId": "LGPL-2.0-only", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/lgpl-2.0-standalone.html" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/LGPL-2.0-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LGPL-2.0-or-later.json", + "referenceNumber": 458, + "name": "GNU Library General Public License v2 or later", + "licenseId": "LGPL-2.0-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/lgpl-2.0-standalone.html" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/LGPL-2.1.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/LGPL-2.1.json", + "referenceNumber": 659, + "name": "GNU Lesser General Public License v2.1 only", + "licenseId": "LGPL-2.1", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html", + "https://opensource.org/licenses/LGPL-2.1" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/LGPL-2.1+.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/LGPL-2.1+.json", + "referenceNumber": 69, + "name": "GNU Lesser General Public License v2.1 or later", + "licenseId": "LGPL-2.1+", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html", + "https://opensource.org/licenses/LGPL-2.1" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/LGPL-2.1-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LGPL-2.1-only.json", + "referenceNumber": 524, + "name": "GNU Lesser General Public License v2.1 only", + "licenseId": "LGPL-2.1-only", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html", + "https://opensource.org/licenses/LGPL-2.1" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/LGPL-2.1-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LGPL-2.1-or-later.json", + "referenceNumber": 336, + "name": "GNU Lesser General Public License v2.1 or later", + "licenseId": "LGPL-2.1-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html", + "https://opensource.org/licenses/LGPL-2.1" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/LGPL-3.0.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/LGPL-3.0.json", + "referenceNumber": 381, + "name": "GNU Lesser General Public License v3.0 only", + "licenseId": "LGPL-3.0", + "seeAlso": [ + "https://www.gnu.org/licenses/lgpl-3.0-standalone.html", + "https://www.gnu.org/licenses/lgpl+gpl-3.0.txt", + "https://opensource.org/licenses/LGPL-3.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/LGPL-3.0+.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/LGPL-3.0+.json", + "referenceNumber": 303, + "name": "GNU Lesser General Public License v3.0 or later", + "licenseId": "LGPL-3.0+", + "seeAlso": [ + "https://www.gnu.org/licenses/lgpl-3.0-standalone.html", + "https://www.gnu.org/licenses/lgpl+gpl-3.0.txt", + "https://opensource.org/licenses/LGPL-3.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/LGPL-3.0-only.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LGPL-3.0-only.json", + "referenceNumber": 225, + "name": "GNU Lesser General Public License v3.0 only", + "licenseId": "LGPL-3.0-only", + "seeAlso": [ + "https://www.gnu.org/licenses/lgpl-3.0-standalone.html", + "https://www.gnu.org/licenses/lgpl+gpl-3.0.txt", + "https://opensource.org/licenses/LGPL-3.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/LGPL-3.0-or-later.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LGPL-3.0-or-later.json", + "referenceNumber": 411, + "name": "GNU Lesser General Public License v3.0 or later", + "licenseId": "LGPL-3.0-or-later", + "seeAlso": [ + "https://www.gnu.org/licenses/lgpl-3.0-standalone.html", + "https://www.gnu.org/licenses/lgpl+gpl-3.0.txt", + "https://opensource.org/licenses/LGPL-3.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/LGPLLR.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LGPLLR.json", + "referenceNumber": 87, + "name": "Lesser General Public License For Linguistic Resources", + "licenseId": "LGPLLR", + "seeAlso": [ + "http://www-igm.univ-mlv.fr/~unitex/lgpllr.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Libpng.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Libpng.json", + "referenceNumber": 531, + "name": "libpng License", + "licenseId": "Libpng", + "seeAlso": [ + "http://www.libpng.org/pub/png/src/libpng-LICENSE.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/libpng-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/libpng-2.0.json", + "referenceNumber": 149, + "name": "PNG Reference Library version 2", + "licenseId": "libpng-2.0", + "seeAlso": [ + "http://www.libpng.org/pub/png/src/libpng-LICENSE.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/libselinux-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/libselinux-1.0.json", + "referenceNumber": 320, + "name": "libselinux public domain notice", + "licenseId": "libselinux-1.0", + "seeAlso": [ + "https://github.com/SELinuxProject/selinux/blob/master/libselinux/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/libtiff.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/libtiff.json", + "referenceNumber": 24, + "name": "libtiff License", + "licenseId": "libtiff", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/libtiff" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/libutil-David-Nugent.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/libutil-David-Nugent.json", + "referenceNumber": 662, + "name": "libutil David Nugent License", + "licenseId": "libutil-David-Nugent", + "seeAlso": [ + "http://web.mit.edu/freebsd/head/lib/libutil/login_ok.3", + "https://cgit.freedesktop.org/libbsd/tree/man/setproctitle.3bsd" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/LiLiQ-P-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LiLiQ-P-1.1.json", + "referenceNumber": 150, + "name": "Licence Libre du Québec – Permissive version 1.1", + "licenseId": "LiLiQ-P-1.1", + "seeAlso": [ + "https://forge.gouv.qc.ca/licence/fr/liliq-v1-1/", + "http://opensource.org/licenses/LiLiQ-P-1.1" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/LiLiQ-R-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LiLiQ-R-1.1.json", + "referenceNumber": 203, + "name": "Licence Libre du Québec – Réciprocité version 1.1", + "licenseId": "LiLiQ-R-1.1", + "seeAlso": [ + "https://www.forge.gouv.qc.ca/participez/licence-logicielle/licence-libre-du-quebec-liliq-en-francais/licence-libre-du-quebec-reciprocite-liliq-r-v1-1/", + "http://opensource.org/licenses/LiLiQ-R-1.1" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/LiLiQ-Rplus-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LiLiQ-Rplus-1.1.json", + "referenceNumber": 314, + "name": "Licence Libre du Québec – Réciprocité forte version 1.1", + "licenseId": "LiLiQ-Rplus-1.1", + "seeAlso": [ + "https://www.forge.gouv.qc.ca/participez/licence-logicielle/licence-libre-du-quebec-liliq-en-francais/licence-libre-du-quebec-reciprocite-forte-liliq-r-v1-1/", + "http://opensource.org/licenses/LiLiQ-Rplus-1.1" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/Linux-man-pages-1-para.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Linux-man-pages-1-para.json", + "referenceNumber": 577, + "name": "Linux man-pages - 1 paragraph", + "licenseId": "Linux-man-pages-1-para", + "seeAlso": [ + "https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man2/getcpu.2#n4" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Linux-man-pages-copyleft.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Linux-man-pages-copyleft.json", + "referenceNumber": 213, + "name": "Linux man-pages Copyleft", + "licenseId": "Linux-man-pages-copyleft", + "seeAlso": [ + "https://www.kernel.org/doc/man-pages/licenses.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Linux-man-pages-copyleft-2-para.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Linux-man-pages-copyleft-2-para.json", + "referenceNumber": 352, + "name": "Linux man-pages Copyleft - 2 paragraphs", + "licenseId": "Linux-man-pages-copyleft-2-para", + "seeAlso": [ + "https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man2/move_pages.2#n5", + "https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man2/migrate_pages.2#n8" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Linux-man-pages-copyleft-var.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Linux-man-pages-copyleft-var.json", + "referenceNumber": 186, + "name": "Linux man-pages Copyleft Variant", + "licenseId": "Linux-man-pages-copyleft-var", + "seeAlso": [ + "https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man2/set_mempolicy.2#n5" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Linux-OpenIB.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Linux-OpenIB.json", + "referenceNumber": 278, + "name": "Linux Kernel Variant of OpenIB.org license", + "licenseId": "Linux-OpenIB", + "seeAlso": [ + "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/infiniband/core/sa.h" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/LOOP.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LOOP.json", + "referenceNumber": 521, + "name": "Common Lisp LOOP License", + "licenseId": "LOOP", + "seeAlso": [ + "https://gitlab.com/embeddable-common-lisp/ecl/-/blob/develop/src/lsp/loop.lsp", + "http://git.savannah.gnu.org/cgit/gcl.git/tree/gcl/lsp/gcl_loop.lsp?h\u003dVersion_2_6_13pre", + "https://sourceforge.net/p/sbcl/sbcl/ci/master/tree/src/code/loop.lisp", + "https://github.com/cl-adams/adams/blob/master/LICENSE.md", + "https://github.com/blakemcbride/eclipse-lisp/blob/master/lisp/loop.lisp", + "https://gitlab.common-lisp.net/cmucl/cmucl/-/blob/master/src/code/loop.lisp" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/LPD-document.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LPD-document.json", + "referenceNumber": 561, + "name": "LPD Documentation License", + "licenseId": "LPD-document", + "seeAlso": [ + "https://github.com/Cyan4973/xxHash/blob/dev/doc/xxhash_spec.md", + "https://www.ietf.org/rfc/rfc1952.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/LPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LPL-1.0.json", + "referenceNumber": 267, + "name": "Lucent Public License Version 1.0", + "licenseId": "LPL-1.0", + "seeAlso": [ + "https://opensource.org/licenses/LPL-1.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/LPL-1.02.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LPL-1.02.json", + "referenceNumber": 122, + "name": "Lucent Public License v1.02", + "licenseId": "LPL-1.02", + "seeAlso": [ + "http://plan9.bell-labs.com/plan9/license.html", + "https://opensource.org/licenses/LPL-1.02" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/LPPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LPPL-1.0.json", + "referenceNumber": 133, + "name": "LaTeX Project Public License v1.0", + "licenseId": "LPPL-1.0", + "seeAlso": [ + "http://www.latex-project.org/lppl/lppl-1-0.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/LPPL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LPPL-1.1.json", + "referenceNumber": 284, + "name": "LaTeX Project Public License v1.1", + "licenseId": "LPPL-1.1", + "seeAlso": [ + "http://www.latex-project.org/lppl/lppl-1-1.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/LPPL-1.2.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LPPL-1.2.json", + "referenceNumber": 407, + "name": "LaTeX Project Public License v1.2", + "licenseId": "LPPL-1.2", + "seeAlso": [ + "http://www.latex-project.org/lppl/lppl-1-2.txt" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/LPPL-1.3a.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LPPL-1.3a.json", + "referenceNumber": 510, + "name": "LaTeX Project Public License v1.3a", + "licenseId": "LPPL-1.3a", + "seeAlso": [ + "http://www.latex-project.org/lppl/lppl-1-3a.txt" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/LPPL-1.3c.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LPPL-1.3c.json", + "referenceNumber": 300, + "name": "LaTeX Project Public License v1.3c", + "licenseId": "LPPL-1.3c", + "seeAlso": [ + "http://www.latex-project.org/lppl/lppl-1-3c.txt", + "https://opensource.org/licenses/LPPL-1.3c" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/lsof.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/lsof.json", + "referenceNumber": 76, + "name": "lsof License", + "licenseId": "lsof", + "seeAlso": [ + "https://github.com/lsof-org/lsof/blob/master/COPYING" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Lucida-Bitmap-Fonts.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Lucida-Bitmap-Fonts.json", + "referenceNumber": 383, + "name": "Lucida Bitmap Fonts License", + "licenseId": "Lucida-Bitmap-Fonts", + "seeAlso": [ + "https://gitlab.freedesktop.org/xorg/font/bh-100dpi/-/blob/master/COPYING?ref_type\u003dheads" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/LZMA-SDK-9.11-to-9.20.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LZMA-SDK-9.11-to-9.20.json", + "referenceNumber": 239, + "name": "LZMA SDK License (versions 9.11 to 9.20)", + "licenseId": "LZMA-SDK-9.11-to-9.20", + "seeAlso": [ + "https://www.7-zip.org/sdk.html", + "https://sourceforge.net/projects/sevenzip/files/LZMA%20SDK/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/LZMA-SDK-9.22.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/LZMA-SDK-9.22.json", + "referenceNumber": 600, + "name": "LZMA SDK License (versions 9.22 and beyond)", + "licenseId": "LZMA-SDK-9.22", + "seeAlso": [ + "https://www.7-zip.org/sdk.html", + "https://sourceforge.net/projects/sevenzip/files/LZMA%20SDK/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Mackerras-3-Clause.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Mackerras-3-Clause.json", + "referenceNumber": 540, + "name": "Mackerras 3-Clause License", + "licenseId": "Mackerras-3-Clause", + "seeAlso": [ + "https://github.com/ppp-project/ppp/blob/master/pppd/chap_ms.c#L6-L28" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Mackerras-3-Clause-acknowledgment.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Mackerras-3-Clause-acknowledgment.json", + "referenceNumber": 176, + "name": "Mackerras 3-Clause - acknowledgment variant", + "licenseId": "Mackerras-3-Clause-acknowledgment", + "seeAlso": [ + "https://github.com/ppp-project/ppp/blob/master/pppd/auth.c#L6-L28" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/magaz.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/magaz.json", + "referenceNumber": 93, + "name": "magaz License", + "licenseId": "magaz", + "seeAlso": [ + "https://mirrors.nic.cz/tex-archive/macros/latex/contrib/magaz/magaz.tex" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/mailprio.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/mailprio.json", + "referenceNumber": 292, + "name": "mailprio License", + "licenseId": "mailprio", + "seeAlso": [ + "https://fossies.org/linux/sendmail/contrib/mailprio" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MakeIndex.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MakeIndex.json", + "referenceNumber": 552, + "name": "MakeIndex License", + "licenseId": "MakeIndex", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/MakeIndex" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Martin-Birgmeier.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Martin-Birgmeier.json", + "referenceNumber": 364, + "name": "Martin Birgmeier License", + "licenseId": "Martin-Birgmeier", + "seeAlso": [ + "https://github.com/Perl/perl5/blob/blead/util.c#L6136" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/McPhee-slideshow.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/McPhee-slideshow.json", + "referenceNumber": 511, + "name": "McPhee Slideshow License", + "licenseId": "McPhee-slideshow", + "seeAlso": [ + "https://mirror.las.iastate.edu/tex-archive/graphics/metapost/contrib/macros/slideshow/slideshow.mp" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/metamail.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/metamail.json", + "referenceNumber": 325, + "name": "metamail License", + "licenseId": "metamail", + "seeAlso": [ + "https://github.com/Dual-Life/mime-base64/blob/master/Base64.xs#L12" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Minpack.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Minpack.json", + "referenceNumber": 634, + "name": "Minpack License", + "licenseId": "Minpack", + "seeAlso": [ + "http://www.netlib.org/minpack/disclaimer", + "https://gitlab.com/libeigen/eigen/-/blob/master/COPYING.MINPACK" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MirOS.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MirOS.json", + "referenceNumber": 202, + "name": "The MirOS Licence", + "licenseId": "MirOS", + "seeAlso": [ + "https://opensource.org/licenses/MirOS" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/MIT.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MIT.json", + "referenceNumber": 601, + "name": "MIT License", + "licenseId": "MIT", + "seeAlso": [ + "https://opensource.org/license/mit/" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/MIT-0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MIT-0.json", + "referenceNumber": 587, + "name": "MIT No Attribution", + "licenseId": "MIT-0", + "seeAlso": [ + "https://github.com/aws/mit-0", + "https://romanrm.net/mit-zero", + "https://github.com/awsdocs/aws-cloud9-user-guide/blob/master/LICENSE-SAMPLECODE" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/MIT-advertising.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MIT-advertising.json", + "referenceNumber": 39, + "name": "Enlightenment License (e16)", + "licenseId": "MIT-advertising", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/MIT_With_Advertising" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MIT-CMU.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MIT-CMU.json", + "referenceNumber": 36, + "name": "CMU License", + "licenseId": "MIT-CMU", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing:MIT?rd\u003dLicensing/MIT#CMU_Style", + "https://github.com/python-pillow/Pillow/blob/fffb426092c8db24a5f4b6df243a8a3c01fb63cd/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MIT-enna.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MIT-enna.json", + "referenceNumber": 207, + "name": "enna License", + "licenseId": "MIT-enna", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/MIT#enna" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MIT-feh.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MIT-feh.json", + "referenceNumber": 146, + "name": "feh License", + "licenseId": "MIT-feh", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/MIT#feh" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MIT-Festival.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MIT-Festival.json", + "referenceNumber": 431, + "name": "MIT Festival Variant", + "licenseId": "MIT-Festival", + "seeAlso": [ + "https://github.com/festvox/flite/blob/master/COPYING", + "https://github.com/festvox/speech_tools/blob/master/COPYING" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MIT-Khronos-old.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MIT-Khronos-old.json", + "referenceNumber": 68, + "name": "MIT Khronos - old variant", + "licenseId": "MIT-Khronos-old", + "seeAlso": [ + "https://github.com/KhronosGroup/SPIRV-Cross/blob/main/LICENSES/LicenseRef-KhronosFreeUse.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MIT-Modern-Variant.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MIT-Modern-Variant.json", + "referenceNumber": 92, + "name": "MIT License Modern Variant", + "licenseId": "MIT-Modern-Variant", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing:MIT#Modern_Variants", + "https://ptolemy.berkeley.edu/copyright.htm", + "https://pirlwww.lpl.arizona.edu/resources/guide/software/PerlTk/Tixlic.html" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/MIT-open-group.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MIT-open-group.json", + "referenceNumber": 520, + "name": "MIT Open Group variant", + "licenseId": "MIT-open-group", + "seeAlso": [ + "https://gitlab.freedesktop.org/xorg/app/iceauth/-/blob/master/COPYING", + "https://gitlab.freedesktop.org/xorg/app/xvinfo/-/blob/master/COPYING", + "https://gitlab.freedesktop.org/xorg/app/xsetroot/-/blob/master/COPYING", + "https://gitlab.freedesktop.org/xorg/app/xauth/-/blob/master/COPYING" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MIT-testregex.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MIT-testregex.json", + "referenceNumber": 578, + "name": "MIT testregex Variant", + "licenseId": "MIT-testregex", + "seeAlso": [ + "https://github.com/dotnet/runtime/blob/55e1ac7c07df62c4108d4acedf78f77574470ce5/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/AttRegexTests.cs#L12-L28" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MIT-Wu.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MIT-Wu.json", + "referenceNumber": 156, + "name": "MIT Tom Wu Variant", + "licenseId": "MIT-Wu", + "seeAlso": [ + "https://github.com/chromium/octane/blob/master/crypto.js" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MITNFA.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MITNFA.json", + "referenceNumber": 650, + "name": "MIT +no-false-attribs license", + "licenseId": "MITNFA", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/MITNFA" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MMIXware.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MMIXware.json", + "referenceNumber": 444, + "name": "MMIXware License", + "licenseId": "MMIXware", + "seeAlso": [ + "https://gitlab.lrz.de/mmix/mmixware/-/blob/master/boilerplate.w" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Motosoto.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Motosoto.json", + "referenceNumber": 31, + "name": "Motosoto License", + "licenseId": "Motosoto", + "seeAlso": [ + "https://opensource.org/licenses/Motosoto" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/MPEG-SSG.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MPEG-SSG.json", + "referenceNumber": 323, + "name": "MPEG Software Simulation", + "licenseId": "MPEG-SSG", + "seeAlso": [ + "https://sourceforge.net/p/netpbm/code/HEAD/tree/super_stable/converter/ppm/ppmtompeg/jrevdct.c#l1189" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/mpi-permissive.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/mpi-permissive.json", + "referenceNumber": 459, + "name": "mpi Permissive License", + "licenseId": "mpi-permissive", + "seeAlso": [ + "https://sources.debian.org/src/openmpi/4.1.0-10/ompi/debuggers/msgq_interface.h/?hl\u003d19#L19" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/mpich2.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/mpich2.json", + "referenceNumber": 448, + "name": "mpich2 License", + "licenseId": "mpich2", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/MIT" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MPL-1.0.json", + "referenceNumber": 248, + "name": "Mozilla Public License 1.0", + "licenseId": "MPL-1.0", + "seeAlso": [ + "http://www.mozilla.org/MPL/MPL-1.0.html", + "https://opensource.org/licenses/MPL-1.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/MPL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MPL-1.1.json", + "referenceNumber": 219, + "name": "Mozilla Public License 1.1", + "licenseId": "MPL-1.1", + "seeAlso": [ + "http://www.mozilla.org/MPL/MPL-1.1.html", + "https://opensource.org/licenses/MPL-1.1" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/MPL-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MPL-2.0.json", + "referenceNumber": 147, + "name": "Mozilla Public License 2.0", + "licenseId": "MPL-2.0", + "seeAlso": [ + "https://www.mozilla.org/MPL/2.0/", + "https://opensource.org/licenses/MPL-2.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/MPL-2.0-no-copyleft-exception.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MPL-2.0-no-copyleft-exception.json", + "referenceNumber": 529, + "name": "Mozilla Public License 2.0 (no copyleft exception)", + "licenseId": "MPL-2.0-no-copyleft-exception", + "seeAlso": [ + "https://www.mozilla.org/MPL/2.0/", + "https://opensource.org/licenses/MPL-2.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/mplus.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/mplus.json", + "referenceNumber": 553, + "name": "mplus Font License", + "licenseId": "mplus", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing:Mplus?rd\u003dLicensing/mplus" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MS-LPL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MS-LPL.json", + "referenceNumber": 412, + "name": "Microsoft Limited Public License", + "licenseId": "MS-LPL", + "seeAlso": [ + "https://www.openhub.net/licenses/mslpl", + "https://github.com/gabegundy/atlserver/blob/master/License.txt", + "https://en.wikipedia.org/wiki/Shared_Source_Initiative#Microsoft_Limited_Public_License_(Ms-LPL)" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MS-PL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MS-PL.json", + "referenceNumber": 360, + "name": "Microsoft Public License", + "licenseId": "MS-PL", + "seeAlso": [ + "http://www.microsoft.com/opensource/licenses.mspx", + "https://opensource.org/licenses/MS-PL" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/MS-RL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MS-RL.json", + "referenceNumber": 212, + "name": "Microsoft Reciprocal License", + "licenseId": "MS-RL", + "seeAlso": [ + "http://www.microsoft.com/opensource/licenses.mspx", + "https://opensource.org/licenses/MS-RL" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/MTLL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MTLL.json", + "referenceNumber": 610, + "name": "Matrix Template Library License", + "licenseId": "MTLL", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Matrix_Template_Library_License" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MulanPSL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MulanPSL-1.0.json", + "referenceNumber": 236, + "name": "Mulan Permissive Software License, Version 1", + "licenseId": "MulanPSL-1.0", + "seeAlso": [ + "https://license.coscl.org.cn/MulanPSL/", + "https://github.com/yuwenlong/longphp/blob/25dfb70cc2a466dc4bb55ba30901cbce08d164b5/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/MulanPSL-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/MulanPSL-2.0.json", + "referenceNumber": 523, + "name": "Mulan Permissive Software License, Version 2", + "licenseId": "MulanPSL-2.0", + "seeAlso": [ + "https://license.coscl.org.cn/MulanPSL2" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/Multics.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Multics.json", + "referenceNumber": 462, + "name": "Multics License", + "licenseId": "Multics", + "seeAlso": [ + "https://opensource.org/licenses/Multics" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/Mup.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Mup.json", + "referenceNumber": 515, + "name": "Mup License", + "licenseId": "Mup", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Mup" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NAIST-2003.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NAIST-2003.json", + "referenceNumber": 118, + "name": "Nara Institute of Science and Technology License (2003)", + "licenseId": "NAIST-2003", + "seeAlso": [ + "https://enterprise.dejacode.com/licenses/public/naist-2003/#license-text", + "https://github.com/nodejs/node/blob/4a19cc8947b1bba2b2d27816ec3d0edf9b28e503/LICENSE#L343" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NASA-1.3.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NASA-1.3.json", + "referenceNumber": 488, + "name": "NASA Open Source Agreement 1.3", + "licenseId": "NASA-1.3", + "seeAlso": [ + "http://ti.arc.nasa.gov/opensource/nosa/", + "https://opensource.org/licenses/NASA-1.3" + ], + "isOsiApproved": true, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/Naumen.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Naumen.json", + "referenceNumber": 400, + "name": "Naumen Public License", + "licenseId": "Naumen", + "seeAlso": [ + "https://opensource.org/licenses/Naumen" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/NBPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NBPL-1.0.json", + "referenceNumber": 168, + "name": "Net Boolean Public License v1", + "licenseId": "NBPL-1.0", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d37b4b3f6cc4bf34e1d3dec61e69914b9819d8894" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NCBI-PD.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NCBI-PD.json", + "referenceNumber": 599, + "name": "NCBI Public Domain Notice", + "licenseId": "NCBI-PD", + "seeAlso": [ + "https://github.com/ncbi/sra-tools/blob/e8e5b6af4edc460156ad9ce5902d0779cffbf685/LICENSE", + "https://github.com/ncbi/datasets/blob/0ea4cd16b61e5b799d9cc55aecfa016d6c9bd2bf/LICENSE.md", + "https://github.com/ncbi/gprobe/blob/de64d30fee8b4c4013094d7d3139ea89b5dd1ace/LICENSE", + "https://github.com/ncbi/egapx/blob/08930b9dec0c69b2d1a05e5153c7b95ef0a3eb0f/LICENSE", + "https://github.com/ncbi/datasets/blob/master/LICENSE.md" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NCGL-UK-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NCGL-UK-2.0.json", + "referenceNumber": 130, + "name": "Non-Commercial Government Licence", + "licenseId": "NCGL-UK-2.0", + "seeAlso": [ + "http://www.nationalarchives.gov.uk/doc/non-commercial-government-licence/version/2/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NCL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NCL.json", + "referenceNumber": 516, + "name": "NCL Source Code License", + "licenseId": "NCL", + "seeAlso": [ + "https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/src/modules/module-filter-chain/pffft.c?ref_type\u003dheads#L1-52" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NCSA.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NCSA.json", + "referenceNumber": 652, + "name": "University of Illinois/NCSA Open Source License", + "licenseId": "NCSA", + "seeAlso": [ + "http://otm.illinois.edu/uiuc_openSource", + "https://opensource.org/licenses/NCSA" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Net-SNMP.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/Net-SNMP.json", + "referenceNumber": 469, + "name": "Net-SNMP License", + "licenseId": "Net-SNMP", + "seeAlso": [ + "http://net-snmp.sourceforge.net/about/license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NetCDF.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NetCDF.json", + "referenceNumber": 189, + "name": "NetCDF license", + "licenseId": "NetCDF", + "seeAlso": [ + "http://www.unidata.ucar.edu/software/netcdf/copyright.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Newsletr.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Newsletr.json", + "referenceNumber": 499, + "name": "Newsletr License", + "licenseId": "Newsletr", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Newsletr" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NGPL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NGPL.json", + "referenceNumber": 167, + "name": "Nethack General Public License", + "licenseId": "NGPL", + "seeAlso": [ + "https://opensource.org/licenses/NGPL" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/NICTA-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NICTA-1.0.json", + "referenceNumber": 486, + "name": "NICTA Public Software License, Version 1.0", + "licenseId": "NICTA-1.0", + "seeAlso": [ + "https://opensource.apple.com/source/mDNSResponder/mDNSResponder-320.10/mDNSPosix/nss_ReadMe.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NIST-PD.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NIST-PD.json", + "referenceNumber": 194, + "name": "NIST Public Domain Notice", + "licenseId": "NIST-PD", + "seeAlso": [ + "https://github.com/tcheneau/simpleRPL/blob/e645e69e38dd4e3ccfeceb2db8cba05b7c2e0cd3/LICENSE.txt", + "https://github.com/tcheneau/Routing/blob/f09f46fcfe636107f22f2c98348188a65a135d98/README.md" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NIST-PD-fallback.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NIST-PD-fallback.json", + "referenceNumber": 223, + "name": "NIST Public Domain Notice with license fallback", + "licenseId": "NIST-PD-fallback", + "seeAlso": [ + "https://github.com/usnistgov/jsip/blob/59700e6926cbe96c5cdae897d9a7d2656b42abe3/LICENSE", + "https://github.com/usnistgov/fipy/blob/86aaa5c2ba2c6f1be19593c5986071cf6568cc34/LICENSE.rst" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NIST-Software.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NIST-Software.json", + "referenceNumber": 251, + "name": "NIST Software License", + "licenseId": "NIST-Software", + "seeAlso": [ + "https://github.com/open-quantum-safe/liboqs/blob/40b01fdbb270f8614fde30e65d30e9da18c02393/src/common/rand/rand_nist.c#L1-L15" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NLOD-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NLOD-1.0.json", + "referenceNumber": 294, + "name": "Norwegian Licence for Open Government Data (NLOD) 1.0", + "licenseId": "NLOD-1.0", + "seeAlso": [ + "http://data.norge.no/nlod/en/1.0" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NLOD-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NLOD-2.0.json", + "referenceNumber": 566, + "name": "Norwegian Licence for Open Government Data (NLOD) 2.0", + "licenseId": "NLOD-2.0", + "seeAlso": [ + "http://data.norge.no/nlod/en/2.0" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NLPL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NLPL.json", + "referenceNumber": 367, + "name": "No Limit Public License", + "licenseId": "NLPL", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/NLPL" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Nokia.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Nokia.json", + "referenceNumber": 145, + "name": "Nokia Open Source License", + "licenseId": "Nokia", + "seeAlso": [ + "https://opensource.org/licenses/nokia" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/NOSL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NOSL.json", + "referenceNumber": 254, + "name": "Netizen Open Source License", + "licenseId": "NOSL", + "seeAlso": [ + "http://bits.netizen.com.au/licenses/NOSL/nosl.txt" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Noweb.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Noweb.json", + "referenceNumber": 30, + "name": "Noweb License", + "licenseId": "Noweb", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Noweb" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NPL-1.0.json", + "referenceNumber": 211, + "name": "Netscape Public License v1.0", + "licenseId": "NPL-1.0", + "seeAlso": [ + "http://www.mozilla.org/MPL/NPL/1.0/" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/NPL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NPL-1.1.json", + "referenceNumber": 595, + "name": "Netscape Public License v1.1", + "licenseId": "NPL-1.1", + "seeAlso": [ + "http://www.mozilla.org/MPL/NPL/1.1/" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/NPOSL-3.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NPOSL-3.0.json", + "referenceNumber": 664, + "name": "Non-Profit Open Software License 3.0", + "licenseId": "NPOSL-3.0", + "seeAlso": [ + "https://opensource.org/licenses/NOSL3.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/NRL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NRL.json", + "referenceNumber": 113, + "name": "NRL License", + "licenseId": "NRL", + "seeAlso": [ + "http://web.mit.edu/network/isakmp/nrllicense.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/NTP.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NTP.json", + "referenceNumber": 390, + "name": "NTP License", + "licenseId": "NTP", + "seeAlso": [ + "https://opensource.org/licenses/NTP" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/NTP-0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/NTP-0.json", + "referenceNumber": 64, + "name": "NTP No Attribution", + "licenseId": "NTP-0", + "seeAlso": [ + "https://github.com/tytso/e2fsprogs/blob/master/lib/et/et_name.c" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Nunit.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/Nunit.json", + "referenceNumber": 27, + "name": "Nunit License", + "licenseId": "Nunit", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Nunit" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/O-UDA-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/O-UDA-1.0.json", + "referenceNumber": 161, + "name": "Open Use of Data Agreement v1.0", + "licenseId": "O-UDA-1.0", + "seeAlso": [ + "https://github.com/microsoft/Open-Use-of-Data-Agreement/blob/v1.0/O-UDA-1.0.md", + "https://cdla.dev/open-use-of-data-agreement-v1-0/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OAR.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OAR.json", + "referenceNumber": 100, + "name": "OAR License", + "licenseId": "OAR", + "seeAlso": [ + "https://sourceware.org/git/?p\u003dnewlib-cygwin.git;a\u003dblob;f\u003dnewlib/libc/string/strsignal.c;hb\u003dHEAD#l35" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OCCT-PL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OCCT-PL.json", + "referenceNumber": 408, + "name": "Open CASCADE Technology Public License", + "licenseId": "OCCT-PL", + "seeAlso": [ + "http://www.opencascade.com/content/occt-public-license" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OCLC-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OCLC-2.0.json", + "referenceNumber": 468, + "name": "OCLC Research Public License 2.0", + "licenseId": "OCLC-2.0", + "seeAlso": [ + "http://www.oclc.org/research/activities/software/license/v2final.htm", + "https://opensource.org/licenses/OCLC-2.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/ODbL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ODbL-1.0.json", + "referenceNumber": 611, + "name": "Open Data Commons Open Database License v1.0", + "licenseId": "ODbL-1.0", + "seeAlso": [ + "http://www.opendatacommons.org/licenses/odbl/1.0/", + "https://opendatacommons.org/licenses/odbl/1-0/" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/ODC-By-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ODC-By-1.0.json", + "referenceNumber": 15, + "name": "Open Data Commons Attribution License v1.0", + "licenseId": "ODC-By-1.0", + "seeAlso": [ + "https://opendatacommons.org/licenses/by/1.0/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OFFIS.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OFFIS.json", + "referenceNumber": 418, + "name": "OFFIS License", + "licenseId": "OFFIS", + "seeAlso": [ + "https://sourceforge.net/p/xmedcon/code/ci/master/tree/libs/dicom/README" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OFL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OFL-1.0.json", + "referenceNumber": 603, + "name": "SIL Open Font License 1.0", + "licenseId": "OFL-1.0", + "seeAlso": [ + "http://scripts.sil.org/cms/scripts/page.php?item_id\u003dOFL10_web" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/OFL-1.0-no-RFN.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OFL-1.0-no-RFN.json", + "referenceNumber": 545, + "name": "SIL Open Font License 1.0 with no Reserved Font Name", + "licenseId": "OFL-1.0-no-RFN", + "seeAlso": [ + "http://scripts.sil.org/cms/scripts/page.php?item_id\u003dOFL10_web" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OFL-1.0-RFN.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OFL-1.0-RFN.json", + "referenceNumber": 446, + "name": "SIL Open Font License 1.0 with Reserved Font Name", + "licenseId": "OFL-1.0-RFN", + "seeAlso": [ + "http://scripts.sil.org/cms/scripts/page.php?item_id\u003dOFL10_web" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OFL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OFL-1.1.json", + "referenceNumber": 0, + "name": "SIL Open Font License 1.1", + "licenseId": "OFL-1.1", + "seeAlso": [ + "http://scripts.sil.org/cms/scripts/page.php?item_id\u003dOFL_web", + "https://opensource.org/licenses/OFL-1.1" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/OFL-1.1-no-RFN.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OFL-1.1-no-RFN.json", + "referenceNumber": 110, + "name": "SIL Open Font License 1.1 with no Reserved Font Name", + "licenseId": "OFL-1.1-no-RFN", + "seeAlso": [ + "http://scripts.sil.org/cms/scripts/page.php?item_id\u003dOFL_web", + "https://opensource.org/licenses/OFL-1.1" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/OFL-1.1-RFN.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OFL-1.1-RFN.json", + "referenceNumber": 90, + "name": "SIL Open Font License 1.1 with Reserved Font Name", + "licenseId": "OFL-1.1-RFN", + "seeAlso": [ + "http://scripts.sil.org/cms/scripts/page.php?item_id\u003dOFL_web", + "https://opensource.org/licenses/OFL-1.1" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/OGC-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OGC-1.0.json", + "referenceNumber": 504, + "name": "OGC Software License, Version 1.0", + "licenseId": "OGC-1.0", + "seeAlso": [ + "https://www.ogc.org/ogc/software/1.0" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OGDL-Taiwan-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OGDL-Taiwan-1.0.json", + "referenceNumber": 23, + "name": "Taiwan Open Government Data License, version 1.0", + "licenseId": "OGDL-Taiwan-1.0", + "seeAlso": [ + "https://data.gov.tw/license" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OGL-Canada-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OGL-Canada-2.0.json", + "referenceNumber": 40, + "name": "Open Government Licence - Canada", + "licenseId": "OGL-Canada-2.0", + "seeAlso": [ + "https://open.canada.ca/en/open-government-licence-canada" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OGL-UK-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OGL-UK-1.0.json", + "referenceNumber": 497, + "name": "Open Government Licence v1.0", + "licenseId": "OGL-UK-1.0", + "seeAlso": [ + "http://www.nationalarchives.gov.uk/doc/open-government-licence/version/1/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OGL-UK-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OGL-UK-2.0.json", + "referenceNumber": 556, + "name": "Open Government Licence v2.0", + "licenseId": "OGL-UK-2.0", + "seeAlso": [ + "http://www.nationalarchives.gov.uk/doc/open-government-licence/version/2/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OGL-UK-3.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OGL-UK-3.0.json", + "referenceNumber": 585, + "name": "Open Government Licence v3.0", + "licenseId": "OGL-UK-3.0", + "seeAlso": [ + "http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OGTSL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OGTSL.json", + "referenceNumber": 97, + "name": "Open Group Test Suite License", + "licenseId": "OGTSL", + "seeAlso": [ + "http://www.opengroup.org/testing/downloads/The_Open_Group_TSL.txt", + "https://opensource.org/licenses/OGTSL" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/OLDAP-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-1.1.json", + "referenceNumber": 420, + "name": "Open LDAP Public License v1.1", + "licenseId": "OLDAP-1.1", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d806557a5ad59804ef3a44d5abfbe91d706b0791f" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OLDAP-1.2.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-1.2.json", + "referenceNumber": 487, + "name": "Open LDAP Public License v1.2", + "licenseId": "OLDAP-1.2", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d42b0383c50c299977b5893ee695cf4e486fb0dc7" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OLDAP-1.3.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-1.3.json", + "referenceNumber": 627, + "name": "Open LDAP Public License v1.3", + "licenseId": "OLDAP-1.3", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003de5f8117f0ce088d0bd7a8e18ddf37eaa40eb09b1" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OLDAP-1.4.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-1.4.json", + "referenceNumber": 45, + "name": "Open LDAP Public License v1.4", + "licenseId": "OLDAP-1.4", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003dc9f95c2f3f2ffb5e0ae55fe7388af75547660941" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OLDAP-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-2.0.json", + "referenceNumber": 537, + "name": "Open LDAP Public License v2.0 (or possibly 2.0A and 2.0B)", + "licenseId": "OLDAP-2.0", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003dcbf50f4e1185a21abd4c0a54d3f4341fe28f36ea" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OLDAP-2.0.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-2.0.1.json", + "referenceNumber": 179, + "name": "Open LDAP Public License v2.0.1", + "licenseId": "OLDAP-2.0.1", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003db6d68acd14e51ca3aab4428bf26522aa74873f0e" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OLDAP-2.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-2.1.json", + "referenceNumber": 342, + "name": "Open LDAP Public License v2.1", + "licenseId": "OLDAP-2.1", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003db0d176738e96a0d3b9f85cb51e140a86f21be715" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OLDAP-2.2.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-2.2.json", + "referenceNumber": 347, + "name": "Open LDAP Public License v2.2", + "licenseId": "OLDAP-2.2", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d470b0c18ec67621c85881b2733057fecf4a1acc3" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OLDAP-2.2.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-2.2.1.json", + "referenceNumber": 208, + "name": "Open LDAP Public License v2.2.1", + "licenseId": "OLDAP-2.2.1", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d4bc786f34b50aa301be6f5600f58a980070f481e" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OLDAP-2.2.2.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-2.2.2.json", + "referenceNumber": 312, + "name": "Open LDAP Public License 2.2.2", + "licenseId": "OLDAP-2.2.2", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003ddf2cc1e21eb7c160695f5b7cffd6296c151ba188" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OLDAP-2.3.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-2.3.json", + "referenceNumber": 276, + "name": "Open LDAP Public License v2.3", + "licenseId": "OLDAP-2.3", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003dd32cf54a32d581ab475d23c810b0a7fbaf8d63c3" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/OLDAP-2.4.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-2.4.json", + "referenceNumber": 108, + "name": "Open LDAP Public License v2.4", + "licenseId": "OLDAP-2.4", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003dcd1284c4a91a8a380d904eee68d1583f989ed386" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OLDAP-2.5.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-2.5.json", + "referenceNumber": 518, + "name": "Open LDAP Public License v2.5", + "licenseId": "OLDAP-2.5", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d6852b9d90022e8593c98205413380536b1b5a7cf" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OLDAP-2.6.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-2.6.json", + "referenceNumber": 275, + "name": "Open LDAP Public License v2.6", + "licenseId": "OLDAP-2.6", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d1cae062821881f41b73012ba816434897abf4205" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OLDAP-2.7.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-2.7.json", + "referenceNumber": 79, + "name": "Open LDAP Public License v2.7", + "licenseId": "OLDAP-2.7", + "seeAlso": [ + "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d47c2415c1df81556eeb39be6cad458ef87c534a2" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/OLDAP-2.8.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLDAP-2.8.json", + "referenceNumber": 72, + "name": "Open LDAP Public License v2.8", + "licenseId": "OLDAP-2.8", + "seeAlso": [ + "http://www.openldap.org/software/release/license.html" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/OLFL-1.3.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OLFL-1.3.json", + "referenceNumber": 204, + "name": "Open Logistics Foundation License Version 1.3", + "licenseId": "OLFL-1.3", + "seeAlso": [ + "https://openlogisticsfoundation.org/licenses/", + "https://opensource.org/license/olfl-1-3/" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/OML.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OML.json", + "referenceNumber": 505, + "name": "Open Market License", + "licenseId": "OML", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Open_Market_License" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OpenPBS-2.3.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OpenPBS-2.3.json", + "referenceNumber": 159, + "name": "OpenPBS v2.3 Software License", + "licenseId": "OpenPBS-2.3", + "seeAlso": [ + "https://github.com/adaptivecomputing/torque/blob/master/PBS_License.txt", + "https://www.mcs.anl.gov/research/projects/openpbs/PBS_License.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OpenSSL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OpenSSL.json", + "referenceNumber": 445, + "name": "OpenSSL License", + "licenseId": "OpenSSL", + "seeAlso": [ + "http://www.openssl.org/source/license.html" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/OpenSSL-standalone.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OpenSSL-standalone.json", + "referenceNumber": 635, + "name": "OpenSSL License - standalone", + "licenseId": "OpenSSL-standalone", + "seeAlso": [ + "https://library.netapp.com/ecm/ecm_download_file/ECMP1196395", + "https://hstechdocs.helpsystems.com/manuals/globalscape/archive/cuteftp6/open_ssl_license_agreement.htm" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OpenVision.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OpenVision.json", + "referenceNumber": 589, + "name": "OpenVision License", + "licenseId": "OpenVision", + "seeAlso": [ + "https://github.com/krb5/krb5/blob/krb5-1.21.2-final/NOTICE#L66-L98", + "https://web.mit.edu/kerberos/krb5-1.21/doc/mitK5license.html", + "https://fedoraproject.org/wiki/Licensing:MIT#OpenVision_Variant" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OPL-1.0.json", + "referenceNumber": 80, + "name": "Open Public License v1.0", + "licenseId": "OPL-1.0", + "seeAlso": [ + "http://old.koalateam.com/jackaroo/OPL_1_0.TXT", + "https://fedoraproject.org/wiki/Licensing/Open_Public_License" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/OPL-UK-3.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OPL-UK-3.0.json", + "referenceNumber": 19, + "name": "United Kingdom Open Parliament Licence v3.0", + "licenseId": "OPL-UK-3.0", + "seeAlso": [ + "https://www.parliament.uk/site-information/copyright-parliament/open-parliament-licence/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OPUBL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OPUBL-1.0.json", + "referenceNumber": 266, + "name": "Open Publication License v1.0", + "licenseId": "OPUBL-1.0", + "seeAlso": [ + "http://opencontent.org/openpub/", + "https://www.debian.org/opl", + "https://www.ctan.org/license/opl" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/OSET-PL-2.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OSET-PL-2.1.json", + "referenceNumber": 307, + "name": "OSET Public License version 2.1", + "licenseId": "OSET-PL-2.1", + "seeAlso": [ + "http://www.osetfoundation.org/public-license", + "https://opensource.org/licenses/OPL-2.1" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/OSL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OSL-1.0.json", + "referenceNumber": 306, + "name": "Open Software License 1.0", + "licenseId": "OSL-1.0", + "seeAlso": [ + "https://opensource.org/licenses/OSL-1.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/OSL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OSL-1.1.json", + "referenceNumber": 111, + "name": "Open Software License 1.1", + "licenseId": "OSL-1.1", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/OSL1.1" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/OSL-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OSL-2.0.json", + "referenceNumber": 457, + "name": "Open Software License 2.0", + "licenseId": "OSL-2.0", + "seeAlso": [ + "http://web.archive.org/web/20041020171434/http://www.rosenlaw.com/osl2.0.html" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/OSL-2.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OSL-2.1.json", + "referenceNumber": 247, + "name": "Open Software License 2.1", + "licenseId": "OSL-2.1", + "seeAlso": [ + "http://web.archive.org/web/20050212003940/http://www.rosenlaw.com/osl21.htm", + "https://opensource.org/licenses/OSL-2.1" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/OSL-3.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/OSL-3.0.json", + "referenceNumber": 432, + "name": "Open Software License 3.0", + "licenseId": "OSL-3.0", + "seeAlso": [ + "https://web.archive.org/web/20120101081418/http://rosenlaw.com:80/OSL3.0.htm", + "https://opensource.org/licenses/OSL-3.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/PADL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/PADL.json", + "referenceNumber": 43, + "name": "PADL License", + "licenseId": "PADL", + "seeAlso": [ + "https://git.openldap.org/openldap/openldap/-/blob/master/libraries/libldap/os-local.c?ref_type\u003dheads#L19-23" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Parity-6.0.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Parity-6.0.0.json", + "referenceNumber": 49, + "name": "The Parity Public License 6.0.0", + "licenseId": "Parity-6.0.0", + "seeAlso": [ + "https://paritylicense.com/versions/6.0.0.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Parity-7.0.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Parity-7.0.0.json", + "referenceNumber": 482, + "name": "The Parity Public License 7.0.0", + "licenseId": "Parity-7.0.0", + "seeAlso": [ + "https://paritylicense.com/versions/7.0.0.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/PDDL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/PDDL-1.0.json", + "referenceNumber": 210, + "name": "Open Data Commons Public Domain Dedication \u0026 License 1.0", + "licenseId": "PDDL-1.0", + "seeAlso": [ + "http://opendatacommons.org/licenses/pddl/1.0/", + "https://opendatacommons.org/licenses/pddl/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/PHP-3.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/PHP-3.0.json", + "referenceNumber": 580, + "name": "PHP License v3.0", + "licenseId": "PHP-3.0", + "seeAlso": [ + "http://www.php.net/license/3_0.txt", + "https://opensource.org/licenses/PHP-3.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/PHP-3.01.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/PHP-3.01.json", + "referenceNumber": 594, + "name": "PHP License v3.01", + "licenseId": "PHP-3.01", + "seeAlso": [ + "http://www.php.net/license/3_01.txt" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Pixar.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Pixar.json", + "referenceNumber": 619, + "name": "Pixar License", + "licenseId": "Pixar", + "seeAlso": [ + "https://github.com/PixarAnimationStudios/OpenSubdiv/raw/v3_5_0/LICENSE.txt", + "https://graphics.pixar.com/opensubdiv/docs/license.html", + "https://github.com/PixarAnimationStudios/OpenSubdiv/blob/v3_5_0/opensubdiv/version.cpp#L2-L22" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/pkgconf.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/pkgconf.json", + "referenceNumber": 16, + "name": "pkgconf License", + "licenseId": "pkgconf", + "seeAlso": [ + "https://github.com/pkgconf/pkgconf/blob/master/cli/main.c#L8" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Plexus.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Plexus.json", + "referenceNumber": 442, + "name": "Plexus Classworlds License", + "licenseId": "Plexus", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Plexus_Classworlds_License" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/pnmstitch.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/pnmstitch.json", + "referenceNumber": 502, + "name": "pnmstitch License", + "licenseId": "pnmstitch", + "seeAlso": [ + "https://sourceforge.net/p/netpbm/code/HEAD/tree/super_stable/editor/pnmstitch.c#l2" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/PolyForm-Noncommercial-1.0.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/PolyForm-Noncommercial-1.0.0.json", + "referenceNumber": 575, + "name": "PolyForm Noncommercial License 1.0.0", + "licenseId": "PolyForm-Noncommercial-1.0.0", + "seeAlso": [ + "https://polyformproject.org/licenses/noncommercial/1.0.0" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/PolyForm-Small-Business-1.0.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/PolyForm-Small-Business-1.0.0.json", + "referenceNumber": 9, + "name": "PolyForm Small Business License 1.0.0", + "licenseId": "PolyForm-Small-Business-1.0.0", + "seeAlso": [ + "https://polyformproject.org/licenses/small-business/1.0.0" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/PostgreSQL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/PostgreSQL.json", + "referenceNumber": 94, + "name": "PostgreSQL License", + "licenseId": "PostgreSQL", + "seeAlso": [ + "http://www.postgresql.org/about/licence", + "https://opensource.org/licenses/PostgreSQL" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/PPL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/PPL.json", + "referenceNumber": 454, + "name": "Peer Production License", + "licenseId": "PPL", + "seeAlso": [ + "https://wiki.p2pfoundation.net/Peer_Production_License", + "http://www.networkcultures.org/_uploads/%233notebook_telekommunist.pdf" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/PSF-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/PSF-2.0.json", + "referenceNumber": 62, + "name": "Python Software Foundation License 2.0", + "licenseId": "PSF-2.0", + "seeAlso": [ + "https://opensource.org/licenses/Python-2.0" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/psfrag.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/psfrag.json", + "referenceNumber": 279, + "name": "psfrag License", + "licenseId": "psfrag", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/psfrag" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/psutils.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/psutils.json", + "referenceNumber": 387, + "name": "psutils License", + "licenseId": "psutils", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/psutils" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Python-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Python-2.0.json", + "referenceNumber": 498, + "name": "Python License 2.0", + "licenseId": "Python-2.0", + "seeAlso": [ + "https://opensource.org/licenses/Python-2.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Python-2.0.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Python-2.0.1.json", + "referenceNumber": 453, + "name": "Python License 2.0.1", + "licenseId": "Python-2.0.1", + "seeAlso": [ + "https://www.python.org/download/releases/2.0.1/license/", + "https://docs.python.org/3/license.html", + "https://github.com/python/cpython/blob/main/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/python-ldap.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/python-ldap.json", + "referenceNumber": 422, + "name": "Python ldap License", + "licenseId": "python-ldap", + "seeAlso": [ + "https://github.com/python-ldap/python-ldap/blob/main/LICENCE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Qhull.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Qhull.json", + "referenceNumber": 123, + "name": "Qhull License", + "licenseId": "Qhull", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Qhull" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/QPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/QPL-1.0.json", + "referenceNumber": 329, + "name": "Q Public License 1.0", + "licenseId": "QPL-1.0", + "seeAlso": [ + "http://doc.qt.nokia.com/3.3/license.html", + "https://opensource.org/licenses/QPL-1.0", + "https://doc.qt.io/archives/3.3/license.html" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/QPL-1.0-INRIA-2004.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/QPL-1.0-INRIA-2004.json", + "referenceNumber": 479, + "name": "Q Public License 1.0 - INRIA 2004 variant", + "licenseId": "QPL-1.0-INRIA-2004", + "seeAlso": [ + "https://github.com/maranget/hevea/blob/master/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/radvd.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/radvd.json", + "referenceNumber": 182, + "name": "radvd License", + "licenseId": "radvd", + "seeAlso": [ + "https://github.com/radvd-project/radvd/blob/master/COPYRIGHT" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Rdisc.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Rdisc.json", + "referenceNumber": 101, + "name": "Rdisc License", + "licenseId": "Rdisc", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Rdisc_License" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/RHeCos-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/RHeCos-1.1.json", + "referenceNumber": 373, + "name": "Red Hat eCos Public License v1.1", + "licenseId": "RHeCos-1.1", + "seeAlso": [ + "http://ecos.sourceware.org/old-license.html" + ], + "isOsiApproved": false, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/RPL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/RPL-1.1.json", + "referenceNumber": 369, + "name": "Reciprocal Public License 1.1", + "licenseId": "RPL-1.1", + "seeAlso": [ + "https://opensource.org/licenses/RPL-1.1" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/RPL-1.5.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/RPL-1.5.json", + "referenceNumber": 102, + "name": "Reciprocal Public License 1.5", + "licenseId": "RPL-1.5", + "seeAlso": [ + "https://opensource.org/licenses/RPL-1.5" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/RPSL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/RPSL-1.0.json", + "referenceNumber": 663, + "name": "RealNetworks Public Source License v1.0", + "licenseId": "RPSL-1.0", + "seeAlso": [ + "https://helixcommunity.org/content/rpsl", + "https://opensource.org/licenses/RPSL-1.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/RSA-MD.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/RSA-MD.json", + "referenceNumber": 139, + "name": "RSA Message-Digest License", + "licenseId": "RSA-MD", + "seeAlso": [ + "http://www.faqs.org/rfcs/rfc1321.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/RSCPL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/RSCPL.json", + "referenceNumber": 405, + "name": "Ricoh Source Code Public License", + "licenseId": "RSCPL", + "seeAlso": [ + "http://wayback.archive.org/web/20060715140826/http://www.risource.org/RPL/RPL-1.0A.shtml", + "https://opensource.org/licenses/RSCPL" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/Ruby.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Ruby.json", + "referenceNumber": 192, + "name": "Ruby License", + "licenseId": "Ruby", + "seeAlso": [ + "https://www.ruby-lang.org/en/about/license.txt" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Ruby-pty.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Ruby-pty.json", + "referenceNumber": 473, + "name": "Ruby pty extension license", + "licenseId": "Ruby-pty", + "seeAlso": [ + "https://github.com/ruby/ruby/blob/9f6deaa6888a423720b4b127b5314f0ad26cc2e6/ext/pty/pty.c#L775-L786", + "https://github.com/ruby/ruby/commit/0a64817fb80016030c03518fb9459f63c11605ea#diff-ef5fa30838d6d0cecad9e675cc50b24628cfe2cb277c346053fafcc36c91c204", + "https://github.com/ruby/ruby/commit/0a64817fb80016030c03518fb9459f63c11605ea#diff-fedf217c1ce44bda01f0a678d3ff8b198bed478754d699c527a698ad933979a0" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SAX-PD.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SAX-PD.json", + "referenceNumber": 205, + "name": "Sax Public Domain Notice", + "licenseId": "SAX-PD", + "seeAlso": [ + "http://www.saxproject.org/copying.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SAX-PD-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SAX-PD-2.0.json", + "referenceNumber": 209, + "name": "Sax Public Domain Notice 2.0", + "licenseId": "SAX-PD-2.0", + "seeAlso": [ + "http://www.saxproject.org/copying.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Saxpath.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Saxpath.json", + "referenceNumber": 67, + "name": "Saxpath License", + "licenseId": "Saxpath", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Saxpath_License" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SCEA.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SCEA.json", + "referenceNumber": 617, + "name": "SCEA Shared Source License", + "licenseId": "SCEA", + "seeAlso": [ + "http://research.scea.com/scea_shared_source_license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SchemeReport.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SchemeReport.json", + "referenceNumber": 472, + "name": "Scheme Language Report License", + "licenseId": "SchemeReport", + "seeAlso": [], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Sendmail.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Sendmail.json", + "referenceNumber": 135, + "name": "Sendmail License", + "licenseId": "Sendmail", + "seeAlso": [ + "http://www.sendmail.com/pdfs/open_source/sendmail_license.pdf", + "https://web.archive.org/web/20160322142305/https://www.sendmail.com/pdfs/open_source/sendmail_license.pdf" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Sendmail-8.23.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Sendmail-8.23.json", + "referenceNumber": 226, + "name": "Sendmail License 8.23", + "licenseId": "Sendmail-8.23", + "seeAlso": [ + "https://www.proofpoint.com/sites/default/files/sendmail-license.pdf", + "https://web.archive.org/web/20181003101040/https://www.proofpoint.com/sites/default/files/sendmail-license.pdf" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SGI-B-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SGI-B-1.0.json", + "referenceNumber": 631, + "name": "SGI Free Software License B v1.0", + "licenseId": "SGI-B-1.0", + "seeAlso": [ + "http://oss.sgi.com/projects/FreeB/SGIFreeSWLicB.1.0.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SGI-B-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SGI-B-1.1.json", + "referenceNumber": 48, + "name": "SGI Free Software License B v1.1", + "licenseId": "SGI-B-1.1", + "seeAlso": [ + "http://oss.sgi.com/projects/FreeB/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SGI-B-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SGI-B-2.0.json", + "referenceNumber": 193, + "name": "SGI Free Software License B v2.0", + "licenseId": "SGI-B-2.0", + "seeAlso": [ + "http://oss.sgi.com/projects/FreeB/SGIFreeSWLicB.2.0.pdf" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/SGI-OpenGL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SGI-OpenGL.json", + "referenceNumber": 565, + "name": "SGI OpenGL License", + "licenseId": "SGI-OpenGL", + "seeAlso": [ + "https://gitlab.freedesktop.org/mesa/glw/-/blob/master/README?ref_type\u003dheads" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SGP4.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SGP4.json", + "referenceNumber": 291, + "name": "SGP4 Permission Notice", + "licenseId": "SGP4", + "seeAlso": [ + "https://celestrak.org/publications/AIAA/2006-6753/faq.php" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SHL-0.5.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SHL-0.5.json", + "referenceNumber": 623, + "name": "Solderpad Hardware License v0.5", + "licenseId": "SHL-0.5", + "seeAlso": [ + "https://solderpad.org/licenses/SHL-0.5/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SHL-0.51.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SHL-0.51.json", + "referenceNumber": 34, + "name": "Solderpad Hardware License, Version 0.51", + "licenseId": "SHL-0.51", + "seeAlso": [ + "https://solderpad.org/licenses/SHL-0.51/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SimPL-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SimPL-2.0.json", + "referenceNumber": 630, + "name": "Simple Public License 2.0", + "licenseId": "SimPL-2.0", + "seeAlso": [ + "https://opensource.org/licenses/SimPL-2.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/SISSL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SISSL.json", + "referenceNumber": 655, + "name": "Sun Industry Standards Source License v1.1", + "licenseId": "SISSL", + "seeAlso": [ + "http://www.openoffice.org/licenses/sissl_license.html", + "https://opensource.org/licenses/SISSL" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/SISSL-1.2.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SISSL-1.2.json", + "referenceNumber": 401, + "name": "Sun Industry Standards Source License v1.2", + "licenseId": "SISSL-1.2", + "seeAlso": [ + "http://gridscheduler.sourceforge.net/Gridengine_SISSL_license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SL.json", + "referenceNumber": 632, + "name": "SL License", + "licenseId": "SL", + "seeAlso": [ + "https://github.com/mtoyoda/sl/blob/master/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Sleepycat.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Sleepycat.json", + "referenceNumber": 283, + "name": "Sleepycat License", + "licenseId": "Sleepycat", + "seeAlso": [ + "https://opensource.org/licenses/Sleepycat" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/SMLNJ.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SMLNJ.json", + "referenceNumber": 413, + "name": "Standard ML of New Jersey License", + "licenseId": "SMLNJ", + "seeAlso": [ + "https://www.smlnj.org/license.html" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/SMPPL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SMPPL.json", + "referenceNumber": 321, + "name": "Secure Messaging Protocol Public License", + "licenseId": "SMPPL", + "seeAlso": [ + "https://github.com/dcblake/SMP/blob/master/Documentation/License.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SNIA.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SNIA.json", + "referenceNumber": 41, + "name": "SNIA Public License 1.1", + "licenseId": "SNIA", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/SNIA_Public_License" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/snprintf.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/snprintf.json", + "referenceNumber": 507, + "name": "snprintf License", + "licenseId": "snprintf", + "seeAlso": [ + "https://github.com/openssh/openssh-portable/blob/master/openbsd-compat/bsd-snprintf.c#L2" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/softSurfer.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/softSurfer.json", + "referenceNumber": 496, + "name": "softSurfer License", + "licenseId": "softSurfer", + "seeAlso": [ + "https://github.com/mm2/Little-CMS/blob/master/src/cmssm.c#L207", + "https://fedoraproject.org/wiki/Licensing/softSurfer" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Soundex.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Soundex.json", + "referenceNumber": 1, + "name": "Soundex License", + "licenseId": "Soundex", + "seeAlso": [ + "https://metacpan.org/release/RJBS/Text-Soundex-3.05/source/Soundex.pm#L3-11" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Spencer-86.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Spencer-86.json", + "referenceNumber": 257, + "name": "Spencer License 86", + "licenseId": "Spencer-86", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Henry_Spencer_Reg-Ex_Library_License" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Spencer-94.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Spencer-94.json", + "referenceNumber": 228, + "name": "Spencer License 94", + "licenseId": "Spencer-94", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Henry_Spencer_Reg-Ex_Library_License", + "https://metacpan.org/release/KNOK/File-MMagic-1.30/source/COPYING#L28" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Spencer-99.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Spencer-99.json", + "referenceNumber": 287, + "name": "Spencer License 99", + "licenseId": "Spencer-99", + "seeAlso": [ + "http://www.opensource.apple.com/source/tcl/tcl-5/tcl/generic/regfronts.c" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SPL-1.0.json", + "referenceNumber": 576, + "name": "Sun Public License v1.0", + "licenseId": "SPL-1.0", + "seeAlso": [ + "https://opensource.org/licenses/SPL-1.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/ssh-keyscan.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ssh-keyscan.json", + "referenceNumber": 78, + "name": "ssh-keyscan License", + "licenseId": "ssh-keyscan", + "seeAlso": [ + "https://github.com/openssh/openssh-portable/blob/master/LICENCE#L82" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SSH-OpenSSH.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SSH-OpenSSH.json", + "referenceNumber": 536, + "name": "SSH OpenSSH license", + "licenseId": "SSH-OpenSSH", + "seeAlso": [ + "https://github.com/openssh/openssh-portable/blob/1b11ea7c58cd5c59838b5fa574cd456d6047b2d4/LICENCE#L10" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SSH-short.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SSH-short.json", + "referenceNumber": 438, + "name": "SSH short notice", + "licenseId": "SSH-short", + "seeAlso": [ + "https://github.com/openssh/openssh-portable/blob/1b11ea7c58cd5c59838b5fa574cd456d6047b2d4/pathnames.h", + "http://web.mit.edu/kolya/.f/root/athena.mit.edu/sipb.mit.edu/project/openssh/OldFiles/src/openssh-2.9.9p2/ssh-add.1", + "https://joinup.ec.europa.eu/svn/lesoll/trunk/italc/lib/src/dsa_key.cpp" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SSLeay-standalone.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SSLeay-standalone.json", + "referenceNumber": 421, + "name": "SSLeay License - standalone", + "licenseId": "SSLeay-standalone", + "seeAlso": [ + "https://www.tq-group.com/filedownloads/files/software-license-conditions/OriginalSSLeay/OriginalSSLeay.pdf" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SSPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SSPL-1.0.json", + "referenceNumber": 295, + "name": "Server Side Public License, v 1", + "licenseId": "SSPL-1.0", + "seeAlso": [ + "https://www.mongodb.com/licensing/server-side-public-license" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/StandardML-NJ.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/StandardML-NJ.json", + "referenceNumber": 201, + "name": "Standard ML of New Jersey License", + "licenseId": "StandardML-NJ", + "seeAlso": [ + "https://www.smlnj.org/license.html" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/SugarCRM-1.1.3.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SugarCRM-1.1.3.json", + "referenceNumber": 11, + "name": "SugarCRM Public License v1.1.3", + "licenseId": "SugarCRM-1.1.3", + "seeAlso": [ + "http://www.sugarcrm.com/crm/SPL" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Sun-PPP.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Sun-PPP.json", + "referenceNumber": 313, + "name": "Sun PPP License", + "licenseId": "Sun-PPP", + "seeAlso": [ + "https://github.com/ppp-project/ppp/blob/master/pppd/eap.c#L7-L16" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Sun-PPP-2000.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Sun-PPP-2000.json", + "referenceNumber": 489, + "name": "Sun PPP License (2000)", + "licenseId": "Sun-PPP-2000", + "seeAlso": [ + "https://github.com/ppp-project/ppp/blob/master/modules/ppp_ahdlc.c#L7-L19" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SunPro.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SunPro.json", + "referenceNumber": 440, + "name": "SunPro License", + "licenseId": "SunPro", + "seeAlso": [ + "https://github.com/freebsd/freebsd-src/blob/main/lib/msun/src/e_acosh.c", + "https://github.com/freebsd/freebsd-src/blob/main/lib/msun/src/e_lgammal.c" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/SWL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/SWL.json", + "referenceNumber": 331, + "name": "Scheme Widget Library (SWL) Software License Agreement", + "licenseId": "SWL", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/SWL" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/swrule.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/swrule.json", + "referenceNumber": 206, + "name": "swrule License", + "licenseId": "swrule", + "seeAlso": [ + "https://ctan.math.utah.edu/ctan/tex-archive/macros/generic/misc/swrule.sty" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Symlinks.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Symlinks.json", + "referenceNumber": 136, + "name": "Symlinks License", + "licenseId": "Symlinks", + "seeAlso": [ + "https://www.mail-archive.com/debian-bugs-rc@lists.debian.org/msg11494.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/TAPR-OHL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/TAPR-OHL-1.0.json", + "referenceNumber": 317, + "name": "TAPR Open Hardware License v1.0", + "licenseId": "TAPR-OHL-1.0", + "seeAlso": [ + "https://www.tapr.org/OHL" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/TCL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/TCL.json", + "referenceNumber": 644, + "name": "TCL/TK License", + "licenseId": "TCL", + "seeAlso": [ + "http://www.tcl.tk/software/tcltk/license.html", + "https://fedoraproject.org/wiki/Licensing/TCL" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/TCP-wrappers.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/TCP-wrappers.json", + "referenceNumber": 245, + "name": "TCP Wrappers License", + "licenseId": "TCP-wrappers", + "seeAlso": [ + "http://rc.quest.com/topics/openssh/license.php#tcpwrappers" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/TermReadKey.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/TermReadKey.json", + "referenceNumber": 37, + "name": "TermReadKey License", + "licenseId": "TermReadKey", + "seeAlso": [ + "https://github.com/jonathanstowe/TermReadKey/blob/master/README#L9-L10" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/TGPPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/TGPPL-1.0.json", + "referenceNumber": 112, + "name": "Transitive Grace Period Public Licence 1.0", + "licenseId": "TGPPL-1.0", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/TGPPL", + "https://tahoe-lafs.org/trac/tahoe-lafs/browser/trunk/COPYING.TGPPL.rst" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/threeparttable.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/threeparttable.json", + "referenceNumber": 319, + "name": "threeparttable License", + "licenseId": "threeparttable", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Threeparttable" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/TMate.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/TMate.json", + "referenceNumber": 509, + "name": "TMate Open Source License", + "licenseId": "TMate", + "seeAlso": [ + "http://svnkit.com/license.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/TORQUE-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/TORQUE-1.1.json", + "referenceNumber": 105, + "name": "TORQUE v2.5+ Software License v1.1", + "licenseId": "TORQUE-1.1", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/TORQUEv1.1" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/TOSL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/TOSL.json", + "referenceNumber": 107, + "name": "Trusster Open Source License", + "licenseId": "TOSL", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/TOSL" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/TPDL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/TPDL.json", + "referenceNumber": 124, + "name": "Time::ParseDate License", + "licenseId": "TPDL", + "seeAlso": [ + "https://metacpan.org/pod/Time::ParseDate#LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/TPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/TPL-1.0.json", + "referenceNumber": 490, + "name": "THOR Public License 1.0", + "licenseId": "TPL-1.0", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing:ThorPublicLicense" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/TTWL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/TTWL.json", + "referenceNumber": 35, + "name": "Text-Tabs+Wrap License", + "licenseId": "TTWL", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/TTWL", + "https://github.com/ap/Text-Tabs/blob/master/lib.modern/Text/Tabs.pm#L148" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/TTYP0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/TTYP0.json", + "referenceNumber": 542, + "name": "TTYP0 License", + "licenseId": "TTYP0", + "seeAlso": [ + "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/TU-Berlin-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/TU-Berlin-1.0.json", + "referenceNumber": 372, + "name": "Technische Universitaet Berlin License 1.0", + "licenseId": "TU-Berlin-1.0", + "seeAlso": [ + "https://github.com/swh/ladspa/blob/7bf6f3799fdba70fda297c2d8fd9f526803d9680/gsm/COPYRIGHT" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/TU-Berlin-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/TU-Berlin-2.0.json", + "referenceNumber": 246, + "name": "Technische Universitaet Berlin License 2.0", + "licenseId": "TU-Berlin-2.0", + "seeAlso": [ + "https://github.com/CorsixTH/deps/blob/fd339a9f526d1d9c9f01ccf39e438a015da50035/licences/libgsm.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Ubuntu-font-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Ubuntu-font-1.0.json", + "referenceNumber": 191, + "name": "Ubuntu Font Licence v1.0", + "licenseId": "Ubuntu-font-1.0", + "seeAlso": [ + "https://ubuntu.com/legal/font-licence", + "https://assets.ubuntu.com/v1/81e5605d-ubuntu-font-licence-1.0.txt" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/UCAR.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/UCAR.json", + "referenceNumber": 452, + "name": "UCAR License", + "licenseId": "UCAR", + "seeAlso": [ + "https://github.com/Unidata/UDUNITS-2/blob/master/COPYRIGHT" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/UCL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/UCL-1.0.json", + "referenceNumber": 550, + "name": "Upstream Compatibility License v1.0", + "licenseId": "UCL-1.0", + "seeAlso": [ + "https://opensource.org/licenses/UCL-1.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/ulem.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ulem.json", + "referenceNumber": 399, + "name": "ulem License", + "licenseId": "ulem", + "seeAlso": [ + "https://mirrors.ctan.org/macros/latex/contrib/ulem/README" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/UMich-Merit.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/UMich-Merit.json", + "referenceNumber": 581, + "name": "Michigan/Merit Networks License", + "licenseId": "UMich-Merit", + "seeAlso": [ + "https://github.com/radcli/radcli/blob/master/COPYRIGHT#L64" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Unicode-3.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Unicode-3.0.json", + "referenceNumber": 262, + "name": "Unicode License v3", + "licenseId": "Unicode-3.0", + "seeAlso": [ + "https://www.unicode.org/license.txt" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/Unicode-DFS-2015.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Unicode-DFS-2015.json", + "referenceNumber": 328, + "name": "Unicode License Agreement - Data Files and Software (2015)", + "licenseId": "Unicode-DFS-2015", + "seeAlso": [ + "https://web.archive.org/web/20151224134844/http://unicode.org/copyright.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Unicode-DFS-2016.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Unicode-DFS-2016.json", + "referenceNumber": 484, + "name": "Unicode License Agreement - Data Files and Software (2016)", + "licenseId": "Unicode-DFS-2016", + "seeAlso": [ + "https://www.unicode.org/license.txt", + "http://web.archive.org/web/20160823201924/http://www.unicode.org/copyright.html#License", + "http://www.unicode.org/copyright.html" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/Unicode-TOU.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Unicode-TOU.json", + "referenceNumber": 628, + "name": "Unicode Terms of Use", + "licenseId": "Unicode-TOU", + "seeAlso": [ + "http://web.archive.org/web/20140704074106/http://www.unicode.org/copyright.html", + "http://www.unicode.org/copyright.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/UnixCrypt.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/UnixCrypt.json", + "referenceNumber": 95, + "name": "UnixCrypt License", + "licenseId": "UnixCrypt", + "seeAlso": [ + "https://foss.heptapod.net/python-libs/passlib/-/blob/branch/stable/LICENSE#L70", + "https://opensource.apple.com/source/JBoss/JBoss-737/jboss-all/jetty/src/main/org/mortbay/util/UnixCrypt.java.auto.html", + "https://archive.eclipse.org/jetty/8.0.1.v20110908/xref/org/eclipse/jetty/http/security/UnixCrypt.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Unlicense.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Unlicense.json", + "referenceNumber": 218, + "name": "The Unlicense", + "licenseId": "Unlicense", + "seeAlso": [ + "https://unlicense.org/" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/UPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/UPL-1.0.json", + "referenceNumber": 5, + "name": "Universal Permissive License v1.0", + "licenseId": "UPL-1.0", + "seeAlso": [ + "https://opensource.org/licenses/UPL" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/URT-RLE.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/URT-RLE.json", + "referenceNumber": 165, + "name": "Utah Raster Toolkit Run Length Encoded License", + "licenseId": "URT-RLE", + "seeAlso": [ + "https://sourceforge.net/p/netpbm/code/HEAD/tree/super_stable/converter/other/pnmtorle.c", + "https://sourceforge.net/p/netpbm/code/HEAD/tree/super_stable/converter/other/rletopnm.c" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Vim.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Vim.json", + "referenceNumber": 549, + "name": "Vim License", + "licenseId": "Vim", + "seeAlso": [ + "http://vimdoc.sourceforge.net/htmldoc/uganda.html" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/VOSTROM.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/VOSTROM.json", + "referenceNumber": 544, + "name": "VOSTROM Public License for Open Source", + "licenseId": "VOSTROM", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/VOSTROM" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/VSL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/VSL-1.0.json", + "referenceNumber": 109, + "name": "Vovida Software License v1.0", + "licenseId": "VSL-1.0", + "seeAlso": [ + "https://opensource.org/licenses/VSL-1.0" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/W3C.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/W3C.json", + "referenceNumber": 28, + "name": "W3C Software Notice and License (2002-12-31)", + "licenseId": "W3C", + "seeAlso": [ + "http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231.html", + "https://opensource.org/licenses/W3C" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/W3C-19980720.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/W3C-19980720.json", + "referenceNumber": 629, + "name": "W3C Software Notice and License (1998-07-20)", + "licenseId": "W3C-19980720", + "seeAlso": [ + "http://www.w3.org/Consortium/Legal/copyright-software-19980720.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/W3C-20150513.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/W3C-20150513.json", + "referenceNumber": 315, + "name": "W3C Software Notice and Document License (2015-05-13)", + "licenseId": "W3C-20150513", + "seeAlso": [ + "https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document", + "https://www.w3.org/copyright/software-license-2015/", + "https://www.w3.org/copyright/software-license-2023/" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/w3m.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/w3m.json", + "referenceNumber": 379, + "name": "w3m License", + "licenseId": "w3m", + "seeAlso": [ + "https://github.com/tats/w3m/blob/master/COPYING" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Watcom-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Watcom-1.0.json", + "referenceNumber": 612, + "name": "Sybase Open Watcom Public License 1.0", + "licenseId": "Watcom-1.0", + "seeAlso": [ + "https://opensource.org/licenses/Watcom-1.0" + ], + "isOsiApproved": true, + "isFsfLibre": false + }, + { + "reference": "https://spdx.org/licenses/Widget-Workshop.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Widget-Workshop.json", + "referenceNumber": 256, + "name": "Widget Workshop License", + "licenseId": "Widget-Workshop", + "seeAlso": [ + "https://github.com/novnc/noVNC/blob/master/core/crypto/des.js#L24" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Wsuipa.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Wsuipa.json", + "referenceNumber": 199, + "name": "Wsuipa License", + "licenseId": "Wsuipa", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Wsuipa" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/WTFPL.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/WTFPL.json", + "referenceNumber": 173, + "name": "Do What The F*ck You Want To Public License", + "licenseId": "WTFPL", + "seeAlso": [ + "http://www.wtfpl.net/about/", + "http://sam.zoy.org/wtfpl/COPYING" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/wxWindows.html", + "isDeprecatedLicenseId": true, + "detailsUrl": "https://spdx.org/licenses/wxWindows.json", + "referenceNumber": 350, + "name": "wxWindows Library License", + "licenseId": "wxWindows", + "seeAlso": [ + "https://opensource.org/licenses/WXwindows" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/X11.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/X11.json", + "referenceNumber": 274, + "name": "X11 License", + "licenseId": "X11", + "seeAlso": [ + "http://www.xfree86.org/3.3.6/COPYRIGHT2.html#3" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/X11-distribute-modifications-variant.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/X11-distribute-modifications-variant.json", + "referenceNumber": 286, + "name": "X11 License Distribution Modification Variant", + "licenseId": "X11-distribute-modifications-variant", + "seeAlso": [ + "https://github.com/mirror/ncurses/blob/master/COPYING" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/X11-swapped.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/X11-swapped.json", + "referenceNumber": 7, + "name": "X11 swapped final paragraphs", + "licenseId": "X11-swapped", + "seeAlso": [ + "https://github.com/fedeinthemix/chez-srfi/blob/master/srfi/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Xdebug-1.03.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Xdebug-1.03.json", + "referenceNumber": 471, + "name": "Xdebug License v 1.03", + "licenseId": "Xdebug-1.03", + "seeAlso": [ + "https://github.com/xdebug/xdebug/blob/master/LICENSE" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Xerox.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Xerox.json", + "referenceNumber": 417, + "name": "Xerox License", + "licenseId": "Xerox", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Xerox" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Xfig.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Xfig.json", + "referenceNumber": 63, + "name": "Xfig License", + "licenseId": "Xfig", + "seeAlso": [ + "https://github.com/Distrotech/transfig/blob/master/transfig/transfig.c", + "https://fedoraproject.org/wiki/Licensing:MIT#Xfig_Variant", + "https://sourceforge.net/p/mcj/xfig/ci/master/tree/src/Makefile.am" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/XFree86-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/XFree86-1.1.json", + "referenceNumber": 311, + "name": "XFree86 License 1.1", + "licenseId": "XFree86-1.1", + "seeAlso": [ + "http://www.xfree86.org/current/LICENSE4.html" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/xinetd.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/xinetd.json", + "referenceNumber": 406, + "name": "xinetd License", + "licenseId": "xinetd", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Xinetd_License" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/xkeyboard-config-Zinoviev.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/xkeyboard-config-Zinoviev.json", + "referenceNumber": 55, + "name": "xkeyboard-config Zinoviev License", + "licenseId": "xkeyboard-config-Zinoviev", + "seeAlso": [ + "https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/blob/master/COPYING?ref_type\u003dheads#L178" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/xlock.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/xlock.json", + "referenceNumber": 140, + "name": "xlock License", + "licenseId": "xlock", + "seeAlso": [ + "https://fossies.org/linux/tiff/contrib/ras/ras2tif.c" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Xnet.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Xnet.json", + "referenceNumber": 639, + "name": "X.Net License", + "licenseId": "Xnet", + "seeAlso": [ + "https://opensource.org/licenses/Xnet" + ], + "isOsiApproved": true + }, + { + "reference": "https://spdx.org/licenses/xpp.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/xpp.json", + "referenceNumber": 243, + "name": "XPP License", + "licenseId": "xpp", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/xpp" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/XSkat.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/XSkat.json", + "referenceNumber": 535, + "name": "XSkat License", + "licenseId": "XSkat", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/XSkat_License" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/xzoom.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/xzoom.json", + "referenceNumber": 339, + "name": "xzoom License", + "licenseId": "xzoom", + "seeAlso": [ + "https://metadata.ftp-master.debian.org/changelogs//main/x/xzoom/xzoom_0.3-27_copyright" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/YPL-1.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/YPL-1.0.json", + "referenceNumber": 506, + "name": "Yahoo! Public License v1.0", + "licenseId": "YPL-1.0", + "seeAlso": [ + "http://www.zimbra.com/license/yahoo_public_license_1.0.html" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/YPL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/YPL-1.1.json", + "referenceNumber": 538, + "name": "Yahoo! Public License v1.1", + "licenseId": "YPL-1.1", + "seeAlso": [ + "http://www.zimbra.com/license/yahoo_public_license_1.1.html" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Zed.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Zed.json", + "referenceNumber": 500, + "name": "Zed License", + "licenseId": "Zed", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/Zed" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Zeeff.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Zeeff.json", + "referenceNumber": 382, + "name": "Zeeff License", + "licenseId": "Zeeff", + "seeAlso": [ + "ftp://ftp.tin.org/pub/news/utils/newsx/newsx-1.6.tar.gz" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Zend-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Zend-2.0.json", + "referenceNumber": 51, + "name": "Zend License v2.0", + "licenseId": "Zend-2.0", + "seeAlso": [ + "https://web.archive.org/web/20130517195954/http://www.zend.com/license/2_00.txt" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Zimbra-1.3.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Zimbra-1.3.json", + "referenceNumber": 555, + "name": "Zimbra Public License v1.3", + "licenseId": "Zimbra-1.3", + "seeAlso": [ + "http://web.archive.org/web/20100302225219/http://www.zimbra.com/license/zimbra-public-license-1-3.html" + ], + "isOsiApproved": false, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/Zimbra-1.4.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Zimbra-1.4.json", + "referenceNumber": 227, + "name": "Zimbra Public License v1.4", + "licenseId": "Zimbra-1.4", + "seeAlso": [ + "http://www.zimbra.com/legal/zimbra-public-license-1-4" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/Zlib.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/Zlib.json", + "referenceNumber": 74, + "name": "zlib License", + "licenseId": "Zlib", + "seeAlso": [ + "http://www.zlib.net/zlib_license.html", + "https://opensource.org/licenses/Zlib" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/zlib-acknowledgement.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/zlib-acknowledgement.json", + "referenceNumber": 371, + "name": "zlib/libpng License with Acknowledgement", + "licenseId": "zlib-acknowledgement", + "seeAlso": [ + "https://fedoraproject.org/wiki/Licensing/ZlibWithAcknowledgement" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/ZPL-1.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ZPL-1.1.json", + "referenceNumber": 598, + "name": "Zope Public License 1.1", + "licenseId": "ZPL-1.1", + "seeAlso": [ + "http://old.zope.org/Resources/License/ZPL-1.1" + ], + "isOsiApproved": false + }, + { + "reference": "https://spdx.org/licenses/ZPL-2.0.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ZPL-2.0.json", + "referenceNumber": 539, + "name": "Zope Public License 2.0", + "licenseId": "ZPL-2.0", + "seeAlso": [ + "http://old.zope.org/Resources/License/ZPL-2.0", + "https://opensource.org/licenses/ZPL-2.0" + ], + "isOsiApproved": true, + "isFsfLibre": true + }, + { + "reference": "https://spdx.org/licenses/ZPL-2.1.html", + "isDeprecatedLicenseId": false, + "detailsUrl": "https://spdx.org/licenses/ZPL-2.1.json", + "referenceNumber": 638, + "name": "Zope Public License 2.1", + "licenseId": "ZPL-2.1", + "seeAlso": [ + "http://old.zope.org/Resources/ZPL/" + ], + "isOsiApproved": true, + "isFsfLibre": true + } + ], + "releaseDate": "2024-08-19" +} diff --git a/templates/SPDX.LicenseExceptionId.template.hs b/templates/SPDX.LicenseExceptionId.template.hs index c2fcd1462b9..aea2fedb586 100644 --- a/templates/SPDX.LicenseExceptionId.template.hs +++ b/templates/SPDX.LicenseExceptionId.template.hs @@ -29,7 +29,7 @@ import qualified Text.PrettyPrint as Disp -- LicenseExceptionId ------------------------------------------------------------------------------- --- | SPDX License Exceptions identifiers list v3.23 +-- | SPDX License Exceptions identifiers list v3.25 data LicenseExceptionId {{ licenseIds }} deriving (Eq, Ord, Enum, Bounded, Show, Read, Typeable, Data, Generic) @@ -101,6 +101,9 @@ licenseExceptionIdList LicenseListVersion_3_16 = licenseExceptionIdList LicenseListVersion_3_23 = {{licenseList_perv.v_3_23}} ++ bulkOfLicenses +licenseExceptionIdList LicenseListVersion_3_25 = +{{licenseList_perv.v_3_25}} + ++ bulkOfLicenses -- | Create a 'LicenseExceptionId' from a 'String'. mkLicenseExceptionId :: LicenseListVersion -> String -> Maybe LicenseExceptionId @@ -111,6 +114,7 @@ mkLicenseExceptionId LicenseListVersion_3_9 s = Map.lookup s stringLookup_3_9 mkLicenseExceptionId LicenseListVersion_3_10 s = Map.lookup s stringLookup_3_10 mkLicenseExceptionId LicenseListVersion_3_16 s = Map.lookup s stringLookup_3_16 mkLicenseExceptionId LicenseListVersion_3_23 s = Map.lookup s stringLookup_3_23 +mkLicenseExceptionId LicenseListVersion_3_25 s = Map.lookup s stringLookup_3_25 stringLookup_3_0 :: Map String LicenseExceptionId stringLookup_3_0 = Map.fromList $ map (\i -> (licenseExceptionId i, i)) $ @@ -140,6 +144,10 @@ stringLookup_3_23 :: Map String LicenseExceptionId stringLookup_3_23 = Map.fromList $ map (\i -> (licenseExceptionId i, i)) $ licenseExceptionIdList LicenseListVersion_3_23 +stringLookup_3_25 :: Map String LicenseExceptionId +stringLookup_3_25 = Map.fromList $ map (\i -> (licenseExceptionId i, i)) $ + licenseExceptionIdList LicenseListVersion_3_25 + -- | License exceptions in all SPDX License lists bulkOfLicenses :: [LicenseExceptionId] bulkOfLicenses = diff --git a/templates/SPDX.LicenseId.template.hs b/templates/SPDX.LicenseId.template.hs index 6ee2bf6ede3..58e04801398 100644 --- a/templates/SPDX.LicenseId.template.hs +++ b/templates/SPDX.LicenseId.template.hs @@ -32,7 +32,7 @@ import qualified Text.PrettyPrint as Disp -- LicenseId ------------------------------------------------------------------------------- --- | SPDX License identifiers list v3.23 +-- | SPDX License identifiers list v3.25 data LicenseId {{ licenseIds }} deriving (Eq, Ord, Enum, Bounded, Show, Read, Typeable, Data) @@ -178,6 +178,9 @@ licenseIdList LicenseListVersion_3_16 = licenseIdList LicenseListVersion_3_23 = {{licenseList_perv.v_3_23}} ++ bulkOfLicenses +licenseIdList LicenseListVersion_3_25 = +{{licenseList_perv.v_3_25}} + ++ bulkOfLicenses -- | Create a 'LicenseId' from a 'String'. mkLicenseId :: LicenseListVersion -> String -> Maybe LicenseId @@ -188,6 +191,7 @@ mkLicenseId LicenseListVersion_3_9 s = Map.lookup s stringLookup_3_9 mkLicenseId LicenseListVersion_3_10 s = Map.lookup s stringLookup_3_10 mkLicenseId LicenseListVersion_3_16 s = Map.lookup s stringLookup_3_16 mkLicenseId LicenseListVersion_3_23 s = Map.lookup s stringLookup_3_23 +mkLicenseId LicenseListVersion_3_25 s = Map.lookup s stringLookup_3_25 stringLookup_3_0 :: Map String LicenseId stringLookup_3_0 = Map.fromList $ map (\i -> (licenseId i, i)) $ @@ -217,6 +221,10 @@ stringLookup_3_23 :: Map String LicenseId stringLookup_3_23 = Map.fromList $ map (\i -> (licenseId i, i)) $ licenseIdList LicenseListVersion_3_23 +stringLookup_3_25 :: Map String LicenseId +stringLookup_3_25 = Map.fromList $ map (\i -> (licenseId i, i)) $ + licenseIdList LicenseListVersion_3_25 + -- | Licenses in all SPDX License lists bulkOfLicenses :: [LicenseId] bulkOfLicenses = From 9c75d3705bdaacad1ba484fd4abc2fa73acda3a8 Mon Sep 17 00:00:00 2001 From: Artem Pelenitsyn Date: Mon, 9 Sep 2024 23:34:29 -0400 Subject: [PATCH 134/207] Add changelogs for 3.14 Forward port of #10336, #10338, and #10358 --- Cabal-syntax/ChangeLog.md | 2 +- Cabal/ChangeLog.md | 3 + cabal-install-solver/ChangeLog.md | 2 +- cabal-install/changelog | 3 + changelog.d/configure-messages | 13 -- changelog.d/issue-10046 | 4 - changelog.d/issue-10051 | 4 - changelog.d/issue-10166 | 20 --- changelog.d/issue-4816 | 23 ---- changelog.d/issue-4816-2 | 26 ---- changelog.d/issue-8817 | 17 --- changelog.d/issue-9702 | 39 ------ changelog.d/pr-10089 | 12 -- changelog.d/pr-10103 | 14 -- changelog.d/pr-10115 | 10 -- changelog.d/pr-10122 | 10 -- changelog.d/pr-10128 | 12 -- changelog.d/pr-10217 | 10 -- changelog.d/pr-10240 | 13 -- changelog.d/pr-10245 | 8 -- changelog.d/pr-10261 | 12 -- changelog.d/pr-8717 | 25 ---- changelog.d/pr-9177 | 31 ----- changelog.d/pr-9551 | 19 --- changelog.d/pr-9740 | 9 -- changelog.d/pr-9821 | 21 --- changelog.d/pr-9969 | 18 --- release-notes/Cabal-3.14.0.0.md | 163 ++++++++++++++++++++++++ release-notes/cabal-install-3.14.0.0.md | 141 ++++++++++++++++++++ 29 files changed, 312 insertions(+), 372 deletions(-) delete mode 100644 changelog.d/configure-messages delete mode 100644 changelog.d/issue-10046 delete mode 100644 changelog.d/issue-10051 delete mode 100644 changelog.d/issue-10166 delete mode 100644 changelog.d/issue-4816 delete mode 100644 changelog.d/issue-4816-2 delete mode 100644 changelog.d/issue-8817 delete mode 100644 changelog.d/issue-9702 delete mode 100644 changelog.d/pr-10089 delete mode 100644 changelog.d/pr-10103 delete mode 100644 changelog.d/pr-10115 delete mode 100644 changelog.d/pr-10122 delete mode 100644 changelog.d/pr-10128 delete mode 100644 changelog.d/pr-10217 delete mode 100644 changelog.d/pr-10240 delete mode 100644 changelog.d/pr-10245 delete mode 100644 changelog.d/pr-10261 delete mode 100644 changelog.d/pr-8717 delete mode 100644 changelog.d/pr-9177 delete mode 100644 changelog.d/pr-9551 delete mode 100644 changelog.d/pr-9740 delete mode 100644 changelog.d/pr-9821 delete mode 100644 changelog.d/pr-9969 create mode 100644 release-notes/Cabal-3.14.0.0.md create mode 100644 release-notes/cabal-install-3.14.0.0.md diff --git a/Cabal-syntax/ChangeLog.md b/Cabal-syntax/ChangeLog.md index 73c417220df..cbba98a3cc4 100644 --- a/Cabal-syntax/ChangeLog.md +++ b/Cabal-syntax/ChangeLog.md @@ -1 +1 @@ -Please see https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.12.1.0.md +Please see https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.14.0.0.md diff --git a/Cabal/ChangeLog.md b/Cabal/ChangeLog.md index 681bbc5a84a..ea3b88e1082 100644 --- a/Cabal/ChangeLog.md +++ b/Cabal/ChangeLog.md @@ -1,3 +1,6 @@ +# 3.14.0.0 [Hécate](mailto:hecate+github@glitchbra.in) September 2024 +* See https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.14.0.0.md + # 3.12.1.0 [Artem Pelenitsyn](mailto:a.pelenitsyn@gmail.com) June 2024 * See https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.12.1.0.md diff --git a/cabal-install-solver/ChangeLog.md b/cabal-install-solver/ChangeLog.md index 3cd7794fe29..978ac0f1b07 100644 --- a/cabal-install-solver/ChangeLog.md +++ b/cabal-install-solver/ChangeLog.md @@ -1 +1 @@ -Please see https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.12.1.0.md +Please see https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.14.0.0.md diff --git a/cabal-install/changelog b/cabal-install/changelog index 281329c7fe7..67711276c8f 100644 --- a/cabal-install/changelog +++ b/cabal-install/changelog @@ -1,5 +1,8 @@ -*-change-log-*- +3.14.0.0 Hécate September 2024 + * See https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.14.0.0.md + 3.12.1.0 Artem Pelenitsyn June 2024 * See https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.12.1.0.md diff --git a/changelog.d/configure-messages b/changelog.d/configure-messages deleted file mode 100644 index f0fab79e734..00000000000 --- a/changelog.d/configure-messages +++ /dev/null @@ -1,13 +0,0 @@ -synopsis: clarify Cabal "configure" messages -packages: Cabal -prs: #9476 - -synopsis: { - - Cabal can issue a number of error messages referencing "Setup configure", - but it simply references "configure" which could mean any of three - things (Setup configure, the package's "configure" script, or "cabal - configure"). This has recently caught out even Cabal devs. Clarify these - messages. - -} diff --git a/changelog.d/issue-10046 b/changelog.d/issue-10046 deleted file mode 100644 index 668d077271e..00000000000 --- a/changelog.d/issue-10046 +++ /dev/null @@ -1,4 +0,0 @@ -synopsis: Bug fix - Don't pass --coverage-for for non-dependency libs of testsuite -packages: cabal-install -issues: #10046 -prs: #10250 diff --git a/changelog.d/issue-10051 b/changelog.d/issue-10051 deleted file mode 100644 index b582fc2b619..00000000000 --- a/changelog.d/issue-10051 +++ /dev/null @@ -1,4 +0,0 @@ -synopsis: Added `--all` and `--haddock-all` switches to `haddock-project` subcommand -packages: cabal-install -issues: #10051 -prs: #2272 diff --git a/changelog.d/issue-10166 b/changelog.d/issue-10166 deleted file mode 100644 index 02d313adca9..00000000000 --- a/changelog.d/issue-10166 +++ /dev/null @@ -1,20 +0,0 @@ -synopsis: Include package version when passing `--promised-dependency` flag -packages: Cabal Cabal-syntax -prs: #10248 -issues: #10166 - -description: { - -The --promised dependency flag now expects an argument in format - -``` -NAME-VER[:COMPONENT_NAME]=CID` -``` - -rather than - -``` -NAME[:COMPONENT_NAME]=CID -``` - -} diff --git a/changelog.d/issue-4816 b/changelog.d/issue-4816 deleted file mode 100644 index e0ac7700b7e..00000000000 --- a/changelog.d/issue-4816 +++ /dev/null @@ -1,23 +0,0 @@ -synopsis: Add support for building profiled dynamic way -packages: Cabal Cabal-syntax cabal-install -prs: #9900 -issues: #4816 - -description: { -Add support for profiled dynamic way - -New options for cabal.project and ./Setup interface: - -* `profiling-shared`: Enable building profiling dynamic way -* Passing `--enable-profiling` and `--enable-executable-dynamic` builds - profiled dynamic executables. - -Support for using `profiling-shared` is guarded behind a constraint -which ensures you are using `Cabal >= 3.13`. - -In the cabal file: - -* `ghc-prof-shared-options`, for passing options when building in - profiling dynamic way - -} diff --git a/changelog.d/issue-4816-2 b/changelog.d/issue-4816-2 deleted file mode 100644 index 96307c3f83e..00000000000 --- a/changelog.d/issue-4816-2 +++ /dev/null @@ -1,26 +0,0 @@ -synopsis: Fix interaction of `--*-shared` and `--*-executable-dynamic` options. -packages: cabal-install -prs: #9900 -issues: #10050 - -description: { - -If you explicitly request `--disable-shared` it should disable the building of -a shared library and override any automatic ways this option is turned on. - -Passing `--enable-executable-dynamic` turns on `--enable-shared` if the option is -not specified explicitly. - -Before this patch, writing `--disable-shared` on its own would not disable the building of shared libraries. Writing `--disable-shared` and `--disable-executable-dynamic` would disable shared library -creation (despite `--disable-executable-dynamic` being the default). - -Now: - -* If you specify `--enable-shared` then shared objects are built. -* If you specify `--disabled-shared` then shared objects are not built. -* If you don't explicitly specify whether you want to build shared libraries then - * `--enable-executable-dynamic` will automatically turn on building shared libraries - * `--enable-executable-dynamic --enable-profiling` will automatically turn on building - shared profiling libraries (if supported by your compiler). - -} diff --git a/changelog.d/issue-8817 b/changelog.d/issue-8817 deleted file mode 100644 index 0743671fa0d..00000000000 --- a/changelog.d/issue-8817 +++ /dev/null @@ -1,17 +0,0 @@ -synopsis: Neutral field to add files to sdist -packages: Cabal Cabal-syntax -prs: #10107 -issues: #8817 -significance: significant - -description: { - -Adds the `extra-files` field to the cabal file specification. This is like -the other `extra-*` fields in that it is copied with the `sdist` command, -except there are no other semantics. Compare to: - -* `extra-source-files`: Tracked by `cabal build`. - -* `extra-doc-files`: Copied by Haddock to the html directory. - -} diff --git a/changelog.d/issue-9702 b/changelog.d/issue-9702 deleted file mode 100644 index 7df998b8d8d..00000000000 --- a/changelog.d/issue-9702 +++ /dev/null @@ -1,39 +0,0 @@ -synopsis: Working directory support for Cabal -packages: Cabal-syntax Cabal cabal-install -prs: #9718 -issues: #9702 - -description: { - -The Cabal library is now able to handle a passed-in working directory, instead -of always relying on the current working directory of the parent process. - -In order to achieve this, the `SymbolicPath` abstraction was fleshed out, and -all fields of `PackageDescription` that, if relative, should be interpreted -with respect to e.g. the package root, use `SymbolicPath` instead of `FilePath`. - -This means that many library functions in `Cabal` take an extra argument of type -`Maybe (SymbolicPath CWD (Dir "Package))`, which is an optional (relative or -absolute) path to the package root (if relative, relative to the current working -directory). In addition, many functions that used to manipulate `FilePath`s now -manipulate `SymbolicPath`s, require explicit conversion using e.g. `getSymbolicPath`. - -To illustrate with file searching, the `Cabal` library defines: - -```haskell -findFileCwd - :: forall dir1 dir2 file - . Verbosity - -> Maybe (SymbolicPath CWD (Dir dir1)) - -- ^ working directory - -> [SymbolicPath dir1 (Dir dir2)] - -- ^ search directories - -> RelativePath dir2 File - -- ^ filename - -> IO (SymbolicPath dir1 File) -``` - -See Note [Symbolic paths] in `Distribution.Utils.Path` for further information -on the design of this API. -} - diff --git a/changelog.d/pr-10089 b/changelog.d/pr-10089 deleted file mode 100644 index ed322194e21..00000000000 --- a/changelog.d/pr-10089 +++ /dev/null @@ -1,12 +0,0 @@ -synopsis: `curl` transport now supports Basic authentication -packages: cabal-install -prs: #10089 - -description: { - -- The `curl` HTTP transport previously only supported the HTTP Digest - authentication scheme. Basic authentication is now supported - when using HTTPS; Curl will use the scheme offered by the server. - The `wget` transport already supports HTTPS. - -} diff --git a/changelog.d/pr-10103 b/changelog.d/pr-10103 deleted file mode 100644 index 3e68cf38d3c..00000000000 --- a/changelog.d/pr-10103 +++ /dev/null @@ -1,14 +0,0 @@ -synopsis: Enhance error detection for cabal root project files, including broken symlinks - -packages: cabal-install - -prs: #10103 - -issues: #9937 - -description: { - -- Added proper detection and reporting for issues with cabal root project files. Previously, these files were silently ignored if they were broken symlinks. Now, `cabal` will exit -with an error in such case. - -} diff --git a/changelog.d/pr-10115 b/changelog.d/pr-10115 deleted file mode 100644 index ce288c105c1..00000000000 --- a/changelog.d/pr-10115 +++ /dev/null @@ -1,10 +0,0 @@ -synopsis: Let cabal init remember chosen language within current session -packages: cabal-install -prs: #10115 -issues: #10096 - -description: { - -When cabal init asks for a language, the last choice will be used as the new default for the current session. - -} \ No newline at end of file diff --git a/changelog.d/pr-10122 b/changelog.d/pr-10122 deleted file mode 100644 index 7e9fbe10d47..00000000000 --- a/changelog.d/pr-10122 +++ /dev/null @@ -1,10 +0,0 @@ -synopsis: Clarify error message when pkg-config is not found -packages: cabal-install-solver -prs: #10122 - -description: { - -- The error message when pkg-config is not found or querying it fails will no -longer incorrectly claim that the package is missing in the database. - -} diff --git a/changelog.d/pr-10128 b/changelog.d/pr-10128 deleted file mode 100644 index 8c7cc45d204..00000000000 --- a/changelog.d/pr-10128 +++ /dev/null @@ -1,12 +0,0 @@ -synopsis: Add flag ignore-build-tools -packages: Cabal -prs: #10128 - -description: { - -- Adds flag --ignore-build-tools which allows a user to ignore the tool - dependencies declared in build-tool-depends. For general use, this flag - should never be needed, but it may be useful for packagers. - -} - diff --git a/changelog.d/pr-10217 b/changelog.d/pr-10217 deleted file mode 100644 index 8e520bab27e..00000000000 --- a/changelog.d/pr-10217 +++ /dev/null @@ -1,10 +0,0 @@ -synopsis: Do not try to build dynamic executables on Windows -packages: Cabal -prs: #10217 - -description: { - -- Cabal will now exit with a descriptive error message instead of attempting to - build a dynamic executable on Windows. - -} diff --git a/changelog.d/pr-10240 b/changelog.d/pr-10240 deleted file mode 100644 index 9bd05100ab7..00000000000 --- a/changelog.d/pr-10240 +++ /dev/null @@ -1,13 +0,0 @@ -synopsis: Filter out dinitial-unique and dunique-increment from package hash -packages: cabal-install -prs: #10122 - -description: { - -`-dinitial-unique` and `-dunique-increment` are now filtered out when computing the -store hash of a package. - -These options shouldn't affect the output of the package and hence -shouldn't affect the store hash of a package. - -} diff --git a/changelog.d/pr-10245 b/changelog.d/pr-10245 deleted file mode 100644 index 2ed3690720a..00000000000 --- a/changelog.d/pr-10245 +++ /dev/null @@ -1,8 +0,0 @@ -synopsis: Add MultilineStrings extension -packages: Cabal-syntax -prs: #10245 -description: { - -- adds support for the `MultilineStrings` language extension (GHC proposal #637) - -} diff --git a/changelog.d/pr-10261 b/changelog.d/pr-10261 deleted file mode 100644 index adcae60fd88..00000000000 --- a/changelog.d/pr-10261 +++ /dev/null @@ -1,12 +0,0 @@ -synopsis: Warn about git:// protocol -packages: cabal-install -prs: #10261 - -description: { - -`cabal check` will warn about insecure git:// protocol in `source-repository`. - -See [Git Book](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols#_the_cons_4) -for an explanation. - -} diff --git a/changelog.d/pr-8717 b/changelog.d/pr-8717 deleted file mode 100644 index b0ac7e09388..00000000000 --- a/changelog.d/pr-8717 +++ /dev/null @@ -1,25 +0,0 @@ -synopsis: Always pass `ghc-options` to GHC -packages: Cabal -prs: #8717 -issues: - -description: { - -Previously, options set in the package field `ghc-options` would not be passed -to GHC during the link phase for shared objects (where multiple `.o` or -`.dyn_o` files are merged into a single object file). This made it impossible -to use `ghc-options` to use a different linker by setting (for example) -`ghc-options: -optl-fuse-ld=mold -optlm-fuse-ld=mold`; the options would be -dropped in the link phase, falling back to the default linker. - -It was possible to work around this by duplicating the `ghc-options` to -`ghc-shared-options`, which _are_ passed in the shared link phase, but that had -the (undocumented and unfortunate) side-effect of disabling the GHC -`-dynamic-too` flag, effectively doubling compilation times when -`ghc-shared-options` are set. - -Now, `ghc-options` are combined with `ghc-shared-options` (to accurately -reflect the documentation on this feature) and the fact that -`ghc-shared-options` disables `-dynamic-too` is documented. - -} diff --git a/changelog.d/pr-9177 b/changelog.d/pr-9177 deleted file mode 100644 index 6b1eb227350..00000000000 --- a/changelog.d/pr-9177 +++ /dev/null @@ -1,31 +0,0 @@ -synopsis: Enable recompilation avoidance during Haddock generation -packages: cabal-install -prs: #9177 -issues: #9175 - -description: { - -* Haddock no longer writes compilation files by default, so we do not need to - pass tmp dirs for `-hidir`, `-stubdir`, and `-odir` via `--optghc`. Indeed, we - do not *want* to do so, since it results in recompilation for every invocation - of Haddock via Cabal. We now stop this from happening for Haddock versions - 2.28 and greater, since that is when Hi Haddock was introduced. - -* We no longer define the `__HADDOCK_VERSION__` macro when invoking GHC through - Haddock, since doing so essentially guarantees recompilation during - documentation generation. We audited all uses of `__HADDOCK_VERSION__` in - hackage, ensuring there was a reasonable path forward to migrate away from - using `__HADDOCK_VERSION__` for each, while generating the same documentation - as it did before. - If you are a user of `__HADDOCK_VERSION__`, please take a look at the - discussion in https://github.com/haskell/cabal/pull/9177 and reach out to us - if your use case is not covered. - -* Rename the `--haddock-lib` flag to `--haddock-resources-dir` (and - `haddock-lib:` cabal.project field to `haddock-resources-dir:`), and add this - flag to the users guide since it was missing an entry. - -* `documentation: true` or `--enable-documentation` now implies `-haddock` for - GHC. - -} diff --git a/changelog.d/pr-9551 b/changelog.d/pr-9551 deleted file mode 100644 index 5116234a653..00000000000 --- a/changelog.d/pr-9551 +++ /dev/null @@ -1,19 +0,0 @@ -synopsis: Introduce SetupHooks -packages: Cabal -prs: #9551 -description: { - Introduction of a new build type: Hooks. - This build type, intended as replacement to the Custom build type, integrates - better with the rest of the ecosystem (`cabal-install`, Haskell Language Server). - - The motivation and full design of this new build-type are specified in the - Haskell Foundation Tech Proposal - [Replacing the Cabal Custom build-type](https://github.com/haskellfoundation/tech-proposals/pull/60). - - Package authors willing to use this feature should declare `build-type: Hooks` - in their `.cabal` file, declare a custom-setup stanza with a dependency on the - `Cabal-hooks` package, and define a module `SetupHooks` that exports a value - `setupHooks :: SetupHooks`, using the API exported by `Distribution.Simple.SetupHooks` - from the `Cabal-hooks` package. Refer to the Haddock documentation of - `Distribution.Simple.SetupHooks` for example usage. -} diff --git a/changelog.d/pr-9740 b/changelog.d/pr-9740 deleted file mode 100644 index c5a3b9a173e..00000000000 --- a/changelog.d/pr-9740 +++ /dev/null @@ -1,9 +0,0 @@ -synopsis: Add language extension NamedDefaults -packages: Cabal-syntax -prs: #9740 - -description: { - -- adds support for the `NamedDefaults` language extension (GHC proposal #409) - -} diff --git a/changelog.d/pr-9821 b/changelog.d/pr-9821 deleted file mode 100644 index bc3e9dcae50..00000000000 --- a/changelog.d/pr-9821 +++ /dev/null @@ -1,21 +0,0 @@ -synopsis: `haddock-project` support for subcomponents -packages: cabal-install -prs: #9821 -issues: -significance: significant - -description: { - -- `haddock-project` handles sublibraries, test suites and benchmarks. -- `haddock` receives `--package-name` flag whcih allows to set names of - components which are included in the main `index.html` file. -- added `--use-unicode` flag to `haddock` and `haddock-project` commands. -- The directory structure of `./dist-newstyle` has changed. `haddock` - subcommand will install `package:sublib` component in a directory - `package/sublib` under `l/sublib/doc/html/`. This is important for - `haddock-project` command and in the future might will be useful for hackage - support of sublibraries. See - https://github.com/haskell/cabal/pull/9821#discussion_r1548557115. - -} - diff --git a/changelog.d/pr-9969 b/changelog.d/pr-9969 deleted file mode 100644 index 17a60b88e99..00000000000 --- a/changelog.d/pr-9969 +++ /dev/null @@ -1,18 +0,0 @@ -synopsis: Configure build-type in terms of Hooks -packages: Cabal cabal-install -prs: #9969 - -description: { - -The `build-type: Configure` is now implemented in terms of `build-type: Hooks` -rather than in terms of `build-type: Custom`. This moves the `Configure` -build-type away from the `Custom` issues. Eventually, `build-type: Hooks` will -no longer imply packages are built in legacy-fallback mode. Now, when that -happens, `Configure` will also stop implying `legacy-fallback`. - -The observable aspect of this change is `runConfigureScript` now having a -different type, and `autoconfSetupHooks` being exposed `Distribution.Simple`. -The former is motivated by internal implementation details, while the latter -provides the `SetupHooks` value for the `Configure` build type, which can be -consumed by other `Hooks` clients (e.g. eventually HLS). -} diff --git a/release-notes/Cabal-3.14.0.0.md b/release-notes/Cabal-3.14.0.0.md new file mode 100644 index 00000000000..004a462db8f --- /dev/null +++ b/release-notes/Cabal-3.14.0.0.md @@ -0,0 +1,163 @@ +Cabal and Cabal-syntax 3.14.0.0 changelog and release notes +--- + + +### Significant changes + +- Neutral field to add files to sdist [#8817](https://github.com/haskell/cabal/issues/8817) [#10107](https://github.com/haskell/cabal/pull/10107) + + Adds the `extra-files` field to the cabal file specification. This is like + the other `extra-*` fields in that it is copied with the `sdist` command, + except there are no other semantics. Compare to: + + * `extra-source-files`: Tracked by `cabal build`. + + * `extra-doc-files`: Copied by Haddock to the html directory. + +### Other changes + +- Include package version when passing `--promised-dependency` flag [#10166](https://github.com/haskell/cabal/issues/10166) [#10248](https://github.com/haskell/cabal/pull/10248) + + The `--promised-dependency` flag now expects an argument in the format + + ``` + NAME-VER[:COMPONENT_NAME]=CID + ``` + + rather than + + ``` + NAME[:COMPONENT_NAME]=CID + ``` + +- Add support for building profiled dynamic way [#4816](https://github.com/haskell/cabal/issues/4816) [#9900](https://github.com/haskell/cabal/pull/9900) + + Add support for profiled dynamic way + + New options for `cabal.project` and `./Setup` interface: + + * `profiling-shared`: Enable building profiling dynamic way + * Passing `--enable-profiling` and `--enable-executable-dynamic` builds + profiled dynamic executables. + + Support for using `profiling-shared` is guarded behind a constraint + which ensures you are using `Cabal >= 3.13`. + + In the cabal file: + + * `ghc-prof-shared-options`, for passing options when building in + profiling dynamic way + +- Working directory support for `Cabal` [#9702](https://github.com/haskell/cabal/issues/9702) [#9718](https://github.com/haskell/cabal/pull/9718) + + The `Cabal` library is now able to handle a passed-in working directory, instead + of always relying on the current working directory of the parent process. + + In order to achieve this, the `SymbolicPath` abstraction was fleshed out, and + all fields of `PackageDescription` that, if relative, should be interpreted + with respect to e.g. the package root, use `SymbolicPath` instead of `FilePath`. + + This means that many library functions in `Cabal` take an extra argument of type + `Maybe (SymbolicPath CWD (Dir "Package"))`, which is an optional (relative or + absolute) path to the package root (if relative, relative to the current working + directory). In addition, many functions that used to manipulate `FilePath`s now + manipulate `SymbolicPath`s, require explicit conversion using e.g. `getSymbolicPath`. + + To illustrate with file searching, the `Cabal` library defines: + + ```haskell + findFileCwd + :: forall dir1 dir2 file + . Verbosity + -> Maybe (SymbolicPath CWD (Dir dir1)) + + -> [SymbolicPath dir1 (Dir dir2)] + + -> RelativePath dir2 File + + -> IO (SymbolicPath dir1 File) + ``` + + See Note [Symbolic paths] in `Distribution.Utils.Path` for further information + on the design of this API. + +- Add `MultilineStrings` extension (GHC proposal #637) [#10245](https://github.com/haskell/cabal/pull/10245) + +- Add `NamedDefaults` extension (GHC proposal #409) [#9740](https://github.com/haskell/cabal/pull/9740) + +- Add `OrPatterns` extension (GHC proposal #958) [#10339](https://github.com/haskell/cabal/pull/10339) + + +### Other changes + +- Add flag `--ignore-build-tools` [#10128](https://github.com/haskell/cabal/pull/10128) + + - Adds flag `--ignore-build-tools` which allows a user to ignore the tool + dependencies declared in `build-tool-depends`. For general use, this flag + should never be needed, but it may be useful for packagers. + +- Do not try to build dynamic executables on Windows [#10217](https://github.com/haskell/cabal/pull/10217) + + - Cabal will now exit with a descriptive error message instead of attempting to + build a dynamic executable on Windows. + +- Always pass `ghc-options` to GHC [#8717](https://github.com/haskell/cabal/pull/8717) + + Previously, options set in the package field `ghc-options` would not be passed + to GHC during the link phase for shared objects (where multiple `.o` or + `.dyn_o` files are merged into a single object file). This made it impossible + to use `ghc-options` to use a different linker by setting (for example) + `ghc-options: -optl-fuse-ld=mold -optlm-fuse-ld=mold`; the options would be + dropped in the link phase, falling back to the default linker. + + It was possible to work around this by duplicating the `ghc-options` to + `ghc-shared-options`, which _are_ passed in the shared link phase, but that had + the undocumented and unfortunate side-effect of disabling the GHC + `-dynamic-too` flag, effectively doubling compilation times when + `ghc-shared-options` are set. + + Now, `ghc-options` are combined with `ghc-shared-options` (to accurately + reflect the documentation on this feature) and the fact that + `ghc-shared-options` disables `-dynamic-too` is documented. + +- Introduce `SetupHooks` [#9551](https://github.com/haskell/cabal/pull/9551) + + Introduction of a new build type: `Hooks`. + This build type, intended to eventually replace the `Custom` build type, integrates + better with the rest of the ecosystem (`cabal-install`, Haskell Language Server). + + The motivation and full design of this new build-type are specified in the + Haskell Foundation Tech Proposal + [Replacing the Cabal Custom build-type](https://github.com/haskellfoundation/tech-proposals/pull/60). + + Package authors willing to use this feature should declare `cabal-version: 3.14` and `build-type: Hooks` + in their `.cabal` file, declare a `custom-setup` stanza with a dependency on the + `Cabal-hooks` package, and define a module `SetupHooks` that exports a value + `setupHooks :: SetupHooks`, using the API exported by `Distribution.Simple.SetupHooks` + from the `Cabal-hooks` package. Refer to the Haddock documentation of + `Distribution.Simple.SetupHooks` for example usage. + +- Redefine `build-type: Configure` in terms of `Hooks` [#9969](https://github.com/haskell/cabal/pull/9969) + + The `build-type: Configure` is now implemented in terms of `build-type: Hooks` + rather than in terms of `build-type: Custom`. This moves the `Configure` + build-type away from the `Custom` issues. Eventually, `build-type: Hooks` will + no longer imply packages are built in legacy-fallback mode. When that + happens, `Configure` will also stop implying `legacy-fallback`. + + The observable aspect of this change is `runConfigureScript` now having a + different type, and `autoconfSetupHooks` being exposed by `Distribution.Simple`. + The former is motivated by internal implementation details, while the latter + provides the `SetupHooks` value for the `Configure` build type, which can be + consumed by other `Hooks` clients (e.g. eventually HLS). + +- Cabal can issue a number of error messages referencing "Setup configure", + but it simply references "configure" which could mean any of three + things (Setup configure, the package's "configure" script, or "cabal + configure"). This has recently caught out even Cabal devs. Clarify these + messages. [#9476](https://github.com/haskell/cabal/pull/9476) + +- Update the SPDX License List to version 3.25 + + The LicenseId and LicenseExceptionId types are updated to reflect the SPDX + License List version 3.25 (2024-08-19). diff --git a/release-notes/cabal-install-3.14.0.0.md b/release-notes/cabal-install-3.14.0.0.md new file mode 100644 index 00000000000..3a890db9acc --- /dev/null +++ b/release-notes/cabal-install-3.14.0.0.md @@ -0,0 +1,141 @@ +cabal-install 3.14.0.0 changelog and release notes. +--- + + +### Significant changes + +- `haddock-project` support for subcomponents [#9821](https://github.com/haskell/cabal/pull/9821) + + - `haddock-project` handles sublibraries, test suites and benchmarks. + - `haddock` receives `--package-name` flag which allows to set names of + components which are included in the main `index.html` file. + - added `--use-unicode` flag to `haddock` and `haddock-project` commands. + - The directory structure of `./dist-newstyle` has changed. `haddock` + subcommand will install `package:sublib` component in a directory + `package/sublib` under `l/sublib/doc/html/`. This is important for + `haddock-project` command and in the future might will be useful for hackage + support of sublibraries. See + https://github.com/haskell/cabal/pull/9821#discussion_r1548557115. + +- Redefine `build-type: Configure` in terms of `Hooks` [#9969](https://github.com/haskell/cabal/pull/9969) + + The `build-type: Configure` is now implemented in terms of `build-type: Hooks` + rather than in terms of `build-type: Custom`. This moves the `Configure` + build-type away from the `Custom` issues. Eventually, `build-type: Hooks` will + no longer imply packages are built in legacy-fallback mode. When that + happens, `Configure` will also stop implying `legacy-fallback`. + + The observable aspect of this change is `runConfigureScript` now having a + different type, and `autoconfSetupHooks` being exposed from `Distribution.Simple`. + The former is motivated by internal implementation details, while the latter + provides the `SetupHooks` value for the `Configure` build type, which can be + consumed by other `Hooks` clients (e.g. eventually HLS). + +### Other changes + +- Add support for building profiled dynamic way [#4816](https://github.com/haskell/cabal/issues/4816) [#9900](https://github.com/haskell/cabal/pull/9900) + + + New options for `cabal.project` and `./Setup` interface: + + * `profiling-shared`: Enable building profiling dynamic way + * Passing `--enable-profiling` and `--enable-executable-dynamic` builds + profiled dynamic executables. + + Support for using `profiling-shared` is guarded behind a constraint + which ensures you are using `Cabal >= 3.13`. + + In the `.cabal` file: + + * `ghc-prof-shared-options`, for passing options when building in + profiling dynamic way + +- Fix interaction of `--*-shared` and `--*-executable-dynamic` options. [#10050](https://github.com/haskell/cabal/issues/10050) [#9900](https://github.com/haskell/cabal/pull/9900) + + If you explicitly request `--disable-shared` it should disable the building of + a shared library and override any automatic ways this option is turned on. + + Passing `--enable-executable-dynamic` turns on `--enable-shared` if the option is + not specified explicitly. + + Before this patch, writing `--disable-shared` on its own would not disable the building of shared libraries. Writing `--disable-shared` and `--disable-executable-dynamic` would disable shared library + creation (despite `--disable-executable-dynamic` being the default). + + Now: + + * If you specify `--enable-shared` then shared objects are built. + * If you specify `--disabled-shared` then shared objects are not built. + * If you don't explicitly specify whether you want to build shared libraries then + * `--enable-executable-dynamic` will automatically turn on building shared libraries + * `--enable-executable-dynamic --enable-profiling` will automatically turn on building + shared profiling libraries (if supported by your compiler). + +- `curl` transport now supports Basic authentication [#10089](https://github.com/haskell/cabal/pull/10089) + + - The `curl` HTTP transport previously only supported the HTTP Digest + authentication scheme. Basic authentication is now supported + when using HTTPS; Curl will use the scheme offered by the server. + The `wget` transport already supports HTTPS. + +- Enhance error detection for cabal root project files, including broken symlinks [#9937](https://github.com/haskell/cabal/issues/9937) [#10103](https://github.com/haskell/cabal/pull/10103) + + - Added proper detection and reporting for issues with cabal root project files. Previously, these files were silently ignored if they were broken symlinks. Now, `cabal` will exit + with an error in such case. + +- Let cabal init remember chosen language within current session [#10096](https://github.com/haskell/cabal/issues/10096) [#10115](https://github.com/haskell/cabal/pull/10115) + + When `cabal init` asks for a language, the last choice made will be used as the new default for the current prompt. + +- Filter out `-dinitial-unique` and `-dunique-increment` from package hash [#10122](https://github.com/haskell/cabal/pull/10122) + + `-dinitial-unique` and `-dunique-increment` are now filtered out when computing the + store hash of a package. + + These options shouldn't affect the output of the package and hence + shouldn't affect the store hash of a package. + +- Warn about `git://` protocol [#10261](https://github.com/haskell/cabal/pull/10261) + + `cabal check` will warn about the insecure (and no longer supported by GitHub or Gitlab, among others) `git://` protocol in `source-repository`. + + See [Git Book](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols#_the_cons_4) + for an explanation. + +- Enable recompilation avoidance during Haddock generation [#9175](https://github.com/haskell/cabal/issues/9175) [#9177](https://github.com/haskell/cabal/pull/9177) + + * Haddock no longer writes compilation files by default, so we do not need to + pass tmp dirs for `-hidir`, `-stubdir`, and `-odir` via `--optghc`. Indeed, we + do not *want* to do so, since it results in recompilation for every invocation + of Haddock via Cabal. We now stop this from happening for Haddock versions + 2.28 and greater, since that is when Hi Haddock was introduced. + + * We no longer define the `__HADDOCK_VERSION__` macro when invoking GHC through + Haddock, since doing so essentially guarantees recompilation during + documentation generation. We audited all uses of `__HADDOCK_VERSION__` in + hackage, ensuring there was a reasonable path forward to migrate away from + using `__HADDOCK_VERSION__` for each, while generating the same documentation + as it did before. + If you are a user of `__HADDOCK_VERSION__`, please take a look at the + discussion in https://github.com/haskell/cabal/pull/9177 and reach out to us + if your use case is not covered. + + * Rename the `--haddock-lib` flag to `--haddock-resources-dir` (and + `haddock-lib:` cabal.project field to `haddock-resources-dir:`), and add this + flag to the users guide since it was missing an entry. + + * `documentation: true` or `--enable-documentation` now implies `-haddock` for + GHC. + +- Bug fix - Don't pass `--coverage-for` for non-dependency libs of testsuite [#10046](https://github.com/haskell/cabal/issues/10046) [#10250](https://github.com/haskell/cabal/pull/10250) + +- Added `--all` and `--haddock-all` switches to `haddock-project` subcommand [#10051](https://github.com/haskell/cabal/issues/10051) [#10163](https://github.com/haskell/cabal/pull/10163) + +- Clarify error message when `pkg-config` is not found [#10122](https://github.com/haskell/cabal/pull/10122) + + - The error message when `pkg-config` is not found or querying it fails will no + longer incorrectly claim that the package is missing in the database. + +- Update the SPDX License List to version 3.25 + + The LicenseId and LicenseExceptionId types are updated to reflect the SPDX + License List version 3.25 (2024-08-19). From 499d8a06dd9a788b416aca51d9e0235027ce3cfa Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Fri, 13 Sep 2024 23:13:16 -0400 Subject: [PATCH 135/207] changelogs are docs We don't mark changelogs as documentation, so CI unnecessarily does full checks when we add changelogs. Correct this. NOTE: we only accept changelog files from top-level subdirectories. There are changelog files in various tests that must be considered to be "code". --- .github/workflows/bootstrap.skip.yml | 9 +++++++++ .github/workflows/bootstrap.yml | 9 +++++++++ .github/workflows/check-sdist.yml | 9 +++++++++ .github/workflows/validate.skip.yml | 9 +++++++++ .github/workflows/validate.yml | 9 +++++++++ 5 files changed, 45 insertions(+) diff --git a/.github/workflows/bootstrap.skip.yml b/.github/workflows/bootstrap.skip.yml index 3a47870b533..40ccb0ae9bc 100644 --- a/.github/workflows/bootstrap.skip.yml +++ b/.github/workflows/bootstrap.skip.yml @@ -19,6 +19,11 @@ on: - 'doc/**' - '**/README.md' - 'CONTRIBUTING.md' + - "changelog.d/**" + # only top level for these, because various test packages have them too + - "*/ChangeLog.md" + - "*/changelog.md" + - "release-notes/**" branches: - master pull_request: @@ -26,6 +31,10 @@ on: - 'doc/**' - '**/README.md' - 'CONTRIBUTING.md' + - "changelog.d/**" + - "*/ChangeLog.md" + - "*/changelog.md" + - "release-notes/**" release: types: - created diff --git a/.github/workflows/bootstrap.yml b/.github/workflows/bootstrap.yml index 956fc7ce570..d85b2ae4f12 100644 --- a/.github/workflows/bootstrap.yml +++ b/.github/workflows/bootstrap.yml @@ -14,6 +14,11 @@ on: - 'doc/**' - '**/README.md' - 'CONTRIBUTING.md' + - "changelog.d/**" + # only top level for these, because various test packages have them too + - "*/ChangeLog.md" + - "*/changelog.md" + - "release-notes/**" branches: - master pull_request: @@ -21,6 +26,10 @@ on: - 'doc/**' - '**/README.md' - 'CONTRIBUTING.md' + - "changelog.d/**" + - "*/ChangeLog.md" + - "*/changelog.md" + - "release-notes/**" release: types: - created diff --git a/.github/workflows/check-sdist.yml b/.github/workflows/check-sdist.yml index d295ad0ccca..3b891465ecc 100644 --- a/.github/workflows/check-sdist.yml +++ b/.github/workflows/check-sdist.yml @@ -11,6 +11,11 @@ on: - "doc/**" - "**/README.md" - "CONTRIBUTING.md" + - "changelog.d/**" + # only top level for these, because various test packages have them too + - "*/ChangeLog.md" + - "*/changelog.md" + - "release-notes/**" branches: - master pull_request: @@ -18,6 +23,10 @@ on: - "doc/**" - "**/README.md" - "CONTRIBUTING.md" + - "changelog.d/**" + - "*/ChangeLog.md" + - "*/changelog.md" + - "release-notes/**" release: types: - created diff --git a/.github/workflows/validate.skip.yml b/.github/workflows/validate.skip.yml index af608e92d49..f4aa50ae191 100644 --- a/.github/workflows/validate.skip.yml +++ b/.github/workflows/validate.skip.yml @@ -19,6 +19,11 @@ on: - 'doc/**' - '**/README.md' - 'CONTRIBUTING.md' + - "changelog.d/**" + # only top level for these, because various test packages have them too + - "*/ChangeLog.md" + - "*/changelog.md" + - "release-notes/**" branches: - master pull_request: @@ -26,6 +31,10 @@ on: - 'doc/**' - '**/README.md' - 'CONTRIBUTING.md' + - "changelog.d/**" + - "*/ChangeLog.md" + - "*/changelog.md" + - "release-notes/**" release: types: - created diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index eb48485d001..b8c1b8a9047 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -14,6 +14,11 @@ on: - "doc/**" - "**/README.md" - "CONTRIBUTING.md" + - "changelog.d/**" + # only top level for these, because various test packages have them too + - "*/ChangeLog.md" + - "*/changelog.md" + - "release-notes/**" branches: - master pull_request: @@ -21,6 +26,10 @@ on: - "doc/**" - "**/README.md" - "CONTRIBUTING.md" + - "changelog.d/**" + - "*/ChangeLog.md" + - "*/changelog.md" + - "release-notes/**" release: types: - created From d736aa8a6a4b21ea7dab25714b0fca6c88aa3ef8 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Wed, 4 Sep 2024 17:58:46 -0700 Subject: [PATCH 136/207] Gitignore `testdb/.../lx-*.lock` files Not sure what's creating these, but they're showing up when I run tests locally. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b14ad050e58..8adb6aee95f 100644 --- a/.gitignore +++ b/.gitignore @@ -76,6 +76,7 @@ testdb/intree/store/**/share/AlexTemplate.hs testdb/intree/store/**/share/AlexWrappers.hs testdb/intree/store/**/share/doc/LICENSE testdb/intree/store/*/incoming/alex-*.lock +testdb/intree/store/*/incoming/lx-*.lock testdb/intree/store/*/package.db/package.cache testdb/intree/store/*/package.db/package.cache.lock From 82e579c7421495a3eb342b11bc352a02fd4f93fe Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Tue, 17 Sep 2024 15:20:15 -0400 Subject: [PATCH 137/207] make LTS branch pre-releases This is pretty much a copy of the HEAD pre-release with "lts" added. --- .github/workflows/validate.yml | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index b8c1b8a9047..91ccbcf2e7a 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -444,6 +444,52 @@ jobs: cabal-head-Linux-static-x86_64.tar.gz cabal-head-macOS-x86_64.tar.gz + prerelease-lts: + name: Create a GitHub LTS prerelease with the binary artifacts + runs-on: ubuntu-latest + # The LTS branch is hardcoded for now, update it on a new LTS! + if: github.ref == 'refs/heads/3.12' + + # IMPORTANT! Any job added to the workflow should be added here too + needs: [validate, validate-old-ghcs, build-alpine, dogfooding] + + steps: + - uses: actions/download-artifact@v4 + with: + name: cabal-Windows-x86_64 + + - uses: actions/download-artifact@v4 + with: + name: cabal-Linux-x86_64 + + - uses: actions/download-artifact@v4 + with: + name: cabal-Linux-static-x86_64 + + - uses: actions/download-artifact@v4 + with: + name: cabal-macOS-x86_64 + + - run: | + # bash-ism, but we forced bash above + mv cabal-{,lts-}head-Windows-x86_64.tar.gz + mv cabal-{,lts-}head-Linux-x86_64.tar.gz + mv cabal-{,lts-}head-Linux-static-x86_64.tar.gz + mv cabal-{,lts-}head-macOS-x86_64.tar.gz + + - name: Create GitHub prerelease + uses: marvinpinto/action-automatic-releases@v1.2.1 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + automatic_release_tag: cabal-lts-head + prerelease: true + title: cabal-lts-head + files: | + cabal-lts-head-Windows-x86_64.tar.gz + cabal-lts-head-Linux-x86_64.tar.gz + cabal-lts-head-Linux-static-x86_64.tar.gz + cabal-lts-head-macOS-x86_64.tar.gz + # We use this job as a summary of the workflow # It will fail if any of the previous jobs does # This way we can use it exclusively in branch protection rules From 98936bfe0b3c89e07382af0c8314ed7b4d40e1d6 Mon Sep 17 00:00:00 2001 From: Artem Pelenitsyn Date: Wed, 18 Sep 2024 15:50:16 -0400 Subject: [PATCH 138/207] CI: fix-whitespace: show violations (verbose mode) --- .github/workflows/whitespace.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/whitespace.yml b/.github/workflows/whitespace.yml index 46088d3d351..b6604798f1e 100644 --- a/.github/workflows/whitespace.yml +++ b/.github/workflows/whitespace.yml @@ -12,3 +12,5 @@ jobs: steps: - uses: actions/checkout@v4 - uses: andreasabel/fix-whitespace-action@v1 + with: + verbose: true From 9b85208740ce7dc4b5d42c5d76dbd63361a46a02 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Fri, 13 Sep 2024 22:41:26 -0400 Subject: [PATCH 139/207] add Mergify config for high priority PRs This allows is to interrupt the merge queue for high priority PRs. It's using the "priority: high :fire:" label currently. Fixes: #10352 --- .github/mergify.yml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/mergify.yml b/.github/mergify.yml index 485d34d50d0..46eae2f7a80 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -1,6 +1,22 @@ # Note: We do not use the rebase strategy to merge PRs, because that # loses information needed by changelog-d to associate commits with PRs. +priority_rules: + + - name: high priority + conditions: + - 'label=priority: high :fire:' + priority: high + + # The idea is we slightly prioritize those PRs because we're in + # a release cycle if a PR matches. + - name: release branch + conditions: + - 'base~=^3\.' + - 'label!=backport' + # 'normal' is 2000, 'high' is 3000 + priority: 2500 + pull_request_rules: # implementing PR delay logic: apply a label after 2 days of inactivity @@ -11,7 +27,9 @@ pull_request_rules: - merge delay passed name: Wait for 2 days before validating merge conditions: - - updated-at<2 days ago + - or: + - 'label=priority: high :fire:' + - updated-at<2 days ago - or: - label=merge me - label=squash+merge me From a7e470b7ef501f93e2a026b4838fbf1d4bbba5f5 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Tue, 17 Sep 2024 20:23:03 -0400 Subject: [PATCH 140/207] add missing sdist skip job There's little point in having a skip-on-docs trigger if there's no alternative, cf. the comment in validate.yml. --- .github/workflows/check-sdist.skip.yml | 48 ++++++++++++++++++++++++++ .github/workflows/check-sdist.yml | 14 ++++++++ 2 files changed, 62 insertions(+) create mode 100644 .github/workflows/check-sdist.skip.yml diff --git a/.github/workflows/check-sdist.skip.yml b/.github/workflows/check-sdist.skip.yml new file mode 100644 index 00000000000..522c9896f0d --- /dev/null +++ b/.github/workflows/check-sdist.skip.yml @@ -0,0 +1,48 @@ +name: Check sdist Skip + +# This Workflow is special and contains a workaround for a known limitation of GitHub CI. +# +# The problem: We don't want to run the "check sdist" jobs on PRs which contain only changes +# to the docs, since these jobs take a long time to complete without providing any benefit. +# We therefore use path-filtering in the workflow triggers for the check sdist jobs, namely +# "paths-ignore: doc/**". But the "Check sdist post job" is a required job, therefore a PR cannot +# be merged unless the "Bootstrap post job" completes succesfully, which it doesn't do if we +# filter it out. +# +# The solution: We use a second job with the same name which always returns the exit code 0. +# The logic implemented for "required" workflows accepts if 1) at least one job with that name +# runs through, AND 2) If multiple jobs of that name exist, then all jobs of that name have to +# finish successfully. +on: + push: + paths: + - 'doc/**' + - '**/README.md' + - 'CONTRIBUTING.md' + - "changelog.d/**" + # only top level for these, because various test packages have them too + - "*/ChangeLog.md" + - "*/changelog.md" + - "release-notes/**" + branches: + - master + pull_request: + paths: + - 'doc/**' + - '**/README.md' + - 'CONTRIBUTING.md' + - "changelog.d/**" + - "*/ChangeLog.md" + - "*/changelog.md" + - "release-notes/**" + release: + types: + - created + +jobs: + check-sdist-post-job: + if: always() + name: Check sdist post job + runs-on: ubuntu-latest + steps: + - run: exit 0 diff --git a/.github/workflows/check-sdist.yml b/.github/workflows/check-sdist.yml index 3b891465ecc..f8cce8d41a9 100644 --- a/.github/workflows/check-sdist.yml +++ b/.github/workflows/check-sdist.yml @@ -89,3 +89,17 @@ jobs: echo No matching bootlib Cabal version to test against. exit 0 fi + + check-sdist-post-job: + if: always() + name: Check sdist post job + runs-on: ubuntu-latest + # IMPORTANT! Any job added to the workflow should be added here too + needs: [dogfood-sdists] + + steps: + - run: | + echo "jobs info: ${{ toJSON(needs) }}" + - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') + run: exit 1 + From e26e23e354bec8c58f89f3dab6ef243f959a4643 Mon Sep 17 00:00:00 2001 From: Phil de Joux Date: Fri, 6 Sep 2024 12:53:01 -0400 Subject: [PATCH 141/207] Add warning and note about cabal init and script Fixes #10325 - Simplify note on relaxing version bounds - Link to GHC release note included or boot packages - May allow, not will allow - Add a second link to footnote on boot packages Co-Authored-By: Artem Pelenitsyn --- doc/getting-started.rst | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/doc/getting-started.rst b/doc/getting-started.rst index 921a5ada6ce..f75e0488132 100644 --- a/doc/getting-started.rst +++ b/doc/getting-started.rst @@ -58,6 +58,18 @@ The ``myapp.cabal`` file is a package description file, commonly referred to as hs-source-dirs: app default-language: Haskell2010 +.. warning:: + + The version bounds on base, a boot library distributed with GHC + [#boot-packages]_, are tied to the GHC version visible when ``cabal init`` + is run. If run with a later version of GHC you might see a difference in the + version bounds. + + .. code-block:: diff + + - build-depends: base ^>=4.19.0.0 + + build-depends: base ^>=4.20.0.0 + It contains metadata (package name and version, author name, license, etc.) and sections to define package components. Components can be used to split large codebases into smaller, more managable building blocks. @@ -189,7 +201,7 @@ the following file named ``myscript``: #!/usr/bin/env cabal {- cabal: build-depends: - base ^>=4.19.0.0, + base, haskell-say ^>=1.0.0.0 -} @@ -198,6 +210,21 @@ the following file named ``myscript``: main :: IO () main = haskellSay "Hello, Haskell!" +.. note:: + + Widening or dropping version bound constraints on *packages included with + the compiler* [#boot-packages]_, like ``base``, may allow single-file + scripts to run with a wider range of compiler versions. + + .. code-block:: diff + + build-depends: + - base ^>=4.19.0.0, + + base, + +The necessary sections of a ``.cabal`` file are placed +directly into the script as a comment. + The necessary sections of a package description that would otherwise be in a ``.cabal`` file are placed directly into the script as a comment. @@ -237,3 +264,9 @@ some of the resources on the Haskell website's `documentation page Cabal on the :doc:`What Cabal does ` page. .. _Cabal-7070: https://errors.haskell.org/messages/Cabal-7070/ + +.. [#boot-packages] Packages included with the compiler are also called boot + packages. Each GHC compiler version has accompanying `release notes`_ that + list these included packages. + +.. _release notes: https://downloads.haskell.org/ghc/latest/docs/users_guide/release-notes.html From e21acd43bd6095dea691861055b5e162e9bab069 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Wed, 25 Sep 2024 10:16:26 -0700 Subject: [PATCH 142/207] Fix `--accept` flag in `cabal-testsuite` This was broken in #10225 --- cabal-testsuite/src/Test/Cabal/Monad.hs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cabal-testsuite/src/Test/Cabal/Monad.hs b/cabal-testsuite/src/Test/Cabal/Monad.hs index 38534402d26..17471c3bd47 100644 --- a/cabal-testsuite/src/Test/Cabal/Monad.hs +++ b/cabal-testsuite/src/Test/Cabal/Monad.hs @@ -475,7 +475,7 @@ runTestM mode m = b <- diff ["-uw"] expect_fp actual_fp unless b . void $ diff ["-u"] expect_fp actual_fp if accept - then do liftIO $ putStrLn "Accepting new output." + then do liftIO $ putStrLn $ "Writing actual test output to " <> testExpectFile env liftIO $ writeFileNoCR (testExpectFile env) actual pure (pure ()) else pure (E.throwIO TestCodeFail) @@ -880,10 +880,10 @@ testUserCabalConfigFile env = testCabalDir env "config" -- | The file where the expected output of the test lives -- --- Pointing to the @testTmpDir@ allows us to modify the expected output if --- needed, to adapt it to outcomes of previous steps in the test. +-- Note: This needs to point to `testSourceDir` so we write @--accept@ output +-- in the correct place. testExpectFile :: TestEnv -> FilePath -testExpectFile env = testTmpDir env testName env <.> "out" +testExpectFile env = testSourceDir env testName env <.> "out" -- | Where we store the actual output testActualFile :: TestEnv -> FilePath From 5e1e2d3b6b0aeb53410361eab29e4c9e343b0cf4 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Wed, 25 Sep 2024 15:17:21 -0700 Subject: [PATCH 143/207] Add `testExpectAcceptFile` --- cabal-testsuite/src/Test/Cabal/Monad.hs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/cabal-testsuite/src/Test/Cabal/Monad.hs b/cabal-testsuite/src/Test/Cabal/Monad.hs index 17471c3bd47..abb9fba5def 100644 --- a/cabal-testsuite/src/Test/Cabal/Monad.hs +++ b/cabal-testsuite/src/Test/Cabal/Monad.hs @@ -475,8 +475,8 @@ runTestM mode m = b <- diff ["-uw"] expect_fp actual_fp unless b . void $ diff ["-u"] expect_fp actual_fp if accept - then do liftIO $ putStrLn $ "Writing actual test output to " <> testExpectFile env - liftIO $ writeFileNoCR (testExpectFile env) actual + then do liftIO $ putStrLn $ "Writing actual test output to " <> testExpectAcceptFile env + liftIO $ writeFileNoCR (testExpectAcceptFile env) actual pure (pure ()) else pure (E.throwIO TestCodeFail) -- normal test, output matches @@ -880,10 +880,17 @@ testUserCabalConfigFile env = testCabalDir env "config" -- | The file where the expected output of the test lives -- --- Note: This needs to point to `testSourceDir` so we write @--accept@ output --- in the correct place. +-- Pointing to the @testTmpDir@ allows us to modify the expected output if +-- needed, to adapt it to outcomes of previous steps in the test. testExpectFile :: TestEnv -> FilePath -testExpectFile env = testSourceDir env testName env <.> "out" +testExpectFile env = testTmpDir env testName env <.> "out" + +-- | The file where the expected output of the test is written in @--accept@ mode +-- +-- Note: This needs to point to `testSourceDir` so the output is visible in the +-- user's repository. +testExpectAcceptFile :: TestEnv -> FilePath +testExpectAcceptFile env = testSourceDir env testName env <.> "out" -- | Where we store the actual output testActualFile :: TestEnv -> FilePath From 5ab42470681a49ba29b97400da25d09c7219aeea Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Mon, 16 Sep 2024 02:00:55 -0400 Subject: [PATCH 144/207] try Apple AArch64 again Let's see if the runner has stabilized yet. Also, fixed the arch issues (validate no longer assumes everything is x86_64). --- .github/workflows/validate.yml | 62 ++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 91ccbcf2e7a..947b47a5f12 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -72,7 +72,7 @@ jobs: sys: - { os: windows-latest, shell: "C:/msys64/usr/bin/bash.exe -e {0}" } - { os: ubuntu-latest, shell: bash } - - { os: macos-13, shell: bash } + - { os: macos-latest, shell: bash } # If you remove something from here, then add it to the old-ghcs job. # Also a removed GHC from here means that we are actually dropping # support, so the PR *must* have a changelog entry. @@ -101,6 +101,19 @@ jobs: - sys: { os: windows-latest, shell: "C:/msys64/usr/bin/bash.exe -e {0}" } ghc: "8.8.4" + # ghc before 8.10.5 doesn't run on AArch64 + # 9.0.2 suffers from https://gitlab.haskell.org/ghc/ghc/-/issues/20592 + # 8.10.7 throws asm errors in hashable's cbits suggesting the runner doesn't + # support a CPU extension for hardware SHA; may be fixable with flags + - sys: + { os: macos-latest, shell: bash } + ghc: "9.0.2" + - sys: + { os: macos-latest, shell: bash } + ghc: "8.10.7" + - sys: + { os: macos-latest, shell: bash } + ghc: "8.8.4" defaults: run: shell: ${{ matrix.sys.shell }} @@ -181,6 +194,16 @@ jobs: - name: Validate build run: sh validate.sh $FLAGS -s build + - name: Canonicalize architecture + run: | + case ${{ runner.arch }} in + X86) arch=i386 ;; + X64) arch=x86_64 ;; + ARM64) arch=aarch64 ;; + *) echo "Unsupported architecture, please fix validate.yaml" 2>/dev/null; exit 1 ;; + esac + echo "CABAL_ARCH=$arch" >> "$GITHUB_ENV" + - name: Tar cabal head executable if: matrix.ghc == env.GHC_FOR_RELEASE run: | @@ -199,7 +222,7 @@ jobs: fi DIR=$(dirname "$CABAL_EXEC") FILE=$(basename "$CABAL_EXEC") - CABAL_EXEC_TAR="cabal-head-${{ runner.os }}-x86_64.tar.gz" + CABAL_EXEC_TAR="cabal-head-${{ runner.os }}-$CABAL_ARCH.tar.gz" tar -czvf "$CABAL_EXEC_TAR" -C "$DIR" "$FILE" echo "CABAL_EXEC_TAR=$CABAL_EXEC_TAR" >> "$GITHUB_ENV" @@ -210,7 +233,7 @@ jobs: if: matrix.ghc == env.GHC_FOR_RELEASE uses: actions/upload-artifact@v4 with: - name: cabal-${{ runner.os }}-x86_64 + name: cabal-${{ runner.os }}-${{ env.CABAL_ARCH }} path: ${{ env.CABAL_EXEC_TAR }} - name: Validate lib-tests @@ -363,18 +386,36 @@ jobs: # This one uses the cabal HEAD generated executable in the previous step # to build itself again, as sanity check dogfooding: - name: Dogfooding ${{ matrix.os }} ghc-${{ matrix.ghc }} - runs-on: ${{ matrix.os }} + name: Dogfooding ${{ matrix.sys.os }} ghc-${{ matrix.ghc }} + runs-on: ${{ matrix.sys.os }} needs: validate strategy: matrix: - os: [ubuntu-latest, macos-13, windows-latest] + sys: + - { os: windows-latest, shell: "C:/msys64/usr/bin/bash.exe -e {0}" } + - { os: ubuntu-latest, shell: bash } + - { os: macos-latest, shell: bash } # We only use one ghc version the used one for the next release (defined at top of the workflow) # We need to build an array dynamically to inject the appropiate env var in a previous job, # see https://docs.github.com/en/actions/learn-github-actions/expressions#fromjson ghc: ${{ fromJSON (needs.validate.outputs.GHC_FOR_RELEASE) }} + defaults: + run: + shell: ${{ matrix.sys.shell }} + steps: + # TODO: make a reusable action for this + - name: Canonicalize architecture + run: | + case ${{ runner.arch }} in + X86) arch=i386 ;; + X64) arch=x86_64 ;; + ARM64) arch=aarch64 ;; + *) echo "Unsupported architecture" 2>/dev/null; exit 1 ;; + esac + echo "CABAL_ARCH=$arch" >> "$GITHUB_ENV" + - name: Work around XDG directories existence (haskell-actions/setup#62) if: runner.os == 'macOS' run: | @@ -392,11 +433,11 @@ jobs: - name: Download cabal executable from workflow artifacts uses: actions/download-artifact@v4 with: - name: cabal-${{ runner.os }}-x86_64 + name: cabal-${{ runner.os }}-${{ env.CABAL_ARCH }} path: cabal-head - name: Untar the cabal executable - run: tar -xzf "./cabal-head/cabal-head-${{ runner.os }}-x86_64.tar.gz" -C cabal-head + run: tar -xzf "./cabal-head/cabal-head-${{ runner.os }}-$CABAL_ARCH.tar.gz" -C cabal-head - name: print-config using cabal HEAD run: sh validate.sh ${{ env.COMMON_FLAGS }} --with-cabal ./cabal-head/cabal -s print-config @@ -415,6 +456,7 @@ jobs: needs: [validate, validate-old-ghcs, build-alpine, dogfooding] steps: + # for now this is hardcoded. is there a better way? - uses: actions/download-artifact@v4 with: name: cabal-Windows-x86_64 @@ -429,7 +471,7 @@ jobs: - uses: actions/download-artifact@v4 with: - name: cabal-macOS-x86_64 + name: cabal-macOS-aarch64 - name: Create GitHub prerelease uses: marvinpinto/action-automatic-releases@v1.2.1 @@ -442,7 +484,7 @@ jobs: cabal-head-Windows-x86_64.tar.gz cabal-head-Linux-x86_64.tar.gz cabal-head-Linux-static-x86_64.tar.gz - cabal-head-macOS-x86_64.tar.gz + cabal-head-macOS-aarch64.tar.gz prerelease-lts: name: Create a GitHub LTS prerelease with the binary artifacts From 81fec84d330af27ea6fa22d2ef27784c83e7911d Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Tue, 24 Sep 2024 11:30:53 -0700 Subject: [PATCH 145/207] Use standard Markdown headings --- CONTRIBUTING.md | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2049b978528..c41a2db8192 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,6 @@ # Contributing to Cabal -Building Cabal for hacking --------------------------- +## Building Cabal for hacking If you use the `cabal` executable from the latest version of the [cabal-install](https://hackage.haskell.org/package/cabal-install) package @@ -58,8 +57,7 @@ $ cabal build Cabal-tests:unit-tests # build Cabal's unit test suite $ cabal build cabal-tests # etc... ``` -Running tests -------------- +## Running tests **Using GitHub Actions.** If you are not in a hurry, the most convenient way to run tests on Cabal @@ -150,8 +148,7 @@ For these test executables, `-p` which applies a regex filter to the test names. When running `cabal-install` test suites, one need only use `cabal test` or `cabal run ` in order to test locally. -QA Notes --------- +## QA Notes Manual Quality Assurance (QA) is performed to ensure that the changes impacting the command-line interface, whether adding or modifying a behaviour, @@ -186,15 +183,13 @@ the code base. * `make style-modified` - Format files modified in the current tree. * `make style-commit COMMIT=` - Format files modified between HEAD and the given reference. -Whitespace Conventions ----------------------- +## Whitespace Conventions We use automated whitespace convention checking. Violations can be fixed by running [fix-whitespace](https://hackage.haskell.org/package/fix-whitespace). If you push a fix of a whitespace violation, please do so in a _separate commit_. -Other Conventions ------------------ +## Other Conventions * Format your commit messages [in the standard way](https://chris.beams.io/posts/git-commit/#seven-rules). @@ -254,8 +249,7 @@ Other Conventions #endif ``` -GitHub Ticket Conventions -------------------- +## GitHub Ticket Conventions Each major `Cabal`/`cabal-install` release (e.g. 3.4, 3.6, etc.) has a corresponding GitHub Project and milestone. A ticket is included in a release's @@ -268,8 +262,7 @@ accepting a fix in that release, i.e. we would very much appreciate someone working on it, but are not committing to actively sourcing someone to work on it. -GitHub Pull Request Conventions -------------------- +## GitHub Pull Request Conventions Every (non-backport) pull request has to go through a review and get 2 approvals. After this is done, the author of the pull request is expected to add @@ -310,8 +303,7 @@ think it does not warrant an issue). Feel free to open a new issue (or new issues) when appropriate. -Changelog ---------- +## Changelog Anything that changes `cabal-install:exe:cabal` or changes exports from library modules or changes behaviour of functions exported from packages published to @@ -365,8 +357,7 @@ At release time, the entries will be merged with In addition, if you're changing the `.cabal` file format specification you should add an entry in `doc/file-format-changelog.rst`. -Communicating -------------- +## Communicating There are a few main venues of communication: @@ -379,8 +370,7 @@ There are a few main venues of communication: * You can join the channel using a web client, even anonymously: https://web.libera.chat/#hackage * Alternatively you can join it using [matrix](https://matrix.org/): https://matrix.to/#/#hackage:libera.chat -Releases --------- +## Releases Notes for how to make a release are at the wiki page ["Making a release"](https://github.com/haskell/cabal/wiki/Making-a-release). @@ -388,8 +378,7 @@ Currently, [@emilypi](https://github.com/emilypi), [@fgaz](https://github.com/fg `haskell.org/cabal`, and [@Mikolaj](https://github.com/Mikolaj) is the point of contact for getting permissions. -Preview Releases ----------------- +## Preview Releases We make preview releases available to facilitate testing of development builds. @@ -407,8 +396,7 @@ To reproduce these locally, set up an Alpine build environment using GHCup, and then build by calling `cabal build cabal-install --enable-executable-static`. -API Documentation ------------------ +## API Documentation Auto-generated API documentation for the `master` branch of Cabal is automatically uploaded here: http://haskell.github.io/cabal-website/doc/html/Cabal/. @@ -416,8 +404,7 @@ Auto-generated API documentation for the `master` branch of Cabal is automatical You can contribute by triaging issues which may include reproducing bug reports or asking for vital information, such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to cabal on CodeTriage](https://www.codetriage.com/haskell/cabal). -Hackage Revisions ------------------ +## Hackage Revisions We are reactive rather than proactive with revising bounds on our dependencies for code already released on Hackage. If you would benefit from a version bump, From 66ad2ee033f43d860f1e952c90f3eb4f480f8411 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Tue, 24 Sep 2024 11:31:38 -0700 Subject: [PATCH 146/207] headings --- CONTRIBUTING.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c41a2db8192..d4e2efd4058 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -171,8 +171,7 @@ Manual QA is not expected to find every possible bug, but to really challenge th of their patch is not influenced by their setup or implicit knowledge of the system. -Code Style ---------------- +## Code Style We use automated formatting with Fourmolu to enforce a unified style across the code bases. It is checked in the CI process. After installing Fourmolu 0.12, there are some makefile targets to help formatting From 842d602e4adab85a57b038630f53784f9d56e5bc Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Tue, 24 Sep 2024 11:31:45 -0700 Subject: [PATCH 147/207] Make Markdown example a code block --- CONTRIBUTING.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d4e2efd4058..ba94cccf036 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -159,13 +159,14 @@ Contributions that touch `cabal-install` are expected to include notes for the Q They are a description of an expected result upon calling `cabal-install` with certain parameters, and should be written in the body of the ticket or PR under their own heading, like this: -For instance: +```markdown +## QA Notes -> \#\# QA Notes -> -> Calling `cabal haddock-project` should produce documentation for the whole cabal project with the following defaults enabled: -> * Documentation lives in ./haddocks -> * The file `./haddocks/index.html` should exist +Calling `cabal haddock-project` should produce documentation for the whole +cabal project with the following defaults enabled: +* Documentation lives in ./haddocks +* The file `./haddocks/index.html` should exist +``` Manual QA is not expected to find every possible bug, but to really challenge the assumptions of the contributor, and to verify that their own testing of their patch is not influenced by their setup or implicit knowledge of the system. From 85ecb80fc4a2ff2cad0ba08576508c21ef9b8255 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Tue, 24 Sep 2024 11:33:17 -0700 Subject: [PATCH 148/207] headings --- CONTRIBUTING.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ba94cccf036..8dcdbbb030b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -59,7 +59,8 @@ $ cabal build cabal-tests # etc... ## Running tests -**Using GitHub Actions.** +### Using GitHub Actions. + If you are not in a hurry, the most convenient way to run tests on Cabal is to make a branch on GitHub and then open a pull request; our continuous integration service on GitHub Actions builds and @@ -83,7 +84,8 @@ Some tips for using GitHub Actions effectively: already failed), be nice to others and cancel the rest of the jobs, so that other commits on the build queue can be processed. -**How to debug a failing CI test.** +### How to debug a failing CI test. + One of the annoying things about running tests on CI is when they fail, there is often no easy way to further troubleshoot the broken build. Here are some guidelines for debugging continuous integration @@ -111,7 +113,8 @@ failures: If none of these let you reproduce, there might be some race condition or continuous integration breakage; please file a bug. -**Running tests locally.** +### Running tests locally. + To run tests locally with `cabal`, you will need to know the name of the test suite you want. Cabal and cabal-install have several. Also, you'll want to read [Where are my build products?](http://cabal.readthedocs.io/en/latest/nix-local-build.html#where-are-my-build-products) From 2a50624e644ff25cc391d6a022a9d822f4e248e6 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Tue, 24 Sep 2024 11:38:28 -0700 Subject: [PATCH 149/207] Point out `validate.sh` in `CONTRIBUTING.md` --- CONTRIBUTING.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8dcdbbb030b..9a06d1c8329 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -59,6 +59,9 @@ $ cabal build cabal-tests # etc... ## Running tests +There are two ways to run tests: in CI with GitHub actions and locally with +`./validate.sh`. + ### Using GitHub Actions. If you are not in a hurry, the most convenient way to run tests on Cabal @@ -115,6 +118,9 @@ or continuous integration breakage; please file a bug. ### Running tests locally. +The [`./validate.sh`](./validate.sh) script runs all the test suites. It takes +various options to restrict the test suites it runs; use `--help` to list them. + To run tests locally with `cabal`, you will need to know the name of the test suite you want. Cabal and cabal-install have several. Also, you'll want to read [Where are my build products?](http://cabal.readthedocs.io/en/latest/nix-local-build.html#where-are-my-build-products) From a85094a726936cfef55951d0effaae294c09a904 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Thu, 19 Sep 2024 20:22:20 -0400 Subject: [PATCH 150/207] add Makefile targets for fix-whitespace `make whitespace` now runs `fix-whitespace --check --verbose` and `make fix-whitespace` runs `fix-whitespace --verbose`. --- .github/workflows/whitespace.yml | 17 ++++++++++++++--- CONTRIBUTING.md | 4 +++- Makefile | 8 ++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/.github/workflows/whitespace.yml b/.github/workflows/whitespace.yml index b6604798f1e..a6869a59e3f 100644 --- a/.github/workflows/whitespace.yml +++ b/.github/workflows/whitespace.yml @@ -7,10 +7,21 @@ on: jobs: whitespace: + defaults: + run: + shell: bash runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 - - uses: andreasabel/fix-whitespace-action@v1 - with: - verbose: true + + - run: | + # no longer using the action because apparently we're supposed to use the Makefile here + wget -q https://github.com/agda/fix-whitespace/releases/download/v0.1/fix-whitespace-0.1-linux.binary + mkdir -p "$HOME/.local/bin" + mv fix-whitespace-0.1-linux.binary "$HOME/.local/bin/fix-whitespace" + chmod +x "$HOME/.local/bin/fix-whitespace" + echo "$HOME/.local/bin" >> $GITHUB_PATH + + - run: make whitespace diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9a06d1c8329..b2d7cc47ffe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -196,7 +196,9 @@ the code base. We use automated whitespace convention checking. Violations can be fixed by running [fix-whitespace](https://hackage.haskell.org/package/fix-whitespace). If -you push a fix of a whitespace violation, please do so in a _separate commit_. +you push a fix of a whitespace violation, please do so in a _separate commit_. For convenience, +`make whitespace` will show violations and `make fix-whitespace` will fix them, if the +`fix-whitespace` utility is installed. ## Other Conventions diff --git a/Makefile b/Makefile index 7b272c55e09..e0b239d80ad 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,14 @@ style-commit: ## Run the code styler on the previous commit @git diff --name-only HEAD $(COMMIT) Cabal Cabal-syntax cabal-install \ | grep '.hs$$' | xargs -P $(PROCS) -I {} fourmolu -q -i {} +.PHONY: whitespace +whitespace: ## Run fix-whitespace in check mode + fix-whitespace --check --verbose + +.PHONY: fix-whitespace +fix-whitespace: ## Run fix-whitespace in fix mode + fix-whitespace --verbose + # source generation: SPDX SPDX_LICENSE_HS:=Cabal-syntax/src/Distribution/SPDX/LicenseId.hs From 242933ba92b5135e56c12cd519e0cfc82bcc4c79 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Fri, 27 Sep 2024 16:53:43 -0700 Subject: [PATCH 151/207] Filter `CommonSetupFlags` more consistently in UnpackedPackage In #10292, we will move the `--keep-temp-files` setting into `CommonSetupFlags` and out of `ReplFlags`/`HaddockFlags`. This means that the flag-filtering behavior (which adapts flags from new versions of `cabal-install` to old version of `Cabal`) will need to know which command is being run to provide the correct `CommonSetupFlags`. Therefore, this change adds several new `filterFooFlags` functions to provide this behavior, and removes the `commonFlags` used for all subcommands in `Distribution.Client.ProjectBuilding.UnpackedPackage`. --- .../Client/ProjectBuilding/UnpackedPackage.hs | 64 +++++----- .../src/Distribution/Client/Setup.hs | 110 ++++++++++++++++-- 2 files changed, 136 insertions(+), 38 deletions(-) diff --git a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs index f1486388b8c..9e3b91d1753 100644 --- a/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs +++ b/cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs @@ -44,10 +44,14 @@ import Distribution.Client.FileMonitor import Distribution.Client.JobControl import Distribution.Client.Setup ( CommonSetupFlags - , filterCommonFlags + , filterBenchmarkFlags + , filterBuildFlags , filterConfigureFlags + , filterCopyFlags , filterHaddockArgs , filterHaddockFlags + , filterRegisterFlags + , filterReplFlags , filterTestFlags ) import Distribution.Client.SetupWrapper @@ -272,9 +276,7 @@ buildAndRegisterUnpackedPackage | otherwise = return () mbWorkDir = useWorkingDir scriptOptions - commonFlags v = - flip filterCommonFlags v $ - setupHsCommonFlags verbosity mbWorkDir builddir + commonFlags = setupHsCommonFlags verbosity mbWorkDir builddir configureCommand = Cabal.configureCommand defaultProgramDb configureFlags v = @@ -284,19 +286,26 @@ buildAndRegisterUnpackedPackage plan rpkg pkgshared - (commonFlags v) + commonFlags configureArgs _ = setupHsConfigureArgs pkg buildCommand = Cabal.buildCommand defaultProgramDb - buildFlags v = setupHsBuildFlags comp_par_strat pkg pkgshared $ commonFlags v + buildFlags v = + flip filterBuildFlags v $ + setupHsBuildFlags + comp_par_strat + pkg + pkgshared + commonFlags buildArgs _ = setupHsBuildArgs pkg copyFlags destdir v = - setupHsCopyFlags - pkg - pkgshared - (commonFlags v) - destdir + flip filterCopyFlags v $ + setupHsCopyFlags + pkg + pkgshared + commonFlags + destdir -- In theory, we could want to copy less things than those that were -- built, but instead, we simply copy the targets that were built. copyArgs = buildArgs @@ -306,23 +315,25 @@ buildAndRegisterUnpackedPackage flip filterTestFlags v $ setupHsTestFlags pkg - (commonFlags v) + commonFlags testArgs _ = setupHsTestArgs pkg benchCommand = Cabal.benchmarkCommand benchFlags v = - setupHsBenchFlags - pkg - pkgshared - (commonFlags v) + flip filterBenchmarkFlags v $ + setupHsBenchFlags + pkg + pkgshared + commonFlags benchArgs _ = setupHsBenchArgs pkg replCommand = Cabal.replCommand defaultProgramDb replFlags v = - setupHsReplFlags - pkg - pkgshared - (commonFlags v) + flip filterReplFlags v $ + setupHsReplFlags + pkg + pkgshared + commonFlags replArgs _ = setupHsReplArgs pkg haddockCommand = Cabal.haddockCommand @@ -332,7 +343,7 @@ buildAndRegisterUnpackedPackage pkg pkgshared buildTimeSettings - (commonFlags v) + commonFlags haddockArgs v = flip filterHaddockArgs v $ setupHsHaddockArgs pkg @@ -394,11 +405,12 @@ buildAndRegisterUnpackedPackage distTempDirectory $ \pkgConfDest -> do let registerFlags v = - setupHsRegisterFlags - pkg - pkgshared - (commonFlags v) - pkgConfDest + flip filterRegisterFlags v $ + setupHsRegisterFlags + pkg + pkgshared + commonFlags + pkgConfDest setup (Cabal.registerCommand) Cabal.registerCommonFlags (\v -> return (registerFlags v)) (const []) withLogging :: (Maybe Handle -> IO r) -> IO r diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index 78e864d1a65..aebba9462c0 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -35,12 +35,15 @@ module Distribution.Client.Setup , defaultConfigExFlags , buildCommand , BuildFlags (..) + , filterBuildFlags , filterTestFlags , replCommand + , filterReplFlags , testCommand , benchmarkCommand , testOptions , benchmarkOptions + , filterBenchmarkFlags , configureExOptions , reconfigureCommand , installCommand @@ -87,7 +90,9 @@ module Distribution.Client.Setup , haddockCommand , cleanCommand , copyCommand + , filterCopyFlags , registerCommand + , filterRegisterFlags , liftOptions , yesNoOpt ) where @@ -183,7 +188,7 @@ import Distribution.Simple.InstallDirs ) import Distribution.Simple.Program (ProgramDb, defaultProgramDb) import Distribution.Simple.Setup - ( BenchmarkFlags + ( BenchmarkFlags (benchmarkCommonFlags) , BooleanFlag (..) , BuildFlags (..) , CleanFlags (..) @@ -192,7 +197,7 @@ import Distribution.Simple.Setup , CopyFlags (..) , HaddockFlags (..) , RegisterFlags (..) - , ReplFlags + , ReplFlags (..) , TestFlags , boolOpt , boolOpt' @@ -1144,6 +1149,21 @@ buildCommand = where parent = Cabal.buildCommand defaultProgramDb +-- | Given some 'BuildFlags' for the version of @Cabal@ that +-- @cabal-install@ was built with, and a target older 'Version' of +-- @Cabal@ that we want to pass these flags to, convert the +-- flags into a form that will be accepted by the older +-- @Setup@ script. Generally speaking, this just means filtering +-- out flags that the old @Cabal@ library doesn't understand, but +-- in some cases it may also mean "emulating" a feature using +-- some more legacy flags. +filterBuildFlags :: BuildFlags -> Version -> BuildFlags +filterBuildFlags flags cabalLibVersion = + flags + { buildCommonFlags = + filterCommonFlags (buildCommonFlags flags) cabalLibVersion + } + -- ------------------------------------------------------------ -- * Test flags @@ -1236,6 +1256,21 @@ replCommand = where parent = Cabal.replCommand defaultProgramDb +-- | Given some 'ReplFlags' for the version of @Cabal@ that +-- @cabal-install@ was built with, and a target older 'Version' of +-- @Cabal@ that we want to pass these flags to, convert the +-- flags into a form that will be accepted by the older +-- @Setup@ script. Generally speaking, this just means filtering +-- out flags that the old @Cabal@ library doesn't understand, but +-- in some cases it may also mean "emulating" a feature using +-- some more legacy flags. +filterReplFlags :: ReplFlags -> Version -> ReplFlags +filterReplFlags flags cabalLibVersion = + flags + { replCommonFlags = + filterCommonFlags (replCommonFlags flags) cabalLibVersion + } + -- ------------------------------------------------------------ -- * Test command @@ -1331,6 +1366,21 @@ benchmarkCommand = parent = Cabal.benchmarkCommand progDb = defaultProgramDb +-- | Given some 'BenchmarkFlags' for the version of @Cabal@ that +-- @cabal-install@ was built with, and a target older 'Version' of +-- @Cabal@ that we want to pass these flags to, convert the +-- flags into a form that will be accepted by the older +-- @Setup@ script. Generally speaking, this just means filtering +-- out flags that the old @Cabal@ library doesn't understand, but +-- in some cases it may also mean "emulating" a feature using +-- some more legacy flags. +filterBenchmarkFlags :: BenchmarkFlags -> Version -> BenchmarkFlags +filterBenchmarkFlags flags cabalLibVersion = + flags + { benchmarkCommonFlags = + filterCommonFlags (benchmarkCommonFlags flags) cabalLibVersion + } + -- ------------------------------------------------------------ -- * Fetch command @@ -2404,21 +2454,25 @@ filterHaddockArgs args cabalLibVersion -- Cabal < 2.3 doesn't know about per-component haddock args_2_3_0 = [] +-- | Given some 'HaddockFlags' for the version of @Cabal@ that +-- @cabal-install@ was built with, and a target older 'Version' of +-- @Cabal@ that we want to pass these flags to, convert the +-- flags into a form that will be accepted by the older +-- @Setup@ script. Generally speaking, this just means filtering +-- out flags that the old @Cabal@ library doesn't understand, but +-- in some cases it may also mean "emulating" a feature using +-- some more legacy flags. filterHaddockFlags :: HaddockFlags -> Version -> HaddockFlags -filterHaddockFlags flags cabalLibVersion = - let flags' = filterHaddockFlags' flags cabalLibVersion - in flags' - { haddockCommonFlags = - filterCommonFlags (haddockCommonFlags flags') cabalLibVersion - } - -filterHaddockFlags' :: HaddockFlags -> Version -> HaddockFlags -filterHaddockFlags' flags cabalLibVersion +filterHaddockFlags flags cabalLibVersion | cabalLibVersion >= mkVersion [2, 3, 0] = flags_latest | cabalLibVersion < mkVersion [2, 3, 0] = flags_2_3_0 | otherwise = flags_latest where - flags_latest = flags + flags_latest = + flags + { haddockCommonFlags = + filterCommonFlags (haddockCommonFlags flags) cabalLibVersion + } flags_2_3_0 = flags_latest @@ -2490,6 +2544,9 @@ testOptions showOrParseArgs = | "test-" `isPrefixOf` name = name | otherwise = "test-" ++ name +-- | Options for the @bench@ command. +-- +-- Not to be confused with the @benchmarkOptions@ field of the `BenchmarkFlags` record! benchmarkOptions :: ShowOrParseArgs -> [OptionField BenchmarkFlags] benchmarkOptions showOrParseArgs = [ opt @@ -3317,6 +3374,35 @@ registerCommand = { commandUsage = \pname -> "Usage: " ++ pname ++ " v1-register [FLAGS]\n" } +-- | Given some 'RegisterFlags' for the version of @Cabal@ that +-- @cabal-install@ was built with, and a target older 'Version' of +-- @Cabal@ that we want to pass these flags to, convert the +-- flags into a form that will be accepted by the older +-- @Setup@ script. Generally speaking, this just means filtering +-- out flags that the old @Cabal@ library doesn't understand, but +-- in some cases it may also mean "emulating" a feature using +-- some more legacy flags. +filterRegisterFlags :: RegisterFlags -> Version -> RegisterFlags +filterRegisterFlags flags cabalLibVersion = + flags + { registerCommonFlags = + filterCommonFlags (registerCommonFlags flags) cabalLibVersion + } + +-- | Given some 'CopyFlags' for the version of @Cabal@ that +-- @cabal-install@ was built with, and a target older 'Version' of +-- @Cabal@ that we want to pass these flags to, convert the +-- flags into a form that will be accepted by the older +-- @Setup@ script. Generally speaking, this just means filtering +-- out flags that the old @Cabal@ library doesn't understand, but +-- in some cases it may also mean "emulating" a feature using +-- some more legacy flags. +filterCopyFlags :: CopyFlags -> Version -> CopyFlags +filterCopyFlags flags cabalLibVersion = + flags + { copyCommonFlags = filterCommonFlags (copyCommonFlags flags) cabalLibVersion + } + -- ------------------------------------------------------------ -- * ActAsSetup flags From 73f719b4448041260a511b234ddce7332fc2fc00 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Thu, 26 Sep 2024 12:12:53 -0700 Subject: [PATCH 152/207] cabal-testsuite: Add glob helpers --- cabal-testsuite/cabal-testsuite.cabal | 1 + cabal-testsuite/src/Test/Cabal/Prelude.hs | 52 ++++++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/cabal-testsuite/cabal-testsuite.cabal b/cabal-testsuite/cabal-testsuite.cabal index 4c114082d43..f0dce35e60e 100644 --- a/cabal-testsuite/cabal-testsuite.cabal +++ b/cabal-testsuite/cabal-testsuite.cabal @@ -70,6 +70,7 @@ library , directory ^>= 1.2.0.1 || ^>= 1.3.0.0 , exceptions ^>= 0.10.0 , filepath ^>= 1.3.0.1 || ^>= 1.4.0.0 || ^>= 1.5.0.0 + , Glob ^>= 0.10.2 , network-wait ^>= 0.1.2.0 || ^>= 0.2.0.0 , optparse-applicative ^>= 0.14.3.0 || ^>=0.15.1.0 || ^>=0.16.0.0 || ^>= 0.17.0.0 || ^>= 0.18.1.0 , process ^>= 1.2.1.0 || ^>= 1.4.2.0 || ^>= 1.6.1.0 diff --git a/cabal-testsuite/src/Test/Cabal/Prelude.hs b/cabal-testsuite/src/Test/Cabal/Prelude.hs index 50f9395d74a..266969b3144 100644 --- a/cabal-testsuite/src/Test/Cabal/Prelude.hs +++ b/cabal-testsuite/src/Test/Cabal/Prelude.hs @@ -55,7 +55,7 @@ import qualified Data.Aeson as JSON import qualified Data.ByteString.Lazy as BSL import Control.Monad (unless, when, void, forM_, liftM2, liftM4) import Control.Monad.Catch ( bracket_ ) -import Control.Monad.Trans.Reader (withReaderT, runReaderT) +import Control.Monad.Trans.Reader (asks, withReaderT, runReaderT) import Control.Monad.IO.Class (MonadIO (..)) import qualified Crypto.Hash.SHA256 as SHA256 import qualified Data.ByteString.Base16 as Base16 @@ -70,6 +70,7 @@ import System.Directory import Control.Retry (exponentialBackoff, limitRetriesByCumulativeDelay) import Network.Wait (waitTcpVerbose) import System.Environment +import qualified System.FilePath.Glob as Glob (globDir1, compile) import System.Process import System.IO @@ -726,7 +727,7 @@ recordHeader args = do ------------------------------------------------------------------------ -- * Subprocess run results -assertFailure :: WithCallStack (String -> m ()) +assertFailure :: WithCallStack (String -> m a) assertFailure msg = withFrozenCallStack $ error msg assertExitCode :: MonadIO m => WithCallStack (ExitCode -> Result -> m ()) @@ -847,6 +848,53 @@ getScriptCacheDirectory script = do let hash = C.unpack . Base16.encode . C.take 26 . SHA256.hash . C.pack $ hashinput return $ cabalDir "script-builds" hash +------------------------------------------------------------------------ +-- * Globs + +-- | Match a glob from a root directory and return the results. +matchGlob :: MonadIO m => FilePath -> String -> m [FilePath] +matchGlob root glob = do + liftIO $ Glob.globDir1 (Glob.compile glob) root + +-- | Assert that a glob matches at least one path in the given root directory. +assertGlobMatches :: MonadIO m => WithCallStack (FilePath -> String -> m ()) +assertGlobMatches root glob = do + results <- matchGlob root glob + withFrozenCallStack $ + when (null results) $ + assertFailure $ + "Expected glob " <> show glob <> " to match in " <> show root + +-- | Assert that a glob matches no paths in the given root directory. +assertGlobDoesNotMatch :: MonadIO m => WithCallStack (FilePath -> String -> m ()) +assertGlobDoesNotMatch root glob = do + results <- matchGlob root glob + withFrozenCallStack $ + unless (null results) $ + assertFailure $ + "Expected glob " + <> show glob + <> " to not match any paths in " + <> show root + <> ", but the following matches were found:" + <> unlines (map ("* " <>) results) + +-- | Assert that a glob matches a path in the given root directory. +-- +-- The root directory is determined from the `TestEnv` with a function like `testDistDir`. +assertGlobMatchesTestDir :: WithCallStack ((TestEnv -> FilePath) -> String -> TestM ()) +assertGlobMatchesTestDir rootSelector glob = do + root <- asks rootSelector + assertGlobMatches root glob + +-- | Assert that a glob matches a path in the given root directory. +-- +-- The root directory is determined from the `TestEnv` with a function like `testDistDir`. +assertGlobDoesNotMatchTestDir :: WithCallStack ((TestEnv -> FilePath) -> String -> TestM ()) +assertGlobDoesNotMatchTestDir rootSelector glob = do + root <- asks rootSelector + assertGlobDoesNotMatch root glob + ------------------------------------------------------------------------ -- * Skipping tests From aa259d1592e2a1ebf2d0c80d610423deb218bf41 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Fri, 27 Sep 2024 11:26:28 -0700 Subject: [PATCH 153/207] cabal-testsuite: Add `assert{Any,No}FileContains` helpers --- cabal-testsuite/src/Test/Cabal/Prelude.hs | 36 +++++++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/cabal-testsuite/src/Test/Cabal/Prelude.hs b/cabal-testsuite/src/Test/Cabal/Prelude.hs index 266969b3144..d8cee954d83 100644 --- a/cabal-testsuite/src/Test/Cabal/Prelude.hs +++ b/cabal-testsuite/src/Test/Cabal/Prelude.hs @@ -53,7 +53,7 @@ import Text.Regex.TDFA ((=~)) import Control.Concurrent.Async (withAsync) import qualified Data.Aeson as JSON import qualified Data.ByteString.Lazy as BSL -import Control.Monad (unless, when, void, forM_, liftM2, liftM4) +import Control.Monad (unless, when, void, forM_, foldM, liftM2, liftM4) import Control.Monad.Catch ( bracket_ ) import Control.Monad.Trans.Reader (asks, withReaderT, runReaderT) import Control.Monad.IO.Class (MonadIO (..)) @@ -836,6 +836,31 @@ assertFileDoesNotContain path needle = (assertFailure ("expected: " ++ needle ++ "\n" ++ " in file: " ++ path))) +-- | Assert that at least one of the given paths contains the given search string. +assertAnyFileContains :: MonadIO m => WithCallStack ([FilePath] -> String -> m ()) +assertAnyFileContains paths needle = do + let findOne found path = + if found + then pure found + else withFileContents path $ \contents -> + pure $! needle `isInfixOf` contents + foundNeedle <- liftIO $ foldM findOne False paths + withFrozenCallStack $ + unless foundNeedle $ + assertFailure $ + "expected: " <> + needle <> + "\nin one of:\n" <> + unlines (map ("* " <>) paths) + +-- | Assert that none of the given paths contains the given search string. +assertNoFileContains :: MonadIO m => WithCallStack ([FilePath] -> String -> m ()) +assertNoFileContains paths needle = + liftIO $ + forM_ paths $ + \path -> + assertFileDoesNotContain path needle + -- | Replace line breaks with spaces, correctly handling "\r\n". concatOutput :: String -> String concatOutput = unwords . lines . filter ((/=) '\r') @@ -857,13 +882,16 @@ matchGlob root glob = do liftIO $ Glob.globDir1 (Glob.compile glob) root -- | Assert that a glob matches at least one path in the given root directory. -assertGlobMatches :: MonadIO m => WithCallStack (FilePath -> String -> m ()) +-- +-- The matched paths are returned for further validation. +assertGlobMatches :: MonadIO m => WithCallStack (FilePath -> String -> m [FilePath]) assertGlobMatches root glob = do results <- matchGlob root glob withFrozenCallStack $ when (null results) $ assertFailure $ "Expected glob " <> show glob <> " to match in " <> show root + pure results -- | Assert that a glob matches no paths in the given root directory. assertGlobDoesNotMatch :: MonadIO m => WithCallStack (FilePath -> String -> m ()) @@ -882,7 +910,9 @@ assertGlobDoesNotMatch root glob = do -- | Assert that a glob matches a path in the given root directory. -- -- The root directory is determined from the `TestEnv` with a function like `testDistDir`. -assertGlobMatchesTestDir :: WithCallStack ((TestEnv -> FilePath) -> String -> TestM ()) +-- +-- The matched paths are returned for further validation. +assertGlobMatchesTestDir :: WithCallStack ((TestEnv -> FilePath) -> String -> TestM [FilePath]) assertGlobMatchesTestDir rootSelector glob = do root <- asks rootSelector assertGlobMatches root glob From 2c85a7c5b00dcb3aaed128980892883005fcb8a3 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Fri, 27 Sep 2024 11:50:17 -0700 Subject: [PATCH 154/207] Fix `withFileContents` documentation The documentation for `Distribution.Utils.Generic.withFileContents` is incorrect: $ cabal repl Cabal-syntax ghci> import Distribution.Utils.Generic ghci> withFileContents "README.md" $ \contents -> pure ("foo" `isInfixOf` contents) *** Exception: README.md: hGetContents: illegal operation (delayed read on closed handle) --- Cabal-syntax/src/Distribution/Utils/Generic.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Utils/Generic.hs b/Cabal-syntax/src/Distribution/Utils/Generic.hs index 997e0132f5a..ace55a67aa3 100644 --- a/Cabal-syntax/src/Distribution/Utils/Generic.hs +++ b/Cabal-syntax/src/Distribution/Utils/Generic.hs @@ -153,8 +153,8 @@ wrapLine width = wrap 0 [] -- | Gets the contents of a file, but guarantee that it gets closed. -- --- The file is read lazily but if it is not fully consumed by the action then --- the remaining input is truncated and the file is closed. +-- The file is read lazily; if it is not fully consumed by the action then an +-- exception is thrown. withFileContents :: FilePath -> (String -> IO a) -> IO a withFileContents name action = withFile From d47be97d0e75e3c31e651215dabbaacb2e75bc09 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Mon, 30 Sep 2024 17:10:25 -0400 Subject: [PATCH 155/207] update changelog.d format and Matrix link (#10383) * update changelog.d format and Matrix link `changelog-d` was changed to make `packages` a list, so reflect this in the example. Also remove the "omit if it's an overarching change" part: we must list all packages if we want it to show up when generating release changelogs. While I was there, I updated the Matrix channel reference because it was still reflecting the EMS Libera bridge. * Update CONTRIBUTING.md Co-authored-by: Artem Pelenitsyn --------- Co-authored-by: Artem Pelenitsyn Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- CONTRIBUTING.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b2d7cc47ffe..18a4d64c5bd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -348,13 +348,32 @@ description: { } ``` +Changelogs may also be written in "markdown-frontmatter" format. This is useful if your +description contains braces, which must be escaped with backslashes in `.cabal` file +format. + +```markdown +--- +synopsis: Add feature xyz +packages: [cabal-install] +prs: #0000 +issues: #0000 #0000 +significance: significant +--- + +- Detail number 1 +- Detail number 2 + +``` +The package list must be enclosed in square brackets and comma-separated, but this isn't needed for `prs` or `issues`. + Only the `synopsis` and `prs` fields are required, but you should also set the others where applicable. | Field | Description | | ----- | ----------- | | `synopsis` | Brief description of the change. Often just the pr title. | | `description` | Longer description, with a list of sub-changes. Not needed for small/atomic changes. | -| `packages` | Packages affected by the change (`cabal-install`, `Cabal`...). Omit if it's an overarching or non-package change. | +| `packages` | Packages affected by the change (`cabal-install`, `Cabal`...). Omit if it's a non-package change. | | `prs` | Space-separated hash-prefixed pull request numbers containing the change (usually just one). | | `issues` | Space-separated hash-prefixed issue numbers that the change fixes/closes/affects. | | `significance` | Set to `significant` if the change is significant, that is if it warrants being put near the top of the changelog. | @@ -379,7 +398,7 @@ There are a few main venues of communication: * Many developers idle on `#hackage` on [`irc.libera.chat`](https://libera.chat). The `#ghc` channel is also a decently good bet. * You can join the channel using a web client, even anonymously: https://web.libera.chat/#hackage - * Alternatively you can join it using [matrix](https://matrix.org/): https://matrix.to/#/#hackage:libera.chat + * Alternatively you can join it using [matrix](https://matrix.org/): https://matrix.to/#/#hackage:matrix.org ## Releases From e35fd92549b7c9e82b5fbf7de8ea846e56a9287d Mon Sep 17 00:00:00 2001 From: Rodrigo Mesquita Date: Tue, 1 Oct 2024 16:18:24 +0100 Subject: [PATCH 156/207] Prefer ErrorCall to ErrorCallWithLocation This future proofs the code for CLC#285, which will remove `ErrorCallWithLocation` to de-duplicate duplicate CallStacks. ErrorCall is already a pattern synonym with the same meaning as it will have in the future, so this change is backwards compatible too. --- Cabal-syntax/src/Distribution/Compat/Binary.hs | 2 +- Cabal-syntax/src/Distribution/Utils/Structured.hs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cabal-syntax/src/Distribution/Compat/Binary.hs b/Cabal-syntax/src/Distribution/Compat/Binary.hs index 8849fc13b10..4927ec1e69b 100644 --- a/Cabal-syntax/src/Distribution/Compat/Binary.hs +++ b/Cabal-syntax/src/Distribution/Compat/Binary.hs @@ -20,4 +20,4 @@ decodeOrFailIO :: Binary a => ByteString -> IO (Either String a) decodeOrFailIO bs = catch (evaluate (decode bs) >>= return . Right) handler where - handler (ErrorCallWithLocation str _) = return $ Left str + handler (ErrorCall str) = return $ Left str diff --git a/Cabal-syntax/src/Distribution/Utils/Structured.hs b/Cabal-syntax/src/Distribution/Utils/Structured.hs index 83ae28995a8..ec8463bd6d3 100644 --- a/Cabal-syntax/src/Distribution/Utils/Structured.hs +++ b/Cabal-syntax/src/Distribution/Utils/Structured.hs @@ -277,7 +277,7 @@ structuredDecodeOrFailIO :: (Binary.Binary a, Structured a) => LBS.ByteString -> structuredDecodeOrFailIO bs = catch (evaluate (structuredDecode bs) >>= return . Right) handler where - handler (ErrorCallWithLocation str _) = return $ Left str + handler (ErrorCall str) = return $ Left str -- | Lazily reconstruct a value previously written to a file. structuredDecodeFileOrFail :: (Binary.Binary a, Structured a) => FilePath -> IO (Either String a) From 82a5b8d8bef1a8641aa091236a4d053718f5c398 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Wed, 4 Sep 2024 18:21:47 -0700 Subject: [PATCH 157/207] Improve assertions in `IntegrationTests2` `testConfigOptionComments` Before, failing asserts in this test would look like this: ``` Writing default configuration to /Users/wiggles/cabal/cabal-install/tests/IntegrationTests2/config/cabal-config/config Downloading the latest package list from hackage.haskell.org Package list of hackage.haskell.org has been updated. The index-state is set to 2024-09-04T15:12:07Z. Integration tests (internal) Flag tests Test Config options for commented options: FAIL tests/IntegrationTests2.hs:2015: expected: " urll" but got: " url" ``` The output includes a message that a configuration file has been written, but that's not the configuration file under test! The actual configuration file being tested is `cabal-install/tests/IntegrationTests2/config/default-config`, which shows up nowhere in the output. Now, the messages include the setting name being searched for and the path of the relevant configuration file: ``` Downloading the latest package list from hackage.haskell.org Package list of hackage.haskell.org has been updated. The index-state is set to 2024-09-04T22:53:05Z. Integration tests (internal) Flag tests Test Config options for commented options: FAIL tests/IntegrationTests2.hs:2015: Did not find expected line for setting "url" in configuration file /Users/wiggles/cabal/cabal-install/tests/IntegrationTests2/config/default-config expected: " urll" but got: " url" ``` The `Writing default configuration to...` message with the misleading path has also been silenced. --- cabal-install/tests/IntegrationTests2.hs | 480 +++++++++++++---------- 1 file changed, 262 insertions(+), 218 deletions(-) diff --git a/cabal-install/tests/IntegrationTests2.hs b/cabal-install/tests/IntegrationTests2.hs index e6373cd18b8..22c7da0c37f 100644 --- a/cabal-install/tests/IntegrationTests2.hs +++ b/cabal-install/tests/IntegrationTests2.hs @@ -103,7 +103,9 @@ main = do removeDirectoryRecursive configDir <|> return () createDirectoryIfMissing True configDir -- sigh - callProcess "cabal" ["user-config", "init", "-f"] + -- NOTE: This is running the `cabal` from the user environment, which is + -- generally not the `cabal` being tested! + callProcess "cabal" ["-v0", "user-config", "init", "-f"] callProcess "cabal" ["update"] defaultMainWithIngredients (defaultIngredients ++ [includingOptions projectConfigOptionDescriptions]) @@ -1982,230 +1984,272 @@ testNixFlags = do -- Tests whether config options are commented or not testConfigOptionComments :: Assertion testConfigOptionComments = do - _ <- createDefaultConfigFile verbosity [] (basedir "config" "default-config") - defaultConfigFile <- readFile (basedir "config" "default-config") - - " url" @=? findLineWith False "url" defaultConfigFile - " -- secure" @=? findLineWith True "secure" defaultConfigFile - " -- root-keys" @=? findLineWith True "root-keys" defaultConfigFile - " -- key-threshold" @=? findLineWith True "key-threshold" defaultConfigFile - - "-- ignore-expiry" @=? findLineWith True "ignore-expiry" defaultConfigFile - "-- http-transport" @=? findLineWith True "http-transport" defaultConfigFile - "-- nix" @=? findLineWith True "nix" defaultConfigFile - "-- store-dir" @=? findLineWith True "store-dir" defaultConfigFile - "-- active-repositories" @=? findLineWith True "active-repositories" defaultConfigFile - "-- local-no-index-repo" @=? findLineWith True "local-no-index-repo" defaultConfigFile - "remote-repo-cache" @=? findLineWith False "remote-repo-cache" defaultConfigFile - "-- logs-dir" @=? findLineWith True "logs-dir" defaultConfigFile - "-- default-user-config" @=? findLineWith True "default-user-config" defaultConfigFile - "-- verbose" @=? findLineWith True "verbose" defaultConfigFile - "-- compiler" @=? findLineWith True "compiler" defaultConfigFile - "-- cabal-file" @=? findLineWith True "cabal-file" defaultConfigFile - "-- with-compiler" @=? findLineWith True "with-compiler" defaultConfigFile - "-- with-hc-pkg" @=? findLineWith True "with-hc-pkg" defaultConfigFile - "-- program-prefix" @=? findLineWith True "program-prefix" defaultConfigFile - "-- program-suffix" @=? findLineWith True "program-suffix" defaultConfigFile - "-- library-vanilla" @=? findLineWith True "library-vanilla" defaultConfigFile - "-- library-profiling" @=? findLineWith True "library-profiling" defaultConfigFile - "-- shared" @=? findLineWith True "shared" defaultConfigFile - "-- static" @=? findLineWith True "static" defaultConfigFile - "-- executable-dynamic" @=? findLineWith True "executable-dynamic" defaultConfigFile - "-- executable-static" @=? findLineWith True "executable-static" defaultConfigFile - "-- profiling" @=? findLineWith True "profiling" defaultConfigFile - "-- executable-profiling" @=? findLineWith True "executable-profiling" defaultConfigFile - "-- profiling-detail" @=? findLineWith True "profiling-detail" defaultConfigFile - "-- library-profiling-detail" @=? findLineWith True "library-profiling-detail" defaultConfigFile - "-- optimization" @=? findLineWith True "optimization" defaultConfigFile - "-- debug-info" @=? findLineWith True "debug-info" defaultConfigFile - "-- build-info" @=? findLineWith True "build-info" defaultConfigFile - "-- library-for-ghci" @=? findLineWith True "library-for-ghci" defaultConfigFile - "-- split-sections" @=? findLineWith True "split-sections" defaultConfigFile - "-- split-objs" @=? findLineWith True "split-objs" defaultConfigFile - "-- executable-stripping" @=? findLineWith True "executable-stripping" defaultConfigFile - "-- library-stripping" @=? findLineWith True "library-stripping" defaultConfigFile - "-- configure-option" @=? findLineWith True "configure-option" defaultConfigFile - "-- user-install" @=? findLineWith True "user-install" defaultConfigFile - "-- package-db" @=? findLineWith True "package-db" defaultConfigFile - "-- flags" @=? findLineWith True "flags" defaultConfigFile - "-- extra-include-dirs" @=? findLineWith True "extra-include-dirs" defaultConfigFile - "-- deterministic" @=? findLineWith True "deterministic" defaultConfigFile - "-- cid" @=? findLineWith True "cid" defaultConfigFile - "-- extra-lib-dirs" @=? findLineWith True "extra-lib-dirs" defaultConfigFile - "-- extra-lib-dirs-static" @=? findLineWith True "extra-lib-dirs-static" defaultConfigFile - "-- extra-framework-dirs" @=? findLineWith True "extra-framework-dirs" defaultConfigFile - "-- extra-prog-path" @=? findLineWith False "extra-prog-path" defaultConfigFile - "-- instantiate-with" @=? findLineWith True "instantiate-with" defaultConfigFile - "-- tests" @=? findLineWith True "tests" defaultConfigFile - "-- coverage" @=? findLineWith True "coverage" defaultConfigFile - "-- library-coverage" @=? findLineWith True "library-coverage" defaultConfigFile - "-- exact-configuration" @=? findLineWith True "exact-configuration" defaultConfigFile - "-- benchmarks" @=? findLineWith True "benchmarks" defaultConfigFile - "-- relocatable" @=? findLineWith True "relocatable" defaultConfigFile - "-- response-files" @=? findLineWith True "response-files" defaultConfigFile - "-- allow-depending-on-private-libs" @=? findLineWith True "allow-depending-on-private-libs" defaultConfigFile - "-- cabal-lib-version" @=? findLineWith True "cabal-lib-version" defaultConfigFile - "-- append" @=? findLineWith True "append" defaultConfigFile - "-- backup" @=? findLineWith True "backup" defaultConfigFile - "-- constraint" @=? findLineWith True "constraint" defaultConfigFile - "-- preference" @=? findLineWith True "preference" defaultConfigFile - "-- solver" @=? findLineWith True "solver" defaultConfigFile - "-- allow-older" @=? findLineWith True "allow-older" defaultConfigFile - "-- allow-newer" @=? findLineWith True "allow-newer" defaultConfigFile - "-- write-ghc-environment-files" @=? findLineWith True "write-ghc-environment-files" defaultConfigFile - "-- documentation" @=? findLineWith True "documentation" defaultConfigFile - "-- doc-index-file" @=? findLineWith True "doc-index-file" defaultConfigFile - "-- only-download" @=? findLineWith True "only-download" defaultConfigFile - "-- target-package-db" @=? findLineWith True "target-package-db" defaultConfigFile - "-- max-backjumps" @=? findLineWith True "max-backjumps" defaultConfigFile - "-- reorder-goals" @=? findLineWith True "reorder-goals" defaultConfigFile - "-- count-conflicts" @=? findLineWith True "count-conflicts" defaultConfigFile - "-- fine-grained-conflicts" @=? findLineWith True "fine-grained-conflicts" defaultConfigFile - "-- minimize-conflict-set" @=? findLineWith True "minimize-conflict-set" defaultConfigFile - "-- independent-goals" @=? findLineWith True "independent-goals" defaultConfigFile - "-- prefer-oldest" @=? findLineWith True "prefer-oldest" defaultConfigFile - "-- shadow-installed-packages" @=? findLineWith True "shadow-installed-packages" defaultConfigFile - "-- strong-flags" @=? findLineWith True "strong-flags" defaultConfigFile - "-- allow-boot-library-installs" @=? findLineWith True "allow-boot-library-installs" defaultConfigFile - "-- reject-unconstrained-dependencies" @=? findLineWith True "reject-unconstrained-dependencies" defaultConfigFile - "-- reinstall" @=? findLineWith True "reinstall" defaultConfigFile - "-- avoid-reinstalls" @=? findLineWith True "avoid-reinstalls" defaultConfigFile - "-- force-reinstalls" @=? findLineWith True "force-reinstalls" defaultConfigFile - "-- upgrade-dependencies" @=? findLineWith True "upgrade-dependencies" defaultConfigFile - "-- index-state" @=? findLineWith True "index-state" defaultConfigFile - "-- root-cmd" @=? findLineWith True "root-cmd" defaultConfigFile - "-- symlink-bindir" @=? findLineWith True "symlink-bindir" defaultConfigFile - "build-summary" @=? findLineWith False "build-summary" defaultConfigFile - "-- build-log" @=? findLineWith True "build-log" defaultConfigFile - "remote-build-reporting" @=? findLineWith False "remote-build-reporting" defaultConfigFile - "-- report-planning-failure" @=? findLineWith True "report-planning-failure" defaultConfigFile - "-- per-component" @=? findLineWith True "per-component" defaultConfigFile - "-- run-tests" @=? findLineWith True "run-tests" defaultConfigFile - "jobs" @=? findLineWith False "jobs" defaultConfigFile - "-- keep-going" @=? findLineWith True "keep-going" defaultConfigFile - "-- offline" @=? findLineWith True "offline" defaultConfigFile - "-- lib" @=? findLineWith True "lib" defaultConfigFile - "-- package-env" @=? findLineWith True "package-env" defaultConfigFile - "-- overwrite-policy" @=? findLineWith True "overwrite-policy" defaultConfigFile - "-- install-method" @=? findLineWith True "install-method" defaultConfigFile - "installdir" @=? findLineWith False "installdir" defaultConfigFile - "-- token" @=? findLineWith True "token" defaultConfigFile - "-- username" @=? findLineWith True "username" defaultConfigFile - "-- password" @=? findLineWith True "password" defaultConfigFile - "-- password-command" @=? findLineWith True "password-command" defaultConfigFile - "-- builddir" @=? findLineWith True "builddir" defaultConfigFile - - " -- keep-temp-files" @=? findLineWith True "keep-temp-files" defaultConfigFile - " -- hoogle" @=? findLineWith True "hoogle" defaultConfigFile - " -- html" @=? findLineWith True "html" defaultConfigFile - " -- html-location" @=? findLineWith True "html-location" defaultConfigFile - " -- executables" @=? findLineWith True "executables" defaultConfigFile - " -- foreign-libraries" @=? findLineWith True "foreign-libraries" defaultConfigFile - " -- all" @=? findLineWith True "all" defaultConfigFile - " -- internal" @=? findLineWith True "internal" defaultConfigFile - " -- css" @=? findLineWith True "css" defaultConfigFile - " -- hyperlink-source" @=? findLineWith True "hyperlink-source" defaultConfigFile - " -- quickjump" @=? findLineWith True "quickjump" defaultConfigFile - " -- hscolour-css" @=? findLineWith True "hscolour-css" defaultConfigFile - " -- contents-location" @=? findLineWith True "contents-location" defaultConfigFile - " -- index-location" @=? findLineWith True "index-location" defaultConfigFile - " -- base-url" @=? findLineWith True "base-url" defaultConfigFile - " -- resources-dir" @=? findLineWith True "resources-dir" defaultConfigFile - " -- output-dir" @=? findLineWith True "output-dir" defaultConfigFile - " -- use-unicode" @=? findLineWith True "use-unicode" defaultConfigFile - - " -- interactive" @=? findLineWith True "interactive" defaultConfigFile - " -- quiet" @=? findLineWith True "quiet" defaultConfigFile - " -- no-comments" @=? findLineWith True "no-comments" defaultConfigFile - " -- minimal" @=? findLineWith True "minimal" defaultConfigFile - " -- cabal-version" @=? findLineWith True "cabal-version" defaultConfigFile - " -- license" @=? findLineWith True "license" defaultConfigFile - " -- extra-doc-file" @=? findLineWith True "extra-doc-file" defaultConfigFile - " -- test-dir" @=? findLineWith True "test-dir" defaultConfigFile - " -- simple" @=? findLineWith True "simple" defaultConfigFile - " -- language" @=? findLineWith True "language" defaultConfigFile - " -- application-dir" @=? findLineWith True "application-dir" defaultConfigFile - " -- source-dir" @=? findLineWith True "source-dir" defaultConfigFile - - " -- prefix" @=? findLineWith True "prefix" defaultConfigFile - " -- bindir"@=? findLineWith True "bindir" defaultConfigFile - " -- libdir" @=? findLineWith True "libdir" defaultConfigFile - " -- libsubdir" @=? findLineWith True "libsubdir" defaultConfigFile - " -- dynlibdir" @=? findLineWith True "dynlibdir" defaultConfigFile - " -- libexecdir" @=? findLineWith True "libexecdir" defaultConfigFile - " -- libexecsubdir" @=? findLineWith True "libexecsubdir" defaultConfigFile - " -- datadir" @=? findLineWith True "datadir" defaultConfigFile - " -- datasubdir" @=? findLineWith True "datasubdir" defaultConfigFile - " -- docdir" @=? findLineWith True "docdir" defaultConfigFile - " -- htmldir" @=? findLineWith True "htmldir" defaultConfigFile - " -- haddockdir" @=? findLineWith True "haddockdir" defaultConfigFile - " -- sysconfdir" @=? findLineWith True "sysconfdir" defaultConfigFile - - " -- alex-location" @=? findLineWith True "alex-location" defaultConfigFile - " -- ar-location" @=? findLineWith True "ar-location" defaultConfigFile - " -- c2hs-location" @=? findLineWith True "c2hs-location" defaultConfigFile - " -- cpphs-location" @=? findLineWith True "cpphs-location" defaultConfigFile - " -- doctest-location" @=? findLineWith True "doctest-location" defaultConfigFile - " -- gcc-location" @=? findLineWith True "gcc-location" defaultConfigFile - " -- ghc-location" @=? findLineWith True "ghc-location" defaultConfigFile - " -- ghc-pkg-location" @=? findLineWith True "ghc-pkg-location" defaultConfigFile - " -- ghcjs-location" @=? findLineWith True "ghcjs-location" defaultConfigFile - " -- ghcjs-pkg-location" @=? findLineWith True "ghcjs-pkg-location" defaultConfigFile - " -- greencard-location" @=? findLineWith True "greencard-location" defaultConfigFile - " -- haddock-location" @=? findLineWith True "haddock-location" defaultConfigFile - " -- happy-location" @=? findLineWith True "happy-location" defaultConfigFile - " -- haskell-suite-location" @=? findLineWith True "haskell-suite-location" defaultConfigFile - " -- haskell-suite-pkg-location" @=? findLineWith True "haskell-suite-pkg-location" defaultConfigFile - " -- hmake-location" @=? findLineWith True "hmake-location" defaultConfigFile - " -- hpc-location" @=? findLineWith True "hpc-location" defaultConfigFile - " -- hscolour-location" @=? findLineWith True "hscolour-location" defaultConfigFile - " -- jhc-location" @=? findLineWith True "jhc-location" defaultConfigFile - " -- ld-location" @=? findLineWith True "ld-location" defaultConfigFile - " -- pkg-config-location" @=? findLineWith True "pkg-config-location" defaultConfigFile - " -- runghc-location" @=? findLineWith True "runghc-location" defaultConfigFile - " -- strip-location" @=? findLineWith True "strip-location" defaultConfigFile - " -- tar-location" @=? findLineWith True "tar-location" defaultConfigFile - " -- uhc-location" @=? findLineWith True "uhc-location" defaultConfigFile - - " -- alex-options" @=? findLineWith True "alex-options" defaultConfigFile - " -- ar-options" @=? findLineWith True "ar-options" defaultConfigFile - " -- c2hs-options" @=? findLineWith True "c2hs-options" defaultConfigFile - " -- cpphs-options" @=? findLineWith True "cpphs-options" defaultConfigFile - " -- doctest-options" @=? findLineWith True "doctest-options" defaultConfigFile - " -- gcc-options" @=? findLineWith True "gcc-options" defaultConfigFile - " -- ghc-options" @=? findLineWith True "ghc-options" defaultConfigFile - " -- ghc-pkg-options" @=? findLineWith True "ghc-pkg-options" defaultConfigFile - " -- ghcjs-options" @=? findLineWith True "ghcjs-options" defaultConfigFile - " -- ghcjs-pkg-options" @=? findLineWith True "ghcjs-pkg-options" defaultConfigFile - " -- greencard-options" @=? findLineWith True "greencard-options" defaultConfigFile - " -- haddock-options" @=? findLineWith True "haddock-options" defaultConfigFile - " -- happy-options" @=? findLineWith True "happy-options" defaultConfigFile - " -- haskell-suite-options" @=? findLineWith True "haskell-suite-options" defaultConfigFile - " -- haskell-suite-pkg-options" @=? findLineWith True "haskell-suite-pkg-options" defaultConfigFile - " -- hmake-options" @=? findLineWith True "hmake-options" defaultConfigFile - " -- hpc-options" @=? findLineWith True "hpc-options" defaultConfigFile - " -- hsc2hs-options" @=? findLineWith True "hsc2hs-options" defaultConfigFile - " -- hscolour-options" @=? findLineWith True "hscolour-options" defaultConfigFile - " -- jhc-options" @=? findLineWith True "jhc-options" defaultConfigFile - " -- ld-options" @=? findLineWith True "ld-options" defaultConfigFile - " -- pkg-config-options" @=? findLineWith True "pkg-config-options" defaultConfigFile - " -- runghc-options" @=? findLineWith True "runghc-options" defaultConfigFile - " -- strip-options" @=? findLineWith True "strip-options" defaultConfigFile - " -- tar-options" @=? findLineWith True "tar-options" defaultConfigFile - " -- uhc-options" @=? findLineWith True "uhc-options" defaultConfigFile - where - -- | Find lines containing a target string. + let + -- | Find the first line containing a target setting name. + -- + -- If `isComment` is set, only comment lines will be found. findLineWith :: Bool -> String -> String -> String findLineWith isComment target text = case findLinesWith isComment target text of [] -> text - (l : _) -> removeCommentValue l + (l : _) -> removeColonAndAfter l + + -- | Find lines containing a target setting name. findLinesWith :: Bool -> String -> String -> [String] findLinesWith isComment target - | isComment = filter (isInfixOf (" " ++ target ++ ":")) . lines + | isComment = filter (isInfixOf ("-- " ++ target ++ ":")) . lines | otherwise = filter (isInfixOf (target ++ ":")) . lines - removeCommentValue :: String -> String - removeCommentValue = takeWhile (/= ':') + + -- | Transform @-- puppy: doggy@ into @-- puppy@. + removeColonAndAfter :: String -> String + removeColonAndAfter = takeWhile (/= ':') + + cwd <- getCurrentDirectory + let configFile = cwd basedir "config" "default-config" + _ <- createDefaultConfigFile verbosity [] configFile + defaultConfigFile <- readFile configFile + + let + -- TODO: These assertions are fairly weak. Potential improvements: + -- + -- - Include the section name in the assertion, so that (e.g.) a + -- `keep-temp-files` setting in the `haddock` section won't be confused + -- with a `keep-temp-files` setting in the `init` section. + -- + -- - Check all matching lines to confirm that settings are not listed + -- multiple times. For example, `cabal-file` is listed twice right now, + -- once under the `haddock` settings! + -- + -- - Consume the file as we go, ensuring that the settings are in a given + -- order. + -- + -- - Check the generated config file into Git (replacing e.g. `$HOME` with + -- a sentinel value) so changes show up in PR diffs. + assertHasLine' :: Bool -> String -> String -> Assertion + assertHasLine' isComment expected settingName = + let actual = findLineWith isComment settingName defaultConfigFile + messagePrefix = + "Did not find expected line for setting " + <> show settingName + <> " in configuration file " + <> configFile + in assertEqual messagePrefix expected actual + + assertHasLine :: String -> String -> Assertion + assertHasLine = assertHasLine' False + + assertHasCommentLine :: String -> String -> Assertion + assertHasCommentLine = assertHasLine' True + + + " url" `assertHasLine` "url" + " -- secure" `assertHasCommentLine` "secure" + " -- root-keys" `assertHasCommentLine` "root-keys" + " -- key-threshold" `assertHasCommentLine` "key-threshold" + + "-- ignore-expiry" `assertHasCommentLine` "ignore-expiry" + "-- http-transport" `assertHasCommentLine` "http-transport" + "-- nix" `assertHasCommentLine` "nix" + "-- store-dir" `assertHasCommentLine` "store-dir" + "-- active-repositories" `assertHasCommentLine` "active-repositories" + "-- local-no-index-repo" `assertHasCommentLine` "local-no-index-repo" + "remote-repo-cache" `assertHasLine` "remote-repo-cache" + "-- logs-dir" `assertHasCommentLine` "logs-dir" + "-- default-user-config" `assertHasCommentLine` "default-user-config" + "-- verbose" `assertHasCommentLine` "verbose" + "-- compiler" `assertHasCommentLine` "compiler" + "-- cabal-file" `assertHasCommentLine` "cabal-file" + "-- with-compiler" `assertHasCommentLine` "with-compiler" + "-- with-hc-pkg" `assertHasCommentLine` "with-hc-pkg" + "-- program-prefix" `assertHasCommentLine` "program-prefix" + "-- program-suffix" `assertHasCommentLine` "program-suffix" + "-- library-vanilla" `assertHasCommentLine` "library-vanilla" + "-- library-profiling" `assertHasCommentLine` "library-profiling" + "-- shared" `assertHasCommentLine` "shared" + "-- static" `assertHasCommentLine` "static" + "-- executable-dynamic" `assertHasCommentLine` "executable-dynamic" + "-- executable-static" `assertHasCommentLine` "executable-static" + "-- profiling" `assertHasCommentLine` "profiling" + "-- executable-profiling" `assertHasCommentLine` "executable-profiling" + "-- profiling-detail" `assertHasCommentLine` "profiling-detail" + "-- library-profiling-detail" `assertHasCommentLine` "library-profiling-detail" + "-- optimization" `assertHasCommentLine` "optimization" + "-- debug-info" `assertHasCommentLine` "debug-info" + "-- build-info" `assertHasCommentLine` "build-info" + "-- library-for-ghci" `assertHasCommentLine` "library-for-ghci" + "-- split-sections" `assertHasCommentLine` "split-sections" + "-- split-objs" `assertHasCommentLine` "split-objs" + "-- executable-stripping" `assertHasCommentLine` "executable-stripping" + "-- library-stripping" `assertHasCommentLine` "library-stripping" + "-- configure-option" `assertHasCommentLine` "configure-option" + "-- user-install" `assertHasCommentLine` "user-install" + "-- package-db" `assertHasCommentLine` "package-db" + "-- flags" `assertHasCommentLine` "flags" + "-- extra-include-dirs" `assertHasCommentLine` "extra-include-dirs" + "-- deterministic" `assertHasCommentLine` "deterministic" + "-- cid" `assertHasCommentLine` "cid" + "-- extra-lib-dirs" `assertHasCommentLine` "extra-lib-dirs" + "-- extra-lib-dirs-static" `assertHasCommentLine` "extra-lib-dirs-static" + "-- extra-framework-dirs" `assertHasCommentLine` "extra-framework-dirs" + "-- extra-prog-path" `assertHasLine` "extra-prog-path" + "-- instantiate-with" `assertHasCommentLine` "instantiate-with" + "-- tests" `assertHasCommentLine` "tests" + "-- coverage" `assertHasCommentLine` "coverage" + "-- library-coverage" `assertHasCommentLine` "library-coverage" + "-- exact-configuration" `assertHasCommentLine` "exact-configuration" + "-- benchmarks" `assertHasCommentLine` "benchmarks" + "-- relocatable" `assertHasCommentLine` "relocatable" + "-- response-files" `assertHasCommentLine` "response-files" + "-- allow-depending-on-private-libs" `assertHasCommentLine` "allow-depending-on-private-libs" + "-- cabal-lib-version" `assertHasCommentLine` "cabal-lib-version" + "-- append" `assertHasCommentLine` "append" + "-- backup" `assertHasCommentLine` "backup" + "-- constraint" `assertHasCommentLine` "constraint" + "-- preference" `assertHasCommentLine` "preference" + "-- solver" `assertHasCommentLine` "solver" + "-- allow-older" `assertHasCommentLine` "allow-older" + "-- allow-newer" `assertHasCommentLine` "allow-newer" + "-- write-ghc-environment-files" `assertHasCommentLine` "write-ghc-environment-files" + "-- documentation" `assertHasCommentLine` "documentation" + "-- doc-index-file" `assertHasCommentLine` "doc-index-file" + "-- only-download" `assertHasCommentLine` "only-download" + "-- target-package-db" `assertHasCommentLine` "target-package-db" + "-- max-backjumps" `assertHasCommentLine` "max-backjumps" + "-- reorder-goals" `assertHasCommentLine` "reorder-goals" + "-- count-conflicts" `assertHasCommentLine` "count-conflicts" + "-- fine-grained-conflicts" `assertHasCommentLine` "fine-grained-conflicts" + "-- minimize-conflict-set" `assertHasCommentLine` "minimize-conflict-set" + "-- independent-goals" `assertHasCommentLine` "independent-goals" + "-- prefer-oldest" `assertHasCommentLine` "prefer-oldest" + "-- shadow-installed-packages" `assertHasCommentLine` "shadow-installed-packages" + "-- strong-flags" `assertHasCommentLine` "strong-flags" + "-- allow-boot-library-installs" `assertHasCommentLine` "allow-boot-library-installs" + "-- reject-unconstrained-dependencies" `assertHasCommentLine` "reject-unconstrained-dependencies" + "-- reinstall" `assertHasCommentLine` "reinstall" + "-- avoid-reinstalls" `assertHasCommentLine` "avoid-reinstalls" + "-- force-reinstalls" `assertHasCommentLine` "force-reinstalls" + "-- upgrade-dependencies" `assertHasCommentLine` "upgrade-dependencies" + "-- index-state" `assertHasCommentLine` "index-state" + "-- root-cmd" `assertHasCommentLine` "root-cmd" + "-- symlink-bindir" `assertHasCommentLine` "symlink-bindir" + "build-summary" `assertHasLine` "build-summary" + "-- build-log" `assertHasCommentLine` "build-log" + "remote-build-reporting" `assertHasLine` "remote-build-reporting" + "-- report-planning-failure" `assertHasCommentLine` "report-planning-failure" + "-- per-component" `assertHasCommentLine` "per-component" + "-- run-tests" `assertHasCommentLine` "run-tests" + "jobs" `assertHasLine` "jobs" + "-- keep-going" `assertHasCommentLine` "keep-going" + "-- offline" `assertHasCommentLine` "offline" + "-- lib" `assertHasCommentLine` "lib" + "-- package-env" `assertHasCommentLine` "package-env" + "-- overwrite-policy" `assertHasCommentLine` "overwrite-policy" + "-- install-method" `assertHasCommentLine` "install-method" + "installdir" `assertHasLine` "installdir" + "-- token" `assertHasCommentLine` "token" + "-- username" `assertHasCommentLine` "username" + "-- password" `assertHasCommentLine` "password" + "-- password-command" `assertHasCommentLine` "password-command" + "-- builddir" `assertHasCommentLine` "builddir" + + " -- keep-temp-files" `assertHasCommentLine` "keep-temp-files" + " -- hoogle" `assertHasCommentLine` "hoogle" + " -- html" `assertHasCommentLine` "html" + " -- html-location" `assertHasCommentLine` "html-location" + " -- executables" `assertHasCommentLine` "executables" + " -- foreign-libraries" `assertHasCommentLine` "foreign-libraries" + " -- all" `assertHasCommentLine` "all" + " -- internal" `assertHasCommentLine` "internal" + " -- css" `assertHasCommentLine` "css" + " -- hyperlink-source" `assertHasCommentLine` "hyperlink-source" + " -- quickjump" `assertHasCommentLine` "quickjump" + " -- hscolour-css" `assertHasCommentLine` "hscolour-css" + " -- contents-location" `assertHasCommentLine` "contents-location" + " -- index-location" `assertHasCommentLine` "index-location" + " -- base-url" `assertHasCommentLine` "base-url" + " -- resources-dir" `assertHasCommentLine` "resources-dir" + " -- output-dir" `assertHasCommentLine` "output-dir" + " -- use-unicode" `assertHasCommentLine` "use-unicode" + + " -- interactive" `assertHasCommentLine` "interactive" + " -- quiet" `assertHasCommentLine` "quiet" + " -- no-comments" `assertHasCommentLine` "no-comments" + " -- minimal" `assertHasCommentLine` "minimal" + " -- cabal-version" `assertHasCommentLine` "cabal-version" + " -- license" `assertHasCommentLine` "license" + " -- extra-doc-file" `assertHasCommentLine` "extra-doc-file" + " -- test-dir" `assertHasCommentLine` "test-dir" + " -- simple" `assertHasCommentLine` "simple" + " -- language" `assertHasCommentLine` "language" + " -- application-dir" `assertHasCommentLine` "application-dir" + " -- source-dir" `assertHasCommentLine` "source-dir" + + " -- prefix" `assertHasCommentLine` "prefix" + " -- bindir" `assertHasCommentLine` "bindir" + " -- libdir" `assertHasCommentLine` "libdir" + " -- libsubdir" `assertHasCommentLine` "libsubdir" + " -- dynlibdir" `assertHasCommentLine` "dynlibdir" + " -- libexecdir" `assertHasCommentLine` "libexecdir" + " -- libexecsubdir" `assertHasCommentLine` "libexecsubdir" + " -- datadir" `assertHasCommentLine` "datadir" + " -- datasubdir" `assertHasCommentLine` "datasubdir" + " -- docdir" `assertHasCommentLine` "docdir" + " -- htmldir" `assertHasCommentLine` "htmldir" + " -- haddockdir" `assertHasCommentLine` "haddockdir" + " -- sysconfdir" `assertHasCommentLine` "sysconfdir" + + " -- alex-location" `assertHasCommentLine` "alex-location" + " -- ar-location" `assertHasCommentLine` "ar-location" + " -- c2hs-location" `assertHasCommentLine` "c2hs-location" + " -- cpphs-location" `assertHasCommentLine` "cpphs-location" + " -- doctest-location" `assertHasCommentLine` "doctest-location" + " -- gcc-location" `assertHasCommentLine` "gcc-location" + " -- ghc-location" `assertHasCommentLine` "ghc-location" + " -- ghc-pkg-location" `assertHasCommentLine` "ghc-pkg-location" + " -- ghcjs-location" `assertHasCommentLine` "ghcjs-location" + " -- ghcjs-pkg-location" `assertHasCommentLine` "ghcjs-pkg-location" + " -- greencard-location" `assertHasCommentLine` "greencard-location" + " -- haddock-location" `assertHasCommentLine` "haddock-location" + " -- happy-location" `assertHasCommentLine` "happy-location" + " -- haskell-suite-location" `assertHasCommentLine` "haskell-suite-location" + " -- haskell-suite-pkg-location" `assertHasCommentLine` "haskell-suite-pkg-location" + " -- hmake-location" `assertHasCommentLine` "hmake-location" + " -- hpc-location" `assertHasCommentLine` "hpc-location" + " -- hscolour-location" `assertHasCommentLine` "hscolour-location" + " -- jhc-location" `assertHasCommentLine` "jhc-location" + " -- ld-location" `assertHasCommentLine` "ld-location" + " -- pkg-config-location" `assertHasCommentLine` "pkg-config-location" + " -- runghc-location" `assertHasCommentLine` "runghc-location" + " -- strip-location" `assertHasCommentLine` "strip-location" + " -- tar-location" `assertHasCommentLine` "tar-location" + " -- uhc-location" `assertHasCommentLine` "uhc-location" + + " -- alex-options" `assertHasCommentLine` "alex-options" + " -- ar-options" `assertHasCommentLine` "ar-options" + " -- c2hs-options" `assertHasCommentLine` "c2hs-options" + " -- cpphs-options" `assertHasCommentLine` "cpphs-options" + " -- doctest-options" `assertHasCommentLine` "doctest-options" + " -- gcc-options" `assertHasCommentLine` "gcc-options" + " -- ghc-options" `assertHasCommentLine` "ghc-options" + " -- ghc-pkg-options" `assertHasCommentLine` "ghc-pkg-options" + " -- ghcjs-options" `assertHasCommentLine` "ghcjs-options" + " -- ghcjs-pkg-options" `assertHasCommentLine` "ghcjs-pkg-options" + " -- greencard-options" `assertHasCommentLine` "greencard-options" + " -- haddock-options" `assertHasCommentLine` "haddock-options" + " -- happy-options" `assertHasCommentLine` "happy-options" + " -- haskell-suite-options" `assertHasCommentLine` "haskell-suite-options" + " -- haskell-suite-pkg-options" `assertHasCommentLine` "haskell-suite-pkg-options" + " -- hmake-options" `assertHasCommentLine` "hmake-options" + " -- hpc-options" `assertHasCommentLine` "hpc-options" + " -- hsc2hs-options" `assertHasCommentLine` "hsc2hs-options" + " -- hscolour-options" `assertHasCommentLine` "hscolour-options" + " -- jhc-options" `assertHasCommentLine` "jhc-options" + " -- ld-options" `assertHasCommentLine` "ld-options" + " -- pkg-config-options" `assertHasCommentLine` "pkg-config-options" + " -- runghc-options" `assertHasCommentLine` "runghc-options" + " -- strip-options" `assertHasCommentLine` "strip-options" + " -- tar-options" `assertHasCommentLine` "tar-options" + " -- uhc-options" `assertHasCommentLine` "uhc-options" testIgnoreProjectFlag :: Assertion testIgnoreProjectFlag = do From b32ebf9fb9913495d9d942083c01e621c9324cf5 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 23 Sep 2024 12:21:36 -0700 Subject: [PATCH 158/207] Show installed versions when configuring fails When `act-as-setup configure` fails, it doesn't indicate which dependencies are missing entirely and which ones don't satisfy the version constraints. The errors from `cabal build` are more informative, but aren't available in all contexts (nixpkgs Haskell builds, for example, use the `act-as-setup` interface). This makes it immediately clear what sort of dependency error has occurred. Before (cabal-install 3.12.1.0): Configuring test-pkg-0.1.0.0... Error: [Cabal-8010] Encountered missing or private dependencies: base <=4.18, foobar, test-pkg:{bar-internal, foo-internal} After: Configuring test-pkg-0.1.0.0... Error: [Cabal-8010] Encountered missing or private dependencies: base <=4.18 (installed: 4.19.1.0), foobar (missing), test-pkg:{bar-internal,foo-internal} (missing: :bar-internal) --- Cabal-syntax/Cabal-syntax.cabal | 3 + .../src/Distribution/Compat/NonEmptySet.hs | 4 ++ .../PackageDescription/Configuration.hs | 62 +++++++---------- Cabal-syntax/src/Distribution/Pretty.hs | 10 +++ .../src/Distribution/Types/Dependency.hs | 16 +---- .../Types/DependencySatisfaction.hs | 14 ++++ .../src/Distribution/Types/LibraryName.hs | 18 +++++ .../Distribution/Types/MissingDependency.hs | 34 +++++++++ .../Types/MissingDependencyReason.hs | 25 +++++++ .../ParserTests/regressions/issue-5846.format | 4 +- Cabal/Cabal.cabal | 3 + Cabal/src/Distribution/Simple/Configure.hs | 49 +++++++++---- Cabal/src/Distribution/Simple/Errors.hs | 5 +- Cabal/src/Distribution/Simple/PackageIndex.hs | 69 +++++++++++++++---- .../src/Distribution/Client/CmdOutdated.hs | 5 +- .../src/Distribution/Client/Configure.hs | 5 +- .../src/Distribution/Client/Dependency.hs | 5 +- .../src/Distribution/Client/GenBounds.hs | 5 +- .../src/Distribution/Client/Install.hs | 5 +- .../src/Distribution/Client/InstallSymlink.hs | 5 +- .../Distribution/Client/ProjectPlanning.hs | 5 +- .../SubLib/setup-explicit-fail.out | 2 +- 22 files changed, 260 insertions(+), 93 deletions(-) create mode 100644 Cabal-syntax/src/Distribution/Types/DependencySatisfaction.hs create mode 100644 Cabal-syntax/src/Distribution/Types/MissingDependency.hs create mode 100644 Cabal-syntax/src/Distribution/Types/MissingDependencyReason.hs diff --git a/Cabal-syntax/Cabal-syntax.cabal b/Cabal-syntax/Cabal-syntax.cabal index 0893f4f2588..42fb7f7d51e 100644 --- a/Cabal-syntax/Cabal-syntax.cabal +++ b/Cabal-syntax/Cabal-syntax.cabal @@ -135,6 +135,7 @@ library Distribution.Types.ConfVar Distribution.Types.Dependency Distribution.Types.DependencyMap + Distribution.Types.DependencySatisfaction Distribution.Types.ExeDependency Distribution.Types.Executable Distribution.Types.Executable.Lens @@ -158,6 +159,8 @@ library Distribution.Types.Library.Lens Distribution.Types.LibraryName Distribution.Types.LibraryVisibility + Distribution.Types.MissingDependency + Distribution.Types.MissingDependencyReason Distribution.Types.Mixin Distribution.Types.Module Distribution.Types.ModuleReexport diff --git a/Cabal-syntax/src/Distribution/Compat/NonEmptySet.hs b/Cabal-syntax/src/Distribution/Compat/NonEmptySet.hs index 17e3811e9a4..9e227459e84 100644 --- a/Cabal-syntax/src/Distribution/Compat/NonEmptySet.hs +++ b/Cabal-syntax/src/Distribution/Compat/NonEmptySet.hs @@ -12,6 +12,7 @@ module Distribution.Compat.NonEmptySet -- * Deletion , delete + , filter -- * Conversions , toNonEmpty @@ -116,6 +117,9 @@ delete x (NES xs) where res = Set.delete x xs +filter :: (a -> Bool) -> NonEmptySet a -> Set.Set a +filter predicate (NES set) = Set.filter predicate set + ------------------------------------------------------------------------------- -- Conversions ------------------------------------------------------------------------------- diff --git a/Cabal-syntax/src/Distribution/PackageDescription/Configuration.hs b/Cabal-syntax/src/Distribution/PackageDescription/Configuration.hs index e811c361221..eebf760094d 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/Configuration.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/Configuration.hs @@ -56,12 +56,13 @@ import Distribution.System import Distribution.Types.Component import Distribution.Types.ComponentRequestedSpec import Distribution.Types.DependencyMap +import Distribution.Types.DependencySatisfaction (DependencySatisfaction (..)) +import Distribution.Types.MissingDependency (MissingDependency (..)) import Distribution.Types.PackageVersionConstraint import Distribution.Utils.Generic import Distribution.Utils.Path (sameDirectory) import Distribution.Version -import qualified Data.Map.Lazy as Map import Data.Tree (Tree (Node)) ------------------------------------------------------------------------------ @@ -144,15 +145,17 @@ parseCondition = condOr ------------------------------------------------------------------------------ --- | Result of dependency test. Isomorphic to @Maybe d@ but renamed for +-- | Result of dependency test. Isomorphic to @Maybe@ but renamed for -- clarity. -data DepTestRslt d = DepOk | MissingDeps d +data DepTestRslt + = DepOk + | MissingDeps [MissingDependency] -instance Semigroup d => Monoid (DepTestRslt d) where +instance Monoid DepTestRslt where mempty = DepOk mappend = (<>) -instance Semigroup d => Semigroup (DepTestRslt d) where +instance Semigroup DepTestRslt where DepOk <> x = x x <> DepOk = x (MissingDeps d) <> (MissingDeps d') = MissingDeps (d <> d') @@ -190,13 +193,13 @@ resolveWithFlags -> [PackageVersionConstraint] -- ^ Additional constraints -> [CondTree ConfVar [Dependency] PDTagged] - -> ([Dependency] -> DepTestRslt [Dependency]) + -> ([Dependency] -> DepTestRslt) -- ^ Dependency test function. - -> Either [Dependency] (TargetSet PDTagged, FlagAssignment) + -> Either [MissingDependency] (TargetSet PDTagged, FlagAssignment) -- ^ Either the missing dependencies (error case), or a pair of -- (set of build targets with dependencies, chosen flag assignments) resolveWithFlags dom enabled os arch impl constrs trees checkDeps = - either (Left . fromDepMapUnion) Right $ explore (build mempty dom) + explore (build mempty dom) where -- simplify trees by (partially) evaluating all conditions and converting -- dependencies to dependency maps. @@ -216,7 +219,7 @@ resolveWithFlags dom enabled os arch impl constrs trees checkDeps = -- computation overhead in the successful case. explore :: Tree FlagAssignment - -> Either DepMapUnion (TargetSet PDTagged, FlagAssignment) + -> Either [MissingDependency] (TargetSet PDTagged, FlagAssignment) explore (Node flags ts) = let targetSet = TargetSet $ @@ -229,7 +232,7 @@ resolveWithFlags dom enabled os arch impl constrs trees checkDeps = DepOk | null ts -> Right (targetSet, flags) | otherwise -> tryAll $ map explore ts - MissingDeps mds -> Left (toDepMapUnion mds) + MissingDeps mds -> Left mds -- Builds a tree of all possible flag assignments. Internal nodes -- have only partial assignments. @@ -238,18 +241,18 @@ resolveWithFlags dom enabled os arch impl constrs trees checkDeps = build assigned ((fn, vals) : unassigned) = Node assigned $ map (\v -> build (insertFlagAssignment fn v assigned) unassigned) vals - tryAll :: [Either DepMapUnion a] -> Either DepMapUnion a + tryAll :: Monoid a => [Either a b] -> Either a b tryAll = foldr mp mz -- special version of `mplus' for our local purposes - mp :: Either DepMapUnion a -> Either DepMapUnion a -> Either DepMapUnion a + mp :: Monoid a => Either a b -> Either a b -> Either a b mp m@(Right _) _ = m mp _ m@(Right _) = m mp (Left xs) (Left ys) = Left (xs <> ys) -- `mzero' - mz :: Either DepMapUnion a - mz = Left (DepMapUnion Map.empty) + mz :: Monoid a => Either a b + mz = Left mempty env :: FlagAssignment -> FlagName -> Either FlagName Bool env flags flag = (maybe (Left flag) Right . lookupFlagAssignment flag) flags @@ -323,27 +326,6 @@ extractConditions f gpkg = , extractCondition (f . benchmarkBuildInfo) . snd <$> condBenchmarks gpkg ] --- | A map of package constraints that combines version ranges using 'unionVersionRanges'. -newtype DepMapUnion = DepMapUnion {unDepMapUnion :: Map PackageName (VersionRange, NonEmptySet LibraryName)} - -instance Semigroup DepMapUnion where - DepMapUnion x <> DepMapUnion y = - DepMapUnion $ - Map.unionWith unionVersionRanges' x y - -unionVersionRanges' - :: (VersionRange, NonEmptySet LibraryName) - -> (VersionRange, NonEmptySet LibraryName) - -> (VersionRange, NonEmptySet LibraryName) -unionVersionRanges' (vr, cs) (vr', cs') = (unionVersionRanges vr vr', cs <> cs') - -toDepMapUnion :: [Dependency] -> DepMapUnion -toDepMapUnion ds = - DepMapUnion $ Map.fromListWith unionVersionRanges' [(p, (vr, cs)) | Dependency p vr cs <- ds] - -fromDepMapUnion :: DepMapUnion -> [Dependency] -fromDepMapUnion m = [Dependency p vr cs | (p, (vr, cs)) <- Map.toList (unDepMapUnion m)] - freeVars :: CondTree ConfVar c a -> [FlagName] freeVars t = [f | PackageFlag f <- freeVars' t] where @@ -453,7 +435,7 @@ finalizePD :: FlagAssignment -- ^ Explicitly specified flag assignments -> ComponentRequestedSpec - -> (Dependency -> Bool) + -> (Dependency -> DependencySatisfaction) -- ^ Is a given dependency satisfiable from the set of -- available packages? If this is unknown then use -- True. @@ -465,7 +447,7 @@ finalizePD -- ^ Additional constraints -> GenericPackageDescription -> Either - [Dependency] + [MissingDependency] (PackageDescription, FlagAssignment) -- ^ Either missing dependencies or the resolved package -- description along with the flag assignments chosen. @@ -526,7 +508,11 @@ finalizePD | otherwise -> [b, not b] -- flagDefaults = map (\(n,x:_) -> (n,x)) flagChoices check ds = - let missingDeps = filter (not . satisfyDep) ds + let missingDeps = + [ MissingDependency dependency reason + | (dependency, Unsatisfied reason) <- + map (\dependency -> (dependency, satisfyDep dependency)) ds + ] in if null missingDeps then DepOk else MissingDeps missingDeps diff --git a/Cabal-syntax/src/Distribution/Pretty.hs b/Cabal-syntax/src/Distribution/Pretty.hs index 3ddb806d81b..fcb0a7f0d0b 100644 --- a/Cabal-syntax/src/Distribution/Pretty.hs +++ b/Cabal-syntax/src/Distribution/Pretty.hs @@ -10,6 +10,8 @@ module Distribution.Pretty , showTokenStr , showFreeText , showFreeTextV3 + , commaSpaceSep + , commaSep -- * Deprecated , Separator @@ -118,3 +120,11 @@ lines_ s = in l : case s' of [] -> [] (_ : s'') -> lines_ s'' + +-- | Separate a list of documents by commas and spaces. +commaSpaceSep :: Pretty a => [a] -> PP.Doc +commaSpaceSep = PP.hsep . PP.punctuate PP.comma . map pretty + +-- | Separate a list of documents by commas. +commaSep :: Pretty a => [a] -> PP.Doc +commaSep = PP.hcat . PP.punctuate PP.comma . map pretty diff --git a/Cabal-syntax/src/Distribution/Types/Dependency.hs b/Cabal-syntax/src/Distribution/Types/Dependency.hs index 222a699a3f9..a152c9e3a68 100644 --- a/Cabal-syntax/src/Distribution/Types/Dependency.hs +++ b/Cabal-syntax/src/Distribution/Types/Dependency.hs @@ -78,31 +78,21 @@ instance NFData Dependency where rnf = genericRnf -- "pkg" -- -- >>> prettyShow $ Dependency (mkPackageName "pkg") anyVersion $ NES.insert (LSubLibName $ mkUnqualComponentName "sublib") mainLibSet --- "pkg:{pkg, sublib}" +-- "pkg:{pkg,sublib}" -- -- >>> prettyShow $ Dependency (mkPackageName "pkg") anyVersion $ NES.singleton (LSubLibName $ mkUnqualComponentName "sublib") -- "pkg:sublib" -- -- >>> prettyShow $ Dependency (mkPackageName "pkg") anyVersion $ NES.insert (LSubLibName $ mkUnqualComponentName "sublib-b") $ NES.singleton (LSubLibName $ mkUnqualComponentName "sublib-a") --- "pkg:{sublib-a, sublib-b}" +-- "pkg:{sublib-a,sublib-b}" instance Pretty Dependency where - pretty (Dependency name ver sublibs) = withSubLibs (pretty name) <+> pver + pretty (Dependency name ver sublibs) = prettyLibraryNames name (NES.toNonEmpty sublibs) <+> pver where -- TODO: change to isAnyVersion after #6736 pver | isAnyVersionLight ver = PP.empty | otherwise = pretty ver - withSubLibs doc = case NES.toList sublibs of - [LMainLibName] -> doc - [LSubLibName uq] -> doc <<>> PP.colon <<>> pretty uq - _ -> doc <<>> PP.colon <<>> PP.braces prettySublibs - - prettySublibs = PP.hsep $ PP.punctuate PP.comma $ prettySublib <$> NES.toList sublibs - - prettySublib LMainLibName = PP.text $ unPackageName name - prettySublib (LSubLibName un) = PP.text $ unUnqualComponentName un - -- | -- -- >>> simpleParsec "mylib:sub" :: Maybe Dependency diff --git a/Cabal-syntax/src/Distribution/Types/DependencySatisfaction.hs b/Cabal-syntax/src/Distribution/Types/DependencySatisfaction.hs new file mode 100644 index 00000000000..56ce74c1c45 --- /dev/null +++ b/Cabal-syntax/src/Distribution/Types/DependencySatisfaction.hs @@ -0,0 +1,14 @@ +module Distribution.Types.DependencySatisfaction + ( DependencySatisfaction (..) + ) where + +import Distribution.Types.MissingDependencyReason (MissingDependencyReason) + +-- | Whether or not a dependency constraint is satisfied. +data DependencySatisfaction + = -- | The dependency constraint is satisfied. + Satisfied + | -- | The dependency constraint is not satisfied. + -- + -- Includes a reason for explanation. + Unsatisfied MissingDependencyReason diff --git a/Cabal-syntax/src/Distribution/Types/LibraryName.hs b/Cabal-syntax/src/Distribution/Types/LibraryName.hs index 2b8f53f4f89..9073aae9a1f 100644 --- a/Cabal-syntax/src/Distribution/Types/LibraryName.hs +++ b/Cabal-syntax/src/Distribution/Types/LibraryName.hs @@ -10,6 +10,7 @@ module Distribution.Types.LibraryName , libraryNameString -- * Pretty & Parse + , prettyLibraryNames , prettyLibraryNameComponent , parsecLibraryNameComponent ) where @@ -17,6 +18,7 @@ module Distribution.Types.LibraryName import Distribution.Compat.Prelude import Prelude () +import qualified Data.List.NonEmpty as NEL import Distribution.Parsec import Distribution.Pretty import Distribution.Types.UnqualComponentName @@ -42,6 +44,22 @@ prettyLibraryNameComponent :: LibraryName -> Disp.Doc prettyLibraryNameComponent LMainLibName = Disp.text "lib" prettyLibraryNameComponent (LSubLibName str) = Disp.text "lib:" <<>> pretty str +-- | Pretty print a 'LibraryName' after a package name. +-- +-- Produces output like @foo@, @foo:bar@, or @foo:{bar,baz}@ +prettyLibraryNames :: Pretty a => a -> NonEmpty LibraryName -> Disp.Doc +prettyLibraryNames package libraries = + let doc = pretty package + + prettyComponent LMainLibName = pretty package + prettyComponent (LSubLibName component) = Disp.text $ unUnqualComponentName component + + prettyComponents = commaSep $ prettyComponent <$> NEL.toList libraries + in case libraries of + LMainLibName :| [] -> doc + LSubLibName component :| [] -> doc <<>> Disp.colon <<>> pretty component + _ -> doc <<>> Disp.colon <<>> Disp.braces prettyComponents + parsecLibraryNameComponent :: CabalParsing m => m LibraryName parsecLibraryNameComponent = do _ <- P.string "lib" diff --git a/Cabal-syntax/src/Distribution/Types/MissingDependency.hs b/Cabal-syntax/src/Distribution/Types/MissingDependency.hs new file mode 100644 index 00000000000..57d90276d8c --- /dev/null +++ b/Cabal-syntax/src/Distribution/Types/MissingDependency.hs @@ -0,0 +1,34 @@ +module Distribution.Types.MissingDependency + ( MissingDependency (..) + ) where + +import Distribution.Compat.Prelude +import Distribution.Pretty +import Distribution.Types.Dependency + ( Dependency + , simplifyDependency + ) +import Distribution.Types.LibraryName + ( prettyLibraryNames + ) +import Distribution.Types.MissingDependencyReason + ( MissingDependencyReason (..) + ) + +import qualified Text.PrettyPrint as PP + +-- | A missing dependency and information on why it's missing. +data MissingDependency = MissingDependency Dependency MissingDependencyReason + deriving (Show) + +instance Pretty MissingDependency where + pretty (MissingDependency dependency reason) = + let prettyReason = + case reason of + MissingLibrary libraries -> + PP.text "missing" <+> prettyLibraryNames PP.empty libraries + MissingPackage -> PP.text "missing" + MissingComponent name -> PP.text "missing component" <+> pretty name + WrongVersion versions -> + PP.text "installed:" <+> commaSpaceSep versions + in pretty (simplifyDependency dependency) <+> PP.parens prettyReason diff --git a/Cabal-syntax/src/Distribution/Types/MissingDependencyReason.hs b/Cabal-syntax/src/Distribution/Types/MissingDependencyReason.hs new file mode 100644 index 00000000000..c1c37800f21 --- /dev/null +++ b/Cabal-syntax/src/Distribution/Types/MissingDependencyReason.hs @@ -0,0 +1,25 @@ +module Distribution.Types.MissingDependencyReason + ( MissingDependencyReason (..) + ) where + +import Data.List.NonEmpty (NonEmpty) +import Distribution.Types.LibraryName (LibraryName) +import Distribution.Types.PackageName (PackageName) +import Distribution.Types.Version (Version) + +-- | A reason for a depency failing to solve. +-- +-- This helps pinpoint dependencies that are installed with an incorrect +-- version vs. dependencies that are not installed at all. +data MissingDependencyReason + = -- | One or more libraries is missing. + MissingLibrary (NonEmpty LibraryName) + | -- | A package is not installed. + MissingPackage + | -- | A package is installed, but the versions don't match. + -- + -- Contains the available versions. + WrongVersion [Version] + | -- | A component is not installed. + MissingComponent PackageName + deriving (Show) diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-5846.format b/Cabal-tests/tests/ParserTests/regressions/issue-5846.format index 749a9c20524..93e53fc48bd 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-5846.format +++ b/Cabal-tests/tests/ParserTests/regressions/issue-5846.format @@ -5,7 +5,7 @@ version: 5846 library default-language: Haskell2010 build-depends: - lib1:{a, b}, + lib1:{a,b}, lib2:c, lib3:d >=1, - lib4:{a, b} >=1 + lib4:{a,b} >=1 diff --git a/Cabal/Cabal.cabal b/Cabal/Cabal.cabal index b9a7e0838ab..a9e108d1f7b 100644 --- a/Cabal/Cabal.cabal +++ b/Cabal/Cabal.cabal @@ -248,6 +248,7 @@ library Distribution.Types.ConfVar, Distribution.Types.Dependency, Distribution.Types.DependencyMap, + Distribution.Types.DependencySatisfaction, Distribution.Types.ExeDependency, Distribution.Types.Executable, Distribution.Types.Executable.Lens, @@ -271,6 +272,8 @@ library Distribution.Types.Library.Lens, Distribution.Types.LibraryName, Distribution.Types.LibraryVisibility, + Distribution.Types.MissingDependency, + Distribution.Types.MissingDependencyReason, Distribution.Types.Mixin, Distribution.Types.Module, Distribution.Types.ModuleReexport, diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index 033f3c9de54..ca597e3bae2 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -106,9 +106,11 @@ import qualified Distribution.Simple.SetupHooks.Internal as SetupHooks import Distribution.Simple.Utils import Distribution.System import Distribution.Types.ComponentRequestedSpec +import Distribution.Types.DependencySatisfaction (DependencySatisfaction (..)) import Distribution.Types.GivenComponent import qualified Distribution.Types.LocalBuildConfig as LBC import Distribution.Types.LocalBuildInfo +import Distribution.Types.MissingDependencyReason (MissingDependencyReason (..)) import Distribution.Types.PackageVersionConstraint import Distribution.Utils.LogProgress import Distribution.Utils.NubList @@ -1480,7 +1482,7 @@ dependencySatisfiable -> Map (PackageName, ComponentName) PromisedComponent -> Map (PackageName, ComponentName) InstalledPackageInfo -- ^ required dependencies - -> (Dependency -> Bool) + -> (Dependency -> DependencySatisfaction) dependencySatisfiable use_external_internal_deps exact_config @@ -1506,16 +1508,14 @@ dependencySatisfiable internalDepSatisfiable else -- Backward compatibility for the old sublibrary syntax - ( sublibs == mainLibSet - && Map.member - ( pn - , CLibName $ - LSubLibName $ - packageNameToUnqualComponentName depName - ) - requiredDepsMap - ) - || all visible sublibs + let depComponentName = + CLibName $ LSubLibName $ packageNameToUnqualComponentName depName + invisibleLibraries = NES.filter (not . visible) sublibs + in if sublibs == mainLibSet && Map.member (pn, depComponentName) requiredDepsMap + then Satisfied + else case nonEmpty $ Set.toList invisibleLibraries of + Nothing -> Satisfied + Just invisibleLibraries' -> Unsatisfied $ MissingLibrary invisibleLibraries' | isInternalDep = if use_external_internal_deps then -- When we are doing per-component configure, we now need to @@ -1532,12 +1532,31 @@ dependencySatisfiable isInternalDep = pn == depName depSatisfiable = - not . null $ PackageIndex.lookupDependency installedPackageSet depName vr + let allVersions = PackageIndex.lookupPackageName installedPackageSet depName + eligibleVersions = + [ version + | (version, _infos) <- PackageIndex.eligibleDependencies allVersions + ] + in if null $ PackageIndex.matchingDependencies vr allVersions + then + if null eligibleVersions + then Unsatisfied $ MissingPackage + else Unsatisfied $ WrongVersion eligibleVersions + else Satisfied internalDepSatisfiable = - Set.isSubsetOf (NES.toSet sublibs) packageLibraries + let missingLibraries = (NES.toSet sublibs) `Set.difference` packageLibraries + in case nonEmpty $ Set.toList missingLibraries of + Nothing -> Satisfied + Just missingLibraries' -> Unsatisfied $ MissingLibrary missingLibraries' + internalDepSatisfiableExternally = - all (\ln -> not $ null $ PackageIndex.lookupInternalDependency installedPackageSet pn vr ln) sublibs + -- TODO: Might need to propagate information on which versions _are_ available, if any... + let missingLibraries = + NES.filter (null . PackageIndex.lookupInternalDependency installedPackageSet pn vr) sublibs + in case nonEmpty $ Set.toList missingLibraries of + Nothing -> Satisfied + Just missingLibraries' -> Unsatisfied $ MissingLibrary missingLibraries' -- Check whether a library exists and is visible. -- We don't disambiguate between dependency on non-existent or private @@ -1572,7 +1591,7 @@ configureFinalizedPackage -> ConfigFlags -> ComponentRequestedSpec -> [PackageVersionConstraint] - -> (Dependency -> Bool) + -> (Dependency -> DependencySatisfaction) -- ^ tests if a dependency is satisfiable. -- Might say it's satisfiable even when not. -> Compiler diff --git a/Cabal/src/Distribution/Simple/Errors.hs b/Cabal/src/Distribution/Simple/Errors.hs index c1cc75b5ad1..253b2f0dfbe 100644 --- a/Cabal/src/Distribution/Simple/Errors.hs +++ b/Cabal/src/Distribution/Simple/Errors.hs @@ -31,6 +31,7 @@ import Distribution.Simple.InstallDirs import Distribution.Simple.PreProcess.Types (Suffix) import Distribution.Simple.SetupHooks.Errors import Distribution.System (OS) +import Distribution.Types.MissingDependency (MissingDependency) import Distribution.Types.VersionRange.Internal () import Distribution.Version import Text.PrettyPrint @@ -126,7 +127,7 @@ data CabalException | CantFindForeignLibraries [String] | ExpectedAbsoluteDirectory FilePath | FlagsNotSpecified [FlagName] - | EncounteredMissingDependency [Dependency] + | EncounteredMissingDependency [MissingDependency] | CompilerDoesn'tSupportThinning | CompilerDoesn'tSupportReexports | CompilerDoesn'tSupportBackpack @@ -552,7 +553,7 @@ exceptionMessage e = case e of . nest 4 . sep . punctuate comma - . map (pretty . simplifyDependency) + . map pretty $ missing ) CompilerDoesn'tSupportThinning -> diff --git a/Cabal/src/Distribution/Simple/PackageIndex.hs b/Cabal/src/Distribution/Simple/PackageIndex.hs index 927e10ae878..e6944430755 100644 --- a/Cabal/src/Distribution/Simple/PackageIndex.hs +++ b/Cabal/src/Distribution/Simple/PackageIndex.hs @@ -68,6 +68,7 @@ module Distribution.Simple.PackageIndex , lookupSourcePackageId , lookupPackageId , lookupPackageName + , lookupInternalPackageName , lookupDependency , lookupInternalDependency @@ -93,6 +94,10 @@ module Distribution.Simple.PackageIndex , dependencyCycles , dependencyGraph , moduleNameIndex + + -- ** Filters on lookup results + , eligibleDependencies + , matchingDependencies ) where import qualified Data.Map.Strict as Map @@ -474,7 +479,18 @@ lookupPackageName -> [(Version, [a])] lookupPackageName index name = -- Do not match internal libraries - case Map.lookup (name, LMainLibName) (packageIdIndex index) of + lookupInternalPackageName index name LMainLibName + +-- | Does a lookup by source package name and library name. +-- +-- Also looks up internal packages. +lookupInternalPackageName + :: PackageIndex a + -> PackageName + -> LibraryName + -> [(Version, [a])] +lookupInternalPackageName index name library = + case Map.lookup (name, library) (packageIdIndex index) of Nothing -> [] Just pvers -> Map.toList pvers @@ -509,23 +525,46 @@ lookupInternalDependency -> LibraryName -> [(Version, [IPI.InstalledPackageInfo])] lookupInternalDependency index name versionRange libn = - case Map.lookup (name, libn) (packageIdIndex index) of - Nothing -> [] - Just pvers -> - [ (ver, pkgs') - | (ver, pkgs) <- Map.toList pvers - , ver `withinRange` versionRange - , let pkgs' = filter eligible pkgs - , -- Enforce the invariant - not (null pkgs') - ] + matchingDependencies versionRange $ + lookupInternalPackageName index name libn + +-- | Filter a set of installed packages to ones eligible as dependencies. +-- +-- When we select for dependencies, we ONLY want to pick up indefinite +-- packages, or packages with no instantiations. We'll do mix-in linking to +-- improve any such package into an instantiated one later. +-- +-- INVARIANT: List of eligible 'IPI.InstalledPackageInfo' is non-empty. +eligibleDependencies + :: [(Version, [IPI.InstalledPackageInfo])] + -> [(Version, [IPI.InstalledPackageInfo])] +eligibleDependencies versions = + [ (ver, pkgs') + | (ver, pkgs) <- versions + , let pkgs' = filter eligible pkgs + , -- Enforce the invariant + not (null pkgs') + ] where - -- When we select for dependencies, we ONLY want to pick up indefinite - -- packages, or packages with no instantiations. We'll do mix-in - -- linking to improve any such package into an instantiated one - -- later. eligible pkg = IPI.indefinite pkg || null (IPI.instantiatedWith pkg) +-- | Get eligible dependencies from a list of versions. +-- +-- This can be used to filter the output of 'lookupPackageName' or +-- 'lookupInternalPackageName'. +-- +-- INVARIANT: List of eligible 'IPI.InstalledPackageInfo' is non-empty. +matchingDependencies + :: VersionRange + -> [(Version, [IPI.InstalledPackageInfo])] + -> [(Version, [IPI.InstalledPackageInfo])] +matchingDependencies versionRange versions = + let eligibleVersions = eligibleDependencies versions + in [ (ver, pkgs) + | (ver, pkgs) <- eligibleVersions + , ver `withinRange` versionRange + ] + -- -- * Case insensitive name lookups diff --git a/cabal-install/src/Distribution/Client/CmdOutdated.hs b/cabal-install/src/Distribution/Client/CmdOutdated.hs index ed40a1a85e6..7674e67286f 100644 --- a/cabal-install/src/Distribution/Client/CmdOutdated.hs +++ b/cabal-install/src/Distribution/Client/CmdOutdated.hs @@ -129,6 +129,9 @@ import Distribution.Types.ComponentRequestedSpec import Distribution.Types.Dependency ( Dependency (..) ) +import Distribution.Types.DependencySatisfaction + ( DependencySatisfaction (..) + ) import Distribution.Types.PackageVersionConstraint ( PackageVersionConstraint (..) , simplifyPackageVersionConstraint @@ -443,7 +446,7 @@ depsFromPkgDesc verbosity comp platform = do finalizePD mempty (ComponentRequestedSpec True True) - (const True) + (const Satisfied) platform cinfo [] diff --git a/cabal-install/src/Distribution/Client/Configure.hs b/cabal-install/src/Distribution/Client/Configure.hs index 6634f874071..5f82329eb52 100644 --- a/cabal-install/src/Distribution/Client/Configure.hs +++ b/cabal-install/src/Distribution/Client/Configure.hs @@ -116,6 +116,9 @@ import Distribution.Simple.Utils as Utils import Distribution.System ( Platform ) +import Distribution.Types.DependencySatisfaction + ( DependencySatisfaction (..) + ) import Distribution.Types.GivenComponent ( GivenComponent (..) ) @@ -555,7 +558,7 @@ configurePackage pkg = case finalizePD flags (enableStanzas stanzas) - (const True) + (const Satisfied) platform comp [] diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index ae731cdc64b..d59bc611c44 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -127,6 +127,9 @@ import Distribution.System ( Platform ) import Distribution.Types.Dependency +import Distribution.Types.DependencySatisfaction + ( DependencySatisfaction (..) + ) import Distribution.Verbosity ( normal ) @@ -1092,7 +1095,7 @@ configuredPackageProblems case finalizePD specifiedFlags compSpec - (const True) + (const Satisfied) platform cinfo [] diff --git a/cabal-install/src/Distribution/Client/GenBounds.hs b/cabal-install/src/Distribution/Client/GenBounds.hs index 935db05fa43..2603a75d302 100644 --- a/cabal-install/src/Distribution/Client/GenBounds.hs +++ b/cabal-install/src/Distribution/Client/GenBounds.hs @@ -63,6 +63,9 @@ import Distribution.Types.ComponentRequestedSpec ( defaultComponentRequestedSpec ) import Distribution.Types.Dependency +import Distribution.Types.DependencySatisfaction + ( DependencySatisfaction (..) + ) import Distribution.Utils.Path (relativeSymbolicPath) import Distribution.Version ( LowerBound (..) @@ -134,7 +137,7 @@ genBounds verbosity packageDBs repoCtxt comp platform progdb globalFlags freezeF finalizePD mempty defaultComponentRequestedSpec - (const True) + (const Satisfied) platform cinfo [] diff --git a/cabal-install/src/Distribution/Client/Install.hs b/cabal-install/src/Distribution/Client/Install.hs index 84a590e3c74..b6a8198ae5c 100644 --- a/cabal-install/src/Distribution/Client/Install.hs +++ b/cabal-install/src/Distribution/Client/Install.hs @@ -244,6 +244,9 @@ import Distribution.System , buildOS , buildPlatform ) +import Distribution.Types.DependencySatisfaction + ( DependencySatisfaction (..) + ) import Distribution.Types.Flag ( FlagAssignment , PackageFlag (..) @@ -1676,7 +1679,7 @@ installReadyPackage pkg = case finalizePD flags (enableStanzas stanzas) - (const True) + (const Satisfied) platform cinfo [] diff --git a/cabal-install/src/Distribution/Client/InstallSymlink.hs b/cabal-install/src/Distribution/Client/InstallSymlink.hs index 7a470843779..46e1edaebef 100644 --- a/cabal-install/src/Distribution/Client/InstallSymlink.hs +++ b/cabal-install/src/Distribution/Client/InstallSymlink.hs @@ -74,6 +74,9 @@ import Distribution.Simple.Utils (info, withTempDirectory) import Distribution.System ( Platform ) +import Distribution.Types.DependencySatisfaction + ( DependencySatisfaction (..) + ) import Distribution.Types.UnqualComponentName import System.Directory @@ -205,7 +208,7 @@ symlinkBinaries case finalizePD flags (enableStanzas stanzas) - (const True) + (const Satisfied) platform cinfo [] diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 50423b2d1df..93baa8bf78f 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -176,6 +176,9 @@ import Distribution.System import Distribution.Types.AnnotatedId import Distribution.Types.ComponentInclude import Distribution.Types.ComponentName +import Distribution.Types.DependencySatisfaction + ( DependencySatisfaction (..) + ) import Distribution.Types.DumpBuildInfo import Distribution.Types.GivenComponent import Distribution.Types.LibraryName @@ -2130,7 +2133,7 @@ elaborateInstallPlan elabPkgDescription = case PD.finalizePD flags elabEnabledSpec - (const True) + (const Satisfied) platform (compilerInfo compiler) [] diff --git a/cabal-testsuite/PackageTests/ConfigureComponent/SubLib/setup-explicit-fail.out b/cabal-testsuite/PackageTests/ConfigureComponent/SubLib/setup-explicit-fail.out index fec347864e5..ee7258799b1 100644 --- a/cabal-testsuite/PackageTests/ConfigureComponent/SubLib/setup-explicit-fail.out +++ b/cabal-testsuite/PackageTests/ConfigureComponent/SubLib/setup-explicit-fail.out @@ -11,4 +11,4 @@ Registering library 'sublib' for Lib-0.1.0.0... Configuring executable 'exe' for Lib-0.1.0.0... Error: [Cabal-8010] Encountered missing or private dependencies: - Lib:sublib + Lib:sublib (missing :sublib) From 231bec937adef9243825f54c9d14ee9991a01e54 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 23 Sep 2024 16:36:49 -0700 Subject: [PATCH 159/207] Add tests --- .../MissingOrPrivate/Lib.cabal | 20 +++++++++++++++++++ .../MissingOrPrivate/Lib.hs | 2 ++ .../MissingOrPrivate/exe/Exe.hs | 2 ++ .../MissingOrPrivate/setup-fail.out | 16 +++++++++++++++ .../MissingOrPrivate/setup-fail.test.hs | 8 ++++++++ .../src/Test/Cabal/OutputNormalizer.hs | 1 + 6 files changed, 49 insertions(+) create mode 100644 cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/Lib.cabal create mode 100644 cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/Lib.hs create mode 100644 cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/exe/Exe.hs create mode 100644 cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/setup-fail.out create mode 100644 cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/setup-fail.test.hs diff --git a/cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/Lib.cabal b/cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/Lib.cabal new file mode 100644 index 00000000000..284513bd8b1 --- /dev/null +++ b/cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/Lib.cabal @@ -0,0 +1,20 @@ +cabal-version: 3.0 +name: Lib +version: 0.1.0.0 +license: BSD-3-Clause +author: Edward Z. Yang +maintainer: ezyang@cs.stanford.edu +build-type: Simple + +library foo-internal + build-depends: base + exposed-modules: Lib + default-language: Haskell2010 + +executable exe + main-is: Exe.hs + build-depends: base <=1.0, + package-that-does-not-exist, + Lib:{foo-internal, bar-internal}, + hs-source-dirs: exe + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/Lib.hs b/cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/Lib.hs new file mode 100644 index 00000000000..1d7d07d5cba --- /dev/null +++ b/cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/Lib.hs @@ -0,0 +1,2 @@ +module Lib where +lib = "OK" diff --git a/cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/exe/Exe.hs b/cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/exe/Exe.hs new file mode 100644 index 00000000000..6ee3fb933aa --- /dev/null +++ b/cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/exe/Exe.hs @@ -0,0 +1,2 @@ +import Lib +main = putStrLn lib diff --git a/cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/setup-fail.out b/cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/setup-fail.out new file mode 100644 index 00000000000..2ea38e253cd --- /dev/null +++ b/cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/setup-fail.out @@ -0,0 +1,16 @@ +# Setup configure +Configuring library 'foo-internal' for Lib-0.1.0.0... +# Setup build +Preprocessing library 'foo-internal' for Lib-0.1.0.0... +Building library 'foo-internal' for Lib-0.1.0.0... +# Setup copy +Installing internal library foo-internal in +# Setup register +Registering library 'foo-internal' for Lib-0.1.0.0... +# Setup configure +Configuring executable 'exe' for Lib-0.1.0.0... +Error: [Cabal-8010] +Encountered missing or private dependencies: + Lib:{bar-internal,foo-internal} (missing :bar-internal), + base <=1.0 (installed: ), + package-that-does-not-exist (missing) diff --git a/cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/setup-fail.test.hs b/cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/setup-fail.test.hs new file mode 100644 index 00000000000..5d8123ee88c --- /dev/null +++ b/cabal-testsuite/PackageTests/ConfigureComponent/MissingOrPrivate/setup-fail.test.hs @@ -0,0 +1,8 @@ + +import Test.Cabal.Prelude +main = setupTest $ do + withPackageDb $ do + base_id <- getIPID "base" + setup_install ["foo-internal", "--cid", "foo-internal-0.1-abc"] + r <- fails $ setup' "configure" [ "exe" ] + assertOutputContains "Lib" r diff --git a/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs b/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs index 33e1522526b..fb2840be9e6 100644 --- a/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs +++ b/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs @@ -80,6 +80,7 @@ normalizeOutput nenv = . maybe id normalizePathCmdOutput (normalizerCabalInstallVersion nenv) -- hackage-security locks occur non-deterministically . resub "(Released|Acquired|Waiting) .*hackage-security-lock\n" "" + . resub "installed: [0-9]+(\\.[0-9]+)*" "installed: " where sameDir = "(\\.((\\\\)+|\\/))*" packageIdRegex pid = From 3e143b154f2047cff0f0d4dffcd44727c9bd25d3 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Wed, 25 Sep 2024 16:27:35 -0700 Subject: [PATCH 160/207] Reorder import --- Cabal-syntax/src/Distribution/Types/LibraryName.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cabal-syntax/src/Distribution/Types/LibraryName.hs b/Cabal-syntax/src/Distribution/Types/LibraryName.hs index 9073aae9a1f..e31d1e82423 100644 --- a/Cabal-syntax/src/Distribution/Types/LibraryName.hs +++ b/Cabal-syntax/src/Distribution/Types/LibraryName.hs @@ -18,11 +18,11 @@ module Distribution.Types.LibraryName import Distribution.Compat.Prelude import Prelude () -import qualified Data.List.NonEmpty as NEL import Distribution.Parsec import Distribution.Pretty import Distribution.Types.UnqualComponentName +import qualified Data.List.NonEmpty as NEL import qualified Distribution.Compat.CharParsing as P import qualified Text.PrettyPrint as Disp From b0dcd3b9329e9c82f7e4bfc29e4fa429298373ca Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Thu, 26 Sep 2024 13:13:24 -0700 Subject: [PATCH 161/207] Add changelog entry --- changelog.d/pr-10273 | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 changelog.d/pr-10273 diff --git a/changelog.d/pr-10273 b/changelog.d/pr-10273 new file mode 100644 index 00000000000..271a49e6f63 --- /dev/null +++ b/changelog.d/pr-10273 @@ -0,0 +1,22 @@ +synopsis: Show why `cabal act-as-setup configure` failed +packages: Cabal +prs: #10273 +significance: + +description: { + +When `cabal act-as-setup configure` fails, it prints a list of "missing or +private dependencies". + +Now, it will show you if each failing dependency is missing, private, or an +incompatible version: + +``` +Error: [Cabal-8010] +Encountered missing or private dependencies: + Lib:{bar-internal,foo-internal} (missing :bar-internal), + base <=1.0 (installed: 4.18.2.1), + package-that-does-not-exist (missing) +``` + +} From b4a9815b667921dc303d1c287cfceb8193edfc47 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Thu, 26 Sep 2024 15:36:59 -0700 Subject: [PATCH 162/207] Escape braces in changelog entry From @geekosaur on Matrix: > since changelog-d uses the cabal file parser to parse changelog files, > internal braces have to be escaped --- changelog.d/pr-10273 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/pr-10273 b/changelog.d/pr-10273 index 271a49e6f63..e589809458c 100644 --- a/changelog.d/pr-10273 +++ b/changelog.d/pr-10273 @@ -14,7 +14,7 @@ incompatible version: ``` Error: [Cabal-8010] Encountered missing or private dependencies: - Lib:{bar-internal,foo-internal} (missing :bar-internal), + Lib:\{bar-internal,foo-internal\} (missing :bar-internal), base <=1.0 (installed: 4.18.2.1), package-that-does-not-exist (missing) ``` From 267834d03dafb4f84d95bdbc40575283641f4b4d Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Thu, 26 Sep 2024 15:41:46 -0700 Subject: [PATCH 163/207] Use Markdown changelog entry --- changelog.d/pr-10273 | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/changelog.d/pr-10273 b/changelog.d/pr-10273 index e589809458c..e83f0e509cb 100644 --- a/changelog.d/pr-10273 +++ b/changelog.d/pr-10273 @@ -1,9 +1,8 @@ -synopsis: Show why `cabal act-as-setup configure` failed +--- +synopsis: "Show why `cabal act-as-setup configure` failed" packages: Cabal -prs: #10273 -significance: - -description: { +prs: 10273 +--- When `cabal act-as-setup configure` fails, it prints a list of "missing or private dependencies". @@ -14,9 +13,7 @@ incompatible version: ``` Error: [Cabal-8010] Encountered missing or private dependencies: - Lib:\{bar-internal,foo-internal\} (missing :bar-internal), + Lib:{bar-internal,foo-internal} (missing :bar-internal), base <=1.0 (installed: 4.18.2.1), package-that-does-not-exist (missing) ``` - -} From 93419535258c52fa49d22e96b93174c583461925 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Thu, 26 Sep 2024 15:44:35 -0700 Subject: [PATCH 164/207] `packages` needs to be an array --- changelog.d/pr-10273 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/pr-10273 b/changelog.d/pr-10273 index e83f0e509cb..343c871377b 100644 --- a/changelog.d/pr-10273 +++ b/changelog.d/pr-10273 @@ -1,6 +1,6 @@ --- synopsis: "Show why `cabal act-as-setup configure` failed" -packages: Cabal +packages: [Cabal] prs: 10273 --- From f62699d5f5e3e6febb9b96c2cb171ffa5cc47cdf Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Sun, 15 Sep 2024 22:40:32 -0400 Subject: [PATCH 165/207] keep running tests even if earlier ones failed Matt Pickering says we should always run all tests. This requires a loop to ensure we still fail if any test does. --- .github/workflows/validate.yml | 35 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 947b47a5f12..047ea46cf09 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -236,29 +236,24 @@ jobs: name: cabal-${{ runner.os }}-${{ env.CABAL_ARCH }} path: ${{ env.CABAL_EXEC_TAR }} - - name: Validate lib-tests + - name: Validate tests env: # `rawSystemStdInOut reports text decoding errors` # test does not find ghc without the full path in windows GHCPATH: ${{ steps.setup-haskell.outputs.ghc-exe }} - run: sh validate.sh $FLAGS -s lib-tests - - - name: Validate lib-suite - run: sh validate.sh $FLAGS -s lib-suite - - - name: Validate cli-tests - run: sh validate.sh $FLAGS -s cli-tests - - - name: Validate cli-suite - run: sh validate.sh $FLAGS -s cli-suite - - - name: Validate solver-benchmarks-tests - if: matrix.ghc == env.GHC_FOR_SOLVER_BENCHMARKS - run: sh validate.sh $FLAGS -s solver-benchmarks-tests - - - name: Validate solver-benchmarks-run - if: matrix.ghc == env.GHC_FOR_SOLVER_BENCHMARKS - run: sh validate.sh $FLAGS -s solver-benchmarks-run + run: | + set +e + rc=0 + tests="lib-tests lib-suite cli-tests cli-suite" + if [ "${{ matrix.ghc }}" = "${{ env.GHC_FOR_SOLVER_BENCHMARKS }}" ]; then + tests="$tests solver-benchmarks-tests solver-benchmarks-run" + fi + for test in $tests; do + echo Validate "$test" + sh validate.sh $FLAGS -s "$test" || rc=1 + echo End "$test" + done + exit $rc validate-old-ghcs: name: Validate old ghcs ${{ matrix.extra-ghc }} @@ -312,11 +307,13 @@ jobs: restore-keys: ${{ runner.os }}-${{ env.GHC_FOR_RELEASE }}- - name: Validate build + id: build run: sh validate.sh ${{ env.COMMON_FLAGS }} -s build - name: "Validate lib-suite-extras --extra-hc ghc-${{ matrix.extra-ghc }}" env: EXTRA_GHC: ghc-${{ matrix.extra-ghc }} + continue-on-error: true run: sh validate.sh ${{ env.COMMON_FLAGS }} --lib-only -s lib-suite-extras --extra-hc "${{ env.EXTRA_GHC }}" build-alpine: From 683ab08791f37cefeedcf41dd505a6a92c2bfbe1 Mon Sep 17 00:00:00 2001 From: Artem Pelenitsyn Date: Fri, 6 Sep 2024 15:48:01 -0400 Subject: [PATCH 166/207] CI: cabal-head prerelease: move to a current GitHub Action for prereleases --- .github/workflows/validate.yml | 58 ++++++++-------------------------- 1 file changed, 13 insertions(+), 45 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 047ea46cf09..ae5e2c7a746 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -448,6 +448,8 @@ jobs: name: Create a GitHub prerelease with the binary artifacts runs-on: ubuntu-latest if: github.ref == 'refs/heads/master' + permissions: + contents: write # IMPORTANT! Any job added to the workflow should be added here too needs: [validate, validate-old-ghcs, build-alpine, dogfooding] @@ -456,32 +458,15 @@ jobs: # for now this is hardcoded. is there a better way? - uses: actions/download-artifact@v4 with: - name: cabal-Windows-x86_64 - - - uses: actions/download-artifact@v4 - with: - name: cabal-Linux-x86_64 - - - uses: actions/download-artifact@v4 - with: - name: cabal-Linux-static-x86_64 - - - uses: actions/download-artifact@v4 - with: - name: cabal-macOS-aarch64 + pattern: cabal-* + path: binaries - name: Create GitHub prerelease - uses: marvinpinto/action-automatic-releases@v1.2.1 + uses: softprops/action-gh-release@v2 with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - automatic_release_tag: cabal-head + tag_name: cabal-head prerelease: true - title: cabal-head - files: | - cabal-head-Windows-x86_64.tar.gz - cabal-head-Linux-x86_64.tar.gz - cabal-head-Linux-static-x86_64.tar.gz - cabal-head-macOS-aarch64.tar.gz + files: binaries/cabal-* prerelease-lts: name: Create a GitHub LTS prerelease with the binary artifacts @@ -495,39 +480,22 @@ jobs: steps: - uses: actions/download-artifact@v4 with: - name: cabal-Windows-x86_64 - - - uses: actions/download-artifact@v4 - with: - name: cabal-Linux-x86_64 - - - uses: actions/download-artifact@v4 - with: - name: cabal-Linux-static-x86_64 - - - uses: actions/download-artifact@v4 - with: - name: cabal-macOS-x86_64 + pattern: cabal-* + path: binaries - run: | # bash-ism, but we forced bash above mv cabal-{,lts-}head-Windows-x86_64.tar.gz mv cabal-{,lts-}head-Linux-x86_64.tar.gz mv cabal-{,lts-}head-Linux-static-x86_64.tar.gz - mv cabal-{,lts-}head-macOS-x86_64.tar.gz + mv cabal-{,lts-}head-macOS-aarch64.tar.gz - name: Create GitHub prerelease - uses: marvinpinto/action-automatic-releases@v1.2.1 + uses: softprops/action-gh-release@v2 with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - automatic_release_tag: cabal-lts-head + tag_name: cabal-lts-head prerelease: true - title: cabal-lts-head - files: | - cabal-lts-head-Windows-x86_64.tar.gz - cabal-lts-head-Linux-x86_64.tar.gz - cabal-lts-head-Linux-static-x86_64.tar.gz - cabal-lts-head-macOS-x86_64.tar.gz + files: binaries/cabal-* # We use this job as a summary of the workflow # It will fail if any of the previous jobs does From b53aae348bcac8ce0fdd4209f7e417839e7525cc Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Fri, 27 Sep 2024 10:55:31 -0700 Subject: [PATCH 167/207] Fix Unicode output in `cabal-testsuite` `System.Process.createPipe` calls (through many intermediaries) `GHC.IO.Handle.FD.fdToHandle`, whose documentation says: > Makes a binary Handle. This is for historical reasons; it should > probably be a text Handle with the default encoding and newline > translation instead. The documentation for `System.IO.hSetBinaryMode` says: > This has the same effect as calling `hSetEncoding` with `char8`, together > with `hSetNewlineMode` with `noNewlineTranslation`. But this is a lie, and Unicode written to or read from binary handles is always encoded or decoded as Latin-1, which is always the wrong choice. Therefore, we explicitly set the output to UTF-8 to keep it consistent between platforms and correct on all modern computers. See: https://gitlab.haskell.org/ghc/ghc/-/issues/25307 --- cabal-testsuite/src/Test/Cabal/Run.hs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/cabal-testsuite/src/Test/Cabal/Run.hs b/cabal-testsuite/src/Test/Cabal/Run.hs index 37b27e9edf3..498c14ded23 100644 --- a/cabal-testsuite/src/Test/Cabal/Run.hs +++ b/cabal-testsuite/src/Test/Cabal/Run.hs @@ -54,6 +54,29 @@ runAction _verbosity mb_cwd env_overrides path0 args input action = do mb_env <- getEffectiveEnvironment env_overrides putStrLn $ "+ " ++ showCommandForUser path args (readh, writeh) <- createPipe + + -- `System.Process.createPipe` calls (through many intermediaries) + -- `GHC.IO.Handle.FD.fdToHandle`, whose documentation says: + -- + -- > Makes a binary Handle. This is for historical reasons; it should + -- > probably be a text Handle with the default encoding and newline + -- > translation instead. + -- + -- The documentation for `System.IO.hSetBinaryMode` says: + -- + -- > This has the same effect as calling `hSetEncoding` with `char8`, together + -- > with `hSetNewlineMode` with `noNewlineTranslation`. + -- + -- But this is a lie, and Unicode written to or read from binary handles is + -- always encoded or decoded as Latin-1, which is always the wrong choice. + -- + -- Therefore, we explicitly set the output to UTF-8 to keep it consistent + -- between platforms and correct on all modern computers. + -- + -- See: https://gitlab.haskell.org/ghc/ghc/-/issues/25307 + hSetEncoding readh utf8 + hSetEncoding writeh utf8 + hSetBuffering readh LineBuffering hSetBuffering writeh LineBuffering let drain = do From f4d78390a33cf3e2a73fc4fd4592b7cc085877e8 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 30 Sep 2024 11:32:30 -0700 Subject: [PATCH 168/207] Set LC_ALL=en_US.UTF-8 in tests --- cabal-testsuite/src/Test/Cabal/Monad.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cabal-testsuite/src/Test/Cabal/Monad.hs b/cabal-testsuite/src/Test/Cabal/Monad.hs index abb9fba5def..63605768de7 100644 --- a/cabal-testsuite/src/Test/Cabal/Monad.hs +++ b/cabal-testsuite/src/Test/Cabal/Monad.hs @@ -402,8 +402,8 @@ runTestM mode m = testSkipSetupTests = argSkipSetupTests (testCommonArgs args), testHaveCabalShared = runnerWithSharedLib senv, testEnvironment = - -- Try to avoid Unicode output - [ ("LC_ALL", Just "C") + -- Use UTF-8 output on all platforms. + [ ("LC_ALL", Just "en_US.UTF-8") -- Hermetic builds (knot-tied) , ("HOME", Just (testHomeDir env)) -- Set CABAL_DIR in addition to HOME, since HOME has no From 35a57e7ccec0e16ee068c768f4076e405aa8b4ae Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Thu, 26 Sep 2024 12:13:10 -0700 Subject: [PATCH 169/207] Add `repl --keep-temp-files` test --- .../MultiRepl/KeepTempFiles/cabal.no.out | 11 +++++++ .../MultiRepl/KeepTempFiles/cabal.project | 2 ++ .../MultiRepl/KeepTempFiles/cabal.test.hs | 31 +++++++++++++++++++ .../MultiRepl/KeepTempFiles/cabal.yes.out | 11 +++++++ .../MultiRepl/KeepTempFiles/pkg-a/Foo.hs | 4 +++ .../MultiRepl/KeepTempFiles/pkg-a/pkg-a.cabal | 8 +++++ .../MultiRepl/KeepTempFiles/pkg-b/Bar.hs | 6 ++++ .../MultiRepl/KeepTempFiles/pkg-b/pkg-b.cabal | 8 +++++ 8 files changed, 81 insertions(+) create mode 100644 cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.no.out create mode 100644 cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.project create mode 100644 cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.test.hs create mode 100644 cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.yes.out create mode 100644 cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-a/Foo.hs create mode 100644 cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-a/pkg-a.cabal create mode 100644 cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-b/Bar.hs create mode 100644 cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-b/pkg-b.cabal diff --git a/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.no.out b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.no.out new file mode 100644 index 00000000000..348fea760af --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.no.out @@ -0,0 +1,11 @@ +# cabal clean +# cabal v2-repl +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - pkg-a-1 (interactive) (lib) (first run) + - pkg-b-0 (interactive) (lib) (first run) +Configuring library for pkg-a-1... +Preprocessing library for pkg-a-1... +Configuring library for pkg-b-0... +Preprocessing library for pkg-b-0... diff --git a/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.project b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.project new file mode 100644 index 00000000000..bf8292adeb5 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.project @@ -0,0 +1,2 @@ +packages: pkg-a/*.cabal +packages: pkg-b/*.cabal diff --git a/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.test.hs b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.test.hs new file mode 100644 index 00000000000..26c90db7ab1 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.test.hs @@ -0,0 +1,31 @@ +import Test.Cabal.Prelude + +main = do + cabalTest' "yes" $ do + skipUnlessGhcVersion ">= 9.4" + cabal' "clean" [] + res <- + cabalWithStdin + "v2-repl" + [ "--keep-temp-files" + , "--enable-multi-repl" + , "pkg-b" + , "pkg-a" + ] + "Bar.bar" + assertOutputContains "foo is 42" res + void $ assertGlobMatchesTestDir testDistDir "multi-out*/" + + cabalTest' "no" $ do + skipUnlessGhcVersion ">= 9.4" + cabal' "clean" [] + res <- + cabalWithStdin + "v2-repl" + [ "--enable-multi-repl" + , "pkg-b" + , "pkg-a" + ] + "Bar.bar" + assertOutputContains "foo is 42" res + void $ assertGlobDoesNotMatchTestDir testDistDir "multi-out*/" diff --git a/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.yes.out b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.yes.out new file mode 100644 index 00000000000..348fea760af --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/cabal.yes.out @@ -0,0 +1,11 @@ +# cabal clean +# cabal v2-repl +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - pkg-a-1 (interactive) (lib) (first run) + - pkg-b-0 (interactive) (lib) (first run) +Configuring library for pkg-a-1... +Preprocessing library for pkg-a-1... +Configuring library for pkg-b-0... +Preprocessing library for pkg-b-0... diff --git a/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-a/Foo.hs b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-a/Foo.hs new file mode 100644 index 00000000000..208f04764de --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-a/Foo.hs @@ -0,0 +1,4 @@ +module Foo where + +foo :: Int +foo = 42 diff --git a/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-a/pkg-a.cabal b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-a/pkg-a.cabal new file mode 100644 index 00000000000..7e4a3e9ef70 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-a/pkg-a.cabal @@ -0,0 +1,8 @@ +cabal-version: 2.2 +name: pkg-a +version: 1 + +library + default-language: Haskell2010 + build-depends: base + exposed-modules: Foo diff --git a/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-b/Bar.hs b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-b/Bar.hs new file mode 100644 index 00000000000..114eedd9306 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-b/Bar.hs @@ -0,0 +1,6 @@ +module Bar (foo, bar) where + +import Foo (foo) + +bar :: String +bar = "foo is " <> show foo diff --git a/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-b/pkg-b.cabal b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-b/pkg-b.cabal new file mode 100644 index 00000000000..8e1a273f0c4 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/KeepTempFiles/pkg-b/pkg-b.cabal @@ -0,0 +1,8 @@ +cabal-version: 2.2 +name: pkg-b +version: 0 + +library + default-language: Haskell2010 + build-depends: base, pkg-a + exposed-modules: Bar From a018eb15f9dc8866ae958aacac1f1920661a5cdd Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Thu, 26 Sep 2024 12:38:21 -0700 Subject: [PATCH 170/207] Add `repl --keep-temp-files` test with custom `Setup.hs` --- .../CustomSetupKeepTempFiles/cabal.no.out | 11 +++++++ .../CustomSetupKeepTempFiles/cabal.out | 10 ++++++ .../CustomSetupKeepTempFiles/cabal.project | 2 ++ .../CustomSetupKeepTempFiles/cabal.test.hs | 33 +++++++++++++++++++ .../CustomSetupKeepTempFiles/cabal.yes.out | 11 +++++++ .../CustomSetupKeepTempFiles/pkg-a/Foo.hs | 4 +++ .../CustomSetupKeepTempFiles/pkg-a/Setup.hs | 4 +++ .../pkg-a/pkg-a.cabal | 12 +++++++ .../CustomSetupKeepTempFiles/pkg-b/Bar.hs | 6 ++++ .../CustomSetupKeepTempFiles/pkg-b/Setup.hs | 4 +++ .../pkg-b/pkg-b.cabal | 12 +++++++ 11 files changed, 109 insertions(+) create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.no.out create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.out create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.project create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.test.hs create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.yes.out create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-a/Foo.hs create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-a/Setup.hs create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-a/pkg-a.cabal create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-b/Bar.hs create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-b/Setup.hs create mode 100644 cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-b/pkg-b.cabal diff --git a/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.no.out b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.no.out new file mode 100644 index 00000000000..073e87feea2 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.no.out @@ -0,0 +1,11 @@ +# cabal clean +# cabal v2-repl +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - pkg-a-1 (interactive) (first run) + - pkg-b-0 (interactive) (first run) +Configuring pkg-a-1... +Preprocessing library for pkg-a-1... +Configuring pkg-b-0... +Preprocessing library for pkg-b-0... diff --git a/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.out b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.out new file mode 100644 index 00000000000..9c141d7ac42 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.out @@ -0,0 +1,10 @@ +# cabal v2-repl +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - pkg-a-1 (interactive) (lib) (first run) + - pkg-b-0 (interactive) (lib) (first run) +Configuring library for pkg-a-1... +Preprocessing library for pkg-a-1... +Configuring library for pkg-b-0... +Preprocessing library for pkg-b-0... diff --git a/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.project b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.project new file mode 100644 index 00000000000..bf8292adeb5 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.project @@ -0,0 +1,2 @@ +packages: pkg-a/*.cabal +packages: pkg-b/*.cabal diff --git a/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.test.hs b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.test.hs new file mode 100644 index 00000000000..ea0851f1f2c --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.test.hs @@ -0,0 +1,33 @@ +import Test.Cabal.Prelude + +main = do + cabalTest' "yes" $ do + skipUnlessAnyCabalVersion ">= 3.11" + skipUnlessGhcVersion ">= 9.4" + cabal' "clean" [] + res <- + cabalWithStdin + "v2-repl" + [ "--keep-temp-files" + , "--enable-multi-repl" + , "pkg-b" + , "pkg-a" + ] + "Bar.bar" + assertOutputContains "foo is 42" res + void $ assertGlobMatchesTestDir testDistDir "multi-out*/" + + cabalTest' "no" $ do + skipUnlessAnyCabalVersion ">= 3.11" + skipUnlessGhcVersion ">= 9.4" + cabal' "clean" [] + res <- + cabalWithStdin + "v2-repl" + [ "--enable-multi-repl" + , "pkg-b" + , "pkg-a" + ] + "Bar.bar" + assertOutputContains "foo is 42" res + void $ assertGlobDoesNotMatchTestDir testDistDir "multi-out*/" diff --git a/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.yes.out b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.yes.out new file mode 100644 index 00000000000..073e87feea2 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/cabal.yes.out @@ -0,0 +1,11 @@ +# cabal clean +# cabal v2-repl +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - pkg-a-1 (interactive) (first run) + - pkg-b-0 (interactive) (first run) +Configuring pkg-a-1... +Preprocessing library for pkg-a-1... +Configuring pkg-b-0... +Preprocessing library for pkg-b-0... diff --git a/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-a/Foo.hs b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-a/Foo.hs new file mode 100644 index 00000000000..208f04764de --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-a/Foo.hs @@ -0,0 +1,4 @@ +module Foo where + +foo :: Int +foo = 42 diff --git a/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-a/Setup.hs b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-a/Setup.hs new file mode 100644 index 00000000000..00bfe1fe441 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-a/Setup.hs @@ -0,0 +1,4 @@ +import Distribution.Simple + +main :: IO () +main = defaultMain diff --git a/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-a/pkg-a.cabal b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-a/pkg-a.cabal new file mode 100644 index 00000000000..3c3bbde21a2 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-a/pkg-a.cabal @@ -0,0 +1,12 @@ +cabal-version: 2.2 +name: pkg-a +version: 1 +build-type: Custom + +custom-setup + setup-depends: Cabal, base + +library + default-language: Haskell2010 + build-depends: base + exposed-modules: Foo diff --git a/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-b/Bar.hs b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-b/Bar.hs new file mode 100644 index 00000000000..114eedd9306 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-b/Bar.hs @@ -0,0 +1,6 @@ +module Bar (foo, bar) where + +import Foo (foo) + +bar :: String +bar = "foo is " <> show foo diff --git a/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-b/Setup.hs b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-b/Setup.hs new file mode 100644 index 00000000000..00bfe1fe441 --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-b/Setup.hs @@ -0,0 +1,4 @@ +import Distribution.Simple + +main :: IO () +main = defaultMain diff --git a/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-b/pkg-b.cabal b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-b/pkg-b.cabal new file mode 100644 index 00000000000..a354090771d --- /dev/null +++ b/cabal-testsuite/PackageTests/MultiRepl/CustomSetupKeepTempFiles/pkg-b/pkg-b.cabal @@ -0,0 +1,12 @@ +cabal-version: 2.2 +name: pkg-b +version: 0 +build-type: Custom + +custom-setup + setup-depends: Cabal, base + +library + default-language: Haskell2010 + build-depends: base, pkg-a + exposed-modules: Bar From 0da821b989502c75406a6f3b21aec688e3d99ad6 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Tue, 1 Oct 2024 10:29:29 -0400 Subject: [PATCH 171/207] avoid incomplete record selection warning Per SPJ suggection. Closes: #10402 --- Cabal/src/Distribution/Simple/GHC/Build/Link.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Cabal/src/Distribution/Simple/GHC/Build/Link.hs b/Cabal/src/Distribution/Simple/GHC/Build/Link.hs index 3f9f00c9d28..ef9f33d79c9 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build/Link.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build/Link.hs @@ -735,7 +735,9 @@ runReplOrWriteFlags ghcProg lbi rflags ghcOpts pkg_name target = Flag out_dir -> do let uid = componentUnitId clbi this_unit = prettyShow uid - reexported_modules = [mn | LibComponentLocalBuildInfo{} <- [clbi], IPI.ExposedModule mn (Just{}) <- componentExposedModules clbi] + reexported_modules = + [ mn | LibComponentLocalBuildInfo{componentExposedModules = exposed_mods} <- [clbi], IPI.ExposedModule mn (Just{}) <- exposed_mods + ] hidden_modules = otherModules bi extra_opts = concat $ From 83ba50d5cc6d6fc554e17a9313730a4502c17750 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Thu, 5 Sep 2024 16:48:38 -0700 Subject: [PATCH 172/207] Convert `validate.sh` to `cabal-validate` Closes #10317. A Haskell script will be easier to maintain and expand than the existing Bash script. This also adds a `--pattern PATTERN` option which lets you filter tests across all test suites. --- Makefile | 6 +- cabal-validate/cabal-validate.cabal | 39 ++ cabal-validate/main/Main.hs | 954 ++++++++++++++++++++++++++++ project-cabal/pkgs/tests.config | 1 + validate.sh | 555 +--------------- 5 files changed, 999 insertions(+), 556 deletions(-) create mode 100644 cabal-validate/cabal-validate.cabal create mode 100644 cabal-validate/main/Main.hs diff --git a/Makefile b/Makefile index e0b239d80ad..12d38557de6 100644 --- a/Makefile +++ b/Makefile @@ -29,16 +29,16 @@ init: ## Set up git hooks and ignored revisions .PHONY: style style: ## Run the code styler - @fourmolu -q -i Cabal Cabal-syntax cabal-install + @fourmolu -q -i Cabal Cabal-syntax cabal-install cabal-validate .PHONY: style-modified style-modified: ## Run the code styler on modified files - @git ls-files --modified Cabal Cabal-syntax cabal-install \ + @git ls-files --modified Cabal Cabal-syntax cabal-install cabal-validate \ | grep '.hs$$' | xargs -P $(PROCS) -I {} fourmolu -q -i {} .PHONY: style-commit style-commit: ## Run the code styler on the previous commit - @git diff --name-only HEAD $(COMMIT) Cabal Cabal-syntax cabal-install \ + @git diff --name-only HEAD $(COMMIT) Cabal Cabal-syntax cabal-install cabal-validate \ | grep '.hs$$' | xargs -P $(PROCS) -I {} fourmolu -q -i {} .PHONY: whitespace diff --git a/cabal-validate/cabal-validate.cabal b/cabal-validate/cabal-validate.cabal new file mode 100644 index 00000000000..938c4aadde8 --- /dev/null +++ b/cabal-validate/cabal-validate.cabal @@ -0,0 +1,39 @@ +cabal-version: 3.0 +name: cabal-validate +version: 1.0.0 +copyright: 2024-2024, Cabal Development Team (see AUTHORS file) +license: BSD-3-Clause +author: Cabal Development Team +synopsis: An internal tool for building and testing the Cabal package manager +build-type: Simple + +common warnings + ghc-options: -Wall + +executable cabal-validate + import: warnings + default-language: Haskell2010 + default-extensions: + OverloadedStrings + , TypeApplications + ghc-options: -O -threaded -rtsopts -with-rtsopts=-N + + if impl(ghc <9.6) + -- Pattern exhaustiveness checker is not as good, misses a case. + ghc-options: -Wno-incomplete-patterns + + main-is: Main.hs + hs-source-dirs: main + + build-depends: + base >=4 && <5 + , ansi-terminal >=1 && <2 + , bytestring >=0.11 && <1 + , containers >=0.6 && <1 + , directory >=1.0 && <2 + , filepath >=1 && <2 + , optparse-applicative >=0.18 && <1 + , terminal-size >=0.3 && <1 + , text >=2 && <3 + , time >=1 && <2 + , typed-process >=0.2 && <1 diff --git a/cabal-validate/main/Main.hs b/cabal-validate/main/Main.hs new file mode 100644 index 00000000000..9da91cc9a87 --- /dev/null +++ b/cabal-validate/main/Main.hs @@ -0,0 +1,954 @@ +module Main where + +import Control.Applicative (Alternative (many, (<|>)), (<**>)) +import Control.Exception (Exception (displayException), catch, throw, throwIO) +import Control.Monad (forM_, unless, when) +import Data.ByteString.Lazy (ByteString) +import qualified Data.ByteString.Lazy as ByteString +import Data.Data (Typeable) +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map +import Data.Maybe (listToMaybe) +import Data.Text (Text) +import qualified Data.Text as T +import qualified Data.Text.IO as T +import qualified Data.Text.Lazy as T (toStrict) +import qualified Data.Text.Lazy.Encoding as T (decodeUtf8) +import Data.Time.Clock (DiffTime, secondsToDiffTime) +import Data.Time.Clock.System (getSystemTime, systemToTAITime) +import Data.Time.Clock.TAI (AbsoluteTime, diffAbsoluteTime) +import Data.Time.Format (defaultTimeLocale, formatTime) +import Data.Version (Version, makeVersion, parseVersion, showVersion) +import GHC.Conc (getNumCapabilities) +import Options.Applicative + ( FlagFields + , Mod + , Parser + , ParserInfo + , auto + , execParser + , flag + , flag' + , fullDesc + , help + , helper + , hidden + , info + , long + , maybeReader + , option + , progDesc + , short + , strOption + , switch + , value + ) +import qualified Options.Applicative as Opt +import System.Console.ANSI + ( Color (Blue, Cyan, Green, Red) + , ColorIntensity (Vivid) + , ConsoleIntensity (BoldIntensity) + , ConsoleLayer (Foreground) + , SGR (Reset, SetColor, SetConsoleIntensity) + , setSGRCode + ) +import qualified System.Console.Terminal.Size as Terminal +import System.Directory (getCurrentDirectory, withCurrentDirectory) +import System.Exit (ExitCode (ExitFailure, ExitSuccess), exitFailure, exitSuccess) +import System.FilePath (()) +import System.Info (arch, os) +import System.Process.Typed (ExitCodeException (..), proc, readProcess, readProcessStdout_, runProcess) +import Text.ParserCombinators.ReadP (readP_to_S) + +tShow :: Show a => a -> Text +tShow = T.pack . show + +tSetSGRCode :: [SGR] -> Text +tSetSGRCode = T.pack . setSGRCode + +decodeStrip :: ByteString -> Text +decodeStrip = T.strip . T.toStrict . T.decodeUtf8 + +-- | Command-line options, resolved with context from the environment. +data ResolvedOpts = ResolvedOpts + { verbose :: Bool + , jobs :: Int + , cwd :: FilePath + , startTime :: AbsoluteTime + , compiler :: Compiler + , extraCompilers :: [FilePath] + , cabal :: FilePath + , hackageTests :: HackageTests + , archPath :: FilePath + , projectFile :: FilePath + , tastyArgs :: [String] + , targets :: [String] + , steps :: [Step] + } + deriving (Show) + +data Compiler = Compiler + { compilerExecutable :: FilePath + , compilerVersion :: Version + } + deriving (Show) + +data VersionParseException = VersionParseException + { versionInput :: String + , versionExecutable :: FilePath + } + deriving (Typeable, Show) + +instance Exception VersionParseException where + displayException exception = + "Failed to parse `" + <> versionExecutable exception + <> " --numeric-version` output: " + <> show (versionInput exception) + +makeCompiler :: FilePath -> IO Compiler +makeCompiler executable = do + stdout <- + readProcessStdout_ $ + proc executable ["--numeric-version"] + let version = T.unpack $ T.strip $ T.toStrict $ T.decodeUtf8 stdout + parsedVersions = readP_to_S parseVersion version + -- Who needs error messages? Those aren't in the API. + maybeParsedVersion = + listToMaybe + [ parsed + | (parsed, []) <- parsedVersions + ] + parsedVersion = case maybeParsedVersion of + Just parsedVersion' -> parsedVersion' + Nothing -> + throw + VersionParseException + { versionInput = version + , versionExecutable = executable + } + + pure + Compiler + { compilerExecutable = executable + , compilerVersion = parsedVersion + } + +baseHc :: ResolvedOpts -> FilePath +baseHc opts = "ghc-" <> showVersion (compilerVersion $ compiler opts) + +baseBuildDir :: ResolvedOpts -> FilePath +baseBuildDir opts = "dist-newstyle-validate-" <> baseHc opts + +buildDir :: ResolvedOpts -> FilePath +buildDir opts = + cwd opts + baseBuildDir opts + "build" + archPath opts + baseHc opts + +jobsArgs :: ResolvedOpts -> [String] +jobsArgs opts = ["--num-threads", show $ jobs opts] + +cabalArgs :: ResolvedOpts -> [String] +cabalArgs opts = + [ "--jobs=" <> show (jobs opts) + , "--with-compiler=" <> compilerExecutable (compiler opts) + , "--builddir=" <> baseBuildDir opts + , "--project-file=" <> projectFile opts + ] + +cabalTestsuiteBuildDir :: ResolvedOpts -> FilePath +cabalTestsuiteBuildDir opts = + buildDir opts + "cabal-testsuite-3" + +cabalNewBuildArgs :: ResolvedOpts -> [String] +cabalNewBuildArgs opts = "build" : cabalArgs opts + +cabalListBinArgs :: ResolvedOpts -> [String] +cabalListBinArgs opts = "list-bin" : cabalArgs opts + +cabalListBin :: ResolvedOpts -> String -> IO FilePath +cabalListBin opts target = do + let args = cabalListBinArgs opts ++ [target] + stdout <- + readProcessStdout_ $ + proc (cabal opts) args + + pure (T.unpack $ T.strip $ T.toStrict $ T.decodeUtf8 stdout) + +rtsArgs :: ResolvedOpts -> [String] +rtsArgs opts = + case archPath opts of + "x86_64-windows" -> + -- See: https://github.com/haskell/cabal/issues/9571 + if compilerVersion (compiler opts) > makeVersion [9, 0, 2] + then ["+RTS", "--io-manager=native", "-RTS"] + else [] + _ -> [] + +resolveOpts :: Opts -> IO ResolvedOpts +resolveOpts opts = do + let optionals :: Bool -> [a] -> [a] + optionals True items = items + optionals False _ = [] + + optional :: Bool -> a -> [a] + optional keep item = optionals keep [item] + + steps' = + if not (null (rawSteps opts)) + then rawSteps opts + else + concat + [ + [ PrintConfig + , PrintToolVersions + , Build + ] + , optional (rawDoctest opts) Doctest + , optional (rawRunLibTests opts) LibTests + , optional (rawRunLibSuite opts) LibSuite + , optional (rawRunLibSuite opts && not (null (rawExtraCompilers opts))) LibSuiteExtras + , optional (rawRunCliTests opts && not (rawLibOnly opts)) CliTests + , optional (rawRunCliSuite opts && not (rawLibOnly opts)) CliSuite + , optionals (rawSolverBenchmarks opts) [SolverBenchmarksTests, SolverBenchmarksRun] + , [TimeSummary] + ] + + targets' = + concat + [ + [ "Cabal" + , "Cabal-hooks" + , "cabal-testsuite" + , "Cabal-tests" + , "Cabal-QuickCheck" + , "Cabal-tree-diff" + , "Cabal-described" + ] + , optionals + (CliTests `elem` steps') + [ "cabal-install" + , "cabal-install-solver" + , "cabal-benchmarks" + ] + , optional (rawSolverBenchmarks opts) "solver-benchmarks" + ] + + archPath' = + let osPath = + case os of + "darwin" -> "osx" + "linux" -> "linux" + "mingw32" -> "windows" + _ -> os -- TODO: Warning? + in arch <> "-" <> osPath + + projectFile' = + if rawLibOnly opts + then "cabal.validate-libonly.project" + else "cabal.validate.project" + + tastyArgs' = + "--hide-successes" + : case rawTastyPattern opts of + Just tastyPattern -> ["--pattern", tastyPattern] + Nothing -> [] + + when (rawListSteps opts) $ do + -- TODO: This should probably list _all_ available steps, not just the selected ones! + putStrLn "Targets:" + forM_ targets' $ \target -> do + putStrLn $ " " <> target + putStrLn "Steps:" + forM_ steps' $ \step -> do + putStrLn $ " " <> displayStep step + exitSuccess + + startTime' <- getAbsoluteTime + jobs' <- maybe getNumCapabilities pure (rawJobs opts) + cwd' <- getCurrentDirectory + compiler' <- makeCompiler (rawCompiler opts) + + pure + ResolvedOpts + { verbose = rawVerbose opts + , jobs = jobs' + , cwd = cwd' + , startTime = startTime' + , compiler = compiler' + , extraCompilers = rawExtraCompilers opts + , cabal = rawCabal opts + , archPath = archPath' + , projectFile = projectFile' + , hackageTests = rawHackageTests opts + , tastyArgs = tastyArgs' + , targets = targets' + , steps = steps' + } + +-- | Command-line options. +data Opts = Opts + { rawVerbose :: Bool + , rawJobs :: Maybe Int + , rawCompiler :: FilePath + , rawCabal :: FilePath + , rawExtraCompilers :: [FilePath] + , rawTastyPattern :: Maybe String + , rawDoctest :: Bool + , rawSteps :: [Step] + , rawListSteps :: Bool + , rawLibOnly :: Bool + , rawRunLibTests :: Bool + , rawRunCliTests :: Bool + , rawRunLibSuite :: Bool + , rawRunCliSuite :: Bool + , rawSolverBenchmarks :: Bool + , rawHackageTests :: HackageTests + } + deriving (Show) + +optsParser :: Parser Opts +optsParser = + Opts + <$> ( flag' + True + ( short 'v' + <> long "verbose" + <> help "Always display build and test output" + ) + <|> flag + False + False + ( short 'q' + <> long "quiet" + <> help "Silence build and test output" + ) + ) + <*> option + (Just <$> auto) + ( short 'j' + <> long "jobs" + <> help "Passed to `cabal build --jobs`" + <> value Nothing + ) + <*> strOption + ( short 'w' + <> long "with-compiler" + <> help "Build Cabal with the given compiler instead of `ghc`" + <> value "ghc" + ) + <*> strOption + ( long "with-cabal" + <> help "Test the given `cabal-install` (the `cabal` on your `$PATH` is used for builds)" + <> value "cabal" + ) + <*> many + ( strOption + ( long "extra-hc" + <> help "Extra compilers to run the test suites against" + ) + ) + <*> option + (Just <$> Opt.str) + ( short 'p' + <> long "pattern" + <> help "Pattern to filter tests by" + <> value Nothing + ) + <*> boolOption + False + "doctest" + ( help "Run doctest on the `Cabal` library" + ) + <*> many + ( option + (maybeReader parseStep) + ( short 's' + <> long "step" + <> help "Run only a specific step (can be specified multiple times)" + ) + ) + <*> switch + ( long "list-steps" + <> help "List the available steps and exit" + ) + <*> ( flag' + True + ( long "lib-only" + <> help "Test only `Cabal` (the library)" + ) + <|> flag + False + False + ( long "cli" + <> help "Test `cabal-install` (the executable) in addition to `Cabal` (the library)" + ) + ) + <*> boolOption + True + "run-lib-tests" + ( help "Run tests for the `Cabal` library" + ) + <*> boolOption + True + "run-cli-tests" + ( help "Run client tests for the `cabal-install` executable" + ) + <*> boolOption + False + "run-lib-suite" + ( help "Run `cabal-testsuite` with the `Cabal` library" + ) + <*> boolOption + False + "run-cli-suite" + ( help "Run `cabal-testsuite` with the `cabal-install` executable" + ) + <*> boolOption + False + "solver-benchmarks" + ( help "Build and trial run `solver-benchmarks`" + ) + <*> ( flag' + CompleteHackageTests + ( long "complete-hackage-tests" + <> help "Run `hackage-tests` on complete Hackage data" + ) + <|> flag + NoHackageTests + PartialHackageTests + ( long "partial-hackage-tests" + <> help "Run `hackage-tests` on parts of Hackage data" + ) + ) + +-- | Parse a boolean switch with separate names for the true and false options. +boolOption' :: Bool -> String -> String -> Mod FlagFields Bool -> Parser Bool +boolOption' defaultValue trueName falseName modifiers = + flag' True (modifiers <> long trueName) + <|> flag defaultValue False (modifiers <> hidden <> long falseName) + +-- | Parse a boolean switch with a `--no-*` flag for setting the option to false. +boolOption :: Bool -> String -> Mod FlagFields Bool -> Parser Bool +boolOption defaultValue trueName = + boolOption' defaultValue trueName ("no-" <> trueName) + +fullOptsParser :: ParserInfo Opts +fullOptsParser = + info + (optsParser <**> helper) + ( fullDesc + <> progDesc "Test suite runner for `Cabal` and `cabal-install` developers" + ) + +data HackageTests + = CompleteHackageTests + | PartialHackageTests + | NoHackageTests + deriving (Show) + +data Step + = PrintConfig + | PrintToolVersions + | Build + | Doctest + | LibTests + | LibSuite + | LibSuiteExtras + | CliTests + | CliSuite + | SolverBenchmarksTests + | SolverBenchmarksRun + | TimeSummary + deriving (Eq, Enum, Bounded, Show) + +displayStep :: Step -> String +displayStep step = + case step of + PrintConfig -> "print-config" + PrintToolVersions -> "print-tool-versions" + Build -> "build" + Doctest -> "doctest" + LibTests -> "lib-tests" + LibSuite -> "lib-suite" + LibSuiteExtras -> "lib-suite-extras" + CliTests -> "cli-tests" + CliSuite -> "cli-suite" + SolverBenchmarksTests -> "solver-benchmarks-tests" + SolverBenchmarksRun -> "solver-benchmarks-run" + TimeSummary -> "time-summary" + +nameToStep :: Map String Step +nameToStep = + Map.fromList + [ (displayStep step, step) + | step <- [minBound .. maxBound] + ] + +parseStep :: String -> Maybe Step +parseStep step = Map.lookup step nameToStep + +runStep :: ResolvedOpts -> Step -> IO () +runStep opts step = do + let title = displayStep step + printHeader title + let action = case step of + PrintConfig -> printConfig opts + PrintToolVersions -> printToolVersions opts + Build -> build opts + Doctest -> doctest opts + LibTests -> libTests opts + LibSuite -> libSuite opts + LibSuiteExtras -> libSuiteExtras opts + CliSuite -> cliSuite opts + CliTests -> cliTests opts + SolverBenchmarksTests -> solverBenchmarksTests opts + SolverBenchmarksRun -> solverBenchmarksRun opts + TimeSummary -> timeSummary opts + withTiming opts title action + T.putStrLn "" + +getTerminalWidth :: IO Int +getTerminalWidth = maybe 80 Terminal.width <$> Terminal.size @Int + +printHeader :: String -> IO () +printHeader title = do + columns <- getTerminalWidth + let left = 3 + right = columns - length title - left - 2 + header = + setSGRCode [SetConsoleIntensity BoldIntensity, SetColor Foreground Vivid Cyan] + <> replicate left '═' + <> " " + <> title + <> " " + <> replicate right '═' + <> setSGRCode [Reset] + putStrLn header + +withTiming :: ResolvedOpts -> String -> IO a -> IO a +withTiming opts title action = do + startTime' <- getAbsoluteTime + + result <- + (Right <$> action) + `catch` (\exception -> pure (Left (exception :: ExitCodeException))) + + endTime <- getAbsoluteTime + + let duration = diffAbsoluteTime endTime startTime' + totalDuration = diffAbsoluteTime endTime (startTime opts) + + case result of + Right inner -> do + putStrLn $ + setSGRCode [SetColor Foreground Vivid Green] + <> title + <> " finished after " + <> formatDiffTime duration + <> "\nTotal time so far: " + <> formatDiffTime totalDuration + <> setSGRCode [Reset] + + pure inner + Left _procFailed -> do + putStrLn $ + setSGRCode [SetColor Foreground Vivid Red] + <> title + <> " failed after " + <> formatDiffTime duration + <> "\nTotal time so far: " + <> formatDiffTime totalDuration + <> setSGRCode [Reset] + + -- TODO: `--keep-going` mode. + exitFailure + +-- TODO: Shell escaping +displayCommand :: String -> [String] -> String +displayCommand command args = command <> " " <> unwords args + +timedCabalBin :: ResolvedOpts -> String -> String -> [String] -> IO () +timedCabalBin opts package component args = do + command <- cabalListBin opts (package <> ":" <> component) + timedWithCwd + opts + package + command + args + +timedWithCwd :: ResolvedOpts -> FilePath -> String -> [String] -> IO () +timedWithCwd opts cdPath command args = + withCurrentDirectory cdPath (timed opts command args) + +timed :: ResolvedOpts -> String -> [String] -> IO () +timed opts command args = do + let prettyCommand = displayCommand command args + process = proc command args + + startTime' <- getAbsoluteTime + + -- TODO: Replace `$HOME` or `opts.cwd` for brevity? + putStrLn $ + setSGRCode [SetColor Foreground Vivid Blue] + <> "$ " + <> prettyCommand + <> setSGRCode [Reset] + + (exitCode, rawStdout, rawStderr) <- + if verbose opts + then do + exitCode <- runProcess process + pure (exitCode, ByteString.empty, ByteString.empty) + else readProcess process + + endTime <- getAbsoluteTime + + let duration = diffAbsoluteTime endTime startTime' + totalDuration = diffAbsoluteTime endTime (startTime opts) + + output = decodeStrip rawStdout <> "\n" <> decodeStrip rawStderr + linesLimit = 50 + outputLines = T.lines output + hiddenLines = length outputLines - linesLimit + tailLines = drop hiddenLines outputLines + + case exitCode of + ExitSuccess -> do + unless (verbose opts) $ do + if hiddenLines <= 0 + then T.putStrLn output + else + T.putStrLn $ + "(" + <> tShow hiddenLines + <> " lines hidden, use `--verbose` to show)\n" + <> "...\n" + <> T.unlines tailLines + + putStrLn $ + setSGRCode [SetColor Foreground Vivid Green] + <> "Finished after " + <> formatDiffTime duration + <> ": " + <> prettyCommand + <> "\nTotal time so far: " + <> formatDiffTime totalDuration + <> setSGRCode [Reset] + ExitFailure exitCode' -> do + unless (verbose opts) $ do + T.putStrLn output + + putStrLn $ + setSGRCode [SetColor Foreground Vivid Red] + <> "Failed with exit code " + <> show exitCode' + <> " after " + <> formatDiffTime duration + <> ": " + <> prettyCommand + <> "\nTotal time so far: " + <> formatDiffTime totalDuration + <> setSGRCode [Reset] + + throwIO + ExitCodeException + { eceExitCode = exitCode + , eceProcessConfig = process + , eceStdout = rawStdout + , eceStderr = rawStderr + } + +getAbsoluteTime :: IO AbsoluteTime +getAbsoluteTime = systemToTAITime <$> getSystemTime + +formatDiffTime :: DiffTime -> String +formatDiffTime delta = + let minute = secondsToDiffTime 60 + hour = 60 * minute + in if delta >= hour + then formatTime defaultTimeLocale "%h:%02M:%02ES" delta + else + if delta >= minute + then formatTime defaultTimeLocale "%m:%2ES" delta + else formatTime defaultTimeLocale "%2Ess" delta + +main :: IO () +main = do + opts <- execParser fullOptsParser + resolvedOpts <- resolveOpts opts + mainInner resolvedOpts + +mainInner :: ResolvedOpts -> IO () +mainInner opts = + forM_ (steps opts) $ \step -> do + runStep opts step + +printConfig :: ResolvedOpts -> IO () +printConfig opts = do + putStrLn $ + "compiler: " + <> compilerExecutable (compiler opts) + <> "\ncabal-install: " + <> cabal opts + <> "\njobs: " + <> show (jobs opts) + <> "\nsteps: " + <> unwords (map displayStep (steps opts)) + <> "\nHackage tests: " + <> show (hackageTests opts) + <> "\nverbose: " + <> show (verbose opts) + <> "\nextra compilers: " + <> unwords (extraCompilers opts) + <> "\nextra RTS options: " + <> unwords (rtsArgs opts) + +printToolVersions :: ResolvedOpts -> IO () +printToolVersions opts = do + timed opts (compilerExecutable (compiler opts)) ["--version"] + timed opts (cabal opts) ["--version"] + + forM_ (extraCompilers opts) $ \compiler' -> do + timed opts compiler' ["--version"] + +build :: ResolvedOpts -> IO () +build opts = do + printHeader "build (dry run)" + timed + opts + (cabal opts) + ( cabalNewBuildArgs opts + ++ targets opts + ++ ["--dry-run"] + ) + + printHeader "build (full build plan; cached and to-be-built dependencies)" + timed + opts + "jq" + [ "-r" + , -- TODO: Maybe use `cabal-plan`? It's a heavy dependency though... + ".\"install-plan\" | map(.\"pkg-name\" + \"-\" + .\"pkg-version\" + \" \" + .\"component-name\") | join(\"\n\")" + , baseBuildDir opts "cache" "plan.json" + ] + + printHeader "build (actual build)" + timed + opts + (cabal opts) + (cabalNewBuildArgs opts ++ targets opts) + +doctest :: ResolvedOpts -> IO () +doctest opts = do + timed + opts + "cabal-env" + [ "--name" + , "doctest-cabal" + , "--transitive" + , "QuickCheck" + ] + + timed + opts + "cabal-env" + [ "--name" + , "doctest-cabal" + , "array" + , "bytestring" + , "containers" + , "deepseq" + , "directory" + , "filepath" + , "pretty" + , "process" + , "time" + , "binary" + , "unix" + , "text" + , "parsec" + , "mtl" + ] + + timed + opts + "doctest" + [ "-package-env=doctest-Cabal" + , "--fast" + , "Cabal/Distribution" + , "Cabal/Language" + ] + +libTests :: ResolvedOpts -> IO () +libTests opts = do + let runCabalTests' suite extraArgs = + timedCabalBin + opts + "Cabal-tests" + ("test:" <> suite) + ( tastyArgs opts + ++ jobsArgs opts + ++ extraArgs + ) + + runCabalTests suite = runCabalTests' suite [] + + runCabalTests' "unit-tests" ["--with-ghc=" <> compilerExecutable (compiler opts)] + runCabalTests "check-tests" + runCabalTests "parser-tests" + runCabalTests "rpmvercmp" + runCabalTests "no-thunks-test" + + runHackageTests opts + +runHackageTests :: ResolvedOpts -> IO () +runHackageTests opts + | NoHackageTests <- hackageTests opts = pure () + | otherwise = do + command <- cabalListBin opts "Cabal-tests:test:hackage-tests" + + let + -- See #10284 for why this value is pinned. + hackageTestsIndexState = "--index-state=2024-08-25" + + hackageTest args = + timedWithCwd + opts + "Cabal-tests" + command + (args ++ [hackageTestsIndexState]) + + hackageTest ["read-fields"] + + case hackageTests opts of + CompleteHackageTests -> do + hackageTest ["parsec"] + hackageTest ["roundtrip"] + PartialHackageTests -> do + hackageTest ["parsec", "d"] + hackageTest ["roundtrip", "k"] + +libSuiteWith :: ResolvedOpts -> FilePath -> [String] -> IO () +libSuiteWith opts ghc extraArgs = + timedCabalBin + opts + "cabal-testsuite" + "exe:cabal-tests" + ( [ "--builddir=" <> cabalTestsuiteBuildDir opts + , "--with-ghc=" <> ghc + , -- This test suite doesn't support `--jobs` _or_ `--num-threads`! + "-j" <> show (jobs opts) + ] + ++ tastyArgs opts + ++ extraArgs + ) + +libSuite :: ResolvedOpts -> IO () +libSuite opts = libSuiteWith opts (compilerExecutable (compiler opts)) (rtsArgs opts) + +libSuiteExtras :: ResolvedOpts -> IO () +libSuiteExtras opts = forM_ (extraCompilers opts) $ \compiler' -> + libSuiteWith opts compiler' [] + +cliTests :: ResolvedOpts -> IO () +cliTests opts = do + -- These are sorted in asc time used, quicker tests first. + timedCabalBin + opts + "cabal-install" + "test:long-tests" + ( jobsArgs opts + ++ tastyArgs opts + ) + + -- This doesn't work in parallel either. + timedCabalBin + opts + "cabal-install" + "test:unit-tests" + ( ["--num-threads", "1"] + ++ tastyArgs opts + ) + + -- Only single job, otherwise we fail with "Heap exhausted" + timedCabalBin + opts + "cabal-install" + "test:mem-use-tests" + ( ["--num-threads", "1"] + ++ tastyArgs opts + ) + + -- This test-suite doesn't like concurrency + timedCabalBin + opts + "cabal-install" + "test:integration-tests2" + ( [ "--num-threads" + , "1" + , "--with-ghc=" <> compilerExecutable (compiler opts) + ] + ++ tastyArgs opts + ) + +cliSuite :: ResolvedOpts -> IO () +cliSuite opts = do + cabal' <- cabalListBin opts "cabal-install:exe:cabal" + + timedCabalBin + opts + "cabal-testsuite" + "exe:cabal-tests" + ( [ "--builddir=" <> cabalTestsuiteBuildDir opts + , "--with-cabal=" <> cabal' + , "--with-ghc=" <> compilerExecutable (compiler opts) + , "--intree-cabal-lib=" <> cwd opts + , "--test-tmp=" <> cwd opts "testdb" + , -- This test suite doesn't support `--jobs` _or_ `--num-threads`! + "-j" + , show (jobs opts) + ] + ++ tastyArgs opts + ++ rtsArgs opts + ) + +solverBenchmarksTests :: ResolvedOpts -> IO () +solverBenchmarksTests opts = do + command <- cabalListBin opts "solver-benchmarks:test:unit-tests" + + timedWithCwd + opts + "Cabal" + command + [] + +solverBenchmarksRun :: ResolvedOpts -> IO () +solverBenchmarksRun opts = do + command <- cabalListBin opts "solver-benchmarks:exe:hackage-benchmark" + cabal' <- cabalListBin opts "cabal-install:exe:cabal" + + timedWithCwd + opts + "Cabal" + command + [ "--cabal1=" <> cabal opts + , "--cabal2=" <> cabal' + , "--trials=5" + , "--packages=Chart-diagrams" + , "--print-trials" + ] + +timeSummary :: ResolvedOpts -> IO () +timeSummary opts = do + endTime <- getAbsoluteTime + let totalDuration = diffAbsoluteTime endTime (startTime opts) + putStrLn $ + setSGRCode [SetConsoleIntensity BoldIntensity, SetColor Foreground Vivid Cyan] + <> "!!! Validation completed in " + <> formatDiffTime totalDuration + <> setSGRCode [Reset] diff --git a/project-cabal/pkgs/tests.config b/project-cabal/pkgs/tests.config index a9cec9c596f..75fe4af5ad7 100644 --- a/project-cabal/pkgs/tests.config +++ b/project-cabal/pkgs/tests.config @@ -2,3 +2,4 @@ packages: Cabal-QuickCheck , Cabal-tests , Cabal-tree-diff + , cabal-validate diff --git a/validate.sh b/validate.sh index b22e033f86e..b887b724e8f 100755 --- a/validate.sh +++ b/validate.sh @@ -1,554 +1,3 @@ -#!/usr/bin/env bash -# shellcheck disable=SC2086 +#!/usr/bin/env sh -# default config -####################################################################### - -# We use the default ghc in PATH as default -# Use the ghc-x.y.z trigger several errors in windows: -# * It triggers the max path length issue: -# See https://github.com/haskell/cabal/issues/6271#issuecomment-1065102255 -# * It triggers a `createProcess: does not exist` error in units tests -# See https://github.com/haskell/cabal/issues/8049 -HC=ghc -CABAL=cabal -JOBS="" -LIBTESTS=true -CLITESTS=true -CABALSUITETESTS=true -LIBONLY=false -DEPSONLY=false -DOCTEST=false -BENCHMARKS=false -VERBOSE=false -HACKAGETESTSALL=false - -TARGETS="" -STEPS="" -EXTRAHCS="" - -LISTSTEPS=false - -# Help -####################################################################### - -show_usage() { -cat <&1 - else - "$@" > "$OUTPUT" 2>&1 - fi - # echo "MOCK" > "$OUTPUT" - RET=$? - - end_time=$(date +%s) - duration=$((end_time - start_time)) - tduration=$((end_time - JOB_START_TIME)) - - if [ $RET -eq 0 ]; then - if ! $VERBOSE; then - # if output is relatively short, show everything - if [ "$(wc -l < "$OUTPUT")" -le 50 ]; then - cat "$OUTPUT" - else - echo "..." - tail -n 20 "$OUTPUT" - fi - - rm -f "$OUTPUT" - fi - - green "<<< $PRETTYCMD" "($duration/$tduration sec)" - - # bottom-margin - echo "" - else - if ! $VERBOSE; then - cat "$OUTPUT" - fi - - red "<<< $PRETTYCMD" "($duration/$tduration sec, $RET)" - red "<<< $*" "($duration/$tduration sec, $RET)" - rm -f "$OUTPUT" - exit 1 - fi -} - -print_header() { - TITLE=$1 - TITLEPAT="$(echo "$TITLE"|sed 's:.:=:g')" - cyan "===X========================================================================== $(date +%T) ===" \ - | sed "s#X$TITLEPAT=# $TITLE #" - -} - -# getopt -####################################################################### - -while [ $# -gt 0 ]; do - arg=$1 - case $arg in - --help) - show_usage - exit - ;; - -j|--jobs) - JOBS="$2" - shift - shift - ;; - --lib-only) - LIBONLY=true - shift - ;; - --cli) - LIBONLY=false - shift - ;; - --run-lib-tests) - LIBTESTS=true - shift - ;; - --no-run-lib-tests) - LIBTESTS=false - shift - ;; - --run-cli-tests) - CLITESTS=true - shift - ;; - --no-run-cli-tests) - CLITESTS=false - shift - ;; - --run-lib-suite) - LIBSUITE=true - shift - ;; - --no-run-lib-suite) - LIBSUITE=false - shift - ;; - --run-cli-suite) - CLISUITE=true - shift - ;; - --no-run-cli-suite) - CLISUITE=false - shift - ;; - -w|--with-compiler) - HC=$2 - shift - shift - ;; - --with-cabal) - CABAL=$2 - shift - shift - ;; - --extra-hc) - EXTRAHCS="$EXTRAHCS $2" - shift - shift - ;; - --doctest) - DOCTEST=true - shift - ;; - --no-doctest) - DOCTEST=false - shift - ;; - --solver-benchmarks) - BENCHMARKS=true - shift - ;; - --no-solver-benchmarks) - BENCHMARKS=false - shift - ;; - --complete-hackage-tests) - HACKAGETESTSALL=true - shift - ;; - --partial-hackage-tests) - HACKAGETESTSALL=false - shift - ;; - -v|--verbose) - VERBOSE=true - shift - ;; - -q|--quiet) - VERBOSE=false - shift - ;; - -s|--step) - STEPS="$STEPS $2" - shift - shift - ;; - --list-steps) - LISTSTEPS=true - shift - ;; - *) - echo "Unknown option $arg" - exit 1 - esac -done - -# calculate steps and build targets -####################################################################### - -# If there are no explicit steps given calculate them -if $LIBONLY; then - CLITESTS=false - CLISUITE=false - BENCHMARKS=false -fi - -if [ -z "$STEPS" ]; then - STEPS="print-config print-tool-versions" - STEPS="$STEPS build" - if $DOCTEST; then STEPS="$STEPS doctest"; fi - if $LIBTESTS; then STEPS="$STEPS lib-tests"; fi - if $LIBSUITE; then STEPS="$STEPS lib-suite"; fi - if $LIBSUITE && [ -n "$EXTRAHCS" ]; - then STEPS="$STEPS lib-suite-extras"; fi - if $CLITESTS; then STEPS="$STEPS cli-tests"; fi - if $CLISUITE; then STEPS="$STEPS cli-suite"; fi - if $BENCHMARKS; then STEPS="$STEPS solver-benchmarks-tests solver-benchmarks-run"; fi - STEPS="$STEPS time-summary" -fi - -TARGETS="Cabal Cabal-hooks cabal-testsuite Cabal-tests Cabal-QuickCheck Cabal-tree-diff Cabal-described" -if ! $LIBONLY; then TARGETS="$TARGETS cabal-install cabal-install-solver cabal-benchmarks"; fi -if $BENCHMARKS; then TARGETS="$TARGETS solver-benchmarks"; fi - -if $LISTSTEPS; then - echo "Targets: $TARGETS" - echo "Steps: $STEPS" - exit -fi - -# Adjust runtime configuration -####################################################################### - -if [ -z "$JOBS" ]; then - if command -v nproc >/dev/null; then - JOBS=$(nproc) - else - echo "Warning: \`nproc\` not found, setting \`--jobs\` to default of 4." - JOBS=4 - fi -fi - -TESTSUITEJOBS="-j$JOBS" -JOBS="-j$JOBS" - -# assume compiler is GHC -RUNHASKELL=$(echo "$HC" | sed -E 's/ghc(-[0-9.]*)$/runghc\1/') - -ARCH=$(uname -m) - -case "$ARCH" in - arm64) - ARCH=aarch64 - ;; - x86_64) - ARCH=x86_64 - ;; - *) - echo "Warning: Unknown architecture '$ARCH'" - ;; -esac - -OS=$(uname) - -case "$OS" in - MINGW64*) - ARCH="$ARCH-windows" - ;; - Linux) - ARCH="$ARCH-linux" - ;; - Darwin) - ARCH="$ARCH-osx" - ;; - *) - echo "Warning: Unknown operating system '$OS'" - ARCH="$ARCH-$OS" - ;; -esac - -if $LIBONLY; then - PROJECTFILE=cabal.validate-libonly.project -else - PROJECTFILE=cabal.validate.project -fi - -BASEHC=ghc-$($HC --numeric-version) -BUILDDIR=dist-newstyle-validate-$BASEHC -CABAL_TESTSUITE_BDIR="$(pwd)/$BUILDDIR/build/$ARCH/$BASEHC/cabal-testsuite-3" - -CABALNEWBUILD="${CABAL} build $JOBS -w $HC --builddir=$BUILDDIR --project-file=$PROJECTFILE" -CABALLISTBIN="${CABAL} list-bin --builddir=$BUILDDIR --project-file=$PROJECTFILE" - -# See https://github.com/haskell/cabal/issues/9571 for why we set this for Windows -RTSOPTS="$([ $ARCH = "x86_64-windows" ] && [ "$($HC --numeric-version)" != "9.0.2" ] && [ "$(echo -e "$(ghc --numeric-version)\n9.0.2" | sort -V | head -n1)" = "9.0.2" ] && echo "+RTS --io-manager=native" || echo "")" - -# header -####################################################################### - -step_print_config() { -print_header print-config - -cat < Date: Fri, 6 Sep 2024 18:16:47 -0700 Subject: [PATCH 173/207] Split `cabal-validate` into modules This disentangles the utility boilerplate from the validation logic, making the `Main.hs` module much easier to read and modify. --- cabal-validate/cabal-validate.cabal | 26 +- cabal-validate/main/Main.hs | 954 ---------------------------- cabal-validate/src/Cli.hs | 381 +++++++++++ cabal-validate/src/ClockUtil.hs | 26 + cabal-validate/src/Main.hs | 379 +++++++++++ cabal-validate/src/OutputUtil.hs | 76 +++ cabal-validate/src/ProcessUtil.hs | 116 ++++ cabal-validate/src/Step.hs | 50 ++ 8 files changed, 1045 insertions(+), 963 deletions(-) delete mode 100644 cabal-validate/main/Main.hs create mode 100644 cabal-validate/src/Cli.hs create mode 100644 cabal-validate/src/ClockUtil.hs create mode 100644 cabal-validate/src/Main.hs create mode 100644 cabal-validate/src/OutputUtil.hs create mode 100644 cabal-validate/src/ProcessUtil.hs create mode 100644 cabal-validate/src/Step.hs diff --git a/cabal-validate/cabal-validate.cabal b/cabal-validate/cabal-validate.cabal index 938c4aadde8..ccd6762c6eb 100644 --- a/cabal-validate/cabal-validate.cabal +++ b/cabal-validate/cabal-validate.cabal @@ -7,26 +7,34 @@ author: Cabal Development Team synopsis: An internal tool for building and testing the Cabal package manager build-type: Simple -common warnings +common common ghc-options: -Wall -executable cabal-validate - import: warnings + if impl(ghc <9.6) + -- Pattern exhaustiveness checker is not as good, misses a case. + ghc-options: -Wno-incomplete-patterns + default-language: Haskell2010 default-extensions: OverloadedStrings , TypeApplications - ghc-options: -O -threaded -rtsopts -with-rtsopts=-N - if impl(ghc <9.6) - -- Pattern exhaustiveness checker is not as good, misses a case. - ghc-options: -Wno-incomplete-patterns +executable cabal-validate + import: common + ghc-options: -O -threaded -rtsopts -with-rtsopts=-N main-is: Main.hs - hs-source-dirs: main + hs-source-dirs: src + + other-modules: + , Cli + , ClockUtil + , OutputUtil + , ProcessUtil + , Step build-depends: - base >=4 && <5 + , base >=4 && <5 , ansi-terminal >=1 && <2 , bytestring >=0.11 && <1 , containers >=0.6 && <1 diff --git a/cabal-validate/main/Main.hs b/cabal-validate/main/Main.hs deleted file mode 100644 index 9da91cc9a87..00000000000 --- a/cabal-validate/main/Main.hs +++ /dev/null @@ -1,954 +0,0 @@ -module Main where - -import Control.Applicative (Alternative (many, (<|>)), (<**>)) -import Control.Exception (Exception (displayException), catch, throw, throwIO) -import Control.Monad (forM_, unless, when) -import Data.ByteString.Lazy (ByteString) -import qualified Data.ByteString.Lazy as ByteString -import Data.Data (Typeable) -import Data.Map.Strict (Map) -import qualified Data.Map.Strict as Map -import Data.Maybe (listToMaybe) -import Data.Text (Text) -import qualified Data.Text as T -import qualified Data.Text.IO as T -import qualified Data.Text.Lazy as T (toStrict) -import qualified Data.Text.Lazy.Encoding as T (decodeUtf8) -import Data.Time.Clock (DiffTime, secondsToDiffTime) -import Data.Time.Clock.System (getSystemTime, systemToTAITime) -import Data.Time.Clock.TAI (AbsoluteTime, diffAbsoluteTime) -import Data.Time.Format (defaultTimeLocale, formatTime) -import Data.Version (Version, makeVersion, parseVersion, showVersion) -import GHC.Conc (getNumCapabilities) -import Options.Applicative - ( FlagFields - , Mod - , Parser - , ParserInfo - , auto - , execParser - , flag - , flag' - , fullDesc - , help - , helper - , hidden - , info - , long - , maybeReader - , option - , progDesc - , short - , strOption - , switch - , value - ) -import qualified Options.Applicative as Opt -import System.Console.ANSI - ( Color (Blue, Cyan, Green, Red) - , ColorIntensity (Vivid) - , ConsoleIntensity (BoldIntensity) - , ConsoleLayer (Foreground) - , SGR (Reset, SetColor, SetConsoleIntensity) - , setSGRCode - ) -import qualified System.Console.Terminal.Size as Terminal -import System.Directory (getCurrentDirectory, withCurrentDirectory) -import System.Exit (ExitCode (ExitFailure, ExitSuccess), exitFailure, exitSuccess) -import System.FilePath (()) -import System.Info (arch, os) -import System.Process.Typed (ExitCodeException (..), proc, readProcess, readProcessStdout_, runProcess) -import Text.ParserCombinators.ReadP (readP_to_S) - -tShow :: Show a => a -> Text -tShow = T.pack . show - -tSetSGRCode :: [SGR] -> Text -tSetSGRCode = T.pack . setSGRCode - -decodeStrip :: ByteString -> Text -decodeStrip = T.strip . T.toStrict . T.decodeUtf8 - --- | Command-line options, resolved with context from the environment. -data ResolvedOpts = ResolvedOpts - { verbose :: Bool - , jobs :: Int - , cwd :: FilePath - , startTime :: AbsoluteTime - , compiler :: Compiler - , extraCompilers :: [FilePath] - , cabal :: FilePath - , hackageTests :: HackageTests - , archPath :: FilePath - , projectFile :: FilePath - , tastyArgs :: [String] - , targets :: [String] - , steps :: [Step] - } - deriving (Show) - -data Compiler = Compiler - { compilerExecutable :: FilePath - , compilerVersion :: Version - } - deriving (Show) - -data VersionParseException = VersionParseException - { versionInput :: String - , versionExecutable :: FilePath - } - deriving (Typeable, Show) - -instance Exception VersionParseException where - displayException exception = - "Failed to parse `" - <> versionExecutable exception - <> " --numeric-version` output: " - <> show (versionInput exception) - -makeCompiler :: FilePath -> IO Compiler -makeCompiler executable = do - stdout <- - readProcessStdout_ $ - proc executable ["--numeric-version"] - let version = T.unpack $ T.strip $ T.toStrict $ T.decodeUtf8 stdout - parsedVersions = readP_to_S parseVersion version - -- Who needs error messages? Those aren't in the API. - maybeParsedVersion = - listToMaybe - [ parsed - | (parsed, []) <- parsedVersions - ] - parsedVersion = case maybeParsedVersion of - Just parsedVersion' -> parsedVersion' - Nothing -> - throw - VersionParseException - { versionInput = version - , versionExecutable = executable - } - - pure - Compiler - { compilerExecutable = executable - , compilerVersion = parsedVersion - } - -baseHc :: ResolvedOpts -> FilePath -baseHc opts = "ghc-" <> showVersion (compilerVersion $ compiler opts) - -baseBuildDir :: ResolvedOpts -> FilePath -baseBuildDir opts = "dist-newstyle-validate-" <> baseHc opts - -buildDir :: ResolvedOpts -> FilePath -buildDir opts = - cwd opts - baseBuildDir opts - "build" - archPath opts - baseHc opts - -jobsArgs :: ResolvedOpts -> [String] -jobsArgs opts = ["--num-threads", show $ jobs opts] - -cabalArgs :: ResolvedOpts -> [String] -cabalArgs opts = - [ "--jobs=" <> show (jobs opts) - , "--with-compiler=" <> compilerExecutable (compiler opts) - , "--builddir=" <> baseBuildDir opts - , "--project-file=" <> projectFile opts - ] - -cabalTestsuiteBuildDir :: ResolvedOpts -> FilePath -cabalTestsuiteBuildDir opts = - buildDir opts - "cabal-testsuite-3" - -cabalNewBuildArgs :: ResolvedOpts -> [String] -cabalNewBuildArgs opts = "build" : cabalArgs opts - -cabalListBinArgs :: ResolvedOpts -> [String] -cabalListBinArgs opts = "list-bin" : cabalArgs opts - -cabalListBin :: ResolvedOpts -> String -> IO FilePath -cabalListBin opts target = do - let args = cabalListBinArgs opts ++ [target] - stdout <- - readProcessStdout_ $ - proc (cabal opts) args - - pure (T.unpack $ T.strip $ T.toStrict $ T.decodeUtf8 stdout) - -rtsArgs :: ResolvedOpts -> [String] -rtsArgs opts = - case archPath opts of - "x86_64-windows" -> - -- See: https://github.com/haskell/cabal/issues/9571 - if compilerVersion (compiler opts) > makeVersion [9, 0, 2] - then ["+RTS", "--io-manager=native", "-RTS"] - else [] - _ -> [] - -resolveOpts :: Opts -> IO ResolvedOpts -resolveOpts opts = do - let optionals :: Bool -> [a] -> [a] - optionals True items = items - optionals False _ = [] - - optional :: Bool -> a -> [a] - optional keep item = optionals keep [item] - - steps' = - if not (null (rawSteps opts)) - then rawSteps opts - else - concat - [ - [ PrintConfig - , PrintToolVersions - , Build - ] - , optional (rawDoctest opts) Doctest - , optional (rawRunLibTests opts) LibTests - , optional (rawRunLibSuite opts) LibSuite - , optional (rawRunLibSuite opts && not (null (rawExtraCompilers opts))) LibSuiteExtras - , optional (rawRunCliTests opts && not (rawLibOnly opts)) CliTests - , optional (rawRunCliSuite opts && not (rawLibOnly opts)) CliSuite - , optionals (rawSolverBenchmarks opts) [SolverBenchmarksTests, SolverBenchmarksRun] - , [TimeSummary] - ] - - targets' = - concat - [ - [ "Cabal" - , "Cabal-hooks" - , "cabal-testsuite" - , "Cabal-tests" - , "Cabal-QuickCheck" - , "Cabal-tree-diff" - , "Cabal-described" - ] - , optionals - (CliTests `elem` steps') - [ "cabal-install" - , "cabal-install-solver" - , "cabal-benchmarks" - ] - , optional (rawSolverBenchmarks opts) "solver-benchmarks" - ] - - archPath' = - let osPath = - case os of - "darwin" -> "osx" - "linux" -> "linux" - "mingw32" -> "windows" - _ -> os -- TODO: Warning? - in arch <> "-" <> osPath - - projectFile' = - if rawLibOnly opts - then "cabal.validate-libonly.project" - else "cabal.validate.project" - - tastyArgs' = - "--hide-successes" - : case rawTastyPattern opts of - Just tastyPattern -> ["--pattern", tastyPattern] - Nothing -> [] - - when (rawListSteps opts) $ do - -- TODO: This should probably list _all_ available steps, not just the selected ones! - putStrLn "Targets:" - forM_ targets' $ \target -> do - putStrLn $ " " <> target - putStrLn "Steps:" - forM_ steps' $ \step -> do - putStrLn $ " " <> displayStep step - exitSuccess - - startTime' <- getAbsoluteTime - jobs' <- maybe getNumCapabilities pure (rawJobs opts) - cwd' <- getCurrentDirectory - compiler' <- makeCompiler (rawCompiler opts) - - pure - ResolvedOpts - { verbose = rawVerbose opts - , jobs = jobs' - , cwd = cwd' - , startTime = startTime' - , compiler = compiler' - , extraCompilers = rawExtraCompilers opts - , cabal = rawCabal opts - , archPath = archPath' - , projectFile = projectFile' - , hackageTests = rawHackageTests opts - , tastyArgs = tastyArgs' - , targets = targets' - , steps = steps' - } - --- | Command-line options. -data Opts = Opts - { rawVerbose :: Bool - , rawJobs :: Maybe Int - , rawCompiler :: FilePath - , rawCabal :: FilePath - , rawExtraCompilers :: [FilePath] - , rawTastyPattern :: Maybe String - , rawDoctest :: Bool - , rawSteps :: [Step] - , rawListSteps :: Bool - , rawLibOnly :: Bool - , rawRunLibTests :: Bool - , rawRunCliTests :: Bool - , rawRunLibSuite :: Bool - , rawRunCliSuite :: Bool - , rawSolverBenchmarks :: Bool - , rawHackageTests :: HackageTests - } - deriving (Show) - -optsParser :: Parser Opts -optsParser = - Opts - <$> ( flag' - True - ( short 'v' - <> long "verbose" - <> help "Always display build and test output" - ) - <|> flag - False - False - ( short 'q' - <> long "quiet" - <> help "Silence build and test output" - ) - ) - <*> option - (Just <$> auto) - ( short 'j' - <> long "jobs" - <> help "Passed to `cabal build --jobs`" - <> value Nothing - ) - <*> strOption - ( short 'w' - <> long "with-compiler" - <> help "Build Cabal with the given compiler instead of `ghc`" - <> value "ghc" - ) - <*> strOption - ( long "with-cabal" - <> help "Test the given `cabal-install` (the `cabal` on your `$PATH` is used for builds)" - <> value "cabal" - ) - <*> many - ( strOption - ( long "extra-hc" - <> help "Extra compilers to run the test suites against" - ) - ) - <*> option - (Just <$> Opt.str) - ( short 'p' - <> long "pattern" - <> help "Pattern to filter tests by" - <> value Nothing - ) - <*> boolOption - False - "doctest" - ( help "Run doctest on the `Cabal` library" - ) - <*> many - ( option - (maybeReader parseStep) - ( short 's' - <> long "step" - <> help "Run only a specific step (can be specified multiple times)" - ) - ) - <*> switch - ( long "list-steps" - <> help "List the available steps and exit" - ) - <*> ( flag' - True - ( long "lib-only" - <> help "Test only `Cabal` (the library)" - ) - <|> flag - False - False - ( long "cli" - <> help "Test `cabal-install` (the executable) in addition to `Cabal` (the library)" - ) - ) - <*> boolOption - True - "run-lib-tests" - ( help "Run tests for the `Cabal` library" - ) - <*> boolOption - True - "run-cli-tests" - ( help "Run client tests for the `cabal-install` executable" - ) - <*> boolOption - False - "run-lib-suite" - ( help "Run `cabal-testsuite` with the `Cabal` library" - ) - <*> boolOption - False - "run-cli-suite" - ( help "Run `cabal-testsuite` with the `cabal-install` executable" - ) - <*> boolOption - False - "solver-benchmarks" - ( help "Build and trial run `solver-benchmarks`" - ) - <*> ( flag' - CompleteHackageTests - ( long "complete-hackage-tests" - <> help "Run `hackage-tests` on complete Hackage data" - ) - <|> flag - NoHackageTests - PartialHackageTests - ( long "partial-hackage-tests" - <> help "Run `hackage-tests` on parts of Hackage data" - ) - ) - --- | Parse a boolean switch with separate names for the true and false options. -boolOption' :: Bool -> String -> String -> Mod FlagFields Bool -> Parser Bool -boolOption' defaultValue trueName falseName modifiers = - flag' True (modifiers <> long trueName) - <|> flag defaultValue False (modifiers <> hidden <> long falseName) - --- | Parse a boolean switch with a `--no-*` flag for setting the option to false. -boolOption :: Bool -> String -> Mod FlagFields Bool -> Parser Bool -boolOption defaultValue trueName = - boolOption' defaultValue trueName ("no-" <> trueName) - -fullOptsParser :: ParserInfo Opts -fullOptsParser = - info - (optsParser <**> helper) - ( fullDesc - <> progDesc "Test suite runner for `Cabal` and `cabal-install` developers" - ) - -data HackageTests - = CompleteHackageTests - | PartialHackageTests - | NoHackageTests - deriving (Show) - -data Step - = PrintConfig - | PrintToolVersions - | Build - | Doctest - | LibTests - | LibSuite - | LibSuiteExtras - | CliTests - | CliSuite - | SolverBenchmarksTests - | SolverBenchmarksRun - | TimeSummary - deriving (Eq, Enum, Bounded, Show) - -displayStep :: Step -> String -displayStep step = - case step of - PrintConfig -> "print-config" - PrintToolVersions -> "print-tool-versions" - Build -> "build" - Doctest -> "doctest" - LibTests -> "lib-tests" - LibSuite -> "lib-suite" - LibSuiteExtras -> "lib-suite-extras" - CliTests -> "cli-tests" - CliSuite -> "cli-suite" - SolverBenchmarksTests -> "solver-benchmarks-tests" - SolverBenchmarksRun -> "solver-benchmarks-run" - TimeSummary -> "time-summary" - -nameToStep :: Map String Step -nameToStep = - Map.fromList - [ (displayStep step, step) - | step <- [minBound .. maxBound] - ] - -parseStep :: String -> Maybe Step -parseStep step = Map.lookup step nameToStep - -runStep :: ResolvedOpts -> Step -> IO () -runStep opts step = do - let title = displayStep step - printHeader title - let action = case step of - PrintConfig -> printConfig opts - PrintToolVersions -> printToolVersions opts - Build -> build opts - Doctest -> doctest opts - LibTests -> libTests opts - LibSuite -> libSuite opts - LibSuiteExtras -> libSuiteExtras opts - CliSuite -> cliSuite opts - CliTests -> cliTests opts - SolverBenchmarksTests -> solverBenchmarksTests opts - SolverBenchmarksRun -> solverBenchmarksRun opts - TimeSummary -> timeSummary opts - withTiming opts title action - T.putStrLn "" - -getTerminalWidth :: IO Int -getTerminalWidth = maybe 80 Terminal.width <$> Terminal.size @Int - -printHeader :: String -> IO () -printHeader title = do - columns <- getTerminalWidth - let left = 3 - right = columns - length title - left - 2 - header = - setSGRCode [SetConsoleIntensity BoldIntensity, SetColor Foreground Vivid Cyan] - <> replicate left '═' - <> " " - <> title - <> " " - <> replicate right '═' - <> setSGRCode [Reset] - putStrLn header - -withTiming :: ResolvedOpts -> String -> IO a -> IO a -withTiming opts title action = do - startTime' <- getAbsoluteTime - - result <- - (Right <$> action) - `catch` (\exception -> pure (Left (exception :: ExitCodeException))) - - endTime <- getAbsoluteTime - - let duration = diffAbsoluteTime endTime startTime' - totalDuration = diffAbsoluteTime endTime (startTime opts) - - case result of - Right inner -> do - putStrLn $ - setSGRCode [SetColor Foreground Vivid Green] - <> title - <> " finished after " - <> formatDiffTime duration - <> "\nTotal time so far: " - <> formatDiffTime totalDuration - <> setSGRCode [Reset] - - pure inner - Left _procFailed -> do - putStrLn $ - setSGRCode [SetColor Foreground Vivid Red] - <> title - <> " failed after " - <> formatDiffTime duration - <> "\nTotal time so far: " - <> formatDiffTime totalDuration - <> setSGRCode [Reset] - - -- TODO: `--keep-going` mode. - exitFailure - --- TODO: Shell escaping -displayCommand :: String -> [String] -> String -displayCommand command args = command <> " " <> unwords args - -timedCabalBin :: ResolvedOpts -> String -> String -> [String] -> IO () -timedCabalBin opts package component args = do - command <- cabalListBin opts (package <> ":" <> component) - timedWithCwd - opts - package - command - args - -timedWithCwd :: ResolvedOpts -> FilePath -> String -> [String] -> IO () -timedWithCwd opts cdPath command args = - withCurrentDirectory cdPath (timed opts command args) - -timed :: ResolvedOpts -> String -> [String] -> IO () -timed opts command args = do - let prettyCommand = displayCommand command args - process = proc command args - - startTime' <- getAbsoluteTime - - -- TODO: Replace `$HOME` or `opts.cwd` for brevity? - putStrLn $ - setSGRCode [SetColor Foreground Vivid Blue] - <> "$ " - <> prettyCommand - <> setSGRCode [Reset] - - (exitCode, rawStdout, rawStderr) <- - if verbose opts - then do - exitCode <- runProcess process - pure (exitCode, ByteString.empty, ByteString.empty) - else readProcess process - - endTime <- getAbsoluteTime - - let duration = diffAbsoluteTime endTime startTime' - totalDuration = diffAbsoluteTime endTime (startTime opts) - - output = decodeStrip rawStdout <> "\n" <> decodeStrip rawStderr - linesLimit = 50 - outputLines = T.lines output - hiddenLines = length outputLines - linesLimit - tailLines = drop hiddenLines outputLines - - case exitCode of - ExitSuccess -> do - unless (verbose opts) $ do - if hiddenLines <= 0 - then T.putStrLn output - else - T.putStrLn $ - "(" - <> tShow hiddenLines - <> " lines hidden, use `--verbose` to show)\n" - <> "...\n" - <> T.unlines tailLines - - putStrLn $ - setSGRCode [SetColor Foreground Vivid Green] - <> "Finished after " - <> formatDiffTime duration - <> ": " - <> prettyCommand - <> "\nTotal time so far: " - <> formatDiffTime totalDuration - <> setSGRCode [Reset] - ExitFailure exitCode' -> do - unless (verbose opts) $ do - T.putStrLn output - - putStrLn $ - setSGRCode [SetColor Foreground Vivid Red] - <> "Failed with exit code " - <> show exitCode' - <> " after " - <> formatDiffTime duration - <> ": " - <> prettyCommand - <> "\nTotal time so far: " - <> formatDiffTime totalDuration - <> setSGRCode [Reset] - - throwIO - ExitCodeException - { eceExitCode = exitCode - , eceProcessConfig = process - , eceStdout = rawStdout - , eceStderr = rawStderr - } - -getAbsoluteTime :: IO AbsoluteTime -getAbsoluteTime = systemToTAITime <$> getSystemTime - -formatDiffTime :: DiffTime -> String -formatDiffTime delta = - let minute = secondsToDiffTime 60 - hour = 60 * minute - in if delta >= hour - then formatTime defaultTimeLocale "%h:%02M:%02ES" delta - else - if delta >= minute - then formatTime defaultTimeLocale "%m:%2ES" delta - else formatTime defaultTimeLocale "%2Ess" delta - -main :: IO () -main = do - opts <- execParser fullOptsParser - resolvedOpts <- resolveOpts opts - mainInner resolvedOpts - -mainInner :: ResolvedOpts -> IO () -mainInner opts = - forM_ (steps opts) $ \step -> do - runStep opts step - -printConfig :: ResolvedOpts -> IO () -printConfig opts = do - putStrLn $ - "compiler: " - <> compilerExecutable (compiler opts) - <> "\ncabal-install: " - <> cabal opts - <> "\njobs: " - <> show (jobs opts) - <> "\nsteps: " - <> unwords (map displayStep (steps opts)) - <> "\nHackage tests: " - <> show (hackageTests opts) - <> "\nverbose: " - <> show (verbose opts) - <> "\nextra compilers: " - <> unwords (extraCompilers opts) - <> "\nextra RTS options: " - <> unwords (rtsArgs opts) - -printToolVersions :: ResolvedOpts -> IO () -printToolVersions opts = do - timed opts (compilerExecutable (compiler opts)) ["--version"] - timed opts (cabal opts) ["--version"] - - forM_ (extraCompilers opts) $ \compiler' -> do - timed opts compiler' ["--version"] - -build :: ResolvedOpts -> IO () -build opts = do - printHeader "build (dry run)" - timed - opts - (cabal opts) - ( cabalNewBuildArgs opts - ++ targets opts - ++ ["--dry-run"] - ) - - printHeader "build (full build plan; cached and to-be-built dependencies)" - timed - opts - "jq" - [ "-r" - , -- TODO: Maybe use `cabal-plan`? It's a heavy dependency though... - ".\"install-plan\" | map(.\"pkg-name\" + \"-\" + .\"pkg-version\" + \" \" + .\"component-name\") | join(\"\n\")" - , baseBuildDir opts "cache" "plan.json" - ] - - printHeader "build (actual build)" - timed - opts - (cabal opts) - (cabalNewBuildArgs opts ++ targets opts) - -doctest :: ResolvedOpts -> IO () -doctest opts = do - timed - opts - "cabal-env" - [ "--name" - , "doctest-cabal" - , "--transitive" - , "QuickCheck" - ] - - timed - opts - "cabal-env" - [ "--name" - , "doctest-cabal" - , "array" - , "bytestring" - , "containers" - , "deepseq" - , "directory" - , "filepath" - , "pretty" - , "process" - , "time" - , "binary" - , "unix" - , "text" - , "parsec" - , "mtl" - ] - - timed - opts - "doctest" - [ "-package-env=doctest-Cabal" - , "--fast" - , "Cabal/Distribution" - , "Cabal/Language" - ] - -libTests :: ResolvedOpts -> IO () -libTests opts = do - let runCabalTests' suite extraArgs = - timedCabalBin - opts - "Cabal-tests" - ("test:" <> suite) - ( tastyArgs opts - ++ jobsArgs opts - ++ extraArgs - ) - - runCabalTests suite = runCabalTests' suite [] - - runCabalTests' "unit-tests" ["--with-ghc=" <> compilerExecutable (compiler opts)] - runCabalTests "check-tests" - runCabalTests "parser-tests" - runCabalTests "rpmvercmp" - runCabalTests "no-thunks-test" - - runHackageTests opts - -runHackageTests :: ResolvedOpts -> IO () -runHackageTests opts - | NoHackageTests <- hackageTests opts = pure () - | otherwise = do - command <- cabalListBin opts "Cabal-tests:test:hackage-tests" - - let - -- See #10284 for why this value is pinned. - hackageTestsIndexState = "--index-state=2024-08-25" - - hackageTest args = - timedWithCwd - opts - "Cabal-tests" - command - (args ++ [hackageTestsIndexState]) - - hackageTest ["read-fields"] - - case hackageTests opts of - CompleteHackageTests -> do - hackageTest ["parsec"] - hackageTest ["roundtrip"] - PartialHackageTests -> do - hackageTest ["parsec", "d"] - hackageTest ["roundtrip", "k"] - -libSuiteWith :: ResolvedOpts -> FilePath -> [String] -> IO () -libSuiteWith opts ghc extraArgs = - timedCabalBin - opts - "cabal-testsuite" - "exe:cabal-tests" - ( [ "--builddir=" <> cabalTestsuiteBuildDir opts - , "--with-ghc=" <> ghc - , -- This test suite doesn't support `--jobs` _or_ `--num-threads`! - "-j" <> show (jobs opts) - ] - ++ tastyArgs opts - ++ extraArgs - ) - -libSuite :: ResolvedOpts -> IO () -libSuite opts = libSuiteWith opts (compilerExecutable (compiler opts)) (rtsArgs opts) - -libSuiteExtras :: ResolvedOpts -> IO () -libSuiteExtras opts = forM_ (extraCompilers opts) $ \compiler' -> - libSuiteWith opts compiler' [] - -cliTests :: ResolvedOpts -> IO () -cliTests opts = do - -- These are sorted in asc time used, quicker tests first. - timedCabalBin - opts - "cabal-install" - "test:long-tests" - ( jobsArgs opts - ++ tastyArgs opts - ) - - -- This doesn't work in parallel either. - timedCabalBin - opts - "cabal-install" - "test:unit-tests" - ( ["--num-threads", "1"] - ++ tastyArgs opts - ) - - -- Only single job, otherwise we fail with "Heap exhausted" - timedCabalBin - opts - "cabal-install" - "test:mem-use-tests" - ( ["--num-threads", "1"] - ++ tastyArgs opts - ) - - -- This test-suite doesn't like concurrency - timedCabalBin - opts - "cabal-install" - "test:integration-tests2" - ( [ "--num-threads" - , "1" - , "--with-ghc=" <> compilerExecutable (compiler opts) - ] - ++ tastyArgs opts - ) - -cliSuite :: ResolvedOpts -> IO () -cliSuite opts = do - cabal' <- cabalListBin opts "cabal-install:exe:cabal" - - timedCabalBin - opts - "cabal-testsuite" - "exe:cabal-tests" - ( [ "--builddir=" <> cabalTestsuiteBuildDir opts - , "--with-cabal=" <> cabal' - , "--with-ghc=" <> compilerExecutable (compiler opts) - , "--intree-cabal-lib=" <> cwd opts - , "--test-tmp=" <> cwd opts "testdb" - , -- This test suite doesn't support `--jobs` _or_ `--num-threads`! - "-j" - , show (jobs opts) - ] - ++ tastyArgs opts - ++ rtsArgs opts - ) - -solverBenchmarksTests :: ResolvedOpts -> IO () -solverBenchmarksTests opts = do - command <- cabalListBin opts "solver-benchmarks:test:unit-tests" - - timedWithCwd - opts - "Cabal" - command - [] - -solverBenchmarksRun :: ResolvedOpts -> IO () -solverBenchmarksRun opts = do - command <- cabalListBin opts "solver-benchmarks:exe:hackage-benchmark" - cabal' <- cabalListBin opts "cabal-install:exe:cabal" - - timedWithCwd - opts - "Cabal" - command - [ "--cabal1=" <> cabal opts - , "--cabal2=" <> cabal' - , "--trials=5" - , "--packages=Chart-diagrams" - , "--print-trials" - ] - -timeSummary :: ResolvedOpts -> IO () -timeSummary opts = do - endTime <- getAbsoluteTime - let totalDuration = diffAbsoluteTime endTime (startTime opts) - putStrLn $ - setSGRCode [SetConsoleIntensity BoldIntensity, SetColor Foreground Vivid Cyan] - <> "!!! Validation completed in " - <> formatDiffTime totalDuration - <> setSGRCode [Reset] diff --git a/cabal-validate/src/Cli.hs b/cabal-validate/src/Cli.hs new file mode 100644 index 00000000000..f82b5b6d944 --- /dev/null +++ b/cabal-validate/src/Cli.hs @@ -0,0 +1,381 @@ +module Cli + ( Opts (..) + , parseOpts + , HackageTests (..) + , Compiler (..) + , VersionParseException (..) + ) +where + +import Control.Applicative (Alternative (many, (<|>)), (<**>)) +import Control.Exception (Exception (displayException), throw) +import Control.Monad (forM_, when) +import Data.Data (Typeable) +import Data.Maybe (listToMaybe) +import qualified Data.Text as T +import qualified Data.Text.Lazy as T (toStrict) +import qualified Data.Text.Lazy.Encoding as T (decodeUtf8) +import Data.Version (Version, parseVersion) +import GHC.Conc (getNumCapabilities) +import Options.Applicative + ( FlagFields + , Mod + , Parser + , ParserInfo + , auto + , execParser + , flag + , flag' + , fullDesc + , help + , helper + , hidden + , info + , long + , maybeReader + , option + , progDesc + , short + , strOption + , switch + , value + ) +import qualified Options.Applicative as Opt +import System.Directory (getCurrentDirectory) +import System.Exit (exitSuccess) +import System.Info (arch, os) +import System.Process.Typed (proc, readProcessStdout_) +import Text.ParserCombinators.ReadP (readP_to_S) + +import ClockUtil (AbsoluteTime, getAbsoluteTime) +import Step (Step (..), displayStep, parseStep) + +-- | Command-line options, resolved with context from the environment. +data Opts = Opts + { verbose :: Bool + , jobs :: Int + , cwd :: FilePath + , startTime :: AbsoluteTime + , compiler :: Compiler + , extraCompilers :: [FilePath] + , cabal :: FilePath + , hackageTests :: HackageTests + , archPath :: FilePath + , projectFile :: FilePath + , tastyArgs :: [String] + , targets :: [String] + , steps :: [Step] + } + deriving (Show) + +data HackageTests + = CompleteHackageTests + | PartialHackageTests + | NoHackageTests + deriving (Show) + +data Compiler = Compiler + { compilerExecutable :: FilePath + , compilerVersion :: Version + } + deriving (Show) + +data VersionParseException = VersionParseException + { versionInput :: String + , versionExecutable :: FilePath + } + deriving (Typeable, Show) + +instance Exception VersionParseException where + displayException exception = + "Failed to parse `" + <> versionExecutable exception + <> " --numeric-version` output: " + <> show (versionInput exception) + +makeCompiler :: FilePath -> IO Compiler +makeCompiler executable = do + stdout <- + readProcessStdout_ $ + proc executable ["--numeric-version"] + let version = T.unpack $ T.strip $ T.toStrict $ T.decodeUtf8 stdout + parsedVersions = readP_to_S parseVersion version + -- Who needs error messages? Those aren't in the API. + maybeParsedVersion = + listToMaybe + [ parsed + | (parsed, []) <- parsedVersions + ] + parsedVersion = case maybeParsedVersion of + Just parsedVersion' -> parsedVersion' + Nothing -> + throw + VersionParseException + { versionInput = version + , versionExecutable = executable + } + + pure + Compiler + { compilerExecutable = executable + , compilerVersion = parsedVersion + } + +resolveOpts :: RawOpts -> IO Opts +resolveOpts opts = do + let optionals :: Bool -> [a] -> [a] + optionals True items = items + optionals False _ = [] + + optional :: Bool -> a -> [a] + optional keep item = optionals keep [item] + + steps' = + if not (null (rawSteps opts)) + then rawSteps opts + else + concat + [ + [ PrintConfig + , PrintToolVersions + , Build + ] + , optional (rawDoctest opts) Doctest + , optional (rawRunLibTests opts) LibTests + , optional (rawRunLibSuite opts) LibSuite + , optional (rawRunLibSuite opts && not (null (rawExtraCompilers opts))) LibSuiteExtras + , optional (rawRunCliTests opts && not (rawLibOnly opts)) CliTests + , optional (rawRunCliSuite opts && not (rawLibOnly opts)) CliSuite + , optionals (rawSolverBenchmarks opts) [SolverBenchmarksTests, SolverBenchmarksRun] + , [TimeSummary] + ] + + targets' = + concat + [ + [ "Cabal" + , "Cabal-hooks" + , "cabal-testsuite" + , "Cabal-tests" + , "Cabal-QuickCheck" + , "Cabal-tree-diff" + , "Cabal-described" + ] + , optionals + (CliTests `elem` steps') + [ "cabal-install" + , "cabal-install-solver" + , "cabal-benchmarks" + ] + , optional (rawSolverBenchmarks opts) "solver-benchmarks" + ] + + archPath' = + let osPath = + case os of + "darwin" -> "osx" + "linux" -> "linux" + "mingw32" -> "windows" + _ -> os -- TODO: Warning? + in arch <> "-" <> osPath + + projectFile' = + if rawLibOnly opts + then "cabal.validate-libonly.project" + else "cabal.validate.project" + + tastyArgs' = + "--hide-successes" + : case rawTastyPattern opts of + Just tastyPattern -> ["--pattern", tastyPattern] + Nothing -> [] + + when (rawListSteps opts) $ do + -- TODO: This should probably list _all_ available steps, not just the selected ones! + putStrLn "Targets:" + forM_ targets' $ \target -> do + putStrLn $ " " <> target + putStrLn "Steps:" + forM_ steps' $ \step -> do + putStrLn $ " " <> displayStep step + exitSuccess + + startTime' <- getAbsoluteTime + jobs' <- maybe getNumCapabilities pure (rawJobs opts) + cwd' <- getCurrentDirectory + compiler' <- makeCompiler (rawCompiler opts) + + pure + Opts + { verbose = rawVerbose opts + , jobs = jobs' + , cwd = cwd' + , startTime = startTime' + , compiler = compiler' + , extraCompilers = rawExtraCompilers opts + , cabal = rawCabal opts + , archPath = archPath' + , projectFile = projectFile' + , hackageTests = rawHackageTests opts + , tastyArgs = tastyArgs' + , targets = targets' + , steps = steps' + } + +-- | Command-line options. +data RawOpts = RawOpts + { rawVerbose :: Bool + , rawJobs :: Maybe Int + , rawCompiler :: FilePath + , rawCabal :: FilePath + , rawExtraCompilers :: [FilePath] + , rawTastyPattern :: Maybe String + , rawDoctest :: Bool + , rawSteps :: [Step] + , rawListSteps :: Bool + , rawLibOnly :: Bool + , rawRunLibTests :: Bool + , rawRunCliTests :: Bool + , rawRunLibSuite :: Bool + , rawRunCliSuite :: Bool + , rawSolverBenchmarks :: Bool + , rawHackageTests :: HackageTests + } + deriving (Show) + +optsParser :: Parser RawOpts +optsParser = + RawOpts + <$> ( flag' + True + ( short 'v' + <> long "verbose" + <> help "Always display build and test output" + ) + <|> flag + False + False + ( short 'q' + <> long "quiet" + <> help "Silence build and test output" + ) + ) + <*> option + (Just <$> auto) + ( short 'j' + <> long "jobs" + <> help "Passed to `cabal build --jobs`" + <> value Nothing + ) + <*> strOption + ( short 'w' + <> long "with-compiler" + <> help "Build Cabal with the given compiler instead of `ghc`" + <> value "ghc" + ) + <*> strOption + ( long "with-cabal" + <> help "Test the given `cabal-install` (the `cabal` on your `$PATH` is used for builds)" + <> value "cabal" + ) + <*> many + ( strOption + ( long "extra-hc" + <> help "Extra compilers to run the test suites against" + ) + ) + <*> option + (Just <$> Opt.str) + ( short 'p' + <> long "pattern" + <> help "Pattern to filter tests by" + <> value Nothing + ) + <*> boolOption + False + "doctest" + ( help "Run doctest on the `Cabal` library" + ) + <*> many + ( option + (maybeReader parseStep) + ( short 's' + <> long "step" + <> help "Run only a specific step (can be specified multiple times)" + ) + ) + <*> switch + ( long "list-steps" + <> help "List the available steps and exit" + ) + <*> ( flag' + True + ( long "lib-only" + <> help "Test only `Cabal` (the library)" + ) + <|> flag + False + False + ( long "cli" + <> help "Test `cabal-install` (the executable) in addition to `Cabal` (the library)" + ) + ) + <*> boolOption + True + "run-lib-tests" + ( help "Run tests for the `Cabal` library" + ) + <*> boolOption + True + "run-cli-tests" + ( help "Run client tests for the `cabal-install` executable" + ) + <*> boolOption + False + "run-lib-suite" + ( help "Run `cabal-testsuite` with the `Cabal` library" + ) + <*> boolOption + False + "run-cli-suite" + ( help "Run `cabal-testsuite` with the `cabal-install` executable" + ) + <*> boolOption + False + "solver-benchmarks" + ( help "Build and trial run `solver-benchmarks`" + ) + <*> ( flag' + CompleteHackageTests + ( long "complete-hackage-tests" + <> help "Run `hackage-tests` on complete Hackage data" + ) + <|> flag + NoHackageTests + PartialHackageTests + ( long "partial-hackage-tests" + <> help "Run `hackage-tests` on parts of Hackage data" + ) + ) + +-- | Parse a boolean switch with separate names for the true and false options. +boolOption' :: Bool -> String -> String -> Mod FlagFields Bool -> Parser Bool +boolOption' defaultValue trueName falseName modifiers = + flag' True (modifiers <> long trueName) + <|> flag defaultValue False (modifiers <> hidden <> long falseName) + +-- | Parse a boolean switch with a `--no-*` flag for setting the option to false. +boolOption :: Bool -> String -> Mod FlagFields Bool -> Parser Bool +boolOption defaultValue trueName = + boolOption' defaultValue trueName ("no-" <> trueName) + +fullOptsParser :: ParserInfo RawOpts +fullOptsParser = + info + (optsParser <**> helper) + ( fullDesc + <> progDesc "Test suite runner for `Cabal` and `cabal-install` developers" + ) + +parseOpts :: IO Opts +parseOpts = execParser fullOptsParser >>= resolveOpts diff --git a/cabal-validate/src/ClockUtil.hs b/cabal-validate/src/ClockUtil.hs new file mode 100644 index 00000000000..aba7930bd58 --- /dev/null +++ b/cabal-validate/src/ClockUtil.hs @@ -0,0 +1,26 @@ +module ClockUtil + ( DiffTime + , AbsoluteTime + , diffAbsoluteTime + , getAbsoluteTime + , formatDiffTime + ) where + +import Data.Time.Clock (DiffTime, secondsToDiffTime) +import Data.Time.Clock.System (getSystemTime, systemToTAITime) +import Data.Time.Clock.TAI (AbsoluteTime, diffAbsoluteTime) +import Data.Time.Format (defaultTimeLocale, formatTime) + +getAbsoluteTime :: IO AbsoluteTime +getAbsoluteTime = systemToTAITime <$> getSystemTime + +formatDiffTime :: DiffTime -> String +formatDiffTime delta = + let minute = secondsToDiffTime 60 + hour = 60 * minute + in if delta >= hour + then formatTime defaultTimeLocale "%h:%02M:%02ES" delta + else + if delta >= minute + then formatTime defaultTimeLocale "%m:%2ES" delta + else formatTime defaultTimeLocale "%2Ess" delta diff --git a/cabal-validate/src/Main.hs b/cabal-validate/src/Main.hs new file mode 100644 index 00000000000..6cf1818e9bc --- /dev/null +++ b/cabal-validate/src/Main.hs @@ -0,0 +1,379 @@ +module Main where + +import Control.Monad (forM_) +import qualified Data.Text as T +import qualified Data.Text.IO as T +import qualified Data.Text.Lazy as T (toStrict) +import qualified Data.Text.Lazy.Encoding as T (decodeUtf8) +import Data.Version (makeVersion, showVersion) +import System.Console.ANSI + ( Color (Cyan) + , ColorIntensity (Vivid) + , ConsoleIntensity (BoldIntensity) + , ConsoleLayer (Foreground) + , SGR (Reset, SetColor, SetConsoleIntensity) + , setSGRCode + ) +import System.FilePath (()) +import System.Process.Typed (proc, readProcessStdout_) + +import Cli (Compiler (..), HackageTests (..), Opts (..), parseOpts) +import ClockUtil (diffAbsoluteTime, formatDiffTime, getAbsoluteTime) +import OutputUtil (printHeader, withTiming) +import ProcessUtil (timed, timedWithCwd) +import Step (Step (..), displayStep) + +main :: IO () +main = do + opts <- parseOpts + forM_ (steps opts) $ \step -> do + runStep opts step + +baseHc :: Opts -> FilePath +baseHc opts = "ghc-" <> showVersion (compilerVersion $ compiler opts) + +baseBuildDir :: Opts -> FilePath +baseBuildDir opts = "dist-newstyle-validate-" <> baseHc opts + +buildDir :: Opts -> FilePath +buildDir opts = + cwd opts + baseBuildDir opts + "build" + archPath opts + baseHc opts + +jobsArgs :: Opts -> [String] +jobsArgs opts = ["--num-threads", show $ jobs opts] + +cabalArgs :: Opts -> [String] +cabalArgs opts = + [ "--jobs=" <> show (jobs opts) + , "--with-compiler=" <> compilerExecutable (compiler opts) + , "--builddir=" <> baseBuildDir opts + , "--project-file=" <> projectFile opts + ] + +cabalTestsuiteBuildDir :: Opts -> FilePath +cabalTestsuiteBuildDir opts = + buildDir opts + "cabal-testsuite-3" + +cabalNewBuildArgs :: Opts -> [String] +cabalNewBuildArgs opts = "build" : cabalArgs opts + +cabalListBinArgs :: Opts -> [String] +cabalListBinArgs opts = "list-bin" : cabalArgs opts + +cabalListBin :: Opts -> String -> IO FilePath +cabalListBin opts target = do + let args = cabalListBinArgs opts ++ [target] + stdout <- + readProcessStdout_ $ + proc (cabal opts) args + + pure (T.unpack $ T.strip $ T.toStrict $ T.decodeUtf8 stdout) + +rtsArgs :: Opts -> [String] +rtsArgs opts = + case archPath opts of + "x86_64-windows" -> + -- See: https://github.com/haskell/cabal/issues/9571 + if compilerVersion (compiler opts) > makeVersion [9, 0, 2] + then ["+RTS", "--io-manager=native", "-RTS"] + else [] + _ -> [] + +runStep :: Opts -> Step -> IO () +runStep opts step = do + let title = displayStep step + printHeader title + let action = case step of + PrintConfig -> printConfig opts + PrintToolVersions -> printToolVersions opts + Build -> build opts + Doctest -> doctest opts + LibTests -> libTests opts + LibSuite -> libSuite opts + LibSuiteExtras -> libSuiteExtras opts + CliSuite -> cliSuite opts + CliTests -> cliTests opts + SolverBenchmarksTests -> solverBenchmarksTests opts + SolverBenchmarksRun -> solverBenchmarksRun opts + TimeSummary -> timeSummary opts + withTiming opts title action + T.putStrLn "" + +timedCabalBin :: Opts -> String -> String -> [String] -> IO () +timedCabalBin opts package component args = do + command <- cabalListBin opts (package <> ":" <> component) + timedWithCwd + opts + package + command + args + +printConfig :: Opts -> IO () +printConfig opts = do + putStrLn $ + "compiler: " + <> compilerExecutable (compiler opts) + <> "\ncabal-install: " + <> cabal opts + <> "\njobs: " + <> show (jobs opts) + <> "\nsteps: " + <> unwords (map displayStep (steps opts)) + <> "\nHackage tests: " + <> show (hackageTests opts) + <> "\nverbose: " + <> show (verbose opts) + <> "\nextra compilers: " + <> unwords (extraCompilers opts) + <> "\nextra RTS options: " + <> unwords (rtsArgs opts) + +printToolVersions :: Opts -> IO () +printToolVersions opts = do + timed opts (compilerExecutable (compiler opts)) ["--version"] + timed opts (cabal opts) ["--version"] + + forM_ (extraCompilers opts) $ \compiler' -> do + timed opts compiler' ["--version"] + +build :: Opts -> IO () +build opts = do + printHeader "build (dry run)" + timed + opts + (cabal opts) + ( cabalNewBuildArgs opts + ++ targets opts + ++ ["--dry-run"] + ) + + printHeader "build (full build plan; cached and to-be-built dependencies)" + timed + opts + "jq" + [ "-r" + , -- TODO: Maybe use `cabal-plan`? It's a heavy dependency though... + ".\"install-plan\" | map(.\"pkg-name\" + \"-\" + .\"pkg-version\" + \" \" + .\"component-name\") | join(\"\n\")" + , baseBuildDir opts "cache" "plan.json" + ] + + printHeader "build (actual build)" + timed + opts + (cabal opts) + (cabalNewBuildArgs opts ++ targets opts) + +doctest :: Opts -> IO () +doctest opts = do + timed + opts + "cabal-env" + [ "--name" + , "doctest-cabal" + , "--transitive" + , "QuickCheck" + ] + + timed + opts + "cabal-env" + [ "--name" + , "doctest-cabal" + , "array" + , "bytestring" + , "containers" + , "deepseq" + , "directory" + , "filepath" + , "pretty" + , "process" + , "time" + , "binary" + , "unix" + , "text" + , "parsec" + , "mtl" + ] + + timed + opts + "doctest" + [ "-package-env=doctest-Cabal" + , "--fast" + , "Cabal/Distribution" + , "Cabal/Language" + ] + +libTests :: Opts -> IO () +libTests opts = do + let runCabalTests' suite extraArgs = + timedCabalBin + opts + "Cabal-tests" + ("test:" <> suite) + ( tastyArgs opts + ++ jobsArgs opts + ++ extraArgs + ) + + runCabalTests suite = runCabalTests' suite [] + + runCabalTests' "unit-tests" ["--with-ghc=" <> compilerExecutable (compiler opts)] + runCabalTests "check-tests" + runCabalTests "parser-tests" + runCabalTests "rpmvercmp" + runCabalTests "no-thunks-test" + + runHackageTests opts + +runHackageTests :: Opts -> IO () +runHackageTests opts + | NoHackageTests <- hackageTests opts = pure () + | otherwise = do + command <- cabalListBin opts "Cabal-tests:test:hackage-tests" + + let + -- See #10284 for why this value is pinned. + hackageTestsIndexState = "--index-state=2024-08-25" + + hackageTest args = + timedWithCwd + opts + "Cabal-tests" + command + (args ++ [hackageTestsIndexState]) + + hackageTest ["read-fields"] + + case hackageTests opts of + CompleteHackageTests -> do + hackageTest ["parsec"] + hackageTest ["roundtrip"] + PartialHackageTests -> do + hackageTest ["parsec", "d"] + hackageTest ["roundtrip", "k"] + +libSuiteWith :: Opts -> FilePath -> [String] -> IO () +libSuiteWith opts ghc extraArgs = + timedCabalBin + opts + "cabal-testsuite" + "exe:cabal-tests" + ( [ "--builddir=" <> cabalTestsuiteBuildDir opts + , "--with-ghc=" <> ghc + , -- This test suite doesn't support `--jobs` _or_ `--num-threads`! + "-j" <> show (jobs opts) + ] + ++ tastyArgs opts + ++ extraArgs + ) + +libSuite :: Opts -> IO () +libSuite opts = libSuiteWith opts (compilerExecutable (compiler opts)) (rtsArgs opts) + +libSuiteExtras :: Opts -> IO () +libSuiteExtras opts = forM_ (extraCompilers opts) $ \compiler' -> + libSuiteWith opts compiler' [] + +cliTests :: Opts -> IO () +cliTests opts = do + -- These are sorted in asc time used, quicker tests first. + timedCabalBin + opts + "cabal-install" + "test:long-tests" + ( jobsArgs opts + ++ tastyArgs opts + ) + + -- This doesn't work in parallel either. + timedCabalBin + opts + "cabal-install" + "test:unit-tests" + ( ["--num-threads", "1"] + ++ tastyArgs opts + ) + + -- Only single job, otherwise we fail with "Heap exhausted" + timedCabalBin + opts + "cabal-install" + "test:mem-use-tests" + ( ["--num-threads", "1"] + ++ tastyArgs opts + ) + + -- This test-suite doesn't like concurrency + timedCabalBin + opts + "cabal-install" + "test:integration-tests2" + ( [ "--num-threads" + , "1" + , "--with-ghc=" <> compilerExecutable (compiler opts) + ] + ++ tastyArgs opts + ) + +cliSuite :: Opts -> IO () +cliSuite opts = do + cabal' <- cabalListBin opts "cabal-install:exe:cabal" + + timedCabalBin + opts + "cabal-testsuite" + "exe:cabal-tests" + ( [ "--builddir=" <> cabalTestsuiteBuildDir opts + , "--with-cabal=" <> cabal' + , "--with-ghc=" <> compilerExecutable (compiler opts) + , "--intree-cabal-lib=" <> cwd opts + , "--test-tmp=" <> cwd opts "testdb" + , -- This test suite doesn't support `--jobs` _or_ `--num-threads`! + "-j" + , show (jobs opts) + ] + ++ tastyArgs opts + ++ rtsArgs opts + ) + +solverBenchmarksTests :: Opts -> IO () +solverBenchmarksTests opts = do + command <- cabalListBin opts "solver-benchmarks:test:unit-tests" + + timedWithCwd + opts + "Cabal" + command + [] + +solverBenchmarksRun :: Opts -> IO () +solverBenchmarksRun opts = do + command <- cabalListBin opts "solver-benchmarks:exe:hackage-benchmark" + cabal' <- cabalListBin opts "cabal-install:exe:cabal" + + timedWithCwd + opts + "Cabal" + command + [ "--cabal1=" <> cabal opts + , "--cabal2=" <> cabal' + , "--trials=5" + , "--packages=Chart-diagrams" + , "--print-trials" + ] + +timeSummary :: Opts -> IO () +timeSummary opts = do + endTime <- getAbsoluteTime + let totalDuration = diffAbsoluteTime endTime (startTime opts) + putStrLn $ + setSGRCode [SetConsoleIntensity BoldIntensity, SetColor Foreground Vivid Cyan] + <> "!!! Validation completed in " + <> formatDiffTime totalDuration + <> setSGRCode [Reset] diff --git a/cabal-validate/src/OutputUtil.hs b/cabal-validate/src/OutputUtil.hs new file mode 100644 index 00000000000..28d4542f6a3 --- /dev/null +++ b/cabal-validate/src/OutputUtil.hs @@ -0,0 +1,76 @@ +module OutputUtil + ( printHeader + , withTiming + ) where + +import Control.Exception (catch) +import System.Console.ANSI + ( Color (Cyan, Green, Red) + , ColorIntensity (Vivid) + , ConsoleIntensity (BoldIntensity) + , ConsoleLayer (Foreground) + , SGR (Reset, SetColor, SetConsoleIntensity) + , setSGRCode + ) +import qualified System.Console.Terminal.Size as Terminal +import System.Process.Typed (ExitCodeException) + +import Cli (Opts (..)) +import ClockUtil (diffAbsoluteTime, formatDiffTime, getAbsoluteTime) +import System.Exit (exitFailure) + +getTerminalWidth :: IO Int +getTerminalWidth = maybe 80 Terminal.width <$> Terminal.size @Int + +printHeader :: String -> IO () +printHeader title = do + columns <- getTerminalWidth + let left = 3 + right = columns - length title - left - 2 + header = + setSGRCode [SetConsoleIntensity BoldIntensity, SetColor Foreground Vivid Cyan] + <> replicate left '═' + <> " " + <> title + <> " " + <> replicate right '═' + <> setSGRCode [Reset] + putStrLn header + +withTiming :: Opts -> String -> IO a -> IO a +withTiming opts title action = do + startTime' <- getAbsoluteTime + + result <- + (Right <$> action) + `catch` (\exception -> pure (Left (exception :: ExitCodeException))) + + endTime <- getAbsoluteTime + + let duration = diffAbsoluteTime endTime startTime' + totalDuration = diffAbsoluteTime endTime (startTime opts) + + case result of + Right inner -> do + putStrLn $ + setSGRCode [SetColor Foreground Vivid Green] + <> title + <> " finished after " + <> formatDiffTime duration + <> "\nTotal time so far: " + <> formatDiffTime totalDuration + <> setSGRCode [Reset] + + pure inner + Left _procFailed -> do + putStrLn $ + setSGRCode [SetColor Foreground Vivid Red] + <> title + <> " failed after " + <> formatDiffTime duration + <> "\nTotal time so far: " + <> formatDiffTime totalDuration + <> setSGRCode [Reset] + + -- TODO: `--keep-going` mode. + exitFailure diff --git a/cabal-validate/src/ProcessUtil.hs b/cabal-validate/src/ProcessUtil.hs new file mode 100644 index 00000000000..cefdb37d13c --- /dev/null +++ b/cabal-validate/src/ProcessUtil.hs @@ -0,0 +1,116 @@ +module ProcessUtil + ( timed + , timedWithCwd + ) where + +import Control.Exception (throwIO) +import Control.Monad (unless) +import Data.ByteString.Lazy (ByteString) +import qualified Data.ByteString.Lazy as ByteString +import Data.Text (Text) +import qualified Data.Text as T +import qualified Data.Text.IO as T +import qualified Data.Text.Lazy as T (toStrict) +import qualified Data.Text.Lazy.Encoding as T (decodeUtf8) +import System.Console.ANSI + ( Color (Blue, Green, Red) + , ColorIntensity (Vivid) + , ConsoleLayer (Foreground) + , SGR (Reset, SetColor) + , setSGRCode + ) +import System.Directory (withCurrentDirectory) +import System.Exit (ExitCode (ExitFailure, ExitSuccess)) +import System.Process.Typed (ExitCodeException (..), proc, readProcess, runProcess) + +import Cli (Opts (..)) +import ClockUtil (diffAbsoluteTime, formatDiffTime, getAbsoluteTime) + +timedWithCwd :: Opts -> FilePath -> String -> [String] -> IO () +timedWithCwd opts cdPath command args = + withCurrentDirectory cdPath (timed opts command args) + +timed :: Opts -> String -> [String] -> IO () +timed opts command args = do + let prettyCommand = displayCommand command args + process = proc command args + + startTime' <- getAbsoluteTime + + -- TODO: Replace `$HOME` or `opts.cwd` for brevity? + putStrLn $ + setSGRCode [SetColor Foreground Vivid Blue] + <> "$ " + <> prettyCommand + <> setSGRCode [Reset] + + (exitCode, rawStdout, rawStderr) <- + if verbose opts + then do + exitCode <- runProcess process + pure (exitCode, ByteString.empty, ByteString.empty) + else readProcess process + + endTime <- getAbsoluteTime + + let duration = diffAbsoluteTime endTime startTime' + totalDuration = diffAbsoluteTime endTime (startTime opts) + + output = decodeStrip rawStdout <> "\n" <> decodeStrip rawStderr + linesLimit = 50 + outputLines = T.lines output + hiddenLines = length outputLines - linesLimit + tailLines = drop hiddenLines outputLines + + case exitCode of + ExitSuccess -> do + unless (verbose opts) $ do + if hiddenLines <= 0 + then T.putStrLn output + else + T.putStrLn $ + "(" + <> T.pack (show hiddenLines) + <> " lines hidden, use `--verbose` to show)\n" + <> "...\n" + <> T.unlines tailLines + + putStrLn $ + setSGRCode [SetColor Foreground Vivid Green] + <> "Finished after " + <> formatDiffTime duration + <> ": " + <> prettyCommand + <> "\nTotal time so far: " + <> formatDiffTime totalDuration + <> setSGRCode [Reset] + ExitFailure exitCode' -> do + unless (verbose opts) $ do + T.putStrLn output + + putStrLn $ + setSGRCode [SetColor Foreground Vivid Red] + <> "Failed with exit code " + <> show exitCode' + <> " after " + <> formatDiffTime duration + <> ": " + <> prettyCommand + <> "\nTotal time so far: " + <> formatDiffTime totalDuration + <> setSGRCode [Reset] + + throwIO + ExitCodeException + { eceExitCode = exitCode + , eceProcessConfig = process + , eceStdout = rawStdout + , eceStderr = rawStderr + } + +decodeStrip :: ByteString -> Text +decodeStrip = T.strip . T.toStrict . T.decodeUtf8 + +-- TODO: Shell escaping +displayCommand :: String -> [String] -> String +displayCommand command args = command <> " " <> unwords args diff --git a/cabal-validate/src/Step.hs b/cabal-validate/src/Step.hs new file mode 100644 index 00000000000..34d771073dc --- /dev/null +++ b/cabal-validate/src/Step.hs @@ -0,0 +1,50 @@ +module Step + ( Step (..) + , displayStep + , nameToStep + , parseStep + ) where + +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map + +data Step + = PrintConfig + | PrintToolVersions + | Build + | Doctest + | LibTests + | LibSuite + | LibSuiteExtras + | CliTests + | CliSuite + | SolverBenchmarksTests + | SolverBenchmarksRun + | TimeSummary + deriving (Eq, Enum, Bounded, Show) + +displayStep :: Step -> String +displayStep step = + case step of + PrintConfig -> "print-config" + PrintToolVersions -> "print-tool-versions" + Build -> "build" + Doctest -> "doctest" + LibTests -> "lib-tests" + LibSuite -> "lib-suite" + LibSuiteExtras -> "lib-suite-extras" + CliTests -> "cli-tests" + CliSuite -> "cli-suite" + SolverBenchmarksTests -> "solver-benchmarks-tests" + SolverBenchmarksRun -> "solver-benchmarks-run" + TimeSummary -> "time-summary" + +nameToStep :: Map String Step +nameToStep = + Map.fromList + [ (displayStep step, step) + | step <- [minBound .. maxBound] + ] + +parseStep :: String -> Maybe Step +parseStep step = Map.lookup step nameToStep From 6c519df41b0f0477a2c6768067ebcb6de32484fc Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 9 Sep 2024 13:07:22 -0700 Subject: [PATCH 174/207] cabal-validate: Add Haddock documentation + README --- cabal-validate/README.md | 23 ++++++++ cabal-validate/src/Cli.hs | 56 ++++++++++++++++++- cabal-validate/src/ClockUtil.hs | 8 +++ cabal-validate/src/Main.hs | 93 ++++++++++++++++++++++++------- cabal-validate/src/OutputUtil.hs | 22 +++++++- cabal-validate/src/ProcessUtil.hs | 31 ++++++++++- cabal-validate/src/Step.hs | 13 +++++ 7 files changed, 219 insertions(+), 27 deletions(-) create mode 100644 cabal-validate/README.md diff --git a/cabal-validate/README.md b/cabal-validate/README.md new file mode 100644 index 00000000000..5f40e9d28f1 --- /dev/null +++ b/cabal-validate/README.md @@ -0,0 +1,23 @@ +# cabal-validate + +`cabal-validate` is a script that builds and tests `Cabal` and `cabal-install`. +`cabal-validate` can be run with `validate.sh` in the repository root; +arguments passed to `validate.sh` will be forwarded to `cabal-validate`. + +Notable arguments include: + +- `-v`/`--verbose` to display build and test output in real-time, instead of + only if commands fail. +- `-s`/`--step` to run a specific step (e.g. `-s build -s lib-tests` will only + run the `build` and `lib-tests` steps). +- `-p`/`--pattern` to filter tests by a pattern. + +## Hacking on cabal-validate + +Overview of important modules: + +- `Main.hs` encodes all the commands that are run for each step. +- `Cli.hs` parses the CLI arguments and resolves default values from the + environment, like determining which steps are run by default or the `--jobs` + argument to pass to test suites. +- `Step.hs` lists the available steps. diff --git a/cabal-validate/src/Cli.hs b/cabal-validate/src/Cli.hs index f82b5b6d944..c0988d2ead4 100644 --- a/cabal-validate/src/Cli.hs +++ b/cabal-validate/src/Cli.hs @@ -1,3 +1,5 @@ +-- | Parse CLI arguments and resolve defaults from the environment. + module Cli ( Opts (..) , parseOpts @@ -53,36 +55,74 @@ import Step (Step (..), displayStep, parseStep) -- | Command-line options, resolved with context from the environment. data Opts = Opts { verbose :: Bool + -- ^ Whether to display build and test output. , jobs :: Int + -- ^ How many jobs to use when running tests. + -- + -- Defaults to the number of physical cores. , cwd :: FilePath + -- ^ Current working directory when @cabal-validate@ was started. , startTime :: AbsoluteTime + -- ^ System time when @cabal-validate@ was started. + -- + -- Used to determine the total test duration so far. , compiler :: Compiler + -- ^ Compiler to build Cabal with. + -- + -- Defaults to @ghc@. , extraCompilers :: [FilePath] + -- ^ Extra compilers to run @cabal-testsuite@ with. , cabal :: FilePath + -- ^ @cabal-install@ to build Cabal with. + -- + -- Defaults to @cabal@. , hackageTests :: HackageTests + -- ^ Whether to run tests on Hackage data, and if so how much. + -- + -- Defaults to `NoHackageTests`. , archPath :: FilePath + -- ^ The path for this system's architecture within the build directory. + -- + -- Like @x86_64-windows@ or @aarch64-osx@ or @arm-linux@. , projectFile :: FilePath + -- ^ Path to the @cabal.project@ file to use for running tests. , tastyArgs :: [String] + -- ^ Extra arguments to pass to @tasty@ test suites. + -- + -- This defaults to @--hide-successes@ (which cannot yet be changed) and + -- includes the @--pattern@ argument if one is given. , targets :: [String] + -- ^ Targets to build. , steps :: [Step] + -- ^ Steps to run. } deriving (Show) +-- | Whether to run tests on Hackage data, and if so how much. data HackageTests = CompleteHackageTests + -- ^ Run tests on complete Hackage data. | PartialHackageTests + -- ^ Run tests on partial Hackage data. | NoHackageTests + -- ^ Do not run tests on Hackage data. deriving (Show) +-- | A compiler executable and version number. data Compiler = Compiler { compilerExecutable :: FilePath + -- ^ The compiler's executable. , compilerVersion :: Version + -- ^ The compiler's version number. } deriving (Show) +-- | An `Exception` thrown when parsing @--numeric-version@ output from a compiler. data VersionParseException = VersionParseException { versionInput :: String + -- ^ The string we attempted to parse. , versionExecutable :: FilePath + -- ^ The compiler which produced the string. } deriving (Typeable, Show) @@ -93,6 +133,8 @@ instance Exception VersionParseException where <> " --numeric-version` output: " <> show (versionInput exception) +-- | Runs @ghc --numeric-version@ for the given executable to construct a +-- `Compiler`. makeCompiler :: FilePath -> IO Compiler makeCompiler executable = do stdout <- @@ -121,6 +163,9 @@ makeCompiler executable = do , compilerVersion = parsedVersion } +-- | Resolve options and default values from the environment. +-- +-- This makes the `Opts` type much nicer to deal with than `RawOpts`. resolveOpts :: RawOpts -> IO Opts resolveOpts opts = do let optionals :: Bool -> [a] -> [a] @@ -222,7 +267,7 @@ resolveOpts opts = do , steps = steps' } --- | Command-line options. +-- | Raw command-line options. data RawOpts = RawOpts { rawVerbose :: Bool , rawJobs :: Maybe Int @@ -243,6 +288,9 @@ data RawOpts = RawOpts } deriving (Show) +-- | `Parser` for `RawOpts`. +-- +-- See: `fullOptsParser` optsParser :: Parser RawOpts optsParser = RawOpts @@ -364,11 +412,13 @@ boolOption' defaultValue trueName falseName modifiers = flag' True (modifiers <> long trueName) <|> flag defaultValue False (modifiers <> hidden <> long falseName) --- | Parse a boolean switch with a `--no-*` flag for setting the option to false. +-- | Parse a boolean switch with a @--no-*@ flag for setting the option to false. boolOption :: Bool -> String -> Mod FlagFields Bool -> Parser Bool boolOption defaultValue trueName = boolOption' defaultValue trueName ("no-" <> trueName) +-- | Full `Parser` for `RawOpts`, which includes a @--help@ argument and +-- information about the program. fullOptsParser :: ParserInfo RawOpts fullOptsParser = info @@ -377,5 +427,7 @@ fullOptsParser = <> progDesc "Test suite runner for `Cabal` and `cabal-install` developers" ) +-- | Parse command-line arguments and resolve defaults from the environment, +-- producing `Opts`. parseOpts :: IO Opts parseOpts = execParser fullOptsParser >>= resolveOpts diff --git a/cabal-validate/src/ClockUtil.hs b/cabal-validate/src/ClockUtil.hs index aba7930bd58..664175789e7 100644 --- a/cabal-validate/src/ClockUtil.hs +++ b/cabal-validate/src/ClockUtil.hs @@ -1,3 +1,5 @@ +-- | Utilities for dealing with times and durations. + module ClockUtil ( DiffTime , AbsoluteTime @@ -11,9 +13,15 @@ import Data.Time.Clock.System (getSystemTime, systemToTAITime) import Data.Time.Clock.TAI (AbsoluteTime, diffAbsoluteTime) import Data.Time.Format (defaultTimeLocale, formatTime) +-- | Get the current time as an `AbsoluteTime`. getAbsoluteTime :: IO AbsoluteTime getAbsoluteTime = systemToTAITime <$> getSystemTime +-- | Format a `DiffTime` nicely. +-- +-- Short durations are formatted like @16.34s@, durations longer than a minute +-- are formatted like @22:34.68@, durations longer than an hour are formatted +-- like @1:32:04.68@. formatDiffTime :: DiffTime -> String formatDiffTime delta = let minute = secondsToDiffTime 60 diff --git a/cabal-validate/src/Main.hs b/cabal-validate/src/Main.hs index 6cf1818e9bc..c75c97baac5 100644 --- a/cabal-validate/src/Main.hs +++ b/cabal-validate/src/Main.hs @@ -1,4 +1,11 @@ -module Main where +-- | Entry-point to the @cabal-validate@ script. +-- +-- This module encodes all the commands that are run for each step in +-- `runStep`. +module Main + ( main + , runStep + ) where import Control.Monad (forM_) import qualified Data.Text as T @@ -23,18 +30,45 @@ import OutputUtil (printHeader, withTiming) import ProcessUtil (timed, timedWithCwd) import Step (Step (..), displayStep) +-- | Entry-point for @cabal-validate@. main :: IO () main = do opts <- parseOpts forM_ (steps opts) $ \step -> do runStep opts step +-- | Run a given `Step` with the given `Opts`. +runStep :: Opts -> Step -> IO () +runStep opts step = do + let title = displayStep step + printHeader title + let action = case step of + PrintConfig -> printConfig opts + PrintToolVersions -> printToolVersions opts + Build -> build opts + Doctest -> doctest opts + LibTests -> libTests opts + LibSuite -> libSuite opts + LibSuiteExtras -> libSuiteExtras opts + CliSuite -> cliSuite opts + CliTests -> cliTests opts + SolverBenchmarksTests -> solverBenchmarksTests opts + SolverBenchmarksRun -> solverBenchmarksRun opts + TimeSummary -> timeSummary opts + withTiming opts title action + T.putStrLn "" + +-- | Compiler with version number like @ghc-9.6.6@. baseHc :: Opts -> FilePath baseHc opts = "ghc-" <> showVersion (compilerVersion $ compiler opts) +-- | Base build directory for @cabal-validate@. baseBuildDir :: Opts -> FilePath baseBuildDir opts = "dist-newstyle-validate-" <> baseHc opts +-- | Absolute path to the build directory for this architecture. +-- +-- This is a path nested fairly deeply under `baseBuildDir`. buildDir :: Opts -> FilePath buildDir opts = cwd opts @@ -43,9 +77,14 @@ buildDir opts = archPath opts baseHc opts +-- | @--num-threads@ argument for test suites. +-- +-- This isn't always used because some test suites are finicky and only accept +-- @-j@. jobsArgs :: Opts -> [String] jobsArgs opts = ["--num-threads", show $ jobs opts] +-- | Default arguments for invoking @cabal@. cabalArgs :: Opts -> [String] cabalArgs opts = [ "--jobs=" <> show (jobs opts) @@ -54,17 +93,23 @@ cabalArgs opts = , "--project-file=" <> projectFile opts ] +-- | The `buildDir` for @cabal-testsuite-3@. cabalTestsuiteBuildDir :: Opts -> FilePath cabalTestsuiteBuildDir opts = buildDir opts "cabal-testsuite-3" +-- | Arguments for @cabal build@. cabalNewBuildArgs :: Opts -> [String] cabalNewBuildArgs opts = "build" : cabalArgs opts +-- | Arguments for @cabal list-bin@. +-- +-- This is used to find the binaries for various test suites. cabalListBinArgs :: Opts -> [String] cabalListBinArgs opts = "list-bin" : cabalArgs opts +-- | Get the binary for a given @cabal@ target by running @cabal list-bin@. cabalListBin :: Opts -> String -> IO FilePath cabalListBin opts target = do let args = cabalListBinArgs opts ++ [target] @@ -74,6 +119,9 @@ cabalListBin opts target = do pure (T.unpack $ T.strip $ T.toStrict $ T.decodeUtf8 stdout) +-- | Get the RTS arguments for invoking test suites. +-- +-- These seem to only be used for some of the test suites, I'm not sure why. rtsArgs :: Opts -> [String] rtsArgs opts = case archPath opts of @@ -84,26 +132,9 @@ rtsArgs opts = else [] _ -> [] -runStep :: Opts -> Step -> IO () -runStep opts step = do - let title = displayStep step - printHeader title - let action = case step of - PrintConfig -> printConfig opts - PrintToolVersions -> printToolVersions opts - Build -> build opts - Doctest -> doctest opts - LibTests -> libTests opts - LibSuite -> libSuite opts - LibSuiteExtras -> libSuiteExtras opts - CliSuite -> cliSuite opts - CliTests -> cliTests opts - SolverBenchmarksTests -> solverBenchmarksTests opts - SolverBenchmarksRun -> solverBenchmarksRun opts - TimeSummary -> timeSummary opts - withTiming opts title action - T.putStrLn "" - +-- | Run a binary built by @cabal@ and output timing information. +-- +-- This is used to run many of the test suites. timedCabalBin :: Opts -> String -> String -> [String] -> IO () timedCabalBin opts package component args = do command <- cabalListBin opts (package <> ":" <> component) @@ -113,6 +144,7 @@ timedCabalBin opts package component args = do command args +-- | Print the configuration for CI logs. printConfig :: Opts -> IO () printConfig opts = do putStrLn $ @@ -133,6 +165,7 @@ printConfig opts = do <> "\nextra RTS options: " <> unwords (rtsArgs opts) +-- | Print the versions of tools being used. printToolVersions :: Opts -> IO () printToolVersions opts = do timed opts (compilerExecutable (compiler opts)) ["--version"] @@ -141,6 +174,7 @@ printToolVersions opts = do forM_ (extraCompilers opts) $ \compiler' -> do timed opts compiler' ["--version"] +-- | Run the build step. build :: Opts -> IO () build opts = do printHeader "build (dry run)" @@ -168,6 +202,10 @@ build opts = do (cabal opts) (cabalNewBuildArgs opts ++ targets opts) +-- | Run doctests. +-- +-- This doesn't work on my machine, maybe @cabal.nix@ needs some love to +-- support @cabal-env@? doctest :: Opts -> IO () doctest opts = do timed @@ -209,6 +247,8 @@ doctest opts = do , "Cabal/Language" ] +-- | Run tests for the @Cabal@ library, and also `runHackageTests` if those are +-- enabled. libTests :: Opts -> IO () libTests opts = do let runCabalTests' suite extraArgs = @@ -231,6 +271,7 @@ libTests opts = do runHackageTests opts +-- | Run Hackage tests, if enabled. runHackageTests :: Opts -> IO () runHackageTests opts | NoHackageTests <- hackageTests opts = pure () @@ -258,6 +299,7 @@ runHackageTests opts hackageTest ["parsec", "d"] hackageTest ["roundtrip", "k"] +-- | Run @cabal-testsuite@ with the @Cabal@ library with a non-default GHC. libSuiteWith :: Opts -> FilePath -> [String] -> IO () libSuiteWith opts ghc extraArgs = timedCabalBin @@ -273,13 +315,18 @@ libSuiteWith opts ghc extraArgs = ++ extraArgs ) +-- | Run @cabal-testsuite@ with the @Cabal@ library with the default GHC. libSuite :: Opts -> IO () libSuite opts = libSuiteWith opts (compilerExecutable (compiler opts)) (rtsArgs opts) +-- | Run @cabal-testsuite@ with the @Cabal@ library with all extra GHCs. libSuiteExtras :: Opts -> IO () libSuiteExtras opts = forM_ (extraCompilers opts) $ \compiler' -> libSuiteWith opts compiler' [] +-- | Test the @cabal-install@ executable. +-- +-- These tests mostly run sequentially, so they're pretty slow as a result. cliTests :: Opts -> IO () cliTests opts = do -- These are sorted in asc time used, quicker tests first. @@ -321,6 +368,7 @@ cliTests opts = do ++ tastyArgs opts ) +-- | Run @cabal-testsuite@ with the @cabal-install@ executable. cliSuite :: Opts -> IO () cliSuite opts = do cabal' <- cabalListBin opts "cabal-install:exe:cabal" @@ -342,6 +390,7 @@ cliSuite opts = do ++ rtsArgs opts ) +-- | Run the @solver-benchmarks@ unit tests. solverBenchmarksTests :: Opts -> IO () solverBenchmarksTests opts = do command <- cabalListBin opts "solver-benchmarks:test:unit-tests" @@ -352,6 +401,7 @@ solverBenchmarksTests opts = do command [] +-- | Run the @solver-benchmarks@. solverBenchmarksRun :: Opts -> IO () solverBenchmarksRun opts = do command <- cabalListBin opts "solver-benchmarks:exe:hackage-benchmark" @@ -368,6 +418,7 @@ solverBenchmarksRun opts = do , "--print-trials" ] +-- | Print the total time taken so far. timeSummary :: Opts -> IO () timeSummary opts = do endTime <- getAbsoluteTime diff --git a/cabal-validate/src/OutputUtil.hs b/cabal-validate/src/OutputUtil.hs index 28d4542f6a3..7e92cdf0362 100644 --- a/cabal-validate/src/OutputUtil.hs +++ b/cabal-validate/src/OutputUtil.hs @@ -1,3 +1,4 @@ +-- | Utilities for printing terminal output. module OutputUtil ( printHeader , withTiming @@ -19,10 +20,17 @@ import Cli (Opts (..)) import ClockUtil (diffAbsoluteTime, formatDiffTime, getAbsoluteTime) import System.Exit (exitFailure) +-- | Get the width of the current terminal, or 80 if no width can be determined. getTerminalWidth :: IO Int getTerminalWidth = maybe 80 Terminal.width <$> Terminal.size @Int -printHeader :: String -> IO () +-- | Print a header for a given step. +-- +-- This is colorful and hard to miss in the output. +printHeader + :: String + -- ^ Title to print. + -> IO () printHeader title = do columns <- getTerminalWidth let left = 3 @@ -37,7 +45,17 @@ printHeader title = do <> setSGRCode [Reset] putStrLn header -withTiming :: Opts -> String -> IO a -> IO a +-- | Run an `IO` action and print duration information after it finishes. +withTiming + :: Opts + -- ^ @cabal-validate@ options. + -> String + -- ^ Name for describing the action. + -- + -- Used in a sentence like "@title@ finished after 16.34s". + -> IO a + -- ^ Action to time. + -> IO a withTiming opts title action = do startTime' <- getAbsoluteTime diff --git a/cabal-validate/src/ProcessUtil.hs b/cabal-validate/src/ProcessUtil.hs index cefdb37d13c..e0cf0bd9fc8 100644 --- a/cabal-validate/src/ProcessUtil.hs +++ b/cabal-validate/src/ProcessUtil.hs @@ -1,3 +1,4 @@ +-- | Utilities for running processes and timing them. module ProcessUtil ( timed , timedWithCwd @@ -26,11 +27,33 @@ import System.Process.Typed (ExitCodeException (..), proc, readProcess, runProce import Cli (Opts (..)) import ClockUtil (diffAbsoluteTime, formatDiffTime, getAbsoluteTime) -timedWithCwd :: Opts -> FilePath -> String -> [String] -> IO () +-- | Like `timed`, but runs the command in a given directory. +timedWithCwd + :: Opts + -- ^ @cabal-validate@ options. + -> FilePath + -- ^ Path to run the command in. + -> FilePath + -- ^ The command to run. + -> [String] + -- ^ Arguments to pass to the command. + -> IO () timedWithCwd opts cdPath command args = withCurrentDirectory cdPath (timed opts command args) -timed :: Opts -> String -> [String] -> IO () +-- | Run a command, displaying timing information after it finishes. +-- +-- This prints out the command to be executed before it's run, handles hiding +-- or showing output (according to the value of `verbose`), and throws an +-- `ExitCodeException` if the command fails. +timed + :: Opts + -- ^ @cabal-validate@ options. + -> FilePath + -- ^ The command to run. + -> [String] + -- ^ Arguments to pass to the command. + -> IO () timed opts command args = do let prettyCommand = displayCommand command args process = proc command args @@ -108,9 +131,13 @@ timed opts command args = do , eceStderr = rawStderr } +-- | Decode `ByteString` output from a command and strip whitespace at the +-- start and end. decodeStrip :: ByteString -> Text decodeStrip = T.strip . T.toStrict . T.decodeUtf8 +-- | Escape a shell command to display it to a user. +-- -- TODO: Shell escaping displayCommand :: String -> [String] -> String displayCommand command args = command <> " " <> unwords args diff --git a/cabal-validate/src/Step.hs b/cabal-validate/src/Step.hs index 34d771073dc..4fafc472061 100644 --- a/cabal-validate/src/Step.hs +++ b/cabal-validate/src/Step.hs @@ -1,3 +1,5 @@ +-- | The steps that can be run by @cabal-validate@. + module Step ( Step (..) , displayStep @@ -8,6 +10,7 @@ module Step import Data.Map.Strict (Map) import qualified Data.Map.Strict as Map +-- | A step to be run by @cabal-validate@. data Step = PrintConfig | PrintToolVersions @@ -23,6 +26,12 @@ data Step | TimeSummary deriving (Eq, Enum, Bounded, Show) +-- | Get the display identifier for a given `Step`. +-- +-- This is used to parse the @--step@ command-line argument. +-- +-- Note that these names are just kebab-case variants of the `Step` constructor +-- names; they do not attempt to describe the steps. displayStep :: Step -> String displayStep step = case step of @@ -39,6 +48,9 @@ displayStep step = SolverBenchmarksRun -> "solver-benchmarks-run" TimeSummary -> "time-summary" +-- | A map from step names to `Steps`. +-- +-- This is an inverse of `displayStep`. nameToStep :: Map String Step nameToStep = Map.fromList @@ -46,5 +58,6 @@ nameToStep = | step <- [minBound .. maxBound] ] +-- | Parse a string as a `Step`. parseStep :: String -> Maybe Step parseStep step = Map.lookup step nameToStep From 09f84e4759054a902677aeae3f2d610a060bdf90 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 30 Sep 2024 10:47:06 -0700 Subject: [PATCH 175/207] Remove `ansi-terminal` dependency --- cabal-validate/cabal-validate.cabal | 2 +- cabal-validate/src/ANSI.hs | 116 ++++++++++++++++++++++++++++ cabal-validate/src/Main.hs | 13 +--- cabal-validate/src/OutputUtil.hs | 21 ++--- cabal-validate/src/ProcessUtil.hs | 20 ++--- 5 files changed, 134 insertions(+), 38 deletions(-) create mode 100644 cabal-validate/src/ANSI.hs diff --git a/cabal-validate/cabal-validate.cabal b/cabal-validate/cabal-validate.cabal index ccd6762c6eb..582cf67434a 100644 --- a/cabal-validate/cabal-validate.cabal +++ b/cabal-validate/cabal-validate.cabal @@ -27,6 +27,7 @@ executable cabal-validate hs-source-dirs: src other-modules: + , ANSI , Cli , ClockUtil , OutputUtil @@ -35,7 +36,6 @@ executable cabal-validate build-depends: , base >=4 && <5 - , ansi-terminal >=1 && <2 , bytestring >=0.11 && <1 , containers >=0.6 && <1 , directory >=1.0 && <2 diff --git a/cabal-validate/src/ANSI.hs b/cabal-validate/src/ANSI.hs new file mode 100644 index 00000000000..79dabf66d77 --- /dev/null +++ b/cabal-validate/src/ANSI.hs @@ -0,0 +1,116 @@ +-- | ANSI escape sequences. +-- +-- This is a stripped-down version of the parts of the @ansi-terminal@ package +-- we use. +-- +-- See: + +module ANSI + ( SGR(..) + , setSGR + ) where + + +-- | Render a single numeric SGR sequence. +rawSGR :: Int -> String +rawSGR code = "\x1b[" <> show code <> "m" + +-- | Render a series of `SGR` escape sequences. +setSGR :: [SGR] -> String +setSGR = concat . map renderSGR + +-- | All of the SGR sequences we want to use. +data SGR + = Reset + | Bold + | Dim + | Italic + | Underline + + | Black + | Red + | Green + | Yellow + | Blue + | Magenta + | Cyan + | White + | Default + + | OnBlack + | OnRed + | OnGreen + | OnYellow + | OnBlue + | OnMagenta + | OnCyan + | OnWhite + | OnDefault + + | BoldBlack + | BoldRed + | BoldGreen + | BoldYellow + | BoldBlue + | BoldMagenta + | BoldCyan + | BoldWhite + + | OnBoldBlack + | OnBoldRed + | OnBoldGreen + | OnBoldYellow + | OnBoldBlue + | OnBoldMagenta + | OnBoldCyan + | OnBoldWhite + + deriving (Show) + +-- Render a single `SGR` sequence. +renderSGR :: SGR -> String +renderSGR code = + case code of + Reset -> rawSGR 0 + Bold -> rawSGR 1 + Dim -> rawSGR 2 + Italic -> rawSGR 3 + Underline -> rawSGR 4 + + Black -> rawSGR 30 + Red -> rawSGR 31 + Green -> rawSGR 32 + Yellow -> rawSGR 33 + Blue -> rawSGR 34 + Magenta -> rawSGR 35 + Cyan -> rawSGR 36 + White -> rawSGR 37 + Default -> rawSGR 39 + + OnBlack -> rawSGR 40 + OnRed -> rawSGR 41 + OnGreen -> rawSGR 42 + OnYellow -> rawSGR 43 + OnBlue -> rawSGR 44 + OnMagenta -> rawSGR 45 + OnCyan -> rawSGR 46 + OnWhite -> rawSGR 47 + OnDefault -> rawSGR 49 + + BoldBlack -> rawSGR 90 + BoldRed -> rawSGR 91 + BoldGreen -> rawSGR 92 + BoldYellow -> rawSGR 93 + BoldBlue -> rawSGR 94 + BoldMagenta -> rawSGR 95 + BoldCyan -> rawSGR 96 + BoldWhite -> rawSGR 97 + + OnBoldBlack -> rawSGR 100 + OnBoldRed -> rawSGR 101 + OnBoldGreen -> rawSGR 102 + OnBoldYellow -> rawSGR 103 + OnBoldBlue -> rawSGR 104 + OnBoldMagenta -> rawSGR 105 + OnBoldCyan -> rawSGR 106 + OnBoldWhite -> rawSGR 107 diff --git a/cabal-validate/src/Main.hs b/cabal-validate/src/Main.hs index c75c97baac5..2361179eeed 100644 --- a/cabal-validate/src/Main.hs +++ b/cabal-validate/src/Main.hs @@ -13,17 +13,10 @@ import qualified Data.Text.IO as T import qualified Data.Text.Lazy as T (toStrict) import qualified Data.Text.Lazy.Encoding as T (decodeUtf8) import Data.Version (makeVersion, showVersion) -import System.Console.ANSI - ( Color (Cyan) - , ColorIntensity (Vivid) - , ConsoleIntensity (BoldIntensity) - , ConsoleLayer (Foreground) - , SGR (Reset, SetColor, SetConsoleIntensity) - , setSGRCode - ) import System.FilePath (()) import System.Process.Typed (proc, readProcessStdout_) +import ANSI (SGR (BoldCyan, Reset), setSGR) import Cli (Compiler (..), HackageTests (..), Opts (..), parseOpts) import ClockUtil (diffAbsoluteTime, formatDiffTime, getAbsoluteTime) import OutputUtil (printHeader, withTiming) @@ -424,7 +417,7 @@ timeSummary opts = do endTime <- getAbsoluteTime let totalDuration = diffAbsoluteTime endTime (startTime opts) putStrLn $ - setSGRCode [SetConsoleIntensity BoldIntensity, SetColor Foreground Vivid Cyan] + setSGR [BoldCyan] <> "!!! Validation completed in " <> formatDiffTime totalDuration - <> setSGRCode [Reset] + <> setSGR [Reset] diff --git a/cabal-validate/src/OutputUtil.hs b/cabal-validate/src/OutputUtil.hs index 7e92cdf0362..afe6f96030f 100644 --- a/cabal-validate/src/OutputUtil.hs +++ b/cabal-validate/src/OutputUtil.hs @@ -5,17 +5,10 @@ module OutputUtil ) where import Control.Exception (catch) -import System.Console.ANSI - ( Color (Cyan, Green, Red) - , ColorIntensity (Vivid) - , ConsoleIntensity (BoldIntensity) - , ConsoleLayer (Foreground) - , SGR (Reset, SetColor, SetConsoleIntensity) - , setSGRCode - ) import qualified System.Console.Terminal.Size as Terminal import System.Process.Typed (ExitCodeException) +import ANSI (SGR (BoldCyan, BoldGreen, BoldRed, Reset), setSGR) import Cli (Opts (..)) import ClockUtil (diffAbsoluteTime, formatDiffTime, getAbsoluteTime) import System.Exit (exitFailure) @@ -36,13 +29,13 @@ printHeader title = do let left = 3 right = columns - length title - left - 2 header = - setSGRCode [SetConsoleIntensity BoldIntensity, SetColor Foreground Vivid Cyan] + setSGR [BoldCyan] <> replicate left '═' <> " " <> title <> " " <> replicate right '═' - <> setSGRCode [Reset] + <> setSGR [Reset] putStrLn header -- | Run an `IO` action and print duration information after it finishes. @@ -71,24 +64,24 @@ withTiming opts title action = do case result of Right inner -> do putStrLn $ - setSGRCode [SetColor Foreground Vivid Green] + setSGR [BoldGreen] <> title <> " finished after " <> formatDiffTime duration <> "\nTotal time so far: " <> formatDiffTime totalDuration - <> setSGRCode [Reset] + <> setSGR [Reset] pure inner Left _procFailed -> do putStrLn $ - setSGRCode [SetColor Foreground Vivid Red] + setSGR [BoldRed] <> title <> " failed after " <> formatDiffTime duration <> "\nTotal time so far: " <> formatDiffTime totalDuration - <> setSGRCode [Reset] + <> setSGR [Reset] -- TODO: `--keep-going` mode. exitFailure diff --git a/cabal-validate/src/ProcessUtil.hs b/cabal-validate/src/ProcessUtil.hs index e0cf0bd9fc8..19e987d5941 100644 --- a/cabal-validate/src/ProcessUtil.hs +++ b/cabal-validate/src/ProcessUtil.hs @@ -13,17 +13,11 @@ import qualified Data.Text as T import qualified Data.Text.IO as T import qualified Data.Text.Lazy as T (toStrict) import qualified Data.Text.Lazy.Encoding as T (decodeUtf8) -import System.Console.ANSI - ( Color (Blue, Green, Red) - , ColorIntensity (Vivid) - , ConsoleLayer (Foreground) - , SGR (Reset, SetColor) - , setSGRCode - ) import System.Directory (withCurrentDirectory) import System.Exit (ExitCode (ExitFailure, ExitSuccess)) import System.Process.Typed (ExitCodeException (..), proc, readProcess, runProcess) +import ANSI (SGR (BoldBlue, BoldGreen, BoldRed, Reset), setSGR) import Cli (Opts (..)) import ClockUtil (diffAbsoluteTime, formatDiffTime, getAbsoluteTime) @@ -62,10 +56,10 @@ timed opts command args = do -- TODO: Replace `$HOME` or `opts.cwd` for brevity? putStrLn $ - setSGRCode [SetColor Foreground Vivid Blue] + setSGR [BoldBlue] <> "$ " <> prettyCommand - <> setSGRCode [Reset] + <> setSGR [Reset] (exitCode, rawStdout, rawStderr) <- if verbose opts @@ -99,20 +93,20 @@ timed opts command args = do <> T.unlines tailLines putStrLn $ - setSGRCode [SetColor Foreground Vivid Green] + setSGR [BoldGreen] <> "Finished after " <> formatDiffTime duration <> ": " <> prettyCommand <> "\nTotal time so far: " <> formatDiffTime totalDuration - <> setSGRCode [Reset] + <> setSGR [Reset] ExitFailure exitCode' -> do unless (verbose opts) $ do T.putStrLn output putStrLn $ - setSGRCode [SetColor Foreground Vivid Red] + setSGR [BoldRed] <> "Failed with exit code " <> show exitCode' <> " after " @@ -121,7 +115,7 @@ timed opts command args = do <> prettyCommand <> "\nTotal time so far: " <> formatDiffTime totalDuration - <> setSGRCode [Reset] + <> setSGR [Reset] throwIO ExitCodeException From 9658752c2ae4d7513e719486466aaf8d56705af2 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 30 Sep 2024 10:53:47 -0700 Subject: [PATCH 176/207] Use `unlines` in `printConfig` --- cabal-validate/src/Main.hs | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/cabal-validate/src/Main.hs b/cabal-validate/src/Main.hs index 2361179eeed..590cc39167e 100644 --- a/cabal-validate/src/Main.hs +++ b/cabal-validate/src/Main.hs @@ -140,23 +140,25 @@ timedCabalBin opts package component args = do -- | Print the configuration for CI logs. printConfig :: Opts -> IO () printConfig opts = do - putStrLn $ - "compiler: " - <> compilerExecutable (compiler opts) - <> "\ncabal-install: " - <> cabal opts - <> "\njobs: " - <> show (jobs opts) - <> "\nsteps: " - <> unwords (map displayStep (steps opts)) - <> "\nHackage tests: " - <> show (hackageTests opts) - <> "\nverbose: " - <> show (verbose opts) - <> "\nextra compilers: " - <> unwords (extraCompilers opts) - <> "\nextra RTS options: " - <> unwords (rtsArgs opts) + putStr $ + unlines + [ "compiler: " + <> compilerExecutable (compiler opts) + , "cabal-install: " + <> cabal opts + , "jobs: " + <> show (jobs opts) + , "steps: " + <> unwords (map displayStep (steps opts)) + , "Hackage tests: " + <> show (hackageTests opts) + , "verbose: " + <> show (verbose opts) + , "extra compilers: " + <> unwords (extraCompilers opts) + , "extra RTS options: " + <> unwords (rtsArgs opts) + ] -- | Print the versions of tools being used. printToolVersions :: Opts -> IO () From 03de99264c229fa8106736d35a0bb93b7419d08e Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 30 Sep 2024 11:05:32 -0700 Subject: [PATCH 177/207] optsParser -> rawOptsParser --- cabal-validate/src/Cli.hs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/cabal-validate/src/Cli.hs b/cabal-validate/src/Cli.hs index c0988d2ead4..d0478b90d64 100644 --- a/cabal-validate/src/Cli.hs +++ b/cabal-validate/src/Cli.hs @@ -267,7 +267,8 @@ resolveOpts opts = do , steps = steps' } --- | Raw command-line options. +-- | Literate command-line options as supplied by the user, before resolving +-- defaults and other values from the environment. data RawOpts = RawOpts { rawVerbose :: Bool , rawJobs :: Maybe Int @@ -290,9 +291,9 @@ data RawOpts = RawOpts -- | `Parser` for `RawOpts`. -- --- See: `fullOptsParser` -optsParser :: Parser RawOpts -optsParser = +-- See: `fullRawOptsParser` +rawOptsParser :: Parser RawOpts +rawOptsParser = RawOpts <$> ( flag' True @@ -419,10 +420,10 @@ boolOption defaultValue trueName = -- | Full `Parser` for `RawOpts`, which includes a @--help@ argument and -- information about the program. -fullOptsParser :: ParserInfo RawOpts -fullOptsParser = +fullRawOptsParser :: ParserInfo RawOpts +fullRawOptsParser = info - (optsParser <**> helper) + (rawOptsParser <**> helper) ( fullDesc <> progDesc "Test suite runner for `Cabal` and `cabal-install` developers" ) @@ -430,4 +431,4 @@ fullOptsParser = -- | Parse command-line arguments and resolve defaults from the environment, -- producing `Opts`. parseOpts :: IO Opts -parseOpts = execParser fullOptsParser >>= resolveOpts +parseOpts = execParser fullRawOptsParser >>= resolveOpts From 2c96048925deee3b4e3e20962882d385cb5ad5a6 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 30 Sep 2024 11:05:49 -0700 Subject: [PATCH 178/207] withTiming: take `startTime` explicitly --- cabal-validate/src/Main.hs | 2 +- cabal-validate/src/OutputUtil.hs | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cabal-validate/src/Main.hs b/cabal-validate/src/Main.hs index 590cc39167e..79a8df67e7c 100644 --- a/cabal-validate/src/Main.hs +++ b/cabal-validate/src/Main.hs @@ -48,7 +48,7 @@ runStep opts step = do SolverBenchmarksTests -> solverBenchmarksTests opts SolverBenchmarksRun -> solverBenchmarksRun opts TimeSummary -> timeSummary opts - withTiming opts title action + withTiming (startTime opts) title action T.putStrLn "" -- | Compiler with version number like @ghc-9.6.6@. diff --git a/cabal-validate/src/OutputUtil.hs b/cabal-validate/src/OutputUtil.hs index afe6f96030f..075368def8c 100644 --- a/cabal-validate/src/OutputUtil.hs +++ b/cabal-validate/src/OutputUtil.hs @@ -9,8 +9,7 @@ import qualified System.Console.Terminal.Size as Terminal import System.Process.Typed (ExitCodeException) import ANSI (SGR (BoldCyan, BoldGreen, BoldRed, Reset), setSGR) -import Cli (Opts (..)) -import ClockUtil (diffAbsoluteTime, formatDiffTime, getAbsoluteTime) +import ClockUtil (AbsoluteTime, diffAbsoluteTime, formatDiffTime, getAbsoluteTime) import System.Exit (exitFailure) -- | Get the width of the current terminal, or 80 if no width can be determined. @@ -40,8 +39,8 @@ printHeader title = do -- | Run an `IO` action and print duration information after it finishes. withTiming - :: Opts - -- ^ @cabal-validate@ options. + :: AbsoluteTime + -- ^ Start time for the whole @cabal-validate@ run. -> String -- ^ Name for describing the action. -- @@ -49,7 +48,7 @@ withTiming -> IO a -- ^ Action to time. -> IO a -withTiming opts title action = do +withTiming startTime title action = do startTime' <- getAbsoluteTime result <- @@ -59,7 +58,7 @@ withTiming opts title action = do endTime <- getAbsoluteTime let duration = diffAbsoluteTime endTime startTime' - totalDuration = diffAbsoluteTime endTime (startTime opts) + totalDuration = diffAbsoluteTime endTime startTime case result of Right inner -> do From c27f9772c121597a64dfafa8f9bb2d5dd9697c66 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 30 Sep 2024 11:15:14 -0700 Subject: [PATCH 179/207] Add `cabal-validate` to `format` job --- .github/workflows/format.yml | 1 + cabal-validate/src/ANSI.hs | 13 +----- cabal-validate/src/Cli.hs | 73 ++++++++++++++++---------------- cabal-validate/src/ClockUtil.hs | 1 - cabal-validate/src/OutputUtil.hs | 2 +- cabal-validate/src/Step.hs | 1 - 6 files changed, 39 insertions(+), 52 deletions(-) diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index d54310be613..116537cf2ea 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -17,3 +17,4 @@ jobs: Cabal/**/*.hs Cabal-syntax/**/*.hs cabal-install/**/*.hs + cabal-validate/**/*.hs diff --git a/cabal-validate/src/ANSI.hs b/cabal-validate/src/ANSI.hs index 79dabf66d77..460261dcde4 100644 --- a/cabal-validate/src/ANSI.hs +++ b/cabal-validate/src/ANSI.hs @@ -4,13 +4,11 @@ -- we use. -- -- See: - module ANSI - ( SGR(..) + ( SGR (..) , setSGR ) where - -- | Render a single numeric SGR sequence. rawSGR :: Int -> String rawSGR code = "\x1b[" <> show code <> "m" @@ -26,7 +24,6 @@ data SGR | Dim | Italic | Underline - | Black | Red | Green @@ -36,7 +33,6 @@ data SGR | Cyan | White | Default - | OnBlack | OnRed | OnGreen @@ -46,7 +42,6 @@ data SGR | OnCyan | OnWhite | OnDefault - | BoldBlack | BoldRed | BoldGreen @@ -55,7 +50,6 @@ data SGR | BoldMagenta | BoldCyan | BoldWhite - | OnBoldBlack | OnBoldRed | OnBoldGreen @@ -64,7 +58,6 @@ data SGR | OnBoldMagenta | OnBoldCyan | OnBoldWhite - deriving (Show) -- Render a single `SGR` sequence. @@ -76,7 +69,6 @@ renderSGR code = Dim -> rawSGR 2 Italic -> rawSGR 3 Underline -> rawSGR 4 - Black -> rawSGR 30 Red -> rawSGR 31 Green -> rawSGR 32 @@ -86,7 +78,6 @@ renderSGR code = Cyan -> rawSGR 36 White -> rawSGR 37 Default -> rawSGR 39 - OnBlack -> rawSGR 40 OnRed -> rawSGR 41 OnGreen -> rawSGR 42 @@ -96,7 +87,6 @@ renderSGR code = OnCyan -> rawSGR 46 OnWhite -> rawSGR 47 OnDefault -> rawSGR 49 - BoldBlack -> rawSGR 90 BoldRed -> rawSGR 91 BoldGreen -> rawSGR 92 @@ -105,7 +95,6 @@ renderSGR code = BoldMagenta -> rawSGR 95 BoldCyan -> rawSGR 96 BoldWhite -> rawSGR 97 - OnBoldBlack -> rawSGR 100 OnBoldRed -> rawSGR 101 OnBoldGreen -> rawSGR 102 diff --git a/cabal-validate/src/Cli.hs b/cabal-validate/src/Cli.hs index d0478b90d64..074739676ff 100644 --- a/cabal-validate/src/Cli.hs +++ b/cabal-validate/src/Cli.hs @@ -1,5 +1,4 @@ -- | Parse CLI arguments and resolve defaults from the environment. - module Cli ( Opts (..) , parseOpts @@ -55,57 +54,57 @@ import Step (Step (..), displayStep, parseStep) -- | Command-line options, resolved with context from the environment. data Opts = Opts { verbose :: Bool - -- ^ Whether to display build and test output. + -- ^ Whether to display build and test output. , jobs :: Int - -- ^ How many jobs to use when running tests. - -- - -- Defaults to the number of physical cores. + -- ^ How many jobs to use when running tests. + -- + -- Defaults to the number of physical cores. , cwd :: FilePath - -- ^ Current working directory when @cabal-validate@ was started. + -- ^ Current working directory when @cabal-validate@ was started. , startTime :: AbsoluteTime - -- ^ System time when @cabal-validate@ was started. - -- - -- Used to determine the total test duration so far. + -- ^ System time when @cabal-validate@ was started. + -- + -- Used to determine the total test duration so far. , compiler :: Compiler - -- ^ Compiler to build Cabal with. - -- - -- Defaults to @ghc@. + -- ^ Compiler to build Cabal with. + -- + -- Defaults to @ghc@. , extraCompilers :: [FilePath] - -- ^ Extra compilers to run @cabal-testsuite@ with. + -- ^ Extra compilers to run @cabal-testsuite@ with. , cabal :: FilePath - -- ^ @cabal-install@ to build Cabal with. - -- - -- Defaults to @cabal@. + -- ^ @cabal-install@ to build Cabal with. + -- + -- Defaults to @cabal@. , hackageTests :: HackageTests - -- ^ Whether to run tests on Hackage data, and if so how much. - -- - -- Defaults to `NoHackageTests`. + -- ^ Whether to run tests on Hackage data, and if so how much. + -- + -- Defaults to `NoHackageTests`. , archPath :: FilePath - -- ^ The path for this system's architecture within the build directory. - -- - -- Like @x86_64-windows@ or @aarch64-osx@ or @arm-linux@. + -- ^ The path for this system's architecture within the build directory. + -- + -- Like @x86_64-windows@ or @aarch64-osx@ or @arm-linux@. , projectFile :: FilePath - -- ^ Path to the @cabal.project@ file to use for running tests. + -- ^ Path to the @cabal.project@ file to use for running tests. , tastyArgs :: [String] - -- ^ Extra arguments to pass to @tasty@ test suites. - -- - -- This defaults to @--hide-successes@ (which cannot yet be changed) and - -- includes the @--pattern@ argument if one is given. + -- ^ Extra arguments to pass to @tasty@ test suites. + -- + -- This defaults to @--hide-successes@ (which cannot yet be changed) and + -- includes the @--pattern@ argument if one is given. , targets :: [String] - -- ^ Targets to build. + -- ^ Targets to build. , steps :: [Step] - -- ^ Steps to run. + -- ^ Steps to run. } deriving (Show) -- | Whether to run tests on Hackage data, and if so how much. data HackageTests - = CompleteHackageTests - -- ^ Run tests on complete Hackage data. - | PartialHackageTests - -- ^ Run tests on partial Hackage data. - | NoHackageTests - -- ^ Do not run tests on Hackage data. + = -- | Run tests on complete Hackage data. + CompleteHackageTests + | -- | Run tests on partial Hackage data. + PartialHackageTests + | -- | Do not run tests on Hackage data. + NoHackageTests deriving (Show) -- | A compiler executable and version number. @@ -120,9 +119,9 @@ data Compiler = Compiler -- | An `Exception` thrown when parsing @--numeric-version@ output from a compiler. data VersionParseException = VersionParseException { versionInput :: String - -- ^ The string we attempted to parse. + -- ^ The string we attempted to parse. , versionExecutable :: FilePath - -- ^ The compiler which produced the string. + -- ^ The compiler which produced the string. } deriving (Typeable, Show) diff --git a/cabal-validate/src/ClockUtil.hs b/cabal-validate/src/ClockUtil.hs index 664175789e7..2df7cdd9866 100644 --- a/cabal-validate/src/ClockUtil.hs +++ b/cabal-validate/src/ClockUtil.hs @@ -1,5 +1,4 @@ -- | Utilities for dealing with times and durations. - module ClockUtil ( DiffTime , AbsoluteTime diff --git a/cabal-validate/src/OutputUtil.hs b/cabal-validate/src/OutputUtil.hs index 075368def8c..36e5acc6a37 100644 --- a/cabal-validate/src/OutputUtil.hs +++ b/cabal-validate/src/OutputUtil.hs @@ -9,7 +9,7 @@ import qualified System.Console.Terminal.Size as Terminal import System.Process.Typed (ExitCodeException) import ANSI (SGR (BoldCyan, BoldGreen, BoldRed, Reset), setSGR) -import ClockUtil (AbsoluteTime, diffAbsoluteTime, formatDiffTime, getAbsoluteTime) +import ClockUtil (AbsoluteTime, diffAbsoluteTime, formatDiffTime, getAbsoluteTime) import System.Exit (exitFailure) -- | Get the width of the current terminal, or 80 if no width can be determined. diff --git a/cabal-validate/src/Step.hs b/cabal-validate/src/Step.hs index 4fafc472061..2636f483a79 100644 --- a/cabal-validate/src/Step.hs +++ b/cabal-validate/src/Step.hs @@ -1,5 +1,4 @@ -- | The steps that can be run by @cabal-validate@. - module Step ( Step (..) , displayStep From 908db2463cffe76677927fc8c011456a69596126 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 30 Sep 2024 12:39:52 -0700 Subject: [PATCH 180/207] Build test suites explicitly This seems to fix an error where `long-tests` isn't built? --- cabal-validate/src/Cli.hs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cabal-validate/src/Cli.hs b/cabal-validate/src/Cli.hs index 074739676ff..996e49205c0 100644 --- a/cabal-validate/src/Cli.hs +++ b/cabal-validate/src/Cli.hs @@ -208,10 +208,16 @@ resolveOpts opts = do , optionals (CliTests `elem` steps') [ "cabal-install" + , "cabal-install:tests" , "cabal-install-solver" , "cabal-benchmarks" + , "Cabal-tests:tests" + ] + , optionals + (rawSolverBenchmarks opts) + [ "solver-benchmarks" + , "solver-benchmarks:tests" ] - , optional (rawSolverBenchmarks opts) "solver-benchmarks" ] archPath' = From 9d1ff835386915d1fe67681cea70736214209da0 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 30 Sep 2024 12:53:07 -0700 Subject: [PATCH 181/207] fixup! Remove `ansi-terminal` dependency --- cabal-validate/src/ANSI.hs | 64 +++++++++++++++---------------- cabal-validate/src/Main.hs | 4 +- cabal-validate/src/OutputUtil.hs | 8 ++-- cabal-validate/src/ProcessUtil.hs | 8 ++-- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/cabal-validate/src/ANSI.hs b/cabal-validate/src/ANSI.hs index 460261dcde4..a0d9111d957 100644 --- a/cabal-validate/src/ANSI.hs +++ b/cabal-validate/src/ANSI.hs @@ -42,22 +42,22 @@ data SGR | OnCyan | OnWhite | OnDefault - | BoldBlack - | BoldRed - | BoldGreen - | BoldYellow - | BoldBlue - | BoldMagenta - | BoldCyan - | BoldWhite - | OnBoldBlack - | OnBoldRed - | OnBoldGreen - | OnBoldYellow - | OnBoldBlue - | OnBoldMagenta - | OnBoldCyan - | OnBoldWhite + | BrightBlack + | BrightRed + | BrightGreen + | BrightYellow + | BrightBlue + | BrightMagenta + | BrightCyan + | BrightWhite + | OnBrightBlack + | OnBrightRed + | OnBrightGreen + | OnBrightYellow + | OnBrightBlue + | OnBrightMagenta + | OnBrightCyan + | OnBrightWhite deriving (Show) -- Render a single `SGR` sequence. @@ -87,19 +87,19 @@ renderSGR code = OnCyan -> rawSGR 46 OnWhite -> rawSGR 47 OnDefault -> rawSGR 49 - BoldBlack -> rawSGR 90 - BoldRed -> rawSGR 91 - BoldGreen -> rawSGR 92 - BoldYellow -> rawSGR 93 - BoldBlue -> rawSGR 94 - BoldMagenta -> rawSGR 95 - BoldCyan -> rawSGR 96 - BoldWhite -> rawSGR 97 - OnBoldBlack -> rawSGR 100 - OnBoldRed -> rawSGR 101 - OnBoldGreen -> rawSGR 102 - OnBoldYellow -> rawSGR 103 - OnBoldBlue -> rawSGR 104 - OnBoldMagenta -> rawSGR 105 - OnBoldCyan -> rawSGR 106 - OnBoldWhite -> rawSGR 107 + BrightBlack -> rawSGR 90 + BrightRed -> rawSGR 91 + BrightGreen -> rawSGR 92 + BrightYellow -> rawSGR 93 + BrightBlue -> rawSGR 94 + BrightMagenta -> rawSGR 95 + BrightCyan -> rawSGR 96 + BrightWhite -> rawSGR 97 + OnBrightBlack -> rawSGR 100 + OnBrightRed -> rawSGR 101 + OnBrightGreen -> rawSGR 102 + OnBrightYellow -> rawSGR 103 + OnBrightBlue -> rawSGR 104 + OnBrightMagenta -> rawSGR 105 + OnBrightCyan -> rawSGR 106 + OnBrightWhite -> rawSGR 107 diff --git a/cabal-validate/src/Main.hs b/cabal-validate/src/Main.hs index 79a8df67e7c..428a8a7358d 100644 --- a/cabal-validate/src/Main.hs +++ b/cabal-validate/src/Main.hs @@ -16,7 +16,7 @@ import Data.Version (makeVersion, showVersion) import System.FilePath (()) import System.Process.Typed (proc, readProcessStdout_) -import ANSI (SGR (BoldCyan, Reset), setSGR) +import ANSI (SGR (Bold, BrightCyan, Reset), setSGR) import Cli (Compiler (..), HackageTests (..), Opts (..), parseOpts) import ClockUtil (diffAbsoluteTime, formatDiffTime, getAbsoluteTime) import OutputUtil (printHeader, withTiming) @@ -419,7 +419,7 @@ timeSummary opts = do endTime <- getAbsoluteTime let totalDuration = diffAbsoluteTime endTime (startTime opts) putStrLn $ - setSGR [BoldCyan] + setSGR [Bold, BrightCyan] <> "!!! Validation completed in " <> formatDiffTime totalDuration <> setSGR [Reset] diff --git a/cabal-validate/src/OutputUtil.hs b/cabal-validate/src/OutputUtil.hs index 36e5acc6a37..576c6180433 100644 --- a/cabal-validate/src/OutputUtil.hs +++ b/cabal-validate/src/OutputUtil.hs @@ -8,7 +8,7 @@ import Control.Exception (catch) import qualified System.Console.Terminal.Size as Terminal import System.Process.Typed (ExitCodeException) -import ANSI (SGR (BoldCyan, BoldGreen, BoldRed, Reset), setSGR) +import ANSI (SGR (Bold, BrightCyan, BrightGreen, BrightRed, Reset), setSGR) import ClockUtil (AbsoluteTime, diffAbsoluteTime, formatDiffTime, getAbsoluteTime) import System.Exit (exitFailure) @@ -28,7 +28,7 @@ printHeader title = do let left = 3 right = columns - length title - left - 2 header = - setSGR [BoldCyan] + setSGR [Bold, BrightCyan] <> replicate left '═' <> " " <> title @@ -63,7 +63,7 @@ withTiming startTime title action = do case result of Right inner -> do putStrLn $ - setSGR [BoldGreen] + setSGR [Bold, BrightGreen] <> title <> " finished after " <> formatDiffTime duration @@ -74,7 +74,7 @@ withTiming startTime title action = do pure inner Left _procFailed -> do putStrLn $ - setSGR [BoldRed] + setSGR [Bold, BrightRed] <> title <> " failed after " <> formatDiffTime duration diff --git a/cabal-validate/src/ProcessUtil.hs b/cabal-validate/src/ProcessUtil.hs index 19e987d5941..3e27f5517a1 100644 --- a/cabal-validate/src/ProcessUtil.hs +++ b/cabal-validate/src/ProcessUtil.hs @@ -17,7 +17,7 @@ import System.Directory (withCurrentDirectory) import System.Exit (ExitCode (ExitFailure, ExitSuccess)) import System.Process.Typed (ExitCodeException (..), proc, readProcess, runProcess) -import ANSI (SGR (BoldBlue, BoldGreen, BoldRed, Reset), setSGR) +import ANSI (SGR (BrightBlue, BrightGreen, BrightRed, Reset), setSGR) import Cli (Opts (..)) import ClockUtil (diffAbsoluteTime, formatDiffTime, getAbsoluteTime) @@ -56,7 +56,7 @@ timed opts command args = do -- TODO: Replace `$HOME` or `opts.cwd` for brevity? putStrLn $ - setSGR [BoldBlue] + setSGR [BrightBlue] <> "$ " <> prettyCommand <> setSGR [Reset] @@ -93,7 +93,7 @@ timed opts command args = do <> T.unlines tailLines putStrLn $ - setSGR [BoldGreen] + setSGR [BrightGreen] <> "Finished after " <> formatDiffTime duration <> ": " @@ -106,7 +106,7 @@ timed opts command args = do T.putStrLn output putStrLn $ - setSGR [BoldRed] + setSGR [BrightRed] <> "Failed with exit code " <> show exitCode' <> " after " From e712c9ed1b42563fde068cc6f6cd27812063ecd6 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 30 Sep 2024 14:36:40 -0700 Subject: [PATCH 182/207] fixup! Build test suites explicitly --- cabal-validate/src/Cli.hs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/cabal-validate/src/Cli.hs b/cabal-validate/src/Cli.hs index 996e49205c0..fed3661a937 100644 --- a/cabal-validate/src/Cli.hs +++ b/cabal-validate/src/Cli.hs @@ -204,15 +204,10 @@ resolveOpts opts = do , "Cabal-QuickCheck" , "Cabal-tree-diff" , "Cabal-described" + , "cabal-install" + , "cabal-install-solver" + , "cabal-benchmarks" ] - , optionals - (CliTests `elem` steps') - [ "cabal-install" - , "cabal-install:tests" - , "cabal-install-solver" - , "cabal-benchmarks" - , "Cabal-tests:tests" - ] , optionals (rawSolverBenchmarks opts) [ "solver-benchmarks" From 18156af0bbaeee88c7b0b8a7527108e6c1d9264c Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 30 Sep 2024 15:35:16 -0700 Subject: [PATCH 183/207] fixup! fixup! Build test suites explicitly --- cabal-validate/src/Cli.hs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cabal-validate/src/Cli.hs b/cabal-validate/src/Cli.hs index fed3661a937..ef01d907594 100644 --- a/cabal-validate/src/Cli.hs +++ b/cabal-validate/src/Cli.hs @@ -204,10 +204,13 @@ resolveOpts opts = do , "Cabal-QuickCheck" , "Cabal-tree-diff" , "Cabal-described" - , "cabal-install" - , "cabal-install-solver" - , "cabal-benchmarks" ] + , optionals + (not (rawLibOnly opts)) + [ "cabal-install" + , "cabal-install-solver" + , "cabal-benchmarks" + ] , optionals (rawSolverBenchmarks opts) [ "solver-benchmarks" From 7f2408a0a303f9e564302d84fc181e92424b6a03 Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Wed, 25 Sep 2024 10:31:09 +0200 Subject: [PATCH 184/207] Create temp files in temp directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change ensures all temporal files are created in the system temp directory which usually is in a short path. This helps with Windows not being capable of creating temp files in long directories, like the ones that result from Backpack. See how GetTempFileNameW specifies: > The string cannot be longer than `MAX_PATH–14` characters or `GetTempFileName` will fail. And actually there is a TODO in `Win32Utils.c` in GHC: https://gitlab.haskell.org/ghc/ghc/-/blob/3939a8bf93e27d8151aa1d92bf3ce10bbbc96a72/libraries/ghc-internal/cbits/Win32Utils.c#L259 Closes #10191. --- .github/workflows/validate.yml | 13 +++++-- .../src/Distribution/Utils/Generic.hs | 36 +++++++++++++++---- .../UnitTests/Distribution/Simple/Utils.hs | 11 +++--- Cabal/src/Distribution/Simple/Configure.hs | 12 +++---- Cabal/src/Distribution/Simple/GHC/Internal.hs | 9 +++-- Cabal/src/Distribution/Simple/Haddock.hs | 4 +-- Cabal/src/Distribution/Simple/PreProcess.hs | 2 -- Cabal/src/Distribution/Simple/Program/Ar.hs | 2 +- Cabal/src/Distribution/Simple/Program/Ld.hs | 4 +-- .../Simple/Program/ResponseFile.hs | 8 ++--- Cabal/src/Distribution/Simple/Utils.hs | 35 +++++++----------- .../src/Distribution/Client/HttpUtils.hs | 7 ++-- .../Backpack/Includes2/cabal-internal.test.hs | 2 +- .../Backpack/Includes3/cabal-external.test.hs | 2 -- .../Backpack/Includes3/cabal-internal.test.hs | 2 +- .../PackageTests/Backpack/T6385/cabal.test.hs | 2 +- .../HaddockKeepsTmps/cabal.test.hs | 26 +++++++------- 17 files changed, 90 insertions(+), 87 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index ae5e2c7a746..23fe4e5e7d1 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -124,6 +124,11 @@ jobs: rm -rf ~/.config/cabal rm -rf ~/.cache/cabal + - name: "WIN: Setup TMP environment variable" + if: runner.os == 'Windows' + run: | + echo "TMP=${{ runner.temp }}" >> "$GITHUB_ENV" + - uses: actions/checkout@v4 # See https://github.com/haskell/cabal/blob/master/CONTRIBUTING.md#hackage-revisions @@ -396,7 +401,6 @@ jobs: # We need to build an array dynamically to inject the appropiate env var in a previous job, # see https://docs.github.com/en/actions/learn-github-actions/expressions#fromjson ghc: ${{ fromJSON (needs.validate.outputs.GHC_FOR_RELEASE) }} - defaults: run: shell: ${{ matrix.sys.shell }} @@ -413,12 +417,17 @@ jobs: esac echo "CABAL_ARCH=$arch" >> "$GITHUB_ENV" - - name: Work around XDG directories existence (haskell-actions/setup#62) + - name: "MAC: Work around XDG directories existence (haskell-actions/setup#62)" if: runner.os == 'macOS' run: | rm -rf ~/.config/cabal rm -rf ~/.cache/cabal + - name: "WIN: Setup TMP environment variable" + if: runner.os == 'Windows' + run: | + echo "TMP=${{ runner.temp }}" >> "$GITHUB_ENV" + - uses: actions/checkout@v4 - uses: haskell-actions/setup@v2 diff --git a/Cabal-syntax/src/Distribution/Utils/Generic.hs b/Cabal-syntax/src/Distribution/Utils/Generic.hs index ace55a67aa3..ca48c8e820a 100644 --- a/Cabal-syntax/src/Distribution/Utils/Generic.hs +++ b/Cabal-syntax/src/Distribution/Utils/Generic.hs @@ -100,11 +100,13 @@ import qualified Data.Set as Set import qualified Control.Exception as Exception import System.Directory - ( removeFile + ( copyFile + , getTemporaryDirectory + , removeFile , renameFile ) import System.FilePath - ( splitFileName + ( takeFileName , (<.>) ) import System.IO @@ -167,18 +169,38 @@ withFileContents name action = -- The file is either written successfully or an IO exception is raised and -- the original file is left unchanged. -- --- On windows it is not possible to delete a file that is open by a process. --- This case will give an IO exception but the atomic property is not affected. +-- On Unix: +-- +-- - If the temp directory (@$TMPDIR@) is in a filesystem different than the +-- destination path, the renaming will be emulated via 'copyFile' then +-- 'deleteFile'. +-- +-- On Windows: +-- +-- - This operation is not guaranteed to be atomic, see 'renameFile'. +-- +-- - It is not possible to delete a file that is open by a process. This case +-- will give an IO exception but the atomic property is not affected. +-- +-- - If the temp directory (@TMP@/@TEMP@/..., see haddocks on +-- 'getTemporaryDirectory') is in a different drive than the destination path, +-- the write will be emulated via 'copyFile', then 'deleteFile'. writeFileAtomic :: FilePath -> LBS.ByteString -> IO () writeFileAtomic targetPath content = do - let (targetDir, targetFile) = splitFileName targetPath + let targetFile = takeFileName targetPath + tmpDir <- getTemporaryDirectory Exception.bracketOnError - (openBinaryTempFileWithDefaultPermissions targetDir $ targetFile <.> "tmp") + (openBinaryTempFileWithDefaultPermissions tmpDir $ targetFile <.> "tmp") (\(tmpPath, handle) -> hClose handle >> removeFile tmpPath) ( \(tmpPath, handle) -> do LBS.hPut handle content hClose handle - renameFile tmpPath targetPath + Exception.catch + (renameFile tmpPath targetPath) + ( \(_ :: Exception.SomeException) -> do + copyFile tmpPath targetPath + removeFile tmpPath + ) ) -- ------------------------------------------------------------ diff --git a/Cabal-tests/tests/UnitTests/Distribution/Simple/Utils.hs b/Cabal-tests/tests/UnitTests/Distribution/Simple/Utils.hs index 2e544c8c52d..48e8aae9c1d 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Simple/Utils.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Simple/Utils.hs @@ -23,16 +23,14 @@ import Test.Tasty.HUnit withTempFileTest :: Assertion withTempFileTest = do fileName <- newIORef "" - tempDir <- getTemporaryDirectory - withTempFile tempDir ".foo" $ \fileName' _handle -> do + withTempFile ".foo" $ \fileName' _handle -> do writeIORef fileName fileName' fileExists <- readIORef fileName >>= doesFileExist assertBool "Temporary file not deleted by 'withTempFile'!" (not fileExists) withTempFileRemovedTest :: Assertion withTempFileRemovedTest = do - tempDir <- getTemporaryDirectory - withTempFile tempDir ".foo" $ \fileName handle -> do + withTempFile ".foo" $ \fileName handle -> do hClose handle removeFile fileName @@ -58,9 +56,8 @@ rawSystemStdInOutTextDecodingTest ghcPath -- so skip the test if it's not. | show localeEncoding /= "UTF-8" = return () | otherwise = do - tempDir <- getTemporaryDirectory - res <- withTempFile tempDir ".hs" $ \filenameHs handleHs -> do - withTempFile tempDir ".exe" $ \filenameExe handleExe -> do + res <- withTempFile ".hs" $ \filenameHs handleHs -> do + withTempFile ".exe" $ \filenameExe handleExe -> do -- Small program printing not utf8 hPutStrLn handleHs "import Data.ByteString" hPutStrLn handleHs "main = Data.ByteString.putStr (Data.ByteString.pack [32, 32, 255])" diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index ca597e3bae2..56d8517b3b9 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -156,7 +156,6 @@ import System.Directory ( canonicalizePath , createDirectoryIfMissing , doesFileExist - , getTemporaryDirectory , removeFile ) import System.FilePath @@ -2693,10 +2692,9 @@ checkForeignDeps pkg lbi verbosity = builds :: String -> [ProgArg] -> IO Bool builds program args = - do - tempDir <- makeSymbolicPath <$> getTemporaryDirectory - withTempFileCwd mbWorkDir tempDir ".c" $ \cName cHnd -> - withTempFileCwd mbWorkDir tempDir "" $ \oNname oHnd -> do + withTempFileCwd ".c" $ \cName cHnd -> + withTempFileCwd "" $ \oNname oHnd -> + do hPutStrLn cHnd program hClose cHnd hClose oHnd @@ -2708,8 +2706,8 @@ checkForeignDeps pkg lbi verbosity = (withPrograms lbi) (getSymbolicPath cName : "-o" : getSymbolicPath oNname : args) return True - `catchIO` (\_ -> return False) - `catchExit` (\_ -> return False) + `catchIO` (\_ -> return False) + `catchExit` (\_ -> return False) explainErrors Nothing [] = return () -- should be impossible! explainErrors _ _ diff --git a/Cabal/src/Distribution/Simple/GHC/Internal.hs b/Cabal/src/Distribution/Simple/GHC/Internal.hs index 0686f30ba1b..6e27b41bc83 100644 --- a/Cabal/src/Distribution/Simple/GHC/Internal.hs +++ b/Cabal/src/Distribution/Simple/GHC/Internal.hs @@ -85,7 +85,7 @@ import Distribution.Utils.Path import Distribution.Verbosity import Distribution.Version (Version) import Language.Haskell.Extension -import System.Directory (getDirectoryContents, getTemporaryDirectory) +import System.Directory (getDirectoryContents) import System.Environment (getEnv) import System.FilePath ( takeDirectory @@ -221,9 +221,8 @@ configureToolchain _implInfo ghcProg ghcInfo = -- we need to find out if ld supports the -x flag configureLd' :: Verbosity -> ConfiguredProgram -> IO ConfiguredProgram configureLd' verbosity ldProg = do - tempDir <- getTemporaryDirectory - ldx <- withTempFile tempDir ".c" $ \testcfile testchnd -> - withTempFile tempDir ".o" $ \testofile testohnd -> do + ldx <- withTempFile ".c" $ \testcfile testchnd -> + withTempFile ".o" $ \testofile testohnd -> do hPutStrLn testchnd "int foo() { return 0; }" hClose testchnd hClose testohnd @@ -236,7 +235,7 @@ configureToolchain _implInfo ghcProg ghcInfo = , "-o" , testofile ] - withTempFile tempDir ".o" $ \testofile' testohnd' -> + withTempFile ".o" $ \testofile' testohnd' -> do hClose testohnd' _ <- diff --git a/Cabal/src/Distribution/Simple/Haddock.hs b/Cabal/src/Distribution/Simple/Haddock.hs index ba025a85549..ec4e60ff685 100644 --- a/Cabal/src/Distribution/Simple/Haddock.hs +++ b/Cabal/src/Distribution/Simple/Haddock.hs @@ -1133,8 +1133,6 @@ renderArgs verbosity mbWorkDir tmpFileOpts version comp platform args k = do withResponseFile verbosity tmpFileOpts - mbWorkDir - outputDir "haddock-response.txt" (if haddockSupportsUTF8 then Just utf8 else Nothing) renderedArgs @@ -1144,7 +1142,7 @@ renderArgs verbosity mbWorkDir tmpFileOpts version comp platform args k = do (Flag pfile, _) -> withPrologueArgs ["--prologue=" ++ pfile] (_, Flag prologueText) -> - withTempFileEx tmpFileOpts mbWorkDir outputDir "haddock-prologue.txt" $ + withTempFileEx tmpFileOpts "haddock-prologue.txt" $ \prologueFileName h -> do when haddockSupportsUTF8 (hSetEncoding h utf8) hPutStrLn h prologueText diff --git a/Cabal/src/Distribution/Simple/PreProcess.hs b/Cabal/src/Distribution/Simple/PreProcess.hs index 61dd8163733..e56627893c1 100644 --- a/Cabal/src/Distribution/Simple/PreProcess.hs +++ b/Cabal/src/Distribution/Simple/PreProcess.hs @@ -511,8 +511,6 @@ ppHsc2hs bi lbi clbi = withResponseFile verbosity defaultTempFileOptions - mbWorkDir - (makeSymbolicPath $ takeDirectory outFile) "hsc2hs-response.txt" Nothing pureArgs diff --git a/Cabal/src/Distribution/Simple/Program/Ar.hs b/Cabal/src/Distribution/Simple/Program/Ar.hs index 004b02cca1a..2e9b432385f 100644 --- a/Cabal/src/Distribution/Simple/Program/Ar.hs +++ b/Cabal/src/Distribution/Simple/Program/Ar.hs @@ -154,7 +154,7 @@ createArLibArchive verbosity lbi targetPath files = do (initial, middle, final) (map getSymbolicPath files) ] - else withResponseFile verbosity defaultTempFileOptions mbWorkDir tmpDir "ar.rsp" Nothing (map getSymbolicPath files) $ + else withResponseFile verbosity defaultTempFileOptions "ar.rsp" Nothing (map getSymbolicPath files) $ \path -> runProgramInvocation verbosity $ invokeWithResponseFile path unless diff --git a/Cabal/src/Distribution/Simple/Program/Ld.hs b/Cabal/src/Distribution/Simple/Program/Ld.hs index 5c2a33809ae..00ed5d182d7 100644 --- a/Cabal/src/Distribution/Simple/Program/Ld.hs +++ b/Cabal/src/Distribution/Simple/Program/Ld.hs @@ -83,8 +83,6 @@ combineObjectFiles verbosity lbi ldProg target files = do middle = ld middleArgs final = ld finalArgs - targetDir = takeDirectorySymbolicPath target - invokeWithResponseFile :: FilePath -> ProgramInvocation invokeWithResponseFile atFile = ld $ simpleArgs ++ ['@' : atFile] @@ -106,7 +104,7 @@ combineObjectFiles verbosity lbi ldProg target files = do if oldVersionManualOverride || responseArgumentsNotSupported then run $ multiStageProgramInvocation simple (initial, middle, final) (map getSymbolicPath files) - else withResponseFile verbosity defaultTempFileOptions mbWorkDir targetDir "ld.rsp" Nothing (map getSymbolicPath files) $ + else withResponseFile verbosity defaultTempFileOptions "ld.rsp" Nothing (map getSymbolicPath files) $ \path -> runProgramInvocation verbosity $ invokeWithResponseFile path where tmpfile = target <.> "tmp" -- perhaps should use a proper temp file diff --git a/Cabal/src/Distribution/Simple/Program/ResponseFile.hs b/Cabal/src/Distribution/Simple/Program/ResponseFile.hs index ee8271545f1..dec6cb0ae50 100644 --- a/Cabal/src/Distribution/Simple/Program/ResponseFile.hs +++ b/Cabal/src/Distribution/Simple/Program/ResponseFile.hs @@ -27,10 +27,6 @@ import Distribution.Verbosity withResponseFile :: Verbosity -> TempFileOptions - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -- ^ Working directory - -> SymbolicPath Pkg (Dir Response) - -- ^ Directory to create response file in. -> String -- ^ Template for response file name. -> Maybe TextEncoding @@ -39,8 +35,8 @@ withResponseFile -- ^ Arguments to put into response file. -> (FilePath -> IO a) -> IO a -withResponseFile verbosity tmpFileOpts mbWorkDir responseDir fileNameTemplate encoding arguments f = - withTempFileEx tmpFileOpts mbWorkDir responseDir fileNameTemplate $ \responsePath hf -> do +withResponseFile verbosity tmpFileOpts fileNameTemplate encoding arguments f = + withTempFileEx tmpFileOpts fileNameTemplate $ \responsePath hf -> do let responseFileName = getSymbolicPath responsePath traverse_ (hSetEncoding hf) encoding let responseContents = diff --git a/Cabal/src/Distribution/Simple/Utils.hs b/Cabal/src/Distribution/Simple/Utils.hs index 3688f602759..d51601e5c27 100644 --- a/Cabal/src/Distribution/Simple/Utils.hs +++ b/Cabal/src/Distribution/Simple/Utils.hs @@ -250,6 +250,7 @@ import System.Directory , getDirectoryContents , getModificationTime , getPermissions + , getTemporaryDirectory , removeDirectoryRecursive , removeFile ) @@ -1733,23 +1734,17 @@ defaultTempFileOptions = TempFileOptions{optKeepTempFiles = False} -- | Use a temporary filename that doesn't already exist withTempFile - :: FilePath - -- ^ Temp dir to create the file in - -> String + :: String -- ^ File name template. See 'openTempFile'. -> (FilePath -> Handle -> IO a) -> IO a -withTempFile tmpDir template f = withFrozenCallStack $ - withTempFileCwd Nothing (makeSymbolicPath tmpDir) template $ +withTempFile template f = withFrozenCallStack $ + withTempFileCwd template $ \fp h -> f (getSymbolicPath fp) h -- | Use a temporary filename that doesn't already exist. withTempFileCwd - :: Maybe (SymbolicPath CWD (Dir Pkg)) - -- ^ Working directory - -> SymbolicPath Pkg (Dir tmpDir) - -- ^ Temp dir to create the file in - -> String + :: String -- ^ File name template. See 'openTempFile'. -> (SymbolicPath Pkg File -> Handle -> IO a) -> IO a @@ -1758,20 +1753,17 @@ withTempFileCwd = withFrozenCallStack $ withTempFileEx defaultTempFileOptions -- | A version of 'withTempFile' that additionally takes a 'TempFileOptions' -- argument. withTempFileEx - :: forall a tmpDir + :: forall a . TempFileOptions - -> Maybe (SymbolicPath CWD (Dir Pkg)) - -- ^ Working directory - -> SymbolicPath Pkg (Dir tmpDir) - -- ^ Temp dir to create the file in -> String -- ^ File name template. See 'openTempFile'. -> (SymbolicPath Pkg File -> Handle -> IO a) -> IO a -withTempFileEx opts mbWorkDir tmpDir template action = +withTempFileEx opts template action = do + tmp <- getTemporaryDirectory withFrozenCallStack $ Exception.bracket - (openTempFile (i tmpDir) template) + (openTempFile tmp template) ( \(name, handle) -> do hClose handle unless (optKeepTempFiles opts) $ @@ -1779,12 +1771,11 @@ withTempFileEx opts mbWorkDir tmpDir template action = removeFile $ name ) - (withLexicalCallStack (\(fn, h) -> action (mkRelToPkg fn) h)) + (withLexicalCallStack (\(fn, h) -> action (mkRelToPkg tmp fn) h)) where - i = interpretSymbolicPath mbWorkDir -- See Note [Symbolic paths] in Distribution.Utils.Path - mkRelToPkg :: FilePath -> SymbolicPath Pkg File - mkRelToPkg fp = - tmpDir makeRelativePathEx (takeFileName fp) + mkRelToPkg :: FilePath -> FilePath -> SymbolicPath Pkg File + mkRelToPkg tmp fp = + makeSymbolicPath tmp makeRelativePathEx (takeFileName fp) -- 'openTempFile' returns a path of the form @i tmpDir fn@, but we -- want 'withTempFileEx' to return @tmpDir fn@. So we split off diff --git a/cabal-install/src/Distribution/Client/HttpUtils.hs b/cabal-install/src/Distribution/Client/HttpUtils.hs index 956241ab307..3cdadf9304c 100644 --- a/cabal-install/src/Distribution/Client/HttpUtils.hs +++ b/cabal-install/src/Distribution/Client/HttpUtils.hs @@ -467,7 +467,6 @@ curlTransport prog = where gethttp verbosity uri etag destPath reqHeaders = do withTempFile - (takeDirectory destPath) "curl-headers.txt" $ \tmpFile tmpHandle -> do hClose tmpHandle @@ -675,10 +674,9 @@ wgetTransport prog = posthttpfile verbosity uri path auth = withTempFile - (takeDirectory path) (takeFileName path) $ \tmpFile tmpHandle -> - withTempFile (takeDirectory path) "response" $ + withTempFile "response" $ \responseFile responseHandle -> do hClose responseHandle (body, boundary) <- generateMultipartBody path @@ -702,7 +700,7 @@ wgetTransport prog = evaluate $ force (code, resp) puthttpfile verbosity uri path auth headers = - withTempFile (takeDirectory path) "response" $ + withTempFile "response" $ \responseFile responseHandle -> do hClose responseHandle let args = @@ -824,7 +822,6 @@ powershellTransport prog = posthttpfile verbosity uri path auth = withTempFile - (takeDirectory path) (takeFileName path) $ \tmpFile tmpHandle -> do (body, boundary) <- generateMultipartBody path diff --git a/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.test.hs index e2c42fe43fd..1413f66dcdc 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.test.hs @@ -2,7 +2,7 @@ import Test.Cabal.Prelude main = cabalTest $ do skipUnlessGhcVersion ">= 8.1" - expectBrokenIfWindowsCI 10191 $ withProjectFile "cabal.internal.project" $ do + withProjectFile "cabal.internal.project" $ do cabal "v2-build" ["exe"] withPlan $ do r <- runPlanExe' "I" "exe" [] diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs index a2431cdf389..a974254fc98 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-external.test.hs @@ -2,8 +2,6 @@ import Test.Cabal.Prelude main = cabalTest $ do skipUnlessGhcVersion ">= 8.1" - ghcVer <- isGhcVersion ">= 9.10" - skipIf "Windows + 9.10.1 (#10191)" (isWindows && ghcVer) withProjectFile "cabal.external.project" $ do cabal "v2-build" ["exe"] withPlan $ do diff --git a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.test.hs b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.test.hs index b0d3e21688f..81f3fcb0027 100644 --- a/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/Includes3/cabal-internal.test.hs @@ -2,7 +2,7 @@ import Test.Cabal.Prelude main = cabalTest $ do skipUnlessGhcVersion ">= 8.1" - expectBrokenIfWindowsCI 10191 $ withProjectFile "cabal.internal.project" $ do + withProjectFile "cabal.internal.project" $ do cabal "v2-build" ["exe"] withPlan $ do r <- runPlanExe' "I" "exe" [] diff --git a/cabal-testsuite/PackageTests/Backpack/T6385/cabal.test.hs b/cabal-testsuite/PackageTests/Backpack/T6385/cabal.test.hs index d05327839da..5048e09d56b 100644 --- a/cabal-testsuite/PackageTests/Backpack/T6385/cabal.test.hs +++ b/cabal-testsuite/PackageTests/Backpack/T6385/cabal.test.hs @@ -1,6 +1,6 @@ import Test.Cabal.Prelude main = - cabalTest $ expectBrokenIfWindows 10191 $ withShorterPathForNewBuildStore $ do + cabalTest $ withShorterPathForNewBuildStore $ do skipUnlessGhcVersion ">= 8.1" withRepo "repo" $ do cabal "v2-build" ["T6385"] diff --git a/cabal-testsuite/PackageTests/HaddockKeepsTmps/cabal.test.hs b/cabal-testsuite/PackageTests/HaddockKeepsTmps/cabal.test.hs index a4db6795625..0f601d77363 100644 --- a/cabal-testsuite/PackageTests/HaddockKeepsTmps/cabal.test.hs +++ b/cabal-testsuite/PackageTests/HaddockKeepsTmps/cabal.test.hs @@ -1,21 +1,23 @@ {-# LANGUAGE LambdaCase #-} import Test.Cabal.Prelude -import Data.List (sort) +import Data.List (sort, isPrefixOf) import Distribution.Verbosity import Distribution.Simple.Glob import Distribution.Simple.Glob.Internal import Distribution.Simple.Utils +import System.Directory -- Test that "cabal haddock" preserves temporary files -- We use haddock-keep-temp-file: True in the cabal.project. -main = cabalTest $ recordMode DoNotRecord $ withProjectFile "cabal.project" $ do - cabal "haddock" [] - - cwd <- fmap testCurrentDir getTestEnv - - -- Windows has multiple response files, and only the last one (alphabetically) is the important one. - (safeLast . sort . globMatches <$> liftIO (runDirFileGlob silent Nothing cwd (GlobDirRecursive [WildCard, Literal "txt"]))) >>= \case - Nothing -> error "Expecting a response file to exist" - Just m -> do - -- Assert the matched response file is not empty, and indeed a haddock rsp - assertFileDoesContain (cwd m) "--package-name" +main = + cabalTest $ recordMode DoNotRecord $ withProjectFile "cabal.project" $ do + pwd <- testTmpDir <$> getTestEnv + liftIO $ createDirectory (pwd "temp") + withEnv [(if isWindows then "TMP" else "TMPDIR", Just $ pwd "temp")] $ + cabal "haddock" [] + files <- liftIO $ listDirectory (pwd "temp") + case [ pwd "temp" f | f <- files, takeExtension f == ".txt" ] of + [] -> error "Expecting a response file being mentioned in the outcome" + files' -> + -- Assert the matched response file is not empty, and indeed a haddock rsp + assertAnyFileContains files' "--package-name" From 254e9a8d0a0da2230df38332002cd6a5a0ad258d Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Tue, 1 Oct 2024 15:00:17 -0700 Subject: [PATCH 185/207] Add `.editorconfig` --- .editorconfig | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000000..bfe127253e2 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# See: https://editorconfig.org +root = true + +[*] +charset = utf-8 + +[*.hs] +indent_style = space +indent_size = 2 + +[Makefile] +indent_style = tab From 700103c51c292d1d1241ab0cc7a60daa7faad31b Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Fri, 27 Sep 2024 09:20:49 -0700 Subject: [PATCH 186/207] Add `haddock --keep-temp-files` test --- .../HaddockKeepTmpsCustom/Setup.hs | 3 +++ .../HaddockKeepTmpsCustom/Simple.hs | 4 ++++ .../HaddockKeepTmpsCustom/cabal.project | 3 +++ .../HaddockKeepTmpsCustom/cabal.test.hs | 22 +++++++++++++++++++ .../HaddockKeepTmpsCustom/my.cabal | 16 ++++++++++++++ 5 files changed, 48 insertions(+) create mode 100644 cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/Setup.hs create mode 100644 cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/Simple.hs create mode 100644 cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/cabal.project create mode 100644 cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/cabal.test.hs create mode 100644 cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/my.cabal diff --git a/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/Setup.hs b/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/Setup.hs new file mode 100644 index 00000000000..e8ef27dbba9 --- /dev/null +++ b/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/Setup.hs @@ -0,0 +1,3 @@ +import Distribution.Simple + +main = defaultMain diff --git a/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/Simple.hs b/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/Simple.hs new file mode 100644 index 00000000000..df38c448c5e --- /dev/null +++ b/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/Simple.hs @@ -0,0 +1,4 @@ +module Simple where + +-- | For hiding needles. +data Haystack = Haystack diff --git a/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/cabal.project b/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/cabal.project new file mode 100644 index 00000000000..f45d5a19d3c --- /dev/null +++ b/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/cabal.project @@ -0,0 +1,3 @@ +packages: . + +haddock-keep-temp-files: true diff --git a/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/cabal.test.hs b/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/cabal.test.hs new file mode 100644 index 00000000000..39433896ce3 --- /dev/null +++ b/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/cabal.test.hs @@ -0,0 +1,22 @@ +import Test.Cabal.Prelude + +-- Test that "cabal haddock" preserves temporary files +-- We use haddock-keep-temp-file: True in the cabal.project. +main = cabalTest $ recordMode DoNotRecord $ withProjectFile "cabal.project" $ do + cabal "haddock" [] + + -- From the docs for `System.IO.openTempFile`: + -- + -- On Windows, the template prefix may be truncated to 3 chars, e.g. + -- "foobar.ext" will be "fooXXX.ext". + let glob = + if isWindows + then "**/had*.txt" + else "**/haddock-response*.txt" + + -- Check that there is a response file. + responseFiles <- assertGlobMatchesTestDir testDistDir glob + + -- Check that the matched response file is not empty, and is indeed a Haddock + -- response file. + assertAnyFileContains responseFiles "--package-name" diff --git a/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/my.cabal b/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/my.cabal new file mode 100644 index 00000000000..a4a24980c12 --- /dev/null +++ b/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/my.cabal @@ -0,0 +1,16 @@ +cabal-version: 3.0 +name: HaddockKeepsTmpsCustom +version: 0.1 +license: BSD-3-Clause +author: Rodrigo Mesquita +stability: stable +category: PackageTests +build-type: Custom + +custom-setup + setup-depends: Cabal, base + +library + default-language: Haskell2010 + exposed-modules: Simple + build-depends: base From c3a271c8ee362e0588c25be0fa0501ff8a7e6dd8 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Thu, 3 Oct 2024 16:02:44 +0100 Subject: [PATCH 187/207] Cabal: Take into account compilerBuildWay when computing final library ways In the profiling dynamic patch I made a mistake when computing the needed ways for a build. When building an executable, the Haskell modules need to be built * For the final link way * For the build way of the compiler if TH is enabled Before this patch, the modules were being built for all the configured library ways, which built modules in more configurations than the previous version of Cabal. Fixes #10418 --- Cabal/src/Distribution/Simple/GHC/Build.hs | 20 ++++++++++++++++--- .../PackageTests/BuildWays/p/CHANGELOG.md | 5 +++++ .../PackageTests/BuildWays/p/p.cabal | 18 +++++++++++++++++ .../PackageTests/BuildWays/p/src/MyLib.hs | 4 ++++ .../PackageTests/BuildWays/q/CHANGELOG.md | 5 +++++ .../PackageTests/BuildWays/q/app/Main.hs | 7 +++++++ .../PackageTests/BuildWays/q/q.cabal | 19 ++++++++++++++++++ .../PackageTests/BuildWays/setup.test.hs | 10 ++++++++++ changelog.d/i10418 | 13 ++++++++++++ 9 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 cabal-testsuite/PackageTests/BuildWays/p/CHANGELOG.md create mode 100644 cabal-testsuite/PackageTests/BuildWays/p/p.cabal create mode 100644 cabal-testsuite/PackageTests/BuildWays/p/src/MyLib.hs create mode 100644 cabal-testsuite/PackageTests/BuildWays/q/CHANGELOG.md create mode 100644 cabal-testsuite/PackageTests/BuildWays/q/app/Main.hs create mode 100644 cabal-testsuite/PackageTests/BuildWays/q/q.cabal create mode 100644 cabal-testsuite/PackageTests/BuildWays/setup.test.hs create mode 100644 changelog.d/i10418 diff --git a/Cabal/src/Distribution/Simple/GHC/Build.hs b/Cabal/src/Distribution/Simple/GHC/Build.hs index 1972e9d903f..c12fb7b2427 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build.hs @@ -12,7 +12,7 @@ import Distribution.Simple.Flag (Flag) import Distribution.Simple.GHC.Build.ExtraSources import Distribution.Simple.GHC.Build.Link import Distribution.Simple.GHC.Build.Modules -import Distribution.Simple.GHC.Build.Utils (isHaskell) +import Distribution.Simple.GHC.Build.Utils (compilerBuildWay, isHaskell) import Distribution.Simple.LocalBuildInfo import Distribution.Simple.Program.Builtin (ghcProgram) import Distribution.Simple.Program.Db (requireProgram) @@ -73,6 +73,7 @@ build numJobs pkg_descr pbci = do verbosity = buildVerbosity pbci isLib = buildIsLib pbci lbi = localBuildInfo pbci + bi = buildBI pbci clbi = buildCLBI pbci isIndef = componentIsIndefinite clbi mbWorkDir = mbWorkDirLBI lbi @@ -111,9 +112,22 @@ build numJobs pkg_descr pbci = do (ghcProg, _) <- liftIO $ requireProgram verbosity ghcProgram (withPrograms lbi) + -- Ways which are wanted from configuration flags let wantedWays@(wantedLibWays, _, wantedExeWay) = buildWays lbi - liftIO $ info verbosity ("Wanted build ways(" ++ show isLib ++ "): " ++ show (if isLib then wantedLibWays isIndef else [wantedExeWay])) + -- Ways which are needed due to the compiler configuration + let doingTH = usesTemplateHaskellOrQQ bi + defaultGhcWay = compilerBuildWay (buildCompiler pbci) + wantedLibBuildWays = + if isLib + then wantedLibWays isIndef + else [wantedExeWay] + finalLibBuildWays = + wantedLibBuildWays + ++ [defaultGhcWay | doingTH && defaultGhcWay `notElem` wantedLibBuildWays] + + liftIO $ info verbosity ("Wanted build ways(" ++ show isLib ++ "): " ++ show wantedLibBuildWays) + liftIO $ info verbosity ("Final lib build ways(" ++ show isLib ++ "): " ++ show finalLibBuildWays) -- We need a separate build and link phase, and C sources must be compiled -- after Haskell modules, because C sources may depend on stub headers -- generated from compiling Haskell modules (#842, #3294). @@ -127,7 +141,7 @@ build numJobs pkg_descr pbci = do | otherwise -> (Nothing, Just mainFile) Nothing -> (Nothing, Nothing) - buildOpts <- buildHaskellModules numJobs ghcProg hsMainFile inputModules buildTargetDir (wantedLibWays isIndef) pbci + buildOpts <- buildHaskellModules numJobs ghcProg hsMainFile inputModules buildTargetDir finalLibBuildWays pbci extraSources <- buildAllExtraSources nonHsMainFile ghcProg buildTargetDir wantedWays pbci linkOrLoadComponent ghcProg diff --git a/cabal-testsuite/PackageTests/BuildWays/p/CHANGELOG.md b/cabal-testsuite/PackageTests/BuildWays/p/CHANGELOG.md new file mode 100644 index 00000000000..9ede8b27d4f --- /dev/null +++ b/cabal-testsuite/PackageTests/BuildWays/p/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for p + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/cabal-testsuite/PackageTests/BuildWays/p/p.cabal b/cabal-testsuite/PackageTests/BuildWays/p/p.cabal new file mode 100644 index 00000000000..687cf16bc0c --- /dev/null +++ b/cabal-testsuite/PackageTests/BuildWays/p/p.cabal @@ -0,0 +1,18 @@ +cabal-version: 3.12 +name: p +version: 0.1.0.0 +license: NONE +author: Matthew Pickering +maintainer: matthewtpickering@gmail.com +build-type: Simple +extra-doc-files: CHANGELOG.md + +common warnings + ghc-options: -Wall + +library + import: warnings + exposed-modules: MyLib + build-depends: base + hs-source-dirs: src + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/BuildWays/p/src/MyLib.hs b/cabal-testsuite/PackageTests/BuildWays/p/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/BuildWays/p/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-testsuite/PackageTests/BuildWays/q/CHANGELOG.md b/cabal-testsuite/PackageTests/BuildWays/q/CHANGELOG.md new file mode 100644 index 00000000000..62632c53766 --- /dev/null +++ b/cabal-testsuite/PackageTests/BuildWays/q/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for q + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/cabal-testsuite/PackageTests/BuildWays/q/app/Main.hs b/cabal-testsuite/PackageTests/BuildWays/q/app/Main.hs new file mode 100644 index 00000000000..642b418a547 --- /dev/null +++ b/cabal-testsuite/PackageTests/BuildWays/q/app/Main.hs @@ -0,0 +1,7 @@ +{-# LANGUAGE TemplateHaskell #-} +module Main where + +import MyLib + +main :: IO () +main = someFunc diff --git a/cabal-testsuite/PackageTests/BuildWays/q/q.cabal b/cabal-testsuite/PackageTests/BuildWays/q/q.cabal new file mode 100644 index 00000000000..a4f2a1d65d7 --- /dev/null +++ b/cabal-testsuite/PackageTests/BuildWays/q/q.cabal @@ -0,0 +1,19 @@ +cabal-version: 3.12 +name: q +version: 0.1.0.0 +license: NONE +author: Matthew Pickering +maintainer: matthewtpickering@gmail.com +build-type: Simple +extra-doc-files: CHANGELOG.md + +common warnings + ghc-options: -Wall + +executable q + import: warnings + main-is: Main.hs + build-depends: p, base + hs-source-dirs: app + ghc-options: -dynamic-too + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/BuildWays/setup.test.hs b/cabal-testsuite/PackageTests/BuildWays/setup.test.hs new file mode 100644 index 00000000000..dd4531599e4 --- /dev/null +++ b/cabal-testsuite/PackageTests/BuildWays/setup.test.hs @@ -0,0 +1,10 @@ +import Test.Cabal.Prelude + +opts = ["--enable-shared", "--enable-library-vanilla", "--enable-library-profiling"] + +-- See #10418 +main = setupTest $ recordMode DoNotRecord $ withPackageDb $ do + skipIfNoSharedLibraries + skipIfNoProfiledLibraries + withDirectory "p" $ setup_install opts + withDirectory "q" $ setup_install opts diff --git a/changelog.d/i10418 b/changelog.d/i10418 new file mode 100644 index 00000000000..9a96e47a1e9 --- /dev/null +++ b/changelog.d/i10418 @@ -0,0 +1,13 @@ +synopsis: Fix build ways for modules in executables +packages: Cabal +prs: #10419 +issues: #10418 +significance: significant + +description: { + +- Modules belonging to executables were being built in too many ways. For instance, if you +had configured to build profiled library files then your executable modules would also +be built profiled. Which was a regression in behaviour since `Cabal-3.12`. + +} From a7eacfaafafe8503fb7e7818b01576eefa755631 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Tue, 1 Oct 2024 16:15:47 -0400 Subject: [PATCH 188/207] patchups to `changelog.d` file descriptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug copied from `changelog-d`'s `README.md`. A good example of why copying it into `CONTRIBUTING.md` because we can't reference it from there is a bad idea. ☹ --- CONTRIBUTING.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 18a4d64c5bd..93835320bb2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -350,14 +350,15 @@ description: { Changelogs may also be written in "markdown-frontmatter" format. This is useful if your description contains braces, which must be escaped with backslashes in `.cabal` file -format. +format. The front matter is in YAML syntax, not `.cabal` file syntax, and the file +_must_ begin with a line containing only hyphens. ```markdown --- synopsis: Add feature xyz packages: [cabal-install] -prs: #0000 -issues: #0000 #0000 +prs: 0000 +issues: [0000, 0000] significance: significant --- @@ -365,7 +366,11 @@ significance: significant - Detail number 2 ``` -The package list must be enclosed in square brackets and comma-separated, but this isn't needed for `prs` or `issues`. +The package list must be enclosed in square brackets and comma-separated, but this +isn't needed for `prs` or `issues`; those are free-form and any YAML syntax will +be accepted. Note that the number signs on PR and issue numbers are required in +`.cabal` file syntax, but won't work in markdown-frontmatter syntax because they +signify comments in YAML. Only the `synopsis` and `prs` fields are required, but you should also set the others where applicable. From 9d9bf65430429b76daaf7069d89a0fe52e0bbdb9 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Fri, 4 Oct 2024 15:12:53 -0700 Subject: [PATCH 189/207] Fix `HaddockKeepTmpsCustom` test for merge skew The `HaddockKeepTmpsCustom` test added in #10392 skewed against #10366, which changes where temporary files are written. We can work around this by setting `$TMPDIR` and `$TEMP` while running tests, so that temporary files are written to the test's temporary directory rather than the system one. --- .../HaddockKeepTmpsCustom/cabal.test.hs | 6 ++-- .../HaddockKeepsTmps/cabal.test.hs | 34 +++++++++++-------- cabal-testsuite/src/Test/Cabal/Monad.hs | 4 +++ 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/cabal.test.hs b/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/cabal.test.hs index 39433896ce3..e2d819e44d6 100644 --- a/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/cabal.test.hs +++ b/cabal-testsuite/PackageTests/HaddockKeepTmpsCustom/cabal.test.hs @@ -11,11 +11,11 @@ main = cabalTest $ recordMode DoNotRecord $ withProjectFile "cabal.project" $ do -- "foobar.ext" will be "fooXXX.ext". let glob = if isWindows - then "**/had*.txt" - else "**/haddock-response*.txt" + then "had*.txt" + else "haddock-response*.txt" -- Check that there is a response file. - responseFiles <- assertGlobMatchesTestDir testDistDir glob + responseFiles <- assertGlobMatchesTestDir testTmpDir glob -- Check that the matched response file is not empty, and is indeed a Haddock -- response file. diff --git a/cabal-testsuite/PackageTests/HaddockKeepsTmps/cabal.test.hs b/cabal-testsuite/PackageTests/HaddockKeepsTmps/cabal.test.hs index 0f601d77363..3a76caadf6c 100644 --- a/cabal-testsuite/PackageTests/HaddockKeepsTmps/cabal.test.hs +++ b/cabal-testsuite/PackageTests/HaddockKeepsTmps/cabal.test.hs @@ -1,23 +1,29 @@ -{-# LANGUAGE LambdaCase #-} -import Test.Cabal.Prelude -import Data.List (sort, isPrefixOf) -import Distribution.Verbosity +import Data.List (isPrefixOf, sort) import Distribution.Simple.Glob import Distribution.Simple.Glob.Internal import Distribution.Simple.Utils +import Distribution.Verbosity import System.Directory +import Test.Cabal.Prelude -- Test that "cabal haddock" preserves temporary files -- We use haddock-keep-temp-file: True in the cabal.project. main = cabalTest $ recordMode DoNotRecord $ withProjectFile "cabal.project" $ do - pwd <- testTmpDir <$> getTestEnv - liftIO $ createDirectory (pwd "temp") - withEnv [(if isWindows then "TMP" else "TMPDIR", Just $ pwd "temp")] $ - cabal "haddock" [] - files <- liftIO $ listDirectory (pwd "temp") - case [ pwd "temp" f | f <- files, takeExtension f == ".txt" ] of - [] -> error "Expecting a response file being mentioned in the outcome" - files' -> - -- Assert the matched response file is not empty, and indeed a haddock rsp - assertAnyFileContains files' "--package-name" + cabal "haddock" [] + + -- From the docs for `System.IO.openTempFile`: + -- + -- On Windows, the template prefix may be truncated to 3 chars, e.g. + -- "foobar.ext" will be "fooXXX.ext". + let glob = + if isWindows + then "had*.txt" + else "haddock-response*.txt" + + -- Check that there is a response file. + responseFiles <- assertGlobMatchesTestDir testTmpDir glob + + -- Check that the matched response file is not empty, and is indeed a Haddock + -- response file. + assertAnyFileContains responseFiles "--package-name" diff --git a/cabal-testsuite/src/Test/Cabal/Monad.hs b/cabal-testsuite/src/Test/Cabal/Monad.hs index 63605768de7..31e1e07bf52 100644 --- a/cabal-testsuite/src/Test/Cabal/Monad.hs +++ b/cabal-testsuite/src/Test/Cabal/Monad.hs @@ -410,6 +410,10 @@ runTestM mode m = -- effect on Windows. , ("CABAL_DIR", Just (testCabalDir env)) , ("CABAL_CONFIG", Just (testUserCabalConfigFile env)) + -- Set `TMPDIR` so that temporary files aren't created in the global `TMPDIR`. + , ("TMPDIR", Just tmp_dir) + -- Windows uses `TMP` for the `TMPDIR`. + , ("TMP", Just tmp_dir) ], testShouldFail = False, testRelativeCurrentDir = ".", From f3db2f7e94d5526bf7644337a5655be45f2ba73d Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Thu, 3 Oct 2024 12:03:02 +0100 Subject: [PATCH 190/207] Fix ./setup install comand Running ./setup install will give you an error: ``` fromFlag NoFlag. Use fromFlagOrDefault CallStack (from HasCallStack): error, called at src/Distribution/Simple/Flag.hs:110:19 in Cabal-3.15.0.0-inplace:Distribution.Simple.Flag fromFlag, called at src/Distribution/Simple/Register.hs:161:16 in Cabal-3.15.0.0-inplace:Distribution.Simple.Register ``` This seems to not be tested anywhere and most people will use ./setup register in any case, but we should fix this for the next point release in 3.14 series. # Please enter the commit message for your changes. Lines starting Fixes #10416 --- Cabal/src/Distribution/Simple.hs | 1 + .../Install/DistPrefInstall/CHANGELOG.md | 5 +++++ .../DistPrefInstall/DistPrefInstall.cabal | 18 ++++++++++++++++++ .../Install/DistPrefInstall/Setup.hs | 2 ++ .../Install/DistPrefInstall/setup.test.hs | 8 ++++++++ .../Install/DistPrefInstall/src/MyLib.hs | 4 ++++ changelog.d/t10416 | 11 +++++++++++ 7 files changed, 49 insertions(+) create mode 100644 cabal-testsuite/PackageTests/Install/DistPrefInstall/CHANGELOG.md create mode 100644 cabal-testsuite/PackageTests/Install/DistPrefInstall/DistPrefInstall.cabal create mode 100644 cabal-testsuite/PackageTests/Install/DistPrefInstall/Setup.hs create mode 100644 cabal-testsuite/PackageTests/Install/DistPrefInstall/setup.test.hs create mode 100644 cabal-testsuite/PackageTests/Install/DistPrefInstall/src/MyLib.hs create mode 100644 changelog.d/t10416 diff --git a/Cabal/src/Distribution/Simple.hs b/Cabal/src/Distribution/Simple.hs index ada1d6c7aad..3533cf78336 100644 --- a/Cabal/src/Distribution/Simple.hs +++ b/Cabal/src/Distribution/Simple.hs @@ -1094,6 +1094,7 @@ defaultInstallHook_setupHooks inst_hooks pkg_descr localbuildinfo _ flags = do defaultRegisterFlags { regInPlace = installInPlace flags , regPackageDB = installPackageDB flags + , registerCommonFlags = installCommonFlags flags } when (hasLibs pkg_descr) $ register pkg_descr localbuildinfo registerFlags diff --git a/cabal-testsuite/PackageTests/Install/DistPrefInstall/CHANGELOG.md b/cabal-testsuite/PackageTests/Install/DistPrefInstall/CHANGELOG.md new file mode 100644 index 00000000000..3d5552b0ba5 --- /dev/null +++ b/cabal-testsuite/PackageTests/Install/DistPrefInstall/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for DistPrefInstall + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/cabal-testsuite/PackageTests/Install/DistPrefInstall/DistPrefInstall.cabal b/cabal-testsuite/PackageTests/Install/DistPrefInstall/DistPrefInstall.cabal new file mode 100644 index 00000000000..536d26b3648 --- /dev/null +++ b/cabal-testsuite/PackageTests/Install/DistPrefInstall/DistPrefInstall.cabal @@ -0,0 +1,18 @@ +cabal-version: 3.12 +name: DistPrefInstall +version: 0.1.0.0 +license: NONE +author: Matthew Pickering +maintainer: matthewtpickering@gmail.com +build-type: Simple +extra-doc-files: CHANGELOG.md + +common warnings + ghc-options: -Wall + +library + import: warnings + exposed-modules: MyLib + build-depends: base + hs-source-dirs: src + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/Install/DistPrefInstall/Setup.hs b/cabal-testsuite/PackageTests/Install/DistPrefInstall/Setup.hs new file mode 100644 index 00000000000..9a994af677b --- /dev/null +++ b/cabal-testsuite/PackageTests/Install/DistPrefInstall/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/cabal-testsuite/PackageTests/Install/DistPrefInstall/setup.test.hs b/cabal-testsuite/PackageTests/Install/DistPrefInstall/setup.test.hs new file mode 100644 index 00000000000..27b709e7070 --- /dev/null +++ b/cabal-testsuite/PackageTests/Install/DistPrefInstall/setup.test.hs @@ -0,0 +1,8 @@ +import Test.Cabal.Prelude + +main = setupTest $ recordMode DoNotRecord $ withPackageDb $ do + setup "configure" [] + setup "build" [] + setup "copy" [] + setup "install" [] + setup "sdist" [] diff --git a/cabal-testsuite/PackageTests/Install/DistPrefInstall/src/MyLib.hs b/cabal-testsuite/PackageTests/Install/DistPrefInstall/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/Install/DistPrefInstall/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/changelog.d/t10416 b/changelog.d/t10416 new file mode 100644 index 00000000000..071b9b1ad95 --- /dev/null +++ b/changelog.d/t10416 @@ -0,0 +1,11 @@ +synopsis: Fix ./setup install command +packages: Cabal +prs: #10417 +issues: #10416 +significance: significant + +description: { + +- `./setup install` was failing with a `fromFlag NoFlag` error. It is now fixed. + +} From b8affe678de07aa10cea392e1b09cf1b0a7f212b Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Fri, 4 Oct 2024 21:59:28 -0400 Subject: [PATCH 191/207] have Mergify insist on all-green CI GitHub's branch protection rules just don't cut it. (As a result, neither does GitHub's merge queue.) --- .github/mergify.yml | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/.github/mergify.yml b/.github/mergify.yml index 46eae2f7a80..7f7712394dd 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -52,15 +52,7 @@ pull_request_rules: - label=merge+no rebase - '#approved-reviews-by>=2' - '#changes-requested-reviews-by=0' - # oy - # lifted these from branch protection imports - - check-success=fourmolu - - check-success=hlint - - check-success=Meta checks - - check-success=Doctest Cabal - - check-success=Validate post job - - check-success=Bootstrap post job - - 'check-success=docs/readthedocs.org:cabal' + - '#check-failure=0' # rebase+merge strategy - actions: @@ -73,6 +65,7 @@ pull_request_rules: - label=merge delay passed - '#approved-reviews-by>=2' - '-label~=^blocked:' + - '#check-failure=0' # merge+squash strategy - actions: @@ -85,6 +78,7 @@ pull_request_rules: - label=merge delay passed - '#approved-reviews-by>=2' - '-label~=^blocked:' + - '#check-failure=0' # merge+no rebase strategy - actions: @@ -97,6 +91,11 @@ pull_request_rules: - label=merge delay passed - '#approved-reviews-by>=2' - '-label~=^blocked:' + - '#check-failure=0' + # unlike the others, we need to force this one to be up to date + # because it's intended for when Mergify doesn't have permission + # to rebase + - '#commits-behind=0' # merge strategy for release branches - actions: @@ -109,6 +108,7 @@ pull_request_rules: - -body~=backport - '#approved-reviews-by>=2' - '-label~=^blocked:' + - '#check-failure=0' # merge+squash strategy for release branches - actions: @@ -121,6 +121,7 @@ pull_request_rules: - -body~=backport - '#approved-reviews-by>=2' - '-label~=^blocked:' + - '#check-failure=0' # merge strategy for backports: require 1 approver instead of 2 - actions: @@ -133,6 +134,7 @@ pull_request_rules: - body~=backport - '#approved-reviews-by>=1' - '-label~=^blocked:' + - '#check-failure=0' # merge+squash strategy for backports: require 1 approver instead of 2 - actions: @@ -145,6 +147,7 @@ pull_request_rules: - body~=backport - '#approved-reviews-by>=1' - '-label~=^blocked:' + - '#check-failure=0' # backports should be labeled as such - actions: From e29f49afb6ae0ec48fc7cb8eb592bda450cb106d Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Fri, 27 Sep 2024 16:42:51 -0700 Subject: [PATCH 192/207] Add type and documentation to `toSavedConfig` This helper function was challenging to understand, so I added an explicit type signature and documentation comments to it. --- cabal-install/src/Distribution/Client/Config.hs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cabal-install/src/Distribution/Client/Config.hs b/cabal-install/src/Distribution/Client/Config.hs index 2faf9e1756d..f7b01512ca4 100644 --- a/cabal-install/src/Distribution/Client/Config.hs +++ b/cabal-install/src/Distribution/Client/Config.hs @@ -160,6 +160,7 @@ import qualified Distribution.Deprecated.ParseUtils as ParseUtils import Distribution.Parsec (ParsecParser, parsecFilePath, parsecOptCommaList, parsecToken) import Distribution.Simple.Command ( CommandUI (commandOptions) + , OptionField , ShowOrParseArgs (..) , commandDefaultFlags ) @@ -1314,6 +1315,19 @@ configFieldDescriptions src = ParseArgs ] where + toSavedConfig + :: (FieldDescr a -> FieldDescr SavedConfig) + -- Lifting function. + -> [OptionField a] + -- Option fields. + -> [String] + -- Fields to exclude, by name. + -> [FieldDescr a] + -- Field replacements. + -- + -- If an option is found with the same name as one of these replacement + -- fields, the replacement field is used instead of the option. + -> [FieldDescr SavedConfig] toSavedConfig lift options exclusions replacements = [ lift (fromMaybe field replacement) | opt <- options From d83d02461429e8e2c4d728ea3ed10ece2217729e Mon Sep 17 00:00:00 2001 From: ffaf1 Date: Tue, 8 Oct 2024 19:16:29 +0200 Subject: [PATCH 193/207] Handle SPDX licences starting with a digit (#10356) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Handle licences starting with a digit cabal has a devscript that parses a json file (containing SPDX licences) and returns a number of of Haskell data constructors. There have been problems when the SPDX short identifier starts with a digit (e.g. “0BSD”), as that would generate an data constructor starting with a digit, which is not valid Haskell. The way to handle such occourrences was in an ad-hoc basis. This patch prepends “N_” to the beginning of every SPDX licence starting with a digit, future-proofing the script. * Regenerate licence files Useless since we are going to have to do it again before a release, needed to make CI green (“Check that diff is clean”). --- .../Distribution/SPDX/LicenseExceptionId.hs | 8 ++++---- .../src/Distribution/SPDX/LicenseId.hs | 18 +++++++++--------- cabal-dev-scripts/src/GenUtils.hs | 9 +++++---- changelog.d/pr-10356 | 11 +++++++++++ 4 files changed, 29 insertions(+), 17 deletions(-) create mode 100644 changelog.d/pr-10356 diff --git a/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs b/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs index 2ab6eb9eeff..6d0bb37caba 100644 --- a/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs +++ b/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs @@ -32,7 +32,7 @@ import qualified Text.PrettyPrint as Disp -- | SPDX License Exceptions identifiers list v3.25 data LicenseExceptionId - = DS389_exception -- ^ @389-exception@, 389 Directory Server Exception + = N_389_exception -- ^ @389-exception@, 389 Directory Server Exception | Asterisk_exception -- ^ @Asterisk-exception@, Asterisk exception, SPDX License List 3.23, SPDX License List 3.25 | Asterisk_linking_protocols_exception -- ^ @Asterisk-linking-protocols-exception@, Asterisk linking protocols exception, SPDX License List 3.25 | Autoconf_exception_2_0 -- ^ @Autoconf-exception-2.0@, Autoconf exception 2.0 @@ -137,7 +137,7 @@ instance NFData LicenseExceptionId where -- | License SPDX identifier, e.g. @"BSD-3-Clause"@. licenseExceptionId :: LicenseExceptionId -> String -licenseExceptionId DS389_exception = "389-exception" +licenseExceptionId N_389_exception = "389-exception" licenseExceptionId Asterisk_exception = "Asterisk-exception" licenseExceptionId Asterisk_linking_protocols_exception = "Asterisk-linking-protocols-exception" licenseExceptionId Autoconf_exception_2_0 = "Autoconf-exception-2.0" @@ -212,7 +212,7 @@ licenseExceptionId X11vnc_openssl_exception = "x11vnc-openssl-exception" -- | License name, e.g. @"GNU General Public License v2.0 only"@ licenseExceptionName :: LicenseExceptionId -> String -licenseExceptionName DS389_exception = "389 Directory Server Exception" +licenseExceptionName N_389_exception = "389 Directory Server Exception" licenseExceptionName Asterisk_exception = "Asterisk exception" licenseExceptionName Asterisk_linking_protocols_exception = "Asterisk linking protocols exception" licenseExceptionName Autoconf_exception_2_0 = "Autoconf exception 2.0" @@ -504,7 +504,7 @@ stringLookup_3_25 = Map.fromList $ map (\i -> (licenseExceptionId i, i)) $ -- | License exceptions in all SPDX License lists bulkOfLicenses :: [LicenseExceptionId] bulkOfLicenses = - [ DS389_exception + [ N_389_exception , Autoconf_exception_2_0 , Autoconf_exception_3_0 , Bison_exception_2_2 diff --git a/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs b/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs index 16421e475f9..95d315906c7 100644 --- a/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs +++ b/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs @@ -35,8 +35,8 @@ import qualified Text.PrettyPrint as Disp -- | SPDX License identifiers list v3.25 data LicenseId - = NullBSD -- ^ @0BSD@, BSD Zero Clause License - | X3D_Slicer_1_0 -- ^ @3D-Slicer-1.0@, 3D Slicer License v1.0, SPDX License List 3.25 + = N_0BSD -- ^ @0BSD@, BSD Zero Clause License + | N_3D_Slicer_1_0 -- ^ @3D-Slicer-1.0@, 3D Slicer License v1.0, SPDX License List 3.25 | AAL -- ^ @AAL@, Attribution Assurance License | Abstyles -- ^ @Abstyles@, Abstyles License | AdaCore_doc -- ^ @AdaCore-doc@, AdaCore Doc License, SPDX License List 3.23, SPDX License List 3.25 @@ -756,8 +756,8 @@ licenseIdMigrationMessage = go where -- | License SPDX identifier, e.g. @"BSD-3-Clause"@. licenseId :: LicenseId -> String -licenseId NullBSD = "0BSD" -licenseId X3D_Slicer_1_0 = "3D-Slicer-1.0" +licenseId N_0BSD = "0BSD" +licenseId N_3D_Slicer_1_0 = "3D-Slicer-1.0" licenseId AAL = "AAL" licenseId Abstyles = "Abstyles" licenseId AdaCore_doc = "AdaCore-doc" @@ -1398,8 +1398,8 @@ licenseId ZPL_2_1 = "ZPL-2.1" -- | License name, e.g. @"GNU General Public License v2.0 only"@ licenseName :: LicenseId -> String -licenseName NullBSD = "BSD Zero Clause License" -licenseName X3D_Slicer_1_0 = "3D Slicer License v1.0" +licenseName N_0BSD = "BSD Zero Clause License" +licenseName N_3D_Slicer_1_0 = "3D Slicer License v1.0" licenseName AAL = "Attribution Assurance License" licenseName Abstyles = "Abstyles License" licenseName AdaCore_doc = "AdaCore Doc License" @@ -2042,7 +2042,7 @@ licenseName ZPL_2_1 = "Zope Public License 2.1" -- -- See . licenseIsOsiApproved :: LicenseId -> Bool -licenseIsOsiApproved NullBSD = True +licenseIsOsiApproved N_0BSD = True licenseIsOsiApproved AAL = True licenseIsOsiApproved AFL_1_1 = True licenseIsOsiApproved AFL_1_2 = True @@ -2886,7 +2886,7 @@ licenseIdList LicenseListVersion_3_23 = ] ++ bulkOfLicenses licenseIdList LicenseListVersion_3_25 = - [ X3D_Slicer_1_0 + [ N_3D_Slicer_1_0 , AdaCore_doc , Adobe_Display_PostScript , Adobe_Utopia @@ -3232,7 +3232,7 @@ stringLookup_3_25 = Map.fromList $ map (\i -> (licenseId i, i)) $ -- | Licenses in all SPDX License lists bulkOfLicenses :: [LicenseId] bulkOfLicenses = - [ NullBSD + [ N_0BSD , AAL , Abstyles , Adobe_2006 diff --git a/cabal-dev-scripts/src/GenUtils.hs b/cabal-dev-scripts/src/GenUtils.hs index f64388463da..17b4669c837 100644 --- a/cabal-dev-scripts/src/GenUtils.hs +++ b/cabal-dev-scripts/src/GenUtils.hs @@ -15,6 +15,7 @@ import Data.Text (Text) import GHC.Generics (Generic) import qualified Data.Algorithm.Diff as Diff +import qualified Data.Char as C import qualified Data.Map as Map import qualified Data.Set as Set import qualified Data.Text as T @@ -165,10 +166,10 @@ toConstructorName t = t f c = c special :: Text -> Text - special "0BSD" = "NullBSD" - special "389_exception" = "DS389_exception" - special "3D_Slicer_1_0" = "X3D_Slicer_1_0" - special u = u + special u + | Just (c, _) <- T.uncons u + , C.isDigit c = "N_" <> u + special u = u mkList :: [Text] -> Text mkList [] = " []" diff --git a/changelog.d/pr-10356 b/changelog.d/pr-10356 new file mode 100644 index 00000000000..dbe464ae492 --- /dev/null +++ b/changelog.d/pr-10356 @@ -0,0 +1,11 @@ +synopsis: New licence constructors for SPDX licences starting with a digit +packages: Cabal-syntax +prs: #10356 + +description: { + +- LicenseId constructor `NullBSD` is now `N_0BSD`. +- LicenseId constructor `DS389_exception` is now and `N_389_exception`. +- LicenseId constructor `X3D_Slicer_1_0` is now and `N_3D_Slicer_1_0`. + +} From da3ab8e1def217369c44d43cd467b95dcba457c4 Mon Sep 17 00:00:00 2001 From: Rodrigo Mesquita Date: Mon, 7 Oct 2024 14:28:19 +0100 Subject: [PATCH 194/207] Fix build ways for foreign libs Patches the component build ways for foreign library components. --- Cabal/src/Distribution/Simple/GHC/Build.hs | 29 ++++++++++--------- .../PackageTests/ProfShared/setup.test.hs | 4 +-- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/Cabal/src/Distribution/Simple/GHC/Build.hs b/Cabal/src/Distribution/Simple/GHC/Build.hs index c12fb7b2427..0993e916886 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build.hs @@ -12,7 +12,7 @@ import Distribution.Simple.Flag (Flag) import Distribution.Simple.GHC.Build.ExtraSources import Distribution.Simple.GHC.Build.Link import Distribution.Simple.GHC.Build.Modules -import Distribution.Simple.GHC.Build.Utils (compilerBuildWay, isHaskell) +import Distribution.Simple.GHC.Build.Utils (compilerBuildWay, isHaskell, withDynFLib) import Distribution.Simple.LocalBuildInfo import Distribution.Simple.Program.Builtin (ghcProgram) import Distribution.Simple.Program.Db (requireProgram) @@ -113,21 +113,24 @@ build numJobs pkg_descr pbci = do (ghcProg, _) <- liftIO $ requireProgram verbosity ghcProgram (withPrograms lbi) -- Ways which are wanted from configuration flags - let wantedWays@(wantedLibWays, _, wantedExeWay) = buildWays lbi + let wantedWays@(wantedLibWays, wantedFLibWay, wantedExeWay) = buildWays lbi -- Ways which are needed due to the compiler configuration let doingTH = usesTemplateHaskellOrQQ bi defaultGhcWay = compilerBuildWay (buildCompiler pbci) - wantedLibBuildWays = - if isLib - then wantedLibWays isIndef - else [wantedExeWay] - finalLibBuildWays = - wantedLibBuildWays - ++ [defaultGhcWay | doingTH && defaultGhcWay `notElem` wantedLibBuildWays] - - liftIO $ info verbosity ("Wanted build ways(" ++ show isLib ++ "): " ++ show wantedLibBuildWays) - liftIO $ info verbosity ("Final lib build ways(" ++ show isLib ++ "): " ++ show finalLibBuildWays) + wantedModBuildWays = case buildComponent pbci of + CLib _ -> wantedLibWays isIndef + CFLib fl -> [wantedFLibWay (withDynFLib fl)] + CExe _ -> [wantedExeWay] + CTest _ -> [wantedExeWay] + CBench _ -> [wantedExeWay] + finalModBuildWays = + wantedModBuildWays + ++ [defaultGhcWay | doingTH && defaultGhcWay `notElem` wantedModBuildWays] + compNameStr = showComponentName $ componentName $ buildComponent pbci + + liftIO $ info verbosity ("Wanted module build ways(" ++ compNameStr ++ "): " ++ show wantedModBuildWays) + liftIO $ info verbosity ("Final module build ways(" ++ compNameStr ++ "): " ++ show finalModBuildWays) -- We need a separate build and link phase, and C sources must be compiled -- after Haskell modules, because C sources may depend on stub headers -- generated from compiling Haskell modules (#842, #3294). @@ -141,7 +144,7 @@ build numJobs pkg_descr pbci = do | otherwise -> (Nothing, Just mainFile) Nothing -> (Nothing, Nothing) - buildOpts <- buildHaskellModules numJobs ghcProg hsMainFile inputModules buildTargetDir finalLibBuildWays pbci + buildOpts <- buildHaskellModules numJobs ghcProg hsMainFile inputModules buildTargetDir finalModBuildWays pbci extraSources <- buildAllExtraSources nonHsMainFile ghcProg buildTargetDir wantedWays pbci linkOrLoadComponent ghcProg diff --git a/cabal-testsuite/PackageTests/ProfShared/setup.test.hs b/cabal-testsuite/PackageTests/ProfShared/setup.test.hs index 84fcbd47e57..54147e34575 100644 --- a/cabal-testsuite/PackageTests/ProfShared/setup.test.hs +++ b/cabal-testsuite/PackageTests/ProfShared/setup.test.hs @@ -16,8 +16,8 @@ main = do let ls = lines (resultOutput r) - library_prefix = "Wanted build ways(True): " - executable_prefix = "Wanted build ways(False): " + library_prefix = "Wanted module build ways(library): " + executable_prefix = "Wanted module build ways(executable 'Prof'): " get_ways prefix = map (drop (length prefix)) (filter (prefix `isPrefixOf`) ls) library_ways = read_ways (get_ways library_prefix) From f3f5a1111b09164c64e77fbd60a16f0a027a8709 Mon Sep 17 00:00:00 2001 From: Artem Pelenitsyn Date: Mon, 7 Oct 2024 10:07:58 -0400 Subject: [PATCH 195/207] README: add Cabal-hooks to the list of packages --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4697cf2b2c6..9d4a937db97 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ This Cabal Git repository contains the following main packages: * [Cabal](Cabal/README.md): the Cabal library package ([license](Cabal/LICENSE)) + * [Cabal-hooks](Cabal-hooks/README.md): the library providing an API for the Cabal `Hooks` build type ([license](Cabal-hooks/LICENSE)) * [Cabal-syntax](Cabal-syntax/README.md): the `.cabal` file format library ([license](Cabal-syntax/LICENSE)) * [cabal-install](cabal-install/README.md): the package containing the `cabal` tool ([license](cabal-install/LICENSE)) * [cabal-install-solver](cabal-install-solver): the package containing the solver component of the `cabal` tool ([license](cabal-install-solver/LICENSE)) From ef35dd85b6eab3fd0782b1fa539f73250b4e9d36 Mon Sep 17 00:00:00 2001 From: Mike Pilgrem Date: Sun, 6 Oct 2024 17:00:00 +0100 Subject: [PATCH 196/207] Avoid partial last in autogen Paths_.hs --- Cabal/src/Distribution/Simple/Build/PathsModule/Z.hs | 10 +++++++--- changelog.d/pr-10432 | 10 ++++++++++ templates/Paths_pkg.template.hs | 10 +++++++--- 3 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 changelog.d/pr-10432 diff --git a/Cabal/src/Distribution/Simple/Build/PathsModule/Z.hs b/Cabal/src/Distribution/Simple/Build/PathsModule/Z.hs index 25c924720ec..ad979c42951 100644 --- a/Cabal/src/Distribution/Simple/Build/PathsModule/Z.hs +++ b/Cabal/src/Distribution/Simple/Build/PathsModule/Z.hs @@ -69,7 +69,6 @@ render z_root = execWriter $ do return () tell "\n" tell "import qualified Control.Exception as Exception\n" - tell "import qualified Data.List as List\n" tell "import Data.Version (Version(..))\n" tell "import System.Environment (getEnv)\n" tell "import Prelude\n" @@ -306,9 +305,14 @@ render z_root = execWriter $ do tell "joinFileName \"\" fname = fname\n" tell "joinFileName \".\" fname = fname\n" tell "joinFileName dir \"\" = dir\n" - tell "joinFileName dir fname\n" - tell " | isPathSeparator (List.last dir) = dir ++ fname\n" + tell "joinFileName dir@(c:cs) fname\n" + tell " | isPathSeparator (lastChar c cs) = dir ++ fname\n" tell " | otherwise = dir ++ pathSeparator : fname\n" + tell " where\n" + tell " -- We do not use Data.List.NonEmpty.last, as that would limit the module to\n" + tell " -- base >= 4.9.0.0 (GHC >= 8.0.1).\n" + tell " lastChar x [] = x\n" + tell " lastChar _ (x:xs) = lastChar x xs\n" tell "\n" tell "pathSeparator :: Char\n" if (zIsWindows z_root) diff --git a/changelog.d/pr-10432 b/changelog.d/pr-10432 new file mode 100644 index 00000000000..1bb76adb0a1 --- /dev/null +++ b/changelog.d/pr-10432 @@ -0,0 +1,10 @@ +synopsis: Avoid partial `Data.List.last` in autogenerated `Paths_.hs` +packages: Cabal +prs: #10432 +significance: + +description: { + +- Autogenerated `Paths_.hs` now avoids use of the partial function `Data.List.last`. + +} diff --git a/templates/Paths_pkg.template.hs b/templates/Paths_pkg.template.hs index 8e1e03d27e4..bea7d6813e3 100644 --- a/templates/Paths_pkg.template.hs +++ b/templates/Paths_pkg.template.hs @@ -26,7 +26,6 @@ import Foreign.C {% endif %} import qualified Control.Exception as Exception -import qualified Data.List as List import Data.Version (Version(..)) import System.Environment (getEnv) import Prelude @@ -175,9 +174,14 @@ joinFileName :: String -> String -> FilePath joinFileName "" fname = fname joinFileName "." fname = fname joinFileName dir "" = dir -joinFileName dir fname - | isPathSeparator (List.last dir) = dir ++ fname +joinFileName dir@(c:cs) fname + | isPathSeparator (lastChar c cs) = dir ++ fname | otherwise = dir ++ pathSeparator : fname + where + -- We do not use Data.List.NonEmpty.last, as that would limit the module to + -- base >= 4.9.0.0 (GHC >= 8.0.1). + lastChar x [] = x + lastChar _ (x:xs) = lastChar x xs pathSeparator :: Char {% if isWindows %} From 77184c9245d30818ddd93837847d42d0808bdc72 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Fri, 11 Oct 2024 11:43:00 -0400 Subject: [PATCH 197/207] switch validate to 22.04 for now `validate-old-ghcs` doesn't work on 24.04, which GHA just updated to; and it uses build artifacts from the earlier steps, so for now the whole thing needs to be downgraded to get thinsg working. We must address this properly later. --- .github/workflows/validate.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 23fe4e5e7d1..5f21db515f7 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -71,7 +71,7 @@ jobs: matrix: sys: - { os: windows-latest, shell: "C:/msys64/usr/bin/bash.exe -e {0}" } - - { os: ubuntu-latest, shell: bash } + - { os: ubuntu-22.04, shell: bash } - { os: macos-latest, shell: bash } # If you remove something from here, then add it to the old-ghcs job. # Also a removed GHC from here means that we are actually dropping @@ -262,7 +262,7 @@ jobs: validate-old-ghcs: name: Validate old ghcs ${{ matrix.extra-ghc }} - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: validate strategy: @@ -395,7 +395,7 @@ jobs: matrix: sys: - { os: windows-latest, shell: "C:/msys64/usr/bin/bash.exe -e {0}" } - - { os: ubuntu-latest, shell: bash } + - { os: ubuntu-22.04, shell: bash } - { os: macos-latest, shell: bash } # We only use one ghc version the used one for the next release (defined at top of the workflow) # We need to build an array dynamically to inject the appropiate env var in a previous job, From 43ace9c4eaa6a7a07cd9f3ae7aaae59eeb7c2f65 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Fri, 27 Sep 2024 16:30:48 -0700 Subject: [PATCH 198/207] haddock-project: add CommonSetupFlags --- .../src/Distribution/Simple/Setup/Haddock.hs | 273 +++++++++--------- .../Distribution/Client/CmdHaddockProject.hs | 114 ++++---- .../src/Distribution/Client/Config.hs | 2 +- .../Client/ProjectConfig/Legacy.hs | 4 +- cabal-install/tests/IntegrationTests2.hs | 9 +- 5 files changed, 204 insertions(+), 198 deletions(-) diff --git a/Cabal/src/Distribution/Simple/Setup/Haddock.hs b/Cabal/src/Distribution/Simple/Setup/Haddock.hs index aee2210d907..7e8df14cfa1 100644 --- a/Cabal/src/Distribution/Simple/Setup/Haddock.hs +++ b/Cabal/src/Distribution/Simple/Setup/Haddock.hs @@ -413,7 +413,8 @@ data Visibility = Visible | Hidden deriving (Eq, Show) data HaddockProjectFlags = HaddockProjectFlags - { haddockProjectHackage :: Flag Bool + { haddockProjectCommonFlags :: !CommonSetupFlags + , haddockProjectHackage :: Flag Bool -- ^ a shortcut option which builds documentation linked to hackage. It implies: -- * `--html-location='https://hackage.haskell.org/package/$prg-$version/docs' -- * `--quickjump` @@ -457,7 +458,8 @@ data HaddockProjectFlags = HaddockProjectFlags defaultHaddockProjectFlags :: HaddockProjectFlags defaultHaddockProjectFlags = HaddockProjectFlags - { haddockProjectHackage = Flag False + { haddockProjectCommonFlags = defaultCommonSetupFlags + , haddockProjectHackage = Flag False , haddockProjectDir = Flag "./haddocks" , haddockProjectPrologue = NoFlag , haddockProjectTestSuites = Flag False @@ -517,140 +519,141 @@ haddockProjectCommand = emptyProgramDb haddockProjectOptions :: ShowOrParseArgs -> [OptionField HaddockProjectFlags] -haddockProjectOptions _showOrParseArgs = - [ option - "" - ["hackage"] - ( concat - [ "A short-cut option to build documentation linked to hackage." - ] - ) - haddockProjectHackage - (\v flags -> flags{haddockProjectHackage = v}) - trueArg - , option - "" - ["output"] - "Output directory" - haddockProjectDir - (\v flags -> flags{haddockProjectDir = v}) - (optArg' "DIRECTORY" maybeToFlag (fmap Just . flagToList)) - , option - "" - ["prologue"] - "File path to a prologue file in haddock format" - haddockProjectPrologue - (\v flags -> flags{haddockProjectPrologue = v}) - (optArg' "PATH" maybeToFlag (fmap Just . flagToList)) - , option - "" - ["hoogle"] - "Generate a hoogle database" - haddockProjectHoogle - (\v flags -> flags{haddockProjectHoogle = v}) - trueArg - , option - "" - ["html-location"] - "Location of HTML documentation for pre-requisite packages" - haddockProjectHtmlLocation - (\v flags -> flags{haddockProjectHtmlLocation = v}) - (reqArgFlag "URL") - , option - "" - ["executables"] - "Run haddock for Executables targets" - haddockProjectExecutables - (\v flags -> flags{haddockProjectExecutables = v}) - trueArg - , option - "" - ["tests"] - "Run haddock for Test Suite targets" - haddockProjectTestSuites - (\v flags -> flags{haddockProjectTestSuites = v}) - trueArg - , option - "" - ["benchmarks"] - "Run haddock for Benchmark targets" - haddockProjectBenchmarks - (\v flags -> flags{haddockProjectBenchmarks = v}) - trueArg - , option - "" - ["foreign-libraries"] - "Run haddock for Foreign Library targets" - haddockProjectForeignLibs - (\v flags -> flags{haddockProjectForeignLibs = v}) - trueArg - , option - "" - ["all", "haddock-all"] - "Run haddock for all targets" - ( \f -> - allFlags - [ haddockProjectExecutables f - , haddockProjectTestSuites f - , haddockProjectBenchmarks f - , haddockProjectForeignLibs f +haddockProjectOptions showOrParseArgs = + withCommonSetupOptions + haddockProjectCommonFlags + (\c f -> f{haddockProjectCommonFlags = c}) + showOrParseArgs + [ option + "" + ["hackage"] + ( concat + [ "A short-cut option to build documentation linked to hackage." ] - ) - ( \v flags -> - flags - { haddockProjectExecutables = v - , haddockProjectTestSuites = v - , haddockProjectBenchmarks = v - , haddockProjectForeignLibs = v - } - ) - trueArg - , option - "" - ["internal"] - "Run haddock for internal modules and include all symbols" - haddockProjectInternal - (\v flags -> flags{haddockProjectInternal = v}) - trueArg - , option - "" - ["css"] - "Use PATH as the haddock stylesheet" - haddockProjectCss - (\v flags -> flags{haddockProjectCss = v}) - (reqArgFlag "PATH") - , option - "" - ["hscolour-css"] - "Use PATH as the HsColour stylesheet" - haddockProjectHscolourCss - (\v flags -> flags{haddockProjectHscolourCss = v}) - (reqArgFlag "PATH") - , option - "" - ["keep-temp-files"] - "Keep temporary files" - haddockProjectKeepTempFiles - (\b flags -> flags{haddockProjectKeepTempFiles = b}) - trueArg - , optionVerbosity - haddockProjectVerbosity - (\v flags -> flags{haddockProjectVerbosity = v}) - , option - "" - ["resources-dir"] - "location of Haddocks static / auxiliary files" - haddockProjectResourcesDir - (\v flags -> flags{haddockProjectResourcesDir = v}) - (reqArgFlag "DIR") - , option - "" - ["use-unicode"] - "Pass --use-unicode option to haddock" - haddockProjectUseUnicode - (\v flags -> flags{haddockProjectUseUnicode = v}) - trueArg - ] + ) + haddockProjectHackage + (\v flags -> flags{haddockProjectHackage = v}) + trueArg + , option + "" + ["output"] + "Output directory" + haddockProjectDir + (\v flags -> flags{haddockProjectDir = v}) + (optArg' "DIRECTORY" maybeToFlag (fmap Just . flagToList)) + , option + "" + ["prologue"] + "File path to a prologue file in haddock format" + haddockProjectPrologue + (\v flags -> flags{haddockProjectPrologue = v}) + (optArg' "PATH" maybeToFlag (fmap Just . flagToList)) + , option + "" + ["hoogle"] + "Generate a hoogle database" + haddockProjectHoogle + (\v flags -> flags{haddockProjectHoogle = v}) + trueArg + , option + "" + ["html-location"] + "Location of HTML documentation for pre-requisite packages" + haddockProjectHtmlLocation + (\v flags -> flags{haddockProjectHtmlLocation = v}) + (reqArgFlag "URL") + , option + "" + ["executables"] + "Run haddock for Executables targets" + haddockProjectExecutables + (\v flags -> flags{haddockProjectExecutables = v}) + trueArg + , option + "" + ["tests"] + "Run haddock for Test Suite targets" + haddockProjectTestSuites + (\v flags -> flags{haddockProjectTestSuites = v}) + trueArg + , option + "" + ["benchmarks"] + "Run haddock for Benchmark targets" + haddockProjectBenchmarks + (\v flags -> flags{haddockProjectBenchmarks = v}) + trueArg + , option + "" + ["foreign-libraries"] + "Run haddock for Foreign Library targets" + haddockProjectForeignLibs + (\v flags -> flags{haddockProjectForeignLibs = v}) + trueArg + , option + "" + ["all", "haddock-all"] + "Run haddock for all targets" + ( \f -> + allFlags + [ haddockProjectExecutables f + , haddockProjectTestSuites f + , haddockProjectBenchmarks f + , haddockProjectForeignLibs f + ] + ) + ( \v flags -> + flags + { haddockProjectExecutables = v + , haddockProjectTestSuites = v + , haddockProjectBenchmarks = v + , haddockProjectForeignLibs = v + } + ) + trueArg + , option + "" + ["internal"] + "Run haddock for internal modules and include all symbols" + haddockProjectInternal + (\v flags -> flags{haddockProjectInternal = v}) + trueArg + , option + "" + ["css"] + "Use PATH as the haddock stylesheet" + haddockProjectCss + (\v flags -> flags{haddockProjectCss = v}) + (reqArgFlag "PATH") + , option + "" + ["hscolour-css"] + "Use PATH as the HsColour stylesheet" + haddockProjectHscolourCss + (\v flags -> flags{haddockProjectHscolourCss = v}) + (reqArgFlag "PATH") + , option + "" + ["keep-temp-files"] + "Keep temporary files" + haddockProjectKeepTempFiles + (\b flags -> flags{haddockProjectKeepTempFiles = b}) + trueArg + , option + "" + ["resources-dir"] + "location of Haddocks static / auxiliary files" + haddockProjectResourcesDir + (\v flags -> flags{haddockProjectResourcesDir = v}) + (reqArgFlag "DIR") + , option + "" + ["use-unicode"] + "Pass --use-unicode option to haddock" + haddockProjectUseUnicode + (\v flags -> flags{haddockProjectUseUnicode = v}) + trueArg + ] emptyHaddockProjectFlags :: HaddockProjectFlags emptyHaddockProjectFlags = mempty diff --git a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs index f632e8b7caa..ca8330b3b8d 100644 --- a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs +++ b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs @@ -85,7 +85,6 @@ import Distribution.Simple.Setup , HaddockProjectFlags (..) , HaddockTarget (..) , Visibility (..) - , defaultCommonSetupFlags , defaultHaddockFlags , haddockProjectCommand ) @@ -119,62 +118,6 @@ haddockProjectAction flags _extraArgs globalFlags = do warn verbosity "haddock-project command is experimental, it might break in the future" - -- build all packages with appropriate haddock flags - let commonFlags = - defaultCommonSetupFlags - { setupVerbosity = haddockProjectVerbosity flags - } - haddockFlags = - defaultHaddockFlags - { haddockCommonFlags = commonFlags - , haddockHtml = Flag True - , -- one can either use `--haddock-base-url` or - -- `--haddock-html-location`. - haddockBaseUrl = - if localStyle - then Flag ".." - else NoFlag - , haddockProgramPaths = haddockProjectProgramPaths flags - , haddockProgramArgs = haddockProjectProgramArgs flags - , haddockHtmlLocation = - if fromFlagOrDefault False (haddockProjectHackage flags) - then Flag "https://hackage.haskell.org/package/$pkg-$version/docs" - else haddockProjectHtmlLocation flags - , haddockHoogle = haddockProjectHoogle flags - , haddockExecutables = haddockProjectExecutables flags - , haddockTestSuites = haddockProjectTestSuites flags - , haddockBenchmarks = haddockProjectBenchmarks flags - , haddockForeignLibs = haddockProjectForeignLibs flags - , haddockInternal = haddockProjectInternal flags - , haddockCss = haddockProjectCss flags - , haddockLinkedSource = Flag True - , haddockQuickJump = Flag True - , haddockHscolourCss = haddockProjectHscolourCss flags - , haddockContents = - if localStyle - then Flag (toPathTemplate "../index.html") - else NoFlag - , haddockIndex = - if localStyle - then Flag (toPathTemplate "../doc-index.html") - else NoFlag - , haddockKeepTempFiles = haddockProjectKeepTempFiles flags - , haddockResourcesDir = haddockProjectResourcesDir flags - , haddockUseUnicode = haddockProjectUseUnicode flags - -- NOTE: we don't pass `haddockOutputDir`. If we do, we'll need to - -- make sure `InstalledPackageInfo` contains the right path to - -- haddock interfaces. Instead we build documentation inside - -- `dist-newstyle` directory and copy it to the output directory. - } - nixFlags = - (commandDefaultFlags CmdHaddock.haddockCommand) - { NixStyleOptions.haddockFlags = haddockFlags - , NixStyleOptions.configFlags = - (NixStyleOptions.configFlags (commandDefaultFlags CmdBuild.buildCommand)) - { configCommonFlags = commonFlags - } - } - -- -- Construct the build plan and infer the list of packages which haddocks -- we need. @@ -409,7 +352,62 @@ haddockProjectAction flags _extraArgs globalFlags = do Nothing flags' where - verbosity = fromFlagOrDefault normal (haddockProjectVerbosity flags) + -- build all packages with appropriate haddock flags + commonFlags = haddockProjectCommonFlags flags + + verbosity = fromFlagOrDefault normal (setupVerbosity commonFlags) + + haddockFlags = + defaultHaddockFlags + { haddockCommonFlags = commonFlags + , haddockHtml = Flag True + , -- one can either use `--haddock-base-url` or + -- `--haddock-html-location`. + haddockBaseUrl = + if localStyle + then Flag ".." + else NoFlag + , haddockProgramPaths = haddockProjectProgramPaths flags + , haddockProgramArgs = haddockProjectProgramArgs flags + , haddockHtmlLocation = + if fromFlagOrDefault False (haddockProjectHackage flags) + then Flag "https://hackage.haskell.org/package/$pkg-$version/docs" + else haddockProjectHtmlLocation flags + , haddockHoogle = haddockProjectHoogle flags + , haddockExecutables = haddockProjectExecutables flags + , haddockTestSuites = haddockProjectTestSuites flags + , haddockBenchmarks = haddockProjectBenchmarks flags + , haddockForeignLibs = haddockProjectForeignLibs flags + , haddockInternal = haddockProjectInternal flags + , haddockCss = haddockProjectCss flags + , haddockLinkedSource = Flag True + , haddockQuickJump = Flag True + , haddockHscolourCss = haddockProjectHscolourCss flags + , haddockContents = + if localStyle + then Flag (toPathTemplate "../index.html") + else NoFlag + , haddockIndex = + if localStyle + then Flag (toPathTemplate "../doc-index.html") + else NoFlag + , haddockKeepTempFiles = haddockProjectKeepTempFiles flags + , haddockResourcesDir = haddockProjectResourcesDir flags + , haddockUseUnicode = haddockProjectUseUnicode flags + -- NOTE: we don't pass `haddockOutputDir`. If we do, we'll need to + -- make sure `InstalledPackageInfo` contains the right path to + -- haddock interfaces. Instead we build documentation inside + -- `dist-newstyle` directory and copy it to the output directory. + } + + nixFlags = + (commandDefaultFlags CmdHaddock.haddockCommand) + { NixStyleOptions.haddockFlags = haddockFlags + , NixStyleOptions.configFlags = + (NixStyleOptions.configFlags (commandDefaultFlags CmdBuild.buildCommand)) + { configCommonFlags = commonFlags + } + } -- Build a self contained directory which contains haddocks of all -- transitive dependencies; or depend on `--haddocks-html-location` to diff --git a/cabal-install/src/Distribution/Client/Config.hs b/cabal-install/src/Distribution/Client/Config.hs index f7b01512ca4..c837db7bb08 100644 --- a/cabal-install/src/Distribution/Client/Config.hs +++ b/cabal-install/src/Distribution/Client/Config.hs @@ -1844,7 +1844,7 @@ haddockFlagsFields = , name `notElem` exclusions ] where - exclusions = ["verbose", "builddir", "for-hackage"] + exclusions = ["verbose", "builddir", "cabal-file", "for-hackage"] -- | Fields for the 'init' section. initFlagsFields :: [FieldDescr IT.InitFlags] diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs index a4191325f8b..7ed13df1232 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs @@ -862,8 +862,8 @@ convertLegacyBuildOnlyFlags installFlags clientInstallFlags haddockFlags - _ - _ = + _testFlags + _benchmarkFlags = ProjectConfigBuildOnly{..} where projectConfigClientInstallFlags = clientInstallFlags diff --git a/cabal-install/tests/IntegrationTests2.hs b/cabal-install/tests/IntegrationTests2.hs index 22c7da0c37f..113b025e280 100644 --- a/cabal-install/tests/IntegrationTests2.hs +++ b/cabal-install/tests/IntegrationTests2.hs @@ -49,7 +49,7 @@ import qualified Distribution.Client.CmdListBin as CmdListBin import Distribution.Package import Distribution.PackageDescription import Distribution.InstalledPackageInfo (InstalledPackageInfo) -import Distribution.Simple.Setup (toFlag, HaddockFlags(..), defaultHaddockFlags) +import Distribution.Simple.Setup (toFlag, CommonSetupFlags(..), HaddockFlags(..), defaultHaddockFlags, defaultCommonSetupFlags) import Distribution.Client.Setup (globalCommand) import Distribution.Client.Config (loadConfig, SavedConfig(savedGlobalFlags), createDefaultConfigFile) import Distribution.Simple.Compiler @@ -2289,7 +2289,12 @@ testHaddockProjectDependencies config = do cleanHaddockProject testdir withCurrentDirectory dir $ do CmdHaddockProject.haddockProjectAction - defaultHaddockProjectFlags { haddockProjectVerbosity = Flag verbosity } + defaultHaddockProjectFlags + { haddockProjectCommonFlags = + defaultCommonSetupFlags + { setupVerbosity = Flag verbosity + } + } ["all"] defaultGlobalFlags { globalStoreDir = Flag "store" } From c102b5bd2bff9968b03559efe97f40746949959f Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Fri, 4 Oct 2024 20:39:15 -0400 Subject: [PATCH 199/207] try to fix LTS prerelease workflow It's being skipped, not failing to fire, implying the wrong ref? This subsumes #10415. --- .github/workflows/validate.yml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 5f21db515f7..83e5a08a23c 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -21,6 +21,8 @@ on: - "release-notes/**" branches: - master + # hardcoded LTS branch, change when new LTS released! + - '3.12' pull_request: paths-ignore: - "doc/**" @@ -481,7 +483,9 @@ jobs: name: Create a GitHub LTS prerelease with the binary artifacts runs-on: ubuntu-latest # The LTS branch is hardcoded for now, update it on a new LTS! - if: github.ref == 'refs/heads/3.12' + # if: github.ref == 'refs/heads/3.12' + permissions: + contents: write # IMPORTANT! Any job added to the workflow should be added here too needs: [validate, validate-old-ghcs, build-alpine, dogfooding] @@ -494,12 +498,15 @@ jobs: - run: | # bash-ism, but we forced bash above - mv cabal-{,lts-}head-Windows-x86_64.tar.gz - mv cabal-{,lts-}head-Linux-x86_64.tar.gz - mv cabal-{,lts-}head-Linux-static-x86_64.tar.gz - mv cabal-{,lts-}head-macOS-aarch64.tar.gz + cd binaries + for f in cabal-*; do + mv "$f" "cabal-lts-${f##cabal-}" + done + + - run: echo ${{ github.ref }} - name: Create GitHub prerelease + if: github.ref == 'refs/heads/3.12' uses: softprops/action-gh-release@v2 with: tag_name: cabal-lts-head From 9a0d55a903f4e8ca11e919a4bb69340a832a4374 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Thu, 3 Oct 2024 20:35:47 -0400 Subject: [PATCH 200/207] round out local Makefile checks by collecting them and adding hlint. Other checks will follow, e.g. API checking once that lands. --- CONTRIBUTING.md | 7 +++++++ Makefile | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 93835320bb2..f2e28f2e069 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -157,6 +157,13 @@ For these test executables, `-p` which applies a regex filter to the test names. When running `cabal-install` test suites, one need only use `cabal test` or `cabal run ` in order to test locally. +## Running other checks locally + +Various other checks done by CI can be run locally to make sure your code doesn't +fail annoyingly once you push it. `make checks` will do these checks. The list of +checks is expected to grow over time, to make it easier to avoid CI turnaround on +simple problems. + ## QA Notes Manual Quality Assurance (QA) is performed to ensure that the changes impacting diff --git a/Makefile b/Makefile index 12d38557de6..5cf1cae4d6f 100644 --- a/Makefile +++ b/Makefile @@ -49,6 +49,13 @@ whitespace: ## Run fix-whitespace in check mode fix-whitespace: ## Run fix-whitespace in fix mode fix-whitespace --verbose +# local checks + +.PHONY: checks +checks: whitespace style + # this should probably be a rule + hlint -j --json -- . + # source generation: SPDX SPDX_LICENSE_HS:=Cabal-syntax/src/Distribution/SPDX/LicenseId.hs From b16a2cee584267dac23d4ef512e21f2ee975ebdf Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Sat, 12 Oct 2024 20:43:24 -0400 Subject: [PATCH 201/207] kill a `continue-on-error` It doesn't do what we really want, nor really does anything else that isn't an unwieldy-at-best stack of conditions. --- .github/workflows/validate.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 83e5a08a23c..9395720b417 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -261,6 +261,12 @@ jobs: echo End "$test" done exit $rc + # The above ensures all the tests get run, for a single platform+ghc. + # Trying to ensure they run for *all* combinations but still fail + # at the end seems to be extremely difficult at best. It's doable, + # but it requires a continuously growing stack of conditions and + # one possibly nightmarish final conditional. 'fail-fast' gets us + # partway there, at least, but is still imperfect. validate-old-ghcs: name: Validate old ghcs ${{ matrix.extra-ghc }} @@ -320,8 +326,9 @@ jobs: - name: "Validate lib-suite-extras --extra-hc ghc-${{ matrix.extra-ghc }}" env: EXTRA_GHC: ghc-${{ matrix.extra-ghc }} - continue-on-error: true run: sh validate.sh ${{ env.COMMON_FLAGS }} --lib-only -s lib-suite-extras --extra-hc "${{ env.EXTRA_GHC }}" + # See the comment above about running all tests but still failing if one + # of them does; it also applies here. build-alpine: name: Build statically linked using alpine From 4e35624ccd7650ac3cdbb6b28a2c9178d72206f2 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Wed, 16 Oct 2024 15:23:52 -0400 Subject: [PATCH 202/207] Revert "have Mergify insist on all-green CI" It didn't do what was intended, and apparently Mergify is now tripping over its own feet about it. This reverts commit d9c2b4093824c7bdf171b3a2113ff41cd09fd0de. --- .github/mergify.yml | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/.github/mergify.yml b/.github/mergify.yml index 7f7712394dd..46eae2f7a80 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -52,7 +52,15 @@ pull_request_rules: - label=merge+no rebase - '#approved-reviews-by>=2' - '#changes-requested-reviews-by=0' - - '#check-failure=0' + # oy + # lifted these from branch protection imports + - check-success=fourmolu + - check-success=hlint + - check-success=Meta checks + - check-success=Doctest Cabal + - check-success=Validate post job + - check-success=Bootstrap post job + - 'check-success=docs/readthedocs.org:cabal' # rebase+merge strategy - actions: @@ -65,7 +73,6 @@ pull_request_rules: - label=merge delay passed - '#approved-reviews-by>=2' - '-label~=^blocked:' - - '#check-failure=0' # merge+squash strategy - actions: @@ -78,7 +85,6 @@ pull_request_rules: - label=merge delay passed - '#approved-reviews-by>=2' - '-label~=^blocked:' - - '#check-failure=0' # merge+no rebase strategy - actions: @@ -91,11 +97,6 @@ pull_request_rules: - label=merge delay passed - '#approved-reviews-by>=2' - '-label~=^blocked:' - - '#check-failure=0' - # unlike the others, we need to force this one to be up to date - # because it's intended for when Mergify doesn't have permission - # to rebase - - '#commits-behind=0' # merge strategy for release branches - actions: @@ -108,7 +109,6 @@ pull_request_rules: - -body~=backport - '#approved-reviews-by>=2' - '-label~=^blocked:' - - '#check-failure=0' # merge+squash strategy for release branches - actions: @@ -121,7 +121,6 @@ pull_request_rules: - -body~=backport - '#approved-reviews-by>=2' - '-label~=^blocked:' - - '#check-failure=0' # merge strategy for backports: require 1 approver instead of 2 - actions: @@ -134,7 +133,6 @@ pull_request_rules: - body~=backport - '#approved-reviews-by>=1' - '-label~=^blocked:' - - '#check-failure=0' # merge+squash strategy for backports: require 1 approver instead of 2 - actions: @@ -147,7 +145,6 @@ pull_request_rules: - body~=backport - '#approved-reviews-by>=1' - '-label~=^blocked:' - - '#check-failure=0' # backports should be labeled as such - actions: From f0acc6731a559b7b00bc7efd9eabff8ed58b4250 Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Wed, 16 Oct 2024 16:47:33 -0400 Subject: [PATCH 203/207] restore up-to-date condition for no-rebase since Mergify can't do it or we wouldn't need the label --- .github/mergify.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/mergify.yml b/.github/mergify.yml index 46eae2f7a80..96bce6b9a36 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -85,6 +85,10 @@ pull_request_rules: - label=merge delay passed - '#approved-reviews-by>=2' - '-label~=^blocked:' + # unlike the others, we need to force this one to be up to date + # because it's intended for when Mergify doesn't have permission + # to rebase + - '#commits-behind=0' # merge+no rebase strategy - actions: From a2c09d716aecd8b4a407f0fda73373a81e008d86 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Fri, 4 Oct 2024 15:15:27 -0700 Subject: [PATCH 204/207] Add `--tasty-arg` to `validate.sh` This lets you add custom arguments to `Tasty` test suites. This can be used to set `--keep-tmp-files` for debugging, or to run a particular test in `cabal-testsuite`: ./validate.sh -v -s build -s cli-suite \ --tasty-arg PackageTests/HaddockKeepTmpsCustom/cabal.test.hs --- cabal-validate/src/Cli.hs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/cabal-validate/src/Cli.hs b/cabal-validate/src/Cli.hs index ef01d907594..423769cd1d9 100644 --- a/cabal-validate/src/Cli.hs +++ b/cabal-validate/src/Cli.hs @@ -234,9 +234,11 @@ resolveOpts opts = do tastyArgs' = "--hide-successes" - : case rawTastyPattern opts of - Just tastyPattern -> ["--pattern", tastyPattern] - Nothing -> [] + : maybe + [] + (\tastyPattern -> ["--pattern", tastyPattern]) + (rawTastyPattern opts) + ++ rawTastyArgs opts when (rawListSteps opts) $ do -- TODO: This should probably list _all_ available steps, not just the selected ones! @@ -279,6 +281,7 @@ data RawOpts = RawOpts , rawCabal :: FilePath , rawExtraCompilers :: [FilePath] , rawTastyPattern :: Maybe String + , rawTastyArgs :: [String] , rawDoctest :: Bool , rawSteps :: [Step] , rawListSteps :: Bool @@ -343,6 +346,12 @@ rawOptsParser = <> help "Pattern to filter tests by" <> value Nothing ) + <*> many + ( strOption + ( long "tasty-arg" + <> help "Extra arguments to pass to Tasty test suites" + ) + ) <*> boolOption False "doctest" From 332c1d273dcfb95c141b4a912a2a72c40d5be67a Mon Sep 17 00:00:00 2001 From: Zubin Duggal Date: Fri, 11 Oct 2024 16:34:24 +0530 Subject: [PATCH 205/207] Bump base bound to 4.21 for GHC 9.12 --- .../buildinfo-reference-generator.cabal | 2 +- cabal-install-solver/cabal-install-solver.cabal | 4 ++-- cabal-install/cabal-install.cabal | 2 +- cabal-testsuite/cabal-testsuite.cabal | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/buildinfo-reference-generator/buildinfo-reference-generator.cabal b/buildinfo-reference-generator/buildinfo-reference-generator.cabal index 47068ee33b1..a09fc4dc62c 100644 --- a/buildinfo-reference-generator/buildinfo-reference-generator.cabal +++ b/buildinfo-reference-generator/buildinfo-reference-generator.cabal @@ -8,7 +8,7 @@ executable buildinfo-reference-generator ghc-options: -Wall main-is: Main.hs build-depends: - , base >=4.11 && <4.21 + , base >=4.11 && <4.22 , Cabal , Cabal-described , containers diff --git a/cabal-install-solver/cabal-install-solver.cabal b/cabal-install-solver/cabal-install-solver.cabal index edd8f9246db..a96b787f55e 100644 --- a/cabal-install-solver/cabal-install-solver.cabal +++ b/cabal-install-solver/cabal-install-solver.cabal @@ -99,7 +99,7 @@ library build-depends: , array >=0.4 && <0.6 - , base >=4.13 && <4.21 + , base >=4.13 && <4.22 , bytestring >=0.10.6.0 && <0.13 , Cabal ^>=3.15 , Cabal-syntax ^>=3.15 @@ -131,7 +131,7 @@ Test-Suite unit-tests UnitTests.Distribution.Solver.Modular.MessageUtils build-depends: - , base >= 4.13 && <4.21 + , base >= 4.13 && <4.22 , Cabal-syntax , cabal-install-solver , tasty >= 1.2.3 && <1.6 diff --git a/cabal-install/cabal-install.cabal b/cabal-install/cabal-install.cabal index 94b97d9f0a3..3e847ac7dac 100644 --- a/cabal-install/cabal-install.cabal +++ b/cabal-install/cabal-install.cabal @@ -52,7 +52,7 @@ common warnings ghc-options: -Wnoncanonical-monadfail-instances common base-dep - build-depends: base >=4.13 && <4.21 + build-depends: base >=4.13 && <4.22 common cabal-dep build-depends: Cabal ^>=3.15 diff --git a/cabal-testsuite/cabal-testsuite.cabal b/cabal-testsuite/cabal-testsuite.cabal index f0dce35e60e..7de6a531115 100644 --- a/cabal-testsuite/cabal-testsuite.cabal +++ b/cabal-testsuite/cabal-testsuite.cabal @@ -26,7 +26,7 @@ common shared default-language: Haskell2010 build-depends: - , base >= 4.11 && < 4.21 + , base >= 4.11 && < 4.22 -- this needs to match the in-tree lib:Cabal version , Cabal ^>= 3.15.0.0 From 47764511a896d318867697a6db53d953245750af Mon Sep 17 00:00:00 2001 From: brandon s allbery kf8nh Date: Mon, 14 Oct 2024 18:33:13 -0400 Subject: [PATCH 206/207] change the backport label MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By request in Matrix. If anyone else has an opinion, speak now or forever hold your peace! ☺ The new label is `Backport #NNN: title` which with GitHub's prefix and suffix for email is `[haskell/cabal] Backport #NNN: title (PR #MMM)` --- .github/mergify.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/mergify.yml b/.github/mergify.yml index 96bce6b9a36..c56a0c01ad7 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -170,3 +170,8 @@ queue_rules: update_bot_account: Mikolaj merge_method: squash update_method: merge + +defaults: + actions: + backport: + title: "Backport #{{ number }}: {{ title }}" From a41517eb041b911f20005cf195681502f2de0c38 Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo Date: Tue, 17 Oct 2023 15:33:29 +1100 Subject: [PATCH 207/207] Rename module CmdOutdated.hs to Outdated.hs The `Cmd*,hs` naming scheme is usually reserved for v2 commands and this is a v1 command so renaming this to make way for a v2 version of this command. Since the `v2-outdated` command does everything the `v1` version of the command does, this `Outdated.hs` module should probably be removed. --- cabal-install/cabal-install.cabal | 1 + cabal-install/src/Distribution/Client/Main.hs | 1 + .../src/Distribution/Client/{CmdOutdated.hs => Outdated.hs} | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) rename cabal-install/src/Distribution/Client/{CmdOutdated.hs => Outdated.hs} (99%) diff --git a/cabal-install/cabal-install.cabal b/cabal-install/cabal-install.cabal index 3e847ac7dac..9782c9dee81 100644 --- a/cabal-install/cabal-install.cabal +++ b/cabal-install/cabal-install.cabal @@ -158,6 +158,7 @@ library Distribution.Client.ManpageFlags Distribution.Client.Nix Distribution.Client.NixStyleOptions + Distribution.Client.Outdated Distribution.Client.PackageHash Distribution.Client.ParseUtils Distribution.Client.ProjectBuilding diff --git a/cabal-install/src/Distribution/Client/Main.hs b/cabal-install/src/Distribution/Client/Main.hs index e6278a5ef9a..5fdfc72d847 100644 --- a/cabal-install/src/Distribution/Client/Main.hs +++ b/cabal-install/src/Distribution/Client/Main.hs @@ -137,6 +137,7 @@ import qualified Distribution.Client.CmdRun as CmdRun import qualified Distribution.Client.CmdSdist as CmdSdist import qualified Distribution.Client.CmdTest as CmdTest import qualified Distribution.Client.CmdUpdate as CmdUpdate +import qualified Distribution.Client.Outdated as Outdated import Distribution.Client.Check as Check (check) import Distribution.Client.Configure (configure, writeConfigFlags) diff --git a/cabal-install/src/Distribution/Client/CmdOutdated.hs b/cabal-install/src/Distribution/Client/Outdated.hs similarity index 99% rename from cabal-install/src/Distribution/Client/CmdOutdated.hs rename to cabal-install/src/Distribution/Client/Outdated.hs index 7674e67286f..c3020d5ccb4 100644 --- a/cabal-install/src/Distribution/Client/CmdOutdated.hs +++ b/cabal-install/src/Distribution/Client/Outdated.hs @@ -13,7 +13,7 @@ -- -- Implementation of the 'outdated' command. Checks for outdated -- dependencies in the package description file or freeze file. -module Distribution.Client.CmdOutdated +module Distribution.Client.Outdated ( outdatedCommand , outdatedAction , ListOutdatedSettings (..)