diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
+* 0.12.5 (2018-07-29)
+- update: more careful now with fuzz 1
+-- handle revised to non-revised
+-- improved for subpackaging
+- improvements to revising of .cabal files
+-- place after any subpackages
+-- use revision when prep'ing and building
+- use "fedpkg sources" to fetch current Fedora sources
+- refresh: handle subpackages
+- missing: better output for missing sub-deps
+- do not put doc* in docs
+
 * 0.12.4 (2018-05-31)
-- now uses Hackage revisions of packages
+- now uses Hackage revisions of packages (using wget)
 - spec --stream STREAM replaces --hackage
 - disable https for ghc < 7.10
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -3,6 +3,7 @@
 [![Stackage LTS](http://stackage.org/package/cabal-rpm/badge/lts)](http://stackage.org/lts/package/cabal-rpm)
 [![Stackage Nightly](http://stackage.org/package/cabal-rpm/badge/nightly)](http://stackage.org/nightly/package/cabal-rpm)
 [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/cabal-rpm/Lobby?utm_source=badge&utm_medium=badge&utm_content=badge)
+[![license](https://img.shields.io/badge/license-GPLv3+-brightgreen.svg)](https://www.gnu.org/licenses/gpl.html)
 
 # cabal-rpm
 
diff --git a/cabal-rpm.cabal b/cabal-rpm.cabal
--- a/cabal-rpm.cabal
+++ b/cabal-rpm.cabal
@@ -1,5 +1,5 @@
 Name:                cabal-rpm
-Version:             0.12.4
+Version:             0.12.5
 Synopsis:            RPM packaging tool for Haskell Cabal-based packages
 Description:
     This package provides a RPM packaging tool for Haskell Cabal-based packages.
@@ -19,14 +19,14 @@
 Author:              Jens Petersen <juhp@community.haskell.org>, Bryan O'Sullivan <bos@serpentine.com>
 Maintainer:          Jens Petersen <juhpetersen@gmail.com>
 Copyright:           2007-2008 Bryan O'Sullivan <bos@serpentine.com>,
-                     2012-2017 Jens Petersen <petersen@fedoraproject.org>
+                     2012-2018 Jens Petersen <petersen@fedoraproject.org>
 Category:            Distribution
 Build-type:          Simple
 Extra-source-files:  README.md ChangeLog man/cabal-rpm.1.md man/cabal-rpm.1
 Cabal-version:       >=1.6
 Tested-with:         GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4,
                      GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2,
-                     GHC == 8.4.2
+                     GHC == 8.4.3
 
 source-repository head
   type:     git
@@ -53,7 +53,7 @@
                       time >= 1.2 && < 1.5
     else
        Build-Depends: time >= 1.5 && < 1.9
-    if impl(ghc >= 7.10) && flag(https)
+    if impl(ghc >= 8.0) && flag(https)
        Build-Depends: bytestring,
                       http-client >= 0.4.30,
                       http-client-tls,
diff --git a/src/Commands/Depends.hs b/src/Commands/Depends.hs
--- a/src/Commands/Depends.hs
+++ b/src/Commands/Depends.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Commands.Depends
--- Copyright   :  (C) 2014-2017 Jens Petersen
+-- Copyright   :  (C) 2014-2018  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -56,7 +56,7 @@
 recurseMissing already [] = return already
 recurseMissing already (dep:deps) = do
   miss <- missingDepsPkg dep
-  putMissing dep miss already
+  putMissing miss already
   let accum = nub $ miss ++ already
   deeper <- recurseMissing accum (miss \\ accum)
   let accum2 = nub $ accum ++ deeper
@@ -71,9 +71,9 @@
   pkgdata <- prepare quiet (Just pkg) False
   missingPackages (packageDesc pkgdata) >>= filterM notAvail
 
-putMissing :: String -> [String] -> [String] -> IO ()
-putMissing _ [] _ = return ()
-putMissing pkg deps already = putStrLn $ pkg +-+ "needs:" +-+ unwords (markAlready deps)
+putMissing :: [String] -> [String] -> IO ()
+putMissing [] _ = return ()
+putMissing deps already = putStrLn $ "  " ++ "needs:" +-+ unwords (markAlready deps)
   where
     markAlready :: [String] -> [String]
     markAlready [] = []
diff --git a/src/Commands/Diff.hs b/src/Commands/Diff.hs
--- a/src/Commands/Diff.hs
+++ b/src/Commands/Diff.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Commands.Diff
--- Copyright   :  (C) 2014,2017  Jens Petersen
+-- Copyright   :  (C) 2014,2017-2018  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
diff --git a/src/Commands/Install.hs b/src/Commands/Install.hs
--- a/src/Commands/Install.hs
+++ b/src/Commands/Install.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Commands.Install
--- Copyright   :  (C) 2012-2016 Jens Petersen
+-- Copyright   :  (C) 2012-2018 Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -21,7 +21,7 @@
 import Dependencies (missingPackages, notInstalled, pkgInstallMissing)
 import Options (RpmFlags (..))
 import PackageUtils (PackageData (..), rpmInstall, RpmStage (..), stripPkgDevel)
-import SysCmd (cmd, cmd_, (+-+))
+import SysCmd (cmd, cmd_, rpmEval, (+-+))
 
 #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
 #else
@@ -41,7 +41,7 @@
     mapM_ cblrpmInstallMissing stillMissing
   spec <- rpmBuild pkgdata flags Binary
   arch <- cmd "arch" []
-  rpmdir <- cmd "rpm" ["--eval", "%{_rpmdir}"]
+  rpmdir <- rpmEval "%{_rpmdir}"
   rpms <- map (\ p -> rpmdir </> arch </> p <.> "rpm") . lines <$>
           cmd "rpmspec" ["-q", spec]
   -- metapkgs don't have base package
diff --git a/src/Commands/Refresh.hs b/src/Commands/Refresh.hs
--- a/src/Commands/Refresh.hs
+++ b/src/Commands/Refresh.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Commands.Refresh
--- Copyright   :  (C) 2016  Jens Petersen
+-- Copyright   :  (C) 2016-2018  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 --
@@ -19,9 +19,9 @@
 import Commands.Spec (createSpecFile)
 import FileUtils (withTempDirectory)
 import Options (RpmFlags (..))
-import PackageUtils (PackageData (..), cabal_, isGitDir, patchSpec,
-                     removePrefix)
-import SysCmd (cmd, cmd_, die, grep_, notNull, optionalProgram)
+import PackageUtils (PackageData (..), cabal_, patchSpec,
+                     removePrefix, rwGitDir)
+import SysCmd (cmd, cmd_, die, grep_, optionalProgram)
 
 #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
 #else
@@ -31,7 +31,7 @@
 import Data.List (isPrefixOf)
 import Data.Version (showVersion)
 import System.Directory (copyFile, createDirectoryIfMissing, doesFileExist,
-                         getCurrentDirectory, setCurrentDirectory)
+                         setCurrentDirectory)
 import System.Environment (getEnv)
 --import System.Exit (exitSuccess)
 import System.FilePath ((</>), (<.>))
@@ -41,11 +41,10 @@
   case specFilename pkgdata of
     Nothing -> die "No (unique) .spec file in directory."
     Just spec -> do
-      gitDir <- getCurrentDirectory >>= isGitDir
-      rwGit <- if gitDir then grep_ "url = ssh://" ".git/config" else return False
+      rwGit <- rwGitDir
       when rwGit $ do
         local <- cmd "git" ["diff"]
-        when (notNull local) $
+        unless (null local) $
           putStrLn "Working dir contain local changes!"
           -- exitSuccess
       first <- head . lines <$> readFile spec
@@ -54,25 +53,28 @@
               if "# generated by cabal-rpm-" `isPrefixOf` first
               then removePrefix "# generated by cabal-rpm-" first
               else "0.9.11"
-        when (cblrpmver == showVersion version) $
-          error "Packaging is up to date"
-        oldspec <- createOldSpec cblrpmver spec
-        newspec <- createSpecFile pkgdata flags Nothing
-        patchSpec Nothing oldspec newspec
+        if cblrpmver == showVersion version
+          then putStrLn "Packaging is up to date"
+          else do
+          subpkg <- grep_ "%{subpkgs}" spec
+          let flags' = if subpkg then flags {rpmSubpackage = True} else flags
+          oldspec <- createOldSpec subpkg cblrpmver spec
+          newspec <- createSpecFile pkgdata flags' Nothing
+          patchSpec Nothing oldspec newspec
 --          setCurrentDirectory cwd
 --          when rwGit $
---            cmd_ "git" ["commit", "-a", "-m", "update to" +-+ newver]
+--            cmd_ "git" ["commit", "-a", "-m", "refreshed to cabal-rpm-" ++ showVersion version]
   where
-    createOldSpec :: String -> FilePath -> IO FilePath
-    createOldSpec crVer spec = do
-      cblrpmVersion crVer
+    createOldSpec :: Bool -> String -> FilePath -> IO FilePath
+    createOldSpec subpkg crVer spec = do
+      cblrpmVersion subpkg crVer
       let backup = spec <.> "cblrpm"
           backup' = backup ++ "-" ++ crVer
       cmd_ "mv" [backup, backup']
       return backup'
 
-    cblrpmVersion :: String -> IO ()
-    cblrpmVersion crver = do
+    cblrpmVersion :: Bool -> String -> IO ()
+    cblrpmVersion subpkg crver = do
       let cblrpmver = "cabal-rpm-" ++ crver
       inpath <- optionalProgram cblrpmver
       if inpath
@@ -95,4 +97,4 @@
           cmd_ "strip" [bin]
           copyFile bin $ bindir </> cblrpmver
           setCurrentDirectory cwd
-        cmd_ (bindir </> cblrpmver) ["spec"]
+        cmd_ (bindir </> cblrpmver) $ ["--subpackage" | subpkg] ++ ["spec"]
diff --git a/src/Commands/RpmBuild.hs b/src/Commands/RpmBuild.hs
--- a/src/Commands/RpmBuild.hs
+++ b/src/Commands/RpmBuild.hs
@@ -1,7 +1,7 @@
 -- |
 -- Module      :  Commands.RpmBuild
 -- Copyright   :  (C) 2007-2008  Bryan O'Sullivan
---                (C) 2012-2016  Jens Petersen
+--                (C) 2012-2018  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -59,7 +59,7 @@
 
   unless (stage == BuildDep) $ do
     let version = packageVersion pkg
-    bringTarball (name ++ "-" ++ version) False
+    bringTarball (name ++ "-" ++ version) True
     rpmbuild stage False Nothing specFile
 
   return specFile
diff --git a/src/Commands/Spec.hs b/src/Commands/Spec.hs
--- a/src/Commands/Spec.hs
+++ b/src/Commands/Spec.hs
@@ -3,7 +3,7 @@
 -- |
 -- Module      :  Commands.Spec
 -- Copyright   :  (C) 2007-2008  Bryan O'Sullivan
---                (C) 2012-2016  Jens Petersen
+--                (C) 2012-2018  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -22,17 +22,13 @@
 
 import Dependencies (notInstalled, missingPackages, packageDependencies,
                      showDep, subPackages, testsuiteDependencies)
-import Distro (Distro(..), detectDistro)
+import Distro (Distro(..), defaultRelease, detectDistro)
 import Options (RpmFlags (..))
 import PackageUtils (bringTarball, getPkgName, latestPackage,
                      PackageData (..), packageName,
                      packageVersion, stripPkgDevel)
-import SysCmd ((+-+), notNull)
+import SysCmd ((+-+))
 
-#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
-#else
-import Control.Applicative ((<$>))
-#endif
 import Control.Monad    (filterM, unless, void, when, (>=>))
 import Data.Char        (toUpper)
 import Data.List        (groupBy, intercalate, intersect, isPrefixOf,
@@ -83,10 +79,6 @@
 import qualified Paths_cabal_rpm (version)
 
 
-defaultRelease :: Distro -> String
-defaultRelease distro =
-    if distro == SUSE then "0" else "1"
-
 rstrip :: (Char -> Bool) -> String -> String
 rstrip p = reverse . dropWhile p . reverse
 
@@ -203,7 +195,7 @@
   -- FIXME sort by build order
   -- FIXME recursive missingdeps
   missing <- do
-    subs <- if rpmSubpackage flags then subPackages (if specAlreadyExists then mspec else Nothing) pkgDesc else return []
+    subs <- if rpmSubpackage flags then subPackages mspec pkgDesc else return []
     miss <- if rpmSubpackage flags || rpmMissing flags then missingPackages pkgDesc else return []
     return $ nub (subs ++ miss)
   subpkgs <- if rpmSubpackage flags then
@@ -211,7 +203,7 @@
            \(m,pv) -> put ("%global" +-+ m +-+ pv) >> return ("%{" ++ m ++ "}"))
            . stripPkgDevel) missing
     else return []
-  let hasSubpkgs = notNull subpkgs
+  let hasSubpkgs = subpkgs /= []
   when hasSubpkgs $ do
     put $ "%global subpkgs" +-+ unwords subpkgs
     putNewline
@@ -223,7 +215,7 @@
   let version = packageVersion pkg
       defRelease = defaultRelease distro
       release = fromMaybe defRelease (rpmRelease flags)
-      revision = lookup "x-revision" (customFieldsPD pkgDesc)
+      revised = isJust $ lookup "x-revision" (customFieldsPD pkgDesc)
   putHdr "Name" (if binlib then "%{pkg_name}" else basename)
   putHdr "Version" version
   when hasSubpkgs $
@@ -244,8 +236,8 @@
   putHdr "Url" $ "https://hackage.haskell.org/package" </> pkg_name
   putHdr "Source0" $ sourceUrl pkgver
   mapM_ (\ (n,p) -> putHdr ("Source" ++ n) (sourceUrl p)) $ number subpkgs
-  when (isJust revision) $
-    putHdr "Source1" $ "https://hackage.haskell.org/package" </> pkgver </> pkg_name <.> "cabal" ++ "#" </> pkgver <.> "cabal"
+  when revised $
+    putHdr ("Source" ++ show (1 + length subpkgs)) $ "https://hackage.haskell.org/package" </> pkgver </> pkg_name <.> "cabal" ++ "#" </> pkgver <.> "cabal"
   case distro of
     Fedora -> return ()
     _ -> putHdr "BuildRoot" "%{_tmppath}/%{name}-%{version}-build"
@@ -311,7 +303,7 @@
       putHdr "Requires" $ (if binlib then "ghc-%{name}" else "%{name}") ++ isa +-+ "= %{version}-%{release}"
     unless (null $ clibs ++ pkgcfgs) $ do
       put "# Begin cabal-rpm deps:"
-      mapM_ (putHdr "Requires") $ sort $ map (++ isa) clibs ++ pkgcfgs ++ ["pkgconfig" | distro == SUSE, notNull pkgcfgs]
+      mapM_ (putHdr "Requires") $ sort $ map (++ isa) clibs ++ pkgcfgs ++ ["pkgconfig" | distro == SUSE, pkgcfgs /= []]
       put "# End cabal-rpm deps"
     putNewline
     put $ "%description" +-+ ghcPkgDevel
@@ -332,8 +324,8 @@
   put "%prep"
   put $ "%setup -q" ++ (if pkgname /= name then " -n" +-+ pkgver else "") +-+
     (if hasSubpkgs then unwords (map (("-a" ++) . fst) $ number subpkgs) else  "")
-  when (isJust revision) $
-    put $ "cp -p %{SOURCE1}" +-+ pkg_name <.> "cabal"
+  when revised $
+    put $ "cp -p %{SOURCE" ++ show (1 + length subpkgs) ++ "}" +-+ pkg_name <.> "cabal"
   sectionNewline
 
   put "%build"
@@ -403,7 +395,7 @@
     unless (null docs) $
       put $ "%doc" +-+ unwords docs
     mapM_ ((\ p -> put $ "%{_bindir}" </> (if p == name then "%{name}" else p)) . unUnqualComponentName) execs
-    when (notNull datafiles && not selfdep) $
+    when (datafiles /= [] && not selfdep) $
       put $ "%{_datadir}" </> pkgver
 
     sectionNewline
@@ -417,7 +409,7 @@
       mapM_ (\ l -> put $ license_macro +-+ l) licensefiles
       when (distro == SUSE && not binlib) $
         mapM_ ((\ p -> put $ "%{_bindir}" </> (if p == name then "%{pkg_name}" else p)) . unUnqualComponentName) execs
-      when (notNull datafiles && (selfdep || not binlib)) $
+      when (datafiles /= [] && (selfdep || not binlib)) $
         put $ "%{_datadir}" </> pkgver
       sectionNewline
     put $ "%files" +-+ ghcPkgDevel +-+  develFiles
@@ -523,3 +515,6 @@
 
 number :: [a] -> [(String,a)]
 number = zip (map show [(1::Int)..])
+
+notNull :: [a] -> Bool
+notNull = not . null
diff --git a/src/Commands/Update.hs b/src/Commands/Update.hs
--- a/src/Commands/Update.hs
+++ b/src/Commands/Update.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Commands.Update
--- Copyright   :  (C) 2014-2017  Jens Petersen
+-- Copyright   :  (C) 2014-2018  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -17,13 +17,14 @@
   ) where
 
 import Commands.Spec (createSpecFile)
-import Distro (detectDistro, Distro(..))
+import Distro (defaultRelease, detectDistro, Distro(..))
 import FileUtils (withTempDirectory)
 import Options (RpmFlags (..))
-import PackageUtils (PackageData (..), bringTarball, getRevisedCabal, isGitDir,
-                     latestPackage, packageName, packageVersion, patchSpec,
-                     prepare, removePrefix)
-import SysCmd (cmd_, die, grep_, (+-+))
+import PackageUtils (PackageData (..), bringTarball, editSpecField,
+                     getRevisedCabal, getSpecField, latestPackage, packageName,
+                     packageVersion, patchSpec, prepare, readVersion,
+                     removePrefix, removeSuffix, rwGitDir)
+import SysCmd (cmd_, die, grep_, shell, (+-+))
 #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
 #else
 import Control.Applicative ((<$>))
@@ -31,9 +32,8 @@
 import Control.Monad (unless, when)
 import Data.Maybe (isJust)
 import Distribution.PackageDescription (PackageDescription (..))
-import System.Directory (createDirectory, getCurrentDirectory,
-                         setCurrentDirectory)
-import System.FilePath ((<.>))
+import System.Directory (createDirectory, setCurrentDirectory)
+import System.FilePath ((</>), (<.>))
 
 update :: PackageData -> RpmFlags -> Maybe String -> IO ()
 update pkgdata flags mpkgver =
@@ -44,44 +44,70 @@
           pkg = package pkgDesc
           name = packageName pkg
           ver = packageVersion pkg
+          curVer = readVersion ver
           current = name ++ "-" ++ ver
           revised = isJust $ lookup "x-revision" (customFieldsPD pkgDesc)
       latest <- case mpkgver of
-                  Just pv -> return pv
-                  Nothing -> latestPackage (rpmStream flags) name
-      let updated = current /= latest
-      getRevisedCabal latest
-      unless updated $
-        putStrLn $ current +-+ "is already latest version."
-      when (not revised || updated) $ do
-        gitDir <- getCurrentDirectory >>= isGitDir
-        rwGit <- if gitDir then grep_ "url = ssh://" ".git/config" else return False
-        when updated $ do
-          bringTarball latest False
-          when rwGit $
-            cmd_ "fedpkg" ["new-sources", latest <.> "tar.gz"]
-        withTempDirectory $ \cwd -> do
-          curspec <- createSpecVersion current spec revised
-          newspec <- createSpecVersion latest spec True
-          patchSpec (Just cwd) curspec newspec
-          setCurrentDirectory cwd
-          distro <- maybe detectDistro return (rpmDistribution flags)
-          let suffix = if distro == SUSE then "" else "%{?dist}"
-          subpkg <- grep_ "%{subpkgs}" spec
-          unless (subpkg || rpmSubpackage flags || not updated) $
-            cmd_ "sed" ["-i", "-e s/^\\(Release:        \\).*/\\10" ++ suffix ++ "/", spec]
-          when updated $ do
-            let newver = removePrefix (name ++ "-") latest
-            if distro == SUSE
-              then cmd_ "sed" ["-i", "-e s/^\\(Version:        \\).*/\\1" ++ newver ++ "/", spec]
-              else cmd_ "rpmdev-bumpspec" ["-c", "update to" +-+ newver, spec]
-            when rwGit $
-              cmd_ "git" ["commit", "-a", "-m", "update to" +-+ newver]
+                    Just pv -> return pv
+                    Nothing -> latestPackage (rpmStream flags) name
+      let newver = removePrefix (name ++ "-") latest
+      let latestVer = readVersion newver
+          updated = latestVer > curVer
+      if latestVer < curVer
+        then putStrLn $ "current" +-+ ver +-+ "is newer!"
+        else do
+        getRevisedCabal latest
+        unless updated $
+          putStrLn "Package is already latest version."
+        when (not revised || updated) $ do
+          rwGit <- rwGitDir
+          when updated $
+            bringTarball latest False
+          withTempDirectory $ \cwd -> do
+            let specfile = cwd </> spec
+            subpkg <- grep_ "%{subpkgs}" specfile
+            (curspec, _) <- createSpecVersion current specfile revised subpkg
+            (newspec, newrevised) <- createSpecVersion latest specfile True subpkg
+            distro <- maybe detectDistro return (rpmDistribution flags)
+            let suffix = if distro == SUSE then "" else "%{?dist}"
+                defrelease = defaultRelease distro
+            currel <- removeSuffix suffix <$> getSpecField "Release" specfile
+            editSpecField "Release" (defrelease ++ suffix) specfile
+            patchSpec (Just cwd) curspec newspec
+            ver' <- getSpecField "Version" specfile
+            when (ver' /= newver) $
+              editSpecField "Version" newver specfile
+            if updated && not subpkg
+              then editSpecField "Release" (defrelease ++ suffix) specfile
+              else editSpecField "Release" (currel ++ suffix) specfile
+            when updated $ do
+              when (distro /= SUSE) $ do
+                -- FIXME reset when all subpkgs updated
+                unless subpkg $
+                  editSpecField "Release" ("0" ++ suffix) specfile
+                cmd_ "rpmdev-bumpspec" ["-c", "update to" +-+ newver, specfile]
+              when rwGit $ do
+                setCurrentDirectory cwd
+                when subpkg $ do
+                  cmd_ "cp" ["-p", "sources", "sources.cblrpm"]
+                  cmd_ "sed" ["-i", "/" ++ current <.> "tar.gz" ++ "/d", "sources.cblrpm"]
+                cmd_ "fedpkg" ["new-sources", latest <.> "tar.gz"]
+                when subpkg $ do
+                  shell $ "cat sources >>" +-+ "sources.cblrpm"
+                  cmd_ "mv" ["-f", "sources.cblrpm", "sources"]
+                when newrevised $
+                  cmd_ "git" ["add", latest <.> "cabal"]
+                cmd_ "git" ["commit", "-a", "-m", "update to" +-+ newver]
   where
-    createSpecVersion :: String -> String -> Bool -> IO FilePath
-    createSpecVersion pkgver spec revise = do
-      pkgdata' <- prepare flags (Just pkgver) revise
-      let pkgdata'' = pkgdata' { specFilename = Just spec }
+    createSpecVersion :: String -> String -> Bool -> Bool -> IO (FilePath, Bool)
+    createSpecVersion pkgver spec revise subpkg = do
+      let flags' = flags { rpmSubpackage = subpkg }
+      pd <- prepare flags' (Just pkgver) revise
+      let pkgdata' = pd { specFilename = Just spec }
           dir = pkgver <.> if revise then "" else "orig"
       createDirectory dir
-      createSpecFile pkgdata'' flags (Just dir)
+      newspec <- createSpecFile pkgdata' flags' (Just dir)
+      let newrevised =
+            let pkgDesc = packageDesc pkgdata' in
+              isJust $ lookup "x-revision" (customFieldsPD pkgDesc)
+      return (newspec, newrevised)
diff --git a/src/Dependencies.hs b/src/Dependencies.hs
--- a/src/Dependencies.hs
+++ b/src/Dependencies.hs
@@ -2,7 +2,7 @@
 
 -- |
 -- Module      :  Dependencies
--- Copyright   :  (C) 2012-2016  Jens Petersen
+-- Copyright   :  (C) 2012-2018  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -27,7 +27,7 @@
   ) where
 
 import PackageUtils (PackageData(..), packageName, packageManager, repoquery)
-import SysCmd (cmd, cmd_, cmdBool, notNull, optionalProgram, trySystem, (+-+))
+import SysCmd (cmd, cmd_, cmdBool, optionalProgram, rpmEval, trySystem, (+-+))
 
 #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
 #else
@@ -117,8 +117,8 @@
         buildinfo = allBuildInfo pkgDesc
         tools =  nub $ map exeDepName (concatMap buildTools buildinfo)
         pkgcfgs = nub $ map pkgcfgDepName $ concatMap pkgconfigDepends buildinfo
-        clibs = concatMap extraLibs buildinfo
-    return (deps, tools, nub clibs, pkgcfgs, selfdep)
+        clibs = nub $ concatMap extraLibs buildinfo
+    return (deps, delete self tools, clibs, pkgcfgs, selfdep)
 
 data QueryBackend = Rpm | Repoquery deriving Eq
 
@@ -226,7 +226,7 @@
     putStrLn $ "Running repoquery" +-+ unwords pkgs
     repopkgs <- filter (/= "") <$> mapM (repoquery ["--qf", "%{name}"]) pkgs
     let missing' = pkgs \\ repopkgs
-    if notNull missing' && hard
+    if missing' /= [] && hard
       then error $ unwords missing' +-+ "not available."
       else do
       unless (null missing') $ do
@@ -245,8 +245,8 @@
         let args = map showPkg repopkgs
         putStrLn $ "Running:" +-+ fromMaybe "" maybeSudo +-+ pkginstaller +-+ "install" +-+ unwords args
         let exec = if hard then cmd_ else trySystem
-        fedora <- cmd "rpm" ["--eval", "%fedora"]
-        let nogpgcheck = ["--nogpgcheck" | fedora `elem` ["22", "23"]]
+        fedora <- rpmEval "%fedora"
+        let nogpgcheck = ["--nogpgcheck" | fedora `elem` []]
         exec (fromMaybe pkginstaller maybeSudo) $ maybe [] (const [pkginstaller]) maybeSudo ++ ("install" : args ++ nogpgcheck)
           where
             showPkg :: String -> String
diff --git a/src/Distro.hs b/src/Distro.hs
--- a/src/Distro.hs
+++ b/src/Distro.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Distro
--- Copyright   :  (C) 2016  Jens Petersen
+-- Copyright   :  (C) 2016, 2018  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 --
@@ -11,11 +11,13 @@
 -- the Free Software Foundation, either version 3 of the License, or
 -- (at your option) any later version.
 
-module Distro (
-    detectDistro, parseDistroName, readDistroName, Distro(..)
-  ) where
+module Distro (defaultRelease,
+               detectDistro,
+               parseDistroName,
+               readDistroName,
+               Distro(..)) where
 
-import SysCmd (cmd)
+import SysCmd (rpmEval)
 import Data.Maybe (fromMaybe)
 import Data.Char (toLower)
 
@@ -23,9 +25,9 @@
 
 detectDistro :: IO Distro
 detectDistro = do
-  suseVersion <- cmd "rpm" ["--eval", "%{?suse_version}"]
+  suseVersion <- rpmEval "%{?suse_version}"
   if null suseVersion then do
-    dist <- cmd "rpm" ["--eval", "%{?dist}"]
+    dist <- rpmEval "%{?dist}"
     -- RHEL5 does not have macros.dist
     return $ if null dist || dist == ".el5" then RHEL5 else Fedora
     else return SUSE
@@ -40,3 +42,7 @@
 
 readDistroName :: String -> Distro
 readDistroName s = fromMaybe (error $ "unrecognized distribution name " ++ show s) (parseDistroName s)
+
+defaultRelease :: Distro -> String
+defaultRelease distro =
+    if distro == SUSE then "0" else "1"
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -1,7 +1,7 @@
 -- |
 -- Module      :  Main
 -- Copyright   :  (C) 2007  Bryan O'Sullivan
---                (C) 2012-2017  Jens Petersen
+--                (C) 2012-2018  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -32,7 +32,7 @@
 main :: IO ()
 main = do
   (opts, cmd, mpkg) <- getArgs >>= parseArgs
-  pkgdata <- prepare opts mpkg False
+  pkgdata <- prepare opts mpkg True
   case cmd of
     "spec"        -> createSpecFile_ pkgdata opts Nothing
     "srpm"        -> rpmBuild_ pkgdata opts Source
diff --git a/src/Options.hs b/src/Options.hs
--- a/src/Options.hs
+++ b/src/Options.hs
@@ -1,7 +1,7 @@
 -- |
 -- Module      :  Options
 -- Copyright   :  (C) 2007-2008  Bryan O'Sullivan
---                (C) 2012-2016  Jens Petersen
+--                (C) 2012-2018  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -56,7 +56,7 @@
     , rpmBinary              :: Bool
     , rpmStrict              :: Bool
     , rpmSubpackage          :: Bool
-    , rpmStream              :: Maybe String
+    , rpmStream              :: String
     , rpmMissing             :: Bool
     , rpmRelease             :: Maybe String
     , rpmCompilerId          :: Maybe CompilerId
@@ -74,7 +74,7 @@
     , rpmBinary = False
     , rpmStrict = False
     , rpmSubpackage = False
-    , rpmStream = Nothing
+    , rpmStream = "lts"
     , rpmMissing = False
     , rpmRelease = Nothing
     , rpmCompilerId = Nothing
@@ -94,7 +94,7 @@
     "Force Haskell package name to be base package name"
   , Option "" ["force"] (NoArg (\x -> x { rpmForce = True }))
     "Overwrite existing spec file."
-  , Option "s" ["stream"] (ReqArg (\s x -> x { rpmStream = Just s }) "STREAM")
+  , Option "s" ["stream"] (ReqArg (\s x -> x { rpmStream = s }) "STREAM")
     "Stackage stream (default 'lts') or 'hackage' used to get package version."
   , Option "" ["missing"] (NoArg (\x -> x { rpmMissing = True }))
     "Comment out missing BuildRequires packages."
diff --git a/src/PackageUtils.hs b/src/PackageUtils.hs
--- a/src/PackageUtils.hs
+++ b/src/PackageUtils.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  PackageUtils
--- Copyright   :  (C) 2013-2017  Jens Petersen
+-- Copyright   :  (C) 2013-2018  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -16,9 +16,10 @@
 module PackageUtils (
   bringTarball,
   cabal_,
+  editSpecField,
   getRevisedCabal,
   getPkgName,
-  isGitDir,
+  getSpecField,
   latestPackage,
   nameVersion,
   PackageData (..),
@@ -27,20 +28,22 @@
   packageVersion,
   patchSpec,
   prepare,
+  readVersion,
   removePrefix,
   removeSuffix,
   repoquery,
   rpmbuild,
   rpmInstall,
   RpmStage (..),
+  rwGitDir,
   stripPkgDevel
   ) where
 
 import FileUtils (filesWithExtension, fileWithExtension,
                   getDirectoryContents_, mktempdir, withTempDirectory)
 import Options (RpmFlags (..))
-import SysCmd (cmd, cmd_, cmdIgnoreErr, cmdSilent, die, (+-+),
-               grep_, optionalProgram, requireProgram, sudo)
+import SysCmd (cmd, cmd_, cmdIgnoreErr, cmdSilent, die, egrep_, grep_,
+               optionalProgram, requireProgram, rpmEval, sudo, (+-+))
 
 import Stackage (latestStackage)
 
@@ -51,8 +54,16 @@
 import Control.Monad    (filterM, unless, when)
 
 import Data.Char (isDigit, toLower)
-import Data.List (isPrefixOf, isSuffixOf, sort, stripPrefix)
+import Data.List (groupBy, isPrefixOf, isSuffixOf, sort, stripPrefix)
 import Data.Maybe (fromMaybe, isJust)
+import Data.Version (
+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
+                     Version,
+                     makeVersion
+#else
+                     Version(..)
+#endif
+                    )
 
 import Distribution.Compiler
 import Distribution.Package  (PackageIdentifier (..),
@@ -131,10 +142,10 @@
 
 stripVersion :: String -> String
 stripVersion n | '-' `notElem` n = n
-stripVersion nv = if hasVer then reverse mEman else nv
+stripVersion nv = if hasVer then reverse emaN else nv
   where
-    (mRev, '-':mEman) = break (== '-') $ reverse nv
-    hasVer = all (\c -> isDigit c || c == '.') mRev
+    (reV, '-':emaN) = break (== '-') $ reverse nv
+    hasVer = all (\c -> isDigit c || c == '.') reV
 
 simplePackageDescription :: FilePath -> RpmFlags
                          -> IO (PackageDescription, [FilePath], [FilePath])
@@ -191,11 +202,11 @@
 #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,20,0)
         licenseFiles pkgDesc
 #else
-        if null (licenseFile pkgDesc) then [] else [licenseFile pkgDesc]
+        [licenseFile pkgDesc | licenseFile pkgDesc /= ""]
 #endif
       docfiles = if null licenses then docs else filter (`notElem` licenses) docs
   return (docfiles, licenses)
-  where names = ["author", "changelog", "changes", "contributors", "copying", "doc",
+  where names = ["author", "changelog", "changes", "contributors", "copying",
                  "example", "licence", "license", "news", "readme", "todo"]
         likely name = let lowerName = map toLower name
                       in any (`isPrefixOf` lowerName) names
@@ -233,8 +244,16 @@
 bringTarball nv revise = do
   srcdir <- getSourceDir
   fExists <- doesFileExist $ srcdir </> tarfile
-  unless fExists $
-    copyTarball False srcdir
+  unless fExists $ do
+    pkggit <- egrep_ "\\(pkgs\\|src\\)." ".git/config"
+    if pkggit
+      then do
+      srcnv <- grep_ tarfile "sources"
+      if srcnv
+        then cmd_ "fedpkg" ["sources"]
+        else copyTarball False srcdir
+      else copyTarball False srcdir
+    -- FIXME could also use "spectool -g -S NAME.spec"
  where
   tarfile = nv <.> "tar.gz"
 
@@ -274,7 +293,7 @@
 getSourceDir = do
     cwd <- getCurrentDirectory
     git <- isGitDir cwd
-    if git then return cwd else cmd "rpm" ["--eval", "%{_sourcedir}"]
+    if git then return cwd else rpmEval "%{_sourcedir}"
 
 getRevisedCabal :: String -> IO ()
 getRevisedCabal nv = do
@@ -306,11 +325,9 @@
         BuildDep -> "_"
   cwd <- getCurrentDirectory
   gitDir <- isGitDir cwd
-  let rpmdirs_override = if gitDir
-                         then ["--define=_rpmdir" +-+ cwd,
-                               "--define=_srcrpmdir" +-+ cwd,
-                               "--define=_sourcedir" +-+ cwd]
-                         else []
+  let rpmdirs_override =
+        [ "--define="++ mcr +-+ cwd |
+          mcr <- ["_rpmdir", "_srcrpmdir", "_sourcedir"], gitDir]
   command "rpmbuild" $ ["-b" ++ rpmCmd] ++
     ["--nodeps" | mode == Prep] ++
     ["--define=_builddir" +-+ maybe cwd (cwd </>) moutdir | isJust moutdir] ++
@@ -365,10 +382,10 @@
     setCurrentDirectory cwd
     return (tmpdir </> pth, Just tmpdir)
 
-latestPackage :: Maybe String -> String -> IO String
-latestPackage (Just "hackage") pkg = latestHackage pkg
-latestPackage mstr pkg = do
-  stk <- latestStackage mstr pkg
+latestPackage :: String -> String -> IO String
+latestPackage "hackage" pkg = latestHackage pkg
+latestPackage str pkg = do
+  stk <- latestStackage str pkg
   case stk of
     Just pv -> return pv
     Nothing -> latestHackage pkg
@@ -404,6 +421,11 @@
 isGitDir :: FilePath -> IO Bool
 isGitDir dir = doesDirectoryExist (dir </> ".git")
 
+rwGitDir :: IO Bool
+rwGitDir = do
+  gitDir <- getCurrentDirectory >>= isGitDir
+  if gitDir then grep_ "url = ssh://" ".git/config" else return False
+
 getPkgName :: Maybe FilePath -> PackageDescription -> Bool -> IO (String, Bool)
 getPkgName (Just spec) pkgDesc binary = do
   let name = packageName $ package pkgDesc
@@ -502,7 +524,7 @@
   out <- cmdIgnoreErr "patch" opts diff
   putStrLn out
   where
-    opts = maybe [] (\ d -> ["-d", d, "-p1" ]) mdir
+    opts = ["--fuzz=1"] ++ ["-p1" | '/' `elem` newspec] ++ maybe [] (\ d -> ["-d", d]) mdir
 
 packageManager :: IO String
 packageManager = do
@@ -522,3 +544,26 @@
   pkginstaller <- packageManager
   let (inst, arg) = if pkginstaller == "dnf" then ("dnf", "install") else ("yum", "localinstall")
   sudo inst $ ["-y", arg] ++ rpms
+
+editSpecField :: String -> String -> FilePath -> IO ()
+editSpecField field new spec =
+  cmd_ "sed" ["-i", "-e s/^\\(" ++ field ++ ":\\s\\+\\).*/\\1" ++ new ++ "/", spec]
+
+getSpecField :: String -> FilePath -> IO String
+getSpecField field spec =
+  cmd "sed" ["-n", "-e s/^" ++ field ++ ":\\s\\+\\(\\S\\+\\)/\\1/p", spec]
+
+readVersion :: String -> Version
+readVersion = makeVersion . parseVer
+  where
+    parseVer :: String -> [Int]
+    parseVer cs =
+      let vs = filter (/= ".") $ groupBy (\ c c' -> c /= '.' && c' /= '.') cs
+      in map read vs
+
+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
+#else
+    -- from Data.Version
+    makeVersion :: [Int] -> Version
+    makeVersion b = Version b []
+#endif
diff --git a/src/Stackage.hs b/src/Stackage.hs
--- a/src/Stackage.hs
+++ b/src/Stackage.hs
@@ -2,7 +2,7 @@
 
 -- |
 -- Module      :  Stackage
--- Copyright   :  (C) 2017  Jens Petersen
+-- Copyright   :  (C) 2017-2018  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -21,7 +21,7 @@
 
 
 import Control.Monad (when, unless)
-import Data.Maybe (isJust, fromJust, fromMaybe)
+import Data.Maybe (isJust, fromJust)
 import Data.List (isPrefixOf)
 
 #ifdef HTTPS
@@ -68,9 +68,8 @@
     return Nothing
 #endif
 
-latestStackage :: Maybe String -> String -> IO (Maybe String)
-latestStackage mstr pkg = do
-  let stream = fromMaybe "lts" mstr
+latestStackage :: String -> String -> IO (Maybe String)
+latestStackage stream pkg = do
   unless (any (`isPrefixOf` stream) ["nightly", "lts"]) $
     putStrLn $ "Unknown Stackage stream:" +-+ stream
   mpkg <- stackageList stream pkg
diff --git a/src/SysCmd.hs b/src/SysCmd.hs
--- a/src/SysCmd.hs
+++ b/src/SysCmd.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  SysCmd
--- Copyright   :  (C) 2013-2016  Jens Petersen
+-- Copyright   :  (C) 2013-2018  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -23,10 +23,11 @@
   cmdQuiet,
   cmdSilent,
   die,
+  egrep_,
   grep_,
-  notNull,
   optionalProgram,
   requireProgram,
+  rpmEval,
   trySystem,
   shell,
   sudo,
@@ -156,6 +157,10 @@
 grep_ pat file =
   cmdBool "grep" ["-q", pat, file]
 
+egrep_ :: String -> FilePath -> IO Bool
+egrep_ pat file =
+  cmdBool "grep" ["-q", "-e", pat, file]
+
 removeTrailingNewline :: String -> String
 removeTrailingNewline "" = ""
 removeTrailingNewline str =
@@ -171,9 +176,6 @@
         | head t == ' ' = s ++ t
 s +-+ t = s ++ " " ++ t
 
-#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
-notNull :: Foldable t => t a -> Bool
-#else
-notNull :: [a] -> Bool
-#endif
-notNull = not . null
+rpmEval :: String -> IO String
+rpmEval s =
+  cmd "rpm" ["--eval", s]
