Commit 652fc8e3 authored by bjorn@bringert.net's avatar bjorn@bringert.net
Browse files

'cabal install' without argument now installs all the dependencies of the...

'cabal install' without argument now installs all the dependencies of the package in the current directory, and then configures, builds and installs it.
parent 8c38e5ab
......@@ -13,6 +13,7 @@
module Hackage.Dependency
(
resolveDependencies
, resolveDependenciesLocal
, packagesToInstall
) where
......@@ -24,6 +25,7 @@ import Distribution.Version (Dependency(..), withinRange)
import Distribution.Package (PackageIdentifier(..))
import Distribution.PackageDescription
(PackageDescription(buildDepends)
, GenericPackageDescription
, finalizePackageDescription)
import Distribution.Simple.Compiler (Compiler, showCompilerId, compilerVersion)
import Distribution.Simple.Program (ProgramConfiguration)
......@@ -46,6 +48,20 @@ resolveDependencies cfg comp conf deps
return [resolveDependency comp installed available dep opts
| UnresolvedDependency dep opts <- deps]
-- | Resolve dependencies of a local package description. This is used
-- when the top-level package does not come from hackage.
resolveDependenciesLocal :: ConfigFlags
-> Compiler
-> ProgramConfiguration
-> GenericPackageDescription
-> [String]
-> IO [ResolvedPackage]
resolveDependenciesLocal cfg comp conf desc opts
= do installed <- listInstalledPackages cfg comp conf
available <- getKnownPackages cfg
return [resolveDependency comp installed available dep []
| dep <- getDependencies comp installed available desc opts]
resolveDependency :: Compiler
-> [PackageIdentifier] -- ^ Installed packages.
-> [PkgInfo] -- ^ Installable packages
......@@ -58,7 +74,7 @@ resolveDependency comp installed available dep opts
resolveFromInstalled = fmap (Installed dep) $ latestInstalledSatisfying installed dep
resolveFromAvailable =
do pkg <- latestAvailableSatisfying available dep
let deps = getDependencies comp installed available pkg opts
let deps = getDependencies comp installed available (pkgDesc pkg) opts
resolved = map (\d -> resolveDependency comp installed available d []) deps
return $ Available dep pkg opts resolved
......@@ -91,7 +107,7 @@ satisfies pkg (Dependency depName vrange)
getDependencies :: Compiler
-> [PackageIdentifier] -- ^ Installed packages.
-> [PkgInfo] -- ^ Available packages
-> PkgInfo
-> GenericPackageDescription
-> [String] -- ^ Options
-> [Dependency]
-- ^ If successful, this is the list of dependencies.
......@@ -109,7 +125,7 @@ getDependencies comp installed available pkg opts
System.Info.os
System.Info.arch
(showCompilerId comp, compilerVersion comp)
(pkgDesc pkg)
pkg
-- | Extracts configurations flags from a list of options.
configurationsFlags :: [String] -> [(String, Bool)]
......
......@@ -26,18 +26,20 @@ import Text.Printf (printf)
import Hackage.Config (message)
import Hackage.Dependency (resolveDependencies, packagesToInstall)
import Hackage.Dependency (resolveDependencies, resolveDependenciesLocal, packagesToInstall)
import Hackage.Fetch (fetchPackage)
import Hackage.Tar (extractTarGzFile)
import Hackage.Types (ConfigFlags(..), UnresolvedDependency(..)
, PkgInfo(..), pkgInfoId)
, PkgInfo(..), pkgInfoId, ResolvedPackage)
import Distribution.Simple.Compiler (Compiler(..))
import Distribution.Simple.InstallDirs (InstallDirs(..), absoluteInstallDirs)
import Distribution.Simple.Program (ProgramConfiguration)
import Distribution.Simple.SetupWrapper (setupWrapper)
import Distribution.Simple.Setup (CopyDest(..))
import Distribution.Simple.Utils (defaultPackageDesc)
import Distribution.Package (showPackageId, PackageIdentifier(..))
import Distribution.PackageDescription (packageDescription, readPackageDescription, package)
import Distribution.Verbosity
......@@ -46,8 +48,23 @@ import Distribution.Verbosity
-- |Installs the packages needed to satisfy a list of dependencies.
install :: ConfigFlags -> Compiler -> ProgramConfiguration -> [String] -> [UnresolvedDependency] -> IO ()
install cfg comp conf globalArgs deps
= do resolvedDeps <- resolveDependencies cfg comp conf deps
case packagesToInstall resolvedDeps of
| null deps = installLocalPackage cfg comp conf globalArgs
| otherwise = do resolvedDeps <- resolveDependencies cfg comp conf deps
installResolvedDeps cfg comp globalArgs resolvedDeps
-- | Install the unpacked package in the current directory, and all its dependencies.
installLocalPackage :: ConfigFlags -> Compiler -> ProgramConfiguration -> [String] -> IO ()
installLocalPackage cfg comp conf globalArgs =
do cabalFile <- defaultPackageDesc (configVerbose cfg)
desc <- readPackageDescription (configVerbose cfg) cabalFile
resolvedDeps <- resolveDependenciesLocal cfg comp conf desc globalArgs
installResolvedDeps cfg comp globalArgs resolvedDeps
let pkgId = package (packageDescription desc)
installUnpackedPkg cfg comp globalArgs pkgId [] Nothing
installResolvedDeps :: ConfigFlags -> Compiler -> [String] -> [ResolvedPackage] -> IO ()
installResolvedDeps cfg comp globalArgs resolvedDeps =
case packagesToInstall resolvedDeps of
Left missing -> fail $ "Unresolved dependencies: " ++ show missing
Right pkgs -> installPackages cfg comp globalArgs pkgs
......@@ -115,12 +132,7 @@ installPkg cfg comp globalArgs (pkg,opts)
tmp <- getTemporaryDirectory
let p = pkgInfoId pkg
tmpDirPath = tmp </> printf "TMP%sTMP" (showPackageId p)
setup cmd
= do let cmdOps = mkPkgOps cfg comp p cmd (globalArgs++opts)
path = tmpDirPath </> showPackageId p
message cfg deafening $
unwords ["setupWrapper", show (cmd:cmdOps), show path]
setupWrapper (cmd:cmdOps) (Just path)
path = tmpDirPath </> showPackageId p
bracket_ (createDirectoryIfMissing True tmpDirPath)
(removeDirectoryRecursive tmpDirPath)
(do message cfg deafening (printf "Extracting %s..." pkgPath)
......@@ -128,12 +140,16 @@ installPkg cfg comp globalArgs (pkg,opts)
let descFilePath = tmpDirPath </> showPackageId p </> pkgName p <.> "cabal"
e <- doesFileExist descFilePath
when (not e) $ fail $ "Package .cabal file not found: " ++ show descFilePath
installUnpackedPkg cfg p setup
installUnpackedPkg cfg comp globalArgs p opts (Just path)
return ())
installUnpackedPkg :: ConfigFlags -> PackageIdentifier
-> (String -> IO ()) -> IO ()
installUnpackedPkg _cfg pkgId setup
installUnpackedPkg :: ConfigFlags -> Compiler
-> [String] -- ^ Arguments for all packages
-> PackageIdentifier
-> [String] -- ^ Arguments for this package
-> Maybe FilePath -- ^ Directory to change to before starting the installation.
-> IO ()
installUnpackedPkg cfg comp globalArgs pkgId opts mpath
= do printf "Building '%s'\n" (showPackageId pkgId)
printf " Configuring...\n"
setup "configure"
......@@ -143,3 +159,9 @@ installUnpackedPkg _cfg pkgId setup
setup "install"
printf " Done.\n"
return ()
where
setup cmd
= do let cmdOps = mkPkgOps cfg comp pkgId cmd (globalArgs++opts)
message cfg deafening $
unwords ["setupWrapper", show (cmd:cmdOps), show mpath]
setupWrapper (cmd:cmdOps) mpath
\ No newline at end of file
......@@ -128,14 +128,6 @@ printGlobalHelp = do pname <- getProgName
| cmd <- commandList ]
where align n str = str ++ replicate (n - length str) ' '
printActionHelp :: Action -> IO ()
printActionHelp action =
do let [cmd] = [c | c <- commandList, cmdAction c == action]
pname <- getProgName
let syntax_line = "Usage: " ++ pname ++ " " ++ cmdName cmd ++ " [FLAGS]\n\nFlags for " ++ cmdName cmd ++ ":"
putStrLn (usageInfo syntax_line (cmdOptions cmd))
putStrLn (cmdDescription cmd)
parseGlobalArgs :: [String] -> IO (Action,[Option],[String])
parseGlobalArgs opts =
do let (flags, args, unrec, errs) = getOpt' RequireOrder globalOptions opts
......@@ -187,9 +179,6 @@ infoCmd = mkCmd "info" "Emit some info"
"Emits information about dependency resolution" InfoCmd
parsePackageArgs :: Action -> [String] -> IO ([String],[UnresolvedDependency])
parsePackageArgs action [] = do
printActionHelp action
exitWith ExitSuccess
parsePackageArgs _ args
= return (globalArgs,parsePkgArgs pkgs)
where (globalArgs,pkgs) = break (not.(==)'-'.head) args
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment