packages feed

cabal-rpm 0.8.10 → 0.8.11

raw patch · 11 files changed

+260/−176 lines, 11 filesdep −regex-compatdep ~Cabal

Dependencies removed: regex-compat

Dependency ranges changed: Cabal

Files

ChangeLog view
@@ -1,3 +1,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+  when testsuites available+- disable debuginfo explicitly when no c-sources in preparation for+  ghc-rpm-macros no longer disabling debuginfo+- reset filemode of downloaded hackage tarballs to 0644:+  workaround for cabal-install setting 0600+- include release again in initial changelog+- also pull in Cabal and ghc-rpm-macros when yum installing deps+- no longer depends on regex-compat+- some refactorings+ * 0.8.10 (2014-03-03) - diff command replaces cblrpm-diff script - new missingdeps command
README.md view
@@ -1,4 +1,5 @@ [![Build Status](https://travis-ci.org/juhp/cabal-rpm.png)](https://travis-ci.org/juhp/cabal-rpm)+[![Hackage](http://img.shields.io/hackage/v/cabal-rpm.png)](http://hackage.haskell.org/package/cabal-rpm)  # cabal-rpm @@ -49,7 +50,7 @@  or -    $ cblrpm rpm somepkg-0.1+    $ cblrpm local somepkg-0.1  will unpack the (latest) 'somepkg' package from hackage (if the dir does not exist, otherwise it uses the existing dir),
cabal-rpm.cabal view
@@ -1,16 +1,16 @@ Name:                cabal-rpm-Version:             0.8.10+Version:             0.8.11 Synopsis:            RPM packaging tool for Haskell Cabal-based packages Description:     This package generates RPM packages from Haskell Cabal packages.     .-    * cblrpm spec: creates a .spec file from a hackage+    * cblrpm spec: create .spec file from a hackage     .-    * cblrpm srpm: creates an source rpm package+    * cblrpm srpm: create source rpm package     .-    * cblrpm rpm: build a binary rpm package, installing depends with yum+    * cblrpm local: build binary rpm package, installing depends with yum     .-    * cblrpm prep: unpacks package source+    * cblrpm prep: unpack package source     .     * cblrpm builddep: yum install depends     .@@ -22,7 +22,7 @@     .     * cblrpm missingdeps: list uninstalled dependencies     .-    * cblrpm diff: diff of current spec file with newly generated one+    * cblrpm diff: diff current spec file with newly generated one Homepage:            https://github.com/juhp/cabal-rpm Bug-reports:         https://github.com/juhp/cabal-rpm/issues License:             GPL-3@@ -43,12 +43,11 @@ Executable cblrpm     Main-is:            Main.hs     Build-depends: base < 5,-                   Cabal > 1.10,+                   Cabal > 1.10 && < 1.19,                    directory,                    filepath,                    old-locale,                    process,-                   regex-compat,                    time,                    unix     Other-modules:
man/cblrpm.1 view
@@ -5,7 +5,7 @@ .SH SYNOPSIS .PP cblrpm [\f[I]options\f[]] spec [\f[I]path\-or\-pkg\f[]] cblrpm-[\f[I]options\f[]] rpm [\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@@ -60,7 +60,7 @@ file. .SH EXAMPLES .PP-Below CMD can be one of: spec, srpm, rpm, install, and depends.+Below CMD can be one of: spec, srpm, prep, local, install, and depends. .PP Do CMD for the package in current directory: .IP
man/cblrpm.1.md view
@@ -7,7 +7,7 @@  # SYNOPSIS cblrpm [*options*] spec [*path-or-pkg*]-cblrpm [*options*] rpm [*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*]@@ -53,7 +53,7 @@ : Override the version number in the .spec file.  # EXAMPLES-Below CMD can be one of: spec, srpm, rpm, install, and depends.+Below CMD can be one of: spec, srpm, prep, local, install, and depends.  Do CMD for the package in current directory: 
src/Commands/RpmBuild.hs view
@@ -20,7 +20,7 @@     ) where  import Commands.Spec (createSpecFile)-import FileUtils (getDirectoryContents_)+import FileUtils (fileWithExtension, getDirectoryContents_) import PackageUtils (isScmDir, missingPackages, packageName, packageVersion) import Setup (RpmFlags (..)) import SysCmd (runSystem, yumInstall, (+-+))@@ -36,6 +36,7 @@ import System.Directory (copyFile, doesFileExist, getCurrentDirectory) import System.Environment (getEnv) import System.FilePath (takeDirectory, (</>))+import System.Posix.Files (setFileMode, getFileStatus, fileMode)  -- autoreconf :: Verbosity -> PackageDescription -> IO () -- autoreconf verbose pkgDesc = do@@ -53,7 +54,10 @@ --    let verbose = rpmVerbosity flags --    bracket (setFileCreationMask 0o022) setFileCreationMask $ \ _ -> do --      autoreconf verbose pkgDesc-    specFile <- specFileName pkgDesc flags+    mspcfile <- fileWithExtension "." ".spec"+    specFile <- case mspcfile of+      Just s -> return s+      Nothing -> specFileName pkgDesc flags     specFileExists <- doesFileExist specFile     if specFileExists       then putStrLn $ "Using existing" +-+ specFile@@ -80,7 +84,7 @@           error "No tarball for source repo"        cwd <- getCurrentDirectory-      copyTarball name version False cwd+      copyTarball name version False       runSystem ("rpmbuild -b" ++ rpmCmd +-+                  (if stage == Prep then "--nodeps" else "") +-+                  "--define \"_rpmdir" +-+ cwd ++ "\"" +-+@@ -88,8 +92,8 @@                  "--define \"_sourcedir" +-+ cwd ++ "\"" +-+                  specFile)   where-    copyTarball :: String -> String -> Bool -> FilePath -> IO ()-    copyTarball n v ranFetch dest = do+    copyTarball :: String -> String -> Bool -> IO ()+    copyTarball n v ranFetch = do       let tarfile = n ++ "-" ++ v ++ ".tar.gz"       already <- doesFileExist tarfile       unless already $ do@@ -105,8 +109,13 @@                then error $ "No" +-+ tarfile +-+ "found"                else do                  runSystem ("cabal fetch -v0 --no-dependencies" +-+ n ++ "-" ++ v)-                 copyTarball n v True dest-          else copyFile (head tarballs) (dest </> tarfile)+                 copyTarball n v True+          else do+            copyFile (head tarballs) tarfile+            -- cabal fetch creates tarballs with mode 0600+            stat <- getFileStatus tarfile+            when (fileMode stat /= 0o100644) $+              setFileMode tarfile 0o0644  specFileName :: PackageDescription    -- ^pkg description                -> RpmFlags            -- ^rpm flags
src/Commands/Spec.hs view
@@ -20,16 +20,17 @@   createSpecFile   ) where -import Dependencies (packageDependencies, showDep)-import PackageUtils (isScmDir, packageName, packageVersion)+import Dependencies (packageDependencies, showDep, testsuiteDependencies)+import FileUtils (fileWithExtension)+import PackageUtils (isScmDir, notInstalled, packageName, packageVersion) import Setup (RpmFlags (..)) import SysCmd ((+-+))  --import Control.Exception (bracket)-import Control.Monad    (unless, when)+import Control.Monad    (filterM, when, unless) import Data.Char        (toLower, toUpper)-import Data.List        (groupBy, isPrefixOf, isSuffixOf, sort)-import Data.Maybe       (fromMaybe)+import Data.List        (groupBy, isPrefixOf, isSuffixOf, sort, (\\))+import Data.Maybe       (fromMaybe, maybeToList) import Data.Time.Clock  (UTCTime, getCurrentTime) import Data.Time.Format (formatTime) import Data.Version     (showVersion)@@ -38,15 +39,16 @@  import Distribution.Simple.Utils (notice, warn) -import Distribution.PackageDescription (PackageDescription (..), exeName,-                                        hasExes, hasLibs, withExe)+import Distribution.PackageDescription (PackageDescription (..), BuildInfo (..),+                                        Executable (..), Library (..),+                                        exeName, hasExes, hasLibs, withExe)  --import Distribution.Version (VersionRange, foldVersionRange')  import System.Directory (doesFileExist, getDirectoryContents) import System.IO     (IOMode (..), hClose, hPutStrLn, openFile) import System.Locale (defaultTimeLocale)-import System.FilePath (dropFileName, takeDirectory, (</>))+import System.FilePath (dropFileName, takeBaseName, takeDirectory, (</>))  import qualified Paths_cabal_rpm (version) @@ -78,16 +80,23 @@     let verbose = rpmVerbosity flags     now <- getCurrentTime     defRelease <- defaultRelease cabalPath now-    let pkg = package pkgDesc+    mspcfile <- if rpmForce flags then return Nothing+                else fileWithExtension "." ".spec"+    let mpkgname = fmap takeBaseName mspcfile+        pkg = package pkgDesc         name = packageName pkg-        pkgname = if isExec then name else "ghc-" ++ name-        pkg_name = if isExec then "%{name}" else "%{pkg_name}"+        pkgname = fromMaybe (if hasExec then name else "ghc-" ++ name) mpkgname+        pkg_name = if pkgname == name then "%{name}" else "%{pkg_name}"+        basename | isBinLib = "%{pkg_name}"+                 | hasExecPkg = name+                 | otherwise = "ghc-%{pkg_name}"         version = packageVersion pkg         release = fromMaybe defRelease (rpmRelease flags)-        specFile = (fromMaybe "" mdest) </> pkgname ++ ".spec"-        isExec = not (rpmLibrary flags) && hasExes pkgDesc-        isLib = hasLibs pkgDesc-        isBinLib = isExec && isLib+        specFile = fromMaybe "" mdest </> pkgname ++ ".spec"+        hasExec = hasExes pkgDesc+        hasLib = hasLibs pkgDesc+        isBinLib = hasLib && not (rpmLibrary flags) && pkgname == name+        hasExecPkg = not (rpmLibrary flags) && (isBinLib || hasExes pkgDesc && not hasLib)     specAlreadyExists <- doesFileExist specFile     let specFilename = specFile ++ if not (rpmForce flags) && specAlreadyExists then ".cblrpm" else ""     when specAlreadyExists $@@ -130,11 +139,24 @@             '\\' -> head cs: filterSymbols (tail cs)             _ -> c: filterSymbols cs         filterSymbols [] = []-    when isLib $ do+    when hasLib $ do       putDef "pkg_name" name       putNewline -    putHdr "Name" (if isExec then (if isLib then "%{pkg_name}" else pkgname) else "ghc-%{pkg_name}")+    let testsuiteDeps = testsuiteDependencies pkgDesc name+    missTestDeps <- filterM notInstalled testsuiteDeps+    unless (null testsuiteDeps) $ do+      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"+      putDef "debug_package" "%{nil}"+      putNewline++    putHdr "Name" (if isBinLib then "%{pkg_name}" else basename)     putHdr "Version" version     putHdr "Release" $ release ++ "%{?dist}"     putHdr "Summary" summary@@ -147,12 +169,17 @@     putHdr "BuildRequires" "ghc-rpm-macros"      (deps, tools, clibs, pkgcfgs, selfdep) <- packageDependencies pkgDesc name-    let alldeps = sort $ deps ++ tools ++ clibs ++ pkgcfgs-    unless (null alldeps) $ do+    let alldeps = sort $ deps ++ tools ++ map (++ "%{?_isa}") clibs ++ pkgcfgs+    let extraTestDeps = sort $ testsuiteDeps \\ deps+    unless (null $ alldeps ++ extraTestDeps) $ do       put "# Begin cabal-rpm deps:"       mapM_ (putHdr "BuildRequires") alldeps       when (any (\ d -> d `elem` map showDep ["template-haskell", "hamlet"]) deps) $         putHdr "ExclusiveArch" "%{ghc_arches_with_ghci}"+      unless (null extraTestDeps) $ do+        put "%if %{with tests}"+        mapM_ (putHdr "BuildRequires") extraTestDeps+        put "%endif"       put "# End cabal-rpm deps"      putNewline@@ -163,8 +190,8 @@      let wrapGenDesc = wordwrap (79 - max 0 (length pkgname - length pkg_name)) -    when isLib $ do-      when isExec $ do+    when hasLib $ do+      when isBinLib $ do         put $ "%package" +-+ ghcPkg         putHdr "Summary" $ "Haskell" +-+ pkg_name +-+ "library"         putNewline@@ -173,14 +200,14 @@         putNewline       put $ "%package" +-+ ghcPkgDevel       putHdr "Summary" $ "Haskell" +-+ pkg_name +-+ "library development files"-      putHdr "Provides" $ (if isExec then "ghc-%{name}" else "%{name}") ++ "-static = %{version}-%{release}"+      putHdr "Provides" $ (if isBinLib then "ghc-%{name}" else "%{name}") ++ "-static = %{version}-%{release}"       putHdr "Requires" "ghc-compiler = %{ghc_version}"       putHdr "Requires(post)" "ghc-compiler = %{ghc_version}"       putHdr "Requires(postun)" "ghc-compiler = %{ghc_version}"-      putHdr "Requires" $ (if isExec then "ghc-%{name}" else "%{name}") ++ "%{?_isa} = %{version}-%{release}"+      putHdr "Requires" $ (if isBinLib then "ghc-%{name}" else "%{name}") ++ "%{?_isa} = %{version}-%{release}"       unless (null $ clibs ++ pkgcfgs) $ do         put "# Begin cabal-rpm deps:"-        mapM_ (putHdr "Requires") $ sort $ clibs ++ pkgcfgs+        mapM_ (putHdr "Requires") $ sort $ map (++ "%{?_isa}") clibs ++ pkgcfgs         put "# End cabal-rpm deps"       putNewline       put $ "%description" +-+ ghcPkgDevel@@ -193,7 +220,7 @@     putNewline      put "%build"-    let pkgType = if isLib then "lib" else "bin"+    let pkgType = if hasLib then "lib" else "bin"     put $ "%ghc_" ++ pkgType ++ "_build"     putNewline     putNewline@@ -206,7 +233,15 @@     putNewline     putNewline -    when isLib $ do+    unless (null testsuiteDeps) $ do+      put "%check"+      put "%if %{with tests}"+      put "%cabal test"+      put "%endif"+      putNewline+      putNewline++    when hasLib $ do       let putInstallScript = do             put "%ghc_pkg_recache"             putNewline@@ -218,7 +253,7 @@      docs <- findDocs cabalPath pkgDesc -    when isExec $ do+    when hasExecPkg $ do       put "%files"       -- Add the license file to the main package only if it wouldn't       -- otherwise be empty.@@ -230,28 +265,35 @@       withExe pkgDesc $ \exe ->         let program = exeName exe in         put $ "%{_bindir}/" ++ (if program == name then "%{name}" else program)-      unless (null (dataFiles pkgDesc) && isExec) $+      unless (null (dataFiles pkgDesc)) $         put "%{_datadir}/%{name}-%{version}"        putNewline       putNewline -    when isLib $ do+    when hasLib $ do       let baseFiles = if isBinLib then "-f ghc-%{name}.files" else "-f %{name}.files"           develFiles = if isBinLib then "-f ghc-%{name}-devel.files" else "-f %{name}-devel.files"       put $ "%files" +-+ ghcPkg +-+ baseFiles       put $ "%doc" +-+ licenseFile pkgDesc+      -- be strict for now+--      unless (null (dataFiles pkgDesc) || isBinLib) $+--        put "%{_datadir}/%{pkg_name}-%{version}"       putNewline       putNewline       put $ "%files" +-+ ghcPkgDevel +-+  develFiles       unless (null docs) $         put $ "%doc" +-+ unwords docs+      when (not isBinLib && hasExec) $+        withExe pkgDesc $ \exe ->+        let program = exeName exe in+        put $ "%{_bindir}/" ++ (if program == name then "%{name}" else program)       putNewline       putNewline      let date = formatTime defaultTimeLocale "%a %b %e %Y" now     put "%changelog"-    put $ "*" +-+ date +-+ "Fedora Haskell SIG <haskell@lists.fedoraproject.org> - " ++ version+    put $ "*" +-+ date +-+ "Fedora Haskell SIG <haskell@lists.fedoraproject.org> - " ++ version ++ "-" ++ release     put $ "- spec file generated by cabal-rpm-" ++ showVersion Paths_cabal_rpm.version     hClose h 
src/Dependencies.hs view
@@ -14,24 +14,27 @@ -- (at your option) any later version.  module Dependencies (-  dependencies, packageDependencies, showDep+  dependencies, packageDependencies, showDep, testsuiteDependencies   ) where  import SysCmd (tryReadProcess) -import Data.List        (nub)+import Data.List (delete, nub)  import Distribution.Package  (Dependency (..), PackageName (..)) import Distribution.PackageDescription (PackageDescription (..),                                         allBuildInfo,-                                        BuildInfo (..))+                                        BuildInfo (..),+                                        TestSuite (..)) +excludedPkgs :: String -> Bool+excludedPkgs = flip notElem ["Cabal", "base", "ghc-prim", "integer-gmp"]+ -- returns list of deps and whether package is self-dependent buildDependencies :: PackageDescription -> String -> ([String], Bool) buildDependencies pkgDesc self =-  let deps = nub $ map depName (buildDepends pkgDesc)-      excludedPkgs n = notElem n [self, "Cabal", "base", "ghc-prim", "integer-gmp"] in-  (filter excludedPkgs deps, self `elem` deps)+  let deps = nub $ map depName (buildDepends pkgDesc) in+  (filter excludedPkgs (delete self deps), self `elem` deps)  depName :: Dependency -> String depName (Dependency (PackageName n) _) = n@@ -52,6 +55,16 @@     clibs <- mapM repoqueryLib $ concatMap extraLibs buildinfo     return (deps, tools, clibs, pkgcfgs, selfdep) +repoqueryLib :: String -> IO String+repoqueryLib lib = do+  let lib_path = "/usr/lib/lib" ++ lib ++ ".so"+  out <- tryReadProcess "repoquery" ["--qf=%{name}", "-qf", lib_path]+  let pkgs = nub $ words out+  case pkgs of+    [pkg] -> return pkg+    [] -> error $ "Could not resolve package that provides lib" ++ lib_path+    _ -> error $ "More than one package seems to provide lib" ++ lib_path ++ ": " ++ show pkgs+ packageDependencies :: PackageDescription  -- ^pkg description                 -> String           -- ^pkg name                 -> IO ([String], [String], [String], [String], Bool)@@ -67,14 +80,11 @@         tools = filter excludedTools $ nub $ map mapTools tools' ++ chrpath      let showPkgCfg p = "pkgconfig(" ++ p ++ ")"-    return (map showDep deps, tools, map (++ "%{?_isa}") clibs, map showPkgCfg pkgcfgs, selfdep)+    return (map showDep deps, tools, clibs, map showPkgCfg pkgcfgs, selfdep) -repoqueryLib :: String -> IO String-repoqueryLib lib = do-  let lib_path = "/usr/lib/lib" ++ lib ++ ".so"-  out <- tryReadProcess "repoquery" ["--qf=%{name}", "-qf", lib_path]-  let pkgs = nub $ words out-  case pkgs of-    [pkg] -> return pkg-    [] -> error $ "Could not resolve package that provides lib" ++ lib_path-    _ -> error $ "More than one package seems to provide lib" ++ lib_path ++ ": " ++ show pkgs+testsuiteDependencies :: PackageDescription  -- ^pkg description+                -> String           -- ^self+                -> [String]         -- ^depends+testsuiteDependencies pkgDesc self =+  map showDep . delete self . filter excludedPkgs . map depName . nub $ concatMap targetBuildDepends $ map testBuildInfo $ testSuites pkgDesc+
src/Main.hs view
@@ -22,39 +22,27 @@ import Commands.RpmBuild (rpmBuild, RpmStage (..)) import Commands.Spec (createSpecFile) -import FileUtils (fileWithExtension, fileWithExtension_,-                  getDirectoryContents_, mktempdir) import PackageUtils (simplePackageDescription)-import Setup (RpmFlags (..), parseArgs)-import SysCmd (runSystem, tryReadProcess)+import Setup (parseArgs) -import Control.Applicative ((<$>))-import Data.List (isSuffixOf, stripPrefix)-import Data.Maybe (isJust, listToMaybe, fromMaybe)-import Distribution.PackageDescription.Parse (readPackageDescription)-import Distribution.Simple.Utils (die, findPackageDesc)-import Distribution.Verbosity (Verbosity)-import System.Directory (doesDirectoryExist, doesFileExist, getCurrentDirectory,-                         removeDirectoryRecursive,-                         setCurrentDirectory)+import Data.Maybe (listToMaybe, fromMaybe)+import System.Directory (removeDirectoryRecursive) import System.Environment (getArgs)-import System.FilePath (takeExtension) -import Text.Regex (matchRegex, mkRegex)- main :: IO () main = do (opts, args) <- getArgs >>= parseArgs-          let verbose = rpmVerbosity opts-              (cmd:args') = args+          let (cmd:args') = args               path = fromMaybe "." $ listToMaybe args'-          (cabalPath, mtmp) <- findCabalFile verbose path-          genPkgDesc <- readPackageDescription verbose cabalPath-          pkgDesc <- simplePackageDescription genPkgDesc opts+          (cabalPath, pkgDesc, mtmp) <- simplePackageDescription path opts           case cmd of                "spec" ->  createSpecFile cabalPath pkgDesc opts Nothing                "srpm" ->  rpmBuild cabalPath pkgDesc opts Source                "prep" ->  rpmBuild cabalPath pkgDesc opts Prep-               "rpm" ->   rpmBuild cabalPath pkgDesc opts Binary+               "local" -> rpmBuild cabalPath pkgDesc opts Binary+               "rpm" -> do+                 putStrLn "* Warning the 'rpm' command has been renamed to 'local':"+                 putStrLn "* this alias may be removed in a future release."+                 rpmBuild cabalPath pkgDesc opts Binary                "builddep" -> rpmBuild cabalPath pkgDesc opts BuildDep                "install" -> install cabalPath pkgDesc                "depends" -> depends pkgDesc@@ -77,70 +65,3 @@   --             }   --           internalPackageSet = PackageIndex.fromList [internalPackage] --- returns path to .cabal file and possibly tmpdir to be removed-findCabalFile :: Verbosity -> FilePath -> IO (FilePath, Maybe FilePath)-findCabalFile vb path = do-  isdir <- doesDirectoryExist path-  if isdir-    then do-      cblfile <- fileWithExtension_ path ".cabal"-      if cblfile-        then do-          file <- findPackageDesc path-          return (file, Nothing)-        else do-          spcfile <- fileWithExtension path ".spec"-          maybe (die "Cannot determine package in dir.")-            (cabalFromSpec vb) spcfile-    else do-      isfile <- doesFileExist path-      if not isfile-        then if isJust $ matchRegex pkg_re path-             then tryUnpack path-             else error $ path ++ ": No such file or directory"-        else if takeExtension path == ".cabal"-             then return (path, Nothing)-             else if takeExtension path == ".spec"-                  then cabalFromSpec vb path-                  else if ".tar.gz" `isSuffixOf` path-                       then do-                         tmpdir <- mktempdir-                         runSystem $ "tar zxf " ++ path ++ " -C " ++ tmpdir ++ " *.cabal"-                         subdir <- getDirectoryContents_ tmpdir-                         file <- findPackageDesc $ tmpdir ++ "/" ++ head subdir-                         return (file, Just tmpdir)-                       else error $ path ++ ": file should be a .cabal, .spec or .tar.gz file."-  where pkg_re = mkRegex "^([A-Za-z0-9-]+)(-([0-9.]+))?$"--cabalFromSpec :: Verbosity -> FilePath -> IO (FilePath, Maybe FilePath)-cabalFromSpec vrb spcfile = do-  -- no rpmspec command in RHEL 5 and 6-  namever <- removePrefix "ghc-" <$> tryReadProcess "rpm" ["-q", "--qf", "%{name}-%{version}\n", "--specfile", spcfile]-  findCabalFile vrb (head $ lines namever)--removePrefix :: String -> String-> String-removePrefix pref str =-  fromMaybe str (stripPrefix pref str)--tryUnpack :: String -> IO (FilePath, Maybe FilePath)-tryUnpack pkg = do-  pkgver <- if '.' `elem` pkg then return pkg-            else do-              contains_pkg <- tryReadProcess "cabal" ["list", "--simple-output", pkg]-              let pkgs = filter ((== pkg) . takeWhile (not . (== ' '))) $ lines contains_pkg-              if null pkgs-                then error $ pkg ++ " hackage not found"-                else return $ map (\c -> if c == ' ' then '-' else c) $ last pkgs-  isdir <- doesDirectoryExist pkgver-  if isdir-    then do-    pth <-findPackageDesc pkgver-    return (pth, Nothing)-    else do-    cwd <- getCurrentDirectory-    tmpdir <- mktempdir-    setCurrentDirectory tmpdir-    runSystem $ "cabal unpack -v0 " ++ pkgver-    pth <- findPackageDesc pkgver-    setCurrentDirectory cwd-    return (tmpdir ++ "/" ++ pth, Just tmpdir)
src/PackageUtils.hs view
@@ -16,47 +16,132 @@ module PackageUtils (   isScmDir,   missingPackages,+  notInstalled,   packageName,   packageVersion,   simplePackageDescription     ) where  import Dependencies (packageDependencies)+import FileUtils (fileWithExtension, fileWithExtension_,+                  getDirectoryContents_, mktempdir) import Setup (RpmFlags (..))-import SysCmd (systemBool, (+-+))+import SysCmd (runSystem, tryReadProcess, systemBool, (+-+)) +import Control.Applicative ((<$>)) import Control.Monad    (filterM, liftM)++import Data.Char (isAlphaNum)+import Data.List (isSuffixOf, stripPrefix)+import Data.Maybe (fromMaybe) import Data.Version     (showVersion)  import Distribution.Compiler (CompilerFlavor (..)) import Distribution.Package  (PackageIdentifier (..),                               PackageName (..))-import Distribution.PackageDescription (GenericPackageDescription (..),-                                        PackageDescription (..))+import Distribution.PackageDescription (PackageDescription (..)) import Distribution.PackageDescription.Configuration (finalizePackageDescription)+import Distribution.PackageDescription.Parse (readPackageDescription)  import Distribution.Simple.Compiler (Compiler (..)) import Distribution.Simple.Configure (configCompiler) import Distribution.Simple.Program   (defaultProgramConfiguration)-import Distribution.Simple.Utils (die)+import Distribution.Simple.Utils (die, findPackageDesc)  import Distribution.System (Platform (..), buildArch, buildOS)+import Distribution.Verbosity (Verbosity) -import System.Directory (doesDirectoryExist)-import System.FilePath ((</>))+import System.Directory (doesDirectoryExist, doesFileExist,+                         getCurrentDirectory, setCurrentDirectory)+import System.FilePath ((</>), takeExtension) -simplePackageDescription :: GenericPackageDescription -> RpmFlags-                         -> IO PackageDescription-simplePackageDescription genPkgDesc flags = do-    (compiler, _) <- configCompiler (Just GHC) Nothing Nothing-                     defaultProgramConfiguration-                     (rpmVerbosity flags)-    case finalizePackageDescription (rpmConfigurationsFlags flags)-          (const True) (Platform buildArch buildOS) (compilerId compiler)-          [] genPkgDesc of-      Left e -> die $ "finalize failed: " ++ show e-      Right (pd, _) -> return pd +-- returns path to .cabal file and possibly tmpdir to be removed+findCabalFile :: Verbosity -> FilePath -> IO (FilePath, Maybe FilePath)+findCabalFile vb path = do+  isdir <- doesDirectoryExist path+  if isdir+    then do+      cblfile <- fileWithExtension_ path ".cabal"+      if cblfile+        then do+          file <- findPackageDesc path+          return (file, Nothing)+        else do+          spcfile <- fileWithExtension path ".spec"+          maybe (die "Cannot determine package in dir.")+            (cabalFromSpec vb) spcfile+    else do+      isfile <- doesFileExist path+      if not isfile+        then if isPackageId path+             then tryUnpack path+             else error $ path ++ ": No such file or directory"+        else if takeExtension path == ".cabal"+             then return (path, Nothing)+             else if takeExtension path == ".spec"+                  then cabalFromSpec vb path+                  else if ".tar.gz" `isSuffixOf` path+                       then do+                         tmpdir <- mktempdir+                         runSystem $ "tar zxf " ++ path ++ " -C " ++ tmpdir ++ " *.cabal"+                         subdir <- getDirectoryContents_ tmpdir+                         file <- findPackageDesc $ tmpdir ++ "/" ++ head subdir+                         return (file, Just tmpdir)+                       else error $ path ++ ": file should be a .cabal, .spec or .tar.gz file."+  where+    isPackageId :: String -> Bool+    isPackageId (c:cs) | isAlphaNum c =+      all (\d -> isAlphaNum  d || d `elem` "-." ) cs+    isPackageId _ = False++simplePackageDescription :: FilePath -> RpmFlags+                         -> IO (FilePath, PackageDescription, Maybe FilePath)+simplePackageDescription path opts = do+  let verbose = rpmVerbosity opts+  (cabalPath, mtmp) <- findCabalFile verbose path+  genPkgDesc <- readPackageDescription verbose cabalPath+  (compiler, _) <- configCompiler (Just GHC) Nothing Nothing+                   defaultProgramConfiguration verbose+  case finalizePackageDescription (rpmConfigurationsFlags opts)+       (const True) (Platform buildArch buildOS) (compilerId compiler)+       [] genPkgDesc of+    Left e -> die $ "finalize failed: " ++ show e+    Right (pd, _) -> return (cabalPath, pd, mtmp)++cabalFromSpec :: Verbosity -> FilePath -> IO (FilePath, Maybe FilePath)+cabalFromSpec vrb spcfile = do+  -- no rpmspec command in RHEL 5 and 6+  namever <- removePrefix "ghc-" <$> tryReadProcess "rpm" ["-q", "--qf", "%{name}-%{version}\n", "--specfile", spcfile]+  findCabalFile vrb (head $ lines namever)+  where+    removePrefix :: String -> String-> String+    removePrefix pref str =+      fromMaybe str (stripPrefix pref str)++tryUnpack :: String -> IO (FilePath, Maybe FilePath)+tryUnpack pkg = do+  pkgver <- if '.' `elem` pkg then return pkg+            else do+              contains_pkg <- tryReadProcess "cabal" ["list", "--simple-output", pkg]+              let pkgs = filter ((== pkg) . takeWhile (not . (== ' '))) $ lines contains_pkg+              if null pkgs+                then error $ pkg ++ " hackage not found"+                else return $ map (\c -> if c == ' ' then '-' else c) $ last pkgs+  isdir <- doesDirectoryExist pkgver+  if isdir+    then do+    pth <-findPackageDesc pkgver+    return (pth, Nothing)+    else do+    cwd <- getCurrentDirectory+    tmpdir <- mktempdir+    setCurrentDirectory tmpdir+    runSystem $ "cabal unpack -v0 " ++ pkgver+    pth <- findPackageDesc pkgver+    setCurrentDirectory cwd+    return (tmpdir ++ "/" ++ pth, Just tmpdir)+ packageName :: PackageIdentifier -> String packageName pkg = name   where PackageName name = pkgName pkg@@ -84,4 +169,5 @@ missingPackages :: PackageDescription -> String -> IO [String] missingPackages pkgDesc name = do   (deps, tools, clibs, pkgcfgs, _) <- packageDependencies pkgDesc name-  filterM notInstalled $ deps ++ tools ++ clibs ++ pkgcfgs+  filterM notInstalled $ deps ++ ["ghc-Cabal-devel", "ghc-rpm-macros"] ++ tools ++ clibs ++ pkgcfgs+
src/Setup.hs view
@@ -88,13 +88,15 @@  printHelp h = do     progName <- getProgName-    let info = "Usage: " ++ progName ++ " [OPTION]... [COMMAND] [PKGDIR|PKG|PKG-VERSION|CABALFILE|TARBALL]\n"+    let info = "Usage: " ++ progName ++ " [OPTION]... COMMAND [PATH|PKG|PKG-VERSION]\n"             ++ "\n"+            ++ "PATH can be to a .spec or .cabal file, pkg dir, or tarball.\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"-            ++ "  rpm\t\t- build rpm package\n"+            ++ "  local\t\t- build rpm package locally\n"             ++ "  builddep\t- install dependencies\n"             ++ "  install\t- user install package\n"             ++ "  depends\t- list Cabal depends\n"@@ -124,7 +126,7 @@        hPutStr stderr "Unrecognised options: "        hPutStrLn stderr $ unwords unknown        exitWith (ExitFailure 1)-     when (null args' || notElem (head args') ["builddep", "depends", "diff", "install", "missingdeps", "prep", "requires", "spec", "srpm", "rpm"]) $ do+     when (null args' || notElem (head args') ["builddep", "depends", "diff", "install", "missingdeps", "prep", "requires", "spec", "srpm", "local", "rpm"]) $ do        printHelp stderr        exitWith (ExitFailure 1)      when (length args' > 2) $ do