cabal-rpm 0.6.6 → 0.7.0
raw patch · 12 files changed
+452/−474 lines, 12 filesnew-component:exe:cblrpm
Files
- NEWS +10/−0
- README.md +11/−13
- cabal-rpm-diff +0/−60
- cabal-rpm.cabal +6/−4
- cblrpm-diff +60/−0
- man/cabal-rpm.1 +0/−104
- man/cabal-rpm.1.md +0/−75
- man/cblrpm.1 +105/−0
- man/cblrpm.1.md +77/−0
- src/Distribution/Package/Rpm.hs +118/−182
- src/Distribution/Package/Rpm/Main.hs +39/−7
- src/Distribution/Package/Rpm/Setup.hs +26/−29
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)