packages feed

cabal-rpm 0.8.7 → 0.8.8

raw patch · 15 files changed

+381/−221 lines, 15 files

Files

ChangeLog view
@@ -1,9 +1,22 @@+* 0.8.8 (2014-02-07)+- updated GPLv3 license headers+- use .spec file to determine package if no .cabal file (works with+  or without arg)+- bugfix: install command now works even if some dependencies not packaged+- bugfix: do not re-copy cached tarball each time+- use new shorter hackage2 URL for packages+- filter @ and \ quotes in descriptions+- new prep command (like "rpmbuild -bp" or "fedpkg prep")+- new depends and requires commands list package depends or buildrequires+- 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) - new "install" command wrapping "cabal install" - "build" command renamed to "rpm" - sort devel Requires - cblrpm-diff: allow package arg-- support copying tarball fetched from another remote-repo (CodeBlock)+- support copying tarball fetched from another remote-repo (Ricky Elrod) - hlint cleanup - support AGPL license in Cabal-1.18 
cabal-rpm.cabal view
@@ -1,10 +1,17 @@ Name:                cabal-rpm-Version:             0.8.7+Version:             0.8.8 Synopsis:            RPM package creator for Haskell Cabal-based packages Description:     This package generates RPM packages from Haskell Cabal packages.     .-    See <https://github.com/juhp/cabal-rpm/blob/master/ChangeLog> for history details.+    * cblrpm spec: creates a .spec file from a hackage+    * cblrpm srpm: creates an source rpm package+    * cblrpm rpm: build a binary rpm package, installing depends with yum+    * cblrpm prep: unpacks package source+    * cblrpm builddep: yum install depends+    * cblrpm install: yum install depends and then cabal install+    * cblrpm depends: list hackage dependencies+    * cblrpm requires: list package dependencies Homepage:            https://github.com/juhp/cabal-rpm Bug-reports:         https://github.com/juhp/cabal-rpm/issues License:             GPL-3@@ -12,7 +19,7 @@ Author:              Bryan O'Sullivan <bos@serpentine.com>, Jens Petersen <juhp@community.haskell.org> Maintainer:          Jens Petersen <petersen@fedoraproject.org> Copyright:           2007-2008 Bryan O'Sullivan <bos@serpentine.com>,-                     2012-2013 Jens Petersen <petersen@fedoraproject.org>+                     2012-2014 Jens Petersen <petersen@fedoraproject.org> Category:            Distribution Build-type:          Simple Extra-source-files:  README.md ChangeLog man/cblrpm.1.md man/cblrpm.1 cblrpm-diff@@ -34,10 +41,11 @@                    time,                    unix     Other-modules:+        Commands.Depends,         Commands.Install,         Commands.RpmBuild,         Commands.Spec,-        Depends,+        Dependencies,         PackageUtils,         Setup,         SysCmd
cblrpm-diff view
@@ -1,6 +1,6 @@ #!/bin/sh -# Copyright (C) 2008-2012 Red Hat, Inc+# Copyright (C) 2008-2013 Red Hat, Inc # Author: Jens Petersen <petersen@redhat.com> # # This program is free software: you can redistribute it and/or modify
man/cblrpm.1 view
@@ -1,24 +1,29 @@-.TH CBLRPM 1 "2013\-01\-21" +.TH "CBLRPM" "1" "2013\-01\-21" "" "" .SH NAME .PP-cblrpm \- generates RPM .spec files from Cabal packages+cblrpm \- 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[]] rpm [\f[I]path\-or\-pkg\f[]] cblrpm-[\f[I]options\f[]] srpm [\f[I]path\-or\-pkg\f[]]-[\f[I]options\f[]] install [\f[I]path\-or\-pkg\f[]]+[\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[]] .SH DESCRIPTION .PP-cblrpm generates RPM .spec files from Haskell Cabal package.+cblrpm 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 .cabal-file in the current directory.+If no \f[I]path\-or\-pkg\f[] is specified, cblrpm looks for a .cabal or+.spec 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 .cabal-file.-If the argument is a path to a .cabal or .tar.gz file then it will use-it.+If the argument is a directory then it will look there for a .cabal or+.spec file.+If the argument is a path to a .cabal, .spec, or .tar.gz 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 file.@@ -56,43 +61,45 @@ file. .SH EXAMPLES .PP-Create a .spec file for the Cabal src package in current directory:+Below CMD can be one of: spec, srpm, rpm, install, and depends.+.PP+Do CMD for the package in current directory: .IP .nf \f[C]-cblrpm\ spec+cblrpm\ CMD \f[] .fi .PP-Create a .spec file for package (directory or package name):+Do CMD for package (directory or package name): .IP .nf \f[C]-cblrpm\ spec\ [package]+cblrpm\ CMD\ [package] \f[] .fi .PP-Create a .spec file for package\-version (directory or package name):+Do CMD for package\-version (directory or package name): .IP .nf \f[C]-cblrpm\ spec\ [package\-version]+cblrpm\ CMD\ [package\-version] \f[] .fi .PP-Create a .spec file for a .cabal file:+Do CMD on a .cabal file: .IP .nf \f[C]-cblrpm\ spec\ path/to/some.cabal+cblrpm\ CMD\ path/to/some.cabal \f[] .fi .PP-Create a .spec file from a tarball:+Do CMD for a tarball: .IP .nf \f[C]-cblrpm\ spec\ path/to/pkg\-ver.tar.gz+cblrpm\ CMD\ path/to/pkg\-ver.tar.gz \f[] .fi .SH HISTORY
man/cblrpm.1.md view
@@ -3,22 +3,26 @@ % 2013-01-21  # NAME-cblrpm - generates RPM .spec files from Cabal packages+cblrpm - a RPM packaging tool for Haskell Cabal packages  # SYNOPSIS cblrpm [*options*] spec [*path-or-pkg*] cblrpm [*options*] rpm [*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*]  # DESCRIPTION-cblrpm generates RPM .spec files from Haskell Cabal package.+cblrpm generates RPM packages and .spec files from Haskell Cabal package. -If no *path-or-pkg* is specified, cblrpm looks for a .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 .cabal file.-If the argument is a path to a .cabal or .tar.gz file then it will use it.-Otherwise if there is no '/' in the argument and it does not exist+If no *path-or-pkg* is specified, cblrpm looks for a .cabal or .spec 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 .cabal or .spec file.+If the argument is a path to a .cabal, .spec, or .tar.gz 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. @@ -50,9 +54,9 @@ : Override the version number in the .spec file.  # EXAMPLES-Below CMD can be one of: spec, srpm, rpm, and install.+Below CMD can be one of: spec, srpm, rpm, install, and depends. -Do CMD for the Cabal src package in current directory:+Do CMD for the package in current directory:      cblrpm CMD 
+ src/Commands/Depends.hs view
@@ -0,0 +1,42 @@+-- |+-- Module      :  Commands.Depends+-- Copyright   :  (C) 2014 Jens Petersen+--+-- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>+-- Stability   :  alpha+--+-- Explanation: cabal wrapper which yum installs dependencies++-- 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 Commands.Depends (+    depends,+    requires+    ) where++import Dependencies (dependencies, packageDependencies )+import PackageUtils (packageName, simplePackageDescription)+import Setup (RpmFlags (..))++import Data.List (sort)+import Distribution.PackageDescription (GenericPackageDescription (..),+                                        PackageDescription (..))++depends :: GenericPackageDescription -> RpmFlags -> IO ()+depends genPkgDesc flags = do+    pkgDesc <- simplePackageDescription genPkgDesc flags+    let pkg = package pkgDesc+        name = packageName pkg+    (deps, tools, clibs, pkgcfgs, _) <- dependencies pkgDesc name+    mapM_ putStrLn $ deps ++ tools ++ clibs ++ pkgcfgs++requires :: GenericPackageDescription -> RpmFlags -> IO ()+requires genPkgDesc flags = do+    pkgDesc <- simplePackageDescription genPkgDesc flags+    let pkg = package pkgDesc+        name = packageName pkg+    (deps, tools, clibs, pkgcfgs, _) <- packageDependencies pkgDesc name+    mapM_ putStrLn $ sort $ deps ++ tools ++ clibs ++ pkgcfgs
src/Commands/Install.hs view
@@ -1,6 +1,6 @@ -- | -- Module      :  Commands.Install--- Copyright   :  Jens Petersen 2012-2013+-- Copyright   :  (C) 2012-2014 Jens Petersen -- -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org> -- Stability   :  alpha@@ -8,17 +8,19 @@ -- -- Explanation: cabal wrapper which yum installs dependencies --- This software may be used and distributed according to the terms of--- the GNU General Public License, incorporated herein by reference.+-- 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 Commands.Install (     install     ) where -import Depends (dependencies)+import Dependencies (dependencies) import PackageUtils (packageName, simplePackageDescription) import Setup (RpmFlags (..))-import SysCmd (trySystem, systemBool, yumInstall, (+-+))+import SysCmd (runSystem, systemBool, yumInstall, (+-+))  import Control.Monad    (filterM, liftM) @@ -34,10 +36,10 @@         name = packageName pkg     (deps, tools, clibs, pkgcfgs, _) <- dependencies pkgDesc name     missing <- filterM notInstalled $ deps ++ tools ++ clibs ++ pkgcfgs-    yumInstall missing+    yumInstall missing False     let pkgDir = takeDirectory cabalPath     setCurrentDirectory pkgDir-    trySystem "cabal install"+    runSystem "cabal install"   where     notInstalled :: String -> IO Bool     notInstalled br =
src/Commands/RpmBuild.hs view
@@ -1,7 +1,7 @@ -- | -- Module      :  Commands.RpmBuild--- Copyright   :  Bryan O'Sullivan 2007, 2008---                Jens Petersen 2012-2013+-- Copyright   :  (C) 2007-2008  Bryan O'Sullivan+--                (C) 2012-2014  Jens Petersen -- -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org> -- Stability   :  alpha@@ -10,18 +10,20 @@ -- Explanation: Support for building RPM packages.  Can also generate -- an RPM spec file if you need a basic one to hand-customize. --- This software may be used and distributed according to the terms of--- the GNU General Public License, incorporated herein by reference.+-- 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 Commands.RpmBuild (-    rpmBuild+    rpmBuild, RpmStage (..)     ) where  import Commands.Spec (createSpecFile) import PackageUtils (isScmDir, packageName, packageVersion,                                       simplePackageDescription) import Setup (RpmFlags (..))-import SysCmd (tryReadProcess, trySystem, systemBool, yumInstall, (+-+))+import SysCmd (runSystem, systemBool, tryReadProcess, yumInstall, (+-+))  --import Control.Exception (bracket) import Control.Applicative ((<$>))@@ -47,10 +49,12 @@ --         c <- doesFileExist "configure" --         when (not c) $ do --             setupMessage verbose "Running autoreconf" pkgDesc---             trySystem "autoreconf"+--             runSystem "autoreconf" -rpmBuild :: FilePath -> GenericPackageDescription -> RpmFlags -> Bool -> IO ()-rpmBuild cabalPath genPkgDesc flags binary = do+data RpmStage = Binary | Source | Prep | BuildDep deriving Eq++rpmBuild :: FilePath -> GenericPackageDescription -> RpmFlags -> RpmStage -> IO ()+rpmBuild cabalPath genPkgDesc flags stage = do --    let verbose = rpmVerbosity flags     pkgDesc <- simplePackageDescription genPkgDesc flags --    bracket (setFileCreationMask 0o022) setFileCreationMask $ \ _ -> do@@ -62,28 +66,34 @@       else createSpecFile cabalPath genPkgDesc flags     let pkg = package pkgDesc         name = packageName pkg-    when binary $ do+    when (stage `elem` [Binary,BuildDep]) $ do       br_out <- tryReadProcess "rpmspec" ["-q", "--buildrequires", specFile]       missing <- filterM notInstalled $ lines br_out-      yumInstall missing+      yumInstall missing True -    let version = packageVersion pkg-        tarFile = name ++ "-" ++ version ++ ".tar.gz"-        rpmCmd = if binary then "a" else "s"+    unless (stage == BuildDep) $ do+      let version = packageVersion pkg+          tarFile = name ++ "-" ++ version ++ ".tar.gz"+          rpmCmd = case stage of+            Binary -> "a"+            Source -> "s"+            Prep -> "p"+            BuildDep -> "_" -    tarFileExists <- doesFileExist tarFile-    unless tarFileExists $ do-      scmRepo <- isScmDir $ takeDirectory cabalPath-      when scmRepo $-        error "No tarball for source repo"+      tarFileExists <- doesFileExist tarFile+      unless tarFileExists $ do+        scmRepo <- isScmDir $ takeDirectory cabalPath+        when scmRepo $+          error "No tarball for source repo" -    cwd <- getCurrentDirectory-    copyTarball name version False cwd-    trySystem ("rpmbuild -b" ++ rpmCmd +-+-               "--define \"_rpmdir" +-+ cwd ++ "\"" +-+-               "--define \"_srcrpmdir" +-+ cwd ++ "\"" +-+-               "--define \"_sourcedir" +-+ cwd ++ "\"" +-+-               specFile)+      cwd <- getCurrentDirectory+      copyTarball name version False cwd+      runSystem ("rpmbuild -b" ++ rpmCmd +-++                 (if stage == Prep then "--nodeps" else "") +-++                 "--define \"_rpmdir" +-+ cwd ++ "\"" +-++                 "--define \"_srcrpmdir" +-+ cwd ++ "\"" +-++                 "--define \"_sourcedir" +-+ cwd ++ "\"" +-++                 specFile)   where     notInstalled :: String -> IO Bool     notInstalled br =@@ -93,21 +103,23 @@     shellQuote "" = ""     copyTarball :: String -> String -> Bool -> FilePath -> IO ()     copyTarball n v ranFetch dest = do-      home <- getEnv "HOME"-      let cacheparent = home </> ".cabal" </> "packages"-          tarfile = n ++ "-" ++ v ++ ".tar.gz"-          tarpath = n </> v </> tarfile-      remotes <- filter (not . isPrefixOf ".") <$> getDirectoryContents cacheparent-      let paths = map (\ repo -> cacheparent </> repo </> tarpath) remotes-      -- if more than one tarball, should maybe warn if they are different-      tarballs <- filterM doesFileExist paths-      if null tarballs-        then if ranFetch-             then error $ "No" +-+ tarfile +-+ "found"-             else do-               trySystem ("cabal fetch -v0 --no-dependencies" +-+ n ++ "-" ++ v)-               copyTarball n v True dest-        else copyFile (head tarballs) (dest </> tarfile)+      let tarfile = n ++ "-" ++ v ++ ".tar.gz"+      already <- doesFileExist tarfile+      unless already $ do+        home <- getEnv "HOME"+        let cacheparent = home </> ".cabal" </> "packages"+            tarpath = n </> v </> tarfile+        remotes <- filter (not . isPrefixOf ".") <$> getDirectoryContents cacheparent+        let paths = map (\ repo -> cacheparent </> repo </> tarpath) remotes+        -- if more than one tarball, should maybe warn if they are different+        tarballs <- filterM doesFileExist paths+        if null tarballs+          then if ranFetch+               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)  specFileName :: PackageDescription    -- ^pkg description                -> RpmFlags            -- ^rpm flags
src/Commands/Spec.hs view
@@ -2,8 +2,8 @@  -- | -- Module      :  Commands.Spec--- Copyright   :  Bryan O'Sullivan 2007, 2008---                Jens Petersen 2012-2013+-- Copyright   :  (C) 2007-2008  Bryan O'Sullivan+--                (C) 2012-2014  Jens Petersen -- -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org> -- Stability   :  alpha@@ -11,14 +11,16 @@ -- -- Explanation: Generates an RPM spec file from a .cabal file. --- This software may be used and distributed according to the terms of--- the GNU General Public License, incorporated herein by reference.+-- 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 Commands.Spec (   createSpecFile   ) where -import Depends (dependencies, showDep)+import Dependencies (packageDependencies, showDep) import PackageUtils (isScmDir, packageName, packageVersion,                      simplePackageDescription) import Setup (RpmFlags (..))@@ -26,7 +28,7 @@  --import Control.Exception (bracket) import Control.Monad    (unless, when)-import Data.Char        (toLower)+import Data.Char        (toLower, toUpper) import Data.List        (groupBy, isPrefixOf, isSuffixOf, sort) import Data.Maybe       (fromMaybe) import Data.Time.Clock  (UTCTime, getCurrentTime)@@ -35,7 +37,7 @@  import Distribution.License  (License (..)) -import Distribution.Simple.Utils (warn)+import Distribution.Simple.Utils (notice, warn)  import Distribution.PackageDescription (PackageDescription (..), exeName,                                         hasExes, hasLibs, withExe,@@ -91,7 +93,8 @@         isBinLib = isExec && isLib     specAlreadyExists <- doesFileExist specFile     let specFilename = specFile ++ if not (rpmForce flags) && specAlreadyExists then ".cblrpm" else ""-    when specAlreadyExists $ putStrLn $ specFile +-+ "exists:" +-+ "creating" +-+ specFilename+    when specAlreadyExists $+      notice verbose $ specFile +-+ "exists:" +-+ if rpmForce flags then "forcing overwrite" else "creating" +-+ specFilename     h <- openFile specFilename WriteMode     let putHdr hdr val = hPutStrLn h (hdr ++ ":" ++ padding hdr ++ val)         padding hdr = replicate (14 - length hdr) ' ' ++ " "@@ -108,9 +111,11 @@     let syn = synopsis pkgDesc     when (null syn) $       warn verbose "this package has no synopsis."+    let initialCapital (c:cs) = toUpper c:cs+        initialCapital [] = []     let syn' = if null syn               then "Haskell" +-+ name +-+ "package"-              else unwords $ lines syn+              else (unwords . lines . initialCapital) syn     let summary = rstrip (== '.') syn'     when (length ("Summary     : " ++ syn') > 79) $       warn verbose "this package has a long synopsis."@@ -118,10 +123,16 @@     let descr = description pkgDesc     when (null descr) $       warn verbose "this package has no description."-    let descLines = (formatParagraphs . lines . finalPeriod) $+    let descLines = (formatParagraphs . initialCapital . filterSymbols . finalPeriod) $           if null descr then syn' else descr         finalPeriod cs = if last cs == '.' then cs else cs ++ "."-+        filterSymbols (c:cs) =+          if c `notElem` "@\\" then c: filterSymbols cs+          else case c of+            '@' -> '\'': filterSymbols cs+            '\\' -> head cs: filterSymbols (tail cs)+            _ -> c: filterSymbols cs+        filterSymbols [] = []     when isLib $ do       putDef "pkg_name" name       putNewline@@ -133,16 +144,16 @@     putNewline     putHdr "License" $ (showLicense . license) pkgDesc     putHdr "URL" $ "http://hackage.haskell.org/package/" ++ pkg_name-    putHdr "Source0" $ "http://hackage.haskell.org/packages/archive/" ++ pkg_name ++ "/%{version}/" ++ pkg_name ++ "-%{version}.tar.gz"+    putHdr "Source0" $ "http://hackage.haskell.org/package/" ++ pkg_name ++ "-%{version}/" ++ pkg_name ++ "-%{version}.tar.gz"     putNewline     putHdr "BuildRequires" "ghc-Cabal-devel"     putHdr "BuildRequires" "ghc-rpm-macros" -    (deps, tools, clibs, pkgcfgs, selfdep) <- dependencies pkgDesc name-    unless (null $ deps ++ tools ++ clibs ++ pkgcfgs) $ do+    (deps, tools, clibs, pkgcfgs, selfdep) <- packageDependencies pkgDesc name+    let alldeps = sort $ deps ++ tools ++ clibs ++ pkgcfgs+    unless (null alldeps) $ do       put "# Begin cabal-rpm deps:"-      let pkgdeps = sort $ deps ++ tools ++ clibs ++ pkgcfgs-      mapM_ (putHdr "BuildRequires") pkgdeps+      mapM_ (putHdr "BuildRequires") alldeps       when (any (\ d -> d `elem` map showDep ["template-haskell", "hamlet"]) deps) $         putHdr "ExclusiveArch" "%{ghc_arches_with_ghci}"       put "# End cabal-rpm deps"@@ -300,5 +311,5 @@ 		where lw = length w                       endp = last w == '.' -formatParagraphs :: [String] -> [String]-formatParagraphs = map (wordwrap 79) . paragraphs+formatParagraphs :: String -> [String]+formatParagraphs = map (wordwrap 79) . paragraphs . lines
+ src/Dependencies.hs view
@@ -0,0 +1,80 @@+-- |+-- Module      :  Dependencies+-- Copyright   :  (C) 2012-2014  Jens Petersen+--+-- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>+-- Stability   :  alpha+-- Portability :  portable+--+-- Explanation: Dependency info++-- 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 Dependencies (+  dependencies, packageDependencies, showDep+  ) where++import SysCmd (tryReadProcess)++import Data.List        (nub)++import Distribution.Package  (Dependency (..), PackageName (..))+import Distribution.PackageDescription (PackageDescription (..),+                                        allBuildInfo,+                                        BuildInfo (..))++-- 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)++depName :: Dependency -> String+depName (Dependency (PackageName n) _) = n++showDep :: String -> String+showDep p = "ghc-" ++ p ++ "-devel"++dependencies :: PackageDescription  -- ^pkg description+                -> String           -- ^pkg name+                -> IO ([String], [String], [String], [String], Bool)+                -- ^depends, tools, c-libs, pkgcfg, selfdep+dependencies pkgDesc self = do+    let (deps, selfdep) = buildDependencies pkgDesc self+        buildinfo = allBuildInfo pkgDesc+        tools =  nub $ map depName (concatMap buildTools buildinfo)+        pkgcfgs = nub $ map depName $ concatMap pkgconfigDepends buildinfo++    clibs <- mapM repoqueryLib $ concatMap extraLibs buildinfo+    return (deps, tools, clibs, pkgcfgs, selfdep)++packageDependencies :: PackageDescription  -- ^pkg description+                -> String           -- ^pkg name+                -> IO ([String], [String], [String], [String], Bool)+                -- ^depends, tools, c-libs, pkgcfg, selfdep+packageDependencies pkgDesc self = do+    (deps, tools', clibs, pkgcfgs, selfdep) <- dependencies pkgDesc self+    let excludedTools n = n `notElem` ["ghc", "hsc2hs", "perl"]+        mapTools "gtk2hsC2hs" = "gtk2hs-buildtools"+        mapTools "gtk2hsHookGenerator" = "gtk2hs-buildtools"+        mapTools "gtk2hsTypeGen" = "gtk2hs-buildtools"+        mapTools tool = tool+        chrpath = ["chrpath" | selfdep]+        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)++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
− src/Depends.hs
@@ -1,68 +0,0 @@--- |--- Module      :  Depends--- Copyright   :  Jens Petersen 2012-2013------ Maintainer  :  Jens Petersen <petersen@fedoraproject.org>--- Stability   :  alpha--- Portability :  portable------ Explanation: Dependency info---- This software may be used and distributed according to the terms of--- the GNU General Public License, incorporated herein by reference.--module Depends (-  dependencies, showDep-  ) where--import SysCmd (tryReadProcess)--import Data.List        (nub)--import Distribution.Package  (Dependency (..), PackageName (..))-import Distribution.PackageDescription (PackageDescription (..),-                                        allBuildInfo,-                                        BuildInfo (..))---- 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)--depName :: Dependency -> String-depName (Dependency (PackageName n) _) = n--showDep :: String -> String-showDep p = "ghc-" ++ p ++ "-devel"--dependencies :: PackageDescription  -- ^pkg description-                -> String           -- ^pkg name-                -> IO ([String], [String], [String], [String], Bool)-                -- ^depends, tools, c-libs, pkgcfg, selfdep-dependencies pkgDesc self = do-    let (deps, selfdep) = buildDependencies pkgDesc self-        buildinfo = allBuildInfo pkgDesc-        excludedTools n = n `notElem` ["ghc", "hsc2hs", "perl"]-        mapTools "gtk2hsC2hs" = "gtk2hs-buildtools"-        mapTools "gtk2hsHookGenerator" = "gtk2hs-buildtools"-        mapTools "gtk2hsTypeGen" = "gtk2hs-buildtools"-        mapTools tool = tool-        chrpath = ["chrpath" | selfdep]-        tools = filter excludedTools $ nub $ map (mapTools . depName) (concatMap buildTools buildinfo) ++ chrpath-        pkgcfgs = nub $ map depName $ concatMap pkgconfigDepends buildinfo--    clibs <- mapM repoqueryLib $ concatMap extraLibs buildinfo-    let showPkgCfg p = "pkgconfig(" ++ p ++ ")"-    return (map showDep deps, tools, map (++ "%{?_isa}") 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
src/Main.hs view
@@ -1,7 +1,7 @@ -- | -- Module      :  Main--- Copyright   :  Bryan O'Sullivan 2007---                Jens Petersen 2012-2013+-- Copyright   :  (C) 2007  Bryan O'Sullivan+--                (C) 2012-2014  Jens Petersen -- -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org> -- Stability   :  alpha@@ -9,25 +9,30 @@ -- -- Explanation: Main entry point for building RPM packages. --- This software may be used and distributed according to the terms of--- the GNU General Public License, incorporated herein by reference.+-- 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 Main where +import Commands.Depends (depends, requires) import Commands.Install (install)-import Commands.RpmBuild (rpmBuild)+import Commands.RpmBuild (rpmBuild, RpmStage (..)) import Commands.Spec (createSpecFile) import Setup (RpmFlags (..), parseArgs)-import SysCmd (tryReadProcess, trySystem)+import SysCmd (runSystem, tryReadProcess) +import Control.Applicative ((<$>)) import Control.Monad (unless)-import Data.List (isSuffixOf)-import Data.Maybe (isJust)+import Data.List (isSuffixOf, stripPrefix)+import Data.Maybe (isJust, listToMaybe, fromMaybe) import Distribution.PackageDescription.Parse (readPackageDescription)-import Distribution.Simple.Utils (defaultPackageDesc, findPackageDesc)+import Distribution.Simple.Utils (die, findPackageDesc) import Distribution.Verbosity (Verbosity, silent) import System.Directory (doesDirectoryExist, doesFileExist, getCurrentDirectory,-                         removeDirectoryRecursive, setCurrentDirectory)+                         getDirectoryContents, removeDirectoryRecursive,+                         setCurrentDirectory) import System.Environment (getArgs) import System.FilePath.Posix (takeExtension) @@ -37,21 +42,17 @@ main = do (opts, args) <- getArgs >>= parseArgs           let verbose = rpmVerbosity opts               (cmd:args') = args-          (cabalPath, mtmp) <- if null args'-                               then do-                                 pth <- defaultPackageDesc verbose-                                 return (pth, Nothing)-                               else findCabalFile verbose $ head args'+          (cabalPath, mtmp) <- findCabalFile verbose $ fromMaybe "." $ listToMaybe args'           genPkgDesc <- readPackageDescription verbose cabalPath           case cmd of                "spec" ->  createSpecFile cabalPath genPkgDesc opts-               "srpm" ->  rpmBuild cabalPath genPkgDesc opts False-               "rpm" -> rpmBuild cabalPath genPkgDesc opts True+               "srpm" ->  rpmBuild cabalPath genPkgDesc opts Source+               "prep" ->  rpmBuild cabalPath genPkgDesc opts Prep+               "rpm" ->   rpmBuild cabalPath genPkgDesc opts Binary+               "builddep" -> rpmBuild cabalPath genPkgDesc opts BuildDep                "install" -> install cabalPath genPkgDesc opts---               "builddep" -> ---               "depends" -> ---               "install" ->---               "showdeps" ->+               "depends" -> depends genPkgDesc opts+               "requires" -> requires genPkgDesc opts                c -> error $ "Unknown cmd: " ++ c           maybe (return ()) removeDirectoryRecursive mtmp @@ -74,9 +75,16 @@   isdir <- doesDirectoryExist path   if isdir     then do-      unless (vb == silent) $ putStrLn $ "Using " ++ path ++ "/"-      file <- findPackageDesc path-      return (file, Nothing)+      cblfile <- fileWithExtension_ path ".cabal"+      if cblfile+        then do+          unless (vb == silent) $ putStrLn $ "trying " ++ path ++ "/"+          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@@ -85,16 +93,41 @@              else error $ path ++ ": No such file or directory"         else if takeExtension path == ".cabal"              then return (path, Nothing)-             else if ".tar.gz" `isSuffixOf` path-                  then do-                    tmpdir <- mktempdir-                    trySystem $ "tar zxf " ++ path ++ " -C " ++ tmpdir ++ " *.cabal"-                    subdir <- tryReadProcess "ls" [tmpdir]-                    file <- findPackageDesc $ tmpdir ++ "/" ++ init subdir-                    return (file, Just tmpdir)-                  else error $ path ++ ": file should be a .cabal or .tar.gz file."+             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 <- tryReadProcess "ls" [tmpdir]+                         file <- findPackageDesc $ tmpdir ++ "/" ++ init 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.]+))?$" +-- looks in current dir for a unique file with given extension+fileWithExtension :: FilePath -> String -> IO (Maybe FilePath)+fileWithExtension dir ext = do+  files <- filter (\ f -> takeExtension f == ext) <$> getDirectoryContents dir+  case files of+       [file] -> return $ Just file+       [] -> return Nothing+       _ -> putStrLn ("More than one " ++ ext ++ " file found!") >> return Nothing++-- looks in current dir for a unique file with given extension+fileWithExtension_ :: FilePath -> String -> IO Bool+fileWithExtension_ dir ext =+  isJust <$> fileWithExtension dir ext++cabalFromSpec :: Verbosity -> FilePath -> IO (FilePath, Maybe FilePath)+cabalFromSpec vrb spcfile = do+  namever <- removePrefix "ghc-" <$> tryReadProcess "rpmspec" ["-q", "--srpm", "--qf", "%{name}-%{version}", spcfile]+  findCabalFile vrb 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@@ -113,7 +146,7 @@     cwd <- getCurrentDirectory     tmpdir <- mktempdir     setCurrentDirectory tmpdir-    trySystem $ "cabal unpack -v0 " ++ pkgver+    runSystem $ "cabal unpack -v0 " ++ pkgver     pth <- findPackageDesc pkgver     setCurrentDirectory cwd     return (tmpdir ++ "/" ++ pth, Just tmpdir)
src/PackageUtils.hs view
@@ -1,6 +1,6 @@ -- | -- Module      :  PackageUtils--- Copyright   :  Jens Petersen 2013+-- Copyright   :  (C) 2013-2014  Jens Petersen -- -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org> -- Stability   :  alpha@@ -8,8 +8,10 @@ -- -- Explanation: functions related to Cabal dependency generation. --- This software may be used and distributed according to the terms of--- the GNU General Public License, incorporated herein by reference.+-- 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 PackageUtils (   isScmDir,
src/Setup.hs view
@@ -1,7 +1,7 @@ -- | -- Module      :  Setup--- Copyright   :  Bryan O'Sullivan 2007, 2008---                Jens Petersen 2012-2013+-- Copyright   :  (C) 2007-2008  Bryan O'Sullivan+--                (C) 2012-2014  Jens Petersen -- -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org> -- Stability   :  alpha@@ -10,8 +10,10 @@ -- Explanation: Command line option processing for building RPM -- packages. --- This software may be used and distributed according to the terms of--- the GNU General Public License, incorporated herein by reference.+-- 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 Setup (       RpmFlags(..)@@ -91,8 +93,12 @@             ++ "Commands:\n"             ++ "  spec\t generate a spec file\n"             ++ "  srpm\t generate a src rpm file\n"+            ++ "  prep\t unpack source\n"             ++ "  rpm\t build rpm package\n"+            ++ "  builddep install dependencies\n"             ++ "  install user install package\n"+            ++ "  depends list Cabal depends\n"+            ++ "  requires list package buildrequires\n" --             ++ "  mock\t mock build package\n"             ++ "\n"             ++ "Options:"@@ -116,7 +122,7 @@        hPutStr stderr "Unrecognised options: "        hPutStrLn stderr $ unwords unknown        exitWith (ExitFailure 1)-     when (null args' || notElem (head args') ["spec", "srpm", "rpm", "install"]) $ do+     when (null args' || notElem (head args') ["builddep", "depends", "install", "prep", "requires", "spec", "srpm", "rpm"]) $ do        printHelp stderr        exitWith (ExitFailure 1)      when (length args' > 2) $ do
src/SysCmd.hs view
@@ -1,6 +1,6 @@ -- | -- Module      :  SysCmd--- Copyright   :  Jens Petersen 2013+-- Copyright   :  (C) 2013-2014  Jens Petersen -- -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org> -- Stability   :  alpha@@ -9,18 +9,20 @@ -- Explanation: Command line option processing for building RPM -- packages. --- This software may be used and distributed according to the terms of--- the GNU General Public License, incorporated herein by reference.+-- 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 SysCmd (   requireProgram,-  trySystem,+  runSystem,   tryReadProcess,   systemBool,   yumInstall,   (+-+)) where -import Control.Monad    (when, unless)+import Control.Monad    (unless, void, when) import Data.Maybe       (isJust, isNothing)  import Distribution.Simple.Utils (die, warn, findProgramLocation)@@ -41,14 +43,19 @@     when (isNothing mavail) $ warn normal (cmd ++ ": command not found")     return $ isJust mavail -trySystem :: String -> IO ()-trySystem cmd = do+runSystem :: String -> IO ()+runSystem cmd = do     requireProgram $ head $ words cmd     ret <- system cmd     case ret of       ExitSuccess -> return ()       ExitFailure n -> die ("\"" ++ cmd ++ "\"" +-+ "failed with status" +-+ show n) +trySystem :: String -> IO ()+trySystem cmd = do+    requireProgram $ head $ words cmd+    void $ system cmd+ systemBool :: String -> IO Bool systemBool cmd = do     requireProgram $ head $ words cmd@@ -67,8 +74,8 @@ s +-+ "" = s s +-+ t = s ++ " " ++ t -yumInstall :: [String] -> IO ()-yumInstall pkgs =+yumInstall :: [String] -> Bool -> IO ()+yumInstall pkgs hard =   unless (null pkgs) $ do     putStrLn "Uninstalled dependencies:"     mapM_ putStrLn pkgs@@ -82,7 +89,8 @@     requireProgram "yum"     let args = unwords $ map showPkg pkgs     putStrLn $ "Running:" +-+ cmdprefix +-+ "yum install" +-+ args-    trySystem $ cmdprefix +-+ "yum install" +-+ args+    let exec = if hard then runSystem else trySystem+    exec $ cmdprefix +-+ "yum install" +-+ args  showPkg :: String -> String showPkg p = if '(' `elem` p then show p else p