cabal-install 1.24.0.0 → 1.24.0.1
raw patch · 35 files changed
+631/−173 lines, 35 filesdep ~Cabaldep ~hackage-security
Dependency ranges changed: Cabal, hackage-security
Files
- Distribution/Client/Check.hs +1/−1
- Distribution/Client/CmdBuild.hs +7/−5
- Distribution/Client/CmdRepl.hs +7/−5
- Distribution/Client/Config.hs +86/−24
- Distribution/Client/GlobalFlags.hs +8/−1
- Distribution/Client/HttpUtils.hs +35/−29
- Distribution/Client/IndexUtils.hs +22/−6
- Distribution/Client/PackageHash.hs +59/−3
- Distribution/Client/ProjectBuilding.hs +13/−5
- Distribution/Client/ProjectConfig.hs +1/−0
- Distribution/Client/ProjectOrchestration.hs +26/−10
- Distribution/Client/ProjectPlanning.hs +39/−22
- Distribution/Client/Setup.hs +19/−9
- Distribution/Client/SetupWrapper.hs +45/−19
- Distribution/Client/SrcDist.hs +1/−0
- Main.hs +21/−11
- bootstrap.sh +93/−17
- cabal-install.cabal +18/−4
- changelog +18/−0
- tests/IntegrationTests/custom-setup/common.sh +9/−0
- tests/IntegrationTests/custom-setup/should_run/Cabal-99998/Cabal.cabal +8/−0
- tests/IntegrationTests/custom-setup/should_run/Cabal-99998/CabalMessage.hs +3/−0
- tests/IntegrationTests/custom-setup/should_run/Cabal-99999/Cabal.cabal +8/−0
- tests/IntegrationTests/custom-setup/should_run/Cabal-99999/CabalMessage.hs +3/−0
- tests/IntegrationTests/custom-setup/should_run/custom-setup-without-cabal-defaultMain/Setup.hs +3/−0
- tests/IntegrationTests/custom-setup/should_run/custom-setup-without-cabal-defaultMain/custom-setup-without-cabal-defaultMain.cabal +9/−0
- tests/IntegrationTests/custom-setup/should_run/custom-setup-without-cabal/Setup.hs +4/−0
- tests/IntegrationTests/custom-setup/should_run/custom-setup-without-cabal/custom-setup-without-cabal.cabal +9/−0
- tests/IntegrationTests/custom-setup/should_run/custom-setup/Setup.hs +5/−0
- tests/IntegrationTests/custom-setup/should_run/custom-setup/custom-setup.cabal +9/−0
- tests/IntegrationTests/custom-setup/should_run/custom_setup_without_Cabal_doesnt_allow_Cabal_import.sh +12/−0
- tests/IntegrationTests/custom-setup/should_run/custom_setup_without_Cabal_doesnt_require_Cabal.sh +11/−0
- tests/IntegrationTests/custom-setup/should_run/installs_Cabal_as_setup_dep.sh +15/−0
- tests/UnitTests/Distribution/Client/ArbitraryInstances.hs +2/−0
- tests/UnitTests/Distribution/Client/UserConfig.hs +2/−2
Distribution/Client/Check.hs view
@@ -58,7 +58,7 @@ printCheckMessages buildImpossible unless (null buildWarning) $ do- putStrLn "The following warnings are likely affect your build negatively:"+ putStrLn "The following warnings are likely to affect your build negatively:" printCheckMessages buildWarning unless (null distSuspicious) $ do
Distribution/Client/CmdBuild.hs view
@@ -8,7 +8,8 @@ import Distribution.Client.ProjectOrchestration ( PreBuildHooks(..), runProjectPreBuildPhase, selectTargets- , ProjectBuildContext(..), runProjectBuildPhase, printPlan )+ , ProjectBuildContext(..), runProjectBuildPhase+ , printPlan, reportBuildFailures ) import Distribution.Client.ProjectConfig ( BuildTimeSettings(..) ) import Distribution.Client.ProjectPlanning@@ -52,10 +53,11 @@ printPlan verbosity buildCtx - unless (buildSettingDryRun buildSettings) $- runProjectBuildPhase- verbosity- buildCtx+ unless (buildSettingDryRun buildSettings) $ do+ plan <- runProjectBuildPhase+ verbosity+ buildCtx+ reportBuildFailures plan where verbosity = fromFlagOrDefault normal (configVerbosity configFlags)
Distribution/Client/CmdRepl.hs view
@@ -8,7 +8,8 @@ import Distribution.Client.ProjectOrchestration ( PreBuildHooks(..), runProjectPreBuildPhase, selectTargets- , ProjectBuildContext(..), runProjectBuildPhase, printPlan )+ , ProjectBuildContext(..), runProjectBuildPhase+ , printPlan, reportBuildFailures ) import Distribution.Client.ProjectConfig ( BuildTimeSettings(..) ) import Distribution.Client.ProjectPlanning@@ -56,10 +57,11 @@ printPlan verbosity buildCtx - unless (buildSettingDryRun buildSettings) $- runProjectBuildPhase- verbosity- buildCtx+ unless (buildSettingDryRun buildSettings) $ do+ plan <- runProjectBuildPhase+ verbosity+ buildCtx+ reportBuildFailures plan where verbosity = fromFlagOrDefault normal (configVerbosity configFlags)
Distribution/Client/Config.hs view
@@ -58,7 +58,7 @@ , ReportFlags(..), reportCommand , showRepo, parseRepo, readRepo ) import Distribution.Utils.NubList- ( NubList, fromNubList, toNubList)+ ( NubList, fromNubList, toNubList, overNubList ) import Distribution.Simple.Compiler ( DebugInfoLevel(..), OptimisationLevel(..) )@@ -104,7 +104,7 @@ import Data.Maybe ( fromMaybe ) import Control.Monad- ( when, unless, foldM, liftM, liftM2 )+ ( when, unless, foldM, liftM ) import qualified Distribution.Compat.ReadP as Parse ( (<++), option ) import Distribution.Compat.Semigroup@@ -438,7 +438,7 @@ return mempty { savedGlobalFlags = mempty { globalCacheDir = toFlag cacheDir,- globalRemoteRepos = toNubList [addInfoForKnownRepos defaultRemoteRepo],+ globalRemoteRepos = toNubList [defaultRemoteRepo], globalWorldFile = toFlag worldFile }, savedConfigureFlags = mempty {@@ -507,23 +507,91 @@ -- we might have only have older info. This lets us fill that in even for old -- config files. ----- TODO: Once we migrate from opt-in to opt-out security for the central--- Hackage repository, we should enable security and specify keys and threshold--- for repositories that have their security setting as 'Nothing' (default). addInfoForKnownRepos :: RemoteRepo -> RemoteRepo-addInfoForKnownRepos repo@RemoteRepo{ remoteRepoName = "hackage.haskell.org" } =- tryHttps- $ if isOldHackageURI (remoteRepoURI repo) then defaultRemoteRepo else repo+addInfoForKnownRepos repo+ | remoteRepoName repo == remoteRepoName defaultRemoteRepo+ = useSecure . tryHttps . fixOldURI $ repo where+ fixOldURI r+ | isOldHackageURI (remoteRepoURI r)+ = r { remoteRepoURI = remoteRepoURI defaultRemoteRepo }+ | otherwise = r+ tryHttps r = r { remoteRepoShouldTryHttps = True }++ useSecure r@RemoteRepo{+ remoteRepoSecure = secure,+ remoteRepoRootKeys = [],+ remoteRepoKeyThreshold = 0+ } | secure /= Just False+ = r {+ --TODO: When we want to switch us from using opt-in to opt-out+ -- security for the central hackage server, uncomment the+ -- following line. That will cause the default (of unspecified)+ -- to get interpreted as if it were "secure: True". For the+ -- moment it means the keys get added but you have to manually+ -- set "secure: True" to opt-in.+ --remoteRepoSecure = Just True,+ remoteRepoRootKeys = defaultHackageRemoteRepoKeys,+ remoteRepoKeyThreshold = defaultHackageRemoteRepoKeyThreshold+ }+ useSecure r = r addInfoForKnownRepos other = other +-- | The current hackage.haskell.org repo root keys that we ship with cabal.+---+-- This lets us bootstrap trust in this repo without user intervention.+-- These keys need to be periodically updated when new root keys are added.+-- See the root key procedures for details. --+defaultHackageRemoteRepoKeys :: [String]+defaultHackageRemoteRepoKeys =+ [ "fe331502606802feac15e514d9b9ea83fee8b6ffef71335479a2e68d84adc6b0",+ "1ea9ba32c526d1cc91ab5e5bd364ec5e9e8cb67179a471872f6e26f0ae773d42",+ "2c6c3627bd6c982990239487f1abd02e08a02e6cf16edb105a8012d444d870c3",+ "0a5c7ea47cd1b15f01f5f51a33adda7e655bc0f0b0615baa8e271f4c3351e21d",+ "51f0161b906011b52c6613376b1ae937670da69322113a246a09f807c62f6921"+ ]++-- | The required threshold of root key signatures for hackage.haskell.org+--+defaultHackageRemoteRepoKeyThreshold :: Int+defaultHackageRemoteRepoKeyThreshold = 3++-- -- * Config file reading -- +-- | Loads the main configuration, and applies additional defaults to give the+-- effective configuration. To loads just what is actually in the config file,+-- use 'loadRawConfig'.+-- loadConfig :: Verbosity -> Flag FilePath -> IO SavedConfig-loadConfig verbosity configFileFlag = addBaseConf $ do+loadConfig verbosity configFileFlag = do+ config <- loadRawConfig verbosity configFileFlag+ extendToEffectiveConfig config++extendToEffectiveConfig :: SavedConfig -> IO SavedConfig+extendToEffectiveConfig config = do+ base <- baseSavedConfig+ let effective0 = base `mappend` config+ globalFlags0 = savedGlobalFlags effective0+ effective = effective0 {+ savedGlobalFlags = globalFlags0 {+ globalRemoteRepos =+ overNubList (map addInfoForKnownRepos)+ (globalRemoteRepos globalFlags0)+ }+ }+ return effective++-- | Like 'loadConfig' but does not apply any additional defaults, it just+-- loads what is actually in the config file. This is thus suitable for+-- comparing or editing a config file, but not suitable for using as the+-- effective configuration.+--+loadRawConfig :: Verbosity -> Flag FilePath -> IO SavedConfig+loadRawConfig verbosity configFileFlag = do (source, configFile) <- getConfigFilePathAndSource configFileFlag minp <- readConfigFile mempty configFile case minp of@@ -531,7 +599,6 @@ notice verbosity $ "Config file path source is " ++ sourceMsg source ++ "." notice verbosity $ "Config file " ++ configFile ++ " not found." createDefaultConfigFile verbosity configFile- loadConfig verbosity configFileFlag Just (ParseOk ws conf) -> do unless (null ws) $ warn verbosity $ unlines (map (showPWarning configFile) ws)@@ -543,11 +610,6 @@ ++ maybe "" (\n -> ':' : show n) line ++ ":\n" ++ msg where- addBaseConf body = do- base <- baseSavedConfig- extra <- body- return (base `mappend` extra)- sourceMsg CommandlineOption = "commandline option" sourceMsg EnvironmentVariable = "env var CABAL_CONFIG" sourceMsg Default = "default config file"@@ -585,12 +647,13 @@ then return Nothing else ioError ioe -createDefaultConfigFile :: Verbosity -> FilePath -> IO ()+createDefaultConfigFile :: Verbosity -> FilePath -> IO SavedConfig createDefaultConfigFile verbosity filePath = do commentConf <- commentSavedConfig initialConf <- initialSavedConfig notice verbosity $ "Writing default configuration to " ++ filePath writeConfigFile filePath commentConf initialConf+ return initialConf writeConfigFile :: FilePath -> SavedConfig -> SavedConfig -> IO () writeConfigFile file comments vals = do@@ -854,8 +917,7 @@ knownSections let remoteRepoSections =- map addInfoForKnownRepos- . reverse+ reverse . nubBy ((==) `on` remoteRepoName) $ remoteRepoSections0 @@ -1026,7 +1088,7 @@ name = fieldName field , name `notElem` exclusions ] where- exclusions = ["verbose", "builddir"]+ exclusions = ["verbose", "builddir", "for-hackage"] -- | Fields for the 'program-locations' section. withProgramsFields :: [FieldDescr [(String, FilePath)]]@@ -1045,8 +1107,8 @@ -- '~/.cabal/config' and the one that cabal would generate if it didn't exist. userConfigDiff :: GlobalFlags -> IO [String] userConfigDiff globalFlags = do- userConfig <- loadConfig normal (globalConfigFile globalFlags)- testConfig <- liftM2 mappend baseSavedConfig initialSavedConfig+ userConfig <- loadRawConfig normal (globalConfigFile globalFlags)+ testConfig <- initialSavedConfig return $ reverse . foldl' createDiff [] . M.toList $ M.unionWith combine (M.fromList . map justFst $ filterShow testConfig)@@ -1090,8 +1152,8 @@ -- | Update the user's ~/.cabal/config' keeping the user's customizations. userConfigUpdate :: Verbosity -> GlobalFlags -> IO () userConfigUpdate verbosity globalFlags = do- userConfig <- loadConfig normal (globalConfigFile globalFlags)- newConfig <- liftM2 mappend baseSavedConfig initialSavedConfig+ userConfig <- loadRawConfig normal (globalConfigFile globalFlags)+ newConfig <- initialSavedConfig commentConf <- commentSavedConfig cabalFile <- getConfigFilePath $ globalConfigFile globalFlags let backup = cabalFile ++ ".backup"
Distribution/Client/GlobalFlags.hs view
@@ -250,8 +250,15 @@ cache :: Sec.Cache cache = Sec.Cache { cacheRoot = cachePath- , cacheLayout = Sec.cabalCacheLayout+ , cacheLayout = Sec.cabalCacheLayout {+ Sec.cacheLayoutIndexTar = cacheFn "01-index.tar"+ , Sec.cacheLayoutIndexIdx = cacheFn "01-index.tar.idx"+ , Sec.cacheLayoutIndexTarGz = cacheFn "01-index.tar.gz"+ } }++ cacheFn :: FilePath -> Sec.CachePath+ cacheFn = Sec.rootPath . Sec.fragment -- We display any TUF progress only in verbose mode, including any transient -- verification errors. If verification fails, then the final exception that
Distribution/Client/HttpUtils.hs view
@@ -363,6 +363,7 @@ , "--user-agent", userAgent , "--silent", "--show-error" , "--header", "Accept: text/plain"+ , "--location" ] resp <- getProgramInvocationOutput verbosity $ addAuthConfig auth (programInvocation prog args)@@ -375,6 +376,7 @@ , "--write-out", "\n%{http_code}" , "--user-agent", userAgent , "--silent", "--show-error"+ , "--location" , "--header", "Accept: text/plain" ] ++ concat@@ -415,7 +417,7 @@ where gethttp verbosity uri etag destPath reqHeaders = do resp <- runWGet verbosity uri args- (code, _err, etag') <- parseResponse uri resp+ (code, etag') <- parseOutput uri resp return (code, etag') where args = [ "--output-document=" ++ destPath@@ -433,31 +435,39 @@ posthttpfile verbosity uri path auth = withTempFile (takeDirectory path)- (takeFileName path) $ \tmpFile tmpHandle -> do+ (takeFileName path) $ \tmpFile tmpHandle ->+ withTempFile (takeDirectory path) "response" $ \responseFile responseHandle -> do+ hClose responseHandle (body, boundary) <- generateMultipartBody path BS.hPut tmpHandle body- BS.writeFile "wget.in" body hClose tmpHandle let args = [ "--post-file=" ++ tmpFile , "--user-agent=" ++ userAgent , "--server-response"+ , "--output-document=" ++ responseFile+ , "--header=Accept: text/plain" , "--header=Content-type: multipart/form-data; " ++ "boundary=" ++ boundary ]- resp <- runWGet verbosity (addUriAuth auth uri) args- (code, err, _etag) <- parseResponse uri resp- return (code, err)+ out <- runWGet verbosity (addUriAuth auth uri) args+ (code, _etag) <- parseOutput uri out+ resp <- readFile responseFile+ return (code, resp) - puthttpfile verbosity uri path auth headers = do- let args = [ "--method=PUT", "--body-file="++path- , "--user-agent=" ++ userAgent- , "--server-response"- , "--header=Accept: text/plain" ]- ++ [ "--header=" ++ show name ++ ": " ++ value- | Header name value <- headers ]+ puthttpfile verbosity uri path auth headers =+ withTempFile (takeDirectory path) "response" $ \responseFile responseHandle -> do+ hClose responseHandle+ let args = [ "--method=PUT", "--body-file="++path+ , "--user-agent=" ++ userAgent+ , "--server-response"+ , "--output-document=" ++ responseFile+ , "--header=Accept: text/plain" ]+ ++ [ "--header=" ++ show name ++ ": " ++ value+ | Header name value <- headers ] - resp <- runWGet verbosity (addUriAuth auth uri) args- (code, err, _etag) <- parseResponse uri resp- return (code, err)+ out <- runWGet verbosity (addUriAuth auth uri) args+ (code, _etag) <- parseOutput uri out+ resp <- readFile responseFile+ return (code, resp) addUriAuth Nothing uri = uri addUriAuth (Just (user, pass)) uri = uri@@ -487,23 +497,19 @@ -- http server response with all headers, we want to find a line like -- "HTTP/1.1 200 OK", but only the last one, since we can have multiple -- requests due to redirects.- --- -- Unfortunately wget apparently cannot be persuaded to give us the body- -- of error responses, so we just return the human readable status message- -- like "Forbidden" etc.- parseResponse uri resp =- let codeerr = listToMaybe- [ (code, unwords err)- | (protocol:codestr:err) <- map words (reverse (lines resp))- , "HTTP/" `isPrefixOf` protocol- , code <- maybeToList (readMaybe codestr) ]+ parseOutput uri resp =+ let parsedCode = listToMaybe+ [ code+ | (protocol:codestr:_err) <- map words (reverse (lines resp))+ , "HTTP/" `isPrefixOf` protocol+ , code <- maybeToList (readMaybe codestr) ] mb_etag :: Maybe ETag mb_etag = listToMaybe [ etag | ["ETag:", etag] <- map words (reverse (lines resp)) ]- in case codeerr of- Just (i, err) -> return (i, err, mb_etag)- _ -> statusParseFail uri resp+ in case parsedCode of+ Just i -> return (i, mb_etag)+ _ -> statusParseFail uri resp powershellTransport :: ConfiguredProgram -> HttpTransport
Distribution/Client/IndexUtils.hs view
@@ -88,7 +88,7 @@ import Distribution.Client.Compat.Time (getFileAge, getModTime) import System.Directory (doesFileExist, doesDirectoryExist) import System.FilePath- ( (</>), takeExtension, replaceExtension, splitDirectories, normalise )+ ( (</>), (<.>), takeExtension, replaceExtension, splitDirectories, normalise ) import System.FilePath.Posix as FilePath.Posix ( takeFileName ) import System.IO@@ -107,6 +107,23 @@ where verbosity' = lessVerbose verbosity ++-- | Get filename base (i.e. without file extension) for index-related files+--+-- /Secure/ cabal repositories use a new extended & incremental+-- @01-index.tar@. In order to avoid issues resulting from clobbering+-- new/old-style index data, we save them locally to different names.+--+-- Example: Use @indexBaseName repo <.> "tar.gz"@ to compute the 'FilePath' of the+-- @00-index.tar.gz@/@01-index.tar.gz@ file.+indexBaseName :: Repo -> FilePath+indexBaseName repo = repoLocalDir repo </> fn+ where+ fn = case repo of+ RepoSecure {} -> "01-index"+ RepoRemote {} -> "00-index"+ RepoLocal {} -> "00-index"+ ------------------------------------------------------------------------ -- Reading the source package index --@@ -204,15 +221,14 @@ -- | Return the age of the index file in days (as a Double). getIndexFileAge :: Repo -> IO Double-getIndexFileAge repo = getFileAge $ repoLocalDir repo </> "00-index.tar"+getIndexFileAge repo = getFileAge $ indexBaseName repo <.> "tar" -- | A set of files (or directories) that can be monitored to detect when -- there might have been a change in the source packages. -- getSourcePackagesMonitorFiles :: [Repo] -> [FilePath] getSourcePackagesMonitorFiles repos =- [ repoLocalDir repo </> "00-index.cache"- | repo <- repos ]+ [ indexBaseName repo <.> "cache" | repo <- repos ] -- | It is not necessary to call this, as the cache will be updated when the -- index is read normally. However you can do the work earlier if you like.@@ -384,11 +400,11 @@ | SandboxIndex FilePath indexFile :: Index -> FilePath-indexFile (RepoIndex _ctxt repo) = repoLocalDir repo </> "00-index.tar"+indexFile (RepoIndex _ctxt repo) = indexBaseName repo <.> "tar" indexFile (SandboxIndex index) = index cacheFile :: Index -> FilePath-cacheFile (RepoIndex _ctxt repo) = repoLocalDir repo </> "00-index.cache"+cacheFile (RepoIndex _ctxt repo) = indexBaseName repo <.> "cache" cacheFile (SandboxIndex index) = index `replaceExtension` "cache" updatePackageIndexCacheFile :: Verbosity -> Index -> IO ()
Distribution/Client/PackageHash.hs view
@@ -16,6 +16,9 @@ hashedInstalledPackageId, hashPackageHashInputs, renderPackageHashInputs,+ -- ** Platform-specific variations+ hashedInstalledPackageIdLong,+ hashedInstalledPackageIdShort, -- * Low level hash choice HashValue,@@ -26,9 +29,9 @@ ) where import Distribution.Package- ( PackageId, mkUnitId )+ ( PackageId, PackageIdentifier(..), mkUnitId ) import Distribution.System- ( Platform )+ ( Platform, OS(Windows), buildOS ) import Distribution.PackageDescription ( FlagName(..), FlagAssignment ) import Distribution.Simple.Compiler@@ -65,12 +68,65 @@ -- | Calculate a 'InstalledPackageId' for a package using our nix-style -- inputs hashing method. --+-- Note that due to path length limitations on Windows, this function uses+-- a different method on Windows that produces shorted package ids.+-- See 'hashedInstalledPackageIdLong' vs 'hashedInstalledPackageIdShort'.+-- hashedInstalledPackageId :: PackageHashInputs -> InstalledPackageId-hashedInstalledPackageId pkghashinputs@PackageHashInputs{pkgHashPkgId} =+hashedInstalledPackageId+ | buildOS == Windows = hashedInstalledPackageIdShort+ | otherwise = hashedInstalledPackageIdLong++-- | Calculate a 'InstalledPackageId' for a package using our nix-style+-- inputs hashing method.+--+-- This produces large ids with big hashes. It is only suitable for systems+-- without significant path length limitations (ie not Windows).+--+hashedInstalledPackageIdLong :: PackageHashInputs -> InstalledPackageId+hashedInstalledPackageIdLong pkghashinputs@PackageHashInputs{pkgHashPkgId} = mkUnitId $ display pkgHashPkgId -- to be a bit user friendly ++ "-" ++ showHashValue (hashPackageHashInputs pkghashinputs)++-- | On Windows we have serious problems with path lengths. Windows imposes a+-- maximum path length of 260 chars, and even if we can use the windows long+-- path APIs ourselves, we cannot guarantee that ghc, gcc, ld, ar, etc etc all+-- do so too.+--+-- So our only choice is to limit the lengths of the paths, and the only real+-- way to do that is to limit the size of the 'InstalledPackageId's that we+-- generate. We do this by truncating the package names and versions and also+-- by truncating the hash sizes.+--+-- Truncating the package names and versions is technically ok because they are+-- just included for human convenience, the full source package id is included+-- in the hash.+--+-- Truncating the hash size is disappointing but also technically ok. We+-- rely on the hash primarily for collision avoidance not for any securty+-- properties (at least for now).+--+hashedInstalledPackageIdShort :: PackageHashInputs -> InstalledPackageId+hashedInstalledPackageIdShort pkghashinputs@PackageHashInputs{pkgHashPkgId} =+ mkUnitId $+ intercalate "-"+ -- max length now 64+ [ truncateStr 14 (display name)+ , truncateStr 8 (display version)+ , showHashValue (truncateHash (hashPackageHashInputs pkghashinputs))+ ]+ where+ PackageIdentifier name version = pkgHashPkgId++ -- Truncate a 32 byte SHA256 hash to 160bits, 20 bytes :-(+ -- It'll render as 40 hex chars.+ truncateHash (HashValue h) = HashValue (BS.take 20 h)++ -- Truncate a string, with a visual indication that it is truncated.+ truncateStr n s | length s <= n = s+ | otherwise = take (n-1) s ++ "_" -- | All the information that contribues to a package's hash, and thus its -- 'InstalledPackageId'.
Distribution/Client/ProjectBuilding.hs view
@@ -1119,7 +1119,8 @@ -- Configure phase -- whenReConfigure $ do- setup configureCommand configureFlags []+ annotateFailure ConfigureFailed $+ setup configureCommand configureFlags [] invalidatePackageRegFileMonitor packageFileMonitor updatePackageConfigFileMonitor packageFileMonitor srcdir pkg @@ -1133,7 +1134,8 @@ whenRebuild $ do timestamp <- beginUpdateFileMonitor- setup buildCommand buildFlags buildArgs+ annotateFailure BuildFailed $+ setup buildCommand buildFlags buildArgs --TODO: [required eventually] this doesn't track file --non-existence, so we could fail to rebuild if someone@@ -1144,7 +1146,7 @@ pkg buildStatus allSrcFiles buildSuccess - mipkg <- whenReRegister $ do+ mipkg <- whenReRegister $ annotateFailure InstallFailed $ do -- Register locally mipkg <- if pkgRequiresRegistration pkg then do@@ -1166,10 +1168,12 @@ -- Repl phase -- whenRepl $+ annotateFailure BuildFailed $ setup replCommand replFlags replArgs -- Haddock phase whenHaddock $+ annotateFailure BuildFailed $ setup haddockCommand haddockFlags [] return (BuildSuccess mipkg buildSuccess)@@ -1255,8 +1259,12 @@ ] where handler :: Exception e => e -> IO a- handler = throwIO . annotate . show- --TODO: [nice to have] use displayException when available+ handler = throwIO . annotate+#if MIN_VERSION_base(4,8,0)+ . displayException+#else+ . show+#endif withTempInstalledPackageInfoFile :: Verbosity -> FilePath
Distribution/Client/ProjectConfig.hs view
@@ -21,6 +21,7 @@ -- * Packages within projects ProjectPackageLocation(..),+ BadPackageLocations(..), BadPackageLocation(..), BadPackageLocationMatch(..), findProjectPackages,
Distribution/Client/ProjectOrchestration.hs view
@@ -50,6 +50,9 @@ -- * Build phase: now do it. runProjectBuildPhase,++ -- * Post build actions+ reportBuildFailures, ) where import Distribution.Client.ProjectConfig@@ -83,6 +86,7 @@ import Data.Map (Map) import Data.List import Data.Either+import System.Exit (exitFailure) -- | Command line configuration flags. These are used to extend\/override the@@ -190,16 +194,14 @@ -- runProjectBuildPhase :: Verbosity -> ProjectBuildContext- -> IO ()-runProjectBuildPhase verbosity ProjectBuildContext {..} = do- _ <- rebuildTargets verbosity- distDirLayout- elaboratedPlan- elaboratedShared- pkgsBuildStatus- buildSettings- --TODO return the result plan and use it for other status reporting- return ()+ -> IO ElaboratedInstallPlan+runProjectBuildPhase verbosity ProjectBuildContext {..} =+ rebuildTargets verbosity+ distDirLayout+ elaboratedPlan+ elaboratedShared+ pkgsBuildStatus+ buildSettings -- Note that it is a deliberate design choice that the 'buildTargets' is -- not passed to phase 1, and the various bits of input config is not@@ -474,4 +476,18 @@ (InstallPlan.processing [pkg] plan) --TODO: [code cleanup] This is a bit of a hack, pretending that each package is installed -- could we use InstallPlan.topologicalOrder?+++reportBuildFailures :: ElaboratedInstallPlan -> IO ()+reportBuildFailures plan =++ case [ (pkg, reason)+ | InstallPlan.Failed pkg reason <- InstallPlan.toList plan ] of+ [] -> return ()+ _failed -> exitFailure+ --TODO: [required eventually] see the old printBuildFailures for an example+ -- of the kind of things we could report, but we want to handle the special+ -- case of the current package better, since if you do "cabal build" then+ -- you don't need a lot of context to explain where the ghc error message+ -- comes from, and indeed extra noise would just be annoying.
Distribution/Client/ProjectPlanning.hs view
@@ -848,7 +848,7 @@ . removeUpperBounds solverSettingAllowNewer - . addDefaultSetupDependencies (defaultSetupDeps platform+ . addDefaultSetupDependencies (defaultSetupDeps comp platform . PD.packageDescription . packageDescription) @@ -1681,8 +1681,10 @@ -- we still need to distinguish the case of explicit and implict setup deps. -- See 'rememberImplicitSetupDeps'. ---defaultSetupDeps :: Platform -> PD.PackageDescription -> Maybe [Dependency]-defaultSetupDeps platform pkg =+defaultSetupDeps :: Compiler -> Platform+ -> PD.PackageDescription+ -> Maybe [Dependency]+defaultSetupDeps compiler platform pkg = case packageSetupScriptStylePreSolver pkg of -- For packages with build type custom that do not specify explicit@@ -1691,26 +1693,30 @@ SetupCustomImplicitDeps -> Just $ [ Dependency depPkgname anyVersion- | depPkgname <- legacyCustomSetupPkgs platform ] ++- -- The Cabal dep is slightly special:- -- * we omit the dep for the Cabal lib itself (since it bootstraps),- -- * we constrain it to be less than 1.23 since all packages- -- relying on later Cabal spec versions are supposed to use- -- explit setup deps. Having this constraint also allows later- -- Cabal lib versions to make breaking API changes without breaking- -- all old Setup.hs scripts.+ | depPkgname <- legacyCustomSetupPkgs compiler platform ] ++ [ Dependency cabalPkgname cabalConstraint | packageName pkg /= cabalPkgname ] where- cabalConstraint = orLaterVersion (PD.specVersion pkg)+ -- The Cabal dep is slightly special:+ -- * We omit the dep for the Cabal lib itself, since it bootstraps.+ -- * We constrain it to be >= 1.18 < 2+ --+ cabalConstraint = orLaterVersion cabalCompatMinVer `intersectVersionRanges`+ orLaterVersion (PD.specVersion pkg)+ `intersectVersionRanges` earlierVersion cabalCompatMaxVer- -- TODO/FIXME: turns out that constraining to less than 1.23 causes- -- problems with GHC8 as there's too many important packages- -- with Custom build-type, for which there wouldn't be any- -- install-plan (as GHC8 requires Cabal-1.24+). So let's- -- set an implicit upper bound `Cabal < 2` instead.- cabalCompatMaxVer = Version [2] []+ -- The idea here is that at some point we will make significant+ -- breaking changes to the Cabal API that Setup.hs scripts use.+ -- So for old custom Setup scripts that do not specify explicit+ -- constraints, we constrain them to use a compatible Cabal version.+ cabalCompatMaxVer = Version [1,25] []+ -- In principle we can talk to any old Cabal version, and we need to+ -- be able to do that for custom Setup scripts that require older+ -- Cabal lib versions. However in practice we have currently have+ -- problems with Cabal-1.16. (1.16 does not know about build targets)+ -- If this is fixed we can relax this constraint.+ cabalCompatMinVer = Version [1,18] [] -- For other build types (like Simple) if we still need to compile an -- external Setup.hs, it'll be one of the simple ones that only depends@@ -1822,14 +1828,25 @@ basePkgname = PackageName "base" -legacyCustomSetupPkgs :: Platform -> [PackageName]-legacyCustomSetupPkgs (Platform _ os) =+legacyCustomSetupPkgs :: Compiler -> Platform -> [PackageName]+legacyCustomSetupPkgs compiler (Platform _ os) = map PackageName $ [ "array", "base", "binary", "bytestring", "containers"- , "deepseq", "directory", "filepath", "pretty"- , "process", "time" ]+ , "deepseq", "directory", "filepath", "old-time", "pretty"+ , "process", "time", "transformers" ] ++ [ "Win32" | os == Windows ] ++ [ "unix" | os /= Windows ]+ ++ [ "ghc-prim" | isGHC ]+ ++ [ "template-haskell" | isGHC ]+ where+ isGHC = compilerCompatFlavor GHC compiler++ -- This util is copied here just in this branch to avoid requiring a new+ -- Cabal version. The master branch already does the right thing.+ compilerCompatFlavor :: CompilerFlavor -> Compiler -> Bool+ compilerCompatFlavor flavor comp =+ flavor == compilerFlavor comp+ || flavor `elem` [ flavor' | CompilerId flavor' _ <- compilerCompat comp ] -- The other aspects of our Setup.hs policy lives here where we decide on -- the 'SetupScriptOptions'.
Distribution/Client/Setup.hs view
@@ -73,6 +73,7 @@ ( defaultProgramConfiguration ) import Distribution.Simple.Command hiding (boolOpt, boolOpt') import qualified Distribution.Simple.Command as Command+import Distribution.Simple.Configure ( computeEffectiveProfiling ) import qualified Distribution.Simple.Setup as Cabal import Distribution.Simple.Setup ( ConfigFlags(..), BuildFlags(..), ReplFlags@@ -83,7 +84,7 @@ , optionVerbosity, boolOpt, boolOpt', trueArg, falseArg , readPToMaybe, optionNumJobs ) import Distribution.Simple.InstallDirs- ( PathTemplate, InstallDirs(sysconfdir)+ ( PathTemplate, InstallDirs(dynlibdir, sysconfdir) , toPathTemplate, fromPathTemplate ) import Distribution.Version ( Version(Version), anyVersion, thisVersion )@@ -349,7 +350,7 @@ filterConfigureFlags :: ConfigFlags -> Version -> ConfigFlags filterConfigureFlags flags cabalLibVersion- | cabalLibVersion >= Version [1,23,0] [] = flags_latest+ | cabalLibVersion >= Version [1,24,1] [] = flags_latest -- ^ NB: we expect the latest version to be the most common case. | cabalLibVersion < Version [1,3,10] [] = flags_1_3_10 | cabalLibVersion < Version [1,10,0] [] = flags_1_10_0@@ -361,8 +362,10 @@ | cabalLibVersion < Version [1,21,1] [] = flags_1_20_0 | cabalLibVersion < Version [1,22,0] [] = flags_1_21_0 | cabalLibVersion < Version [1,23,0] [] = flags_1_22_0+ | cabalLibVersion < Version [1,24,1] [] = flags_1_24_0 | otherwise = flags_latest where+ (profEnabledLib, profEnabledExe) = computeEffectiveProfiling flags flags_latest = flags { -- Cabal >= 1.19.1 uses '--dependency' and does not need '--constraint'. configConstraints = [],@@ -371,22 +374,29 @@ configAllowNewer = Just Cabal.AllowNewerNone } + -- Cabal < 1.24.1 doesn't know about --dynlibdir.+ flags_1_24_0 = flags_latest { configInstallDirs = configInstallDirs_1_24_0}+ configInstallDirs_1_24_0 = (configInstallDirs flags) { dynlibdir = NoFlag }+ -- Cabal < 1.23 doesn't know about '--profiling-detail'.- flags_1_22_0 = flags_latest { configProfDetail = NoFlag+ -- Cabal < 1.23 has a hacked up version of 'enable-profiling'+ -- which we shouldn't use.+ flags_1_22_0 = flags_1_24_0 { configProfDetail = NoFlag , configProfLibDetail = NoFlag- , configIPID = NoFlag }+ , configIPID = NoFlag+ , configProf = NoFlag+ , configProfExe = Flag profEnabledExe+ , configProfLib = Flag profEnabledLib+ } -- Cabal < 1.22 doesn't know about '--disable-debug-info'. flags_1_21_0 = flags_1_22_0 { configDebugInfo = NoFlag } -- Cabal < 1.21.1 doesn't know about 'disable-relocatable' -- Cabal < 1.21.1 doesn't know about 'enable-profiling'+ -- (but we already dealt with it in flags_1_22_0) flags_1_20_0 = flags_1_21_0 { configRelocatable = NoFlag- , configProf = NoFlag- , configProfExe = configProf flags- , configProfLib =- mappend (configProf flags) (configProfLib flags) , configCoverage = NoFlag , configLibCoverage = configCoverage flags }@@ -400,7 +410,7 @@ -- Cabal < 1.18.0 doesn't know about --extra-prog-path and --sysconfdir. flags_1_18_0 = flags_1_19_0 { configProgramPathExtra = toNubList [] , configInstallDirs = configInstallDirs_1_18_0}- configInstallDirs_1_18_0 = (configInstallDirs flags) { sysconfdir = NoFlag }+ configInstallDirs_1_18_0 = (configInstallDirs flags_1_19_0) { sysconfdir = NoFlag } -- Cabal < 1.14.0 doesn't know about '--disable-benchmarks'. flags_1_14_0 = flags_1_18_0 { configBenchmarks = NoFlag } -- Cabal < 1.12.0 doesn't know about '--enable/disable-executable-dynamic'
Distribution/Client/SetupWrapper.hs view
@@ -105,7 +105,7 @@ import Data.Monoid ( mempty ) #endif import Control.Monad ( when, unless )-import Data.List ( foldl1' )+import Data.List ( find, foldl1' ) import Data.Maybe ( fromMaybe, isJust ) import Data.Char ( isSpace ) import Distribution.Client.Compat.ExecutablePath ( getExecutablePath )@@ -381,26 +381,45 @@ Nothing -> getInstalledPackages verbosity comp (usePackageDB options') conf - cabalLibVersionToUse :: IO (Version, (Maybe UnitId)+ -- Choose the version of Cabal to use if the setup script has a dependency on+ -- Cabal, and possibly update the setup script options. The version also+ -- determines how to filter the flags to Setup.+ --+ -- We first check whether the dependency solver has specified a Cabal version.+ -- If it has, we use the solver's version without looking at the installed+ -- package index (See issue #3436). Otherwise, we pick the Cabal version by+ -- checking 'useCabalSpecVersion', then the saved version, and finally the+ -- versions available in the index.+ --+ -- The version chosen here must match the one used in 'compileSetupExecutable'+ -- (See issue #3433).+ cabalLibVersionToUse :: IO (Version, Maybe UnitId ,SetupScriptOptions) cabalLibVersionToUse =- case useCabalSpecVersion options of- Just version -> do+ case find (hasCabal . snd) (useDependencies options) of+ Just (unitId, pkgId) -> do+ let version = pkgVersion pkgId updateSetupScript version bt- writeFile setupVersionFile (show version ++ "\n")- return (version, Nothing, options)- Nothing -> do- savedVer <- savedVersion- case savedVer of- Just version | version `withinRange` useCabalVersion options- -> do updateSetupScript version bt- -- Does the previously compiled setup executable still exist- -- and is it up-to date?- useExisting <- canUseExistingSetup version- if useExisting- then return (version, Nothing, options)- else installedVersion- _ -> installedVersion+ writeSetupVersionFile version+ return (version, Just unitId, options)+ Nothing ->+ case useCabalSpecVersion options of+ Just version -> do+ updateSetupScript version bt+ writeSetupVersionFile version+ return (version, Nothing, options)+ Nothing -> do+ savedVer <- savedVersion+ case savedVer of+ Just version | version `withinRange` useCabalVersion options+ -> do updateSetupScript version bt+ -- Does the previously compiled setup executable still exist+ -- and is it up-to date?+ useExisting <- canUseExistingSetup version+ if useExisting+ then return (version, Nothing, options)+ else installedVersion+ _ -> installedVersion where -- This check duplicates the checks in 'getCachedSetupExecutable' / -- 'compileSetupExecutable'. Unfortunately, we have to perform it twice@@ -416,13 +435,20 @@ (&&) <$> setupProgFile `existsAndIsMoreRecentThan` setupHs <*> setupProgFile `existsAndIsMoreRecentThan` setupVersionFile + writeSetupVersionFile :: Version -> IO ()+ writeSetupVersionFile version =+ writeFile setupVersionFile (show version ++ "\n")++ hasCabal (PackageIdentifier (PackageName "Cabal") _) = True+ hasCabal _ = False+ installedVersion :: IO (Version, Maybe UnitId ,SetupScriptOptions) installedVersion = do (comp, conf, options') <- configureCompiler options (version, mipkgid, options'') <- installedCabalVersion options' comp conf updateSetupScript version bt- writeFile setupVersionFile (show version ++ "\n")+ writeSetupVersionFile version return (version, mipkgid, options'') savedVersion :: IO (Maybe Version)
Distribution/Client/SrcDist.hs view
@@ -90,6 +90,7 @@ distPref = fromFlag (sDistDistPref flags) tmpTargetDir = fromFlagOrDefault (srcPref distPref) (sDistDirectory flags) setupOpts = defaultSetupScriptOptions {+ useDistPref = distPref, -- The '--output-directory' sdist flag was introduced in Cabal 1.12, and -- '--list-sources' in 1.17. useCabalVersion = if isListSources
Main.hs view
@@ -46,7 +46,8 @@ , manpageCommand ) import Distribution.Simple.Setup- ( HaddockFlags(..), haddockCommand, defaultHaddockFlags+ ( HaddockTarget(..)+ , HaddockFlags(..), haddockCommand, defaultHaddockFlags , HscolourFlags(..), hscolourCommand , ReplFlags(..) , CopyFlags(..), copyCommand@@ -179,7 +180,8 @@ import Data.Monoid (Monoid(..)) import Control.Applicative (pure, (<$>)) #endif-import Control.Monad (when, unless)+import Control.Exception (SomeException(..), try)+import Control.Monad (when, unless, void) -- | Entry point --@@ -311,7 +313,8 @@ commandAddAction command { commandDefaultFlags = mempty } $ \flags extraArgs globalFlags -> do let verbosity = fromFlagOrDefault normal (verbosityFlag flags)- (_, config) <- loadConfigOrSandboxConfig verbosity globalFlags+ load <- try (loadConfigOrSandboxConfig verbosity globalFlags)+ let config = either (\(SomeException _) -> mempty) snd load distPref <- findSavedDistPref config (distPrefFlag flags) let setupScriptOptions = defaultSetupScriptOptions { useDistPref = distPref } setupWrapper verbosity setupScriptOptions Nothing@@ -695,7 +698,8 @@ installAction (configFlags, _, installFlags, _) _ globalFlags | fromFlagOrDefault False (installOnly installFlags) = do let verbosity = fromFlagOrDefault normal (configVerbosity configFlags)- (_, config) <- loadConfigOrSandboxConfig verbosity globalFlags+ load <- try (loadConfigOrSandboxConfig verbosity globalFlags)+ let config = either (\(SomeException _) -> mempty) snd load distPref <- findSavedDistPref config (configDistPref configFlags) let setupOpts = defaultSetupScriptOptions { useDistPref = distPref } setupWrapper verbosity setupOpts Nothing installCommand (const mempty) []@@ -901,7 +905,7 @@ setupScriptOptions = defaultSetupScriptOptions { useDistPref = distPref } setupWrapper verbosity setupScriptOptions Nothing haddockCommand (const haddockFlags') extraArgs- when (fromFlagOrDefault False $ haddockForHackage haddockFlags) $ do+ when (haddockForHackage haddockFlags == Flag ForHackage) $ do pkg <- fmap LBI.localPkgDescr (getPersistBuildConfig distPref) let dest = distPref </> name <.> "tar.gz" name = display (packageId pkg) ++ "-docs"@@ -911,7 +915,8 @@ cleanAction :: CleanFlags -> [String] -> Action cleanAction cleanFlags extraArgs globalFlags = do- (_, config) <- loadConfigOrSandboxConfig verbosity globalFlags+ load <- try (loadConfigOrSandboxConfig verbosity globalFlags)+ let config = either (\(SomeException _) -> mempty) snd load distPref <- findSavedDistPref config (cleanDistPref cleanFlags) let setupScriptOptions = defaultSetupScriptOptions { useDistPref = distPref@@ -1101,9 +1106,13 @@ (file', ".gz") -> takeExtension file' == ".tar" _ -> False generateDocTarball config = do- notice verbosity- "No documentation tarball specified. Building documentation tarball..."- haddockAction (defaultHaddockFlags { haddockForHackage = Flag True })+ notice verbosity $+ "No documentation tarball specified. "+ ++ "Building a documentation tarball with default settings...\n"+ ++ "If you need to customise Haddock options, "+ ++ "run 'haddock --for-hackage' first "+ ++ "to generate a documentation tarball."+ haddockAction (defaultHaddockFlags { haddockForHackage = Flag ForHackage }) [] globalFlags distPref <- findSavedDistPref config NoFlag pkg <- fmap LBI.localPkgDescr (getPersistBuildConfig distPref)@@ -1144,7 +1153,8 @@ unless (null extraArgs) $ die $ "'sdist' doesn't take any extra arguments: " ++ unwords extraArgs let verbosity = fromFlag (sDistVerbosity sdistFlags)- (_, config) <- loadConfigOrSandboxConfig verbosity globalFlags+ load <- try (loadConfigOrSandboxConfig verbosity globalFlags)+ let config = either (\(SomeException _) -> mempty) snd load distPref <- findSavedDistPref config (sDistDistPref sdistFlags) let sdistFlags' = sdistFlags { sDistDistPref = toFlag distPref } sdist sdistFlags' sdistExFlags@@ -1274,7 +1284,7 @@ path <- configFile fileExists <- doesFileExist path if (not fileExists || (fileExists && force))- then createDefaultConfigFile verbosity path+ then void $ createDefaultConfigFile verbosity path else die $ path ++ " already exists." ("diff":_) -> mapM_ putStrLn =<< userConfigDiff globalFlags ("update":_) -> userConfigUpdate verbosity globalFlags
bootstrap.sh view
@@ -99,13 +99,13 @@ ${GHC_PKG} --version > /dev/null 2>&1 || die "${GHC_PKG} not found." -GHC_VER="$(${GHC} --numeric-version)" GHC_PKG_VER="$(${GHC_PKG} --version | cut -d' ' -f 5)" [ ${GHC_VER} = ${GHC_PKG_VER} ] || die "Version mismatch between ${GHC} and ${GHC_PKG}. If you set the GHC variable then set GHC_PKG too." +JOBS="-j1" while [ "$#" -gt 0 ]; do case "${1}" in "--user")@@ -128,14 +128,28 @@ "--no-doc") NO_DOCUMENTATION=1 shift;;+ "-j"|"--jobs")+ shift+ # check if there is another argument which doesn't start with - or --+ if [ "$#" -le 0 ] \+ || [ ! -z $(echo "${1}" | grep "^-") ] \+ || [ ! -z $(echo "${1}" | grep "^--") ]+ then+ JOBS="-j"+ else+ JOBS="-j${1}"+ shift+ fi;; *) echo "Unknown argument or option, quitting: ${1}" echo "usage: bootstrap.sh [OPTION]" echo echo "options:"+ echo " -j/--jobs Number of concurrent workers to use (Default: 1)"+ echo " -j without an argument will use all available cores" echo " --user Install for the local user (default)" echo " --global Install systemwide (must be run as root)"- echo " --no-doc Do not generate documentation for installed "\+ echo " --no-doc Do not generate documentation for installed"\ "packages" echo " --sandbox Install to a sandbox in the default location"\ "(.cabal-sandbox)"@@ -144,6 +158,15 @@ esac done +# Do not try to use -j with GHC older than 7.8+case $GHC_VER in+ 7.4*|7.6*)+ JOBS=""+ ;;+ *)+ ;;+esac+ abspath () { case "$1" in /*)printf "%s\n" "$1";; *)printf "%s\n" "$PWD/$1";; esac; } @@ -181,15 +204,28 @@ # >= 3.0 && < 3.2 DEEPSEQ_VER="1.4.2.0"; DEEPSEQ_VER_REGEXP="1\.[1-9]\." # >= 1.1 && < 2-BINARY_VER="0.8.3.0"; BINARY_VER_REGEXP="[0]\.[78]\."- # >= 0.7 && < 0.9++case "$GHC_VER" in+ 7.4*|7.6*)+ # GHC 7.4 or 7.6+ BINARY_VER="0.8.2.1"+ BINARY_VER_REGEXP="[0]\.[78]\.[0-2]\." # >= 0.7 && < 0.8.3+ ;;+ *)+ # GHC >= 7.8+ BINARY_VER="0.8.3.0"+ BINARY_VER_REGEXP="[0]\.[78]\." # >= 0.7 && < 0.9+ ;;+esac++ TEXT_VER="1.2.2.1"; TEXT_VER_REGEXP="((1\.[012]\.)|(0\.([2-9]|(1[0-1]))\.))" # >= 0.2 && < 1.3 NETWORK_VER="2.6.2.1"; NETWORK_VER_REGEXP="2\.[0-6]\." # >= 2.0 && < 2.7 NETWORK_URI_VER="2.6.1.0"; NETWORK_URI_VER_REGEXP="2\.6\." # >= 2.6 && < 2.7-CABAL_VER="1.24.0.0"; CABAL_VER_REGEXP="1\.24\.[0-9]"+CABAL_VER="1.24.1.0"; CABAL_VER_REGEXP="1\.24\.[0-9]" # >= 1.24 && < 1.25 TRANS_VER="0.5.2.0"; TRANS_VER_REGEXP="0\.[45]\." # >= 0.2.* && < 0.6@@ -213,23 +249,25 @@ # >=1.0.0.0 && <1.1 BASE16_BYTESTRING_VER="0.1.1.6"; BASE16_BYTESTRING_VER_REGEXP="0\.1" # 0.1.*-BASE64_BYTESTRING_VER="1.0.0.1"; BASE64_BYTESTRING_REGEXP="1\."+BASE64_BYTESTRING_VER="1.0.0.1"; BASE64_BYTESTRING_REGEXP="1\." # >=1.0 CRYPTOHASH_SHA256_VER="0.11.7.1"; CRYPTOHASH_SHA256_VER_REGEXP="0\.11\.?" # 0.11.* ED25519_VER="0.0.5.0"; ED25519_VER_REGEXP="0\.0\.?" # 0.0.*-HACKAGE_SECURITY_VER="0.5.1.0"; HACKAGE_SECURITY_VER_REGEXP="0\.5\.[1-9]"- # >= 0.5.1 && < 0.6-TAR_VER="0.5.0.1"; TAR_VER_REGEXP="0\.5\.([1-9]|1[0-9]|0\.1)\.?"- # >= 0.5.0.1 && < 0.6+HACKAGE_SECURITY_VER="0.5.2.2"; HACKAGE_SECURITY_VER_REGEXP="0\.5\.(2\.[2-9]|[3-9])"+ # >= 0.5.2 && < 0.6+BYTESTRING_BUILDER_VER="0.10.8.1.0"; BYTESTRING_BUILDER_VER_REGEXP="0\.10\.?"+TAR_VER="0.5.0.3"; TAR_VER_REGEXP="0\.5\.([1-9]|1[0-9]|0\.[3-9]|0\.1[0-9])\.?"+ # >= 0.5.0.3 && < 0.6 HASHABLE_VER="1.2.4.0"; HASHABLE_VER_REGEXP="1\." # 1.* HACKAGE_URL="https://hackage.haskell.org/package" -# Haddock fails for network-2.5.0.0.-NO_DOCS_PACKAGES_VER_REGEXP="network-uri-2\.5\.[0-9]+\.[0-9]+"+# Haddock fails for network-2.5.0.0, and for hackage-security for+# GHC <8, c.f. https://github.com/well-typed/hackage-security/issues/149+NO_DOCS_PACKAGES_VER_REGEXP="network-uri-2\.5\.[0-9]+\.[0-9]+|hackage-security-0\.5\.[0-9]+\.[0-9]+" # Cache the list of packages: echo "Checking installed packages for ghc-${GHC_VER}..."@@ -316,7 +354,7 @@ [ -x Setup ] && ./Setup clean [ -f Setup ] && rm Setup - ${GHC} --make Setup -o Setup ||+ ${GHC} --make ${JOBS} Setup -o Setup || die "Compiling the Setup script failed." [ -x Setup ] || die "The Setup script does not exist or cannot be run"@@ -327,7 +365,7 @@ ./Setup configure $args || die "Configuring the ${PKG} package failed." - ./Setup build ${EXTRA_BUILD_OPTS} ${VERBOSE} ||+ ./Setup build ${JOBS} ${EXTRA_BUILD_OPTS} ${VERBOSE} || die "Building the ${PKG} package failed." if [ ! ${NO_DOCUMENTATION} ]@@ -368,6 +406,26 @@ fi } +# If we're bootstrapping from a Git clone, install the local version of Cabal+# instead of downloading one from Hackage.+do_Cabal_pkg () {+ if [ -d "../.git" ]+ then+ if need_pkg "Cabal" ${CABAL_VER_REGEXP}+ then+ echo "Cabal-${CABAL_VER} will be installed from the local Git clone."+ cd ../Cabal+ install_pkg ${CABAL_VER} ${CABAL_VER_REGEXP}+ cd ../cabal-install+ else+ echo "Cabal-${CABAL_VER} is already installed and the version is ok."+ fi+ else+ info_pkg "Cabal" ${CABAL_VER} ${CABAL_VER_REGEXP}+ do_pkg "Cabal" ${CABAL_VER} ${CABAL_VER_REGEXP}+ fi+}+ # Replicate the flag selection logic for network-uri in the .cabal file. do_network_uri_pkg () { # Refresh installed package list.@@ -389,12 +447,22 @@ fi } +# Conditionally install bytestring-builder if bytestring is < 0.10.2.+do_bytestring_builder_pkg () {+ if egrep "bytestring-0\.(9|10\.[0,1])\.?" ghc-pkg-stage2.list > /dev/null 2>&1+ then+ info_pkg "bytestring-builder" ${BYTESTRING_BUILDER_VER} \+ ${BYTESTRING_BUILDER_VER_REGEXP}+ do_pkg "bytestring-builder" ${BYTESTRING_BUILDER_VER} \+ ${BYTESTRING_BUILDER_VER_REGEXP}+ fi+}+ # Actually do something! info_pkg "deepseq" ${DEEPSEQ_VER} ${DEEPSEQ_VER_REGEXP} info_pkg "binary" ${BINARY_VER} ${BINARY_VER_REGEXP} info_pkg "time" ${TIME_VER} ${TIME_VER_REGEXP}-info_pkg "Cabal" ${CABAL_VER} ${CABAL_VER_REGEXP} info_pkg "transformers" ${TRANS_VER} ${TRANS_VER_REGEXP} info_pkg "mtl" ${MTL_VER} ${MTL_VER_REGEXP} info_pkg "text" ${TEXT_VER} ${TEXT_VER_REGEXP}@@ -415,14 +483,17 @@ ${CRYPTOHASH_SHA256_VER_REGEXP} info_pkg "ed25519" ${ED25519_VER} ${ED25519_VER_REGEXP} info_pkg "tar" ${TAR_VER} ${TAR_VER_REGEXP}-info_pkg "hashable" ${HASHABLE_VER} ${HASHABLE_VER_REGEXP}+info_pkg "hashable" ${HASHABLE_VER} ${HASHABLE_VER_REGEXP} info_pkg "hackage-security" ${HACKAGE_SECURITY_VER} \ ${HACKAGE_SECURITY_VER_REGEXP} do_pkg "deepseq" ${DEEPSEQ_VER} ${DEEPSEQ_VER_REGEXP} do_pkg "binary" ${BINARY_VER} ${BINARY_VER_REGEXP} do_pkg "time" ${TIME_VER} ${TIME_VER_REGEXP}-do_pkg "Cabal" ${CABAL_VER} ${CABAL_VER_REGEXP}++# Install the Cabal library from the local Git clone if possible.+do_Cabal_pkg+ do_pkg "transformers" ${TRANS_VER} ${TRANS_VER_REGEXP} do_pkg "mtl" ${MTL_VER} ${MTL_VER_REGEXP} do_pkg "text" ${TEXT_VER} ${TEXT_VER_REGEXP}@@ -446,6 +517,11 @@ do_pkg "cryptohash-sha256" ${CRYPTOHASH_SHA256_VER} \ ${CRYPTOHASH_SHA256_VER_REGEXP} do_pkg "ed25519" ${ED25519_VER} ${ED25519_VER_REGEXP}++# We conditionally install bytestring-builder, depending on the bytestring+# version.+do_bytestring_builder_pkg+ do_pkg "tar" ${TAR_VER} ${TAR_VER_REGEXP} do_pkg "hashable" ${HASHABLE_VER} ${HASHABLE_VER_REGEXP} do_pkg "hackage-security" ${HACKAGE_SECURITY_VER} \
cabal-install.cabal view
@@ -1,5 +1,5 @@ Name: cabal-install-Version: 1.24.0.0+Version: 1.24.0.1 Synopsis: The command-line interface for Cabal and Hackage. Description: The \'cabal\' command-line program simplifies the process of managing@@ -30,6 +30,20 @@ -- Generated with '../Cabal/misc/gen-extra-source-files.sh' -- Do NOT edit this section manually; instead, run the script. -- BEGIN gen-extra-source-files+ tests/IntegrationTests/custom-setup/common.sh+ tests/IntegrationTests/custom-setup/should_run/Cabal-99998/Cabal.cabal+ tests/IntegrationTests/custom-setup/should_run/Cabal-99998/CabalMessage.hs+ tests/IntegrationTests/custom-setup/should_run/Cabal-99999/Cabal.cabal+ tests/IntegrationTests/custom-setup/should_run/Cabal-99999/CabalMessage.hs+ tests/IntegrationTests/custom-setup/should_run/custom-setup-without-cabal-defaultMain/Setup.hs+ tests/IntegrationTests/custom-setup/should_run/custom-setup-without-cabal-defaultMain/custom-setup-without-cabal-defaultMain.cabal+ tests/IntegrationTests/custom-setup/should_run/custom-setup-without-cabal/Setup.hs+ tests/IntegrationTests/custom-setup/should_run/custom-setup-without-cabal/custom-setup-without-cabal.cabal+ tests/IntegrationTests/custom-setup/should_run/custom-setup/Setup.hs+ tests/IntegrationTests/custom-setup/should_run/custom-setup/custom-setup.cabal+ tests/IntegrationTests/custom-setup/should_run/custom_setup_without_Cabal_doesnt_allow_Cabal_import.sh+ tests/IntegrationTests/custom-setup/should_run/custom_setup_without_Cabal_doesnt_require_Cabal.sh+ tests/IntegrationTests/custom-setup/should_run/installs_Cabal_as_setup_dep.sh tests/IntegrationTests/custom/common.sh tests/IntegrationTests/custom/should_run/plain.err tests/IntegrationTests/custom/should_run/plain.sh@@ -261,10 +275,10 @@ pretty >= 1.1 && < 1.2, random >= 1 && < 1.2, stm >= 2.0 && < 3,- tar >= 0.5.0.1 && < 0.6,+ tar >= 0.5.0.3 && < 0.6, time >= 1.4 && < 1.7, zlib >= 0.5.3 && < 0.7,- hackage-security >= 0.5.1 && < 0.6+ hackage-security >= 0.5.2.2 && < 0.6 if flag(old-bytestring) build-depends: bytestring < 0.10.2, bytestring-builder >= 0.10 && < 1@@ -400,5 +414,5 @@ else ghc-options: -threaded - ghc-options: -Wall+ ghc-options: -Wall -fwarn-tabs -fno-ignore-asserts default-language: Haskell2010
changelog view
@@ -1,4 +1,21 @@ -*-change-log-*-+1.24.0.1 Ryan Thomas <ryan@ryant.org> October 2016+ * Fixed issue with passing '--enable-profiling' when invoking+ Setup scripts built with older versions of Cabal (#3873).+ * Fixed various behaviour differences between network transports+ (#3429).+ * Updated to depend on the latest hackage-security that fixes+ various issues on Windows.+ * Fixed 'new-build' to exit with a non-zero exit code on failure+ (#3506).+ * Store secure repo index data as 01-index.* (#3862).+ * Added new hackage-security root keys for distribution with+ cabal-install.+ * Fix an issue where 'cabal install' sometimes had to be run twice+ for packages with build-type: Custom and a custom-setup stanza+ (#3723).+ * 'cabal sdist' no longer ignores '--builddir' when the package's+ build-type is Custom (#3794). 1.24.0.0 Ryan Thomas <ryan@ryant.org> May 2016 * If there are multiple remote repos, 'cabal update' now updates@@ -54,6 +71,7 @@ (#3171). * Improved performance of '--reorder-goals' (#3208). * Fixed space leaks in modular solver (#2916, #2914).+ * Made the solver aware of pkg-config constraints (#3023). * Added a new command: 'gen-bounds' (#3223). See http://softwaresimply.blogspot.se/2015/08/cabal-gen-bounds-easy-generation-of.html. * Tech preview of new nix-style isolated project-based builds.
+ tests/IntegrationTests/custom-setup/common.sh view
@@ -0,0 +1,9 @@+# Helper to run Cabal+cabal() {+ "$CABAL" $CABAL_ARGS "$@"+}++die() {+ echo "die: $@"+ exit 1+}
+ tests/IntegrationTests/custom-setup/should_run/Cabal-99998/Cabal.cabal view
@@ -0,0 +1,8 @@+name: Cabal+version: 99998+build-type: Simple+cabal-version: >= 1.2++library+ build-depends: base+ exposed-modules: CabalMessage
+ tests/IntegrationTests/custom-setup/should_run/Cabal-99998/CabalMessage.hs view
@@ -0,0 +1,3 @@+module CabalMessage where++message = "This is Cabal-99998"
+ tests/IntegrationTests/custom-setup/should_run/Cabal-99999/Cabal.cabal view
@@ -0,0 +1,8 @@+name: Cabal+version: 99999+build-type: Simple+cabal-version: >= 1.2++library+ build-depends: base+ exposed-modules: CabalMessage
+ tests/IntegrationTests/custom-setup/should_run/Cabal-99999/CabalMessage.hs view
@@ -0,0 +1,3 @@+module CabalMessage where++message = "This is Cabal-99999"
+ tests/IntegrationTests/custom-setup/should_run/custom-setup-without-cabal-defaultMain/Setup.hs view
@@ -0,0 +1,3 @@+import Distribution.Simple++main = defaultMain
+ tests/IntegrationTests/custom-setup/should_run/custom-setup-without-cabal-defaultMain/custom-setup-without-cabal-defaultMain.cabal view
@@ -0,0 +1,9 @@+name: custom-setup-without-cabal-defaultMain+version: 1.0+build-type: Custom+cabal-version: >= 1.2++custom-setup+ setup-depends: base++library
+ tests/IntegrationTests/custom-setup/should_run/custom-setup-without-cabal/Setup.hs view
@@ -0,0 +1,4 @@+import System.Exit+import System.IO++main = hPutStrLn stderr "My custom Setup" >> exitFailure
+ tests/IntegrationTests/custom-setup/should_run/custom-setup-without-cabal/custom-setup-without-cabal.cabal view
@@ -0,0 +1,9 @@+name: custom-setup-without-cabal+version: 1.0+build-type: Custom+cabal-version: >= 99999++custom-setup+ setup-depends: base++library
+ tests/IntegrationTests/custom-setup/should_run/custom-setup/Setup.hs view
@@ -0,0 +1,5 @@+import CabalMessage (message)+import System.Exit+import System.IO++main = hPutStrLn stderr message >> exitFailure
+ tests/IntegrationTests/custom-setup/should_run/custom-setup/custom-setup.cabal view
@@ -0,0 +1,9 @@+name: custom-setup+version: 1.0+build-type: Custom+cabal-version: >= 99999++custom-setup+ setup-depends: base, Cabal >= 99999++library
+ tests/IntegrationTests/custom-setup/should_run/custom_setup_without_Cabal_doesnt_allow_Cabal_import.sh view
@@ -0,0 +1,12 @@+. ../common.sh+cd custom-setup-without-cabal-defaultMain++# This package has explicit setup dependencies that do not include Cabal.+# Compilation should fail because Setup.hs imports Distribution.Simple.+! cabal new-build custom-setup-without-cabal-defaultMain > output 2>&1+cat output+grep -q "\(Could not find module\|Failed to load interface for\).*Distribution\\.Simple" output \+ || die "Should not have been able to import Cabal"++grep -q "It is a member of the hidden package .*Cabal-" output \+ || die "Cabal should be available"
+ tests/IntegrationTests/custom-setup/should_run/custom_setup_without_Cabal_doesnt_require_Cabal.sh view
@@ -0,0 +1,11 @@+. ../common.sh+cd custom-setup-without-cabal++# This package has explicit setup dependencies that do not include Cabal.+# new-build should try to build it, even though the cabal-version cannot be+# satisfied by an installed version of Cabal (cabal-version: >= 99999). However,+# configure should fail because Setup.hs just prints an error message and exits.+! cabal new-build custom-setup-without-cabal > output 2>&1+cat output+grep -q "My custom Setup" output \+ || die "Expected output from custom Setup"
+ tests/IntegrationTests/custom-setup/should_run/installs_Cabal_as_setup_dep.sh view
@@ -0,0 +1,15 @@+# Regression test for issue #3436++. ../common.sh+cabal sandbox init+cabal install ./Cabal-99998+cabal sandbox add-source Cabal-99999++# Install custom-setup, which has a setup dependency on Cabal-99999.+# cabal should build the setup script with Cabal-99999, but then+# configure should fail because Setup just prints an error message+# imported from Cabal and exits.+! cabal install custom-setup/ > output 2>&1++cat output+grep -q "This is Cabal-99999" output || die "Expected output from Cabal-99999"
tests/UnitTests/Distribution/Client/ArbitraryInstances.hs view
@@ -67,6 +67,7 @@ arbitraryShortToken :: Gen String arbitraryShortToken = getShortToken <$> arbitrary +#if !MIN_VERSION_QuickCheck(2,9,0) instance Arbitrary Version where arbitrary = do branch <- shortListOf1 4 $@@ -81,6 +82,7 @@ [ Version branch' [] | branch' <- shrink branch, not (null branch') ] shrink (Version branch _tags) = [ Version branch [] ]+#endif instance Arbitrary VersionRange where arbitrary = canonicaliseVersionRange <$> sized verRangeExp
tests/UnitTests/Distribution/Client/UserConfig.hs view
@@ -48,7 +48,7 @@ appendFile configFile "verbose: 0\n" diff <- userConfigDiff $ globalFlags configFile assertBool (unlines $ "Should detect a difference:" : diff) $- diff == [ "- verbose: 1", "+ verbose: 0" ]+ diff == [ "+ verbose: 0" ] canUpdateConfig :: Assertion@@ -85,7 +85,7 @@ sysTmpDir <- getTemporaryDirectory withTempDirectory silent sysTmpDir "cabal-test" $ \tmpDir -> do let configFile = tmpDir </> "tmp.config"- createDefaultConfigFile silent configFile+ _ <- createDefaultConfigFile silent configFile exists <- doesFileExist configFile assertBool ("Config file should be written to " ++ configFile) exists