fbrnch-1.7: src/Cmd/Install.hs
{-# LANGUAGE CPP #-}
module Cmd.Install (
installCmd,
notInstalledCmd,
Select(..),
unInstallCmd
) where
import Data.RPM
import Safe (headMay)
import SelectRPMs
import Branches
import Cmd.Merge
import Common
import Common.System
import Git
import Package
import Repoquery
import RpmBuild
-- FIXME --rpm to avoid dnf
-- FIXME --force removal of existing incompatible dependent packages
-- FIXME --subpackage to specify subpackage(s) to install/add
-- FIXME --exclude to specify subpackage(s) not to install
-- FIXME --ignore-uninstalled subpackages
-- FIXME --skip-unavailable
-- FIXME --check any/all of package installed
-- FIXME add --debug or respect --verbose for dnf commands
-- FIXME handle subpackage renames (eg ghc-rpm-macros-no-prof to ghc-rpm-macros-quick)
-- FIXME allow building an srpm
installCmd :: Bool -> Bool -> Maybe Branch -> Maybe Natural
-> Maybe ForceShort -> [BCond] -> Bool -> Bool -> Bool -> Yes
-> Select -> Maybe ExistingStrategy -> (Maybe Branch,[String])
-> IO ()
installCmd quiet recurse mfrom mjobs mforceshort bconds reinstall nobuild nobuilddeps yes select mexisting (mbr, pkgs) = do
when (recurse && isShortCircuit mforceshort) $
error' "cannot use --recurse and --shortcircuit"
withPackagesMaybeBranch (boolHeader (recurse || length pkgs > 1)) True Nothing installPkg (mbr, filter (/= ":") pkgs)
where
installPkg :: Package -> AnyBranch -> IO ()
installPkg pkg br = do
whenJust mbr $ gitSwitchBranch . RelBranch
dead <- doesFileExist "dead.package"
if dead
then putStrLn "dead package"
else do
spec <-
if isNothing mfrom
then localBranchSpecFile pkg br
else do
mergeCmd False False True Nothing False mfrom (Branches [onlyRelBranch br], ["."])
localBranchSpecFile pkg br
rpms <- builtRpms br spec
let nvras = map readNVRA rpms
-- FIXME can this be removed now?
already <- filterM nvraInstalled nvras
if isJust mforceshort || null already || reinstall || select /= selectDefault
then doInstallRPMs mforceshort spec rpms
else putStrLn $ unlines (map showNVRA already) ++
"\nalready installed!\n"
where
doInstallRPMs mforceshort' spec rpms = do
-- FIXME show source NVR (eg not pandoc-common)
whenJust (headMay rpms) $
putStrLn . showNVR . dropArch . readNVRA
unless (nobuilddeps || nobuild) $ do
missingdeps <- nub <$> (buildRequires spec >>= filterM notInstalled)
unless (null missingdeps) $
if recurse
then do
-- srcs <- nub <$> mapM (derefSrcPkg topdir dist True) hmissing
rbr <- anyBranchToRelease br
forM_ missingdeps $ \ dep -> do
-- FIXME check not metadep with parens
mpkgdir <- lookForPkgDir rbr ".." dep
case mpkgdir of
Nothing -> putStrLn $ dep +-+ "not known"
Just pkgdir -> installCmd quiet recurse mfrom mjobs mforceshort bconds reinstall nobuild nobuilddeps yes select mexisting (mbr, [pkgdir]) >> putNewLn
-- FIXME option to enable/disable installing missing deps
-- FIXME --skip-missing-deps or prompt
else installDeps True spec
-- FIXME unused
_wasbuilt <-
if nobuild
then return True
else buildRPMs quiet False False mjobs mforceshort' bconds rpms br spec
unless (isShortCircuit mforceshort') $ do
let nvras = rpmsToNVRAs rpms
-- FIXME: prefix = fromMaybe (nvrName nvr) mprefix
decided <- decideRPMs yes False mexisting select (unPackage pkg) nvras
-- FIXME dryrun and debug
-- FIXME return Bool?
installRPMs False False Nothing yes $ groupOnArch "RPMS" decided
lookForPkgDir :: Branch -> FilePath -> String -> IO (Maybe FilePath)
lookForPkgDir rbr topdir p = do
mdir <- checkForPkgDir p
case mdir of
Just dir -> return $ Just dir
Nothing ->
if '-' `elem` p then do
-- FIXME check provides p
mdir' <- checkForPkgDir (init (dropWhileEnd (/= '-') p))
case mdir' of
Just dir' -> return $ Just dir'
Nothing -> repoquerySrc >>= checkForPkgDir
else repoquerySrc >>= checkForPkgDir
where
checkForPkgDir :: FilePath -> IO (Maybe FilePath)
checkForPkgDir p' = do
let pdir = topdir </> p'
exists <- doesDirectoryExist pdir
return $ if exists
then Just pdir
else Nothing
repoquerySrc = do
putStrLn $ "Repoquerying" +-+ p
sysbr <- systemBranch
repoquery sysbr rbr ["--qf=%{source_name}", "--whatprovides", p]
notInstalledCmd :: (Maybe Branch,[String]) -> IO ()
notInstalledCmd =
withPackagesMaybeBranchNoHeadergit notInstalledPkg
where
notInstalledPkg :: Package -> AnyBranch -> IO ()
notInstalledPkg pkg br = do
dead <- doesFileExist "dead.package"
unless dead $ do
spec <- findSpecfile
rpms <- builtRpms br spec
let nvras = map readNVRA rpms
installed <- filterM nvraInstalled nvras
when (null installed) $ do
let pkgnames = map rpmName nvras
older <- filterM pkgInstalled pkgnames
if null older
then putStrLn $ unPackage pkg
else putStrLn $ " " ++ unPackage pkg
pkgInstalled :: String -> IO Bool
pkgInstalled pkg =
cmdBool "rpm" ["--quiet", "-q", pkg]
unInstallCmd :: Yes -> (Maybe Branch,[String]) -> IO ()
unInstallCmd yes (mbr, pkgs) = do
withPackagesMaybeBranch (boolHeader (length pkgs > 1)) True Nothing unInstallPkg (mbr, pkgs)
where
unInstallPkg :: Package -> AnyBranch -> IO ()
unInstallPkg pkg br = do
whenJust mbr $ gitSwitchBranch . RelBranch
dead <- doesFileExist "dead.package"
if dead
then putStrLn "dead package"
else do
spec <- localBranchSpecFile pkg br
built <- builtRpms br spec
let rpms = map (rpmName . readNVRA) built
-- FIXME can this be removed now?
installed <- filterM (\p -> cmdBool "rpm" ["--quiet", "-q", p]) rpms
unless (null installed) $ do
whenJust (headMay built) $
putStrLn . showNVR . dropArch . readNVRA
unInstallRPMs False installed
unInstallRPMs :: Bool -> [String] -> IO ()
unInstallRPMs debug rpms =
unless (null rpms) $ do
mgr <- do
ostree <- doesDirectoryExist "/sysroot/ostree"
if ostree
then return OSTREE
else do
mdnf5 <- findExecutable "dnf5"
return $ maybe DNF3 (const DNF5) mdnf5
let pkgmgr =
case mgr of
DNF3 -> "dnf-3"
DNF5 -> "dnf5"
RPM -> "rpm"
OSTREE -> "rpm-ostree"
com = unInstallCommand mgr
in
do
when debug $ mapM_ putStrLn rpms
(case mgr of
OSTREE -> cmd_
_ -> if debug then sudoLog else sudo_) pkgmgr $
com ++ rpms ++ ["--assumeyes" | yes == Yes && mgr `elem` [DNF3,DNF5]]
unInstallCommand :: PkgMgr -> [String]
unInstallCommand mgr =
case mgr of
DNF3 -> ["remove"]
DNF5 -> ["remove"]
RPM -> ["-e"]
OSTREE -> ["uninstall"]
#if !MIN_VERSION_simple_cmd(0,2,7)
sudoLog :: String -- ^ command
-> [String] -- ^ arguments
-> IO ()
sudoLog = sudo_
#endif