fbrnch-1.4: src/Cmd/Update.hs
module Cmd.Update
( updateCmd,
updatePkg
)
where
import Branches
import Common
import Common.System
import Git
import InterleaveOutput (cmdSilent')
import Krb
import Package
import Data.RPM.VerCmp
import SimplePrompt (promptEnter)
-- FIXME if autorelease, drop -b baserelease
-- FIXME --no-prep to avoid overwriting ongoing build
-- FIXME don't bump release if already bumped
-- FIXME check EVR increased
-- FIXME if multiple sources might need to bump release
-- FIXME Haskell subpackages require release bump even with version bump
updateCmd :: Bool -> Bool -> Bool -> (Maybe Branch,[String]) -> IO ()
updateCmd onlysources force allowHEAD (mbr,args) = do
pkgGit <- isPkgGitSshRepo
(mver,pkgs) <-
case args of
[a] -> do
if pkgGit
then return (Just a,[])
else do
mspec <- maybeFindSpecfile
return $ if isJust mspec
then (Just a,[])
else (Nothing,[a])
_ -> return (Nothing,args)
let mgitops =
let dirty = if allowHEAD then dirtyGitHEAD else dirtyGitFetch
in if pkgGit
then dirty
else if null pkgs then Nothing else dirty
withPackagesMaybeBranch HeaderMay False mgitops (updatePkg onlysources force allowHEAD pkgGit mver) (mbr, pkgs)
updatePkg :: Bool -> Bool -> Bool -> Bool -> Maybe String -> Package -> AnyBranch
-> IO ()
updatePkg onlysources force allowHEAD distgit mver pkg br = do
when (distgit && br /= RelBranch Rawhide && isRelBranch br) $
promptEnter $ "Are you sure you want to update" +-+ show br +-+ "branch?! Press Enter to continue"
spec <- if allowHEAD
then findSpecfile
else localBranchSpecFile pkg br
(curver,_) <- pkgVerRel spec
vdiff <- filter ("Version:" `isInfixOf`) . filter (not . ("@@ " `isPrefixOf`)) <$> gitLines "diff" ["-U0", "HEAD", spec]
unless (length vdiff `elem` [0,2]) $
error' $ "diff contains complex version change:\n" ++ unlines vdiff
case mver of
Nothing -> do
when (null vdiff && not onlysources) $
error' "specify or edit version to update"
putStrLn $ "current version:" +-+ curver
Just nver -> do
when (length vdiff == 2) $
error' $ "spec version already bumped to" +-+ curver
when (curver == nver) $
putStrLn $ "already new version" +-+ curver
let moldnewver =
case mver of
Just nver -> Just (curver,nver)
Nothing ->
-- FIXME confused by fresh multiversion package (eg hadrian-0.1.0.0 make new ghcX.Y to 0.1.0.0
case map (last . words) vdiff of
[old,new] -> Just (old,new)
_ -> Nothing
unless onlysources $ do
let (oldver,newver) =
fromMaybe (error' "complex version change") moldnewver
-- FIXME take epoch into account
when (rpmVerCompare oldver newver == GT) $
putStrLn $ "current" +-+ oldver +-+ "is newer!"
putStrLn $ oldver +-+ "->\n" ++ newver
when (curver /= newver) $ do
editSpecField "Version" newver spec
-- FIXME do not touch %autorelease
editSpecField "Release" "0%{?dist}" spec
-- FIXME should be sure sources exists for distgit
whenM (doesFileExist "sources") $
cmd_ "sed" ["-i", "/" ++ unPackage pkg ++ "-" ++ oldver ++ "./d", "sources"]
whenM isPkgGitSshRepo $ do
-- FIXME forM_
sources <- map sourceFieldFile <$> cmdLines "spectool" ["-S", spec]
existing <- filterM doesFileExist sources
unless (existing == sources) $ do
cmd_ "fedpkg" ["sources"]
unless force $
-- FIXME only if not all exist
cmd_ "spectool" ["-g", "-S", spec]
patches <- map sourceFieldFile <$> cmdLines "spectool" ["-P", spec]
forM_ patches $ \patch ->
unlessM (doesFileExist patch) $
cmd_ "spectool" ["-g", "-P", spec]
when force $ do
let archives = filter isArchiveFile existing
forM_ archives removeFile
cmd_ "spectool" ["-g", "-S", spec]
krbTicket
cmd_ "fedpkg" $ "new-sources" : filter isArchiveFile sources
whenJust moldnewver $ \(_old,newver) -> do
versions <- changelogVersions spec
let missing = null versions || not ((newver ++ "-") `isPrefixOf` head versions)
when missing $ do
cmd_ "rpmdev-bumpspec" ["-c", "update to" +-+ newver, spec]
git_ "commit" ["-a", "-m", "update to" +-+ newver]
putStr "Prepping... "
cmdSilent' "rpmbuild" ["-bp", "--nodeps", spec]
putStrLn "done"
-- FIXME git amend (if previous commit was update)
where
sourceFieldFile :: String -> FilePath
sourceFieldFile field =
if null field then
-- should be impossible
error "empty source field!"
else (takeFileName . last . words) field
-- FIXME handle .tgz?
isArchiveFile :: FilePath -> Bool
isArchiveFile f =
any ($ f) [(".tar." `isInfixOf`),
(".zip" `isSuffixOf`),
(".gpg" `isSuffixOf`),
(".tgz" `isSuffixOf`)]
pkgVerRel :: FilePath -> IO (String,String)
pkgVerRel spec = do
--dist <- branchDist br
-- workaround dist with bootstrap
--hostdist <- cmd "rpm" ["--eval", "%{dist}"]
mvr <- cmdMaybe "rpmspec" ["-q", "--srpm", "--qf", "%{version}-%{release}", spec]
case mvr of
Nothing -> error' $ "Failed to read package ver-rel:" +-+ spec
Just vr -> return $ splitBy "-" vr
splitBy :: String -> String -> (String,String)
splitBy sep xs =
let ws = splitOn sep xs in
case ws of
[f,v] -> (f,v)
_ -> error $ "inconsistent field:" +-+ xs
changelogVersions :: FilePath -> IO [String]
changelogVersions spec = do
ns <- cmdLines "rpmspec" ["-q", "--srpm", "--qf", "%{changelogname}", spec]
return $ map (removePrefix "- " . dropWhile (/= '-')) ns