diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+# 2.0.5 (2020-06-10)
+- spec --tests flag to force enabling testsuite
+- spec: fix permissions of extra-source-files
+- update url for Fedora Haskell Packaging Guidelines (TristanCacqueray)
+- make cabal update silent and check for 01-index
+- support Cabal-3.2 ShortText (hekkaidekapus)
+- use simple-cmd-args 0.1.6 for working subcommand help
+- improve handling of update --stream for subpackaging
+- default to Stackage LTS 15
+
 # 2.0.4 (2020-02-27) Fedora 32
 - update: also unbreak patching
 
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -4,9 +4,13 @@
 	pandoc -s -t man $< > $@
 
 stack-all:
+	stack --resolver nightly --stack-yaml stack-ghc810.yaml build
+	@echo
 	stack --resolver nightly build
 	@echo
 	stack --resolver lts build
+	@echo
+	stack --resolver lts-15 build
 	@echo
 	stack --resolver lts-14 build
 	@echo
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -81,9 +81,6 @@
 ## Development
 The latest source code is available from: https://github.com/juhp/cabal-rpm
 
-There is an Freenode irc channel #haskell-rpm for rpm distro packaging
-discussion.
-
 ## Plans
 More features are planned and patches welcome.
 See the [TODO](TODO) file for more details.
diff --git a/TODO b/TODO
--- a/TODO
+++ b/TODO
@@ -1,5 +1,11 @@
+- read cabal-tweak-flag for correct deps
+- spec: use user's email
+- spec --force does not work (file busy)
+- use tmp workspace for duration of executation to reference prep(are) etc
+- guess user email address
+- lts downgrades for older branches
 - support internal libs: eg dns-internal
-- fix lts package version check to ignore old snapshot results
+- fix lts package version check to ignore old snapshot results (eg old nightly)
 - diff misses flags in subpackages: eg skylighting-core
 - cabal-tweak-drop-dep "ignored" by update etc
 - switch to v2 commands
@@ -11,6 +17,8 @@
 - changelog for subpkg bumps
 - update --stream should add --stream to header
 - cleanup .Cblrpm
+- update/diff should remove dropped subpackages
+- check krb5 ticket before attempting source upload
 
 - --without-tests/--disable-tests/--no-tests (also for install etc)
   - or default to no tests and explicitly enable with --tests
@@ -40,7 +48,6 @@
 
 - detect dropped subpkgs (eg here dropped in hledger-1.14.2)
 
-- check/warn about executable doc files!
 - add rpmlint command
 
 - only "cabal update" when needed
@@ -92,7 +99,7 @@
 ## update
 - warm about new missing deps
 - reverse deps and rebuilds
-? update subpkg sources
+- update subpkg sources
 - depsort sources
 
 ## depends
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:             2.0.4
+Version:             2.0.5
 Synopsis:            RPM packaging tool for Haskell Cabal-based packages
 Description:
     This package provides a RPM packaging tool for Haskell Cabal-based packages.
@@ -23,10 +23,10 @@
 Category:            Distribution
 Build-type:          Simple
 Extra-source-files:  ChangeLog Makefile README.md TODO man/cabal-rpm.1.md
-Cabal-version:       >=1.6
+Cabal-version:       >=1.10
 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.5, GHC == 8.8.2
+                     GHC == 8.6.5, GHC == 8.8.3, GHC == 8.10.1
 
 source-repository head
   type:     git
@@ -43,14 +43,14 @@
 Executable cabal-rpm
     Main-is:            Main.hs
     Build-depends: base < 5,
-                   Cabal > 1.10,
+                   Cabal > 1.10 && < 3.3,
                    directory,
                    filepath,
                    optparse-applicative,
                    process,
                    simple-cabal >= 0.1.0,
                    simple-cmd >= 0.2.0,
-                   simple-cmd-args >= 0.1.2,
+                   simple-cmd-args >= 0.1.6,
                    unix
     if flag(old-locale)
        Build-Depends: old-locale >= 1 && < 1.1,
@@ -67,6 +67,7 @@
     else
        Build-Depends: curl
        Cpp-options: -DCURL
+    Default-Language:    Haskell2010
     Other-modules:
                   Commands.BuildDep,
                   Commands.Depends,
diff --git a/src/Commands/Depends.hs b/src/Commands/Depends.hs
--- a/src/Commands/Depends.hs
+++ b/src/Commands/Depends.hs
@@ -20,7 +20,8 @@
     ) where
 
 import Dependencies (dependencies, hsDep, missingPackages, notAvail,
-                     packageDependencies, recurseMissing, showDep)
+                     PackageDependencies(..), packageDependencies,
+                     recurseMissing, showDep)
 import PackageUtils (PackageData (..), prepare)
 import Types
 
@@ -47,8 +48,8 @@
           pkgcfgs' = map (<.> "pc") pkgcfgs
       mapM_ putStrLn $ map display (nub (deps ++ setup)) ++ tools ++ clibs' ++ pkgcfgs'
     Requires -> do
-      (deps, setup, tools, clibs, pkgcfgs) <- packageDependencies pkgDesc
-      mapM_ putStrLn $ sort . nub  $ map (showRpm . RpmHsLib Devel) (deps ++ setup) ++ tools ++ clibs ++ pkgcfgs
+      pkgdeps <- packageDependencies pkgDesc
+      mapM_ putStrLn $ sort . nub  $ map (showRpm . RpmHsLib Devel) (buildDeps pkgdeps ++ setupDeps pkgdeps) ++ toolDeps pkgdeps ++ clibDeps pkgdeps ++ pkgcfgDeps pkgdeps
     Missing -> do
       missing <- missingPackages pkgDesc >>= filterM notAvail
       mapM_ (putStrLn . showDep) missing
diff --git a/src/Commands/Diff.hs b/src/Commands/Diff.hs
--- a/src/Commands/Diff.hs
+++ b/src/Commands/Diff.hs
@@ -44,14 +44,14 @@
     Just spec -> do
       subpkg <- grep_ "%{subpkgs}" spec
       tmpdir <- mktempdir
-      speccblrpm <- createSpecFile silent flags False pkgtype subpkg (Just tmpdir) mpvs
+      speccblrpm <- createSpecFile silent flags False False pkgtype (if subpkg then Just Nothing else Nothing) (Just tmpdir) mpvs
       diffcmd <- words <$> getEnvDefault "CBLRPM_DIFF" "diff -u"
-      hsp <- optionalProgram "hsp"
-      if hsp
+      hawk <- optionalProgram "hawk"
+      if hawk
         then
         pipe3_ (head diffcmd, tail diffcmd ++ [spec, speccblrpm])
           ("sed", ["-e", "s%" ++ speccblrpm ++ "%" ++ spec <.> "cblrpm" ++ "%"])
-          ("hsp", ["takeWhile (not . (\"%changelog\" `T.isSuffixOf`) . getText) pp | p"])
+          ("hawk", ["-d''", "-a", "takeWhile (/= [\"%changelog\"])"])
         else
         pipe_ (head diffcmd, tail diffcmd ++ [spec, speccblrpm])
         ("sed", ["-e", "s%" ++ speccblrpm ++ "%" ++ spec <.> "cblrpm" ++ "%"])
diff --git a/src/Commands/Refresh.hs b/src/Commands/Refresh.hs
--- a/src/Commands/Refresh.hs
+++ b/src/Commands/Refresh.hs
@@ -65,7 +65,7 @@
                   _ -> pkgtype
           subpkg <- grep_ "%{subpkgs}" spec
           oldspec <- createOldSpec subpkg cblrpmver spec
-          newspec <- createSpecFile silent [] False spectype subpkg Nothing mpvs
+          newspec <- createSpecFile silent [] False False spectype (if subpkg then Just Nothing else Nothing) Nothing mpvs
           patchSpec dryrun Nothing oldspec newspec
 --          setCurrentDirectory cwd
 --          when rwGit $
diff --git a/src/Commands/RpmBuild.hs b/src/Commands/RpmBuild.hs
--- a/src/Commands/RpmBuild.hs
+++ b/src/Commands/RpmBuild.hs
@@ -45,7 +45,7 @@
     void $ pkgInstallMissing' pkgdata
   let pkgDesc = packageDesc pkgdata
       mspec = specFilename pkgdata
-  specFile <- maybe (createSpecFile normal flags False pkgtype subpackage Nothing mpvs)
+  specFile <- maybe (createSpecFile normal flags False False pkgtype (if subpackage then Just Nothing else Nothing) Nothing mpvs)
               (\ s -> putStrLn ("Using existing" +-+ s) >> return s)
               mspec
   let pkgid = package pkgDesc
diff --git a/src/Commands/Spec.hs b/src/Commands/Spec.hs
--- a/src/Commands/Spec.hs
+++ b/src/Commands/Spec.hs
@@ -22,21 +22,21 @@
 
 import Dependencies (missingLibraries,
                      missingOtherPkgs, notSrcOrInst, packageDeps,
-                     packageDependencies, pkgSuffix,
+                     PackageDependencies(..), packageDependencies, pkgSuffix,
                      subPackages, testsuiteDependencies')
 import Header (headerOption, withSpecHead)
 import PackageUtils (bringTarball, latestPackage, PackageData (..), prepare)
 import SimpleCabal (buildable, mkPackageName, PackageDescription (..),
                     PackageIdentifier(..), PackageName, showVersion)
-import SimpleCmd ((+-+), grep_, removePrefix)
+import SimpleCmd ((+-+), grep, grep_, removePrefix)
 import Stackage (defaultLTS)
 import Types
 
-import Control.Monad    (filterM, unless, void, when, (>=>))
+import Control.Monad    (filterM, forM_, unless, void, when, (>=>))
 
 #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
 #else
---import Control.Applicative ((<$>))
+import Control.Applicative ((<$>))
 #endif
 
 import Data.Char        (toUpper)
@@ -69,7 +69,7 @@
 #endif
 import Distribution.Verbosity (Verbosity)
 
-import System.Directory (doesFileExist)
+import System.Directory (doesDirectoryExist, doesFileExist, executable, getPermissions)
 import System.IO     (IOMode (..), hClose, hPutStrLn, openFile)
 #if defined(MIN_VERSION_time) && MIN_VERSION_time(1,5,0)
 import Data.Time.Format (defaultTimeLocale)
@@ -80,7 +80,11 @@
 
 import qualified Paths_cabal_rpm (version)
 
+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(3,2,0)
+import qualified Distribution.Utils.ShortText as ST (fromShortText)
+#endif
 
+
 rstrip :: (Char -> Bool) -> String -> String
 rstrip p = reverse . dropWhile p . reverse
 
@@ -90,10 +94,11 @@
 unUnqualComponentName = id
 #endif
 
-createSpecFile :: Verbosity -> Flags -> Bool -> PackageType -> Bool
-               -> Maybe FilePath -> Maybe PackageVersionSpecifier
+createSpecFile :: Verbosity -> Flags -> Bool -> Bool -> PackageType
+               -> Maybe (Maybe Stream) -> Maybe FilePath
+               -> Maybe PackageVersionSpecifier
                -> IO FilePath
-createSpecFile verbose flags force pkgtype subpkgOpt mdest mpvs = do
+createSpecFile verbose flags testsuite force pkgtype subpkgStream mdest mpvs = do
   pkgdata <- prepare flags mpvs True
   let mspec = case pkgtype of
                 SpecFile f -> Just f
@@ -116,7 +121,7 @@
             else return False
 
   subpackage <-
-    if subpkgOpt
+    if isJust subpkgStream
     then
       if pkgtype == StandalonePkg
       then do
@@ -144,10 +149,15 @@
                | otherwise = "ghc-%{pkg_name}"
       targetSpecFile = fromMaybe "" mdest </> pkgname <.> "spec"
       hasExecPkg = binlib || (hasExec && not hasLibPkg)
+  targetSpecAlreadyExists <- doesFileExist targetSpecFile
   -- run commands before opening file to prevent empty file on error
   -- maybe shell commands should be in a monad or something
-  (deps, setupDeps, tools, clibs, pkgcfgs) <- packageDependencies pkgDesc
-  targetSpecAlreadyExists <- doesFileExist targetSpecFile
+  droppedDeps <- if targetSpecAlreadyExists then do
+      map (mkPackageName . removePrefix "cabal-tweak-drop-dep ") <$> grep "cabal-tweak-drop-dep" targetSpecFile
+      else return []
+  pkgdeps <- do
+    alldeps <- packageDependencies pkgDesc
+    return $ alldeps {buildDeps = buildDeps alldeps \\ droppedDeps}
   let outputFile = targetSpecFile ++ if not force && targetSpecAlreadyExists then ".cblrpm" else ""
   if targetSpecAlreadyExists
     then warn verbose $ targetSpecFile +-+ "exists:" +-+ (if force then "forcing overwrite" else "creating") +-+ outputFile
@@ -178,11 +188,15 @@
 
   put $ "# generated by cabal-rpm-" ++ V.showVersion Paths_cabal_rpm.version
     +-+ unwords (["--standalone" | standalone] ++ ["--stream " ++ showStream (fromJust mstream) | isJust mstream, mstream /= Just defaultLTS] ++ ["--subpackage" | subpackage])
-  put "# https://fedoraproject.org/wiki/Packaging:Haskell"
+  put "# https://docs.fedoraproject.org/en-US/packaging-guidelines/Haskell/"
   putNewline
 
   -- Some packages conflate the synopsis and description fields.  Ugh.
-  let syn = synopsis pkgDesc
+  let syn =
+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(3,2,0)
+        ST.fromShortText $
+#endif
+        synopsis pkgDesc
   when (null syn) $
     warn verbose "this package has no synopsis."
   let initialCapital (c:cs) = toUpper c:cs
@@ -194,7 +208,11 @@
   when (length ("Summary     : " ++ syn') > 79) $
     warn verbose "this package has a long synopsis."
 
-  let descr = description pkgDesc
+  let descr =
+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(3,2,0)
+        ST.fromShortText $
+#endif
+        description pkgDesc
   when (null descr) $
     warn verbose "this package has no description."
   let descLines = (formatParagraphs . initialCapital . filterSymbols . finalPeriod) $ if null descr then syn' else descr
@@ -212,6 +230,8 @@
     global "ghc_without_shared" "1"
     put "%undefine with_ghc_prof"
     put "%undefine with_haddock"
+    global "without_prof" "1"
+    global "without_haddock" "1"
     global "debug_package" "%{nil}"
     putNewline
 
@@ -226,10 +246,10 @@
   -- FIXME recursive missingdeps
   missingLibs <- do
     subs <- if subpackage then subPackages mspec pkgDesc else return []
-    miss <- if subpackage || standalone then missingLibraries hasLibPkg pkgDesc else return []
-    return $ nub (subs ++ miss)
+    miss <- if subpackage || standalone then missingLibraries pkgDesc else return []
+    return $ nub (subs ++ miss) \\ droppedDeps
   subpkgs <- if subpackage then
-    mapM (getsubpkgMacro mstream mspec >=>
+    mapM (getsubpkgMacro (fromMaybe mstream subpkgStream) mspec >=>
           \(m,pv) -> global m (display pv) >> return ("%{" ++ m ++ "}")) missingLibs
     else return []
   let hasSubpkgs = subpkgs /= []
@@ -238,12 +258,13 @@
     putNewline
 
   let testsuiteDeps = testsuiteDependencies' pkgDesc
-  missTestDeps <- filterM notSrcOrInst $ map (RpmHsLib Devel) testsuiteDeps
-  let testable = not (null testsuiteDeps) && null missTestDeps
-  when testable $ do
+  missTestDeps <- filterM (notSrcOrInst . RpmHsLib Devel) testsuiteDeps
+  let testable = not (null testsuiteDeps) && (null missTestDeps || testsuite)
+  if testable then do
     put "%bcond_without tests"
     putNewline
-
+    else unless (null testsuiteDeps) $
+         warn verbose $ "testsuite ignored due to missing deps: " ++ unwords (map display missTestDeps)
   let version = display $ pkgVersion pkgid
       release = "1"
   revised <-
@@ -274,20 +295,20 @@
   put "# End cabal-rpm sources"
   putNewline
   put "# Begin cabal-rpm deps:"
-  when (mkPackageName "Cabal" `notElem` deps || not hasLib || not (null setupDeps)) $ do
+  when (mkPackageName "Cabal" `notElem` buildDeps pkgdeps || not hasLib || not (null (setupDeps pkgdeps))) $ do
 --    put "# Setup"
-    when (mkPackageName "Cabal" `notElem` deps) $
+    when (mkPackageName "Cabal" `notElem` buildDeps pkgdeps) $
       putHdr "BuildRequires" "ghc-Cabal-devel"
-    mapM_ (\ d -> (if d `elem` missingLibs then putHdrComment else putHdr) "BuildRequires" (showRpm (RpmHsLib Devel d))) setupDeps
+    mapM_ (\ d -> (if d `elem` missingLibs then putHdrComment else putHdr) "BuildRequires" (showRpm (RpmHsLib Devel d))) $ setupDeps pkgdeps
   putHdr "BuildRequires" $ "ghc-rpm-macros" ++ (if hasSubpkgs then "-extra" else "")
 
-  unless (null deps) $ do
+  unless (null (buildDeps pkgdeps)) $ do
 --    put "# Build"
     let metaPackages = map mkPackageName ["haskell-gi-overloading"]
         ghcLibDep d | d `elem` metaPackages = RpmHsLib Devel d
                     | otherwise = (RpmHsLib $ if standalone then Devel else if hasLibPkg then Prof else Static) d
-    mapM_ (\ d -> (if d `elem` missingLibs then putHdrComment else putHdr) "BuildRequires" (showRpm (ghcLibDep d))) $ sort deps
-  let otherdeps = sort $ tools ++ clibs ++ pkgcfgs
+    mapM_ (\ d -> (if d `elem` missingLibs then putHdrComment else putHdr) "BuildRequires" (showRpm (ghcLibDep d))) $ sort $ buildDeps pkgdeps
+  let otherdeps = sort $ toolDeps pkgdeps ++ clibDeps pkgdeps ++ pkgcfgDeps pkgdeps
   unless (null otherdeps) $ do
 --    put "# Other"
     missingOthers <- missingOtherPkgs pkgDesc
@@ -296,7 +317,7 @@
     -- when (epel7 &&
     --       any (\ d -> d `elem` map showDep ["template-haskell", "hamlet"]) deps) $
     --   putHdr "ExclusiveArch" "%{ghc_arches_with_ghci}"
-  let testDeps = sort $ testsuiteDeps \\ (mkPackageName "Cabal" : (deps ++ setupDeps))
+  let testDeps = sort $ testsuiteDeps \\ (mkPackageName "Cabal" : (buildDeps pkgdeps ++ setupDeps pkgdeps))
   when (testable && not (null testDeps)) $ do
     put "%if %{with tests}"
     mapM_ (putHdr "BuildRequires" . showRpm . RpmHsLib Devel) testDeps
@@ -312,13 +333,12 @@
     unless (null missingLibs) $ do
       putStrLn "checking for deps of missing dependencies:"
       let deptype = if standalone then Devel else Prof
-          putPkgDeps pkg = do
-            more <- packageDeps flags Nothing pkg
-            let moredeps = sort $ more \\ (deps ++ missingLibs)
-            unless (null moredeps) $ do
-              put $ "# for missing dep '" ++ display pkg ++ "':"
-              mapM_ (\ d -> (if d `elem` missingLibs then putHdrComment else putHdr) "BuildRequires" (showRpm (RpmHsLib deptype d))) moredeps
-      mapM_ putPkgDeps missingLibs
+      forM_ missingLibs $ \ pkg -> do
+        more <- packageDeps flags (fromMaybe mstream subpkgStream) pkg
+        let moredeps = sort $ more \\ (buildDeps pkgdeps ++ missingLibs)
+        unless (null moredeps) $ do
+          put $ "# for missing dep '" ++ display pkg ++ "':"
+          mapM_ (\ d -> (if d `elem` missingLibs then putHdrComment else putHdr) "BuildRequires" (showRpm (RpmHsLib deptype d))) moredeps
   put "# End cabal-rpm deps"
   putNewline
 
@@ -341,7 +361,7 @@
   -- (strictly should also check for otherModules (autogenModules?)
   --  but libraries wihout exposedModules should be useless/redundant)
   let hasModules =
-        hasLib && ((notNull . exposedModules . fromJust . library) pkgDesc || mkPackageName "haskell-gi" `elem` (deps ++ setupDeps))
+        hasLib && (isJust (library pkgDesc) && (notNull . exposedModules . fromJust . library) pkgDesc || mkPackageName "haskell-gi" `elem` (buildDeps pkgdeps ++ setupDeps pkgdeps))
       baselibpkg = if binlib then "ghc-%{name}" else "%{name}"
 
   when hasLibPkg $ do
@@ -365,9 +385,9 @@
     put "%endif"
     when hasModules $
       putHdr "Requires" $ baselibpkg ++ isa ++ versionRelease
-    unless (null $ clibs ++ pkgcfgs) $ do
+    unless (null $ clibDeps pkgdeps ++ pkgcfgDeps pkgdeps) $ do
       put "# Begin cabal-rpm deps:"
-      mapM_ (putHdr "Requires") $ sort $ map (++ isa) clibs ++ pkgcfgs
+      mapM_ (putHdr "Requires") $ sort $ map (++ isa) (clibDeps pkgdeps) ++ pkgcfgDeps pkgdeps
       put "# End cabal-rpm deps"
     putNewline
     put $ "%description" +-+ subpkgParam Devel
@@ -440,7 +460,7 @@
 
   unless (null dupdocs) $ do
     putNewline
-    putStrLn $ "Warning: doc files found in datadir:" +-+ unwords dupdocs
+    warn verbose $ "doc files found in datadir:" +-+ unwords dupdocs
     put $ "rm %{buildroot}%{_datadir}" </> pkgver </>
       case length dupdocs of
          1 -> head dupdocs
@@ -457,6 +477,16 @@
     put "find %{buildroot}%{_libdir} -name 'libHS%{pkgver}-*.so' -delete"
     put "rm -r %{buildroot}%{ghclibdir}"
 
+  let extrasourcedocs = sort $ filter (`elem` docs) $ extraSrcFiles pkgDesc
+  unless (null extrasourcedocs) $ do
+    let pkgdir = display pkgid
+    havePrep <- doesDirectoryExist pkgdir
+    if havePrep then do
+      executabledocs <- filterM (fmap executable . getPermissions . (pkgdir </>)) extrasourcedocs
+      unless (null executabledocs) $
+        put $ "chmod a-x" +-+ unwords executabledocs
+      else warn verbose $ "Check file permissions of" +-+ unwords extrasourcedocs
+
   put "# End cabal-rpm install"
   sectionNewline
 
@@ -546,10 +576,10 @@
   hClose h
   return outputFile
 
-createSpecFile_ :: Verbosity -> Flags -> Bool -> PackageType
-                -> Bool -> Maybe PackageVersionSpecifier -> IO ()
-createSpecFile_ verbose flags force pkgtype subpackage mpvs =
-  void (createSpecFile verbose flags force pkgtype subpackage Nothing mpvs)
+createSpecFile_ :: Verbosity -> Flags -> Bool -> Bool -> PackageType
+                -> Maybe (Maybe Stream) -> Maybe PackageVersionSpecifier -> IO ()
+createSpecFile_ verbose flags testsuite force pkgtype subpkgStream mpvs =
+  void (createSpecFile verbose flags testsuite force pkgtype subpkgStream Nothing mpvs)
 
 isBuildable :: Executable -> Bool
 isBuildable exe = buildable $ buildInfo exe
diff --git a/src/Commands/Update.hs b/src/Commands/Update.hs
--- a/src/Commands/Update.hs
+++ b/src/Commands/Update.hs
@@ -54,27 +54,33 @@
           name = pkgName oldPkgId
           wasrevised = isJust $ lookup "x-revision" (customFieldsPD pkgDesc)
       putStrLn $ display oldPkgId +-+ "->"
-      newPkgId <- case mpvs of
-                    Nothing -> do
-                      stream <-
-                        withSpecHead spec $ \ headerwords -> do
-                        let mspecstream = read <$> headerOption "--stream" headerwords
-                        case mspecstream of
-                          Just specStream -> do
-                            putStrLn $ "Using stream" +-+ showStream specStream  +-+ "from spec file"
-                            when (specStream <= defaultLTS) $
-                              putStrLn $ "Warning: < current default stream" +-+ showStream defaultLTS
-                          Nothing -> return ()
-                        return mspecstream
-                      latestPackage stream name
-                    Just pvs ->
-                      case pvs of
-                        PVStreamPackage stream mpkg ->
-                          case mpkg of
-                            Just pkg | pkg /= name -> error' "different package name"
-                            _ -> latestPackage (Just stream) name
-                        PVPackageId pkgid -> return pkgid
-                        PVPackageName pkg -> latestPackage Nothing pkg
+      (newPkgId, mstream) <-
+        case mpvs of
+          Nothing -> do
+            stream <-
+              withSpecHead spec $ \ headerwords -> do
+              let mspecstream = read <$> headerOption "--stream" headerwords
+              case mspecstream of
+                Just specStream -> do
+                  putStrLn $ "Using stream" +-+ showStream specStream  +-+ "from spec file"
+                  when (specStream <= defaultLTS) $
+                    putStrLn $ "Warning: < current default stream" +-+ showStream defaultLTS
+                Nothing -> return ()
+              return mspecstream
+            latest <- latestPackage stream name
+            return (latest, stream)
+          Just pvs ->
+            case pvs of
+              PVStreamPackage stream mpkg ->
+                case mpkg of
+                  Just pkg | pkg /= name -> error' "different package name"
+                  _ -> do
+                    latest <- latestPackage (Just stream) name
+                    return (latest, Just stream)
+              PVPackageId pkgid -> return (pkgid, Nothing)
+              PVPackageName pkg -> do
+                latest <- latestPackage Nothing pkg
+                return (latest, Nothing)
 
       let newver = pkgVersion newPkgId
           oldver = pkgVersion oldPkgId
@@ -87,8 +93,8 @@
           putStrLn "Package is already latest version."
         when (newrev || updated) $ do
           subpkg <- grep_ "%{subpkgs}" spec
-          (curspec, _) <- createSpecVersion oldPkgId spec wasrevised subpkg
-          (newspec, newrevised) <- createSpecVersion newPkgId spec True subpkg
+          (curspec, _) <- createSpecVersion oldPkgId spec wasrevised (if subpkg then Just Nothing else Nothing)
+          (newspec, newrevised) <- createSpecVersion newPkgId spec True (if subpkg then Just mstream else Nothing)
           currel <- getSpecField "Release" spec
           let suffix = "%{?dist}"
               defrelease = "1"
@@ -122,15 +128,16 @@
                 cmd_ "git" ["rm", display oldPkgId <.> "cabal"]
               cmd_ "git" ["commit", "-a", "-m", "update to" +-+ showVersion newver]
   where
-    createSpecVersion :: PackageIdentifier -> String -> Bool -> Bool -> IO (FilePath, Bool)
-    createSpecVersion pkgid spec revise subpkg = do
+    -- Just Nothing is default stream
+    createSpecVersion :: PackageIdentifier -> String -> Bool -> Maybe (Maybe Stream) -> IO (FilePath, Bool)
+    createSpecVersion pkgid spec revise subpkgStream = do
       pd <- prepare [] (streamPkgToPVS Nothing (Just pkgid)) revise
       let pkgdata = pd { specFilename = Just spec }
           dir = ".Cblrpm/" ++ display pkgid ++ if revise then ".revised" else ".orig"
       direxists <- doesDirectoryExist dir
       when direxists $ removeDirectoryRecursive dir
       createDirectoryIfMissing True dir
-      newspec <- createSpecFile silent [] False (SpecFile spec) subpkg (Just dir) (streamPkgToPVS Nothing (Just pkgid))
+      newspec <- createSpecFile silent [] False False (SpecFile spec) subpkgStream (Just dir) (streamPkgToPVS Nothing (Just pkgid))
       let newrevised =
             isJust $ lookup "x-revision" (customFieldsPD (packageDesc pkgdata))
       return (newspec, newrevised)
diff --git a/src/Dependencies.hs b/src/Dependencies.hs
--- a/src/Dependencies.hs
+++ b/src/Dependencies.hs
@@ -25,6 +25,7 @@
   notInstalled,
   notSrcOrInst,
   packageDeps,
+  PackageDependencies(..),
   packageDependencies,
   pkgInstallMissing,
   pkgInstallMissing',
@@ -118,9 +119,16 @@
       warning $ "More than one package seems to provide" +-+ file ++ ": " +-+ unwords pkgs
       return Nothing
 
+data PackageDependencies = PackageDepends
+                           { buildDeps :: [PackageName]
+                           , setupDeps :: [PackageName]
+                           , toolDeps ::[String]
+                           , clibDeps :: [String]
+                           , pkgcfgDeps :: [String]
+                           }
+
 packageDependencies :: PackageDescription  -- ^pkg description
-                -> IO ([PackageName], [PackageName], [String], [String], [String])
-                -- ^depends, setup, tools, c-libs, pkgcfg
+                -> IO PackageDependencies
 packageDependencies pkgDesc = do
     let (deps, setup, tools', clibs', pkgcfgs) = dependencies pkgDesc
         excludedTools n = n `notElem` ["ghc", "hsc2hs", "perl"]
@@ -137,7 +145,7 @@
       warning "could not resolve all clib dependencies"
     let clibs = catMaybes clibsWithErrors
     let showPkgCfg p = "pkgconfig(" ++ p ++ ")"
-    return (deps, setup, tools, nub clibs, map showPkgCfg pkgcfgs)
+    return $ PackageDepends deps setup tools (nub clibs) (map showPkgCfg pkgcfgs)
 
 testsuiteDependencies' :: PackageDescription -> [PackageName]
 testsuiteDependencies' =
@@ -145,31 +153,31 @@
 
 missingPackages :: PackageDescription -> IO [RpmPackage]
 missingPackages pkgDesc = do
-  (deps, setup, tools, clibs, pkgcfgs) <- packageDependencies pkgDesc
-  pcpkgs <- mapM derefPkg pkgcfgs
-  filterM notSrcOrInst $ nub $ map (RpmHsLib Devel) (deps ++ setup ++ [mkPackageName "Cabal"]) ++ map RpmOther (["ghc-rpm-macros"] ++ tools ++ clibs ++ pcpkgs)
+  pkgdeps <- packageDependencies pkgDesc
+  pcpkgs <- mapM derefPkg $ pkgcfgDeps pkgdeps
+  filterM notSrcOrInst $ nub $ map (RpmHsLib Devel) (buildDeps pkgdeps ++ setupDeps pkgdeps ++ [mkPackageName "Cabal"]) ++ map RpmOther (["ghc-rpm-macros"] ++ toolDeps pkgdeps ++ clibDeps pkgdeps ++ pcpkgs)
 
-missingLibraries :: Bool -> PackageDescription -> IO [PackageName]
-missingLibraries hasLibPkg pkgDesc = do
-  (deps, setup, _, _, _) <- packageDependencies pkgDesc
-  let libType = if hasLibPkg then Prof else Devel
-  bdeps <- filterM (notSrcOrInst . RpmHsLib libType) deps
-  sdeps <- filterM (notSrcOrInst . RpmHsLib Devel) $ (mkPackageName "Cabal" : setup) \\ deps
+missingLibraries :: PackageDescription -> IO [PackageName]
+missingLibraries pkgDesc = do
+  pkgdeps <- packageDependencies pkgDesc
+  -- just use Devel for deps because -devel presence implies -prof should exist
+  bdeps <- filterM (notSrcOrInst . RpmHsLib Devel) $ buildDeps pkgdeps
+  sdeps <- filterM (notSrcOrInst . RpmHsLib Devel) $ (mkPackageName "Cabal" : setupDeps pkgdeps) \\ buildDeps pkgdeps
   return $ bdeps ++ sdeps
 
 uninstalledLibraries :: Bool -> PackageDescription -> IO [PackageName]
 uninstalledLibraries hasLibPkg pkgDesc = do
-  (deps, setup, _, _, _) <- packageDependencies pkgDesc
+  pkgdeps <- packageDependencies pkgDesc
   let libType = if hasLibPkg then Prof else Devel
-  bdeps <- filterM (notInstalled . RpmHsLib libType) deps
-  sdeps <- filterM (notInstalled . RpmHsLib Devel) $ (mkPackageName "Cabal" : setup) \\ deps
+  bdeps <- filterM (notInstalled . RpmHsLib libType) $ buildDeps pkgdeps
+  sdeps <- filterM (notInstalled . RpmHsLib Devel) $ (mkPackageName "Cabal" : setupDeps pkgdeps) \\ buildDeps pkgdeps
   return $ bdeps ++ sdeps
 
 missingOtherPkgs :: PackageDescription -> IO [String]
 missingOtherPkgs pkgDesc = do
-  (_, _, tools, clibs, pkgcfgs) <- packageDependencies pkgDesc
-  pcpkgs <- mapM derefPkg pkgcfgs
-  filterM (notSrcOrInst . RpmOther) $ nub $ ["ghc-rpm-macros"] ++ tools ++ clibs ++ pcpkgs
+  pkgdeps <- packageDependencies pkgDesc
+  pcpkgs <- mapM derefPkg $ pkgcfgDeps pkgdeps
+  filterM (notSrcOrInst . RpmOther) $ nub $ ["ghc-rpm-macros"] ++ toolDeps pkgdeps ++ clibDeps pkgdeps ++ pcpkgs
 
 notSrcOrInst :: RpmPackage -> IO Bool
 notSrcOrInst pkg = do
diff --git a/src/FileUtils.hs b/src/FileUtils.hs
--- a/src/FileUtils.hs
+++ b/src/FileUtils.hs
@@ -48,7 +48,7 @@
 filesWithExtension dir ext =
   filter (\ f -> takeExtension f == ext) <$> getDirectoryContents dir
 
--- looks in current dir for a unique file with given extension
+-- looks in dir for a unique file with given extension
 fileWithExtension :: FilePath -> String -> IO (Maybe FilePath)
 fileWithExtension dir ext = do
   files <- filesWithExtension dir ext
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -55,7 +55,7 @@
     "RPM package tool for Haskell Stackage/Hackage packages" $
     subcommands
     [ Subcommand "spec" "Generate a spec file" $
-      createSpecFile_ <$> quietOpt <*> flags <*> force <*> pkgtype <*> subpackage <*> pkgVerSpecifier
+      createSpecFile_ <$> quietOpt <*> flags <*> testsuite <*> force <*> pkgtype <*> fmap toSubpkgStream subpackage <*> pkgVerSpecifier
     , Subcommand "srpm" "Generate an srpm" $
       rpmBuild_ Source <$> flags <*> pkgtype <*> subpackage <*> pkgVerSpecifier
     , Subcommand "prep" "Unpack source" $
@@ -93,6 +93,9 @@
     flags :: Parser Flags
     flags = optionalWith auto 'f' "flag" "[(String,Bool)]" "Set or disable Cabal flags" []
 
+    testsuite :: Parser Bool
+    testsuite = switchWith 'T' "tests" "Force enabling the test-suite (even if deps missing)"
+
     force :: Parser Bool
     force = switchWith 'F' "force" "Force overwriting existing of any .spec file"
 
@@ -111,3 +114,7 @@
 
     pkgVerSpecifier :: Parser (Maybe PackageVersionSpecifier)
     pkgVerSpecifier = streamPkgToPVS <$> stream <*> pkgId
+
+    toSubpkgStream :: Bool -> Maybe (Maybe Stream)
+    toSubpkgStream False = Nothing
+    toSubpkgStream True = Just Nothing
diff --git a/src/PackageUtils.hs b/src/PackageUtils.hs
--- a/src/PackageUtils.hs
+++ b/src/PackageUtils.hs
@@ -40,7 +40,7 @@
 import SimpleCabal (finalPackageDescription, licenseFiles, mkPackageName,
                     PackageDescription, PackageIdentifier(..), PackageName,
                     tryFindPackageDesc)
-import SimpleCmd (cmd, cmd_, cmdIgnoreErr, cmdLines, error', grep_,
+import SimpleCmd (cmd, cmd_, cmdBool, cmdIgnoreErr, cmdLines, error', grep_,
                   removePrefix, sudo, sudo_, (+-+))
 import SimpleCmd.Git (isGitDir, grepGitConfig)
 import SimpleCmd.Rpm (rpmspec)
@@ -172,12 +172,15 @@
   let file = display (pkgName pkgid) <.> "cabal"
   dir <- getSourceDir
   withTempDirectory $ \ _ -> do
-    cmd_ "wget" ["--quiet", "https://hackage.haskell.org/package" </> display pkgid </> file]
-    revised <- grep_ "x-revision" file
-    when revised $ do
-      cmd_ "dos2unix" ["--keepdate", file]
-      renameFile file $ dir </> display pkgid <.> "cabal"
-    return revised
+    dl <- cmdBool "wget" ["--quiet", "https://hackage.haskell.org/package" </> display pkgid </> file]
+    if not dl
+      then return False
+      else do
+      revised <- grep_ "x-revision" file
+      when revised $ do
+        cmd_ "dos2unix" ["--keepdate", file]
+        renameFile file $ dir </> display pkgid <.> "cabal"
+      return revised
 
 data RpmStage = Binary | Source | Prep deriving Eq
 
@@ -203,8 +206,8 @@
   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"]
+    done' <- checkTimestamp $ dir </> "01-index.cache"
+    unless done' cabalUpdateCmd
   where
     checkTimestamp tsfile = do
       haveFile <- doesFileExist tsfile
@@ -212,11 +215,16 @@
         ts <- getModificationTime tsfile
         t <- getCurrentTime
         -- less than 3 hours
-        when (diffUTCTime t ts > 10000) $ cmd_ "cabal" ["update"]
+        when (diffUTCTime t ts > 10000) cabalUpdateCmd
         return True
         else
         return False
 
+    cabalUpdateCmd :: IO ()
+    cabalUpdateCmd = do
+      putStrLn "Running 'cabal update'"
+      cmd_ "cabal" ["update", "-v0"]
+
 cabal :: String -> [String] -> IO [String]
 cabal c args = do
   cabalUpdate
@@ -258,6 +266,7 @@
     Just pkgid -> return pkgid
     Nothing -> latestHackage pkg
 
+-- use cabal-file when it parses preferred-versions
 latestHackage :: PackageName -> IO PackageIdentifier
 latestHackage pkgname = do
   let pkg = display pkgname
diff --git a/src/Stackage.hs b/src/Stackage.hs
--- a/src/Stackage.hs
+++ b/src/Stackage.hs
@@ -44,7 +44,7 @@
 defaultLTS = LTS "14"
 
 latestLTS :: Stream
-latestLTS = LTS "14"
+latestLTS = LTS "15"
 
 stackageList :: Stream -> PackageName -> IO (Maybe PackageIdentifier)
 stackageList stream pkg = do
diff --git a/src/SysCmd.hs b/src/SysCmd.hs
--- a/src/SysCmd.hs
+++ b/src/SysCmd.hs
@@ -21,7 +21,6 @@
   optionalProgram,
   requireProgram,
   rpmEval,
-  rpmMacroDefined,
   trySystem) where
 
 #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
@@ -66,7 +65,3 @@
 rpmEval s = do
   res <- cmd "rpm" ["--eval", s]
   return $ if null res || res == s then Nothing else Just res
-
-rpmMacroDefined :: String -> IO Bool
-rpmMacroDefined macro =
-  isJust <$> rpmEval ("%{?" ++ macro ++ "}")
