packages feed

cabal-rpm 0.6.6 → 0.7.0

raw patch · 12 files changed

+452/−474 lines, 12 filesnew-component:exe:cblrpm

Files

NEWS view
@@ -1,3 +1,13 @@+* 0.7.0+- cabal-rpm command renamed to cblrpm, and cabal-rpm-diff to cblrpm-diff+- cblrpm now has commands for spec, srpm, and build+- cblrpm will try to install packaged uninstalled depends with sudo yum install+- add %ghc_arches_with_ghci for hamlet dep+- cblrpm-diff supports -l+- cblrpm --version+- sort extralibs depends+- cleanup of unused options and help output+ * 0.6.6 - generate BRs and Req's for C libraries (extra-libraries) - initial map for some C libs: libglut, libiw, libz, libX*
README.md view
@@ -22,33 +22,33 @@ ## Usage To create a `.spec` file for a Haskell src package in the current dir: -    $ cabal-rpm+    $ cblrpm spec  or directly on a `.cabal` file: -    $ cabal-rpm path/to/mypkg.cabal+    $ cblrpm spec path/to/mypkg.cabal  or tarball: -    $ cabal-rpm path/to/mypkg-version.tar.gz+    $ cblrpm spec path/to/mypkg-version.tar.gz  or on a package source dir: -    $ cabal-rpm mypkg-0.1+    $ cblrpm spec mypkg-0.1  You can also package directly from hackage: -    $ cabal-rpm somepkg+    $ cblrpm build somepkg  or -    $ cabal-rpm somepkg-0.1+    $ cblrpm build somepkg-0.1  will unpack the (latest) 'somepkg' package from hackage-(if the dir does not exist, otherwise it uses the existing dir)-and create a spec file for it.+(if the dir does not exist, otherwise it uses the existing dir),+create a spec file for it, and build it. -cabal-rpm always creates `.spec` files in the current dir+cblrpm always creates `.spec` files in the current dir and if a `.spec` file already exists it will append `.cblrpm` to the generated filename to avoid overwriting an existing file. @@ -56,7 +56,5 @@ The latest source code is available from: https://github.com/juhp/cabal-rpm  ## Plans-More features are planned and patches welcome.-Including restoring the rpmbuild feature and recursive-packaging and hopefully yum integration.  See the TODO file-for more details.+More features are planned and patches welcome, including recursive packaging.+See the TODO file for more details.
− cabal-rpm-diff
@@ -1,60 +0,0 @@-#!/bin/sh--# Copyright (C) 2008-2010 Red Hat, Inc-# Written by Jens Petersen <petersen@redhat.com>, 2008.-#-# 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.-#-# This program is distributed in the hope that it will be useful,-# but WITHOUT ANY WARRANTY; without even the implied warranty of-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the-# GNU General Public License for more details.-#-# You should have received a copy of the GNU General Public License-# along with this program.  If not, see <http://www.gnu.org/licenses/>.--set -e--# use -l to force lib package-if getopts l opt; then-  shift-  case $opt in-      l) FORCE_LIB=--name=ghc-PKG-	  ;;-  esac-fi--if [ $# -ne 1 -o ! -r "$1" ]; then-    echo "Usage: $(basename $0) [-l] [hackage|hackage.tar.gz|hackage.cabal]"-    echo "  -l      assume BinLib package is Lib"-    exit 1-fi--FILE=$1--WORKDIR=$(mktemp --tmpdir=. -d)--cd $WORKDIR--if ! cabal-rpm ../$FILE; then-    cd ..-    rm -r $WORKDIR-    exit 1-fi--SPECFILE=$(ls *.spec)--cd ---if [ ! -r "$SPECFILE" ]; then-  echo No $SPECFILE file found for $FILE-  rm -r $WORKDIR-  exit 1-fi--diff -uw $WORKDIR/$SPECFILE $SPECFILE | sed -e "s%$WORKDIR/$SPECFILE%$SPECFILE.cabal-rpm%"--[ -d "$WORKDIR" ] && rm -r $WORKDIR
cabal-rpm.cabal view
@@ -1,11 +1,13 @@ Name:                cabal-rpm-Version:             0.6.6+Version:             0.7.0 Synopsis:            RPM package creator for Haskell Cabal-based packages Description:     This package generates RPM spec files from Haskell Cabal packages.     .     Recent changes:     .+    * 0.7.0: command arg for spec, srpm, or build; installs existing packaged depends with sudo yum+    .     * 0.6.6: generate depends for extra-libraries, build-tools, and pkgconfig-depends     .     * 0.6.5: simplify BuildRequires without versions and drop explicit hscolour@@ -26,17 +28,17 @@ Author:              Bryan O'Sullivan <bos@serpentine.com> Maintainer:          Jens Petersen <juhp@community.haskell.org> Copyright:           2007-2008 Bryan O'Sullivan <bos@serpentine.com>,-                     2012 Jens Petersen <petersen@fedoraproject.org>+                     2012-2013 Jens Petersen <petersen@fedoraproject.org> Category:            Distribution Build-type:          Simple-Extra-source-files:  README.md NEWS man/cabal-rpm.1.md man/cabal-rpm.1 cabal-rpm-diff+Extra-source-files:  README.md NEWS man/cblrpm.1.md man/cblrpm.1 cblrpm-diff Cabal-version:       >=1.6  source-repository head   type:     git   location: https://github.com/juhp/cabal-rpm -Executable cabal-rpm+Executable cblrpm     Main-is:            CabalRpm.hs     Build-depends: base < 5,                    Cabal > 1.10,
+ cblrpm-diff view
@@ -0,0 +1,60 @@+#!/bin/sh++# Copyright (C) 2008-2012 Red Hat, Inc+# Author: Jens Petersen <petersen@redhat.com>+#+# 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.+#+# This program is distributed in the hope that it will be useful,+# but WITHOUT ANY WARRANTY; without even the implied warranty of+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+# GNU General Public License for more details.+#+# You should have received a copy of the GNU General Public License+# along with this program.  If not, see <http://www.gnu.org/licenses/>.++set -e++# use -l to force lib package+if getopts l opt; then+  shift+  case $opt in+      l) FORCE_LIB=-l+	  ;;+  esac+fi++if [ $# -ne 1 -o ! -r "$1" ]; then+    echo "Usage: $(basename $0) [-l] [hackage|hackage.tar.gz|hackage.cabal]"+    echo "  -l      assume BinLib package is Lib"+    exit 1+fi++FILE=$1++WORKDIR=$(mktemp --tmpdir=. -d)++cd $WORKDIR++if ! cblrpm spec $FORCE_LIB ../$FILE; then+    cd ..+    rm -r $WORKDIR+    exit 1+fi++SPECFILE=$(ls *.spec)++cd -++if [ ! -r "$SPECFILE" ]; then+  echo No $SPECFILE file found for $FILE+  rm -r $WORKDIR+  exit 1+fi++diff -uw $WORKDIR/$SPECFILE $SPECFILE | sed -e "s%$WORKDIR/$SPECFILE%$SPECFILE.cblrpm%"++[ -d "$WORKDIR" ] && rm -r $WORKDIR
− man/cabal-rpm.1
@@ -1,104 +0,0 @@-.TH CABAL-RPM 1 "2012-11-01" -.SH NAME-.PP-cabal-rpm - generates RPM .spec files from Cabal packages-.SH SYNOPSIS-.PP-cabal-rpm [\f[I]options\f[]] [\f[I]path-or-pkg\f[]]-.SH DESCRIPTION-.PP-Cabal-rpm generates RPM .spec files from Haskell Cabal package.-.PP-If no \f[I]path-or-pkg\f[] is specified, cabal-rpm looks for a .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 .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 \[aq]/\[aq] in the argument and it does not-exist 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.-.PP-Cabal-rpm then parses the above specified .cabal file and uses it to-generate a .spec file that can be built.-.PP-If a .spec already exists, cabal-rpm output to .spec.cblrpm instead.-.PP-The cabal-rpm-diff command can be used in the same way to output a diff-of .spec and .spec.cblrpm directly.-.SH OPTIONS-.TP-.B -h, --help-Show the help text.-.RS-.RE-.TP-.B -l, --library-Force a BinLib package with executable(s) to be considered a Lib-package.-.RS-.RE-.PP--f \f[I]FLAGS\f[], --flags=\f[I]FLAGS\f[] : Override one or more Cabal-build configuration flags.-.PP---release=\f[I]RELEASE\f[] : Override the release number in the .spec-file.-.PP--v \f[I]N\f[], --verbose=\f[I]N\f[] : Set verbosity to \f[I]N\f[].-.PP---version=\f[I]VERSION\f[] : Override the version number in the .spec-file.-.SH EXAMPLES-.PP-Create a .spec file for the Cabal src package in current directory:-.IP-.nf-\f[C]-cabal-rpm-\f[]-.fi-.PP-Create a .spec file for package (directory or package name):-.IP-.nf-\f[C]-cabal-rpm\ [package]-\f[]-.fi-.PP-Create a .spec file for package-version (directory or package name):-.IP-.nf-\f[C]-cabal-rpm\ [package-version]-\f[]-.fi-.PP-Create a .spec file for a .cabal file:-.IP-.nf-\f[C]-cabal-rpm\ path/to/some.cabal-\f[]-.fi-.PP-Create a .spec file from a tarball:-.IP-.nf-\f[C]-cabal-rpm\ path/to/pkg-ver.tar.gz-\f[]-.fi-.SH HISTORY-.PP-Cabal-rpm was originally written by Bryan O\[aq]Sullivan in 2007-2008-and resurrected by Jens Petersen in 2012 to replace cabal2spec.-.SH SEE ALSO-.PP-<http://github.com/juhp/cabal-rpm/>-.SH AUTHORS-This manpage was written by Jens Petersen.
− man/cabal-rpm.1.md
@@ -1,75 +0,0 @@-% CABAL-RPM(1)-% This manpage was written by Jens Petersen-% 2012-11-01--# NAME-cabal-rpm - generates RPM .spec files from Cabal packages--# SYNOPSIS-cabal-rpm [*options*] [*path-or-pkg*]--# DESCRIPTION-Cabal-rpm generates RPM .spec files from Haskell Cabal package.--If no *path-or-pkg* is specified, cabal-rpm 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-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 above specified .cabal file and-uses it to generate a .spec file that can be built.--If a <PKG>.spec already exists, cabal-rpm output to <PKG>.spec.cblrpm instead.--The cabal-rpm-diff command can be used in the same way to output a diff-of <PKG>.spec and <PKG>.spec.cblrpm directly.--# OPTIONS--h, --help-:   Show the help text.---l, --library-:   Force a BinLib package with executable(s) to be considered a Lib package.---f *FLAGS*, --flags=*FLAGS*-: Override one or more Cabal build configuration flags.----release=*RELEASE*-: Override the release number in the .spec file.---v *N*, --verbose=*N*-: Set verbosity to *N*.----version=*VERSION*-: Override the version number in the .spec file.--# EXAMPLES-Create a .spec file for the Cabal src package in current directory:--    cabal-rpm--Create a .spec file for package (directory or package name):- -    cabal-rpm [package]--Create a .spec file for package-version (directory or package name):--    cabal-rpm [package-version]--Create a .spec file for a .cabal file:--    cabal-rpm path/to/some.cabal--Create a .spec file from a tarball:--    cabal-rpm path/to/pkg-ver.tar.gz--# HISTORY-Cabal-rpm was originally written by Bryan O'Sullivan in 2007-2008-and resurrected by Jens Petersen in 2012 to replace cabal2spec.--# SEE ALSO-<http://github.com/juhp/cabal-rpm/>
+ man/cblrpm.1 view
@@ -0,0 +1,105 @@+.TH CBLRPM 1 "2013\-01\-21" +.SH NAME+.PP+cblrpm \- generates RPM .spec files from Cabal packages+.SH SYNOPSIS+.PP+cblrpm [\f[I]options\f[]] spec [\f[I]path\-or\-pkg\f[]] cblrpm+[\f[I]options\f[]] build [\f[I]path\-or\-pkg\f[]] cblrpm+[\f[I]options\f[]] srpm [\f[I]path\-or\-pkg\f[]]+.SH DESCRIPTION+.PP+cblrpm generates RPM .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.+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.+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.+cblrpm uses a temporary directory for unpackaging tarballs or packages.+.PP+cblrpm then parses the above specified .cabal file and uses it to+generate a .spec file that can be built.+.PP+If a .spec already exists, cblrpm output to .spec.cblrpm instead.+.PP+The cblrpm\-diff command can be used in the same way to output a diff of+.spec and .spec.cblrpm directly.+.SH OPTIONS+.TP+.B \-h, \-\-help+Show the help text.+.RS+.RE+.TP+.B \-l, \-\-library+Force a BinLib package with executable(s) to be considered a Lib+package.+.RS+.RE+.PP+\-f \f[I]FLAGS\f[], \-\-flags=\f[I]FLAGS\f[] : Override one or more+Cabal build configuration flags.+.PP+\-\-release=\f[I]RELEASE\f[] : Override the release number in the .spec+file.+.PP+\-v \f[I]N\f[], \-\-verbose=\f[I]N\f[] : Set verbosity to \f[I]N\f[].+.PP+\-\-version=\f[I]VERSION\f[] : Override the version number in the .spec+file.+.SH EXAMPLES+.PP+Create a .spec file for the Cabal src package in current directory:+.IP+.nf+\f[C]+cblrpm+\f[]+.fi+.PP+Create a .spec file for package (directory or package name):+.IP+.nf+\f[C]+cblrpm\ [package]+\f[]+.fi+.PP+Create a .spec file for package\-version (directory or package name):+.IP+.nf+\f[C]+cblrpm\ [package\-version]+\f[]+.fi+.PP+Create a .spec file for a .cabal file:+.IP+.nf+\f[C]+cblrpm\ path/to/some.cabal+\f[]+.fi+.PP+Create a .spec file from a tarball:+.IP+.nf+\f[C]+cblrpm\ path/to/pkg\-ver.tar.gz+\f[]+.fi+.SH HISTORY+.PP+Cabal\-rpm was originally written by Bryan O\[aq]Sullivan in 2007\-2008+and resurrected by Jens Petersen in 2012 to replace cabal2spec.+.SH SEE ALSO+.PP+<http://github.com/juhp/cabal-rpm/>+.SH AUTHORS+This manpage was written by Jens Petersen.
+ man/cblrpm.1.md view
@@ -0,0 +1,77 @@+% CBLRPM(1)+% This manpage was written by Jens Petersen+% 2013-01-21++# NAME+cblrpm - generates RPM .spec files from Cabal packages++# SYNOPSIS+cblrpm [*options*] spec [*path-or-pkg*]+cblrpm [*options*] build [*path-or-pkg*]+cblrpm [*options*] srpm [*path-or-pkg*]++# DESCRIPTION+cblrpm generates RPM .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+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 above specified .cabal file and+uses it to generate a .spec file that can be built.++If a <PKG>.spec already exists, cblrpm output to <PKG>.spec.cblrpm instead.++The cblrpm-diff command can be used in the same way to output a diff+of <PKG>.spec and <PKG>.spec.cblrpm directly.++# OPTIONS+-h, --help+:   Show the help text.++-l, --library+:   Force a BinLib package with executable(s) to be considered a Lib package.++-f *FLAGS*, --flags=*FLAGS*+: Override one or more Cabal build configuration flags.++--release=*RELEASE*+: Override the release number in the .spec file.++-v *N*, --verbose=*N*+: Set verbosity to *N*.++--version=*VERSION*+: Override the version number in the .spec file.++# EXAMPLES+Create a .spec file for the Cabal src package in current directory:++    cblrpm++Create a .spec file for package (directory or package name):+ +    cblrpm [package]++Create a .spec file for package-version (directory or package name):++    cblrpm [package-version]++Create a .spec file for a .cabal file:++    cblrpm path/to/some.cabal++Create a .spec file from a tarball:++    cblrpm path/to/pkg-ver.tar.gz++# HISTORY+Cabal-rpm was originally written by Bryan O'Sullivan in 2007-2008+and resurrected by Jens Petersen in 2012 to replace cabal2spec.++# SEE ALSO+<http://github.com/juhp/cabal-rpm/>
src/Distribution/Package/Rpm.hs view
@@ -1,6 +1,7 @@ -- | -- Module      :  Distribution.Package.Rpm -- Copyright   :  Bryan O'Sullivan 2007, 2008+--                Jens Petersen 2012 -- -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org> -- Stability   :  alpha@@ -14,56 +15,44 @@  module Distribution.Package.Rpm (       createSpecFile---    , rpm---    , rpmBuild+    , rpmBuild     ) where  --import Control.Exception (bracket)-import Control.Monad    (unless, when)+import Control.Monad    (unless, void, when) import Data.Char        (toLower)-import Data.List        (intercalate, isPrefixOf, isSuffixOf, nub)+import Data.List        (intercalate, isPrefixOf, isSuffixOf, nub, sort) import Data.Maybe       (fromMaybe) import Data.Time.Clock  (UTCTime, getCurrentTime) import Data.Time.Format (formatTime) import Data.Version     (showVersion) ---import System.Cmd (system)-import System.Directory (doesDirectoryExist, doesFileExist,-                         getDirectoryContents)---import System.Exit (ExitCode(..))-import System.IO     (IOMode (..), hClose, hPutStrLn, openFile)-import System.Locale (defaultTimeLocale)---import System.Process (runInteractiveCommand, waitForProcess)-import System.FilePath (dropFileName)---import System.Posix.Files (setFileCreationMask)--import Distribution.Compiler (CompilerFlavor (..)) import Distribution.License  (License (..)) import Distribution.Package  (Dependency (..), PackageIdentifier (..),                               PackageName (..)) -import Distribution.Simple.Compiler (Compiler (..))---import Distribution.Simple.PreProcess (knownSuffixHandlers)-import Distribution.Simple.Configure (configCompiler)-import Distribution.Simple.Program   (defaultProgramConfiguration)---import Distribution.Simple.LocalBuildInfo (LocalBuildInfo)---import Distribution.Simple.SrcDist (createArchive, prepareTree) import Distribution.Simple.Utils (die, warn) -import Distribution.PackageDescription (GenericPackageDescription (..),-                                        PackageDescription (..), exeName,+import Distribution.PackageDescription (PackageDescription (..), exeName,                                         hasExes, hasLibs, withExe, allBuildInfo,                                         BuildInfo (..)) -import Distribution.PackageDescription.Configuration (finalizePackageDescription)--import Distribution.PackageDescription.Parse (readPackageDescription)---import Distribution.Verbosity (Verbosity)+import Distribution.Verbosity (normal) --import Distribution.Version (VersionRange, foldVersionRange')---import Distribution.Simple.Setup (configConfigurationsFlags, emptyConfigFlags)+ import Distribution.Package.Rpm.Setup (RpmFlags (..))-import Distribution.System            (Platform (..), buildArch, buildOS) +import System.Cmd (system)+import System.Directory (doesDirectoryExist, doesFileExist,+                         getCurrentDirectory, getDirectoryContents)+import System.Exit (ExitCode(..))+import System.Environment (getEnv)+import System.IO     (IOMode (..), hClose, hPutStrLn, openFile)+import System.Locale (defaultTimeLocale)+--import System.Process (runInteractiveCommand, waitForProcess)+import System.FilePath (dropFileName)+import System.FilePath.Posix ((</>))+ import qualified Paths_cabal_rpm (version)  (+-+) :: String -> String -> String@@ -71,78 +60,74 @@ s +-+ "" = s s +-+ t = s ++ " " ++ t -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---- | Copy a file or directory (recursively, in the latter case) to the--- same name in the target directory.  Arguments flipped from the--- conventional order.---- copyTo :: Verbosity -> FilePath -> FilePath -> IO ()---- copyTo verbose dest src = do---     isFile <- doesFileExist src---     let destDir = dest </> src---     if isFile---       then copyFileVerbose verbose src destDir---       else copyDirectoryRecursiveVerbose verbose src destDir- -- autoreconf :: Verbosity -> PackageDescription -> IO ()- -- autoreconf verbose pkgDesc = do --     ac <- doesFileExist "configure.ac" --     when ac $ do --         c <- doesFileExist "configure" --         when (not c) $ do --             setupMessage verbose "Running autoreconf" pkgDesc---             ret <- system "autoreconf"---             case ret of---               ExitSuccess -> return ()---               ExitFailure n -> die ("autoreconf failed with status" +-+ show n)+--             trySystem "autoreconf" --- localBuildInfo :: PackageDescription -> RpmFlags -> IO LocalBuildInfo--- localBuildInfo pkgDesc flags = do---   mb_lbi <- maybeGetPersistBuildConfig---   case mb_lbi of---     Just lbi -> return lbi---     Nothing -> configure (Right pkgDesc, emptyHookedBuildInfo)---                ((emptyConfigFlags defaultProgramConfiguration)---                 { configConfigurationsFlags = rpmConfigurationsFlags flags })+unlessSystem :: String -> String -> IO ()+unlessSystem tst act = do+    ret <- system tst+    case ret of+      ExitSuccess -> return ()+      ExitFailure _ -> void $ trySystemWarn act --- rpmBuild :: GenericPackageDescription -> RpmFlags -> IO ()+maybeInstall :: String -> IO ()+maybeInstall pkg = do+    unlessSystem ("rpm -q" +-+ pkg) ("sudo yum install" +-+ pkg) --- rpmBuild genPkgDesc flags = do---     tgtPfx <- canonicalizePath (rpmTopDir flags)---     (compiler, pkgDesc) <- simplePackageDescription genPkgDesc flags---     let verbose = rpmVerbosity flags---         tmpDir = tgtPfx </> "src"---     flip mapM_ ["BUILD", "RPMS", "SOURCES", "SPECS", "SRPMS"] $ \ subDir -> do---       createDirectoryIfMissing True (tgtPfx </> subDir)---     let specsDir = tgtPfx </> "SPECS"---     lbi <- localBuildInfo pkgDesc flags---     bracket (setFileCreationMask 0o022) setFileCreationMask $ \ _ -> do--- --      autoreconf verbose pkgDesc---       (specFile, extraDocs) <- createSpecFile pkgDesc flags compiler---                                specsDir---       tree <- prepareTree pkgDesc verbose (Just lbi) False tmpDir---               knownSuffixHandlers 0---       mapM_ (copyTo verbose tree) extraDocs---       createArchive pkgDesc verbose (Just lbi) tmpDir (tgtPfx </> "SOURCES")---       ret <- system ("rpmbuild -ba --define \"_topdir" +-+ tgtPfx ++ "\"" +-+---                      specFile)---       case ret of---         ExitSuccess -> return ()---         ExitFailure n -> die ("rpmbuild failed with status" +-+ show n)+rpmBuild :: FilePath -> PackageDescription -> RpmFlags -> Bool -> IO ()+rpmBuild cabalPath pkgDesc flags binary = do+--    let verbose = rpmVerbosity flags+--    flip mapM_ ["BUILD", "RPMS", "SOURCES", "SPECS", "SRPMS"] $ \ subDir -> do+--      createDirectoryIfMissing True (tgtPfx </> subDir)+--    bracket (setFileCreationMask 0o022) setFileCreationMask $ \ _ -> do+--      autoreconf verbose pkgDesc+    specFile <- specFileName pkgDesc flags+    specFileExists <- doesFileExist specFile+    unless specFileExists $+      createSpecFile cabalPath pkgDesc flags+    let pkg = package pkgDesc+        name = packageName pkg+    when binary $ do+        --      trySystem ("sudo yum-builddep" +-+ specFile)+        mapM_ maybeInstall $ map showDep $ buildDependencies pkgDesc [name]+    cwd <- getCurrentDirectory+    home <- getEnv "HOME"+    let version = packageVersion pkg+        cachedir = home </> ".cabal/packages/hackage.haskell.org" </> name </> version+        tarFile = name ++ "-" ++ version ++ ".tar.gz"+        rpmCmd = if binary then "a" else "s"+    tarFileExists <- doesFileExist tarFile+    srcdir <- if tarFileExists+                then return cwd+                else do+                     trySystem ("cabal fetch -v0 --no-dependencies" +-+ name ++ "-" ++ version)+                     return cachedir+    trySystem ("rpmbuild -b" ++ rpmCmd +-++                     "--define \"_rpmdir" +-+ cwd ++ "\"" +-++                     "--define \"_srcrpmdir" +-+ cwd ++ "\"" +-++                     "--define \"_sourcedir" +-+ srcdir ++ "\"" +-++                     specFile) +trySystem :: String -> IO ()+trySystem cmd = do+    ret <- system cmd+    case ret of+      ExitSuccess -> return ()+      ExitFailure n -> die ("\"" ++ cmd ++ "\"" +-+ "failed with status" +-+ show n)++trySystemWarn :: String -> IO ()+trySystemWarn cmd = do+    ret <- system cmd+    case ret of+      ExitSuccess -> return ()+      ExitFailure n -> warn normal ("\"" ++ cmd ++ "\"" +-+ "failed with status" +-+ show n)+ defaultRelease :: UTCTime -> IO String defaultRelease now = do     darcsRepo <- doesDirectoryExist "_darcs"@@ -153,27 +138,52 @@ rstrip :: (Char -> Bool) -> String -> String rstrip p = reverse . dropWhile p . reverse +packageName :: PackageIdentifier -> String+packageName pkg = name+  where PackageName name = pkgName pkg -createSpecFile :: FilePath            -- ^pkg src dir+packageVersion :: PackageIdentifier -> String+packageVersion pkg = (showVersion . pkgVersion) pkg++specFileName :: PackageDescription    -- ^pkg description                -> RpmFlags            -- ^rpm flags                -> IO FilePath-createSpecFile cabalPath flags = do+specFileName pkgDesc flags = do+    let pkg = package pkgDesc+        name = packageName pkg+        pkgname = if isExec then name else "ghc-" ++ name+        isExec = if (rpmLibrary flags) then False else hasExes pkgDesc+    return $ pkgname ++ ".spec"++buildDependencies :: PackageDescription -> [String] -> [String]+buildDependencies pkgDesc excl = filter excludedPkgs $ nub $ map depName (buildDepends pkgDesc)+  where excludedPkgs n = notElem n $ ["ghc-prim", "integer-gmp"] ++ excl++depName :: Dependency -> String+depName (Dependency (PackageName n) _) = n++showDep :: String -> String+showDep p = "ghc-" ++ p ++ "-devel"++createSpecFile :: FilePath            -- ^pkg spec file+               -> PackageDescription  -- ^pkg description+               -> RpmFlags            -- ^rpm flags+               -> IO ()+createSpecFile cabalPath pkgDesc flags = do     let verbose = rpmVerbosity flags-    genPkgDesc <- readPackageDescription verbose cabalPath-    pkgDesc <- simplePackageDescription genPkgDesc flags     now <- getCurrentTime     defRelease <- defaultRelease now     let pkg = package pkgDesc-        PackageName packageName = pkgName pkg-        name = if isExec then packageName else "ghc-" ++ packageName+        name = packageName pkg+        pkgname = if isExec then name else "ghc-" ++ name         pkg_name = if isExec then "%{name}" else "%{pkg_name}"-        version = fromMaybe ((showVersion . pkgVersion) pkg) (rpmVersion flags)+        version = packageVersion pkg         release = fromMaybe defRelease (rpmRelease flags)-        specPath = name ++ ".spec"+        specFile = pkgname ++ ".spec"         isExec = if (rpmLibrary flags) then False else hasExes pkgDesc         isLib = hasLibs pkgDesc-    specAlreadyExists <- doesFileExist specPath-    h <- openFile (specPath ++ if specAlreadyExists then ".cblrpm" else "") WriteMode+    specAlreadyExists <- doesFileExist specFile+    h <- openFile (specFile ++ if specAlreadyExists then ".cblrpm" else "") WriteMode     let putHdr hdr val = hPutStrLn h (hdr ++ ":" ++ padding hdr ++ val)         padding hdr = replicate (15 - length hdr) ' '         putHdr_ hdr val = unless (null val) $ putHdr hdr val@@ -192,7 +202,7 @@     (syn', synTooLong) <- case lines syn of               (x:_) -> return (x, x /= syn)               _ -> do warn verbose "This package has no synopsis."-                      return ("Haskell" +-+ packageName +-+ "package", False)+                      return ("Haskell" +-+ name +-+ "package", False)     let common_summary = if synTooLong                          then syn' +-+ "[...]"                          else rstrip (== '.') syn'@@ -207,14 +217,14 @@               else description pkgDesc      when isLib $ do-      putDef "pkg_name" packageName+      putDef "pkg_name" name       putNewline       putDef "common_summary" common_summary       putNewline       putDef "common_description" $ intercalate "\\\n" common_description       putNewline -    putHdr "Name" (if isExec then (if isLib then "%{pkg_name}" else name) else "ghc-%{pkg_name}")+    putHdr "Name" (if isExec then (if isLib then "%{pkg_name}" else pkgname) else "ghc-%{pkg_name}")     putHdr "Version" version     putHdr "Release" $ release ++ "%{?dist}"     if isLib@@ -228,10 +238,7 @@     putHdr "BuildRequires" "ghc-Cabal-devel"     putHdr "BuildRequires" $ "ghc-rpm-macros" -    let excludedPkgs n = notElem n [packageName, "Cabal", "base", "ghc-prim", "integer-gmp"]-        depName (Dependency (PackageName n) _) = n-        deps = filter excludedPkgs $ nub $ map depName (buildDepends pkgDesc)-        showDep p = "ghc-" ++ p ++ "-devel"+    let deps = buildDependencies pkgDesc [name, "Cabal", "base"]         buildinfo = allBuildInfo pkgDesc         excludedTools n = notElem n ["ghc", "perl"]         mapTools "gtk2hsC2hs" = "gtk2hs-buildtools"@@ -245,14 +252,14 @@         mapCLibs "z" = "zlib"         mapCLibs ('X':lib) = "libX" ++ lib         mapCLibs lib = lib-        clibs = filter excludedCLibs $ nub $ map mapCLibs $ concat (map extraLibs buildinfo)+        clibs = sort $ filter excludedCLibs $ nub $ map mapCLibs $ concat (map extraLibs buildinfo)         pkgcfgs = nub $ map depName $ concat (map pkgconfigDepends buildinfo)         showPkgCfg p = "pkgconfig(" ++ p ++ ")"      when (not . null $ deps ++ tools ++ clibs ++ pkgcfgs) $ do       put "# Begin cabal-rpm deps:"       mapM_ (putHdr "BuildRequires") $ map showDep deps-      when (elem "template-haskell" deps) $+      when (any (\ d -> elem d ["template-haskell", "hamlet"]) deps) $         putHdr "ExclusiveArch" "%{ghc_arches_with_ghci}"       mapM_ (putHdr "BuildRequires") tools       mapM_ (putHdr "BuildRequires") $ map (++ "-devel%{?_isa}") clibs@@ -267,7 +274,7 @@     putNewline      put "%prep"-    put $ "%setup -q" ++ (if name /= packageName then " -n %{pkg_name}-%{version}" else "")+    put $ "%setup -q" ++ (if pkgname /= name then " -n %{pkg_name}-%{version}" else "")     putNewline     putNewline @@ -317,7 +324,7 @@        withExe pkgDesc $ \exe ->         let program = exeName exe in-        put $ "%{_bindir}/" ++ (if program == packageName then "%{name}" else program)+        put $ "%{_bindir}/" ++ (if program == name then "%{name}" else program)       unless (null (dataFiles pkgDesc) && isExec) $         put "%{_datadir}/%{name}-%{version}" @@ -335,7 +342,6 @@     put $ "*" +-+ date +-+ "Fedora Haskell SIG <haskell@lists.fedoraproject.org>"     put $ "- spec file generated by cabal-rpm-" ++ showVersion Paths_cabal_rpm.version     hClose h-    return specPath  findDocs :: FilePath -> PackageDescription -> IO [FilePath] findDocs cabalPath pkgDesc = do@@ -363,73 +369,3 @@ showLicense AllRightsReserved = "Proprietary" showLicense OtherLicense = "Unknown" showLicense (UnknownLicense l) = "Unknown" +-+ l---- | Generate a string expressing runtime dependencies, but only--- on package/version pairs not already "built into" a compiler--- distribution.---- showRuntimeReq :: Verbosity -> PackageDescription -> IO String---- showRuntimeReq verbose pkgDesc = do---     let externalDeps = (buildDepends pkgDesc)---     clauses <- mapM (showRpmReq verbose) externalDeps---     return $ (commaSep . concat) clauses---- -- | Find the paths to all "extra" libraries specified in the package--- -- config.  Prefer shared libraries, since that's what gcc prefers.--- findLibPaths :: BuildInfo -> IO [FilePath]---- findLibPaths buildInfo = mapM findLib (extraLibs buildInfo)---   where findLib :: String -> IO FilePath---         findLib lib = do---             so <- findLibPath ("lib" ++ lib ++ ".so")---             if isJust so---               then return (fromJust so)---               else findLibPath ("lib" ++ lib ++ ".a") >>=---                    maybe (die $ "could not find library: lib" ++ lib)---                          return---         findLibPath extraLib = do---             loc <- findInExtraLibs (extraLibDirs buildInfo)---             if isJust loc---               then return loc---               else findWithGcc extraLib---           where findInExtraLibs (d:ds) = do---                     let path = d </> extraLib---                     exists <- doesFileExist path---                     if exists---                       then return (Just path)---                       else findInExtraLibs ds---                 findInExtraLibs [] = return Nothing---- | Return the full path to a file (usually an object file) that gcc--- knows about.---- findWithGcc :: FilePath -> IO (Maybe FilePath)---- findWithGcc lib = do---     (i,o,e,p) <- runInteractiveCommand $ "gcc -print-file-name=" ++ lib---     loc <- hGetLine o---     mapM_ hClose [i,o,e]---     waitForProcess p---     return $ if loc == lib then Nothing else Just loc---- | Return the RPM that owns a particular file or directory.  Die if--- not owned.---- findRpmOwner :: FilePath -> IO String--- findRpmOwner path = do---     (i,o,e,p) <- runInteractiveCommand (rpmQuery ++ path)---     pkg <- hGetLine o---     mapM_ hClose [i,o,e]---     ret <- waitForProcess p---     case ret of---       ExitSuccess -> return pkg---       _ -> die $ "not owned by any package:" +-+ path---   where rpmQuery = "rpm --queryformat='%{NAME}' -qf "---- | Find all RPMs on which the build of this package depends.  Die if--- a dependency is not present, or not owned by an RPM.----findLibDeps :: BuildInfo -> IO [String]----findLibDeps buildInfo = findLibPaths buildInfo >>= mapM findRpmOwner
src/Distribution/Package/Rpm/Main.hs view
@@ -1,6 +1,7 @@ -- | -- Module      :  Distribution.Package.Rpm.Main -- Copyright   :  Bryan O'Sullivan 2007+--                Jens Petersen 2012 -- -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org> -- Stability   :  alpha@@ -13,10 +14,18 @@  module Distribution.Package.Rpm.Main where -import Distribution.Package.Rpm (createSpecFile)+import Distribution.Compiler (CompilerFlavor (..))+import Distribution.Package.Rpm (createSpecFile, rpmBuild) import Distribution.Package.Rpm.Setup (RpmFlags (..), parseArgs)-import Distribution.Simple.Utils (defaultPackageDesc, findPackageDesc)-import Control.Monad (void)+import Distribution.PackageDescription (GenericPackageDescription (..),+                                        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 (defaultPackageDesc, die, findPackageDesc)+import Distribution.System            (Platform (..), buildArch, buildOS) import Data.Char (isDigit) import Data.List (isSuffixOf) import System.Directory (doesDirectoryExist, doesFileExist, getCurrentDirectory,@@ -28,14 +37,37 @@ main :: IO () main = do (opts, args) <- getArgs >>= parseArgs           let verbosity = rpmVerbosity opts-          (cabalPath, mtmp) <- if null args+              (cmd:args') = args+          (cabalPath, mtmp) <- if null args'                                then do                                  pth <- defaultPackageDesc verbosity                                  return (pth, Nothing)-                               else findCabalFile $ head args-          void $ createSpecFile cabalPath opts+                               else findCabalFile $ head args'+          let verbose = rpmVerbosity opts+          genPkgDesc <- readPackageDescription verbose cabalPath+          pkgDesc <- simplePackageDescription genPkgDesc opts+          case cmd of+               "spec" -> createSpecFile cabalPath pkgDesc opts+               "srpm" ->  rpmBuild cabalPath pkgDesc opts False+               "build" -> rpmBuild cabalPath pkgDesc opts True+--               "install" ->+--               "builddep" ->+--               "showdeps" ->+               c -> error $ "Unknown cmd: " ++ c           maybe (return ()) removeDirectoryRecursive mtmp +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 :: FilePath -> IO (FilePath, Maybe FilePath) findCabalFile path = do@@ -78,7 +110,7 @@     cwd <- getCurrentDirectory     tmpdir <- mktempdir     setCurrentDirectory tmpdir-    _ <- system $ "cabal unpack " ++ pkgver+    _ <- system $ "cabal unpack -v0 " ++ pkgver     pth <- findPackageDesc pkgver     setCurrentDirectory cwd     return (tmpdir ++ "/" ++ pth, Just tmpdir)
src/Distribution/Package/Rpm/Setup.hs view
@@ -1,6 +1,7 @@ -- | -- Module      :  Distribution.Package.Rpm.Setup -- Copyright   :  Bryan O'Sullivan 2007, 2008+--                Jens Petersen 2012 -- -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org> -- Stability   :  alpha@@ -19,6 +20,7 @@  import Control.Monad (unless, when) import Data.Char     (toLower)+import Data.Version  (showVersion)  import Distribution.PackageDescription (FlagName (..)) import Distribution.ReadE              (readEOrFail)@@ -30,18 +32,15 @@ import System.Exit           (ExitCode (..), exitSuccess, exitWith) import System.IO             (Handle, hPutStr, hPutStrLn, stderr, stdout) +import Paths_cabal_rpm       (version)+ data RpmFlags = RpmFlags     { rpmConfigurationsFlags :: [(FlagName, Bool)]-    , rpmGenSpec             :: Bool-    , rpmHaddock             :: Bool     , rpmHelp                :: Bool-    , rpmLibProf             :: Bool     , rpmLibrary             :: Bool-    , rpmOptimisation        :: Bool     , rpmRelease             :: Maybe String-    , rpmTopDir              :: Maybe FilePath     , rpmVerbosity           :: Verbosity-    , rpmVersion             :: Maybe String+    , rpmVersion             :: Bool     }     deriving (Eq, Show) @@ -49,44 +48,29 @@  emptyRpmFlags = RpmFlags     { rpmConfigurationsFlags = []-    , rpmGenSpec = False-    , rpmHaddock = True     , rpmHelp = False-    , rpmLibProf = True     , rpmLibrary = False-    , rpmOptimisation = True     , rpmRelease = Nothing-    , rpmTopDir = Nothing     , rpmVerbosity = normal-    , rpmVersion = Nothing+    , rpmVersion = False     }  options :: [OptDescr (RpmFlags -> RpmFlags)]  options =     [-      Option "" ["gen-spec"] (NoArg (\x -> x { rpmGenSpec = True }))-             "Generate a spec file, nothing more",       Option "h?" ["help"] (NoArg (\x -> x { rpmHelp = True }))              "Show this help text",       Option "l" ["library"] (NoArg (\x -> x { rpmLibrary = True }))-             "Ignore executables and force package to be a library",-      Option "" ["disable-haddock"] (NoArg (\x -> x { rpmHaddock = False }))-             "Don't generate API docs",-      Option "" ["disable-library-profiling"] (NoArg (\x -> x { rpmLibProf = False }))-             "Don't generate profiling libraries",-      Option "" ["disable-optimization"] (NoArg (\x -> x { rpmOptimisation = False }))-             "Don't generate optimised code",+             "Force package to be a Library ignoring executables",       Option "f" ["flags"] (ReqArg (\flags x -> x { rpmConfigurationsFlags = rpmConfigurationsFlags x ++ flagList flags }) "FLAGS")              "Set given flags in Cabal conditionals",       Option "" ["release"] (ReqArg (\rel x -> x { rpmRelease = Just rel }) "RELEASE")              "Override the default package release",-      Option "" ["topdir"] (ReqArg (\path x -> x { rpmTopDir = Just path }) "TOPDIR")-             "Override the default build directory",       Option "v" ["verbose"] (ReqArg (\verb x -> x { rpmVerbosity = readEOrFail flagToVerbosity verb }) "n")              "Change build verbosity",-      Option "" ["version"] (ReqArg (\vers x -> x { rpmVersion = Just vers }) "VERSION")-             "Override the default package version"+      Option "V" ["version"] (NoArg (\x -> x { rpmVersion = True }))+             "Show version number"     ]  -- Lifted from Distribution.Simple.Setup, since it's not exported.@@ -99,9 +83,16 @@  printHelp h = do     progName <- getProgName-    let info = "Usage: " ++ progName ++ " [OPTION]... [PKGPATH]\n" ++-               "Generate a RPM .spec file from " ++-               "a .cabal file, dir, or package name\n"+    let info = "Usage: " ++ progName ++ " [OPTION]... [COMMAND] [PKGDIR|PKG|PKG-VERSION|CABALFILE|TARBALL]\n"+            ++ "\n"+            ++ "Commands:\n"+            ++ "  spec\t generate a spec file\n"+            ++ "  srpm\t generate a src rpm file\n"+            ++ "  build\t build rpm package\n"+--             ++ "  install\t install rpm package\n"+--             ++ "  mock\t mock build package\n"+            ++ "\n"+            ++ "Options:"     hPutStrLn h (usageInfo info options)  parseArgs :: [String] -> IO (RpmFlags, [String])@@ -111,6 +102,9 @@      when (rpmHelp opts) $ do        printHelp stdout        exitSuccess+     when (rpmVersion opts) $ do+       hPutStrLn stderr $ "Version " ++ (showVersion version)+       exitSuccess      unless (null errs) $ do        hPutStrLn stderr "Error:"        mapM_ (hPutStrLn stderr) errs@@ -119,7 +113,10 @@        hPutStr stderr "Unrecognised options: "        hPutStrLn stderr $ unwords unknown        exitWith (ExitFailure 1)-     when (length args' > 1) $ do+     when ((null args') || (notElem (head args') ["spec", "srpm", "build", "install"])) $ do+       printHelp stderr+       exitWith (ExitFailure 1)+     when (length args' > 2) $ do        hPutStr stderr "Too many arguments: "        hPutStrLn stderr $ unwords args'        exitWith (ExitFailure 1)