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 +6/−1
- Makefile +17/−0
- cabal-rpm.cabal +7/−6
- src/Commands/BuildDep.hs +6/−4
- src/Commands/Depends.hs +39/−29
- src/Commands/Diff.hs +9/−4
- src/Commands/Install.hs +12/−10
- src/Commands/Refresh.hs +7/−6
- src/Commands/RpmBuild.hs +13/−14
- src/Commands/Spec.hs +69/−48
- src/Commands/Update.hs +32/−35
- src/Dependencies.hs +50/−59
- src/Main.hs +24/−18
- src/PackageUtils.hs +68/−136
- src/Stackage.hs +17/−15
- src/Types.hs +62/−3
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