packages feed

cabal-rpm 0.12 → 0.12.1

raw patch · 13 files changed

+221/−233 lines, 13 files

Files

ChangeLog view
@@ -1,3 +1,11 @@+* 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)+- no longer leave leftover tmpdirs (#26)+- change 'cblrpm' to 'cabal-rpm' in documentation+- drop support for SCM snapshot releases+ * 0.12 (2017-11-17) - default to querying stackage.org directly via https - fix stackage-query usage and suggest installing if missing@@ -9,7 +17,7 @@ - allow building with ghc-8.2 and Cabal-2.0  * 0.11.2 (2017-07-31)-- fix cblrpm update --subpackage+- 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)
cabal-rpm.cabal view
@@ -1,10 +1,10 @@ Name:                cabal-rpm-Version:             0.12+Version:             0.12.1 Synopsis:            RPM packaging tool for Haskell Cabal-based packages Description:     This package provides a RPM packaging tool for Haskell Cabal-based packages.     .-    cblrpm has commands to generate a RPM spec file and srpm for a package.+    cabal-rpm has commands to generate a RPM spec file and srpm for a package.     It can rpmbuild packages, yum/dnf install their dependencies, prep packages,     and install them. There are commands to list package dependencies and     missing dependencies. The diff command compares the current spec file
man/cabal-rpm.1 view
@@ -1,43 +1,44 @@-.\" Automatically generated by Pandoc 1.19.1+.\" Automatically generated by Pandoc 1.19.2.4 .\"-.TH "CBLRPM" "1" "2013\-01\-21" "" ""+.TH "CABAL\-RPM" "1" "2013\-01\-21" "" "" .hy .SH NAME .PP-cblrpm \- a RPM packaging tool for Haskell Cabal packages+cabal\-rpm \- a RPM packaging tool for Haskell Cabal packages .SH SYNOPSIS .PP-cblrpm [\f[I]options\f[]] spec [\f[I]path\-or\-pkg\f[]] cblrpm-[\f[I]options\f[]] local [\f[I]path\-or\-pkg\f[]] cblrpm-[\f[I]options\f[]] srpm [\f[I]path\-or\-pkg\f[]] cblrpm-[\f[I]options\f[]] prep [\f[I]path\-or\-pkg\f[]] cblrpm-[\f[I]options\f[]] builddep [\f[I]path\-or\-pkg\f[]] cblrpm-[\f[I]options\f[]] install [\f[I]path\-or\-pkg\f[]] cblrpm-[\f[I]options\f[]] depends [\f[I]path\-or\-pkg\f[]] cblrpm-[\f[I]options\f[]] requires [\f[I]path\-or\-pkg\f[]] cblrpm-[\f[I]options\f[]] missingdeps [\f[I]path\-or\-pkg\f[]] cblrpm-[\f[I]options\f[]] diff [\f[I]path\-or\-pkg\f[]] cblrpm-[\f[I]options\f[]] update [\f[I]path\-or\-pkg\f[]] cblrpm+cabal\-rpm [\f[I]options\f[]] spec [\f[I]path\-or\-pkg\f[]] cabal\-rpm+[\f[I]options\f[]] local [\f[I]path\-or\-pkg\f[]] cabal\-rpm+[\f[I]options\f[]] srpm [\f[I]path\-or\-pkg\f[]] cabal\-rpm+[\f[I]options\f[]] prep [\f[I]path\-or\-pkg\f[]] cabal\-rpm+[\f[I]options\f[]] builddep [\f[I]path\-or\-pkg\f[]] cabal\-rpm+[\f[I]options\f[]] install [\f[I]path\-or\-pkg\f[]] cabal\-rpm+[\f[I]options\f[]] depends [\f[I]path\-or\-pkg\f[]] cabal\-rpm+[\f[I]options\f[]] requires [\f[I]path\-or\-pkg\f[]] cabal\-rpm+[\f[I]options\f[]] missingdeps [\f[I]path\-or\-pkg\f[]] cabal\-rpm+[\f[I]options\f[]] diff [\f[I]path\-or\-pkg\f[]] cabal\-rpm+[\f[I]options\f[]] update [\f[I]path\-or\-pkg\f[]] cabal\-rpm [\f[I]options\f[]] refresh [\f[I]path\-or\-pkg\f[]] .SH DESCRIPTION .PP-cblrpm generates RPM packages and .spec files from Haskell Cabal+cabal\-rpm generates RPM packages and .spec files from Haskell Cabal package. .PP-If no \f[I]path\-or\-pkg\f[] is specified, cblrpm looks for a .spec or-\&.cabal file in the current directory.+If no \f[I]path\-or\-pkg\f[] is specified, cabal\-rpm looks for a .spec+or .cabal file in the current directory. Otherwise, it will look for \f[I]path\-or\-pkg\f[]. If the argument is a directory then it will look there for a .spec or \&.cabal file. If the argument is a path to a .cabal file then it will use it. Otherwise if there is no \[aq]/\[aq] in the argument and it does not-exist then cblrpm will try to unpack the package and use its .cabal+exist then cabal\-rpm will try to unpack the package and use its .cabal file.-cblrpm uses a temporary directory for unpackaging tarballs or packages.-cblrpm then parses the .cabal file and uses it to generate a .spec file-that can be built.+cabal\-rpm uses a temporary directory for unpackaging tarballs or+packages.+cabal\-rpm then parses the .cabal file and uses it to generate a .spec+file that can be built. .PP-If a .spec already exists, cblrpm outputs to .spec.cblrpm instead.+If a .spec already exists, cabal\-rpm outputs to .spec.cblrpm instead. .SH OPTIONS .TP .B \-h, \-\-help@@ -78,7 +79,7 @@ .IP .nf \f[C]-cblrpm\ CMD+cabal\-rpm\ CMD \f[] .fi .PP@@ -86,7 +87,7 @@ .IP .nf \f[C]-cblrpm\ CMD\ [package]+cabal\-rpm\ CMD\ [package] \f[] .fi .PP@@ -94,7 +95,7 @@ .IP .nf \f[C]-cblrpm\ CMD\ [package\-version]+cabal\-rpm\ CMD\ [package\-version] \f[] .fi .PP@@ -102,7 +103,7 @@ .IP .nf \f[C]-cblrpm\ CMD\ path/to/some.cabal+cabal\-rpm\ CMD\ path/to/some.cabal \f[] .fi .SH HISTORY
man/cabal-rpm.1.md view
@@ -1,38 +1,38 @@-% CBLRPM(1)+% CABAL-RPM(1) % This manpage was written by Jens Petersen % 2013-01-21  # NAME-cblrpm - a RPM packaging tool for Haskell Cabal packages+cabal-rpm - a RPM packaging tool for Haskell Cabal packages  # SYNOPSIS-cblrpm [*options*] spec [*path-or-pkg*]-cblrpm [*options*] local [*path-or-pkg*]-cblrpm [*options*] srpm [*path-or-pkg*]-cblrpm [*options*] prep [*path-or-pkg*]-cblrpm [*options*] builddep [*path-or-pkg*]-cblrpm [*options*] install [*path-or-pkg*]-cblrpm [*options*] depends [*path-or-pkg*]-cblrpm [*options*] requires [*path-or-pkg*]-cblrpm [*options*] missingdeps [*path-or-pkg*]-cblrpm [*options*] diff [*path-or-pkg*]-cblrpm [*options*] update [*path-or-pkg*]-cblrpm [*options*] refresh [*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-cblrpm generates RPM packages and .spec files from Haskell Cabal package.+cabal-rpm generates RPM packages and .spec files from Haskell Cabal package. -If no *path-or-pkg* is specified, cblrpm looks for a .spec or .cabal file+If no *path-or-pkg* is specified, cabal-rpm looks for a .spec or .cabal file in the current directory.  Otherwise, it will look for *path-or-pkg*. If the argument is a directory then it will look there for a .spec or .cabal file. If the argument is a path to a .cabal file then it will use it. Otherwise if there is no '/' in the argument and it does not exist-then cblrpm will try to unpack the package and use its .cabal file.-cblrpm uses a temporary directory for unpackaging tarballs or packages.-cblrpm then parses the .cabal file and uses it to generate a .spec file+then cabal-rpm will try to unpack the package and use its .cabal file.+cabal-rpm uses a temporary directory for unpackaging tarballs or packages.+cabal-rpm then parses the .cabal file and uses it to generate a .spec file that can be built. -If a <PKG>.spec already exists, cblrpm outputs to <PKG>.spec.cblrpm instead.+If a <PKG>.spec already exists, cabal-rpm outputs to <PKG>.spec.cblrpm instead.  # OPTIONS -h, --help@@ -60,19 +60,19 @@  Do CMD for the package in current directory: -    cblrpm CMD+    cabal-rpm CMD  Do CMD for package (directory or package name):  -    cblrpm CMD [package]+    cabal-rpm CMD [package]  Do CMD for package-version (directory or package name): -    cblrpm CMD [package-version]+    cabal-rpm CMD [package-version]  Do CMD on a .cabal file: -    cblrpm CMD path/to/some.cabal+    cabal-rpm CMD path/to/some.cabal  # HISTORY Cabal-rpm was originally written by Bryan O'Sullivan in 2007-2008
src/Commands/Depends.hs view
@@ -28,7 +28,6 @@ #endif import Control.Monad (filterM, unless, void) import Data.List (nub, sort, (\\))-import System.Directory (removeDirectoryRecursive)  data Depends = Depends | Requires | Missing @@ -69,7 +68,6 @@ missingDepsPkg :: String -> IO [String] missingDepsPkg pkg = do   pkgdata <- prepare quiet (Just pkg)-  maybe (return ()) removeDirectoryRecursive $ workingDir pkgdata   missingPackages (packageDesc pkgdata) >>= filterM notAvail  putMissing :: String -> [String] -> [String] -> IO ()
src/Commands/Diff.hs view
@@ -6,7 +6,7 @@ -- Stability   :  alpha -- Portability :  portable ----- Explanation: diff current spec file with cblrpm spec output+-- Explanation: diff current spec file with cabal-rpm spec output  -- 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
src/Commands/Install.hs view
@@ -18,9 +18,9 @@     ) where  import Commands.RpmBuild (rpmBuild)-import Dependencies (missingPackages, notInstalled)+import Dependencies (missingPackages, notInstalled, pkgInstallMissing) import Options (RpmFlags (..))-import PackageUtils (PackageData (..), pkgInstall, rpmInstall, RpmStage (..), stripPkgDevel)+import PackageUtils (PackageData (..), rpmInstall, RpmStage (..), stripPkgDevel) import SysCmd (cmd, cmd_, (+-+))  #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))@@ -34,13 +34,11 @@ install :: PackageData -> RpmFlags -> IO () install pkgdata flags = do   let pkgDesc = packageDesc pkgdata-  missing <- missingPackages pkgDesc-  unless (null missing) $ do-    pkgInstall missing False-    stillMissing <- missingPackages pkgDesc-    unless (null stillMissing) $ do-      putStrLn $ "Missing:" +-+ unwords stillMissing-      mapM_ installMissing stillMissing+  pkgInstallMissing pkgdata False+  stillMissing <- missingPackages pkgDesc+  unless (null stillMissing) $ do+    putStrLn $ "Missing:" +-+ unwords stillMissing+    mapM_ cblrpmInstallMissing stillMissing   spec <- rpmBuild pkgdata flags Binary   arch <- cmd "arch" []   rpmdir <- cmd "rpm" ["--eval", "%{_rpmdir}"]@@ -49,10 +47,10 @@   -- metapkgs don't have base package   filterM doesFileExist rpms >>= rpmInstall -installMissing :: String -> IO ()-installMissing pkg = do-  noInstall <- notInstalled pkg-  when noInstall $ do+cblrpmInstallMissing :: String -> IO ()+cblrpmInstallMissing pkg = do+  noPkg <- notInstalled pkg+  when noPkg $ do     let dep = stripPkgDevel pkg-    putStrLn $ "Running cblrpm install" +-+ dep-    cmd_ "cblrpm" ["install", dep]+    putStrLn $ "Running cabal-rpm install" +-+ dep+    cmd_ "cabal-rpm" ["install", dep]
src/Commands/RpmBuild.hs view
@@ -20,21 +20,20 @@     ) where  import Commands.Spec (createSpecFile)-import Dependencies (missingPackages)+import Dependencies (pkgInstallMissing) import Options (RpmFlags (..))-import PackageUtils (copyTarball, isScmDir, PackageData (..), packageName,-                     packageVersion, rpmbuild, pkgInstall, RpmStage (..))+import PackageUtils (copyTarball, PackageData (..), packageName,+                     packageVersion, rpmbuild, RpmStage (..)) import SysCmd (cmd, (+-+))  --import Control.Exception (bracket) import Control.Monad    (unless, void, when)- import Distribution.PackageDescription (PackageDescription (..))  --import Distribution.Version (VersionRange, foldVersionRange')  import System.Directory (doesFileExist)-import System.FilePath (takeDirectory, (</>))+import System.FilePath ((</>))  -- autoreconf :: Verbosity -> PackageDescription -> IO () -- autoreconf verbose pkgDesc = do@@ -53,15 +52,13 @@ --    autoreconf verbose pkgDesc   let pkgDesc = packageDesc pkgdata       mspec = specFilename pkgdata-      cabalPath = cabalFilename pkgdata   specFile <- maybe (createSpecFile pkgdata flags Nothing)               (\ s -> putStrLn ("Using existing" +-+ s) >> return s)               mspec   let pkg = package pkgDesc       name = packageName pkg-  when (stage `elem` [Binary,BuildDep]) $ do-    missing <- missingPackages pkgDesc-    pkgInstall missing (stage == Binary)+  when (stage `elem` [Binary,BuildDep]) $+    pkgInstallMissing pkgdata (stage == Binary)    unless (stage == BuildDep) $ do     srcdir <- cmd "rpm" ["--eval", "%{_sourcedir}"]@@ -69,10 +66,8 @@         tarFile = srcdir </> name ++ "-" ++ version ++ ".tar.gz"      tarFileExists <- doesFileExist tarFile-    unless tarFileExists $ do-      scmRepo <- isScmDir $ takeDirectory cabalPath-      when scmRepo $-        error "No tarball for source repo"+    unless tarFileExists $+      error "No tarball for source repo"      copyTarball name version False srcdir 
src/Commands/Spec.hs view
@@ -20,11 +20,11 @@   createSpecFile, createSpecFile_   ) where -import Dependencies (notInstalled, packageDependencies, showDep,-                     subPackages, testsuiteDependencies)+import Dependencies (notInstalled, missingPackages, packageDependencies,+                     showDep, subPackages, testsuiteDependencies) import Distro (Distro(..), detectDistro) import Options (RpmFlags (..))-import PackageUtils (copyTarball, getPkgName, isScmDir, latestPackage,+import PackageUtils (copyTarball, getPkgName, latestPackage,                      nameVersion, PackageData (..), packageName,                      packageVersion, stripPkgDevel) import SysCmd ((+-+), notNull)@@ -34,9 +34,9 @@ import Control.Applicative ((<$>)) #endif import Control.Monad    (filterM, unless, void, when, (>=>))-import Data.Char        (toLower, toUpper)-import Data.List        (groupBy, intercalate, intersect, isPrefixOf, isSuffixOf,-                         sort, (\\))+import Data.Char        (toUpper)+import Data.List        (groupBy, intercalate, intersect, isPrefixOf,+                         nub, sort, (\\)) import Data.Maybe       (fromMaybe, fromJust) import Data.Time.Clock  (getCurrentTime) import Data.Time.Format (formatTime)@@ -64,27 +64,21 @@  --import Distribution.Version (VersionRange, foldVersionRange') -import System.Directory (doesFileExist, getDirectoryContents)+import System.Directory (doesFileExist) import System.IO     (IOMode (..), hClose, hPutStrLn, openFile) #if defined(MIN_VERSION_time) && MIN_VERSION_time(1,5,0) import Data.Time.Format (defaultTimeLocale) #else import System.Locale (defaultTimeLocale) #endif-import System.FilePath (dropFileName, takeBaseName, takeDirectory, (</>))+import System.FilePath (takeBaseName, (</>))  import qualified Paths_cabal_rpm (version)  -defaultRelease :: FilePath -> Distro -> IO String-defaultRelease cabalPath distro = do-  let pkgDir = takeDirectory cabalPath-  scmRepo <- isScmDir pkgDir-  if scmRepo-    then do-    now <- getCurrentTime-    return $ formatTime defaultTimeLocale "0.%Y%m%d" now-    else return $ if distro == SUSE then "0" else "1"+defaultRelease :: Distro -> String+defaultRelease distro =+    if distro == SUSE then "0" else "1"  rstrip :: (Char -> Bool) -> String -> String rstrip p = reverse . dropWhile p . reverse@@ -102,7 +96,8 @@                   Maybe FilePath -> IO FilePath createSpecFile pkgdata flags mdest = do   let mspec = specFilename pkgdata-      cabalPath = cabalFilename pkgdata+      docs = docFilenames pkgdata+      licensefiles = licenseFilenames pkgdata       pkgDesc = packageDesc pkgdata       pkg = package pkgDesc       name = packageName pkg@@ -200,11 +195,15 @@    -- FIXME sort by build order   -- FIXME recursive missingdeps-  missing <- if rpmSubpackage flags then subPackages (if specAlreadyExists then mspec else Nothing) pkgDesc else return []-  subpkgs <-+  missing <- do+    subs <- if rpmSubpackage flags then subPackages (if specAlreadyExists then mspec else Nothing) pkgDesc else return []+    miss <- if rpmSubpackage flags || rpmMissing flags then missingPackages pkgDesc else return []+    return $ nub (subs ++ miss)+  subpkgs <- if rpmSubpackage flags then     mapM ((getsubpkgMacro flags >=>            \(m,pv) -> put ("%global" +-+ m +-+ pv) >> return ("%{" ++ m ++ "}"))            . stripPkgDevel) missing+    else return []   let hasSubpkgs = notNull subpkgs   when hasSubpkgs $ do     put $ "%global subpkgs" +-+ unwords subpkgs@@ -214,15 +213,8 @@     put $ "%bcond_" ++ (if null missTestDeps then "without" else "with") +-+ "tests"     putNewline -  -- let eCsources = concatMap (cSources . buildInfo) $ executables pkgDesc-  -- let lCsources = concatMap (cSources . libBuildInfo) $ maybeToList $ library pkgDesc-  -- when (null $ eCsources ++ lCsources) $ do-  --   put "# no useful debuginfo for Haskell packages without C sources"-  --   put $ "%global debug_package" +-+ "%{nil}"-  --   putNewline--  defRelease <- defaultRelease cabalPath distro   let version = packageVersion pkg+      defRelease = defaultRelease distro       release = fromMaybe defRelease (rpmRelease flags)       revision = show $ maybe (0::Int) read (lookup "x-revision" (customFieldsPD pkgDesc))   putHdr "Name" (if binlib then "%{pkg_name}" else basename)@@ -252,8 +244,7 @@   putHdr "BuildRequires" "ghc-Cabal-devel"   putHdr "BuildRequires" $ "ghc-rpm-macros" ++ (if hasSubpkgs then "-extra" else "") -  let isa = if distro == SUSE then "" else "%{?_isa}"-  let alldeps = sort $ deps ++ tools ++ map (++ isa) clibs ++ pkgcfgs+  let alldeps = sort $ deps ++ tools ++ clibs ++ pkgcfgs   let extraTestDeps = sort $ testsuiteDeps \\ deps   unless (null $ alldeps ++ extraTestDeps) $ do     put "# Begin cabal-rpm deps:"@@ -306,6 +297,7 @@     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 exposesModules $       putHdr "Requires" $ (if binlib then "ghc-%{name}" else "%{name}") ++ isa +-+ "= %{version}-%{release}"     unless (null $ clibs ++ pkgcfgs) $ do@@ -355,15 +347,6 @@   when selfdep $     put $ "%ghc_fix_rpath" +-+ pkgver -  let licensefiles =-#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,20,0)-        licenseFiles pkgDesc-#else-        if null (licenseFile pkgDesc) then [] else [licenseFile pkgDesc]-#endif--  -- remove docs from datafiles (#38)-  docs <- sort <$> findDocs cabalPath licensefiles   let datafiles = dataFiles pkgDesc       dupdocs = docs `intersect` datafiles       datafiles' = datafiles \\ dupdocs@@ -406,7 +389,8 @@     when (distro /= Fedora) $ put "%defattr(-,root,root,-)"     -- Add the license file to the main package only if it wouldn't     -- otherwise be empty.-    mapM_ (\ l -> put $ license_macro +-+ l) licensefiles+    unless (selfdep && binlib) $+      mapM_ (\ l -> put $ license_macro +-+ l) licensefiles     unless (null docs) $       put $ "%doc" +-+ unwords docs     mapM_ ((\ p -> put $ "%{_bindir}" </> (if p == name then "%{name}" else p)) . unUnqualComponentName) execs@@ -453,19 +437,6 @@  isBuildable :: Executable -> Bool isBuildable exe = buildable $ buildInfo exe--findDocs :: FilePath -> [FilePath] -> IO [FilePath]-findDocs cabalPath licensefiles = do-  contents <- getDirectoryContents $ dropFileName cabalPath-  let docs = filter likely contents-  return $ if null licensefiles-           then docs-           else filter unlikely $ filter (`notElem` licensefiles) docs-  where names = ["author", "changelog", "changes", "contributors", "copying", "doc",-                 "example", "licence", "license", "news", "readme", "todo"]-        likely name = let lowerName = map toLower name-                      in any (`isPrefixOf` lowerName) names-        unlikely name = not $ any (`isSuffixOf` name) ["~", ".cabal"]  showLicense :: Distro -> License -> String showLicense SUSE (GPL Nothing) = "GPL-1.0+"
src/Dependencies.hs view
@@ -20,22 +20,23 @@   missingPackages,   notInstalled,   packageDependencies,+  pkgInstallMissing,   showDep,   subPackages,   testsuiteDependencies   ) where -import PackageUtils (packageName, repoquery)-import SysCmd (cmd, cmdBool, (+-+))+import PackageUtils (PackageData(..), packageName, packageManager, repoquery)+import SysCmd (cmd, cmd_, cmdBool, notNull, optionalProgram, trySystem, (+-+))  #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2)) #else import Control.Applicative ((<$>)) #endif-import Control.Monad (filterM, when)+import Control.Monad (filterM, when, unless) -import Data.List (delete, isSuffixOf, nub)-import Data.Maybe (catMaybes, isNothing)+import Data.List (delete, isSuffixOf, nub, (\\))+import Data.Maybe (catMaybes, fromMaybe, isNothing)  import Distribution.Package  (Dependency (..), #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,22,0)@@ -65,6 +66,7 @@                                         ) import System.Directory (doesDirectoryExist, doesFileExist) import System.IO (hPutStrLn, stderr)+import System.Posix.User (getEffectiveUserID)  excludedPkgs :: String -> Bool excludedPkgs = flip notElem ["Cabal", "base", "ghc-prim", "integer-gmp"]@@ -134,7 +136,6 @@ -- use repoquery or rpm -q to query which package provides file rpmqueryFile :: QueryBackend -> FilePath -> IO (Maybe String) rpmqueryFile backend file = do-  -- FIXME dnf repoquery does not support -f !   let args =  ["-q", "--qf=%{name}", "-f"]   out <- if backend == Rpm          then cmd "rpm" (args ++ [file])@@ -210,6 +211,43 @@ subPackages mspec pkgDesc = do   develSubpkgs <- filter ("-devel" `isSuffixOf`) . lines <$> maybe (return "") (\ f -> cmd "rpmspec" ["-q", "--qf", "%{name}\n", f]) mspec   let self = packageName $ package pkgDesc-      subpkgs = delete (showDep self) develSubpkgs+  return $ delete (showDep self) develSubpkgs++pkgInstallMissing :: PackageData -> Bool -> IO ()+pkgInstallMissing pkgdata hard = do+  let pkgDesc = packageDesc pkgdata+      mspec = specFilename pkgdata   missing <- missingPackages pkgDesc-  return $ nub (subpkgs ++ missing)+  unless (null missing) $ do+    subpkgs <- subPackages mspec pkgDesc+    let pkgs = missing \\ subpkgs+    pkginstaller <- packageManager+    putStrLn $ "Running repoquery" +-+ unwords pkgs+    repopkgs <- filter (/= "") <$> mapM (repoquery ["--qf", "%{name}"]) pkgs+    let missing' = pkgs \\ repopkgs+    if notNull missing' && hard+      then error $ unwords missing' +-+ "not available."+      else do+      unless (null missing') $ do+        putStrLn "Unavailable dependencies:"+        mapM_ putStrLn missing'+      unless (null repopkgs) $ do+        putStrLn "Uninstalled dependencies:"+        mapM_ putStrLn repopkgs+        uid <- getEffectiveUserID+        maybeSudo <-+          if uid == 0+          then return Nothing+          else do+            havesudo <- optionalProgram "sudo"+            return $ if havesudo then Just "sudo" else Nothing+        let args = map showPkg repopkgs+        putStrLn $ "Running:" +-+ fromMaybe "" maybeSudo +-+ pkginstaller +-+ "install" +-+ unwords args+        let exec = if hard then cmd_ else trySystem+        fedora <- cmd "rpm" ["--eval", "%fedora"]+        let nogpgcheck = ["--nogpgcheck" | fedora `elem` ["22", "23"]]+        exec (fromMaybe pkginstaller maybeSudo) $ maybe [] (const [pkginstaller]) maybeSudo ++ ("install" : args ++ nogpgcheck)+          where+            showPkg :: String -> String+            showPkg p = if '(' `elem` p then show p else p+
src/Main.hs view
@@ -25,34 +25,30 @@ import Commands.Update (update)  import Options (parseArgs)-import PackageUtils (prepare, PackageData (..), RpmStage (..))+import PackageUtils (prepare, RpmStage (..)) -import Control.Exception (bracket)-import System.Directory (removeDirectoryRecursive) import System.Environment (getArgs)  main :: IO () main = do   (opts, cmd, mpkg) <- getArgs >>= parseArgs-  bracket (prepare opts mpkg)-    (maybe (return ()) removeDirectoryRecursive . workingDir)-    (\pkgdata ->-      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 'local':"-          putStrLn "* this alias may be removed in a future release."-          rpmBuild_ pkgdata opts Binary-        c -> error $ "Unknown cmd: " ++ c)+  pkgdata <- prepare opts mpkg+  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 'local':"+      putStrLn "* this alias may be removed in a future release."+      rpmBuild_ pkgdata opts Binary+    c -> error $ "Unknown cmd: " ++ c
src/Options.hs view
@@ -57,6 +57,7 @@     , rpmStrict              :: Bool     , rpmSubpackage          :: Bool     , rpmHackage             :: Bool+    , rpmMissing             :: Bool     , rpmRelease             :: Maybe String     , rpmCompilerId          :: Maybe CompilerId     , rpmDistribution        :: Maybe Distro@@ -74,6 +75,7 @@     , rpmStrict = False     , rpmSubpackage = False     , rpmHackage = False+    , rpmMissing = False     , rpmRelease = Nothing     , rpmCompilerId = Nothing     , rpmDistribution = Nothing@@ -94,6 +96,8 @@     "Overwrite existing spec file."   , Option "" ["hackage"] (NoArg (\x -> x { rpmHackage = True }))     "Use Hackage to get package version instead of Stackage."+  , Option "" ["missing"] (NoArg (\x -> x { rpmMissing = True }))+    "Comment out missing BuildRequires packages."   , Option "" ["strict"] (NoArg (\x -> x { rpmStrict = True }))     "Fail rather than produce an incomplete spec file."   , Option "" ["subpackage"] (NoArg (\x -> x { rpmSubpackage = True }))@@ -143,7 +147,7 @@              ++ "  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 cblrpm\n"+             ++ "  refresh\t- refresh spec file to current cabal-rpm\n"              ++ "\n"              ++ "Options:"   hPutStrLn h (usageInfo info options)
src/PackageUtils.hs view
@@ -19,14 +19,13 @@   copyTarball,   getPkgName,   isGitDir,-  isScmDir,   latestPackage,   nameVersion,   PackageData (..),+  packageManager,   packageName,   packageVersion,   patchSpec,-  pkgInstall,   prepare,   removePrefix,   removeSuffix,@@ -34,7 +33,6 @@   rpmbuild,   rpmInstall,   RpmStage (..),-  simplePackageDescription,   stripPkgDevel   ) where @@ -42,7 +40,7 @@                   getDirectoryContents_, mktempdir) import Options (RpmFlags (..)) import SysCmd (cmd, cmd_, cmdIgnoreErr, cmdSilent, (+-+),-               notNull, optionalProgram, requireProgram, sudo, trySystem)+               optionalProgram, requireProgram, sudo)  import Stackage (latestStackage) @@ -52,8 +50,8 @@ #endif import Control.Monad    (filterM, unless, when) -import Data.Char (isDigit)-import Data.List (isPrefixOf, stripPrefix, (\\))+import Data.Char (isDigit, toLower)+import Data.List (isPrefixOf, isSuffixOf, sort, stripPrefix) import Data.Maybe (fromMaybe, isJust)  import Distribution.Compiler@@ -101,12 +99,12 @@  import System.Directory (copyFile, createDirectoryIfMissing,doesDirectoryExist,                          doesFileExist, getCurrentDirectory,+                         getDirectoryContents, removeDirectoryRecursive,                          setCurrentDirectory) import System.Environment (getEnv)-import System.FilePath ((</>), (<.>), takeBaseName, takeFileName)+import System.FilePath ((</>), (<.>), dropFileName, takeBaseName, takeFileName) import System.Posix.Files (accessTime, fileMode, getFileStatus,                            modificationTime, setFileMode)-import System.Posix.User (getEffectiveUserID)  -- returns path to .cabal file and possibly tmpdir to be removed --findCabalFile :: Verbosity -> FilePath -> IO (FilePath, Maybe FilePath)@@ -120,10 +118,10 @@     hasVer = all (\c -> isDigit c || c == '.') mRev  simplePackageDescription :: FilePath -> RpmFlags-                         -> IO PackageDescription-simplePackageDescription path opts = do+                         -> IO (PackageDescription, [FilePath], [FilePath])+simplePackageDescription cabalfile opts = do   let verbose = rpmVerbosity opts-  genPkgDesc <- readPackageDescription verbose path+  genPkgDesc <- readPackageDescription verbose cabalfile   compiler <- case rpmCompilerId opts of                 Just cid -> return #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,22,0)@@ -148,10 +146,31 @@        compiler        [] genPkgDesc of     Left e -> die $ "finalize failed: " ++ show e-    Right (pd, _) -> return pd+    Right (pd, _) -> do+      (docs, licensefiles) <- findDocsLicenses (dropFileName cabalfile) pd+      return (pd, docs, licensefiles) +findDocsLicenses :: FilePath -> PackageDescription -> IO ([FilePath], [FilePath])+findDocsLicenses dir pkgDesc = do+  contents <- getDirectoryContents dir+  let docs = sort $ filter unlikely $ filter likely contents+  let licenses = #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,20,0)+        licenseFiles pkgDesc #else+        if null (licenseFile pkgDesc) then [] else [licenseFile pkgDesc]+#endif+      docfiles = if null licenses then docs else filter (`notElem` licenses) docs+  return (docfiles, licenses)+  where names = ["author", "changelog", "changes", "contributors", "copying", "doc",+                 "example", "licence", "license", "news", "readme", "todo"]+        likely name = let lowerName = map toLower name+                      in any (`isPrefixOf` lowerName) names+        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@@ -304,15 +323,6 @@ packageVersion :: PackageIdentifier -> String packageVersion = showVersion . pkgVersion -(<||>) :: IO Bool -> IO Bool -> IO Bool-(<||>) f s = do-  one <- f-  if one then return True else s--isScmDir :: FilePath -> IO Bool-isScmDir dir =-  isGitDir dir <||> doesDirectoryExist (dir </> "_darcs")- isGitDir :: FilePath -> IO Bool isGitDir dir = doesDirectoryExist (dir </> ".git") @@ -398,9 +408,9 @@  data PackageData =   PackageData { specFilename :: Maybe FilePath-              , cabalFilename :: FilePath+              , docFilenames :: [FilePath]+              , licenseFilenames :: [FilePath]               , packageDesc :: PackageDescription-              , workingDir :: Maybe FilePath               }  -- Nothing implies existing packaging in cwd@@ -412,8 +422,9 @@   case mspec of     Just spec -> do       (cabalfile, mtmp) <- cabalFromSpec spec-      pkgDesc <- simplePackageDescription cabalfile flags-      return $ PackageData mspec cabalfile pkgDesc mtmp+      (pkgDesc, docs, licenses) <- simplePackageDescription cabalfile flags+      maybe (return ()) removeDirectoryRecursive mtmp+      return $ PackageData mspec docs licenses pkgDesc     Nothing ->       case mpkgver of         Nothing -> do@@ -423,15 +434,16 @@           mcabal <- checkForCabalFile pkgmver           case mcabal of             Just cabalfile -> do-              pkgDesc <- simplePackageDescription cabalfile flags-              return $ PackageData Nothing cabalfile pkgDesc Nothing+              (pkgDesc, docs, licenses) <- simplePackageDescription cabalfile flags+              return $ PackageData Nothing docs licenses pkgDesc             Nothing -> do               pkgver <- if stripVersion pkgmver == pkgmver                         then latestPackage (rpmHackage flags) pkgmver                         else return pkgmver               (cabalfile, mtmp) <- tryUnpack pkgver-              pkgDesc <- simplePackageDescription cabalfile flags-              return $ PackageData Nothing cabalfile pkgDesc mtmp+              (pkgDesc, docs, licenses) <- simplePackageDescription cabalfile flags+              maybe (return ()) removeDirectoryRecursive mtmp+              return $ PackageData Nothing docs licenses pkgDesc  patchSpec :: Maybe FilePath -> FilePath -> FilePath -> IO () patchSpec mdir oldspec newspec = do@@ -454,39 +466,6 @@   havednf <- optionalProgram "dnf"   let (prog, subcmd) = if havednf then ("dnf", ["repoquery", "-q"]) else ("repoquery", [])   cmd prog (subcmd ++ args ++ [key])--pkgInstall :: [String] -> Bool -> IO ()-pkgInstall [] _ = return ()-pkgInstall pkgs hard = do-  pkginstaller <- packageManager-  putStrLn $ "Running repoquery" +-+ unwords pkgs-  repopkgs <- filter (/= "") <$> mapM (repoquery ["--qf", "%{name}"]) pkgs-  let missing = pkgs \\ repopkgs-  if notNull missing && hard-    then error $ unwords missing +-+ "not available."-    else do-    unless (null missing) $ do-      putStrLn "Unavailable dependencies:"-      mapM_ putStrLn missing-    unless (null repopkgs) $ do-      putStrLn "Uninstalled dependencies:"-      mapM_ putStrLn repopkgs-      uid <- getEffectiveUserID-      maybeSudo <--        if uid == 0-        then return Nothing-        else do-          havesudo <- optionalProgram "sudo"-          return $ if havesudo then Just "sudo" else Nothing-      let args = map showPkg repopkgs-      putStrLn $ "Running:" +-+ fromMaybe "" maybeSudo +-+ pkginstaller +-+ "install" +-+ unwords args-      let exec = if hard then cmd_ else trySystem-      fedora <- cmd "rpm" ["--eval", "%fedora"]-      let nogpgcheck = ["--nogpgcheck" | fedora `elem` ["22", "23"]]-      exec (fromMaybe pkginstaller maybeSudo) $ maybe [] (const [pkginstaller]) maybeSudo ++ ("install" : args ++ nogpgcheck)-        where-          showPkg :: String -> String-          showPkg p = if '(' `elem` p then show p else p  rpmInstall :: [String] -> IO () rpmInstall rpms = do