diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+* 0.13 (2019-02-18)
+- improve license and doc filtering
+- backup revised .cabal files
+- fallback to spectool for source downloading
+- drop selfdep
+- common subpackage for binlib data files
+- section dividers for sources, setup, build, install, and files
+- only run "cabal update" if more than 10min old
+- drop support for ghc-7.4.2
+
 * 0.12.6 (2018-10-20)
 - update: remove old revised .cabal
 - convert revised .cabal file to unix format
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -8,17 +8,16 @@
 # cabal-rpm
 
 cabal-rpm is a tool for RPM packaging of Haskell Cabal-based packages.
-It interacts with yum/dnf to install build dependencies and can also act as
-a cabal-install wrapper installing dependencies packaged in Fedora before
-running "cabal install".
+Firstly it creates RPM spec files from the .cabal files of Haskell packages.
+It can also install build dependencies using dnf/yum, it prefers package
+versions from Stackage, and can build and install packages and their dependencies
+recursively as rpm packages. It can also update packages and refresh spec files.
 
 Cabal-rpm was originally created by Bryan O'Sullivan (see README.orig)
-but has since been updated to work with current Cabal and Fedora Packaging
-Guidelines replacing cabal2spec.  It is used by Fedora and OpenSuSE.
-It is licensed under the terms of the GPL version 3 (see the COPYING file).
-
-You can build from source as normal by running `cabal install`
-or via Hackage with `cabal install cabal-rpm`.
+to create spec files, and was later updated by Jens Petersen to work with current
+Cabal and Fedora Packaging Guidelines replacing cabal2spec, and extended with
+many new features.  It is used by Fedora and earlier by OpenSuSE. It is licensed
+under the terms of the GPL version 3 (see the COPYING file).
 
 ## Requirements
 cabal-rpm assumes you are using ghc-rpm-macros for Haskell RPM packaging.
@@ -30,30 +29,30 @@
 
     $ cabal install cabal-rpm
 
-## Usage
-To create a `.spec` file for a Haskell src package in the current dir:
-
-    $ cabal-rpm spec
+You can also install it with `stack install cabal-rpm`.
 
-or directly on a `.cabal` file:
+You can also build and install it from source as normal by running
+`cabal install`.
 
-    $ cabal-rpm spec path/to/mypkg.cabal
+## Usage
+To create a `.spec` file for a package:
 
-or on a package source dir:
+    $ cabal-rpm spec somepkg
 
-    $ cabal-rpm spec mypkg-0.1
+By default it will use the package version in Stackage LTS or else the latest
+version from Hackage.
 
-You can also package directly from hackage:
+You can also specify a version if you wish
 
-    $ cabal-rpm srpm somepkg
+    $ cabal-rpm spec somepkg-0.1
 
-or
+which will unpack 'somepkg-0.1' from Hackage (unless the dir already exists),
+and create a spec file for it.
 
-    $ cabal-rpm local somepkg-0.1
+cabal-rpm also works in an rpm package source directory or inside the source of
+a Haskell package:
 
-will unpack 'somepkg-0.1' from hackage
-(if the dir does not exist, otherwise it uses the existing dir),
-create a spec file for it, and build it.
+    $ cabal-rpm spec
 
 cabal-rpm creates `.spec` files in the current dir
 and if a `.spec` file already exists it will append `.cblrpm`
@@ -61,8 +60,10 @@
 
     $ cabal-rpm install [pkg][-ver]
 
-will yum/dnf install available missing dependencies and
-run "cabal install" to build the package.
+will yum/dnf install any available missing dependencies and
+build an rpm package run "cabal install" to build the package.
+Additionally it will recursively package and install missing Haskell
+dependencies.
 
     $ cabal-rpm diff
 
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.6
+Version:             0.13
 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-2018 Jens Petersen <petersen@fedoraproject.org>
+                     2012-2019 Jens Petersen <petersen@fedoraproject.org>
 Category:            Distribution
 Build-type:          Simple
 Extra-source-files:  README.md ChangeLog TODO 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.3
+Tested-with:         GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3,
+                     GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.4,
+                     GHC == 8.6.3
 
 source-repository head
   type:     git
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-2018  Jens Petersen
+-- Copyright   :  (C) 2014-2019  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -22,7 +22,7 @@
 import PackageUtils (PackageData (..), prepare, repoquery, stripPkgDevel)
 import SimpleCmd ((+-+))
 
-#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
 #else
 import Control.Applicative ((<$>))
 #endif
@@ -37,12 +37,12 @@
   let pkgDesc = packageDesc pkgdata
   case action of
     Depends -> do
-      (deps, tools, clibs, pkgcfgs, _) <- dependencies pkgDesc
+      (deps, tools, clibs, pkgcfgs) <- dependencies pkgDesc
       let clibs' = map (\ lib -> "lib" ++ lib <.> "so") clibs
       let pkgcfgs' = map (<.> "pc") pkgcfgs
       mapM_ putStrLn $ deps ++ tools ++ clibs' ++ pkgcfgs'
     Requires -> do
-      (deps, tools, clibs, pkgcfgs, _) <- packageDependencies False pkgDesc
+      (deps, tools, clibs, pkgcfgs) <- packageDependencies False pkgDesc
       mapM_ putStrLn $ sort $ deps ++ tools ++ clibs ++ pkgcfgs
     Missing -> do
       miss <- missingPackages pkgDesc >>= filterM notAvail
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-2018 Jens Petersen
+-- Copyright   :  (C) 2012-2019 Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -25,7 +25,7 @@
 import SimpleCmd.Rpm (rpmspec)
 import SysCmd (rpmEval)
 
-#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
 #else
 import Control.Applicative ((<$>))
 #endif
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-2018  Jens Petersen
+-- Copyright   :  (C) 2016-2019  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 --
@@ -25,7 +25,7 @@
 import SimpleCmd.Git (rwGitDir)
 import SysCmd (die, optionalProgram)
 
-#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
 #else
 import Control.Applicative ((<$>))
 #endif
@@ -45,7 +45,7 @@
     Just spec -> do
       rwGit <- rwGitDir
       when rwGit $ do
-        local <- cmd "git" ["diff"]
+        local <- cmd "git" ["diff"] :: IO String
         unless (null local) $
           putStrLn "Working dir contain local changes!"
           -- exitSuccess
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-2018  Jens Petersen
+--                (C) 2012-2019  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -25,14 +25,13 @@
 import Distro (Distro(..), defaultRelease, detectDistro)
 import Options (RpmFlags (..))
 import PackageUtils (bringTarball, getPkgName, latestPackage,
-                     PackageData (..), packageName,
-                     packageVersion, stripPkgDevel)
+                     PackageData (..), packageName, packageVersion,
+                     prettyShow, stripPkgDevel)
 import SimpleCmd ((+-+))
-import SysCmd (rpmMacroDefined)
 
 import Control.Monad    (filterM, unless, void, when, (>=>))
 
-#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
 #else
 import Control.Applicative ((<$>))
 #endif
@@ -43,7 +42,7 @@
 import Data.Maybe       (isJust, fromMaybe, fromJust)
 import Data.Time.Clock  (getCurrentTime)
 import Data.Time.Format (formatTime)
-import qualified Data.Version (showVersion)
+import Data.Version (showVersion)
 
 import Distribution.License  (License (..)
 #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,2,0)
@@ -67,9 +66,6 @@
 
 #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)
 import Distribution.Types.UnqualComponentName (unUnqualComponentName)
-import Distribution.Version (showVersion)
-#else
-import Data.Version (showVersion)
 #endif
 
 --import Distribution.Version (VersionRange, foldVersionRange')
@@ -110,6 +106,9 @@
       verbose = rpmVerbosity flags
       hasExec = hasExes pkgDesc
       hasLib = hasLibs pkgDesc
+      dupdocs = docs `intersect` dataFiles pkgDesc
+      datafiles = dataFiles pkgDesc \\ dupdocs
+
   (pkgname, binlib) <- getPkgName mspec pkgDesc (rpmBinary flags)
   let pkg_name = if pkgname == name then "%{name}" else "%{pkg_name}"
       basename | binlib = "%{pkg_name}"
@@ -119,10 +118,7 @@
       hasExecPkg = binlib || (hasExec && not hasLib)
   -- run commands before opening file to prevent empty file on error
   -- maybe shell commands should be in a monad or something
-  (deps, tools, clibs, pkgcfgs, hasSelfdep) <- packageDependencies (rpmStrict flags) pkgDesc
-  selfdep <- if not hasSelfdep
-             then return False
-             else not <$> rpmMacroDefined "ghc_without_dynamic"
+  (deps, tools, clibs, pkgcfgs) <- packageDependencies (rpmStrict flags) pkgDesc
   let testsuiteDeps = testsuiteDependencies pkgDesc name
 
   specAlreadyExists <- doesFileExist specFile
@@ -144,7 +140,7 @@
       ghcPkg = if binlib then "-n ghc-%{name}" else ""
       ghcPkgDevel = if binlib then "-n ghc-%{name}-devel" else "devel"
 
-  put $ "# generated by cabal-rpm-" ++ Data.Version.showVersion Paths_cabal_rpm.version
+  put $ "# generated by cabal-rpm-" ++ showVersion Paths_cabal_rpm.version
   distro <- maybe detectDistro return (rpmDistribution flags)
   if distro /= SUSE
     then put "# https://fedoraproject.org/wiki/Packaging:Haskell"
@@ -244,32 +240,39 @@
 #endif
   putHdr "License" $ (showLicense distro . licenseFromSPDX . license) pkgDesc
   putHdr "Url" $ "https://hackage.haskell.org/package" </> pkg_name
+  put "# Begin cabal-rpm sources:"
   putHdr "Source0" $ sourceUrl pkgver
   mapM_ (\ (n,p) -> putHdr ("Source" ++ n) (sourceUrl p)) $ number subpkgs
   when revised $
     putHdr ("Source" ++ show (1 + length subpkgs)) $ "https://hackage.haskell.org/package" </> pkgver </> pkg_name <.> "cabal" ++ "#" </> pkgver <.> "cabal"
+  put "# End cabal-rpm sources"
   case distro of
     Fedora -> return ()
     _ -> putHdr "BuildRoot" "%{_tmppath}/%{name}-%{version}-build"
   putNewline
+  put "# Begin cabal-rpm deps:"
   putHdr "BuildRequires" "ghc-Cabal-devel"
   putHdr "BuildRequires" $ "ghc-rpm-macros" ++ (if hasSubpkgs then "-extra" else "")
 
   let alldeps = sort $ deps ++ tools ++ clibs ++ pkgcfgs
-  let extraTestDeps = sort $ testsuiteDeps \\ deps
-  unless (null $ alldeps ++ extraTestDeps) $ do
-    put "# Begin cabal-rpm deps:"
+  let testDeps = sort $ testsuiteDeps \\ deps
+  unless (null $ alldeps ++ testDeps) $ do
     mapM_ (\ d -> (if d `elem` missing then putHdrComment else putHdr) "BuildRequires" d) alldeps
     -- for ghc < 7.8
     when (distro `notElem` [Fedora, SUSE] &&
           any (\ d -> d `elem` map showDep ["template-haskell", "hamlet"]) deps) $
       putHdr "ExclusiveArch" "%{ghc_arches_with_ghci}"
-    unless (null extraTestDeps) $ do
+    unless (null testDeps) $ do
       put "%if %{with tests}"
-      mapM_ (putHdr "BuildRequires") extraTestDeps
+      mapM_ (putHdr "BuildRequires") testDeps
       put "%endif"
-    put "# End cabal-rpm deps"
 
+  let common = binlib && datafiles /= []
+
+  when common $
+    putHdr "Requires" $ "%{name}-common = %{version}-%{release}"
+  put "# End cabal-rpm deps"
+
   putNewline
 
   put "%description"
@@ -278,6 +281,15 @@
 
   let wrapGenDesc = wordwrap (79 - max 0 (length pkgname - length pkg_name))
 
+  when common $ do
+    put "%package common"
+    putHdr "Summary" $ pkg_name +-+ "common files"
+    putHdr "BuildArch" "noarch"
+    putNewline
+    put $ "%description common"
+    put $ wrapGenDesc $ "This package provides the" +-+ pkg_name +-+ "common data files."
+    putNewline
+
   -- haskell-gi generates lib source files at configure time
   let hasModules =
         hasLib && ((notNull . exposedModules . fromJust . library) pkgDesc || "ghc-haskell-gi-devel" `elem` deps)
@@ -290,6 +302,8 @@
         SUSE -> putHdr "Group" "System/Libraries"
         RHEL5 -> putHdr "Group" "System Environment/Libraries"
         _ -> return ()
+      when common $
+        putHdr "Requires" $ "%{name}-common = %{version}-%{release}"
       putNewline
       put $ "%description" +-+ ghcPkg
       put $ wrapGenDesc $ "This package provides the Haskell" +-+ pkg_name +-+ "shared library."
@@ -333,13 +347,16 @@
     sectionNewline
 
   put "%prep"
+  put "# Begin cabal-rpm setup:"
   put $ "%setup -q" ++ (if pkgname /= name then " -n" +-+ pkgver else "") +-+
     (if hasSubpkgs then unwords (map (("-a" ++) . fst) $ number subpkgs) else  "")
   when revised $
-    put $ "cp -p %{SOURCE" ++ show (1 + length subpkgs) ++ "}" +-+ pkg_name <.> "cabal"
+    put $ "cp -bp %{SOURCE" ++ show (1 + length subpkgs) ++ "}" +-+ pkg_name <.> "cabal"
+  put "# End cabal-rpm setup"
   sectionNewline
 
   put "%build"
+  put "# Begin cabal-rpm build:"
   when hasSubpkgs $
     put "%ghc_libs_build %{subpkgs}"
   when (distro == SUSE && rpmConfigurationsFlags flags /= []) $ do
@@ -349,19 +366,15 @@
   if hasLib && not hasModules
     then put $ "%ghc_" ++ pkgType ++ "_build_without_haddock"
     else put $ "%ghc_" ++ pkgType ++ "_build"
+  put "# End cabal-rpm build"
   sectionNewline
 
   put "%install"
+  put "# Begin cabal-rpm install"
   when hasSubpkgs $
     put "%ghc_libs_install %{subpkgs}"
   put $ "%ghc_" ++ pkgType ++ "_install"
 
-  when selfdep $
-    put $ "%ghc_fix_rpath" +-+ pkgver
-
-  let ds = dataFiles pkgDesc
-      dupdocs = docs `intersect` ds
-      datafiles = ds \\ dupdocs
   unless (null dupdocs) $ do
     putNewline
     putStrLn $ "Warning: doc files found in datadir:" +-+ unwords dupdocs
@@ -374,9 +387,7 @@
   when (hasLib && not hasModules) $
     put "mv %{buildroot}%{_ghcdocdir}{,-devel}"
 
-  -- can really be dropped for static executables
-  when (selfdep && binlib) $
-    put "mv %{buildroot}%{_ghclicensedir}/{,ghc-}%{name}"
+  put "# End cabal-rpm install"
 
   sectionNewline
 
@@ -399,39 +410,58 @@
 
   when hasExecPkg $ do
     put "%files"
+    put "# Begin cabal-rpm files:"
     when (distro /= Fedora) $ put "%defattr(-,root,root,-)"
     -- Add the license file to the main package only if it wouldn't
     -- otherwise be empty.
-    unless (selfdep && binlib) $
+    unless common $ do
       mapM_ (\ l -> put $ license_macro +-+ l) licensefiles
-    unless (null docs) $
-      put $ "%doc" +-+ unwords docs
+      unless (null docs) $
+        put $ "%doc" +-+ unwords docs
     mapM_ ((\ p -> put $ "%{_bindir}" </> (if p == name then "%{name}" else p)) . unUnqualComponentName) execs
-    when (datafiles /= [] && not selfdep) $
+    unless (common || null datafiles) $
       put $ "%{_datadir}" </> pkgver
+    put "# End cabal-rpm files"
 
     sectionNewline
 
+  when common $ do
+    put $ "%files common"
+    put "# Begin cabal-rpm files:"
+    when (distro /= Fedora) $ put "%defattr(-,root,root,-)"
+    mapM_ (\ l -> put $ license_macro +-+ l) licensefiles
+    unless (null docs) $
+      put $ "%doc" +-+ unwords docs
+    put $ "%{_datadir}" </> pkgver
+    put "# End cabal-rpm files"
+    sectionNewline
+
   when hasLib $ do
     let baseFiles = if binlib then "-f ghc-%{name}.files" else "-f %{name}.files"
         develFiles = if binlib then "-f ghc-%{name}-devel.files" else "-f %{name}-devel.files"
     when hasModules $ do
       put $ "%files" +-+ ghcPkg +-+ baseFiles
+      put "# Begin cabal-rpm files:"
       when (distro /= Fedora) $ put "%defattr(-,root,root,-)"
-      mapM_ (\ l -> put $ license_macro +-+ l) licensefiles
+      unless common $
+        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 (datafiles /= [] && (selfdep || not binlib)) $
+      unless (common || null datafiles) $
         put $ "%{_datadir}" </> pkgver
+      put "# End cabal-rpm files"
       sectionNewline
+
     put $ "%files" +-+ ghcPkgDevel +-+  develFiles
+    -- put "# Begin cabal-rpm files:"
     when (distro /= Fedora) $ put "%defattr(-,root,root,-)"
     unless hasModules $
       mapM_ (\ l -> put $ license_macro +-+ l) licensefiles
-    unless (null docs) $
+    unless (common || null docs) $
       put $ "%doc" +-+ unwords docs
     when (distro /= SUSE && not binlib) $
       mapM_ ((\ p -> put $ "%{_bindir}" </> (if p == name then "%{pkg_name}" else p)) . unUnqualComponentName) execs
+    -- put "# End cabal-rpm files"
     sectionNewline
 
   put "%changelog"
@@ -439,7 +469,7 @@
     now <- getCurrentTime
     let date = formatTime defaultTimeLocale "%a %b %e %Y" now
     put $ "*" +-+ date +-+ "Fedora Haskell SIG <haskell@lists.fedoraproject.org> - " ++ version ++ "-" ++ release
-    put $ "- spec file generated by cabal-rpm-" ++ Data.Version.showVersion Paths_cabal_rpm.version
+    put $ "- spec file generated by cabal-rpm-" ++ showVersion Paths_cabal_rpm.version
   hClose h
   return specFile'
 
@@ -454,12 +484,12 @@
 showLicense :: Distro -> License -> String
 showLicense SUSE (GPL Nothing) = "GPL-1.0+"
 showLicense _    (GPL Nothing) = "GPL+"
-showLicense SUSE (GPL (Just ver)) = "GPL-" ++ showVersion ver ++ "+"
-showLicense _    (GPL (Just ver)) = "GPLv" ++ showVersion ver ++ "+"
+showLicense SUSE (GPL (Just ver)) = "GPL-" ++ prettyShow ver ++ "+"
+showLicense _    (GPL (Just ver)) = "GPLv" ++ prettyShow ver ++ "+"
 showLicense SUSE (LGPL Nothing) = "LGPL-2.0+"
 showLicense _    (LGPL Nothing) = "LGPLv2+"
-showLicense SUSE (LGPL (Just ver)) = "LGPL-" ++ showVersion ver ++ "+"
-showLicense _    (LGPL (Just ver)) = "LGPLv" ++ [head $ showVersion ver] ++ "+"
+showLicense SUSE (LGPL (Just ver)) = "LGPL-" ++ prettyShow ver ++ "+"
+showLicense _    (LGPL (Just ver)) = "LGPLv" ++ [head $ prettyShow ver] ++ "+"
 showLicense SUSE BSD3 = "BSD-3-Clause"
 showLicense _    BSD3 = "BSD"
 showLicense SUSE BSD4 = "BSD-4-Clause"
@@ -470,22 +500,22 @@
 showLicense SUSE AllRightsReserved = "SUSE-NonFree"
 showLicense _    AllRightsReserved = "Proprietary"
 showLicense _ OtherLicense = "Unknown"
-showLicense _ (UnknownLicense l) = "Unknown" +-+ l
+showLicense _ (UnknownLicense l) = l
 #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,16,0)
 showLicense SUSE (Apache Nothing) = "Apache-2.0"
 showLicense _    (Apache Nothing) = "ASL ?"
-showLicense SUSE (Apache (Just ver)) = "Apache-" ++ showVersion ver
-showLicense _    (Apache (Just ver)) = "ASL" +-+ showVersion ver
+showLicense SUSE (Apache (Just ver)) = "Apache-" ++ prettyShow ver
+showLicense _    (Apache (Just ver)) = "ASL" +-+ prettyShow ver
 #endif
 #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,18,0)
 showLicense _ (AGPL Nothing) = "AGPLv?"
-showLicense _ (AGPL (Just ver)) = "AGPLv" ++ showVersion ver
+showLicense _ (AGPL (Just ver)) = "AGPLv" ++ prettyShow ver
 #endif
 #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,20,0)
 showLicense SUSE BSD2 = "BSD-2-Clause"
 showLicense _ BSD2 = "BSD"
-showLicense SUSE (MPL ver) = "MPL-" ++ showVersion ver
-showLicense _ (MPL ver) = "MPLv" ++ showVersion ver
+showLicense SUSE (MPL ver) = "MPL-" ++ prettyShow ver
+showLicense _ (MPL ver) = "MPLv" ++ prettyShow ver
 #endif
 #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,22,0)
 showLicense _ ISC = "ISC"
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-2018  Jens Petersen
+-- Copyright   :  (C) 2014-2019  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -27,7 +27,7 @@
 import SimpleCmd (cmd_, grep_, shell_, (+-+))
 import SimpleCmd.Git (rwGitDir)
 import SysCmd (die)
-#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
 #else
 import Control.Applicative ((<$>))
 #endif
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-2018  Jens Petersen
+-- Copyright   :  (C) 2012-2019  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -31,7 +31,7 @@
 import SimpleCmd.Rpm (rpmspec)
 import SysCmd (optionalProgram, rpmEval, trySystem)
 
-#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
 #else
 import Control.Applicative ((<$>))
 #endif
@@ -63,7 +63,6 @@
                                         allBuildInfo,
                                         BuildInfo (..),
                                         TestSuite (..),
-                                        hasExes, 
 #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,24,0)
                                         setupDepends
 #endif
@@ -82,13 +81,12 @@
 allBuildDepends = buildDepends
 #endif
 
--- returns list of deps and whether package is self-dependent
-buildDependencies :: PackageDescription -> String -> ([String], Bool)
+-- returns list of deps
+buildDependencies :: PackageDescription -> String -> [String]
 buildDependencies pkgDesc self =
   let deps = nub $ map depName (allBuildDepends pkgDesc)
                    ++ setupDependencies pkgDesc
-  in
-    (filter excludedPkgs (delete self deps), self `elem` deps && hasExes pkgDesc)
+  in filter excludedPkgs (delete self deps)
 
 setupDependencies :: PackageDescription  -- ^pkg description
                   -> [String]         -- ^depends
@@ -126,16 +124,16 @@
 showDep p = "ghc-" ++ p ++ "-devel"
 
 dependencies :: PackageDescription  -- ^pkg description
-                -> IO ([String], [String], [String], [String], Bool)
-                -- ^depends, tools, c-libs, pkgcfg, selfdep
+                -> IO ([String], [String], [String], [String])
+                -- ^depends, tools, c-libs, pkgcfg
 dependencies pkgDesc = do
     let self = packageName $ package pkgDesc
-        (deps, selfdep) = buildDependencies pkgDesc self
+        deps = buildDependencies pkgDesc self
         buildinfo = allBuildInfo pkgDesc
         tools =  nub $ map exeDepName (concatMap buildTools buildinfo)
         pkgcfgs = nub $ map pkgcfgDepName $ concatMap pkgconfigDepends buildinfo
         clibs = nub $ concatMap extraLibs buildinfo
-    return (deps, delete self tools, clibs, pkgcfgs, selfdep)
+    return (deps, delete self tools, clibs, pkgcfgs)
 
 data QueryBackend = Rpm | Repoquery deriving Eq
 
@@ -174,17 +172,16 @@
 
 packageDependencies :: Bool   -- ^strict mode: True means abort on unknown dependencies
                 -> PackageDescription  -- ^pkg description
-                -> IO ([String], [String], [String], [String], Bool)
-                -- ^depends, tools, c-libs, pkgcfg, selfdep
+                -> IO ([String], [String], [String], [String])
+                -- ^depends, tools, c-libs, pkgcfg
 packageDependencies strict pkgDesc = do
-    (deps, tools', clibs', pkgcfgs, selfdep) <- dependencies pkgDesc
+    (deps, tools', clibs', pkgcfgs) <- dependencies pkgDesc
     let excludedTools n = n `notElem` ["ghc", "hsc2hs", "perl"]
         mapTools "gtk2hsC2hs" = "gtk2hs-buildtools"
         mapTools "gtk2hsHookGenerator" = "gtk2hs-buildtools"
         mapTools "gtk2hsTypeGen" = "gtk2hs-buildtools"
         mapTools tool = tool
-        chrpath = ["chrpath" | selfdep]
-        tools = filter excludedTools $ nub $ map mapTools tools' ++ chrpath
+        tools = filter excludedTools $ nub $ map mapTools tools'
     clibsWithErrors <- mapM resolveLib clibs'
     when (any isNothing clibsWithErrors) $
       if strict
@@ -192,7 +189,7 @@
       else putStrLn "Warning: could not resolve all clib dependencies"
     let clibs = catMaybes clibsWithErrors
     let showPkgCfg p = "pkgconfig(" ++ p ++ ")"
-    return (map showDep deps, tools, nub clibs, map showPkgCfg pkgcfgs, selfdep)
+    return (map showDep deps, tools, nub clibs, map showPkgCfg pkgcfgs)
 
 testsuiteDependencies :: PackageDescription  -- ^pkg description
                 -> String           -- ^self
@@ -202,7 +199,7 @@
 
 missingPackages :: PackageDescription -> IO [String]
 missingPackages pkgDesc = do
-  (deps, tools, clibs, pkgcfgs, _) <- packageDependencies False pkgDesc
+  (deps, tools, clibs, pkgcfgs) <- packageDependencies False pkgDesc
   pcpkgs <- mapM derefPkg pkgcfgs
   filterM notInstalled $ deps ++ ["ghc-Cabal-devel", "ghc-rpm-macros"] ++ tools ++ clibs ++ pcpkgs
 
diff --git a/src/FileUtils.hs b/src/FileUtils.hs
--- a/src/FileUtils.hs
+++ b/src/FileUtils.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  FileUtils
--- Copyright   :  (C) 2014, 2016-2017  Jens Petersen
+-- Copyright   :  (C) 2014, 2016-2019  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -25,7 +25,7 @@
 
 import SimpleCmd (cmd)
 
-#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
 #else
 import Control.Applicative ((<$>))
 #endif
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-2018  Jens Petersen
+-- Copyright   :  (C) 2013-2019  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -28,6 +28,7 @@
   packageVersion,
   patchSpec,
   prepare,
+  prettyShow,
   readVersion,
   removePrefix,
   removeSuffix,
@@ -47,15 +48,16 @@
 import SysCmd (die, optionalProgram, requireProgram, rpmEval)
 import Stackage (latestStackage)
 
-#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
 #else
 import Control.Applicative ((<$>))
 #endif
 import Control.Monad    (filterM, unless, when)
 
 import Data.Char (isDigit, toLower)
-import Data.List (groupBy, isPrefixOf, isSuffixOf, sort, stripPrefix)
+import Data.List (groupBy, isPrefixOf, isSuffixOf, nub, sort, stripPrefix)
 import Data.Maybe (fromJust, fromMaybe, isJust)
+import Data.Time.Clock (diffUTCTime, getCurrentTime)
 import Data.Version (
 #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
                      Version,
@@ -63,14 +65,16 @@
 #else
                      Version(..),
 #endif
+                    )
+
 #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)
+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,2,0)
+import Distribution.Pretty (prettyShow)
 #else
-                     showVersion
+import qualified Distribution.Version (showVersion)
 #endif
-                    )
-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)
-import Distribution.Version (showVersion)
 #else
+import qualified Data.Version (showVersion)
 #endif
 
 import Distribution.Compiler
@@ -129,15 +133,25 @@
     )
 import Distribution.System (Platform (..), buildArch, buildOS)
 
-import System.Directory (copyFile, createDirectoryIfMissing,doesDirectoryExist,
+import System.Directory (copyFile, createDirectoryIfMissing, doesDirectoryExist,
                          doesFileExist, getCurrentDirectory,
-                         getDirectoryContents, removeDirectoryRecursive,
-                         renameFile, setCurrentDirectory)
+                         getDirectoryContents, getModificationTime,
+                         removeDirectoryRecursive, renameFile,
+                         setCurrentDirectory)
 import System.Environment (getEnv)
 import System.FilePath ((</>), (<.>), dropFileName, takeBaseName, takeFileName)
 import System.Posix.Files (accessTime, fileMode, getFileStatus,
                            modificationTime, setFileMode)
 
+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,2,0)
+#else
+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)
+prettyShow = Distribution.Version.showVersion
+#else
+prettyShow = Data.Version.showVersion
+#endif
+#endif
+
 -- returns path to .cabal file and possibly tmpdir to be removed
 --findCabalFile :: Verbosity -> FilePath -> IO (FilePath, Maybe FilePath)
 --findCabalFile vb path = do
@@ -199,18 +213,20 @@
 findDocsLicenses :: FilePath -> PackageDescription -> IO ([FilePath], [FilePath])
 findDocsLicenses dir pkgDesc = do
   contents <- getDirectoryContents dir
-  let docs = sort $ filter unlikely $ filter likely contents
-  let licenses =
+  let docs = sort $ filter unlikely $ filter (likely docNames) contents
+  let licenses = sort $ nub $
 #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,20,0)
         licenseFiles pkgDesc
 #else
         [licenseFile pkgDesc | licenseFile pkgDesc /= ""]
 #endif
+        ++ filter (likely licenseNames) contents
       docfiles = if null licenses then docs else filter (`notElem` licenses) docs
   return (docfiles, licenses)
-  where names = ["author", "changelog", "changes", "contributors", "copying",
-                 "example", "licence", "license", "news", "readme", "todo"]
-        likely name = let lowerName = map toLower name
+  where docNames = ["author", "changelog", "changes", "contributors",
+                    "example", "news", "readme", "todo"]
+        licenseNames = ["copying", "licence", "license"]
+        likely names name = let lowerName = map toLower name
                       in any (`isPrefixOf` lowerName) names
         unlikely name = not $ any (`isSuffixOf` name) ["~", ".cabal"]
 
@@ -257,12 +273,14 @@
       when srcnv $
         cmd_ "fedpkg" ["sources"]
     when havespec $
-      cmd_ "spectool" ["-g", "-S", "-C", srcdir, spec]
-    -- why not versioned?
+      createDirectoryIfMissing True srcdir
     haveLocalCabal <- doesFileExist $ srcdir </> nv <.> "cabal"
+    mapM_ (copyTarball False srcdir) sources
     when (not haveLocalCabal && revise) $
       getRevisedCabal nv
-    mapM_ (copyTarball False srcdir) sources
+    allExist' <- and <$> mapM (doesFileExist . (srcdir </>)) sources
+    unless allExist' $
+      cmd_ "spectool" ["-g", "-S", "-C", srcdir, spec]
  where
   tarfile = nv <.> "tar.gz"
 
@@ -277,8 +295,8 @@
   copyTarball ranFetch dir file = do
     let dest = dir </> file
     already <- doesFileExist dest
-    home <- getEnv "HOME"
     unless already $ do
+      home <- getEnv "HOME"
       let cacheparent = home </> ".cabal" </> "packages"
       havecache <- doesDirectoryExist cacheparent
       unless havecache cabalUpdate
@@ -364,7 +382,23 @@
 stripPkgDevel = removeSuffix "-devel" . removePrefix "ghc-"
 
 cabalUpdate :: IO ()
-cabalUpdate = cmd_ "cabal" ["update"]
+cabalUpdate = do
+  home <- getEnv "HOME"
+  let dir = home </> ".cabal/packages/hackage.haskell.org"
+  done <- checkTimestamp $ dir </> "01-index.timestamp"
+  unless done $ do
+    done' <- checkTimestamp $ dir </> "00-index.cache"
+    unless done' $ cmd_ "cabal" ["update"]
+  where
+    checkTimestamp tsfile = do
+      haveFile <- doesFileExist tsfile
+      if haveFile then do
+        ts <- getModificationTime tsfile
+        t <- getCurrentTime
+        when (diffUTCTime t ts > 600) $ cmd_ "cabal" ["update"]
+        return True
+        else
+        return False
 
 cabal :: String -> [String] -> IO [String]
 cabal c args = do
@@ -426,7 +460,7 @@
 packageName = unPackageName . pkgName
 
 packageVersion :: PackageIdentifier -> String
-packageVersion = showVersion . pkgVersion
+packageVersion = prettyShow . pkgVersion
 
 getPkgName :: Maybe FilePath -> PackageDescription -> Bool -> IO (String, Bool)
 getPkgName (Just spec) pkgDesc binary = do
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-2018  Jens Petersen
+-- Copyright   :  (C) 2017-2019  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -32,7 +32,7 @@
 import System.FilePath (takeFileName)
 import SimpleCmd ((+-+))
 #else
-#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
 #else
 import Control.Applicative ((<$>))
 #endif
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-2018  Jens Petersen
+-- Copyright   :  (C) 2013-2019  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
 -- Stability   :  alpha
@@ -22,7 +22,7 @@
   rpmMacroDefined,
   trySystem) where
 
-#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))
+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
 #else
 import Control.Applicative ((<$>))
 #endif
@@ -30,18 +30,16 @@
 import Data.Maybe       (isJust, isNothing)
 
 #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,18,0)
-import Distribution.Simple.Program.Find (defaultProgramSearchPath,
-                                         findProgramOnSearchPath)
 #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)
 import Distribution.Simple.Utils (dieNoVerbosity)
 #else
 import Distribution.Simple.Utils (die)
 #endif
 #else
-import Distribution.Simple.Utils (die, findProgramLocation)
+import Distribution.Simple.Utils (die)
 #endif
-import Distribution.Verbosity (normal)
 
+import System.Directory (findExecutable)
 import System.Process (rawSystem)
 
 import SimpleCmd (cmd)
@@ -51,25 +49,14 @@
 die = dieNoVerbosity
 #endif
 
-findProgram :: FilePath -> IO (Maybe FilePath)
-findProgram =
-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,18,0)
-  \ prog -> findProgramOnSearchPath normal defaultProgramSearchPath prog
-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,23,0)
-    >>= return . fmap fst
-#endif
-#else
-  findProgramLocation normal
-#endif
-
 requireProgram :: String -> IO ()
 requireProgram c = do
-  mavail <- findProgram c
+  mavail <- findExecutable c
   when (isNothing mavail) $ die (c ++ ": command not found")
 
 optionalProgram :: String -> IO Bool
 optionalProgram c =
-  isJust <$> findProgram c
+  isJust <$> findExecutable c
 
 trySystem :: String -> [String] -> IO ()
 trySystem c args = do
