cabal-dev 0.7.4.0 → 0.7.4.1
raw patch · 4 files changed
+161/−78 lines, 4 files
Files
- cabal-dev.cabal +2/−1
- src/Distribution/Dev/CabalInstall.hs +103/−0
- src/Distribution/Dev/InstallDependencies.hs +41/−26
- src/Distribution/Dev/InvokeCabal.hs +15/−51
cabal-dev.cabal view
@@ -1,5 +1,5 @@ Name: cabal-dev-Version: 0.7.4.0+Version: 0.7.4.1 Synopsis: Manage sandboxed Haskell build environments Description: cabal-dev is a tool for managing development builds of@@ -136,6 +136,7 @@ Distribution.Dev.AddSource, Distribution.Dev.Sandbox, Distribution.Dev.Command,+ Distribution.Dev.CabalInstall, Distribution.Dev.Flags, Distribution.Dev.Ghci, Distribution.Dev.InvokeCabal,
+ src/Distribution/Dev/CabalInstall.hs view
@@ -0,0 +1,103 @@+module Distribution.Dev.CabalInstall+ ( findOnPath+ , program+ , getFeatures+ , CabalFeatures+ , needsQuotes+ , hasOnlyDependencies+ , configDir+ )+where++import Control.Applicative ( (<$>) )+import Distribution.Version ( Version(..), withinRange+ , earlierVersion, orLaterVersion )+import Distribution.Verbosity ( Verbosity )+import Distribution.Simple.Program ( Program( programFindVersion+ )+ , ConfiguredProgram+ , emptyProgramConfiguration+ , findProgramVersion+ , programLocation+ , programVersion+ , requireProgram+ , getProgramOutput+ , simpleProgram+ )+import Distribution.Simple.Utils ( debug )+import Distribution.Text ( display, simpleParse )++import System.Directory ( getAppUserDataDirectory )++-- XXX This is duplicated in Setup.hs+-- |Definition of the cabal-install program+program :: Program+program =+ (simpleProgram "cabal") { programFindVersion =+ findProgramVersion "--numeric-version" id+ }++-- |Find cabal-install on the user's PATH+findOnPath :: Verbosity -> IO ConfiguredProgram+findOnPath v = do+ (cabal, _) <- requireProgram v program emptyProgramConfiguration+ debug v $ concat [ "Using cabal-install "+ , maybe "(unknown version)" display $ programVersion cabal+ , " at "+ , show (programLocation cabal)+ ]+ return cabal++-- |Parse the Cabal library version from the output of cabal --version+parseVersionOutput :: String -> Either String Version+parseVersionOutput str =+ case lines str of+ [] -> Left "No version string provided."+ [_] -> Left "Could not find Cabal version line."+ (_:ln:_) -> case simpleParse ((words ln)!!2) of+ Just v -> Right v+ Nothing -> Left $ err ln+ where err line = "Could not parse Cabal verison.\n"+ ++ "(simpleParse "++show line++")"++-- |The information necessary to properly invoke cabal-install+data CabalFeatures = CabalFeatures { cfLibVersion :: Version+ , cfExeVersion :: Version+ }++mkVer :: [Int] -> Version+mkVer l = Version l []++-- |Extract the features of this cabal-install executable+getFeatures :: Verbosity -> ConfiguredProgram ->+ IO (Either String CabalFeatures)+getFeatures v cabal = do+ case programVersion cabal of+ Nothing -> return $ Left "Failed to find cabal-install version"+ Just exeVer -> do+ verRes <- parseVersionOutput <$> getProgramOutput v cabal ["--version"]+ case verRes of+ Left err -> return $ Left $ "Detecting cabal-install's Cabal: " ++ err+ Right libVer -> return $ Right $+ CabalFeatures { cfLibVersion = libVer+ , cfExeVersion = exeVer+ }++-- |Does the cabal-install configuration file use quoted paths in the+-- install-dirs section?+needsQuotes :: CabalFeatures -> Bool+needsQuotes = (`withinRange` earlierVersion (mkVer [1,10])) . cfLibVersion++-- |Does this cabal-install executable support the --dependencies-only+-- flag to install?+hasOnlyDependencies :: CabalFeatures -> Bool+hasOnlyDependencies =+ (`withinRange` orLaterVersion (mkVer [0, 10])) . cfExeVersion++-- |What is the configuration directory for this cabal-install executable?++-- XXX: This needs to do something different for certain platforms for+-- new versions of cabal-install (look at the tickets on creswick's+-- cabal-dev repo)+configDir :: CabalFeatures -> IO FilePath+configDir _ = getAppUserDataDirectory "cabal"
src/Distribution/Dev/InstallDependencies.hs view
@@ -7,13 +7,14 @@ import Distribution.Dev.Flags ( Config, getVerbosity ) import Distribution.Dev.Sandbox ( resolveSandbox ) import Distribution.Dev.InitPkgDb ( initPkgDb )-import Distribution.Dev.InvokeCabal ( setup, cabalProgram )+import Distribution.Dev.InvokeCabal ( setup )+import qualified Distribution.Dev.CabalInstall as CI import Distribution.Simple.Program ( requireProgram , getProgramOutput , runProgram ) import Distribution.Simple.Program.Db ( emptyProgramDb )-import Distribution.Simple.Utils ( notice )+import Distribution.Simple.Utils ( notice, warn ) actions :: CommandActions actions = CommandActions@@ -27,31 +28,45 @@ installDependencies flgs pkgNames = do let v = getVerbosity flgs s <- initPkgDb v =<< resolveSandbox flgs- (cabal, _) <- requireProgram v cabalProgram emptyProgramDb+ (cabal, _) <- requireProgram v CI.program emptyProgramDb+ eFeatures <- CI.getFeatures v cabal setupRes <- setup s cabal flgs- case setupRes of- Left err -> return $ CommandError err- Right args -> do- out <- getProgramOutput v cabal $ concat- [ args- , ["install", "--dry-run", "--verbose=1"]- , pkgNames- ]- let -- Drop the lines that say:- -- Resolving dependencies...- -- In order, the following [...]- pkgIdStrs = drop 2 $ lines out+ case (setupRes, eFeatures) of+ (Left err, _) -> return $ CommandError err+ (_, Left err) -> return $ CommandError err+ (Right args, Right features) ->+ if CI.hasOnlyDependencies features+ then do notice v "You are using a version of cabal-install that has \+ \the --only-dependencies flag to the install command.\+ \ Invoking that instead..."+ runProgram v cabal $ concat [ args+ , ["install", "--only-dependencies"]+ , pkgNames+ ]+ return CommandOk+ else do+ warn v "Using a work-around to install dependencies for cabal-install\+ \ less than 0.10"+ out <- getProgramOutput v cabal $ concat+ [ args+ , ["install", "--dry-run", "--verbose=1"]+ , pkgNames+ ]+ let -- Drop the lines that say:+ -- Resolving dependencies...+ -- In order, the following [...]+ pkgIdStrs = drop 2 $ lines out - -- We take the init if no pkgNames were supplied because- -- that means we're working on the cabal file in the- -- current directory.- deps = case pkgNames of- [] | not $ null pkgIdStrs -> init pkgIdStrs- _ -> pkgIdStrs+ -- We take the init if no pkgNames were supplied because+ -- that means we're working on the cabal file in the+ -- current directory.+ deps = case pkgNames of+ [] | not $ null pkgIdStrs -> init pkgIdStrs+ _ -> pkgIdStrs - case deps of- [] -> notice v "No dependencies need to be installed"- _ -> do notice v $ "Installing dependencies: " ++ unwords deps- runProgram v cabal $ args ++ ("install":deps)+ case deps of+ [] -> notice v "No dependencies need to be installed"+ _ -> do notice v $ "Installing dependencies: " ++ unwords deps+ runProgram v cabal $ args ++ ("install":deps) - return CommandOk+ return CommandOk
src/Distribution/Dev/InvokeCabal.hs view
@@ -3,30 +3,23 @@ ( actions , setup , extraArgs- , cabalProgram , cabalArgs ) where -import Distribution.Version ( Version(..), VersionRange, withinRange, earlierVersion ) import Distribution.Verbosity ( Verbosity, showForCabal )-import Distribution.Simple.Program ( Program( programFindVersion- , programFindLocation- )+import Distribution.Simple.Program ( Program( programFindLocation ) , ConfiguredProgram , emptyProgramConfiguration- , findProgramVersion , locationPath , programLocation- , programVersion , requireProgram , runProgram- , getProgramOutput , simpleProgram ) import Distribution.Simple.Utils ( withUTF8FileContents, writeUTF8File , debug, cabalVersion )-import Distribution.Text ( display, simpleParse )+import Distribution.Version ( Version(..) ) import System.Console.GetOpt ( OptDescr ) import Distribution.Dev.Command ( CommandActions(..)@@ -37,6 +30,7 @@ ) import Distribution.Dev.InitPkgDb ( initPkgDb ) import qualified Distribution.Dev.RewriteCabalConfig as R+import qualified Distribution.Dev.CabalInstall as CI import Distribution.Dev.Sandbox ( resolveSandbox , cabalConf , Sandbox@@ -48,8 +42,6 @@ ) import Distribution.Dev.Utilities ( ensureAbsolute ) -import System.Directory ( getAppUserDataDirectory )- actions :: String -> CommandActions actions act = CommandActions { cmdDesc = "Invoke cabal-install with the development configuration"@@ -62,7 +54,7 @@ invokeCabal flgs args = do let v = getVerbosity flgs s <- initPkgDb v =<< resolveSandbox flgs- cabal <- findCabalOnPath v+ cabal <- CI.findOnPath v res <- setup s cabal flgs case res of Left err -> return $ CommandError err@@ -76,18 +68,18 @@ s <- initPkgDb v =<< resolveSandbox flgs setup s cabal flgs -setup :: Sandbox KnownVersion -> ConfiguredProgram -> Config -> IO (Either String [String])+setup :: Sandbox KnownVersion -> ConfiguredProgram -> Config ->+ IO (Either String [String]) setup s cabal flgs = do let v = getVerbosity flgs- verOut <- getProgramOutput v cabal ["--version"] cfgIn <- getCabalConfig flgs+ cVer <- CI.getFeatures v cabal let cfgOut = cabalConf s- case cabalVer verOut of+ case cVer of Left err -> return $ Left err- Right ver -> do- cabalHome <- getAppUserDataDirectory "cabal"- let qInstDirs = withinRange ver cabalNeedsQuotes- rew = R.Rewrite cabalHome (sandbox s) (pkgConf s) qInstDirs+ Right features -> do+ cabalHome <- CI.configDir features+ let rew = R.Rewrite cabalHome (sandbox s) (pkgConf s) (CI.needsQuotes features) withUTF8FileContents cfgIn $ \cIn -> do cfgRes <- R.rewriteCabalConfig rew cIn case cfgRes of@@ -122,7 +114,10 @@ _ -> return [] -- XXX: this is very imprecise. Right now, we require a specific--- version of Cabal, so this is ok (and is equivalent to True)+-- version of Cabal, so this is ok (and is equivalent to True). Note+-- that this is the version of Cabal that THIS PROGRAM is being built+-- against, rather than the version that CABAL-INSTALL was built+-- against. needsGHC68Compat :: Bool needsGHC68Compat = cabalVersion < Version [1, 9] [] @@ -136,34 +131,3 @@ } where p = simpleProgram "ghc-pkg-6_8-compat"---- XXX This is duplicated in Setup.hs-cabalProgram :: Program-cabalProgram =- (simpleProgram "cabal") { programFindVersion =- findProgramVersion "--numeric-version" id- }--findCabalOnPath :: Verbosity -> IO ConfiguredProgram-findCabalOnPath v = do- (cabal, _) <- requireProgram v cabalProgram emptyProgramConfiguration- debug v $ concat [ "Using cabal-install "- , maybe "(unknown version)" display $ programVersion cabal- , " at "- , show (programLocation cabal)- ]- return cabal--cabalVer :: String -> Either String Version-cabalVer str =- case lines str of- [] -> Left "No version string provided."- [_] -> Left "Could not find Cabal version line."- (_:ln:_) -> case simpleParse ((words ln)!!2) of- Just v -> Right v- Nothing -> Left $ err ln- where err line = "Could not parse Cabal verison.\n"- ++ "(simpleParse "++show line++")"--cabalNeedsQuotes :: VersionRange-cabalNeedsQuotes = earlierVersion $ Version [1,10] []