packages feed

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 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