cabal-rpm 0.13.3 → 1.0.1
raw patch · 22 files changed
+733/−1018 lines, 22 filesdep +semigroupsdep +simple-cabaldep +simple-cmd-argsdep ~simple-cmd
Dependencies added: semigroups, simple-cabal, simple-cmd-args
Dependency ranges changed: simple-cmd
Files
- ChangeLog +64/−52
- Makefile +4/−0
- TODO +15/−3
- cabal-rpm.cabal +23/−19
- man/cabal-rpm.1 +0/−0
- man/cabal-rpm.1.md +11/−11
- src/Commands/BuildDep.hs +9/−0
- src/Commands/Depends.hs +25/−21
- src/Commands/Diff.hs +20/−12
- src/Commands/Install.hs +12/−14
- src/Commands/Refresh.hs +22/−19
- src/Commands/RpmBuild.hs +21/−41
- src/Commands/Spec.hs +150/−196
- src/Commands/Update.hs +25/−26
- src/Dependencies.hs +94/−127
- src/Distro.hs +0/−48
- src/Main.hs +75/−25
- src/Options.hs +0/−189
- src/PackageUtils.hs +82/−201
- src/Stackage.hs +10/−10
- src/SysCmd.hs +0/−4
- src/Types.hs +71/−0
ChangeLog view
@@ -1,5 +1,17 @@-* 0.13.3 (2019-05-10)-- default to lts-12+# 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+- handle setup-depends+- diff: autodetect subpackaging+- diff (experimental): trim %changelog with bawolk/hsp if available+- drop pre-built manpage: use Makefile to build it++# 0.13.3 (2019-05-10)+- default stream to lts-12 - repoquery for missing deps' package .conf file to avoid modular ghc conflicts - only --assumeyes for dnf install when not tty - give up if more than one spec file@@ -9,14 +21,14 @@ - finalPackageDescription for debugging Cabal - use simple-cmd-0.1.3.1 for sudo fixes -* 0.13.2 (2019-04-09)+# 0.13.2 (2019-04-09) - include ANNOUNCE in docs - if dependency parallel directory exists, don't check if installed - fix buildDepends on Cabal-2.4 - new --standalone option for private packages built with cabal-install - print --{missing,standalone,subpackage} options on spec file header line -* 0.13.1 (2019-02-27)+# 0.13.1 (2019-02-27) - update: fix rw git dir detection - fix tarball downloading and copying of revised .cabal file - show output (errors) when prepping source and prep in working dir@@ -24,7 +36,7 @@ - need chrpath for subpackages - move license dir to any common subpackage -* 0.13 (2019-02-18)+# 0.13 (2019-02-18) - improve license and doc filtering - backup revised .cabal files - fallback to spectool for source downloading@@ -34,7 +46,7 @@ - only run "cabal update" if more than 10min old - drop support for ghc-7.4.2 -* 0.12.6 (2018-10-20)+# 0.12.6 (2018-10-20) - update: remove old revised .cabal - convert revised .cabal file to unix format - spec: support haskell-gi libraries@@ -45,7 +57,7 @@ - support ghc_without_dynamic for static executables - build with Cabal-2.4 (ghc-8.6) -* 0.12.5 (2018-07-29)+# 0.12.5 (2018-07-29) - update: more careful now with fuzz 1 -- handle revised to non-revised -- improved for subpackaging@@ -57,21 +69,21 @@ - missing: better output for missing sub-deps - do not put doc* in docs -* 0.12.4 (2018-05-31)+# 0.12.4 (2018-05-31) - now uses Hackage revisions of packages (using wget) - spec --stream STREAM replaces --hackage - disable https for ghc < 7.10 -* 0.12.3 (2018-05-14)+# 0.12.3 (2018-05-14) - build: remove erroneous tarball check - refresh: use cblrpm for old cabal-rpm -* 0.12.2 (2018-03-29)+# 0.12.2 (2018-03-29) - diff now supports CBLRPM_DIFF envvar to override "diff -u" - try to build even when missing rpms deps not available - package now builds with Cabal-2.2 -* 0.12.1 (2018-02-20)+# 0.12.1 (2018-02-20) - new option --missing: comments out missing dependencies - put license files in lib subpackage - no longer append %_isa to C BuildRequires (#54)@@ -79,7 +91,7 @@ - change 'cblrpm' to 'cabal-rpm' in documentation - drop support for SCM snapshot releases -* 0.12 (2017-11-17)+# 0.12 (2017-11-17) - default to querying stackage.org directly via https - fix stackage-query usage and suggest installing if missing - run cabal update before cabal commands@@ -89,13 +101,13 @@ - silence mock rpmbuild -bs warnings about undefined %ghc_version - allow building with ghc-8.2 and Cabal-2.0 -* 0.11.2 (2017-07-31)+# 0.11.2 (2017-07-31) - fix cabal-rpm update --subpackage - fix rpm installation when no sudo (#49) - fix handling of no exposed modules (#50) - fix license handling for selfdep binlib (#51) -* 0.11.1 (2017-03-13)+# 0.11.1 (2017-03-13) - support building meta (compat) packages - invocation of optional stackage-query to update to LTS now works - initial --subpackage support for %{subpkgs} of missing deps:@@ -104,7 +116,7 @@ - (+-+) absorbs extra space - update no longer resets release for %{subpkgs} -* 0.11 (2017-01-27)+# 0.11 (2017-01-27) - refresh command now reads the cabal-rpm version header in the spec file and installs that version of cabal-rpm under ~/.cblrpm/ and uses it to make patch - diff and update now follow package-version args@@ -115,13 +127,13 @@ - rename Setup to Options - silence <$> import warnings -* 0.10.1 (2016-11-29)+# 0.10.1 (2016-11-29) - no longer need to remove License file by hand - use new %ghc_fix_rpath - include Contributors in docs - warn about duplicate docs in datadir and remove them -* 0.10.0 (2016-07-27)+# 0.10.0 (2016-07-27) - rename executable and manpage back to 'cabal-rpm': more predictable - explicit error for unknown command - sort docs and include upstream changelogs and news@@ -140,50 +152,50 @@ - package datadir better - for SUSE libs executables now go in the base package -* 0.9.11 (2016-05-06)+# 0.9.11 (2016-05-06) - build with Cabal-1.24 -* 0.9.10 (2016-03-24)+# 0.9.10 (2016-03-24) - bugfixes - update no longer tries to grep non-existent .git - fix duplicate clibs - fix build with ghc-8.0 (Cabal-1.23 and time-1.6) - SuSE improvements: no disttag or rpmdev-bumpspec -* 0.9.9 (2016-01-25)+# 0.9.9 (2016-01-25) - couple of minor improvements for SUSE packaging -* 0.9.8 (2015-10-08)+# 0.9.8 (2015-10-08) - better %license logic - fix handling of versions without '.' - no duplicate test deps -* 0.9.7 (2015-08-28)+# 0.9.7 (2015-08-28) - only list buildable executables in spec file - bring back 'build' as an alias for 'local' - use %license macro - do not warn about missing optional system programs -* 0.9.6 (2015-05-21)+# 0.9.6 (2015-05-21) - make "cabal list" quiet - filter missing packages from repoquery -* 0.9.5.1 (2015-05-01)+# 0.9.5.1 (2015-05-01) - add old-locale Cabal flag to fix build on ghc-7.10 -* 0.9.5 (2015-04-20)+# 0.9.5 (2015-04-20) - fix for dnf repoquery - create SOURCES/ for tarball - fixes for Cabal-1.22 - nogpgcheck for Fedora 22+ - warn about hidden backup spec files -* 0.9.4 (2015-02-17)+# 0.9.4 (2015-02-17) - use dnf if installed instead of yum for install and repoquery - update now only commits changes and new source if git origin is ssh - allow Cabal-1.22 -* 0.9.3 (2015-02-05)+# 0.9.3 (2015-02-05) - make sure tarball destdir exists before copying - improve output for listing missing packages - update improvements: new-sources first, continue if patch fails, git commit changes@@ -191,7 +203,7 @@ - drop the debuginfo handling for C files - ignore emacs temp ".#pkgname.spec" files -* 0.9.2 (2014-12-18)+# 0.9.2 (2014-12-18) - lots of bug fixes - improved missingdeps output - use https for hackage URLs (codeblock)@@ -201,14 +213,14 @@ - fix build and warnings for Cabal 1.20 - use TMPDIR -* 0.9.1 (2014-08-26)+# 0.9.1 (2014-08-26) - missingdeps now lists missing dependencies recursively and outputs Hackage package names rather than ghc-*-devel package names - do not assume package order when testing if dependencies installed - check ~/.cabal/packages/ exists before looking for tarballs - pass actual exeNames to %ghc_fix_dynamic_rpath -* 0.9 (2014-07-17)+# 0.9 (2014-07-17) - reworked initial logic to make better use of existing spec files, and prep source tree properly - default to Library packaging instead of BinLib:@@ -224,7 +236,7 @@ - include "cblrpm" in tempdir names - use current dir name as a last guess of package name -* 0.8.11 (2014-05-17)+# 0.8.11 (2014-05-17) - build command renamed again from "rpm" to "local" (like fedpkg) - use .spec file to determine pkg-ver when no .cabal file around - automatically generate bcond for %check and add testsuite BRs@@ -238,16 +250,16 @@ - no longer depends on regex-compat - some refactorings -* 0.8.10 (2014-03-03)+# 0.8.10 (2014-03-03) - diff command replaces cblrpm-diff script - new missingdeps command - replace use of rpmspec: no "rpmspec --srpm" on RHEL 5 and 6 -* 0.8.9 (2014-02-10)+# 0.8.9 (2014-02-10) - bugfix for error handling dir with spec file - cblrpm-diff arg is now optional -* 0.8.8 (2014-02-09)+# 0.8.8 (2014-02-09) - updated GPLv3 license headers - use .spec file to determine package if no .cabal file (works with or without arg)@@ -261,7 +273,7 @@ - new builddep command (like yum-buildep, but allows missing packages) - notice for overwriting existing spec file with force option -* 0.8.7 (2013-12-31)+# 0.8.7 (2013-12-31) - new "install" command wrapping "cabal install" - "build" command renamed to "rpm" - sort devel Requires@@ -270,14 +282,14 @@ - hlint cleanup - support AGPL license in Cabal-1.18 -* 0.8.6 (2013-10-04)+# 0.8.6 (2013-10-04) - check for _darcs or .git dir in package topdir not pwd -* 0.8.5 (2013-09-29)+# 0.8.5 (2013-09-29) - fix repoquery when a package update exists for C lib - make cblrpm-diff quieter -* 0.8.4 (2013-09-28)+# 0.8.4 (2013-09-28) - use repoquery to determine extra C library dependencies - quote "pkgconfig(foo)" for rpm query and yum install - show sudo command before sudo password prompt appears@@ -286,7 +298,7 @@ - drop release from initial changelog entry for packager to add an entry - do not try to fetch tarball for a darcs or git source dir -* 0.8.3 (2013-07-12)+# 0.8.3 (2013-07-12) - only try to install missing dependencies - for executables depending on own lib add BR chrpath and %ghc_fix_dynamic_rpath - word-wrap generic descriptions@@ -294,7 +306,7 @@ - move modules to toplevel - Rpm module split into Spec and Build in Commands/ -* 0.8.2 (2013-07-02)+# 0.8.2 (2013-07-02) - handle pkg-ver arg, and check cabal list is non-empty - sort all generated deps - use yum-builddep again to install deps@@ -305,12 +317,12 @@ - --version now outputs to stdout - new --force flag to overwrite existing .spec file -* 0.8.1 (2013-06-14)+# 0.8.1 (2013-06-14) - word wrapping of descriptions - use generic description for shared subpackage - simplify logic for summary and description processing -* 0.8.0 (2013-05-31)+# 0.8.0 (2013-05-31) - new simplier revision to Fedora Packaging - drop %common_summary and %common_description - drop %ghc_package, %ghc_description, %ghc_devel_package,@@ -319,7 +331,7 @@ - check external programs available before use - tweaks for ghc-7.6.3 and Cabal-1.16 -* 0.7.1 (2013-03-22)+# 0.7.1 (2013-03-22) - add final full-stop to description if missing - add ver-rel to initial changelog entry - fix use of cblrpm-diff force lib option@@ -328,7 +340,7 @@ - output when trying a path - map curl C dep to libcurl -* 0.7.0 (2013-01-22)+# 0.7.0 (2013-01-22) - cabal-rpm command renamed to cblrpm, and cabal-rpm-diff to cblrpm-diff - cblrpm now has commands for spec, srpm, and build - cblrpm will try to install packaged uninstalled depends with sudo yum install@@ -338,7 +350,7 @@ - sort extralibs depends - cleanup of unused options and help output -* 0.6.6 (2012-11-21)+# 0.6.6 (2012-11-21) - generate BRs and Req's for C libraries (extra-libraries) - initial map for some C libs: libglut, libiw, libz, libX* - generate BRs and Req's for pkgconfig-depends@@ -348,32 +360,32 @@ - backup suffix changed from .cabal-rpm to .cblrpm - don't mistake non-existent file in cwd for a package -* 0.6.5 (2012-11-01)+# 0.6.5 (2012-11-01) - drop hscolour BuildRequires - simplify generated BuildRequires: drop version ranges for now, exclude pkg self, base libs, and Cabal - use ExclusiveArch ghc_arches_with_ghci for template-haskell dep - replace --name option with --library to force Lib -* 0.6.4 (2012-09-25)+# 0.6.4 (2012-09-25) - add cabal-rpm-diff - fix manpage generation -* 0.6.3 (2012-09-24)+# 0.6.3 (2012-09-24) - support tarball path argument - use a temporary working dir for opening tarball or cabal unpack - add a manpage -* 0.6.2 (2012-09-10)+# 0.6.2 (2012-09-10) - fix output of L/GPL version -* 0.6.1 (2012-07-25)+# 0.6.1 (2012-07-25) bugfixes: - fix "cabal-rpm pkg" when other *pkg* packages exist in hackage - always generate the extra docs list from the pkg src dir! - now no backslash at end of common_description -* 0.6.0 (2012-07-24)+# 0.6.0 (2012-07-24) - updated to work with Cabal >= 1.10 and current cabal2spec style packaging using currently actively used ghc-rpm-macros - should generate haskell dependencies correctly and also summary and@@ -381,7 +393,7 @@ - some of the generic compiler supported was dropped for simplicity - rpmbuild support will be re-introduced in a future version -* 0.5.1 and earlier (2007-2008) released by Bryan O'Sullivan+# 0.5.1 and earlier (2007-2008) released by Bryan O'Sullivan - should work with ghc-6.8
+ Makefile view
@@ -0,0 +1,4 @@+man: man/cabal-rpm.1++man/cabal-rpm.1: man/cabal-rpm.1.md+ pandoc -s -t man $< > $@
TODO view
@@ -1,3 +1,17 @@+- switch to Cabal 2 for better License handling+- builddep should only install ghc-*-devel not ghc-*-prof+- type for rpm (dep) packages++- spec --bounds+- distinguish binlib executable and library build-deps+ and library and testsuite build-tools+- rework "BR: ghc-*-static" with %{?_isa}+- jump from lts-N to lts-N+1 instead of straight to Hackage+- move Main to app?+- check for cabal executable+- revisions of subpackages+- use Set for deps?+ ## Misc ? run "cabal update" if package-version not found - read options from header line@@ -17,8 +31,6 @@ ## spec/packaging - filter or blockformat literate code in description ("> ...")-- sort devel packages ignoring -devel suffix?-? include version ranges in BRs ? use repoquery for missing testdeps - support tarballs again * filter dummy pkgs like fail, bytestring-builder and mtl-compat@@ -43,7 +55,7 @@ - use rpmspec + dnf/yum-builddep if needed to install deps not in .cabal ## install-- check ghc version compatible+- check ghc version compatible (done?) ## update - warm about new missing deps
cabal-rpm.cabal view
@@ -1,5 +1,5 @@ Name: cabal-rpm-Version: 0.13.3+Version: 1.0.1 Synopsis: RPM packaging tool for Haskell Cabal-based packages Description: This package provides a RPM packaging tool for Haskell Cabal-based packages.@@ -22,11 +22,11 @@ 2012-2019 Jens Petersen <petersen@fedoraproject.org> Category: Distribution Build-type: Simple-Extra-source-files: README.md ChangeLog TODO man/cabal-rpm.1.md man/cabal-rpm.1+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.3+ GHC == 8.6.5 source-repository head type: git@@ -47,13 +47,17 @@ directory, filepath, process,- simple-cmd >= 0.1.3.1,+ simple-cabal >= 0.1.0,+ simple-cmd >= 0.2.0,+ simple-cmd-args >= 0.1.2, unix if flag(old-locale) Build-Depends: old-locale >= 1 && < 1.1, time >= 1.2 && < 1.5 else Build-Depends: time >= 1.5 && < 1.9+ if impl(ghc<8.0)+ Build-Depends: semigroups if impl(ghc >= 8.0) && flag(https) Build-Depends: bytestring, http-client >= 0.4.30,@@ -61,21 +65,21 @@ http-conduit Cpp-options: -DHTTPS Other-modules:- Commands.Depends,- Commands.Diff,- Commands.Install,- Commands.RpmBuild,- Commands.Refresh,- Commands.Spec,- Commands.Update,- Dependencies,- Distro,- FileUtils,- Options,- PackageUtils,- Stackage,- SysCmd,- Paths_cabal_rpm+ Commands.BuildDep,+ Commands.Depends,+ Commands.Diff,+ Commands.Install,+ Commands.RpmBuild,+ Commands.Refresh,+ Commands.Spec,+ Commands.Update,+ Dependencies,+ FileUtils,+ PackageUtils,+ Stackage,+ SysCmd,+ Types,+ Paths_cabal_rpm Hs-Source-Dirs: src GHC-options: -fwarn-missing-signatures -Wall Extensions: CPP
− man/cabal-rpm.1
man/cabal-rpm.1.md view
@@ -6,17 +6,17 @@ cabal-rpm - a RPM packaging tool for Haskell Cabal packages # SYNOPSIS-cabal-rpm [*options*] spec [*path-or-pkg*]-cabal-rpm [*options*] local [*path-or-pkg*]-cabal-rpm [*options*] srpm [*path-or-pkg*]-cabal-rpm [*options*] prep [*path-or-pkg*]-cabal-rpm [*options*] builddep [*path-or-pkg*]-cabal-rpm [*options*] install [*path-or-pkg*]-cabal-rpm [*options*] depends [*path-or-pkg*]-cabal-rpm [*options*] requires [*path-or-pkg*]-cabal-rpm [*options*] missingdeps [*path-or-pkg*]-cabal-rpm [*options*] diff [*path-or-pkg*]-cabal-rpm [*options*] update [*path-or-pkg*]+cabal-rpm [*options*] spec [*path-or-pkg*]\+cabal-rpm [*options*] local [*path-or-pkg*]\+cabal-rpm [*options*] srpm [*path-or-pkg*]\+cabal-rpm [*options*] prep [*path-or-pkg*]\+cabal-rpm [*options*] builddep [*path-or-pkg*]\+cabal-rpm [*options*] install [*path-or-pkg*]\+cabal-rpm [*options*] depends [*path-or-pkg*]\+cabal-rpm [*options*] requires [*path-or-pkg*]\+cabal-rpm [*options*] missingdeps [*path-or-pkg*]\+cabal-rpm [*options*] diff [*path-or-pkg*]\+cabal-rpm [*options*] update [*path-or-pkg*\]\ cabal-rpm [*options*] refresh [*path-or-pkg*] # DESCRIPTION
+ src/Commands/BuildDep.hs view
@@ -0,0 +1,9 @@+module Commands.BuildDep (builddep) where++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
src/Commands/Depends.hs view
@@ -17,9 +17,12 @@ Depends (..) ) where -import Dependencies (dependencies, missingPackages, packageDependencies)-import Options (quiet)-import PackageUtils (PackageData (..), prepare, repoquery, stripPkgDevel)+import Dependencies (dependencies, ghcDep, LibPkgType(..), missingPackages,+ packageDependencies)+import PackageUtils (PackageData (..), prepare, repoquery,+ stripPkgDevel, unPackageName)+import Types+ import SimpleCmd ((+-+)) #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))@@ -32,43 +35,44 @@ data Depends = Depends | Requires | Missing -depends :: PackageData -> Depends -> IO ()-depends pkgdata action = do+depends :: Depends -> Flags -> Stream -> Maybe Package -> IO ()+depends action flags stream mpkg = do+ pkgdata <- prepare flags stream mpkg False let pkgDesc = packageDesc pkgdata case action of Depends -> do- (deps, tools, clibs, pkgcfgs) <- dependencies pkgDesc- let clibs' = map (\ lib -> "lib" ++ lib <.> "so") clibs- let pkgcfgs' = map (<.> "pc") pkgcfgs- mapM_ putStrLn $ deps ++ tools ++ clibs' ++ pkgcfgs'+ 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' Requires -> do- (deps, tools, clibs, pkgcfgs) <- packageDependencies False pkgDesc- mapM_ putStrLn $ sort $ deps ++ tools ++ clibs ++ pkgcfgs+ (deps, setup, tools, clibs, pkgcfgs) <- packageDependencies pkgDesc+ mapM_ putStrLn $ sort . nub $ map (ghcDep LibDevel) (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 miss missing+ void $ recurseMissing flags stream miss missing -recurseMissing :: [String] -> [String] -> IO [String]-recurseMissing already [] = return already-recurseMissing already (dep:deps) = do- miss <- missingDepsPkg dep+recurseMissing :: Flags -> Stream -> [String] -> [String] -> IO [String]+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 accum (miss \\ accum)+ deeper <- recurseMissing flags stream accum (miss \\ accum) let accum2 = nub $ accum ++ deeper- more <- recurseMissing accum2 (deps \\ accum2)+ more <- recurseMissing flags stream accum2 (deps \\ accum2) return $ nub $ accum2 ++ more notAvail :: String -> IO Bool notAvail pkg = null <$> repoquery [] pkg -missingDepsPkg :: String -> IO [String]-missingDepsPkg pkg = do- pkgdata <- prepare quiet (Just pkg) False+missingDepsPkg :: Flags -> Stream -> Package -> IO [String]+missingDepsPkg flags stream pkg = do+ pkgdata <- prepare flags stream (Just pkg) False missingPackages (packageDesc pkgdata) >>= filterM notAvail putMissing :: [String] -> [String] -> IO ()
src/Commands/Diff.hs view
@@ -18,27 +18,35 @@ ) where import Commands.Spec (createSpecFile)-import FileUtils (mktempdir, withCurrentDirectory)-import Options (RpmFlags (..))+import FileUtils (mktempdir) import PackageUtils (PackageData (..), prepare)-import SimpleCmd ((+-+), shell_)-import SysCmd (die)+import SysCmd (die, optionalProgram)+import Types -import Data.Maybe (isNothing)+import SimpleCmd (grep_, pipe_, pipe3_) +import Distribution.Verbosity (silent) import System.Directory (removeDirectoryRecursive) import System.FilePath ((<.>)) import System.Posix.Env (getEnvDefault) -diff :: PackageData -> RpmFlags -> Maybe String -> IO ()-diff pkgdata flags mpkg =+diff :: Flags -> PackageType -> Stream -> Maybe Package -> IO ()+diff flags pkgtype stream mpkg = do+ pkgdata <- prepare flags stream mpkg True case specFilename pkgdata of Nothing -> die "No (unique) .spec file in directory." Just spec -> do+ subpkg <- grep_ "%{subpkgs}" spec tmpdir <- mktempdir- pd <- if isNothing mpkg then return pkgdata- else withCurrentDirectory tmpdir $ prepare flags mpkg False- speccblrpm <- createSpecFile pd flags (Just tmpdir)- diffcmd <- getEnvDefault "CBLRPM_DIFF" "diff -u"- shell_ $ diffcmd +-+ spec +-+ speccblrpm +-+ "| sed -e s%" ++ speccblrpm ++ "%" ++ spec <.> "cblrpm" ++ "%"+ speccblrpm <- createSpecFile silent flags False pkgtype subpkg stream (Just tmpdir) mpkg+ diffcmd <- words <$> getEnvDefault "CBLRPM_DIFF" "diff -u"+ hsp <- optionalProgram "hsp"+ if hsp+ then+ pipe3_ (head diffcmd, tail diffcmd ++ [spec, speccblrpm])+ ("sed", ["-e", "s%" ++ speccblrpm ++ "%" ++ spec <.> "cblrpm" ++ "%"])+ ("hsp", ["takeWhile (not . (\"%changelog\" `T.isSuffixOf`) . getText) pp | p"])+ else+ pipe_ (head diffcmd, tail diffcmd ++ [spec, speccblrpm])+ ("sed", ["-e", "s%" ++ speccblrpm ++ "%" ++ spec <.> "cblrpm" ++ "%"]) removeDirectoryRecursive tmpdir
src/Commands/Install.hs view
@@ -18,34 +18,32 @@ ) where import Commands.RpmBuild (rpmBuild)-import Dependencies (missingPackages, notInstalled, pkgInstallMissing)+import Dependencies (notInstalled, pkgInstallMissing) import FileUtils (withTempDirectory)-import Options (RpmFlags (..))-import PackageUtils (PackageData (..), rpmInstall, RpmStage (..), stripPkgDevel)+import PackageUtils (rpmInstall, RpmStage (..), stripPkgDevel)+import SysCmd (rpmEval)+import Types+ import SimpleCmd (cmd_, (+-+)) import SimpleCmd.Rpm (rpmspec)-import SysCmd (rpmEval) #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0)) #else --import Control.Applicative ((<$>)) #endif import Control.Monad (unless, when)-import System.Directory (removeDirectoryRecursive) import System.FilePath ((</>)) -install :: PackageData -> RpmFlags -> IO ()-install pkgdata flags = do- let pkgDesc = packageDesc pkgdata- pkgInstallMissing flags pkgdata- stillMissing <- missingPackages pkgDesc+install :: Flags -> PackageType -> Bool -> Stream -> Maybe Package -> IO ()+install flags pkgtype subpackage stream mpkg = do+ stillMissing <- pkgInstallMissing flags stream mpkg unless (null stillMissing) $ do putStrLn $ "Missing:" +-+ unwords stillMissing mapM_ cblrpmInstallMissing stillMissing- (spec, mtmpdir) <- rpmBuild pkgdata flags Binary- rpmdir <- rpmEval "%{_rpmdir}"- rpmspec [] (fmap (</> "%{arch}/%{name}-%{version}-%{release}.%{arch}.rpm") rpmdir) spec >>= rpmInstall- maybe (return ()) removeDirectoryRecursive mtmpdir+ withTempDirectory $ \ _ -> do+ spec <- rpmBuild Binary flags pkgtype subpackage stream mpkg+ rpmdir <- rpmEval "%{_rpmdir}"+ rpmspec [] (fmap (</> "%{arch}/%{name}-%{version}-%{release}.%{arch}.rpm") rpmdir) spec >>= rpmInstall False cblrpmInstallMissing :: String -> IO ()
src/Commands/Refresh.hs view
@@ -18,12 +18,13 @@ import Paths_cabal_rpm (version) import Commands.Spec (createSpecFile) import FileUtils (withTempDirectory)-import Options (RpmFlags (..)) import PackageUtils (PackageData (..), cabal_, patchSpec,- removePrefix)+ prepare, removePrefix)+import SysCmd (die, optionalProgram)+import Types+ import SimpleCmd (cmd, cmd_, grep_) import SimpleCmd.Git (rwGitDir)-import SysCmd (die, optionalProgram) #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0)) #else@@ -32,14 +33,16 @@ import Control.Monad (unless, when) import Data.List (isPrefixOf) import Data.Version (showVersion)+import Distribution.Verbosity (silent) import System.Directory (copyFile, createDirectoryIfMissing, doesFileExist, renameFile, setCurrentDirectory) import System.Environment (getEnv) --import System.Exit (exitSuccess) import System.FilePath ((</>), (<.>)) -refresh :: PackageData -> RpmFlags -> IO ()-refresh pkgdata flags =+refresh :: Bool -> PackageType -> Stream -> Maybe Package -> IO ()+refresh dryrun pkgtype stream mpkg = do+ pkgdata <- prepare [] stream mpkg True case specFilename pkgdata of Nothing -> die "No (unique) .spec file in directory." Just spec -> do@@ -50,19 +53,18 @@ putStrLn "Working dir contain local changes!" -- exitSuccess first <- head . lines <$> readFile spec- do- let cblrpmver =- if "# generated by cabal-rpm-" `isPrefixOf` first- then removePrefix "# generated by cabal-rpm-" first- else "0.9.11"- if cblrpmver == showVersion version- then putStrLn "Packaging is up to date"- else do- subpkg <- grep_ "%{subpkgs}" spec- let flags' = if subpkg then flags {rpmSubpackage = True} else flags- oldspec <- createOldSpec subpkg cblrpmver spec- newspec <- createSpecFile pkgdata flags' Nothing- patchSpec Nothing oldspec newspec+ -- filter "--subpackage", etc+ let cblrpmver = head . words $+ if "# generated by cabal-rpm-" `isPrefixOf` first+ then removePrefix "# generated by cabal-rpm-" first+ else "0.9.11"+ if cblrpmver == showVersion version+ then putStrLn "Packaging is up to date"+ else do+ subpkg <- grep_ "%{subpkgs}" spec+ oldspec <- createOldSpec subpkg cblrpmver spec+ newspec <- createSpecFile silent [] False pkgtype subpkg stream Nothing mpkg+ patchSpec dryrun Nothing oldspec newspec -- setCurrentDirectory cwd -- when rwGit $ -- cmd_ "git" ["commit", "-a", "-m", "refreshed to cabal-rpm-" ++ showVersion version]@@ -99,4 +101,5 @@ cmd_ "strip" [bin] copyFile bin $ bindir </> cblrpmver setCurrentDirectory cwd- cmd_ (bindir </> cblrpmver) $ ["--subpackage" | subpkg] ++ ["spec"]+ -- Fixme 1.0.1 supports --quiet+ cmd_ (bindir </> cblrpmver) $ "spec" : ["--subpackage" | subpkg]
src/Commands/RpmBuild.hs view
@@ -20,11 +20,12 @@ ) where import Commands.Spec (createSpecFile)-import Dependencies (pkgInstallMissing)-import FileUtils (mktempdir)-import Options (RpmFlags (..))-import PackageUtils (bringTarball, PackageData (..), packageName,- packageVersion, rpmbuild, RpmStage (..))+import Dependencies (pkgInstallMissing')+import PackageUtils (bringTarball, PackageData (..), prepare,+ rpmbuild, RpmStage (..))+import Types++import SimpleCabal (showPkgId) import SimpleCmd ((+-+)) #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))@@ -32,49 +33,28 @@ import Control.Applicative ((<$>)) #endif --import Control.Exception (bracket)-import Control.Monad (unless, when)-import Data.Maybe (isNothing)+import Control.Monad (void, when) import Distribution.PackageDescription (PackageDescription (..))-import System.Directory (removeDirectoryRecursive)----import Distribution.Version (VersionRange, foldVersionRange')+import Distribution.Verbosity (normal) --- autoreconf :: Verbosity -> PackageDescription -> IO ()--- autoreconf verbose pkgDesc = do--- ac <- doesFileExist "configure.ac"--- when ac $ do--- c <- doesFileExist "configure"--- when (not c) $ do--- setupMessage verbose "Running autoreconf" pkgDesc--- cmd_ "autoreconf" []+rpmBuild :: RpmStage -> Flags -> PackageType -> Bool -> Stream -> Maybe Package ->+ IO FilePath+rpmBuild stage flags pkgtype subpackage stream mpkg = do+ pkgdata <- prepare flags stream mpkg True+ when (stage == Binary) $+ void $ pkgInstallMissing' pkgdata -rpmBuild :: PackageData -> RpmFlags -> RpmStage ->- IO (FilePath, Maybe FilePath)-rpmBuild pkgdata flags stage = do--- let verbose = rpmVerbosity flags--- bracket (setFileCreationMask 0o022) setFileCreationMask $ \ _ -> do--- autoreconf verbose pkgDesc let pkgDesc = packageDesc pkgdata mspec = specFilename pkgdata- mtmp <- if isNothing mspec- then Just <$> mktempdir- else return Nothing- specFile <- maybe (createSpecFile pkgdata flags mtmp)+ specFile <- maybe (createSpecFile normal flags False pkgtype subpackage stream Nothing mpkg) (\ s -> putStrLn ("Using existing" +-+ s) >> return s) mspec let pkg = package pkgDesc- name = packageName pkg- when (stage `elem` [Binary,BuildDep]) $- pkgInstallMissing flags pkgdata-- unless (stage == BuildDep) $ do- let version = packageVersion pkg- bringTarball (name ++ "-" ++ version) True specFile- rpmbuild stage specFile+ bringTarball (showPkgId pkg) True specFile+ rpmbuild stage specFile - return (specFile, mtmp)+ return specFile -rpmBuild_ :: PackageData -> RpmFlags -> RpmStage -> IO ()-rpmBuild_ pkgdata flags stage = do- (_, mtmpdir) <- rpmBuild pkgdata flags stage- maybe (return ()) removeDirectoryRecursive mtmpdir+rpmBuild_ :: RpmStage -> Flags -> PackageType -> Bool -> Stream -> Maybe Package -> IO ()+rpmBuild_ stage flags pkgtype subpackage stream mpkg =+ void $ rpmBuild stage flags pkgtype subpackage stream mpkg
src/Commands/Spec.hs view
@@ -20,13 +20,15 @@ createSpecFile, createSpecFile_ ) where -import Dependencies (notInstalled, missingPackages, packageDependencies,- showDep, subPackages, testsuiteDependencies)-import Distro (Distro(..), defaultRelease, detectDistro)-import Options (RpmFlags (..))+import Dependencies (ghcDep, LibPkgType(..), missingLibraries,+ missingOtherPkgs, notSrcOrInst,+ packageDependencies, pkgSuffix, subPackages,+ testsuiteDependencies')+import Types import PackageUtils (bringTarball, getPkgName, latestPackage, PackageData (..), packageName, packageVersion,- prettyShow, stripPkgDevel)+ prepare, removePrefix)+import SimpleCabal (mkPackageName, PackageName, showVersion, unPackageName) import SimpleCmd ((+-+)) import Control.Monad (filterM, unless, void, when, (>=>))@@ -42,7 +44,7 @@ import Data.Maybe (isJust, fromMaybe, fromJust) import Data.Time.Clock (getCurrentTime) import Data.Time.Format (formatTime)-import Data.Version (showVersion)+import qualified Data.Version as V import Distribution.License (License (..) #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,2,0)@@ -56,19 +58,13 @@ #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,2,0) license, #endif-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)- unFlagName-#else- FlagName (..)-#endif )-import Distribution.Simple.Utils (notice, warn)+import Distribution.Simple.Utils (warn) #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0) import Distribution.Types.UnqualComponentName (unUnqualComponentName) #endif----import Distribution.Version (VersionRange, foldVersionRange')+import Distribution.Verbosity (Verbosity) import System.Directory (doesFileExist) import System.IO (IOMode (..), hClose, hPutStrLn, openFile)@@ -87,30 +83,28 @@ #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0) #else-unFlagName :: FlagName -> String-unFlagName (FlagName n) = n- unUnqualComponentName :: String -> String unUnqualComponentName = id #endif -createSpecFile :: PackageData -> RpmFlags ->- Maybe FilePath -> IO FilePath-createSpecFile pkgdata flags mdest = do- let mspec = specFilename pkgdata+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+ let mspec = case pkgtype of+ SpecFile f -> Just f+ _ -> specFilename pkgdata docs = docFilenames pkgdata licensefiles = licenseFilenames pkgdata pkgDesc = packageDesc pkgdata pkg = package pkgDesc- name = packageName pkg- verbose = rpmVerbosity flags+ name = unPackageName $ packageName pkg+ standalone = pkgtype == StandalonePkg hasExec = hasExes pkgDesc hasLib = hasLibs pkgDesc hasLibPkg = hasLib && not standalone dupdocs = docs `intersect` dataFiles pkgDesc datafiles = dataFiles pkgDesc \\ dupdocs- standalone = rpmStandalone flags- (pkgname, binlib) <- getPkgName mspec pkgDesc (rpmBinary flags || standalone)+ (pkgname, binlib) <- getPkgName mspec pkgDesc (pkgtype == BinaryPkg || standalone) let pkg_name = if pkgname == name then "%{name}" else "%{pkg_name}" basename | binlib = "%{pkg_name}" | hasExecPkg = name@@ -119,13 +113,12 @@ hasExecPkg = binlib || (hasExec && not hasLibPkg) -- run commands before opening file to prevent empty file on error -- maybe shell commands should be in a monad or something- (deps, tools, clibs, pkgcfgs) <- packageDependencies (rpmStrict flags) pkgDesc- let testsuiteDeps = testsuiteDependencies pkgDesc name+ (deps, setupDeps, tools, clibs, pkgcfgs) <- packageDependencies pkgDesc specAlreadyExists <- doesFileExist specFile- let specFile' = specFile ++ if not (rpmForce flags) && specAlreadyExists then ".cblrpm" else ""+ let specFile' = specFile ++ if not force && specAlreadyExists then ".cblrpm" else "" if specAlreadyExists- then notice verbose $ specFile +-+ "exists:" +-+ if rpmForce flags then "forcing overwrite" else "creating" +-+ specFile'+ then warn verbose $ specFile +-+ "exists:" +-+ (if force then "forcing overwrite" else "creating") +-+ specFile' else do let realdir dir = "cblrpm." `isPrefixOf` takeBaseName dir when (maybe True realdir mdest) $@@ -139,33 +132,11 @@ sectionNewline = putNewline >> putNewline put = hPutStrLn h global m v = put $ "%global" +-+ m +-+ v- ghcPkg = if binlib then "-n ghc-%{name}" else ""- ghcPkgDevel = if binlib then "-n ghc-%{name}-devel" else "devel"+ subpkgParam lt = if binlib then "-n ghc-%{name}" ++ pkgSuffix lt else show lt - put $ "# generated by cabal-rpm-" ++ showVersion Paths_cabal_rpm.version- +-+ unwords (["--missing" | rpmMissing flags] ++ ["--standalone" | standalone] ++ ["--subpackage" | rpmSubpackage flags])- distro <- maybe detectDistro return (rpmDistribution flags)- if distro /= SUSE- then put "# https://fedoraproject.org/wiki/Packaging:Haskell"- else do- now <- getCurrentTime- let year = formatTime defaultTimeLocale "%Y" now- put "#"- put $ "# spec file for package " ++ pkgname- put "#"- put $ "# Copyright (c) " ++ year ++ " SUSE LINUX GmbH, Nuernberg, Germany."- put "#"- put "# All modifications and additions to the file contributed by third parties"- put "# remain the property of their copyright owners, unless otherwise agreed"- put "# upon. The license for this file, and modifications and additions to the"- put "# file, is the same license as for the pristine package itself (unless the"- put "# license for the pristine package is not an Open Source License, in which"- put "# case the license is the MIT License). An \"Open Source License\" is a"- put "# license that conforms to the Open Source Definition (Version 1.9)"- put "# published by the Open Source Initiative."- putNewline- put "# Please submit bugfixes or comments via http://bugs.opensuse.org/"- put "#"+ put $ "# generated by cabal-rpm-" ++ V.showVersion Paths_cabal_rpm.version+ +-+ unwords (["--standalone" | standalone] ++ ["--subpackage" | subpackage])+ put "# https://fedoraproject.org/wiki/Packaging:Haskell" putNewline -- Some packages conflate the synopsis and description fields. Ugh.@@ -211,46 +182,40 @@ -- FIXME sort by build order -- FIXME recursive missingdeps- missing <- do- subs <- if rpmSubpackage flags then subPackages mspec pkgDesc else return []- miss <- if rpmSubpackage flags || rpmMissing flags || standalone then missingPackages pkgDesc else return []+ missingLibs <- do+ subs <- if subpackage then subPackages mspec pkgDesc else return []+ miss <- if subpackage || standalone then missingLibraries pkgDesc else return [] return $ nub (subs ++ miss)- subpkgs <- if rpmSubpackage flags then- mapM ((getsubpkgMacro flags specFile >=>- \(m,pv) -> global m pv >> return ("%{" ++ m ++ "}"))- . stripPkgDevel) missing+ subpkgs <- if subpackage then+ mapM (getsubpkgMacro stream specFile >=>+ \(m,pv) -> global m pv >> return ("%{" ++ m ++ "}")) missingLibs else return [] let hasSubpkgs = subpkgs /= [] when hasSubpkgs $ do global "subpkgs" $ unwords subpkgs putNewline + let testsuiteDeps = testsuiteDependencies' pkgDesc unless (null testsuiteDeps) $ do- missTestDeps <- filterM notInstalled testsuiteDeps+ missTestDeps <- filterM notSrcOrInst $ map (ghcDep LibDevel) testsuiteDeps put $ "%bcond_" ++ (if null missTestDeps then "without" else "with") +-+ "tests" putNewline let version = packageVersion pkg- defRelease = defaultRelease distro- release = fromMaybe defRelease (rpmRelease flags)+ release = "1" revised = isJust $ lookup "x-revision" (customFieldsPD pkgDesc) putHdr "Name" (if binlib then "%{pkg_name}" else basename) putHdr "Version" version when hasSubpkgs $ put "# can only be reset when all subpkgs bumped"- putHdr "Release" $ release ++ (if distro == SUSE then [] else "%{?dist}")+ putHdr "Release" $ release ++ "%{?dist}" putHdr "Summary" summary- case distro of- SUSE -> putHdr "Group" "Development/Languages/Other"- RHEL5 -> putHdr "Group" (if binlib then "Development/Languages"- else "System Environment/Libraries")- _ -> return () putNewline #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,2,0) #else let licenseFromSPDX = id #endif- putHdr "License" $ (showLicense distro . licenseFromSPDX . license) pkgDesc+ putHdr "License" $ (showLicense . licenseFromSPDX . license) pkgDesc putHdr "Url" $ "https://hackage.haskell.org/package" </> pkg_name put "# Begin cabal-rpm sources:" putHdr "Source0" $ sourceUrl pkgver@@ -258,26 +223,34 @@ when revised $ putHdr ("Source" ++ show (1 + length subpkgs)) $ "https://hackage.haskell.org/package" </> pkgver </> pkg_name <.> "cabal" ++ "#" </> pkgver <.> "cabal" put "# End cabal-rpm sources"- case distro of- Fedora -> return ()- _ -> putHdr "BuildRoot" "%{_tmppath}/%{name}-%{version}-build" putNewline put "# Begin cabal-rpm deps:"- putHdr "BuildRequires" "ghc-Cabal-devel"+ when (mkPackageName "Cabal" `notElem` deps || not hasLib || not (null setupDeps)) $ do+-- put "# Setup"+ -- `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 putHdr "BuildRequires" $ "ghc-rpm-macros" ++ (if hasSubpkgs then "-extra" else "") - let alldeps = sort $ deps ++ tools ++ clibs ++ pkgcfgs ++ ["chrpath" | hasSubpkgs]- let testDeps = sort $ testsuiteDeps \\ deps- unless (null $ alldeps ++ testDeps) $ do- mapM_ (\ d -> (if d `elem` missing then putHdrComment else putHdr) "BuildRequires" d) alldeps- -- for ghc < 7.8- when (distro `notElem` [Fedora, SUSE] &&- any (\ d -> d `elem` map showDep ["template-haskell", "hamlet"]) deps) $- putHdr "ExclusiveArch" "%{ghc_arches_with_ghci}"- unless (null testDeps) $ do- put "%if %{with tests}"- mapM_ (putHdr "BuildRequires") testDeps- put "%endif"+ 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 otherdeps = sort $ tools ++ clibs ++ pkgcfgs+ unless (null otherdeps) $ do+-- put "# Other"+ missingOthers <- missingOtherPkgs pkgDesc+ mapM_ (\ d -> (if d `elem` missingOthers then putHdrComment else putHdr) "BuildRequires" d) otherdeps+ -- -- for ghc < 7.8:+ -- when (epel7 &&+ -- any (\ d -> d `elem` map showDep ["template-haskell", "hamlet"]) deps) $+ -- putHdr "ExclusiveArch" "%{ghc_arches_with_ghci}"+ let testDeps = sort $ testsuiteDeps \\ (mkPackageName "Cabal" : (deps ++ setupDeps))+ unless (null testDeps) $ do+ put "%if %{with tests}"+ mapM_ (putHdr "BuildRequires" . ghcDep LibDevel) testDeps+ put "%endif" let common = binlib && datafiles /= [] && not standalone when common $@@ -291,7 +264,7 @@ mapM_ put descLines putNewline - let wrapGenDesc = wordwrap (79 - max 0 (length pkgname - length pkg_name))+ let wrapGenDesc = init . wordwrap (79 - max 0 (length pkgname - length pkg_name)) when common $ do put "%package common"@@ -300,56 +273,62 @@ putNewline put "%description common" put $ wrapGenDesc $ "This package provides the" +-+ pkg_name +-+ "common data files."- putNewline+ sectionNewline -- haskell-gi generates lib source files at configure time- -- (stricly should also check for otherModules (autogenModules?)+ -- (strictly should also check for otherModules (autogenModules?) -- but libraries wihout exposedModules should be useless/redundant) let hasModules =- hasLib && ((notNull . exposedModules . fromJust . library) pkgDesc || "ghc-haskell-gi-devel" `elem` deps)+ hasLib && ((notNull . exposedModules . fromJust . library) pkgDesc || mkPackageName "haskell-gi" `elem` (deps ++ setupDeps)) when hasLibPkg $ do when (binlib && hasModules) $ do- put $ "%package" +-+ ghcPkg+ put $ "%package" +-+ subpkgParam LibBase putHdr "Summary" $ "Haskell" +-+ pkg_name +-+ "library"- case distro of- SUSE -> putHdr "Group" "System/Libraries"- RHEL5 -> putHdr "Group" "System Environment/Libraries"- _ -> return () when common $ putHdr "Requires" "%{name}-common = %{version}-%{release}" putNewline- put $ "%description" +-+ ghcPkg+ put $ "%description" +-+ subpkgParam LibBase put $ wrapGenDesc $ "This package provides the Haskell" +-+ pkg_name +-+ "shared library."- putNewline- put $ "%package" +-+ ghcPkgDevel+ sectionNewline+ let isa = "%{?_isa}"+ put $ "%package" +-+ subpkgParam LibDevel putHdr "Summary" $ "Haskell" +-+ pkg_name +-+ "library development files"- case distro of- RHEL5 -> putHdr "Group" "Development/Libraries"- SUSE -> putHdr "Group" "Development/Libraries/Other"- _ -> return ()- unless (distro == SUSE) $- putHdr "Provides" $ (if binlib then "ghc-%{name}" else "%{name}") ++ "-static = %{version}-%{release}"- when hasModules $- putHdr "Provides" $ (if binlib then "ghc-%{name}" else "%{name}") ++ "-doc" +-+ "= %{version}-%{release}"+ 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}" put "%if %{defined ghc_version}" putHdr "Requires" "ghc-compiler = %{ghc_version}"- putHdr "Requires(post)" "ghc-compiler = %{ghc_version}"- putHdr "Requires(postun)" "ghc-compiler = %{ghc_version}" put "%endif"- let isa = if distro == SUSE then "" else "%{?_isa}" when hasModules $ putHdr "Requires" $ (if binlib then "ghc-%{name}" else "%{name}") ++ isa +-+ "= %{version}-%{release}" unless (null $ clibs ++ pkgcfgs) $ do put "# Begin cabal-rpm deps:"- mapM_ (putHdr "Requires") $ sort $ map (++ isa) clibs ++ pkgcfgs ++ ["pkgconfig" | distro == SUSE, pkgcfgs /= []]+ mapM_ (putHdr "Requires") $ sort $ map (++ isa) clibs ++ pkgcfgs put "# End cabal-rpm deps" putNewline- put $ "%description" +-+ ghcPkgDevel+ put $ "%description" +-+ subpkgParam LibDevel put $ wrapGenDesc $ "This package provides the Haskell" +-+ pkg_name +-+ "library development files."- -- previous line ends in an extra newline+ sectionNewline+-- ? when hasModules $+ put "%if %{with haddock}"+ put $ "%package" +-+ subpkgParam LibDoc+ putHdr "Summary" $ "Haskell" +-+ pkg_name +-+ "library documentation" putNewline+ put $ "%description" +-+ subpkgParam LibDoc+ put $ wrapGenDesc $ "This package provides the Haskell" +-+ pkg_name +-+ "library documentation."+ put "%endif"+ sectionNewline + put "%if %{with ghc_prof}"+ put $ "%package" +-+ subpkgParam LibProf+ putHdr "Summary" $ "Haskell" +-+ pkg_name +-+ "profiling library"+ putHdr "Requires" $ (if binlib then "ghc-%{name}" else "%{name}") ++ "-devel" ++ isa +-+ "= %{version}-%{release}"+ putNewline+ put $ "%description" +-+ subpkgParam LibProf+ put $ wrapGenDesc $ "This package provides the Haskell" +-+ pkg_name +-+ "profiling library."+ put "%endif"+ sectionNewline+ when hasSubpkgs $ do global "main_version" "%{version}" putNewline@@ -378,12 +357,9 @@ put "%cabal update" put "%cabal sandbox init" put "%cabal install --only-dependencies"- when (distro == SUSE && rpmConfigurationsFlags flags /= []) $ do- let cabalFlags = [ "-f" ++ (if b then "" else "-") ++ unFlagName n | (n, b) <- rpmConfigurationsFlags flags ]- put $ "%define cabal_configure_options " ++ unwords cabalFlags let pkgType = if hasLibPkg then "lib" else "bin" put $ "%ghc_" ++ pkgType ++ "_build" ++- if hasLibPkg && not hasModules then "_build_without_haddock" else []+ if hasLibPkg && not hasModules then "_without_haddock" else [] put "# End cabal-rpm build" sectionNewline @@ -399,11 +375,10 @@ unless (null dupdocs) $ do putNewline putStrLn $ "Warning: doc files found in datadir:" +-+ unwords dupdocs- unless (distro == SUSE) $- put $ "rm %{buildroot}%{_datadir}" </> pkgver </>- case length dupdocs of- 1 -> head dupdocs- _ -> "{" ++ intercalate "," dupdocs ++ "}"+ put $ "rm %{buildroot}%{_datadir}" </> pkgver </>+ case length dupdocs of+ 1 -> head dupdocs+ _ -> "{" ++ intercalate "," dupdocs ++ "}" when (hasLibPkg && not hasModules) $ put "mv %{buildroot}%{_ghcdocdir}{,-devel}"@@ -411,13 +386,12 @@ when common $ put "mv %{buildroot}%{_ghcdocdir}{,-common}" - put "# End cabal-rpm install"- when (standalone && hasLib) $ do -- can be dropped with ghc-rpm-macros-1.9.8 put "find %{buildroot}%{_libdir} -name 'libHS%{pkgver}-*.so' -delete" put "rm -r %{buildroot}%{ghclibdir}" + put "# End cabal-rpm install" sectionNewline unless (null testsuiteDeps) $ do@@ -425,22 +399,12 @@ put "%cabal_test" sectionNewline - when hasLibPkg $ do- put $ "%post" +-+ ghcPkgDevel- put "%ghc_pkg_recache"- sectionNewline-- put $ "%postun" +-+ ghcPkgDevel- put "%ghc_pkg_recache"- sectionNewline-- let license_macro = if distro == Fedora then "%license" else "%doc"+ let license_macro = "%license" let execs = sort $ map exeName $ filter isBuildable $ executables pkgDesc when hasExecPkg $ do put "%files" put "# Begin cabal-rpm files:"- when (distro /= Fedora) $ put "%defattr(-,root,root,-)" -- Add the license file to the main package only if it wouldn't -- otherwise be empty. unless common $ do@@ -456,7 +420,6 @@ when common $ do put "%files common" put "# Begin cabal-rpm files:"- when (distro /= Fedora) $ put "%defattr(-,root,root,-)" mapM_ (\ l -> put $ license_macro +-+ l) licensefiles unless (null docs) $ put $ "%doc" +-+ unwords docs@@ -465,89 +428,80 @@ sectionNewline when hasLibPkg $ do- let baseFiles = if binlib then "-f ghc-%{name}.files" else "-f %{name}.files"- develFiles = if binlib then "-f ghc-%{name}-devel.files" else "-f %{name}-devel.files"+ let filesParams lt = subpkgParam lt +-+ "-f" +-+ (if binlib then "ghc-" else "" ) ++ "%{name}" ++ pkgSuffix lt ++ ".files" when hasModules $ do- put $ "%files" +-+ ghcPkg +-+ baseFiles- put "# Begin cabal-rpm files:"- when (distro /= Fedora) $ put "%defattr(-,root,root,-)"- unless common $+ put $ "%files" +-+ filesParams LibBase+ unless common $ do+ put "# Begin cabal-rpm files:" mapM_ (\ l -> put $ license_macro +-+ l) licensefiles- when (distro == SUSE && not binlib) $- mapM_ ((\ p -> put $ "%{_bindir}" </> (if p == name then "%{pkg_name}" else p)) . unUnqualComponentName) execs- unless (common || null datafiles) $- put $ "%{_datadir}" </> pkgver- put "# End cabal-rpm files"+ unless (null datafiles) $+ put $ "%{_datadir}" </> pkgver+ put "# End cabal-rpm files" sectionNewline - put $ "%files" +-+ ghcPkgDevel +-+ develFiles+ put $ "%files" +-+ filesParams LibDevel -- put "# Begin cabal-rpm files:"- when (distro /= Fedora) $ put "%defattr(-,root,root,-)" unless hasModules $ mapM_ (\ l -> put $ license_macro +-+ l) licensefiles unless (common || null docs) $ put $ "%doc" +-+ unwords docs- when (distro /= SUSE && not binlib) $+ unless binlib $ mapM_ ((\ p -> put $ "%{_bindir}" </> (if p == name then "%{pkg_name}" else p)) . unUnqualComponentName) execs -- put "# End cabal-rpm files" sectionNewline + put "%if %{with haddock}"+ put $ "%files" +-+ filesParams LibDoc+ put "%endif"+ sectionNewline+ put "%if %{with ghc_prof}"+ put $ "%files" +-+ filesParams LibProf+ put "%endif"+ sectionNewline+ put "%changelog"- unless (distro == SUSE) $ do- now <- getCurrentTime- let date = formatTime defaultTimeLocale "%a %b %e %Y" now- put $ "*" +-+ date +-+ "Fedora Haskell SIG <haskell@lists.fedoraproject.org> - " ++ version ++ "-" ++ release- put $ "- spec file generated by cabal-rpm-" ++ showVersion Paths_cabal_rpm.version+ now <- getCurrentTime+ let date = formatTime defaultTimeLocale "%a %b %e %Y" now+ put $ "*" +-+ date +-+ "Fedora Haskell SIG <haskell@lists.fedoraproject.org> - " ++ version ++ "-" ++ release+ put $ "- spec file generated by cabal-rpm-" ++ V.showVersion Paths_cabal_rpm.version hClose h return specFile' -createSpecFile_ :: PackageData -> RpmFlags ->- Maybe FilePath -> IO ()-createSpecFile_ pkgFiles flags mdest =- void (createSpecFile pkgFiles flags mdest)+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) isBuildable :: Executable -> Bool isBuildable exe = buildable $ buildInfo exe -showLicense :: Distro -> License -> String-showLicense SUSE (GPL Nothing) = "GPL-1.0+"-showLicense _ (GPL Nothing) = "GPL+"-showLicense SUSE (GPL (Just ver)) = "GPL-" ++ prettyShow ver ++ "+"-showLicense _ (GPL (Just ver)) = "GPLv" ++ prettyShow ver ++ "+"-showLicense SUSE (LGPL Nothing) = "LGPL-2.0+"-showLicense _ (LGPL Nothing) = "LGPLv2+"-showLicense SUSE (LGPL (Just ver)) = "LGPL-" ++ prettyShow ver ++ "+"-showLicense _ (LGPL (Just ver)) = "LGPLv" ++ [head $ prettyShow ver] ++ "+"-showLicense SUSE BSD3 = "BSD-3-Clause"-showLicense _ BSD3 = "BSD"-showLicense SUSE BSD4 = "BSD-4-Clause"-showLicense _ BSD4 = "BSD"-showLicense _ MIT = "MIT"-showLicense SUSE PublicDomain = "SUSE-Public-Domain"-showLicense _ PublicDomain = "Public Domain"-showLicense SUSE AllRightsReserved = "SUSE-NonFree"-showLicense _ AllRightsReserved = "Proprietary"-showLicense _ OtherLicense = "Unknown"-showLicense _ (UnknownLicense l) = l+showLicense :: License -> String+showLicense (GPL Nothing) = "GPL+"+showLicense (GPL (Just ver)) = "GPLv" ++ showVersion ver ++ "+"+showLicense (LGPL Nothing) = "LGPLv2+"+showLicense (LGPL (Just ver)) = "LGPLv" ++ [head $ showVersion ver] ++ "+"+showLicense BSD3 = "BSD"+showLicense BSD4 = "BSD"+showLicense MIT = "MIT"+showLicense PublicDomain = "Public Domain"+showLicense AllRightsReserved = "Proprietary"+showLicense OtherLicense = "Unknown"+ -- FIXME+showLicense (UnknownLicense l) = removePrefix "LicenseRef" l #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,16,0)-showLicense SUSE (Apache Nothing) = "Apache-2.0"-showLicense _ (Apache Nothing) = "ASL ?"-showLicense SUSE (Apache (Just ver)) = "Apache-" ++ prettyShow ver-showLicense _ (Apache (Just ver)) = "ASL" +-+ prettyShow ver+showLicense (Apache Nothing) = "ASL ?"+showLicense (Apache (Just ver)) = "ASL" +-+ showVersion ver #endif #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,18,0)-showLicense _ (AGPL Nothing) = "AGPLv?"-showLicense _ (AGPL (Just ver)) = "AGPLv" ++ prettyShow ver+showLicense (AGPL Nothing) = "AGPLv?"+showLicense (AGPL (Just ver)) = "AGPLv" ++ showVersion ver #endif #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,20,0)-showLicense SUSE BSD2 = "BSD-2-Clause"-showLicense _ BSD2 = "BSD"-showLicense SUSE (MPL ver) = "MPL-" ++ prettyShow ver-showLicense _ (MPL ver) = "MPLv" ++ prettyShow ver+showLicense BSD2 = "BSD"+showLicense (MPL ver) = "MPLv" ++ showVersion ver #endif #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,22,0)-showLicense _ ISC = "ISC"-showLicense _ UnspecifiedLicense = "Unspecified license!"+showLicense ISC = "ISC"+showLicense UnspecifiedLicense = "Unspecified license!" #endif sourceUrl :: String -> String@@ -576,10 +530,10 @@ paragraphs :: [String] -> [String] paragraphs = map (unlines . filter notNull) . groupBy (const notNull) -getsubpkgMacro :: RpmFlags -> FilePath -> String -> IO (String, String)-getsubpkgMacro flags spec pkg = do- let macro = filter (/= '-') pkg- pkgver <- latestPackage (rpmStream flags) pkg+getsubpkgMacro :: Stream -> FilePath -> PackageName -> IO (String, String)+getsubpkgMacro stream spec pkg = do+ let macro = filter (/= '-') $ unPackageName pkg+ pkgver <- latestPackage stream pkg bringTarball pkgver False spec return (macro, pkgver)
src/Commands/Update.hs view
@@ -17,29 +17,31 @@ ) where import Commands.Spec (createSpecFile)-import Distro (defaultRelease, detectDistro, Distro(..)) import FileUtils (withTempDirectory)-import Options (RpmFlags (..)) import PackageUtils (PackageData (..), bringTarball, editSpecField, getRevisedCabal, getSpecField, latestPackage, packageName,- packageVersion, patchSpec, prepare, readVersion,- removePrefix, removeSuffix)+ packageVersion, patchSpec, prepare,+ readVersion, removePrefix, removeSuffix)+import SysCmd (die)+import Types++import SimpleCabal (showPkgId, unPackageName) import SimpleCmd (cmd_, grep_, shell_, (+-+)) import SimpleCmd.Git (rwGitDir)-import SysCmd (die) #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0)) #else import Control.Applicative ((<$>)) #endif import Control.Monad (unless, when)-import Data.List (isPrefixOf) import Data.Maybe (isJust) import Distribution.PackageDescription (PackageDescription (..))+import Distribution.Verbosity (silent) import System.Directory (createDirectory, renameFile, setCurrentDirectory) import System.FilePath ((</>), (<.>)) -update :: PackageData -> RpmFlags -> Maybe String -> IO ()-update pkgdata flags mpkgver =+update :: Stream -> Maybe String -> IO ()+update stream mver = do+ pkgdata <- prepare [] stream Nothing True case specFilename pkgdata of Nothing -> die "No (unique) .spec file in directory." Just spec -> do@@ -48,12 +50,12 @@ name = packageName pkg ver = packageVersion pkg curVer = readVersion ver- current = name ++ "-" ++ ver+ current = showPkgId pkg revised = isJust $ lookup "x-revision" (customFieldsPD pkgDesc)- latest <- case mpkgver of- Just pv | (name ++ "-") `isPrefixOf` pv -> return pv- _ -> latestPackage (rpmStream flags) name- let newver = removePrefix (name ++ "-") latest+ latest <- case mver of+ Just v -> return v+ _ -> latestPackage stream name+ let newver = removePrefix (unPackageName name ++ "-") latest latestVer = readVersion newver updated = latestVer > curVer if latestVer < curVer@@ -68,12 +70,11 @@ subpkg <- grep_ "%{subpkgs}" specfile (curspec, _) <- createSpecVersion current specfile revised subpkg (newspec, newrevised) <- createSpecVersion latest specfile True subpkg- distro <- maybe detectDistro return (rpmDistribution flags)- let suffix = if distro == SUSE then "" else "%{?dist}"- defrelease = defaultRelease distro+ let suffix = "%{?dist}"+ defrelease = "1" currel <- removeSuffix suffix <$> getSpecField "Release" specfile editSpecField "Release" (defrelease ++ suffix) specfile- patchSpec (Just cwd) curspec newspec+ patchSpec False (Just cwd) curspec newspec ver' <- getSpecField "Version" specfile when (ver' /= newver) $ editSpecField "Version" newver specfile@@ -81,11 +82,10 @@ then editSpecField "Release" (defrelease ++ suffix) specfile else editSpecField "Release" (currel ++ suffix) specfile when updated $ do- when (distro /= SUSE) $ do- -- FIXME reset when all subpkgs updated- unless subpkg $- editSpecField "Release" ("0" ++ suffix) specfile- cmd_ "rpmdev-bumpspec" ["-c", "update to" +-+ newver, specfile]+ -- FIXME reset when all subpkgs updated+ unless subpkg $+ editSpecField "Release" ("0" ++ suffix) specfile+ cmd_ "rpmdev-bumpspec" ["-c", "update to" +-+ newver, specfile] setCurrentDirectory cwd rwGit <- rwGitDir when (rwGit && subpkg) $ do@@ -105,12 +105,11 @@ where createSpecVersion :: String -> String -> Bool -> Bool -> IO (FilePath, Bool) createSpecVersion pkgver spec revise subpkg = do- let flags' = flags { rpmSubpackage = subpkg }- pd <- prepare flags' (Just pkgver) revise+ pd <- prepare [] stream (Just pkgver) revise let pkgdata' = pd { specFilename = Just spec }- dir = pkgver <.> if revise then "" else "orig"+ dir = pkgver ++ if revise then ".revised" else ".orig" createDirectory dir- newspec <- createSpecFile pkgdata' flags' (Just dir)+ newspec <- createSpecFile silent [] False (SpecFile spec) subpkg stream (Just dir) (Just pkgver) let newrevised = let pkgDesc = packageDesc pkgdata' in isJust $ lookup "x-revision" (customFieldsPD pkgDesc)
src/Dependencies.hs view
@@ -17,19 +17,29 @@ module Dependencies ( dependencies,+ ghcDep,+ LibPkgType(..),+ missingLibraries,+ missingOtherPkgs, missingPackages, notInstalled,+ notSrcOrInst, packageDependencies, pkgInstallMissing,- showDep,+ pkgInstallMissing',+ pkgSuffix, subPackages,- testsuiteDependencies+ testsuiteDependencies' ) where -import Options (RpmFlags(..))-import PackageUtils (PackageData(..), packageName, removeSuffix, repoquery,- rpmInstall, stripPkgDevel)-import SimpleCmd (cmd, cmdBool, (+-+))+import PackageUtils (PackageData(..), prepare, removeLibSuffix,+ repoquery, rpmInstall, stripPkgDevel)+import Types++import SimpleCabal (buildDependencies, mkPackageName, exeDepName,+ PackageName, pkgcfgDepName, pkgName,+ setupDependencies, testsuiteDependencies, unPackageName)+import SimpleCmd (cmd, cmdBool, warning, (+-+)) import SimpleCmd.Rpm (rpmspec) #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))@@ -41,102 +51,48 @@ import Data.List (delete, isPrefixOf, isSuffixOf, nub, (\\)) import Data.Maybe (catMaybes, fromJust, isNothing) -import Distribution.Package (Dependency (..),-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,22,0)- unPackageName,-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)- unPkgconfigName-#endif-#else- PackageName (..)-#endif- )--#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,4,0)-import Distribution.Types.ComponentRequestedSpec (defaultComponentRequestedSpec)-#endif-import Distribution.Types.LegacyExeDependency (LegacyExeDependency (..))-import Distribution.Types.PkgconfigDependency (PkgconfigDependency (..))-#endif- import Distribution.PackageDescription (PackageDescription (..),-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,4,0)- enabledBuildDepends,-#endif allBuildInfo, BuildInfo (..),- TestSuite (..),-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,24,0)- setupDepends-#endif ) import System.Directory (doesDirectoryExist, doesFileExist) import System.FilePath ((<.>), (</>))-import System.IO (hPutStrLn, stderr) -excludedPkgs :: String -> Bool-excludedPkgs = flip notElem ["Cabal", "base", "ghc-prim", "integer-gmp"]--#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,4,0)-buildDepends :: PackageDescription -> [Dependency]-buildDepends = flip enabledBuildDepends defaultComponentRequestedSpec-#else-#endif---- returns list of deps-buildDependencies :: PackageDescription -> String -> [String]-buildDependencies pkgDesc self =- let deps = nub $ map depName (buildDepends pkgDesc)- ++ setupDependencies pkgDesc- in filter excludedPkgs (delete self deps)--setupDependencies :: PackageDescription -- ^pkg description- -> [String] -- ^depends-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,24,0)-setupDependencies pkgDesc =- maybe [] (map depName . setupDepends) (setupBuildInfo pkgDesc)-#else-setupDependencies _pkgDesc = []-#endif--#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,22,0)-#else-unPackageName :: PackageName -> String-unPackageName (PackageName n) = n-#endif--depName :: Dependency -> String-depName (Dependency n _) = unPackageName n+excludedPkgs :: PackageName -> Bool+excludedPkgs =+ flip notElem $ map mkPackageName ["ghc-prim", "integer-gmp"] -#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)-exeDepName :: LegacyExeDependency -> String-exeDepName (LegacyExeDependency n _) = n+data LibPkgType = LibBase | LibDevel | LibProf | LibDoc | LibStatic -pkgcfgDepName :: PkgconfigDependency -> String-pkgcfgDepName (PkgconfigDependency n _) = unPkgconfigName n-#else-exeDepName :: Dependency -> String-exeDepName = depName+instance Show LibPkgType where+ show LibBase = ""+ show LibDevel = "devel"+ show LibProf = "prof"+ show LibDoc = "doc"+ show LibStatic = "static" -pkgcfgDepName :: Dependency -> String-pkgcfgDepName = depName-#endif+pkgSuffix :: LibPkgType -> String+pkgSuffix lpt =+ let rep = show lpt in+ if null rep then "" else '-' : rep -showDep :: String -> String-showDep p = "ghc-" ++ p ++ "-devel"+ghcDep :: LibPkgType -> PackageName -> String+ghcDep lt p = "ghc-" ++ unPackageName p ++ pkgSuffix lt dependencies :: PackageDescription -- ^pkg description- -> IO ([String], [String], [String], [String])- -- ^depends, tools, c-libs, pkgcfg-dependencies pkgDesc = do- let self = packageName $ package pkgDesc- deps = buildDependencies pkgDesc self+ -> ([PackageName], [PackageName], [String], [String], [String])+ -- ^depends, setup, tools, c-libs, pkgcfg+dependencies pkgDesc =+ let self = pkgName $ package pkgDesc+ deps = filter excludedPkgs $ buildDependencies pkgDesc+ setup = filter excludedPkgs $ setupDependencies pkgDesc buildinfo = allBuildInfo pkgDesc tools = nub $ map exeDepName (concatMap buildTools buildinfo) pkgcfgs = nub $ map pkgcfgDepName $ concatMap pkgconfigDepends buildinfo clibs = nub $ concatMap extraLibs buildinfo- return (deps, delete self tools, clibs, pkgcfgs)+ stdcpp = "stdc++"+ cpp = ["gcc-c++" | stdcpp `elem` clibs]+ in (deps, setup \\ (mkPackageName "Cabal" : deps), delete (unPackageName self) tools ++ cpp, clibs \\ ["m", stdcpp], pkgcfgs) data QueryBackend = Rpm | Repoquery deriving Eq @@ -149,7 +105,7 @@ if libInst then rpmqueryFile Rpm lib_path else do- putStrLn $ "Running repoquery on" +-+ "lib" ++ lib+ putStrLn $ "Running repoquery for" +-+ lib_path rpmqueryFile Repoquery lib_path -- use repoquery or rpm -q to query which package provides file@@ -170,49 +126,56 @@ warning $ "More than one package seems to provide" +-+ file ++ ": " +-+ unwords pkgs return Nothing -warning :: String -> IO ()-warning s = hPutStrLn stderr $ "Warning:" +-+ s--packageDependencies :: Bool -- ^strict mode: True means abort on unknown dependencies- -> PackageDescription -- ^pkg description- -> IO ([String], [String], [String], [String])- -- ^depends, tools, c-libs, pkgcfg-packageDependencies strict pkgDesc = do- (deps, tools', clibs', pkgcfgs) <- dependencies pkgDesc- let excludedTools n = n `notElem` ["ghc", "hsc2hs", "perl"]+packageDependencies :: PackageDescription -- ^pkg description+ -> IO ([PackageName], [PackageName], [String], [String], [String])+ -- ^depends, setup, tools, c-libs, pkgcfg+packageDependencies pkgDesc = do+ let (deps, setup, tools', clibs', pkgcfgs) = dependencies pkgDesc+ excludedTools n = n `notElem` ["ghc", "hsc2hs", "perl"] mapTools "cabal" = "cabal-install" mapTools "gtk2hsC2hs" = "gtk2hs-buildtools" mapTools "gtk2hsHookGenerator" = "gtk2hs-buildtools" mapTools "gtk2hsTypeGen" = "gtk2hs-buildtools"+ mapTools "hspec-discover" = "ghc-hspec-discover-devel" mapTools tool = tool tools = filter excludedTools $ nub $ map mapTools tools' clibsWithErrors <- mapM resolveLib clibs'+ when (any isNothing clibsWithErrors) $- if strict- then fail "cannot resolve all clib dependencies"- else putStrLn "Warning: could not resolve all clib dependencies"+ warning "could not resolve all clib dependencies" let clibs = catMaybes clibsWithErrors let showPkgCfg p = "pkgconfig(" ++ p ++ ")"- return (map showDep deps, tools, nub clibs, map showPkgCfg pkgcfgs)+ return (deps, setup, tools, nub clibs, map showPkgCfg pkgcfgs) -testsuiteDependencies :: PackageDescription -- ^pkg description- -> String -- ^self- -> [String] -- ^depends-testsuiteDependencies pkgDesc self =- map showDep . delete self . filter excludedPkgs . nub . map depName $ concatMap (targetBuildDepends . testBuildInfo) (testSuites pkgDesc)+testsuiteDependencies' :: PackageDescription -> [PackageName]+testsuiteDependencies' =+ filter excludedPkgs . testsuiteDependencies missingPackages :: PackageDescription -> IO [String] missingPackages pkgDesc = do- (deps, tools, clibs, pkgcfgs) <- packageDependencies False pkgDesc+ (deps, setup, tools, clibs, pkgcfgs) <- packageDependencies pkgDesc pcpkgs <- mapM derefPkg pkgcfgs- filterM notSrcOrInst $ deps ++ ["ghc-Cabal-devel", "ghc-rpm-macros"] ++ tools ++ clibs ++ pcpkgs- where- notSrcOrInst :: String -> IO Bool- notSrcOrInst pkg = do- src <- doesDirectoryExist (".." </> removeSuffix "-devel" pkg)- if src then return False- else notInstalled pkg+ filterM notSrcOrInst $ nub $ map (ghcDep LibDevel) (deps ++ setup) ++ ["ghc-Cabal-devel", "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+ 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++notSrcOrInst :: String -> IO Bool+notSrcOrInst pkg = do+ src <- doesDirectoryExist (".." </> removeLibSuffix pkg)+ if src then return False+ else notInstalled pkg+ notInstalled :: String -> IO Bool notInstalled dep = not <$> cmdBool "rpm" ["-q", "--quiet", "--whatprovides", shellQuote dep]@@ -232,21 +195,27 @@ singleLine "" = "" singleLine s = (head . lines) s -subPackages :: Maybe FilePath -> PackageDescription -> IO [String]+subPackages :: Maybe FilePath -> PackageDescription -> IO [PackageName] subPackages mspec pkgDesc = do- develSubpkgs <- filter ("-devel" `isSuffixOf`) <$> maybe (return []) (rpmspec [] (Just "%{name}")) mspec- let self = packageName $ package pkgDesc- return $ delete (showDep self) develSubpkgs+ develSubpkgs <- map stripPkgDevel . filter ("-devel" `isSuffixOf`) <$> maybe (return []) (rpmspec [] (Just "%{name}")) mspec+ let self = pkgName $ package pkgDesc+ return $ delete self $ map mkPackageName develSubpkgs -pkgInstallMissing :: RpmFlags -> PackageData -> IO ()-pkgInstallMissing flags pkgdata = do+pkgInstallMissing :: Flags -> Stream -> Maybe Package -> IO [String]+pkgInstallMissing flags stream mpkg = do+ pkgdata <- prepare flags stream mpkg True+ pkgInstallMissing' pkgdata++pkgInstallMissing' :: PackageData -> IO [String]+pkgInstallMissing' pkgdata = do let pkgDesc = packageDesc pkgdata mspec = specFilename pkgdata- missing <- missingPackages pkgDesc- unless (null missing) $ do+ missing <- missingLibraries pkgDesc+ if null missing then return []+ else do subpkgs <- subPackages mspec pkgDesc- let pkgs = missing \\ subpkgs- pkgconfdir <- fromJust . lookup "Global Package DB" . read <$> cmd (ghcCmd flags) ["--info"]+ let pkgs = map (ghcDep LibProf) $ missing \\ subpkgs+ pkgconfdir <- fromJust . lookup "Global Package DB" . read <$> cmd "ghc" ["--info"] putStrLn $ "Running repoquery" +-+ unwords pkgs repopkgs <- filter (/= "") <$> mapM (repoqueryPackageConf pkgconfdir) pkgs let missing' = pkgs \\ repopkgs@@ -258,7 +227,8 @@ mapM_ putStrLn repopkgs -- fedora <- rpmEval "%fedora" -- let nogpgcheck = ["--nogpgcheck" | fedora `elem` []]- rpmInstall $ map showPkg repopkgs+ rpmInstall True $ map showPkg repopkgs+ return missing' where showPkg :: String -> String showPkg p = if '(' `elem` p then show p else p@@ -269,9 +239,6 @@ then pkgconfd </> stripPkgDevel pkg ++ "-[0-9]*.conf" else pkg in repoquery ["--qf", "%{name}"] key--ghcCmd :: RpmFlags -> FilePath-ghcCmd flags = maybe "ghc" show $ rpmCompilerId flags isGhcDevelPkg :: String -> Bool isGhcDevelPkg p =
− src/Distro.hs
@@ -1,48 +0,0 @@--- |--- Module : Distro--- Copyright : (C) 2016, 2018 Jens Petersen------ Maintainer : Jens Petersen <petersen@fedoraproject.org>------ Types and utility functions to represent different RPM-based distributions.---- This program is free software: you can redistribute it and/or modify--- it under the terms of the GNU General Public License as published by--- the Free Software Foundation, either version 3 of the License, or--- (at your option) any later version.--module Distro (defaultRelease,- detectDistro,- parseDistroName,- readDistroName,- Distro(..)) where--import SysCmd (rpmEval, rpmMacroDefined)-import Data.Maybe (fromMaybe, isNothing)-import Data.Char (toLower)--data Distro = Fedora | RHEL5 | SUSE deriving (Show, Eq)--detectDistro :: IO Distro-detectDistro = do- suse <- rpmMacroDefined "suse_version"- if suse then return SUSE- else do- dist <- rpmEval "%{?dist}"- -- RHEL5 does not have macros.dist- return $ if isNothing dist || dist == Just ".el5" then RHEL5 else Fedora--parseDistroName :: String -> Maybe Distro-parseDistroName x = lookup (map toLower x) known- where- known = [ ("suse", SUSE)- , ("fedora", Fedora)- , ("rhel5", RHEL5)- ]--readDistroName :: String -> Distro-readDistroName s = fromMaybe (error $ "unrecognized distribution name " ++ show s) (parseDistroName s)--defaultRelease :: Distro -> String-defaultRelease distro =- if distro == SUSE then "0" else "1"
src/Main.hs view
@@ -16,6 +16,16 @@ module Main where +import Control.Applicative ((<|>)+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))+#else+ , (<$>), (<*>)+#endif+ )+import Distribution.Verbosity (normal, silent)+import System.IO (BufferMode(LineBuffering), hSetBuffering, stdout)++import Commands.BuildDep (builddep) import Commands.Depends (depends, Depends (..)) import Commands.Diff (diff) import Commands.Install (install)@@ -24,33 +34,73 @@ import Commands.Spec (createSpecFile_) import Commands.Update (update) -import Options (parseArgs)-import PackageUtils (prepare, RpmStage (..))+import PackageUtils (RpmStage (..))+import Paths_cabal_rpm (version)+import Types -import System.Environment (getArgs)-import System.IO (BufferMode(LineBuffering), hSetBuffering, stdout)+import SimpleCmdArgs --(simpleCmdArgs, subcommands) main :: IO () main = do hSetBuffering stdout LineBuffering- (opts, cmd, mpkg) <- getArgs >>= parseArgs- pkgdata <- prepare opts mpkg True- case cmd of- "spec" -> createSpecFile_ pkgdata opts Nothing- "srpm" -> rpmBuild_ pkgdata opts Source- "prep" -> rpmBuild_ pkgdata opts Prep- "local" -> rpmBuild_ pkgdata opts Binary- "build" -> rpmBuild_ pkgdata opts Binary- "builddep" -> rpmBuild_ pkgdata opts BuildDep- "diff" -> diff pkgdata opts mpkg- "install" -> install pkgdata opts- "depends" -> depends pkgdata Depends- "refresh" -> refresh pkgdata opts- "requires" -> depends pkgdata Requires- "missingdeps" -> depends pkgdata Missing- "update" -> update pkgdata opts mpkg- "rpm" -> do- putStrLn "* Warning the 'rpm' command has been renamed to 'build':"- putStrLn "* this alias may be removed in a future release."- rpmBuild_ pkgdata opts Binary- c -> error $ "Unknown cmd: " ++ c+ simpleCmdArgs (Just version) "Cabal-rpm tool"+ "RPM package tool for Haskell Stackage/Hackage packages" $+ subcommands+ [ Subcommand "spec" "Generate a spec file" $+ createSpecFile_ Nothing <$> quietOpt <*> flags <*> force <*> pkgtype <*> subpackage <*> stream <*> packageArg+ , Subcommand "srpm" "Generate an srpm" $+ rpmBuild_ Source <$> flags <*> pkgtype <*> subpackage <*> stream <*> packageArg+ , Subcommand "prep" "Unpack source" $+ rpmBuild_ Prep <$> flags <*> pkgtype <*> subpackage <*> stream <*> packageArg+ , Subcommand "local" "Build rpm package locally" $+ rpmBuild_ Binary <$> flags <*> pkgtype <*> subpackage <*> stream <*> packageArg+ , Subcommand "build" "Alias for 'local' - builds rpm locally" $+ rpmBuild_ Binary <$> flags <*> pkgtype <*> subpackage <*> stream <*> packageArg+ , Subcommand "builddep" "Install build dependencies with dnf" $+ builddep <$> flags <*> stream <*> packageArg+ , Subcommand "install" "Build and install recursively" $+ install <$> flags <*> pkgtype <*> subpackage <*> stream <*> packageArg+ -- should be (optional versionArg) not pkgver+ , Subcommand "diff" "Diff with pristine generated spec file" $+ diff <$> flags <*> pkgtype <*> stream <*> packageArg+ , Subcommand "depends" "List Haskell dependencies" $+ depends Depends <$> flags <*> stream <*> packageArg+ , Subcommand "requires" "List buildrequires for package" $+ depends Requires <$> flags <*> stream <*> packageArg+ , Subcommand "missingdeps" "List dependencies not available" $+ depends Missing <$> flags <*> stream <*> packageArg+ , Subcommand "refresh" "Refresh spec file to lastest packaging" $+ refresh <$> dryrun <*> pkgtype <*> stream <*> packageArg+ , Subcommand "update" "Update package to latest version" $+ update <$> stream <*> optional versionArg+ ]+ where+ packageArg :: Parser (Maybe Package)+ packageArg = optional (strArg "PKG[VER]")++ stream :: Parser Stream+ stream = optionalWith auto 's' "stream" "STREAM" "Stackage stream or Hackage" (LTS "13")++ flags :: Parser Flags+ flags = optionalWith auto 'f' "flag" "[(String,Bool)]" "Set or disable Cabal flags" []++ force :: Parser Bool+ force = switchWith 'F' "force" "Force overwriting existing of any .spec file"++ dryrun = switchWith 'n' "dry-run" "Just show patch"++ -- quietOpt :: Parser Verbosity+ quietOpt = flagWith normal silent 'q' "quiet" "Silence Cabal"++ pkgtype :: Parser PackageType+ pkgtype =+ flagWith' StandalonePkg 't' "standalone" "Create a standalone package that uses cabal-install to build and install" <|>+ flagWith DefaultPkg BinaryPkg 'b' "binary" "Make the base package name to be the Haskell package name"++ subpackage :: Parser Bool+ subpackage = switchWith 'S' "subpackage" "Subpackage missing Haskell dependencies"++ -- FIXME: use Version+ versionArg :: Parser String+ versionArg = strArg "VERSION"+
− src/Options.hs
@@ -1,189 +0,0 @@--- |--- Module : Options--- Copyright : (C) 2007-2008 Bryan O'Sullivan--- (C) 2012-2018 Jens Petersen------ Maintainer : Jens Petersen <petersen@fedoraproject.org>--- Stability : alpha--- Portability : portable------ Explanation: Command line option processing for building RPM--- packages.---- This program is free software: you can redistribute it and/or modify--- it under the terms of the GNU General Public License as published by--- the Free Software Foundation, either version 3 of the License, or--- (at your option) any later version.--module Options (- RpmFlags(..)- , parseArgs- , quiet- ) where--import Control.Monad (unless, when)-import Data.Char (toLower)-import Data.Maybe (listToMaybe, fromMaybe)-import Data.Version (showVersion)--import Distribution.Compiler (CompilerId)-import Distribution.Text (simpleParse)-import Distribution.PackageDescription (-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)- FlagName, mkFlagName-#else- FlagName (..)-#endif- )-import Distribution.ReadE (readEOrFail)-import Distribution.Verbosity (Verbosity, flagToVerbosity, normal,- silent)--import System.Console.GetOpt (ArgDescr (..), ArgOrder (..), OptDescr (..),- getOpt', usageInfo)-import System.Environment (getProgName)-import System.Exit (ExitCode (..), exitSuccess, exitWith)-import System.IO (Handle, hPutStrLn, stderr, stdout)--import Distro (Distro(..), readDistroName)-import Paths_cabal_rpm (version)-import SimpleCmd ((+-+))--data RpmFlags = RpmFlags- { rpmConfigurationsFlags :: [(FlagName, Bool)]- , rpmForce :: Bool- , rpmHelp :: Bool- , rpmBinary :: Bool- , rpmStandalone :: Bool- , rpmStrict :: Bool- , rpmSubpackage :: Bool- , rpmMissing :: Bool- , rpmStream :: String- , rpmRelease :: Maybe String- , rpmCompilerId :: Maybe CompilerId- , rpmDistribution :: Maybe Distro- , rpmVerbosity :: Verbosity- , rpmVersion :: Bool- }- deriving (Eq, Show)--emptyRpmFlags :: RpmFlags-emptyRpmFlags = RpmFlags- { rpmConfigurationsFlags = []- , rpmForce = False- , rpmHelp = False- , rpmBinary = False- , rpmStandalone = False- , rpmStrict = False- , rpmSubpackage = False- , rpmMissing = False- , rpmStream = defaultStream- , rpmRelease = Nothing- , rpmCompilerId = Nothing- , rpmDistribution = Nothing- , rpmVerbosity = normal- , rpmVersion = False- }--defaultStream :: String-defaultStream = "lts-12"--quiet :: RpmFlags-quiet = emptyRpmFlags {rpmVerbosity = silent}--options :: [OptDescr (RpmFlags -> RpmFlags)]-options =- [ Option "h?" ["help"] (NoArg (\x -> x { rpmHelp = True }))- "Show this help text"- , Option "b" ["binary"] (NoArg (\x -> x { rpmBinary = True }))- "Force Haskell package name to be base package name"- , Option "" ["force"] (NoArg (\x -> x { rpmForce = True }))- "Overwrite existing spec file."- , Option "s" ["stream"] (ReqArg (\s x -> x { rpmStream = s }) "STREAM") $- "Stackage stream (default '" ++ defaultStream ++ "') or 'hackage' used to get package version."- , Option "" ["missing"] (NoArg (\x -> x { rpmMissing = True }))- "Comment out missing BuildRequires packages."- , Option "" ["standalone"] (NoArg (\x -> x { rpmStandalone = True }))- "Create a standalone package that uses cabal-install to build and install."- , Option "" ["strict"] (NoArg (\x -> x { rpmStrict = True }))- "Fail rather than produce an incomplete spec file."- , Option "" ["subpackage"] (NoArg (\x -> x { rpmSubpackage = True }))- "Subpackage missing dependencies."- , Option "V" ["version"] (NoArg (\x -> x { rpmVersion = True }))- "Show version number"- , Option "f" ["flags"] (ReqArg (\flags x -> x { rpmConfigurationsFlags = rpmConfigurationsFlags x ++ flagList flags }) "FLAGS")- "Set given flags in Cabal conditionals"- , Option "" ["release"] (ReqArg (\rel x -> x { rpmRelease = Just rel }) "RELEASE")- "Override the default package release"- , Option "" ["compiler"] (ReqArg (\cid x -> x { rpmCompilerId = Just (parseCompilerId cid) }) "COMPILER-ID")- "Finalize Cabal files targetting the given compiler version"- , Option "" ["distro"] (ReqArg (\did x -> x { rpmDistribution = Just (readDistroName did) }) "DISTRO")- "Choose the distribution generated spec files will target"- , Option "v" ["verbose"] (ReqArg (\verb x -> x { rpmVerbosity = readEOrFail flagToVerbosity verb }) "n")- "Change build verbosity"- ]--#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)-#else-mkFlagName :: String -> FlagName-mkFlagName = FlagName-#endif---- Lifted from Distribution.Simple.Setup, since it's not exported.-flagList :: String -> [(FlagName, Bool)]-flagList = map tagWithValue . words- where tagWithValue ('-':name) = (mkFlagName (map toLower name), False)- tagWithValue name = (mkFlagName (map toLower name), True)--printHelp :: Handle -> IO ()-printHelp h = do- progName <- getProgName- let info = "Usage: " ++ progName ++ " [OPTION]... COMMAND [PATH|PKG|PKG-VERSION]\n"- ++ "\n"- ++ "PATH can be a .spec file, .cabal file, or pkg dir.\n"- ++ "\n"- ++ "Commands:\n"- ++ " spec\t\t- generate a spec file\n"- ++ " srpm\t\t- generate a src rpm file\n"- ++ " prep\t\t- unpack source\n"- ++ " local\t\t- build rpm package locally\n"- ++ " builddep\t- install dependencies\n"- ++ " install\t- install packages recursively\n"- ++ " depends\t- list Cabal depends\n"- ++ " requires\t- list package buildrequires\n"- ++ " missingdeps\t- list missing buildrequires\n"- ++ " diff\t\t- diff current spec file\n"- ++ " update\t- update spec file package to latest version\n"- ++ " refresh\t- refresh spec file to current cabal-rpm\n"- ++ "\n"- ++ "Options:"- hPutStrLn h (usageInfo info options)--parseCompilerId :: String -> CompilerId-parseCompilerId x = fromMaybe err (simpleParse x)- where err = error (show x ++ " is not a valid compiler id")--parseArgs :: [String] -> IO (RpmFlags, String, Maybe String)-parseArgs args = do- let (os, args', unknown, errs) = getOpt' Permute options args- opts = foldl (flip ($)) emptyRpmFlags os- when (rpmHelp opts) $ do- printHelp stdout- exitSuccess- when (rpmVersion opts) $ do- putStrLn $ showVersion version- exitSuccess- unless (null errs) $- error $ unlines errs- unless (null unknown) $- error $ "Unrecognised options:" +-+ unwords unknown- when (null args') $ do- printHelp stderr- exitWith (ExitFailure 1)- when (head args' `notElem` ["builddep", "depends", "diff", "install", "missingdeps", "prep", "requires", "spec", "srpm", "build", "local", "rpm", "update", "refresh"]) $ do- hPutStrLn stderr $ "Unknown command:" +-+ head args'- printHelp stderr- exitWith (ExitFailure 1)- when (length args' > 2) $- error $ "Too many arguments:" +-+ unwords args'- return (opts, head args', listToMaybe $ tail args')
src/PackageUtils.hs view
@@ -28,25 +28,30 @@ packageVersion, patchSpec, prepare,- prettyShow, readVersion,+ removeLibSuffix, removePrefix, removeSuffix, repoquery, rpmbuild, rpmInstall, RpmStage (..),- stripPkgDevel+ stripPkgDevel,+ unPackageName ) where import FileUtils (filesWithExtension, fileWithExtension,- getDirectoryContents_, mktempdir, withTempDirectory)-import Options (RpmFlags (..))-import SimpleCmd (cmd, cmd_, cmdIgnoreErr, cmdLines, grep_, sudo,- (+-+))+ getDirectoryContents_, mktempdir, withCurrentDirectory,+ withTempDirectory)+import SimpleCabal (finalPackageDescription, licenseFiles, mkPackageName,+ PackageName, packageName, packageVersion,+ tryFindPackageDesc, unPackageName)+import SimpleCmd (cmd, cmd_, cmdIgnoreErr, cmdLines, grep_, removePrefix,+ removeSuffix, sudo, sudo_, (+-+)) import SimpleCmd.Git (isGitDir, grepGitConfig)-import SysCmd (die, optionalProgram, requireProgram, rpmEval)+import SysCmd (optionalProgram, requireProgram, rpmEval) import Stackage (latestStackage)+import Types #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0)) #else@@ -55,8 +60,8 @@ import Control.Monad (filterM, unless, when) import Data.Char (isDigit, toLower)-import Data.List (groupBy, isPrefixOf, isSuffixOf, nub, sort, stripPrefix)-import Data.Maybe (isNothing, fromJust, fromMaybe)+import Data.List (groupBy, 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))@@ -67,72 +72,10 @@ #endif ) -#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,2,0)-import Distribution.Pretty (prettyShow)-#else-import qualified Distribution.Version (showVersion, Version)-#endif-#else-import qualified Data.Version (showVersion)-#endif--import Distribution.Compiler-import Distribution.Package (PackageIdentifier (..),-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,22,0)- unPackageName-#else- PackageName (..)-#endif- ) import Distribution.PackageDescription (PackageDescription (..), hasExes, hasLibs-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,2,0)- , mkFlagAssignment-#endif )-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)-import Distribution.PackageDescription.Configuration (finalizePD)-import Distribution.Types.ComponentRequestedSpec (defaultComponentRequestedSpec)-#else-import Distribution.PackageDescription.Configuration (finalizePackageDescription)-#endif-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,2,0)-import Distribution.PackageDescription.Parsec (readGenericPackageDescription)-#elif defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)-import Distribution.PackageDescription.Parse (readGenericPackageDescription)-#else-import Distribution.PackageDescription.Parse (readPackageDescription)-#endif -import Distribution.Simple.Compiler (-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,22,0)- compilerInfo-#else- Compiler (..)-#endif- )-import Distribution.Simple.Configure (-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,18,0)- configCompilerEx-#else- configCompiler-#endif- )-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)-import Distribution.Simple.Program (defaultProgramDb)-#else-import Distribution.Simple.Program (defaultProgramConfiguration)-#endif-import Distribution.Simple.Utils (-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,20,0)- tryFindPackageDesc-#else- findPackageDesc-#endif- )-import Distribution.System (Platform (..), buildArch, buildOS)- import System.Directory (copyFile, createDirectoryIfMissing, doesDirectoryExist, doesFileExist, getCurrentDirectory, getDirectoryContents, getModificationTime,@@ -145,17 +88,6 @@ import System.Posix.Files (accessTime, fileMode, getFileStatus, modificationTime, setFileMode) -#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,2,0)-#else-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)-prettyShow :: Distribution.Version.Version -> String-prettyShow = Distribution.Version.showVersion-#else-prettyShow :: Version -> String-prettyShow = Data.Version.showVersion-#endif-#endif- stripVersion :: String -> String stripVersion n | '-' `notElem` n = n stripVersion nv = if hasVer then reverse emaN else nv@@ -163,69 +95,18 @@ (reV, '-':emaN) = break (== '-') $ reverse nv hasVer = all (\c -> isDigit c || c == '.') reV -simplePackageDescription :: FilePath -> RpmFlags+simplePackageDescription :: Flags -> FilePath -> IO (PackageDescription, [FilePath], [FilePath])-simplePackageDescription cabalfile opts = do- final <- finalPackageDescription cabalfile opts+simplePackageDescription flags cabalfile = do+ final <- finalPackageDescription flags cabalfile (docs, licensefiles) <- findDocsLicenses (dropFileName cabalfile) final return (final, docs, licensefiles) -finalPackageDescription :: FilePath -> RpmFlags- -> IO PackageDescription-finalPackageDescription cabalfile opts = do- let verbose = rpmVerbosity opts-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)-#else- let readGenericPackageDescription = readPackageDescription- defaultProgramDb = defaultProgramConfiguration-#endif-- genPkgDesc <- readGenericPackageDescription verbose cabalfile- compiler <- case rpmCompilerId opts of- Just cid -> return-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,22,0)- (unknownCompilerInfo cid NoAbiTag)-#else- cid-#endif- Nothing -> do-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,18,0)- (compiler, _, _) <- configCompilerEx-#else- (compiler, _) <- configCompiler-#endif- (Just GHC) Nothing Nothing defaultProgramDb verbose-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,22,0)- return (compilerInfo compiler)-#else- return (compilerId compiler)-#endif-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,2,0)-#else- let mkFlagAssignment = id-#endif-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)- let finalizePackageDescription flags = finalizePD flags defaultComponentRequestedSpec-#endif- let final =- finalizePackageDescription (mkFlagAssignment $ rpmConfigurationsFlags opts)- (const True) (Platform buildArch buildOS)- compiler- [] genPkgDesc- case final of- Left e -> die $ "finalize failed: " ++ show e- Right res -> return $ fst res- findDocsLicenses :: FilePath -> PackageDescription -> IO ([FilePath], [FilePath]) findDocsLicenses dir pkgDesc = do contents <- getDirectoryContents dir let docs = sort $ filter unlikely $ filter (likely docNames) contents- let licenses = sort $ nub $-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,20,0)- licenseFiles pkgDesc-#else- [licenseFile pkgDesc | licenseFile pkgDesc /= ""]-#endif+ let licenses = sort $ nub $ licenseFiles pkgDesc ++ filter (likely licenseNames) contents docfiles = if null licenses then docs else filter (`notElem` licenses) docs return (docfiles, licenses)@@ -237,12 +118,6 @@ unlikely name = not $ any (`isSuffixOf` name) ["~", ".cabal"] -#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,20,0)-#else-tryFindPackageDesc :: FilePath -> IO FilePath-tryFindPackageDesc = findPackageDesc-#endif- cabalFromSpec :: FilePath -> Bool -> IO FilePath cabalFromSpec specFile revise = do -- no rpmspec command in RHEL 5 and 6@@ -253,8 +128,10 @@ then do specTime <- modificationTime <$> getFileStatus specFile dirTime <- accessTime <$> getFileStatus namever- when (specTime > dirTime) $+ when (specTime > dirTime) $ do rpmbuild Prep specFile+ dExists' <- doesDirectoryExist namever+ when dExists' $ cmd_ "touch" [namever] else rpmbuild Prep specFile tryFindPackageDesc namever@@ -350,7 +227,7 @@ where (rev, '-':eman) = break (== '-') $ reverse nv -data RpmStage = Binary | Source | Prep | BuildDep deriving Eq+data RpmStage = Binary | Source | Prep deriving Eq rpmbuild :: RpmStage -> FilePath -> IO () rpmbuild mode spec = do@@ -358,7 +235,6 @@ Binary -> "a" Source -> "s" Prep -> "p"- BuildDep -> "_" cwd <- getCurrentDirectory gitDir <- isGitDir "." let rpmdirs_override =@@ -369,18 +245,15 @@ rpmdirs_override ++ [spec] -removePrefix :: String -> String-> String-removePrefix pref str = fromMaybe str (stripPrefix pref str)--removeSuffix :: String -> String -> String-removeSuffix suffix orig =- fromMaybe orig $ stripSuffix suffix orig- where- stripSuffix sf str = reverse <$> stripPrefix (reverse sf) (reverse str)- 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"@@ -395,7 +268,8 @@ if haveFile then do ts <- getModificationTime tsfile t <- getCurrentTime- when (diffUTCTime t ts > 600) $ cmd_ "cabal" ["update"]+ -- less than 3 hours+ when (diffUTCTime t ts > 10000) $ cmd_ "cabal" ["update"] return True else return False@@ -415,8 +289,12 @@ isdir <- doesDirectoryExist pkgver if isdir then do- pth <- tryFindPackageDesc pkgver- return (pth, Nothing)+ let (n,_) = nameVersion pkgver+ mcabal <- withCurrentDirectory pkgver $ checkForCabalFile (Just n)+ if isJust mcabal then do+ pth <- tryFindPackageDesc pkgver+ return (pth, Nothing)+ else error $ "could not find" +-+ n <.> "cabal" else do cwd <- getCurrentDirectory tmpdir <- mktempdir@@ -426,16 +304,17 @@ setCurrentDirectory cwd return (tmpdir </> pth, Just tmpdir) -latestPackage :: String -> String -> IO String-latestPackage "hackage" pkg = latestHackage pkg-latestPackage str pkg = do- stk <- latestStackage str pkg+latestPackage :: Stream -> PackageName -> IO String+latestPackage Hackage pkg = latestHackage pkg+latestPackage stream pkg = do+ stk <- latestStackage stream pkg case stk of Just pv -> return pv Nothing -> latestHackage pkg -latestHackage :: String -> IO String-latestHackage pkg = do+latestHackage :: PackageName -> IO String+latestHackage pkgname = do+ let pkg = unPackageName pkgname contains_pkg <- cabal "list" ["-v0", pkg] let top = dropWhile (/= "*" +-+ pkg) contains_pkg if null top@@ -450,33 +329,21 @@ putStrLn $ res +-+ "in Hackage" return res -#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,22,0)-#else-unPackageName :: PackageName -> String-unPackageName (PackageName n) = n-#endif--packageName :: PackageIdentifier -> String-packageName = unPackageName . pkgName--packageVersion :: PackageIdentifier -> String-packageVersion = prettyShow . pkgVersion- getPkgName :: Maybe FilePath -> PackageDescription -> Bool -> IO (String, Bool) getPkgName (Just spec) pkgDesc binary = do- let name = packageName $ package pkgDesc+ 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 = packageName $ package pkgDesc+ 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) checkForSpecFile :: Maybe String -> IO (Maybe FilePath) checkForSpecFile mpkg = do- allSpecs <- allSpecfiles+ allSpecs <- filesWithExtension "." ".spec" -- emacs makes ".#*.spec" tmp files let predicate = maybe ((/= '.') . head) (\ pkg -> (`elem` [pkg <.> "spec", "ghc-" ++ pkg <.> "spec"])) mpkg specs = filter predicate allSpecs@@ -487,11 +354,18 @@ [] -> return Nothing _ -> error "More than one spec file found!" -allSpecfiles :: IO [FilePath]-allSpecfiles = filesWithExtension "." ".spec"+checkForCabalFile :: Maybe Package -> IO (Maybe FilePath)+checkForCabalFile mpkg = do+ allCabals <- filesWithExtension "." ".cabal"+ let predicate = maybe (const True) (\ pkg -> (== pkg <.> "cabal")) mpkg+ cabals = filter predicate allCabals+ case cabals of+ [one] -> return $ Just one+ [] -> return Nothing+ _ -> error "More than one cabal file found!" -checkForCabalFile :: String -> IO (Maybe FilePath)-checkForCabalFile pkgmver = do+checkForPkgCabalFile :: String -> IO (Maybe FilePath)+checkForPkgCabalFile pkgmver = do let pkg = stripVersion pkgmver cabalfile = pkg <.> "cabal" pkgcabal <- doesFileExist cabalfile@@ -519,41 +393,48 @@ -- Nothing implies existing packaging in cwd -- Something implies either new packaging or some existing spec file in dir-prepare :: RpmFlags -> Maybe String -> Bool -> IO PackageData-prepare flags mpkgver revise = do+prepare :: Flags -> Stream -> Maybe Package -> Bool -> IO PackageData+prepare flags stream mpkgver revise = do let mpkg = stripVersion <$> mpkgver mspec <- checkForSpecFile mpkg case mspec of Just spec -> do cabalfile <- cabalFromSpec spec revise- (pkgDesc, docs, licenses) <- simplePackageDescription cabalfile flags+ (pkgDesc, docs, licenses) <- simplePackageDescription flags cabalfile return $ PackageData mspec docs licenses pkgDesc Nothing -> case mpkgver of Nothing -> do- cwd <- getCurrentDirectory- prepare flags (Just $ takeFileName cwd) revise+ mcabal <- checkForCabalFile mpkg+ 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 <- checkForCabalFile pkgmver+ mcabal <- checkForPkgCabalFile pkgmver case mcabal of Just cabalfile -> do- (pkgDesc, docs, licenses) <- simplePackageDescription cabalfile flags+ (pkgDesc, docs, licenses) <- simplePackageDescription flags cabalfile return $ PackageData Nothing docs licenses pkgDesc Nothing -> do pkgver <- if stripVersion pkgmver == pkgmver- then latestPackage (rpmStream flags) pkgmver+ then latestPackage stream (mkPackageName pkgmver) else return pkgmver (cabalfile, mtmp) <- tryUnpack pkgver revise- (pkgDesc, docs, licenses) <- simplePackageDescription cabalfile flags+ (pkgDesc, docs, licenses) <- simplePackageDescription flags cabalfile maybe (return ()) removeDirectoryRecursive mtmp return $ PackageData Nothing docs licenses pkgDesc -patchSpec :: Maybe FilePath -> FilePath -> FilePath -> IO ()-patchSpec mdir oldspec newspec = do+patchSpec :: Bool -> Maybe FilePath -> FilePath -> FilePath -> IO ()+patchSpec dryrun mdir oldspec newspec = do diff <- cmdIgnoreErr "diff" ["-u2", "-I", "- spec file generated by cabal-rpm", "-I", "Fedora Haskell SIG <haskell@lists.fedoraproject.org>", oldspec, newspec] "" >>= cmdIgnoreErr "sed" ["-e", "s/.cblrpm//"] putStrLn diff- out <- cmdIgnoreErr "patch" opts diff- putStrLn out+ unless dryrun $ do+ out <- cmdIgnoreErr "patch" opts diff+ putStrLn out where opts = ["--fuzz=1"] ++ ["-p1" | '/' `elem` newspec] ++ maybe [] (\ d -> ["-d", d]) mdir @@ -568,15 +449,15 @@ repoquery args key = do havednf <- optionalProgram "dnf" let (prog, subcmd) = if havednf then ("dnf", ["repoquery", "-q"]) else ("repoquery", [])- cmd prog (subcmd ++ args ++ [key])+ sudo prog (subcmd ++ args ++ [key]) -rpmInstall :: [String] -> IO ()-rpmInstall [] = return ()-rpmInstall rpms = do+rpmInstall :: Bool -> [String] -> IO ()+rpmInstall _ [] = return ()+rpmInstall yes rpms = do pkginstaller <- packageManager let (inst, arg) = if pkginstaller == "dnf" then ("dnf", "install") else ("yum", "localinstall") tty <- hIsTerminalDevice stdout- sudo inst $ ["-y" | not tty] ++ [arg] ++ rpms+ sudo_ inst $ ["-y" | yes || not tty] ++ [arg] ++ rpms editSpecField :: String -> String -> FilePath -> IO () editSpecField field new spec =
src/Stackage.hs view
@@ -20,12 +20,12 @@ ) where -import Control.Monad (when, unless)+import Control.Monad (when) import Data.Maybe (isJust, fromJust)-import Data.List (isPrefixOf) #ifdef HTTPS import qualified Data.ByteString.Char8 as B+import Data.List (isPrefixOf) import Data.Maybe (mapMaybe) import Network.HTTP.Client import Network.HTTP.Client.TLS@@ -39,13 +39,15 @@ import SimpleCmd ((+-+), cmdMaybe) import SysCmd (optionalProgram) #endif+import SimpleCabal (PackageName, unPackageName)+import Types -stackageList :: String -> String -> IO (Maybe String)+stackageList :: Stream -> PackageName -> IO (Maybe String) stackageList stream pkg = do #ifdef HTTPS mgr <- newManager tlsManagerSettings- let pkgurl = topurl ++ stream ++ "/package/"- req <- parseRequest $ pkgurl ++ pkg+ let pkgurl = topurl ++ (show stream) ++ "/package/"+ req <- parseRequest $ pkgurl ++ unPackageName pkg hist <- responseOpenHistory req mgr let redirs = mapMaybe (lookup "Location" . responseHeaders . snd) $ hrRedirects hist if null redirs@@ -63,17 +65,15 @@ haveStackage <- optionalProgram "stackage" if haveStackage then- fmap ((pkg ++ "-") ++) <$> cmdMaybe "stackage" ["package", stream, pkg]+ fmap ((unPackageName pkg ++ "-") ++) <$> cmdMaybe "stackage" ["package", show stream, unPackageName pkg] else do putStrLn "'cabal install stackage-query' to check against Stackage LTS" return Nothing #endif -latestStackage :: String -> String -> IO (Maybe String)+latestStackage :: Stream -> PackageName -> IO (Maybe String) latestStackage stream pkg = do- unless (any (`isPrefixOf` stream) ["nightly", "lts"]) $- putStrLn $ "Unknown Stackage stream:" +-+ stream mpkg <- stackageList stream pkg when (isJust mpkg) $- putStrLn $ fromJust mpkg +-+ "in Stackage" +-+ stream+ putStrLn $ fromJust mpkg +-+ "in Stackage" +-+ show stream return mpkg
src/SysCmd.hs view
@@ -29,12 +29,8 @@ import Control.Monad (void, when) import Data.Maybe (isJust, isNothing) -#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,18,0) #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0) import Distribution.Simple.Utils (dieNoVerbosity)-#else-import Distribution.Simple.Utils (die)-#endif #else import Distribution.Simple.Utils (die) #endif
+ src/Types.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE CPP #-}++-- |+-- Module : Types+-- Copyright : (C) 2019 Jens Petersen+--+-- Maintainer : Jens Petersen <petersen@fedoraproject.org>+--+-- Explanation: types for cabal-rpm++-- This program is free software: you can redistribute it and/or modify+-- it under the terms of the GNU General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.++module Types (+ Flags, -- flagList,+ Package,+ PackageType(..),+ Stream(..),+ Verbose(..)+ ) where++import Data.Char (isDigit {--, toLower--})+import Data.List+import Data.Maybe (fromMaybe)+#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,11,0))+#else+import Data.Semigroup ((<>))+#endif+import SimpleCabal (FlagName {--, mkFlagName--})++type Package = String++data Verbose = Quiet | Verbose+ deriving Eq++type Flags = [(FlagName, Bool)]++-- -- lifted from Distribution.Simple.Setup, since it's not exported.+-- flagList :: String -> Flags+-- flagList = map tagWithValue . words+-- where tagWithValue ('-':name) = (mkFlagName (map toLower name), False)+-- tagWithValue name = (mkFlagName (map toLower name), True)++data Stream = LatestNightly | LatestLTS | LTS String | Nightly String | Hackage++instance Show Stream where+ show LatestNightly = "nightly"+ show LatestLTS = "lts"+ show (Nightly date) = "nightly-" <> date+ show (LTS ver) = "lts-" <> ver+ show Hackage = "hackage"++instance Read Stream where+ readsPrec _ "hackage" = [(Hackage,"")]+ readsPrec _ "nightly" = [(LatestNightly,"")]+ readsPrec _ "lts" = [(LatestLTS,"")]+ readsPrec _ input | "nightly-" `isPrefixOf` input =+ let (date,rest) = span (\ c -> isDigit c || c == '-') $ removePrefix "nightly-" input in+ [(Nightly date,rest)]+ readsPrec _ input | "lts-" `isPrefixOf` input =+ let (ver,rest) = span (\ c -> isDigit c || c == '.') $ removePrefix "lts-" input in+ [(LTS ver,rest)]+ readsPrec _ _ = []++removePrefix :: String -> String-> String+removePrefix pref orig = fromMaybe orig (stripPrefix pref orig)++data PackageType = DefaultPkg | BinaryPkg | StandalonePkg | SpecFile FilePath+ deriving Eq