packages feed

cabal-rpm 1.0.1 → 1.0.2

raw patch · 16 files changed

+438/−388 lines, 16 filesdep +optparse-applicativedep ~time

Dependencies added: optparse-applicative

Dependency ranges changed: time

Files

ChangeLog view
@@ -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
Makefile view
@@ -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
cabal-rpm.cabal view
@@ -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)
src/Commands/BuildDep.hs view
@@ -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
src/Commands/Depends.hs view
@@ -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
src/Commands/Diff.hs view
@@ -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
src/Commands/Install.hs view
@@ -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]
src/Commands/Refresh.hs view
@@ -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 $
src/Commands/RpmBuild.hs view
@@ -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
src/Commands/Spec.hs view
@@ -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)
src/Commands/Update.hs view
@@ -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)
src/Dependencies.hs view
@@ -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
src/Main.hs view
@@ -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"-
src/PackageUtils.hs view
@@ -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
src/Stackage.hs view
@@ -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
src/Types.hs view
@@ -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