diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,10 +1,15 @@
+# 1.0.2 (2019-12-09)
+- allow newer time for ghc-8.8
+- more type refactoring: PackageIdentifier, LibPkgType, RpmPackage
+  and some associated bugfixes
+
 # 1.0.1 (2019-09-29)
 - doc and prof subpackages for libraries
 - reworked to use optparse-applicative (simple-cmd-args)
 - default to Stackage LTS 13
 - F31+ uses triggers for ghc-pkg recache
 - wait 10^4s (< 3 hours) between cabal update's
-- refactor for simple-cabal 1.0, PackageName and LibPkgType
+- refactor using simple-cabal, PackageName and LibPkgType
 - handle setup-depends
 - diff: autodetect subpackaging
 - diff (experimental): trim %changelog with bawolk/hsp if available
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -2,3 +2,20 @@
 
 man/cabal-rpm.1: man/cabal-rpm.1.md
 	pandoc -s -t man $< > $@
+
+stack-all:
+	stack --resolver nightly build
+	@echo
+	stack --resolver lts build
+	@echo
+	stack --resolver lts-13 --stack-yaml stack-lts13.yaml build
+	@echo
+#	stack --resolver lts-12 --stack-yaml stack-lts12.yaml build
+	@echo
+	stack --resolver lts-11 --stack-yaml stack-lts11.yaml build
+	@echo
+	stack --resolver lts-10 --stack-yaml stack-lts11.yaml build
+	@echo
+	stack --resolver lts-9 --stack-yaml stack-lts9.yaml build
+	@echo
+	stack --resolver lts-8 --stack-yaml stack-lts9.yaml build
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:             1.0.1
+Version:             1.0.2
 Synopsis:            RPM packaging tool for Haskell Cabal-based packages
 Description:
     This package provides a RPM packaging tool for Haskell Cabal-based packages.
@@ -16,17 +16,17 @@
 Bug-reports:         https://github.com/juhp/cabal-rpm/issues
 License:             GPL-3
 License-file:        COPYING
-Author:              Jens Petersen <juhp@community.haskell.org>, Bryan O'Sullivan <bos@serpentine.com>
-Maintainer:          Jens Petersen <juhpetersen@gmail.com>
+Author:              Jens Petersen <juhpetersen@gmail.com>, Bryan O'Sullivan <bos@serpentine.com>
+Maintainer:          Jens Petersen <petersen@fedoraproject.org>
 Copyright:           2007-2008 Bryan O'Sullivan <bos@serpentine.com>,
-                     2012-2019 Jens Petersen <petersen@fedoraproject.org>
+                     2012-2019 Jens Petersen <juhpetersen@gmail.com>
 Category:            Distribution
 Build-type:          Simple
 Extra-source-files:  ChangeLog Makefile README.md TODO man/cabal-rpm.1.md
 Cabal-version:       >=1.6
 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.6.5, GHC == 8.8.1
 
 source-repository head
   type:     git
@@ -46,6 +46,7 @@
                    Cabal > 1.10,
                    directory,
                    filepath,
+                   optparse-applicative,
                    process,
                    simple-cabal >= 0.1.0,
                    simple-cmd >= 0.2.0,
@@ -55,7 +56,7 @@
        Build-Depends: old-locale >= 1 && < 1.1,
                       time >= 1.2 && < 1.5
     else
-       Build-Depends: time >= 1.5 && < 1.9
+       Build-Depends: time >= 1.5
     if impl(ghc<8.0)
        Build-Depends: semigroups
     if impl(ghc >= 8.0) && flag(https)
diff --git a/src/Commands/BuildDep.hs b/src/Commands/BuildDep.hs
--- a/src/Commands/BuildDep.hs
+++ b/src/Commands/BuildDep.hs
@@ -3,7 +3,9 @@
 import Dependencies (pkgInstallMissing)
 import Types
 
-builddep :: Flags -> Stream -> Maybe Package -> IO ()
-builddep flags stream mpkg = do
-  missing <- pkgInstallMissing flags stream mpkg
-  mapM_ (builddep flags stream . Just) missing
+import SimpleCabal (PackageIdentifier)
+
+builddep :: Flags -> Stream -> Maybe PackageIdentifier -> IO ()
+builddep flags stream mpkgid = do
+  missing <- pkgInstallMissing flags stream mpkgid
+  mapM_ (builddep flags stream . Just . unversionedPkgId) missing
diff --git a/src/Commands/Depends.hs b/src/Commands/Depends.hs
--- a/src/Commands/Depends.hs
+++ b/src/Commands/Depends.hs
@@ -17,12 +17,11 @@
     Depends (..)
     ) where
 
-import Dependencies (dependencies, ghcDep, LibPkgType(..), missingPackages,
-                     packageDependencies)
-import PackageUtils (PackageData (..), prepare, repoquery,
-                     stripPkgDevel, unPackageName)
+import Dependencies (dependencies, missingPackages, packageDependencies)
+import PackageUtils (PackageData (..), prepare, repoquery)
 import Types
 
+import SimpleCabal (PackageIdentifier, PackageName)
 import SimpleCmd ((+-+))
 
 #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
@@ -31,56 +30,67 @@
 #endif
 import Control.Monad (filterM, unless, void)
 import Data.List (nub, sort, (\\))
+import Data.Maybe (mapMaybe)
+import Distribution.Text (display)
 import System.FilePath ((<.>))
 
 data Depends = Depends | Requires | Missing
 
-depends :: Depends -> Flags -> Stream -> Maybe Package -> IO ()
-depends action flags stream mpkg = do
-  pkgdata <- prepare flags stream mpkg False
+depends :: Depends -> Flags -> Stream -> Maybe PackageIdentifier -> IO ()
+depends action flags stream mpkgid = do
+  pkgdata <- prepare flags stream mpkgid False
   let pkgDesc = packageDesc pkgdata
   case action of
     Depends -> do
       let (deps, setup, tools, clibs, pkgcfgs) = dependencies pkgDesc
           clibs' = map (\ lib -> "lib" ++ lib <.> "so") clibs
           pkgcfgs' = map (<.> "pc") pkgcfgs
-      mapM_ putStrLn $ map unPackageName (nub (deps ++ setup)) ++ tools ++ clibs' ++ 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 (ghcDep LibDevel) (deps ++ setup) ++ tools ++ clibs ++ pkgcfgs
+      mapM_ putStrLn $ sort . nub  $ map (show . RpmHsLib Devel) (deps ++ setup) ++ tools ++ clibs ++ pkgcfgs
     Missing -> do
-      miss <- missingPackages pkgDesc >>= filterM notAvail
-      let missing = map stripPkgDevel miss
-      mapM_ putStrLn missing
-      unless (null missing) $
-        putStrLn ""
-      void $ recurseMissing flags stream miss missing
+      missing <- missingPackages pkgDesc >>= filterM notAvail
+      mapM_ (putStrLn . showDep) missing
+      let miss = mapMaybe hsDep missing
+      unless (null miss) $ putStrLn ""
+      void $ recurseMissing flags stream [] miss
+  where
+    showDep :: RpmPackage -> String
+    showDep (RpmHsLib _ n) = display n
+    showDep (RpmHsBin n) = display n
+    showDep p = show p
 
-recurseMissing :: Flags -> Stream -> [String] -> [String] -> IO [String]
+hsDep :: RpmPackage -> Maybe PackageName
+hsDep (RpmHsLib _ n) = Just n
+hsDep _ = Nothing
+
+recurseMissing :: Flags -> Stream -> [PackageName] -> [PackageName] -> IO [PackageName]
 recurseMissing _ _ already [] = return already
 recurseMissing flags stream already (dep:deps) = do
   miss <- missingDepsPkg flags stream dep
   putMissing miss already
-  let accum = nub $ miss ++ already
-  deeper <- recurseMissing flags stream accum (miss \\ accum)
-  let accum2 = nub $ accum ++ deeper
-  more <- recurseMissing flags stream accum2 (deps \\ accum2)
-  return $ nub $ accum2 ++ more
+  let hmiss = mapMaybe hsDep miss
+  let accum = nub $ hmiss ++ already
+  -- deeper <- recurseMissing flags stream accum (miss \\ accum)
+  -- let accum2 = nub $ accum ++ deeper
+  more <- recurseMissing flags stream accum (deps \\ accum)
+  return $ nub $ accum ++ more
 
-notAvail :: String -> IO Bool
-notAvail pkg = null <$> repoquery [] pkg
+notAvail :: RpmPackage -> IO Bool
+notAvail pkg = null <$> repoquery [] (show pkg)
 
-missingDepsPkg :: Flags -> Stream -> Package -> IO [String]
+missingDepsPkg :: Flags -> Stream -> PackageName -> IO [RpmPackage]
 missingDepsPkg flags stream pkg = do
-  pkgdata <- prepare flags stream (Just pkg) False
+  pkgdata <- prepare flags stream (Just (unversionedPkgId pkg)) False
   missingPackages (packageDesc pkgdata) >>= filterM notAvail
 
-putMissing :: [String] -> [String] -> IO ()
+putMissing :: [RpmPackage] -> [PackageName] -> IO ()
 putMissing [] _ = return ()
 putMissing deps already = putStrLn $ "  " ++ "needs:" +-+ unwords (markAlready deps)
   where
-    markAlready :: [String] -> [String]
+    markAlready :: [RpmPackage] -> [String]
     markAlready [] = []
     markAlready (d:ds) =
-      let (op, cl) = if d `elem` already then ("(", ")") else ("", "") in
-      (op ++ stripPkgDevel d ++ cl) : markAlready ds
+      let (op, cl) = if maybe False (`elem` already) (hsDep d) then ("(", ")") else ("", "") in
+      (op ++ show d ++ cl) : markAlready ds
diff --git a/src/Commands/Diff.hs b/src/Commands/Diff.hs
--- a/src/Commands/Diff.hs
+++ b/src/Commands/Diff.hs
@@ -23,22 +23,27 @@
 import SysCmd (die, optionalProgram)
 import Types
 
+import SimpleCabal (PackageIdentifier)
 import SimpleCmd (grep_, pipe_, pipe3_)
 
+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
+#else
+import Control.Applicative ((<$>))
+#endif
 import Distribution.Verbosity (silent)
 import System.Directory (removeDirectoryRecursive)
 import System.FilePath ((<.>))
 import System.Posix.Env (getEnvDefault)
 
-diff :: Flags -> PackageType -> Stream -> Maybe Package -> IO ()
-diff flags pkgtype stream mpkg = do
-  pkgdata <- prepare flags stream mpkg True
+diff :: Flags -> PackageType -> Stream -> Maybe PackageIdentifier -> IO ()
+diff flags pkgtype stream mpkgid = do
+  pkgdata <- prepare flags stream mpkgid True
   case specFilename pkgdata of
     Nothing -> die "No (unique) .spec file in directory."
     Just spec -> do
       subpkg <- grep_ "%{subpkgs}" spec
       tmpdir <- mktempdir
-      speccblrpm <- createSpecFile silent flags False pkgtype subpkg stream (Just tmpdir) mpkg
+      speccblrpm <- createSpecFile silent flags False pkgtype subpkg stream (Just tmpdir) mpkgid
       diffcmd <- words <$> getEnvDefault "CBLRPM_DIFF" "diff -u"
       hsp <- optionalProgram "hsp"
       if hsp
diff --git a/src/Commands/Install.hs b/src/Commands/Install.hs
--- a/src/Commands/Install.hs
+++ b/src/Commands/Install.hs
@@ -20,10 +20,11 @@
 import Commands.RpmBuild (rpmBuild)
 import Dependencies (notInstalled, pkgInstallMissing)
 import FileUtils (withTempDirectory)
-import PackageUtils (rpmInstall, RpmStage (..), stripPkgDevel)
+import PackageUtils (rpmInstall, RpmStage (..))
 import SysCmd (rpmEval)
 import Types
 
+import SimpleCabal(PackageIdentifier, PackageName)
 import SimpleCmd (cmd_, (+-+))
 import SimpleCmd.Rpm (rpmspec)
 
@@ -32,25 +33,26 @@
 --import Control.Applicative ((<$>))
 #endif
 import Control.Monad (unless, when)
+import Distribution.Text (display)
 import System.FilePath ((</>))
 
-install :: Flags -> PackageType -> Bool -> Stream -> Maybe Package -> IO ()
-install flags pkgtype subpackage stream mpkg = do
-  stillMissing <- pkgInstallMissing flags stream mpkg
+install :: Flags -> PackageType -> Bool -> Stream -> Maybe PackageIdentifier
+        -> IO ()
+install flags pkgtype subpackage stream mpkgid = do
+  stillMissing <- pkgInstallMissing flags stream mpkgid
   unless (null stillMissing) $ do
-    putStrLn $ "Missing:" +-+ unwords stillMissing
+    putStrLn $ "Missing:" +-+ unwords (map display stillMissing)
     mapM_ cblrpmInstallMissing stillMissing
   withTempDirectory $ \ _ -> do
-    spec <- rpmBuild Binary flags pkgtype subpackage stream mpkg
+    spec <- rpmBuild Binary flags pkgtype subpackage stream mpkgid
     rpmdir <- rpmEval "%{_rpmdir}"
     rpmspec [] (fmap (</> "%{arch}/%{name}-%{version}-%{release}.%{arch}.rpm") rpmdir) spec >>= rpmInstall False
 
-
-cblrpmInstallMissing :: String -> IO ()
+cblrpmInstallMissing :: PackageName -> IO ()
 cblrpmInstallMissing pkg = do
-  noPkg <- notInstalled pkg
+  noPkg <- notInstalled $ RpmHsLib Prof pkg
   when noPkg $ do
-    let dep = stripPkgDevel pkg
+    let dep = display pkg
     withTempDirectory $ \ _ -> do
       putStrLn $ "Running cabal-rpm install" +-+ dep
       cmd_ "cabal-rpm" ["install", dep]
diff --git a/src/Commands/Refresh.hs b/src/Commands/Refresh.hs
--- a/src/Commands/Refresh.hs
+++ b/src/Commands/Refresh.hs
@@ -19,11 +19,12 @@
 import Commands.Spec (createSpecFile)
 import FileUtils (withTempDirectory)
 import PackageUtils (PackageData (..), cabal_, patchSpec,
-                     prepare, removePrefix)
+                     prepare)
 import SysCmd (die, optionalProgram)
 import Types
 
-import SimpleCmd (cmd, cmd_, grep_)
+import SimpleCabal(PackageIdentifier)
+import SimpleCmd (cmd, cmd_, grep_, removePrefix)
 import SimpleCmd.Git (rwGitDir)
 
 #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
@@ -40,9 +41,9 @@
 --import System.Exit (exitSuccess)
 import System.FilePath ((</>), (<.>))
 
-refresh :: Bool -> PackageType -> Stream -> Maybe Package -> IO ()
-refresh dryrun pkgtype stream mpkg = do
-  pkgdata <- prepare [] stream mpkg True
+refresh :: Bool -> PackageType -> Stream -> Maybe PackageIdentifier -> IO ()
+refresh dryrun pkgtype stream mpkgid = do
+  pkgdata <- prepare [] stream mpkgid True
   case specFilename pkgdata of
     Nothing -> die "No (unique) .spec file in directory."
     Just spec -> do
@@ -63,7 +64,7 @@
         else do
         subpkg <- grep_ "%{subpkgs}" spec
         oldspec <- createOldSpec subpkg cblrpmver spec
-        newspec <- createSpecFile silent [] False pkgtype subpkg stream Nothing mpkg
+        newspec <- createSpecFile silent [] False pkgtype subpkg stream Nothing mpkgid
         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
@@ -25,36 +25,35 @@
                      rpmbuild, RpmStage (..))
 import Types
 
-import SimpleCabal (showPkgId)
+import SimpleCabal (package, PackageIdentifier)
 import SimpleCmd ((+-+))
 
 #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
 #else
-import Control.Applicative ((<$>))
+--import Control.Applicative ((<$>))
 #endif
---import Control.Exception (bracket)
 import Control.Monad (void, when)
-import Distribution.PackageDescription (PackageDescription (..))
 import Distribution.Verbosity (normal)
 
-rpmBuild :: RpmStage -> Flags -> PackageType -> Bool -> Stream -> Maybe Package ->
-            IO FilePath
-rpmBuild stage flags pkgtype subpackage stream mpkg = do
-  pkgdata <- prepare flags stream mpkg True
+rpmBuild :: RpmStage -> Flags -> PackageType -> Bool -> Stream ->
+            Maybe PackageIdentifier -> IO FilePath
+rpmBuild stage flags pkgtype subpackage stream mpkgid = do
+  pkgdata <- prepare flags stream mpkgid True
   when (stage == Binary) $
     void $ pkgInstallMissing' pkgdata
 
   let pkgDesc = packageDesc pkgdata
       mspec = specFilename pkgdata
-  specFile <- maybe (createSpecFile normal flags False pkgtype subpackage stream Nothing mpkg)
+  specFile <- maybe (createSpecFile normal flags False pkgtype subpackage stream Nothing mpkgid)
               (\ s -> putStrLn ("Using existing" +-+ s) >> return s)
               mspec
-  let pkg = package pkgDesc
-  bringTarball (showPkgId pkg) True specFile
+  let pkgid = package pkgDesc
+  bringTarball pkgid True specFile
   rpmbuild stage specFile
 
   return specFile
 
-rpmBuild_ :: RpmStage -> Flags -> PackageType -> Bool -> Stream -> Maybe Package -> IO ()
-rpmBuild_ stage flags pkgtype subpackage stream mpkg =
-  void $ rpmBuild stage flags pkgtype subpackage stream mpkg
+rpmBuild_ :: RpmStage -> Flags -> PackageType -> Bool -> Stream ->
+             Maybe PackageIdentifier -> IO ()
+rpmBuild_ stage flags pkgtype subpackage stream mpkgid =
+  void $ rpmBuild stage flags pkgtype subpackage stream mpkgid
diff --git a/src/Commands/Spec.hs b/src/Commands/Spec.hs
--- a/src/Commands/Spec.hs
+++ b/src/Commands/Spec.hs
@@ -20,16 +20,15 @@
   createSpecFile, createSpecFile_
   ) where
 
-import Dependencies (ghcDep, LibPkgType(..), missingLibraries,
+import Dependencies (missingLibraries,
                      missingOtherPkgs, notSrcOrInst,
                      packageDependencies, pkgSuffix, subPackages,
                      testsuiteDependencies')
 import Types
-import PackageUtils (bringTarball, getPkgName, latestPackage,
-                     PackageData (..), packageName, packageVersion,
-                     prepare, removePrefix)
-import SimpleCabal (mkPackageName, PackageName, showVersion, unPackageName)
-import SimpleCmd ((+-+))
+import PackageUtils (bringTarball, latestPackage, PackageData (..), prepare)
+import SimpleCabal (buildable, mkPackageName, PackageDescription (..),
+                    PackageIdentifier(..), PackageName, showVersion)
+import SimpleCmd ((+-+), removePrefix)
 
 import Control.Monad    (filterM, unless, void, when, (>=>))
 
@@ -46,15 +45,17 @@
 import Data.Time.Format (formatTime)
 import qualified Data.Version as V
 
+import Distribution.Text (display)
 import Distribution.License  (License (..)
 #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,2,0)
                              , licenseFromSPDX
 #endif
                              )
 
-import Distribution.PackageDescription (BuildInfo (..), PackageDescription (..),
-                                        Executable (..),
-                                        Library (..), exeName, hasExes, hasLibs,
+import Distribution.PackageDescription (
+                                        Executable (buildInfo),
+                                        Library (exposedModules), exeName,
+                                        hasExes, hasLibs,
 #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,2,0)
                                         license,
 #endif
@@ -87,17 +88,18 @@
 unUnqualComponentName = id
 #endif
 
-createSpecFile :: Verbosity -> Flags -> Bool -> PackageType -> Bool -> Stream -> Maybe FilePath -> Maybe Package -> IO FilePath
-createSpecFile verbose flags force pkgtype subpackage stream mdest mpkg = do
-  pkgdata <- prepare flags stream mpkg True
+createSpecFile :: Verbosity -> Flags -> Bool -> PackageType -> Bool -> Stream
+               -> Maybe FilePath -> Maybe PackageIdentifier -> IO FilePath
+createSpecFile verbose flags force pkgtype subpackage stream mdest mpkgid = do
+  pkgdata <- prepare flags stream mpkgid True
   let mspec = case pkgtype of
                 SpecFile f -> Just f
                 _ -> specFilename pkgdata
       docs = docFilenames pkgdata
       licensefiles = licenseFilenames pkgdata
       pkgDesc = packageDesc pkgdata
-      pkg = package pkgDesc
-      name = unPackageName $ packageName pkg
+      pkgid = package pkgDesc
+      name = display $ pkgName pkgid
       standalone = pkgtype == StandalonePkg
       hasExec = hasExes pkgDesc
       hasLib = hasLibs pkgDesc
@@ -188,7 +190,7 @@
     return $ nub (subs ++ miss)
   subpkgs <- if subpackage then
     mapM (getsubpkgMacro stream specFile >=>
-           \(m,pv) -> global m pv >> return ("%{" ++ m ++ "}")) missingLibs
+           \(m,pv) -> global m (display pv) >> return ("%{" ++ m ++ "}")) missingLibs
     else return []
   let hasSubpkgs = subpkgs /= []
   when hasSubpkgs $ do
@@ -197,11 +199,11 @@
 
   let testsuiteDeps = testsuiteDependencies' pkgDesc
   unless (null testsuiteDeps) $ do
-    missTestDeps <- filterM notSrcOrInst $ map (ghcDep LibDevel) testsuiteDeps
+    missTestDeps <- filterM notSrcOrInst $ map (RpmHsLib Devel) testsuiteDeps
     put $ "%bcond_" ++ (if null missTestDeps then "without" else "with") +-+ "tests"
     putNewline
 
-  let version = packageVersion pkg
+  let version = display $ pkgVersion pkgid
       release = "1"
       revised = isJust $ lookup "x-revision" (customFieldsPD pkgDesc)
   putHdr "Name" (if binlib then "%{pkg_name}" else basename)
@@ -230,13 +232,13 @@
   -- `not hasLib` is for -static
     when (mkPackageName "Cabal" `notElem` deps {-|| not hasLib-}) $
       putHdr "BuildRequires" "ghc-Cabal-devel"
-    mapM_ (\ d -> (if d `elem` missingLibs then putHdrComment else putHdr) "BuildRequires" (ghcDep LibDevel d)) setupDeps
+    mapM_ (\ d -> (if d `elem` missingLibs then putHdrComment else putHdr) "BuildRequires" (show (RpmHsLib Devel d))) setupDeps
   putHdr "BuildRequires" $ "ghc-rpm-macros" ++ (if hasSubpkgs then "-extra" else "")
 
   unless (null deps) $ do
 --    put "# Build"
-    let ghcLibDep = ghcDep $ if hasLibPkg then LibProf else LibStatic
-    mapM_ (\ d -> (if d `elem` missingLibs then putHdrComment else putHdr) "BuildRequires" (ghcLibDep d)) $ sort deps
+    let ghcLibDep = RpmHsLib $ if hasLibPkg then Prof else Static
+    mapM_ (\ d -> (if d `elem` missingLibs then putHdrComment else putHdr) "BuildRequires" (show (ghcLibDep d))) $ sort deps
   let otherdeps = sort $ tools ++ clibs ++ pkgcfgs
   unless (null otherdeps) $ do
 --    put "# Other"
@@ -249,12 +251,13 @@
   let testDeps = sort $ testsuiteDeps \\ (mkPackageName "Cabal" : (deps ++ setupDeps))
   unless (null testDeps) $ do
     put "%if %{with tests}"
-    mapM_ (putHdr "BuildRequires" . ghcDep LibDevel) testDeps
+    mapM_ (putHdr "BuildRequires" . show . RpmHsLib Devel) testDeps
     put "%endif"
 
   let common = binlib && datafiles /= [] && not standalone
+      versionRelease = " = %{version}-%{release}"
   when common $
-    putHdr "Requires" "%{name}-common = %{version}-%{release}"
+    putHdr "Requires" $ "%{name}-common" ++ versionRelease
   put "# End cabal-rpm deps"
   when standalone $
     putHdr "BuildRequires" "cabal-install > 1.18"
@@ -280,51 +283,54 @@
   --  but libraries wihout exposedModules should be useless/redundant)
   let hasModules =
         hasLib && ((notNull . exposedModules . fromJust . library) pkgDesc || mkPackageName "haskell-gi" `elem` (deps ++ setupDeps))
+      baselibpkg = if binlib then "ghc-%{name}" else "%{name}"
 
   when hasLibPkg $ do
     when (binlib && hasModules) $ do
-      put $ "%package" +-+ subpkgParam LibBase
+      put $ "%package" +-+ subpkgParam Base
       putHdr "Summary" $ "Haskell" +-+ pkg_name +-+ "library"
       when common $
-        putHdr "Requires" "%{name}-common = %{version}-%{release}"
+        putHdr "Requires" $ "%{name}-common" ++ versionRelease
       putNewline
-      put $ "%description" +-+ subpkgParam LibBase
+      put $ "%description" +-+ subpkgParam Base
       put $ wrapGenDesc $ "This package provides the Haskell" +-+ pkg_name +-+ "shared library."
       sectionNewline
     let isa = "%{?_isa}"
-    put $ "%package" +-+ subpkgParam LibDevel
+    put $ "%package" +-+ subpkgParam Devel
     putHdr "Summary" $ "Haskell" +-+ pkg_name +-+ "library development files"
-    putHdr "Provides" $ (if binlib then "ghc-%{name}" else "%{name}") ++ "-static = %{version}-%{release}"
-    putHdr "Provides" $ (if binlib then "ghc-%{name}" else "%{name}") ++ "-static" ++ isa +-+ "= %{version}-%{release}"
+    putHdr "Provides" $ baselibpkg ++ "-static" ++ versionRelease
+    putHdr "Provides" $ baselibpkg ++ "-static" ++ isa ++ versionRelease
     put "%if %{defined ghc_version}"
     putHdr "Requires" "ghc-compiler = %{ghc_version}"
     put "%endif"
     when hasModules $
-      putHdr "Requires" $ (if binlib then "ghc-%{name}" else "%{name}") ++ isa +-+ "= %{version}-%{release}"
+      putHdr "Requires" $ baselibpkg ++ isa ++ versionRelease
     unless (null $ clibs ++ pkgcfgs) $ do
       put "# Begin cabal-rpm deps:"
       mapM_ (putHdr "Requires") $ sort $ map (++ isa) clibs ++ pkgcfgs
       put "# End cabal-rpm deps"
     putNewline
-    put $ "%description" +-+ subpkgParam LibDevel
+    put $ "%description" +-+ subpkgParam Devel
     put $ wrapGenDesc $ "This package provides the Haskell" +-+ pkg_name +-+ "library development files."
     sectionNewline
 -- ? when hasModules $
     put "%if %{with haddock}"
-    put $ "%package" +-+ subpkgParam LibDoc
+    put $ "%package" +-+ subpkgParam Doc
     putHdr "Summary" $ "Haskell" +-+ pkg_name +-+ "library documentation"
+    putHdr "BuildArch" "noarch"
     putNewline
-    put $ "%description" +-+ subpkgParam LibDoc
+    put $ "%description" +-+ subpkgParam Doc
     put $ wrapGenDesc $ "This package provides the Haskell" +-+ pkg_name +-+ "library documentation."
     put "%endif"
     sectionNewline
 
     put "%if %{with ghc_prof}"
-    put $ "%package" +-+ subpkgParam LibProf
+    put $ "%package" +-+ subpkgParam Prof
     putHdr "Summary" $ "Haskell" +-+ pkg_name +-+ "profiling library"
-    putHdr "Requires" $ (if binlib then "ghc-%{name}" else "%{name}") ++ "-devel" ++ isa +-+ "= %{version}-%{release}"
+    putHdr "Requires" $ baselibpkg ++ "-devel" ++ isa ++ versionRelease
+    putHdr "Supplements" $ "(" ++ baselibpkg ++ "-devel and ghc-prof)"
     putNewline
-    put $ "%description" +-+ subpkgParam LibProf
+    put $ "%description" +-+ subpkgParam Prof
     put $ wrapGenDesc $ "This package provides the Haskell" +-+ pkg_name +-+ "profiling library."
     put "%endif"
     sectionNewline
@@ -428,9 +434,9 @@
     sectionNewline
 
   when hasLibPkg $ do
-    let filesParams lt = subpkgParam lt +-+ "-f" +-+ (if binlib then "ghc-" else "" ) ++ "%{name}" ++ pkgSuffix lt ++ ".files"
+    let filesParams lt = subpkgParam lt +-+ "-f" +-+ baselibpkg ++ pkgSuffix lt ++ ".files"
     when hasModules $ do
-      put $ "%files" +-+ filesParams LibBase
+      put $ "%files" +-+ filesParams Base
       unless common $ do
         put "# Begin cabal-rpm files:"
         mapM_ (\ l -> put $ license_macro +-+ l) licensefiles
@@ -439,7 +445,7 @@
         put "# End cabal-rpm files"
       sectionNewline
 
-    put $ "%files" +-+ filesParams LibDevel
+    put $ "%files" +-+ filesParams Devel
     -- put "# Begin cabal-rpm files:"
     unless hasModules $
       mapM_ (\ l -> put $ license_macro +-+ l) licensefiles
@@ -451,11 +457,12 @@
     sectionNewline
 
     put "%if %{with haddock}"
-    put $ "%files" +-+ filesParams LibDoc
+    put $ "%files" +-+ filesParams Doc
+    mapM_ (\ l -> put $ license_macro +-+ l) licensefiles
     put "%endif"
     sectionNewline
     put "%if %{with ghc_prof}"
-    put $ "%files" +-+ filesParams LibProf
+    put $ "%files" +-+ filesParams Prof
     put "%endif"
     sectionNewline
 
@@ -467,9 +474,10 @@
   hClose h
   return specFile'
 
-createSpecFile_ :: Maybe FilePath -> Verbosity -> Flags -> Bool -> PackageType -> Bool -> Stream -> Maybe Package -> IO ()
-createSpecFile_ mdest verbose flags force pkgtype subpackage stream mpkg =
-  void (createSpecFile verbose flags force pkgtype subpackage stream mdest mpkg)
+createSpecFile_ :: Maybe FilePath -> Verbosity -> Flags -> Bool -> PackageType
+                -> Bool -> Stream -> Maybe PackageIdentifier -> IO ()
+createSpecFile_ mdest verbose flags force pkgtype subpackage stream mpkgid =
+  void (createSpecFile verbose flags force pkgtype subpackage stream mdest mpkgid)
 
 isBuildable :: Executable -> Bool
 isBuildable exe = buildable $ buildInfo exe
@@ -530,15 +538,28 @@
     paragraphs :: [String] -> [String]
     paragraphs = map (unlines . filter notNull) . groupBy (const notNull)
 
-getsubpkgMacro :: Stream -> FilePath -> PackageName -> IO (String, String)
+getsubpkgMacro :: Stream -> FilePath -> PackageName
+               -> IO (String, PackageIdentifier)
 getsubpkgMacro stream spec pkg = do
-  let macro = filter (/= '-') $ unPackageName pkg
-  pkgver <- latestPackage stream pkg
-  bringTarball pkgver False spec
-  return (macro, pkgver)
+  let macro = filter (/= '-') $ display pkg
+  pkgid <- latestPackage stream pkg
+  bringTarball pkgid False spec
+  return (macro, pkgid)
 
 number :: [a] -> [(String,a)]
 number = zip (map show [(1::Int)..])
 
 notNull :: [a] -> Bool
 notNull = not . null
+
+getPkgName :: Maybe FilePath -> PackageDescription -> Bool -> IO (String, Bool)
+getPkgName (Just spec) pkgDesc binary = do
+  let name = display . pkgName $ package pkgDesc
+      pkgname = takeBaseName spec
+      hasLib = hasLibs pkgDesc
+  return $ if name == pkgname || binary then (name, hasLib) else (pkgname, False)
+getPkgName Nothing pkgDesc binary = do
+  let name = display . pkgName $ package pkgDesc
+      hasExec = hasExes pkgDesc
+      hasLib = hasLibs pkgDesc
+  return $ if binary || hasExec && not hasLib then (name, hasLib) else ("ghc-" ++ name, False)
diff --git a/src/Commands/Update.hs b/src/Commands/Update.hs
--- a/src/Commands/Update.hs
+++ b/src/Commands/Update.hs
@@ -19,14 +19,14 @@
 import Commands.Spec (createSpecFile)
 import FileUtils (withTempDirectory)
 import PackageUtils (PackageData (..), bringTarball, editSpecField,
-                     getRevisedCabal, getSpecField, latestPackage, packageName,
-                     packageVersion, patchSpec, prepare,
-                     readVersion, removePrefix, removeSuffix)
+                     getRevisedCabal, getSpecField, latestPackage,
+                     patchSpec, prepare)
 import SysCmd (die)
 import Types
 
-import SimpleCabal (showPkgId, unPackageName)
-import SimpleCmd (cmd_, grep_, shell_, (+-+))
+import SimpleCabal (PackageDescription (customFieldsPD, package),
+                    PackageIdentifier (..), showVersion)
+import SimpleCmd (cmd_, grep_, removeSuffix, shell_, (+-+))
 import SimpleCmd.Git (rwGitDir)
 #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
 #else
@@ -34,7 +34,7 @@
 #endif
 import Control.Monad (unless, when)
 import Data.Maybe (isJust)
-import Distribution.PackageDescription (PackageDescription (..))
+import Distribution.Text (display)
 import Distribution.Verbosity (silent)
 import System.Directory (createDirectory, renameFile, setCurrentDirectory)
 import System.FilePath ((</>), (<.>))
@@ -46,38 +46,35 @@
     Nothing -> die "No (unique) .spec file in directory."
     Just spec -> do
       let pkgDesc = packageDesc pkgdata
-          pkg = package pkgDesc
-          name = packageName pkg
-          ver = packageVersion pkg
-          curVer = readVersion ver
-          current = showPkgId pkg
+          oldPkgId = package pkgDesc
+          name = pkgName oldPkgId
           revised = isJust $ lookup "x-revision" (customFieldsPD pkgDesc)
-      latest <- case mver of
-                    Just v -> return v
+      newPkgId <- case mver of
+                    Just v -> return $ PackageIdentifier name (read v)
                     _ -> latestPackage stream name
-      let newver = removePrefix (unPackageName name ++ "-") latest
-          latestVer = readVersion newver
-          updated = latestVer > curVer
-      if latestVer < curVer
-        then putStrLn $ "current" +-+ ver +-+ "is newer!"
+      let newver = pkgVersion newPkgId
+          oldver = pkgVersion oldPkgId
+          updated = newver > oldver
+      if newver < oldver
+        then putStrLn $ "current" +-+ display oldver +-+ "is newer!"
         else do
-        getRevisedCabal latest
+        getRevisedCabal newPkgId
         unless updated $
           putStrLn "Package is already latest version."
         when (not revised || updated) $
           withTempDirectory $ \cwd -> do
             let specfile = cwd </> spec
             subpkg <- grep_ "%{subpkgs}" specfile
-            (curspec, _) <- createSpecVersion current specfile revised subpkg
-            (newspec, newrevised) <- createSpecVersion latest specfile True subpkg
+            (curspec, _) <- createSpecVersion oldPkgId specfile revised subpkg
+            (newspec, newrevised) <- createSpecVersion newPkgId specfile True subpkg
             let suffix = "%{?dist}"
                 defrelease = "1"
             currel <- removeSuffix suffix <$> getSpecField "Release" specfile
             editSpecField "Release" (defrelease ++ suffix) specfile
             patchSpec False (Just cwd) curspec newspec
-            ver' <- getSpecField "Version" specfile
+            ver' <- readVersion <$> getSpecField "Version" specfile
             when (ver' /= newver) $
-              editSpecField "Version" newver specfile
+              editSpecField "Version" (showVersion newver) specfile
             if updated && not subpkg
               then editSpecField "Release" (defrelease ++ suffix) specfile
               else editSpecField "Release" (currel ++ suffix) specfile
@@ -85,31 +82,31 @@
               -- FIXME reset when all subpkgs updated
               unless subpkg $
                 editSpecField "Release" ("0" ++ suffix) specfile
-              cmd_ "rpmdev-bumpspec" ["-c", "update to" +-+ newver, specfile]
+              cmd_ "rpmdev-bumpspec" ["-c", "update to" +-+ showVersion newver, specfile]
               setCurrentDirectory cwd
               rwGit <- rwGitDir
               when (rwGit && subpkg) $ do
                 cmd_ "cp" ["-p", "sources", "sources.cblrpm"]
-                cmd_ "sed" ["-i", "/" ++ current <.> "tar.gz" ++ "/d", "sources.cblrpm"]
-              bringTarball latest False spec
+                cmd_ "sed" ["-i", "/" ++ display oldPkgId <.> "tar.gz" ++ "/d", "sources.cblrpm"]
+              bringTarball newPkgId False spec
               when rwGit $ do
-                cmd_ "fedpkg" ["new-sources", latest <.> "tar.gz"]
+                cmd_ "fedpkg" ["new-sources", display newPkgId <.> "tar.gz"]
                 when subpkg $ do
                   shell_ $ "cat sources >>" +-+ "sources.cblrpm"
                   renameFile "sources.cblrpm" "sources"
                 when newrevised $
-                  cmd_ "git" ["add", latest <.> "cabal"]
+                  cmd_ "git" ["add", display newPkgId <.> "cabal"]
                 when revised $
-                  cmd_ "git" ["rm", current <.> "cabal"]
-                cmd_ "git" ["commit", "-a", "-m", "update to" +-+ newver]
+                  cmd_ "git" ["rm", display oldPkgId <.> "cabal"]
+                cmd_ "git" ["commit", "-a", "-m", "update to" +-+ showVersion newver]
   where
-    createSpecVersion :: String -> String -> Bool -> Bool -> IO (FilePath, Bool)
-    createSpecVersion pkgver spec revise subpkg = do
-      pd <- prepare [] stream (Just pkgver) revise
+    createSpecVersion :: PackageIdentifier -> String -> Bool -> Bool -> IO (FilePath, Bool)
+    createSpecVersion pkgid spec revise subpkg = do
+      pd <- prepare [] stream (Just pkgid) revise
       let pkgdata' = pd { specFilename = Just spec }
-          dir = pkgver ++ if revise then ".revised" else ".orig"
+          dir = display pkgid ++ if revise then ".revised" else ".orig"
       createDirectory dir
-      newspec <- createSpecFile silent [] False (SpecFile spec) subpkg stream (Just dir) (Just pkgver)
+      newspec <- createSpecFile silent [] False (SpecFile spec) subpkg stream (Just dir) (Just pkgid)
       let newrevised =
             let pkgDesc = packageDesc pkgdata' in
               isJust $ lookup "x-revision" (customFieldsPD pkgDesc)
diff --git a/src/Dependencies.hs b/src/Dependencies.hs
--- a/src/Dependencies.hs
+++ b/src/Dependencies.hs
@@ -17,8 +17,6 @@
 
 module Dependencies (
   dependencies,
-  ghcDep,
-  LibPkgType(..),
   missingLibraries,
   missingOtherPkgs,
   missingPackages,
@@ -32,14 +30,16 @@
   testsuiteDependencies'
   ) where
 
-import PackageUtils (PackageData(..), prepare, removeLibSuffix,
-                     repoquery, rpmInstall, stripPkgDevel)
+import PackageUtils (PackageData(..), prepare, repoquery, rpmInstall)
 import Types
 
-import SimpleCabal (buildDependencies, mkPackageName, exeDepName,
+import SimpleCabal (buildDependencies, mkPackageName,
+                    exeDepName,
+                    PackageDescription (package),
+                    PackageIdentifier,
                     PackageName, pkgcfgDepName, pkgName,
-                    setupDependencies, testsuiteDependencies, unPackageName)
-import SimpleCmd (cmd, cmdBool, warning, (+-+))
+                    setupDependencies, testsuiteDependencies)
+import SimpleCmd (cmd, cmdBool, removePrefix, removeSuffix, warning, (+-+))
 import SimpleCmd.Rpm (rpmspec)
 
 #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
@@ -48,13 +48,12 @@
 #endif
 import Control.Monad (filterM, when, unless)
 
-import Data.List (delete, isPrefixOf, isSuffixOf, nub, (\\))
+import Data.List (delete, isSuffixOf, nub, (\\))
 import Data.Maybe (catMaybes, fromJust, isNothing)
 
-import Distribution.PackageDescription (PackageDescription (..),
-                                        allBuildInfo,
-                                        BuildInfo (..),
-                                        )
+import Distribution.Text (display)
+import Distribution.PackageDescription (allBuildInfo, BuildInfo (..))
+
 import System.Directory (doesDirectoryExist, doesFileExist)
 import System.FilePath ((<.>), (</>))
 
@@ -62,22 +61,11 @@
 excludedPkgs =
   flip notElem $ map mkPackageName ["ghc-prim", "integer-gmp"]
 
-data LibPkgType = LibBase | LibDevel | LibProf | LibDoc | LibStatic
-
-instance Show LibPkgType where
-  show LibBase = ""
-  show LibDevel = "devel"
-  show LibProf = "prof"
-  show LibDoc = "doc"
-  show LibStatic = "static"
-
 pkgSuffix :: LibPkgType -> String
 pkgSuffix lpt =
-  let rep = show lpt in
   if null rep then "" else '-' : rep
-
-ghcDep :: LibPkgType -> PackageName -> String
-ghcDep lt p = "ghc-" ++ unPackageName p ++ pkgSuffix lt
+  where
+    rep = show lpt
 
 dependencies :: PackageDescription  -- ^pkg description
                 -> ([PackageName], [PackageName], [String], [String], [String])
@@ -92,7 +80,7 @@
         clibs = nub $ concatMap extraLibs buildinfo
         stdcpp = "stdc++"
         cpp = ["gcc-c++" | stdcpp `elem` clibs]
-    in (deps, setup \\ (mkPackageName "Cabal" : deps), delete (unPackageName self) tools ++ cpp, clibs \\ ["m", stdcpp], pkgcfgs)
+    in (deps, setup \\ (mkPackageName "Cabal" : deps), delete (display self) tools ++ cpp, clibs \\ ["m", stdcpp], pkgcfgs)
 
 data QueryBackend = Rpm | Repoquery deriving Eq
 
@@ -151,35 +139,43 @@
 testsuiteDependencies' =
   filter excludedPkgs . testsuiteDependencies
 
-missingPackages :: PackageDescription -> IO [String]
+missingPackages :: PackageDescription -> IO [RpmPackage]
 missingPackages pkgDesc = do
   (deps, setup, tools, clibs, pkgcfgs) <- packageDependencies pkgDesc
   pcpkgs <- mapM derefPkg pkgcfgs
-  filterM notSrcOrInst $ nub $ map (ghcDep LibDevel) (deps ++ setup) ++ ["ghc-Cabal-devel", "ghc-rpm-macros"] ++ tools ++ clibs ++ pcpkgs
+  filterM notSrcOrInst $ nub $ map (RpmHsLib Devel) (deps ++ setup ++ [mkPackageName "Cabal"]) ++ map RpmOther (["ghc-rpm-macros"] ++ tools ++ clibs ++ pcpkgs)
 
 missingLibraries :: PackageDescription -> IO [PackageName]
 missingLibraries pkgDesc = do
   (deps, setup, _, _, _) <- packageDependencies pkgDesc
-  bdeps <- filterM (notSrcOrInst . ghcDep LibProf) deps
-  sdeps <- filterM (notSrcOrInst . ghcDep LibDevel) $ (mkPackageName "Cabal" : setup) \\ deps
+  bdeps <- filterM (notSrcOrInst . RpmHsLib Prof) deps
+  sdeps <- filterM (notSrcOrInst . RpmHsLib Devel) $ (mkPackageName "Cabal" : setup) \\ deps
   return $ bdeps ++ sdeps
 
 missingOtherPkgs :: PackageDescription -> IO [String]
 missingOtherPkgs pkgDesc = do
   (_, _, tools, clibs, pkgcfgs) <- packageDependencies pkgDesc
   pcpkgs <- mapM derefPkg pkgcfgs
-  filterM notSrcOrInst $ nub $ ["ghc-rpm-macros"] ++ tools ++ clibs ++ pcpkgs
+  filterM (notSrcOrInst . RpmOther) $ nub $ ["ghc-rpm-macros"] ++ tools ++ clibs ++ pcpkgs
 
-notSrcOrInst :: String -> IO Bool
+notSrcOrInst :: RpmPackage -> IO Bool
 notSrcOrInst pkg = do
-  src <- doesDirectoryExist (".." </> removeLibSuffix pkg)
+  src <- doesDirectoryExist (".." </> show (baseLibPackage pkg))
   if src then return False
     else notInstalled pkg
+  where
+    baseLibPackage :: RpmPackage -> RpmPackage
+    baseLibPackage (RpmHsLib _ n) = RpmHsLib Base n
+    baseLibPackage p = p
 
-notInstalled :: String -> IO Bool
+notInstalled :: RpmPackage -> IO Bool
 notInstalled dep =
-  not <$> cmdBool "rpm" ["-q", "--quiet", "--whatprovides", shellQuote dep]
+  not <$> cmdBool "rpm" ["-q", "--quiet", "--whatprovides", quoteShow dep]
   where
+    quoteShow :: RpmPackage -> String
+    quoteShow (RpmOther cs) = shellQuote cs
+    quoteShow p = show p
+
     shellQuote :: String -> String
     shellQuote (c:cs) = (if c `elem` "()" then (['\\', c] ++) else (c:)) (shellQuote cs)
     shellQuote "" = ""
@@ -200,13 +196,16 @@
   develSubpkgs <- map stripPkgDevel . filter ("-devel" `isSuffixOf`) <$> maybe (return []) (rpmspec [] (Just "%{name}")) mspec
   let self = pkgName $ package pkgDesc
   return $ delete self $ map mkPackageName develSubpkgs
+  where
+    stripPkgDevel :: String -> String
+    stripPkgDevel = removeSuffix "-devel" . removePrefix "ghc-"
 
-pkgInstallMissing :: Flags -> Stream -> Maybe Package -> IO [String]
-pkgInstallMissing flags stream mpkg = do
-  pkgdata <- prepare flags stream mpkg True
+pkgInstallMissing :: Flags -> Stream -> Maybe PackageIdentifier -> IO [PackageName]
+pkgInstallMissing flags stream mpkgid = do
+  pkgdata <- prepare flags stream mpkgid True
   pkgInstallMissing' pkgdata
 
-pkgInstallMissing' :: PackageData -> IO [String]
+pkgInstallMissing' :: PackageData -> IO [PackageName]
 pkgInstallMissing' pkgdata = do
   let pkgDesc = packageDesc pkgdata
       mspec = specFilename pkgdata
@@ -214,32 +213,24 @@
   if null missing then return []
     else do
     subpkgs <- subPackages mspec pkgDesc
-    let pkgs = map (ghcDep LibProf) $ missing \\ subpkgs
+    let pkgs = missing \\ subpkgs
     pkgconfdir <- fromJust . lookup "Global Package DB" . read <$> cmd "ghc" ["--info"]
-    putStrLn $ "Running repoquery" +-+ unwords pkgs
-    repopkgs <- filter (/= "") <$> mapM (repoqueryPackageConf pkgconfdir) pkgs
+    putStrLn $ "Running repoquery" +-+ unwords (map display pkgs)
+    repopkgs <- catMaybes <$> mapM (repoqueryPackageConf pkgconfdir) pkgs
     let missing' = pkgs \\ repopkgs
     unless (null missing') $ do
       putStrLn "Unavailable dependencies:"
-      mapM_ putStrLn missing'
+      mapM_ (putStrLn . display) missing'
     unless (null repopkgs) $ do
       putStrLn "Uninstalled dependencies:"
-      mapM_ putStrLn repopkgs
+      mapM_ (putStrLn . display) repopkgs
       -- fedora <- rpmEval "%fedora"
       -- let nogpgcheck = ["--nogpgcheck" | fedora `elem` []]
-      rpmInstall True $ map showPkg repopkgs
+      rpmInstall True $ map (show . RpmHsLib Prof) repopkgs
     return missing'
-        where
-          showPkg :: String -> String
-          showPkg p = if '(' `elem` p then show p else p
-
-repoqueryPackageConf :: String -> String -> IO String
-repoqueryPackageConf pkgconfd pkg =
-  let key = if isGhcDevelPkg pkg
-        then pkgconfd </> stripPkgDevel pkg ++ "-[0-9]*.conf"
-        else pkg in
-    repoquery ["--qf", "%{name}"] key
-
-isGhcDevelPkg :: String -> Bool
-isGhcDevelPkg p =
-  "ghc-" `isPrefixOf` p && "-devel" `isSuffixOf` p
+      where
+        repoqueryPackageConf :: String -> PackageName -> IO (Maybe PackageName)
+        repoqueryPackageConf pkgconfd pkg = do
+              let key = pkgconfd </> display pkg ++ "-[0-9]*.conf"
+              res <- repoquery ["--qf", "%{name}"] key
+              return $ if null res then Nothing else  Just pkg
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -16,12 +16,16 @@
 
 module Main where
 
+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,13,0))
+#else
 import Control.Applicative ((<|>)
 #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
 #else
                          , (<$>), (<*>)
 #endif
                            )
+#endif
+import Distribution.Text (simpleParse)
 import Distribution.Verbosity (normal, silent)
 import System.IO (BufferMode(LineBuffering), hSetBuffering, stdout)
 
@@ -34,11 +38,13 @@
 import Commands.Spec (createSpecFile_)
 import Commands.Update (update)
 
+import Options.Applicative (maybeReader)
 import PackageUtils (RpmStage (..))
-import Paths_cabal_rpm       (version)
+import Paths_cabal_rpm (version)
 import Types
 
-import SimpleCmdArgs --(simpleCmdArgs, subcommands)
+import SimpleCabal (PackageIdentifier)
+import SimpleCmdArgs
 
 main :: IO ()
 main = do
@@ -47,36 +53,37 @@
     "RPM package tool for Haskell Stackage/Hackage packages" $
     subcommands
     [ Subcommand "spec" "Generate a spec file" $
-      createSpecFile_ Nothing <$> quietOpt <*> flags <*> force <*> pkgtype <*> subpackage <*> stream <*> packageArg
+      createSpecFile_ Nothing <$> quietOpt <*> flags <*> force <*> pkgtype <*> subpackage <*> stream <*> pkgId
     , Subcommand "srpm" "Generate an srpm" $
-      rpmBuild_ Source <$> flags <*> pkgtype <*> subpackage <*> stream <*> packageArg
+      rpmBuild_ Source <$> flags <*> pkgtype <*> subpackage <*> stream <*> pkgId
     , Subcommand "prep" "Unpack source" $
-      rpmBuild_ Prep <$> flags <*> pkgtype <*> subpackage <*> stream <*> packageArg
+      rpmBuild_ Prep <$> flags <*> pkgtype <*> subpackage <*> stream <*> pkgId
     , Subcommand "local" "Build rpm package locally" $
-      rpmBuild_ Binary <$> flags <*> pkgtype <*> subpackage <*> stream <*> packageArg
+      rpmBuild_ Binary <$> flags <*> pkgtype <*> subpackage <*> stream <*> pkgId
     , Subcommand "build" "Alias for 'local' - builds rpm locally" $
-      rpmBuild_ Binary <$> flags <*> pkgtype <*> subpackage <*> stream <*> packageArg
+      rpmBuild_ Binary <$> flags <*> pkgtype <*> subpackage <*> stream <*> pkgId
     , Subcommand "builddep" "Install build dependencies with dnf" $
-      builddep <$> flags <*> stream <*> packageArg
+      builddep <$> flags <*> stream <*> pkgId
     , Subcommand "install" "Build and install recursively" $
-      install <$> flags <*> pkgtype <*> subpackage <*> stream <*> packageArg
-    -- should be (optional versionArg) not pkgver
+      install <$> flags <*> pkgtype <*> subpackage <*> stream <*> pkgId
+    -- should be (optional versionArg) not pkgid
     , Subcommand "diff" "Diff with pristine generated spec file" $
-      diff <$> flags <*> pkgtype <*> stream <*> packageArg
+      diff <$> flags <*> pkgtype <*> stream <*> pkgId
     , Subcommand "depends" "List Haskell dependencies" $
-      depends Depends <$> flags <*> stream <*> packageArg
+      depends Depends <$> flags <*> stream <*> pkgId
     , Subcommand "requires" "List buildrequires for package" $
-      depends Requires <$> flags <*> stream <*> packageArg
+      depends Requires <$> flags <*> stream <*> pkgId
     , Subcommand "missingdeps" "List dependencies not available" $
-      depends Missing <$> flags <*> stream <*> packageArg
+      depends Missing <$> flags <*> stream <*> pkgId
+    -- should be just Maybe PackageName
     , Subcommand "refresh" "Refresh spec file to lastest packaging" $
-      refresh <$> dryrun <*> pkgtype <*> stream <*> packageArg
+      refresh <$> dryrun <*> pkgtype <*> stream <*> pkgId
     , Subcommand "update" "Update package to latest version" $
       update <$> stream <*> optional versionArg
     ]
   where
-    packageArg :: Parser (Maybe Package)
-    packageArg = optional (strArg "PKG[VER]")
+    pkgId :: Parser (Maybe PackageIdentifier)
+    pkgId = optional (argumentWith (maybeReader simpleParse) "PKG[VER]")
 
     stream :: Parser Stream
     stream = optionalWith auto 's' "stream" "STREAM" "Stackage stream or Hackage" (LTS "13")
@@ -103,4 +110,3 @@
     -- FIXME: use Version
     versionArg :: Parser String
     versionArg = strArg "VERSION"
-
diff --git a/src/PackageUtils.hs b/src/PackageUtils.hs
--- a/src/PackageUtils.hs
+++ b/src/PackageUtils.hs
@@ -18,37 +18,28 @@
   cabal_,
   editSpecField,
   getRevisedCabal,
-  getPkgName,
   getSpecField,
   latestPackage,
-  nameVersion,
   PackageData (..),
   packageManager,
-  packageName,
-  packageVersion,
   patchSpec,
   prepare,
-  readVersion,
-  removeLibSuffix,
-  removePrefix,
-  removeSuffix,
   repoquery,
   rpmbuild,
   rpmInstall,
-  RpmStage (..),
-  stripPkgDevel,
-  unPackageName
+  RpmStage (..)
   ) where
 
 import FileUtils (filesWithExtension, fileWithExtension,
                   getDirectoryContents_, mktempdir, withCurrentDirectory,
                   withTempDirectory)
 import SimpleCabal (finalPackageDescription, licenseFiles, mkPackageName,
-                    PackageName, packageName, packageVersion,
-                    tryFindPackageDesc, unPackageName)
+                    PackageDescription, PackageIdentifier(..), PackageName,
+                    tryFindPackageDesc)
 import SimpleCmd (cmd, cmd_, cmdIgnoreErr, cmdLines, grep_, removePrefix,
-                  removeSuffix, sudo, sudo_, (+-+))
+                  sudo, sudo_, (+-+))
 import SimpleCmd.Git (isGitDir, grepGitConfig)
+import SimpleCmd.Rpm (rpmspec)
 import SysCmd (optionalProgram, requireProgram, rpmEval)
 import Stackage (latestStackage)
 import Types
@@ -59,22 +50,12 @@
 #endif
 import Control.Monad    (filterM, unless, when)
 
-import Data.Char (isDigit, toLower)
-import Data.List (groupBy, isPrefixOf, isSuffixOf, nub, sort)
+import Data.Char (toLower)
+import Data.List (isPrefixOf, isSuffixOf, nub, sort)
 import Data.Maybe (isNothing, isJust, fromJust)
 import Data.Time.Clock (diffUTCTime, getCurrentTime)
-import Data.Version (
-#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
-                     Version,
-                     makeVersion,
-#else
-                     Version(..),
-#endif
-                    )
 
-import Distribution.PackageDescription (PackageDescription (..),
-                                        hasExes, hasLibs
-                                       )
+import Distribution.Text (display, simpleParse)
 
 import System.Directory (copyFile, createDirectoryIfMissing, doesDirectoryExist,
                          doesFileExist, getCurrentDirectory,
@@ -82,19 +63,12 @@
                          removeDirectoryRecursive, renameFile,
                          setCurrentDirectory)
 import System.Environment (getEnv)
-import System.FilePath ((</>), (<.>), dropFileName, takeBaseName, takeExtensions,
+import System.FilePath ((</>), (<.>), dropFileName, takeExtensions,
                         takeFileName)
 import System.IO (hIsTerminalDevice, stdout)
 import System.Posix.Files (accessTime, fileMode, getFileStatus,
                            modificationTime, setFileMode)
 
-stripVersion :: String -> String
-stripVersion n | '-' `notElem` n = n
-stripVersion nv = if hasVer then reverse emaN else nv
-  where
-    (reV, '-':emaN) = break (== '-') $ reverse nv
-    hasVer = all (\c -> isDigit c || c == '.') reV
-
 simplePackageDescription :: Flags -> FilePath
                          -> IO (PackageDescription, [FilePath], [FilePath])
 simplePackageDescription flags cabalfile = do
@@ -117,12 +91,12 @@
                       in any (`isPrefixOf` lowerName) names
         unlikely name = not $ any (`isSuffixOf` name) ["~", ".cabal"]
 
-
 cabalFromSpec :: FilePath -> Bool -> IO FilePath
 cabalFromSpec specFile revise = do
-  -- no rpmspec command in RHEL 5 and 6
-  namever <- removePrefix "ghc-" . head <$> cmdLines "rpm" ["-q", "--qf", "%{name}-%{version}\n", "--specfile", specFile]
-  bringTarball namever revise specFile
+  namever <- removePrefix "ghc-" . head <$> rpmspec ["--srpm"] (Just "%{name}-%{version}") specFile
+  case simpleParse namever of
+    Nothing -> error "pkgid could not be parsed"
+    Just pkgid -> bringTarball pkgid revise specFile
   dExists <- doesDirectoryExist namever
   if dExists
     then do
@@ -136,8 +110,8 @@
     rpmbuild Prep specFile
   tryFindPackageDesc namever
 
-bringTarball :: FilePath -> Bool -> FilePath -> IO ()
-bringTarball nv revise spec = do
+bringTarball :: PackageIdentifier -> Bool -> FilePath -> IO ()
+bringTarball pkgid revise spec = do
   havespec <- doesFileExist spec
   sources <- if havespec
              then map sourceFieldFile <$> cmdLines "spectool" ["-S", spec]
@@ -153,14 +127,14 @@
     when havespec $
       createDirectoryIfMissing True srcdir
     mapM_ (copyTarball False srcdir) sources
-    haveLocalCabal <- doesFileExist $ srcdir </> nv <.> "cabal"
+    haveLocalCabal <- doesFileExist $ srcdir </> display pkgid <.> "cabal"
     when (not haveLocalCabal && revise) $
-      getRevisedCabal nv
+      getRevisedCabal pkgid
     allExist' <- and <$> mapM (doesFileExist . (srcdir </>)) sources
     unless allExist' $
       cmd_ "spectool" ["-g", "-S", "-C", srcdir, spec]
  where
-  tarfile = nv <.> "tar.gz"
+  tarfile = display pkgid <.> "tar.gz"
 
   sourceFieldFile :: String -> FilePath
   sourceFieldFile field =
@@ -181,8 +155,7 @@
       unless havecache cabalUpdate
       remotes <- getDirectoryContents_ cacheparent
 
-      let (n,v) = nameVersion nv
-          tarpath = n </> v </> tarfile
+      let tarpath = display (pkgName pkgid) </> display (pkgVersion pkgid) </> tarfile
           paths = map (\ repo -> cacheparent </> repo </> tarpath) remotes
       -- if more than one tarball, should maybe warn if they are different
       tarballs <- filterM doesFileExist paths
@@ -190,7 +163,7 @@
         then if ranFetch
              then error $ "No" +-+ tarfile +-+ "found"
              else do
-             cabal_ "fetch" ["-v0", "--no-dependencies", nv]
+             cabal_ "fetch" ["-v0", "--no-dependencies", display pkgid]
              copyTarball True dir file
         else do
         createDirectoryIfMissing True dir
@@ -207,25 +180,16 @@
       then getCurrentDirectory
       else fromJust <$> rpmEval "%{_sourcedir}"
 
-getRevisedCabal :: String -> IO ()
-getRevisedCabal nv = do
-  let (n,_) = nameVersion nv
-      file = n <.> "cabal"
+getRevisedCabal :: PackageIdentifier -> IO ()
+getRevisedCabal pkgid = do
+  let file = display (pkgName pkgid) <.> "cabal"
   dir <- getSourceDir
   withTempDirectory $ \ _ -> do
-    cmd_ "wget" ["--quiet", "https://hackage.haskell.org/package" </> nv </> file]
+    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 </> nv <.> "cabal"
-
-nameVersion :: String -> (String, String)
-nameVersion nv =
-  if '-' `notElem` nv
-    then error $ "nameVersion: malformed NAME-VER string" +-+ nv
-    else (reverse eman, reverse rev)
-  where
-    (rev, '-':eman) = break (== '-') $ reverse nv
+      renameFile file $ dir </> display pkgid <.> "cabal"
 
 data RpmStage = Binary | Source | Prep deriving Eq
 
@@ -238,22 +202,13 @@
   cwd <- getCurrentDirectory
   gitDir <- isGitDir "."
   let rpmdirs_override =
-        [ "--define="++ mcr +-+ cwd |
-          mcr <- ["_builddir", "_rpmdir", "_srcrpmdir", "_sourcedir"], gitDir]
+        [ "--define="++ mcr +-+ cwd | gitDir,
+          mcr <- ["_builddir", "_rpmdir", "_srcrpmdir", "_sourcedir"]]
   cmd_ "rpmbuild" $ ["-b" ++ rpmCmd] ++
     ["--nodeps" | mode == Prep] ++
     rpmdirs_override ++
     [spec]
 
-stripPkgDevel :: String -> String
-stripPkgDevel = removeSuffix "-devel" . removePrefix "ghc-"
-
-removeLibSuffix :: String -> String
-removeLibSuffix p | "-devel" `isSuffixOf` p = removeSuffix "-devel" p
-                  | "-prof" `isSuffixOf` p = removeSuffix "-prof" p
-                  | "-static" `isSuffixOf` p = removeSuffix "-static" p
-                  | otherwise = p
-
 cabalUpdate :: IO ()
 cabalUpdate = do
   home <- getEnv "HOME"
@@ -284,37 +239,40 @@
   cabalUpdate
   cmd_ "cabal" (c:args)
 
-tryUnpack :: String -> Bool -> IO (FilePath, Maybe FilePath)
-tryUnpack pkgver revise = do
-  isdir <- doesDirectoryExist pkgver
+
+tryUnpack :: PackageIdentifier -> Bool ->
+             IO (FilePath, Maybe FilePath) -- (cabalfile, mtmpdir)
+tryUnpack pkgid revise = do
+  let dir = display pkgid
+  isdir <- doesDirectoryExist dir
   if isdir
     then do
-    let (n,_) = nameVersion pkgver
-    mcabal <- withCurrentDirectory pkgver $ checkForCabalFile (Just n)
+    mcabal <- withCurrentDirectory dir $ checkForCabalFile (Just pkgid)
     if isJust mcabal then do
-      pth <- tryFindPackageDesc pkgver
+      pth <- tryFindPackageDesc dir
       return (pth, Nothing)
-      else error $ "could not find" +-+ n <.> "cabal"
+      else
+      error $ "could not find" +-+ display (pkgName pkgid) <.> "cabal"
     else do
     cwd <- getCurrentDirectory
     tmpdir <- mktempdir
     setCurrentDirectory tmpdir
-    cabal_ "unpack" $ ["-v0"] ++ ["--pristine" | not revise] ++ [pkgver]
-    pth <- tryFindPackageDesc pkgver
+    cabal_ "unpack" $ ["-v0"] ++ ["--pristine" | not revise] ++ [display pkgid]
+    pth <- tryFindPackageDesc dir
     setCurrentDirectory cwd
     return (tmpdir </> pth, Just tmpdir)
 
-latestPackage :: Stream -> PackageName -> IO String
+latestPackage :: Stream -> PackageName -> IO PackageIdentifier
 latestPackage Hackage pkg = latestHackage pkg
 latestPackage stream pkg = do
   stk <- latestStackage stream pkg
   case stk of
-    Just pv -> return pv
+    Just pkgid -> return pkgid
     Nothing -> latestHackage pkg
 
-latestHackage :: PackageName -> IO String
+latestHackage :: PackageName -> IO PackageIdentifier
 latestHackage pkgname = do
-  let pkg = unPackageName pkgname
+  let pkg = display pkgname
   contains_pkg <- cabal "list" ["-v0", pkg]
   let top = dropWhile (/= "*" +-+ pkg) contains_pkg
   if null top
@@ -327,22 +285,11 @@
       else do
       let res = pkg ++ "-" ++ head avails
       putStrLn $ res +-+ "in Hackage"
-      return res
-
-getPkgName :: Maybe FilePath -> PackageDescription -> Bool -> IO (String, Bool)
-getPkgName (Just spec) pkgDesc binary = do
-  let name = unPackageName . packageName $ package pkgDesc
-      pkgname = takeBaseName spec
-      hasLib = hasLibs pkgDesc
-  return $ if name == pkgname || binary then (name, hasLib) else (pkgname, False)
-getPkgName Nothing pkgDesc binary = do
-  let name = unPackageName . packageName $ package pkgDesc
-      hasExec = hasExes pkgDesc
-      hasLib = hasLibs pkgDesc
-  return $ if binary || hasExec && not hasLib then (name, hasLib) else ("ghc-" ++ name, False)
+      return $ PackageIdentifier (mkPackageName pkg) $ readVersion $ head avails
 
-checkForSpecFile :: Maybe String -> IO (Maybe FilePath)
-checkForSpecFile mpkg = do
+checkForSpecFile :: Maybe PackageIdentifier -> IO (Maybe FilePath)
+checkForSpecFile mpkgid = do
+  let mpkg = display .  pkgName <$> mpkgid
   allSpecs <- filesWithExtension "." ".spec"
   -- emacs makes ".#*.spec" tmp files
   let predicate = maybe ((/= '.') . head) (\ pkg -> (`elem` [pkg <.> "spec", "ghc-" ++ pkg <.> "spec"])) mpkg
@@ -354,8 +301,9 @@
     [] -> return Nothing
     _ -> error "More than one spec file found!"
 
-checkForCabalFile :: Maybe Package -> IO (Maybe FilePath)
-checkForCabalFile mpkg = do
+checkForCabalFile :: Maybe PackageIdentifier -> IO (Maybe FilePath)
+checkForCabalFile mpkgid = do
+  let mpkg = display . pkgName <$> mpkgid
   allCabals <- filesWithExtension "." ".cabal"
   let predicate = maybe (const True) (\ pkg -> (== pkg <.> "cabal")) mpkg
       cabals = filter predicate allCabals
@@ -364,17 +312,17 @@
     [] -> return Nothing
     _ -> error "More than one cabal file found!"
 
-checkForPkgCabalFile :: String -> IO (Maybe FilePath)
-checkForPkgCabalFile pkgmver = do
-  let pkg = stripVersion pkgmver
-      cabalfile = pkg <.> "cabal"
+checkForPkgCabalFile :: PackageIdentifier -> IO (Maybe FilePath)
+checkForPkgCabalFile pkgid = do
+  let pkg = pkgName pkgid
+      cabalfile = display pkg <.> "cabal"
   pkgcabal <- doesFileExist cabalfile
   if pkgcabal
     then return $ Just cabalfile
     else do
-    exists <- doesDirectoryExist pkgmver
+    exists <- doesDirectoryExist $ display pkgid
     if exists
-      then fileWithExtension pkgmver ".cabal"
+      then fileWithExtension (display pkg) ".cabal"
       else return Nothing
 
 -- findSpecFile :: PackageDescription -> RpmFlags -> IO (FilePath, Bool)
@@ -393,37 +341,36 @@
 
 -- Nothing implies existing packaging in cwd
 -- Something implies either new packaging or some existing spec file in dir
-prepare :: Flags -> Stream -> Maybe Package -> Bool -> IO PackageData
-prepare flags stream mpkgver revise = do
-  let mpkg = stripVersion <$> mpkgver
-  mspec <- checkForSpecFile mpkg
+prepare :: Flags -> Stream -> Maybe PackageIdentifier -> Bool -> IO PackageData
+prepare flags stream mpkgid revise = do
+  mspec <- checkForSpecFile mpkgid
   case mspec of
     Just spec -> do
       cabalfile <- cabalFromSpec spec revise
       (pkgDesc, docs, licenses) <- simplePackageDescription flags cabalfile
       return $ PackageData mspec docs licenses pkgDesc
     Nothing ->
-      case mpkgver of
+      case mpkgid of
         Nothing -> do
-          mcabal <- checkForCabalFile mpkg
+          mcabal <- checkForCabalFile Nothing
           case mcabal of
             Just cabalfile -> do
               (pkgDesc, docs, licenses) <- simplePackageDescription flags cabalfile
               return $ PackageData Nothing docs licenses pkgDesc
             Nothing -> do
               cwd <- getCurrentDirectory
-              prepare flags stream (Just $ takeFileName cwd) revise
-        Just pkgmver -> do
-          mcabal <- checkForPkgCabalFile pkgmver
+              prepare flags stream (simpleParse (takeFileName cwd)) revise
+        Just pkgid -> do
+          mcabal <- checkForPkgCabalFile pkgid
           case mcabal of
             Just cabalfile -> do
               (pkgDesc, docs, licenses) <- simplePackageDescription flags cabalfile
               return $ PackageData Nothing docs licenses pkgDesc
             Nothing -> do
-              pkgver <- if stripVersion pkgmver == pkgmver
-                        then latestPackage stream (mkPackageName pkgmver)
-                        else return pkgmver
-              (cabalfile, mtmp) <- tryUnpack pkgver revise
+              pkgid' <- if pkgVersion pkgid == nullVersion
+                          then latestPackage stream (pkgName pkgid)
+                          else return pkgid
+              (cabalfile, mtmp) <- tryUnpack pkgid' revise
               (pkgDesc, docs, licenses) <- simplePackageDescription flags cabalfile
               maybe (return ()) removeDirectoryRecursive mtmp
               return $ PackageData Nothing docs licenses pkgDesc
@@ -466,18 +413,3 @@
 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
@@ -20,9 +20,6 @@
   ) where
 
 
-import Control.Monad (when)
-import Data.Maybe (isJust, fromJust)
-
 #ifdef HTTPS
 import qualified Data.ByteString.Char8 as B
 import Data.List (isPrefixOf)
@@ -30,7 +27,7 @@
 import Network.HTTP.Client
 import Network.HTTP.Client.TLS
 import System.FilePath (takeFileName)
-import SimpleCmd ((+-+))
+import SimpleCmd ((+-+), removePrefix)
 #else
 #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
 #else
@@ -39,15 +36,16 @@
 import SimpleCmd ((+-+), cmdMaybe)
 import SysCmd (optionalProgram)
 #endif
-import SimpleCabal (PackageName, unPackageName)
+import Distribution.Text (display)
+import SimpleCabal (PackageIdentifier(..), PackageName)
 import Types
 
-stackageList :: Stream -> PackageName -> IO (Maybe String)
+stackageList :: Stream -> PackageName -> IO (Maybe PackageIdentifier)
 stackageList stream pkg = do
 #ifdef HTTPS
   mgr <- newManager tlsManagerSettings
   let pkgurl = topurl ++ (show stream) ++ "/package/"
-  req <- parseRequest $ pkgurl ++ unPackageName pkg
+  req <- parseRequest $ pkgurl ++ display pkg
   hist <- responseOpenHistory req mgr
   let redirs = mapMaybe (lookup "Location" . responseHeaders . snd) $ hrRedirects hist
   if null redirs
@@ -55,7 +53,9 @@
     else do
     let loc = B.unpack $ last redirs
     if topurl `isPrefixOf` loc
-      then return $ Just (takeFileName loc)
+      then
+      let ver = (readVersion . removePrefix (display pkg ++ "-") . takeFileName) loc
+      in return $ Just (PackageIdentifier pkg ver)
       else return Nothing
   where
     topurl :: String
@@ -64,16 +64,18 @@
   -- check for stackage-query
   haveStackage <- optionalProgram "stackage"
   if haveStackage
-    then
-    fmap ((unPackageName pkg ++ "-") ++) <$> cmdMaybe "stackage" ["package", show stream, unPackageName pkg]
+    then do
+    mver <- cmdMaybe "stackage" ["package", show stream, display pkg]
+    return $ PackageIdentifier pkg . readVersion <$> mver
     else do
     putStrLn "'cabal install stackage-query' to check against Stackage LTS"
     return Nothing
 #endif
 
-latestStackage :: Stream -> PackageName -> IO (Maybe String)
+latestStackage :: Stream -> PackageName -> IO (Maybe PackageIdentifier)
 latestStackage stream pkg = do
-  mpkg <- stackageList stream pkg
-  when (isJust mpkg) $
-    putStrLn $ fromJust mpkg +-+ "in Stackage" +-+ show stream
-  return mpkg
+  mpkgid <- stackageList stream pkg
+  case mpkgid of
+    Nothing -> return ()
+    Just pkgid -> putStrLn $ display pkgid +-+ "in Stackage" +-+ show stream
+  return mpkgid
diff --git a/src/Types.hs b/src/Types.hs
--- a/src/Types.hs
+++ b/src/Types.hs
@@ -15,9 +15,13 @@
 
 module Types (
   Flags, -- flagList,
-  Package,
+  LibPkgType(..),
   PackageType(..),
+  unversionedPkgId,
+  readVersion,
+  RpmPackage(..),
   Stream(..),
+  nullVersion,
   Verbose(..)
   ) where
 
@@ -28,10 +32,45 @@
 #else
 import Data.Semigroup ((<>))
 #endif
-import SimpleCabal (FlagName {--, mkFlagName--})
+import Distribution.Text (display)
+import Distribution.Version (
+#if (defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0))
+                     Version,
+                     mkVersion,
+                     nullVersion
+#else
+                     Version(..)
+#endif
+                    )
 
-type Package = String
+import SimpleCabal (FlagName, {-- mkFlagName, --}
+                    PackageIdentifier(..), PackageName)
 
+data LibPkgType = Base | Devel | Prof | Doc | Static
+  deriving Eq
+
+instance Show LibPkgType where
+  show Base = ""
+  show Devel = "devel"
+  show Prof = "prof"
+  show Doc = "doc"
+  show Static = "static"
+
+data RpmPackage = RpmHsLib LibPkgType PackageName
+                | RpmHsBin PackageName
+                | RpmOther String
+  deriving Eq
+
+instance Show RpmPackage where
+  show (RpmHsLib t n) = "ghc-" ++ display n ++ pkgSuffix t
+  show (RpmHsBin n) = display n
+  show (RpmOther n) = n
+
+pkgSuffix :: LibPkgType -> String
+pkgSuffix lpt =
+  let rep = show lpt in
+  if null rep then "" else '-' : rep
+
 data Verbose = Quiet | Verbose
   deriving Eq
 
@@ -69,3 +108,23 @@
 
 data PackageType = DefaultPkg | BinaryPkg | StandalonePkg | SpecFile FilePath
   deriving Eq
+
+readVersion :: String -> Version
+readVersion = mkVersion . parseVer
+  where
+    parseVer :: String -> [Int]
+    parseVer cs =
+      let vs = filter (/= ".") $ groupBy (\ c c' -> c /= '.' && c' /= '.') cs
+      in map read vs
+
+unversionedPkgId :: PackageName -> PackageIdentifier
+unversionedPkgId pn = PackageIdentifier pn nullVersion
+
+#if (defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0))
+#else
+mkVersion :: [Int] -> Version
+mkVersion is = Version is []
+
+nullVersion :: Version
+nullVersion = mkVersion []
+#endif
