cabal-rpm 0.5.1 → 0.6.0
raw patch · 7 files changed
+447/−770 lines, 7 filesdep ~Cabaldep ~basedep ~timenew-uploader
Dependency ranges changed: Cabal, base, time
Files
- NEWS +10/−0
- README.md +56/−0
- cabal-rpm.cabal +34/−33
- src/Distribution/Package/Rpm.hs +282/−487
- src/Distribution/Package/Rpm/Bundled.hs +0/−203
- src/Distribution/Package/Rpm/Main.hs +37/−6
- src/Distribution/Package/Rpm/Setup.hs +28/−41
+ NEWS view
@@ -0,0 +1,10 @@+* 0.6.0 (2012-07-24)+- updated to work with Cabal >= 1.10 and current cabal2spec style packaging+ using currently actively used ghc-rpm-macros+- should generate haskell dependencies correctly and also summary and+ description text+- some of the generic compiler supported was dropped for simplicity+- rpmbuild support will be re-introduced in a future version++* 0.5.1 and earlier (2007-2008) released by Bryan O'Sullivan+- should work with ghc-6.8
+ README.md view
@@ -0,0 +1,56 @@+# cabal-rpm++cabal-rpm creates RPM spec files for packaging Haskell Cabal-based packages.++This version updates the older cabal-rpm-0.5.1 package by Bryan O'Sullivan+(see README.orig) to work with current Cabal and also updated to current RPM+packaging conventions defined until now by cabal2spec which is used by Fedora+and also OpenSuSE. It is licensed under the terms of the GPL version 3+(see the COPYING file). It is designed to replace the simple cabal2spec tool+shell script made by the maintainer.++You can build from source as normal by running `cabal install`+or via Hackage with `cabal install cabal-rpm`.++## Requirements+cabal-rpm assumes you are using ghc-rpm-macros for Haskell RPM packaging.+It currently needs Cabal 1.10 or later to build (ie ghc7),+but it should not be hard to patch it to build at least for ghc-6.12.++## Usage+To create a `.spec` file for a Haskell src package in the current dir:++ $ cabal-rpm++or directly on a `.cabal` file:++ $ cabal-rpm path/to/mypkg.cabal++or on a package source dir:++ $ cabal-rpm mypkg-0.1++You can also package directly from hackage:++ $ cabal-rpm somepkg++or++ $ cabal-rpm somepkg-0.1++will unpack the (latest) 'something' package from hackage+(if the dir does not exist, otherwise it uses the existing dir)+and create a spec file for it.++cabal-rpm always creates `.spec` files in the current dir+and if a `.spec` file already exists it will append `.cabal-rpm`+to the generated filename to avoid overwriting an existing file.++## Development+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.
cabal-rpm.cabal view
@@ -1,36 +1,37 @@-Name: cabal-rpm-Version: 0.5.1-License: GPL-License-File: COPYING-Author: Bryan O'Sullivan <bos@serpentine.com>-Maintainer: Bryan O'Sullivan <bos@serpentine.com>-Copyright: 2007, 2008 Bryan O'Sullivan <bos@serpentine.com>-Homepage: http://www.serpentine.com/software/cabal-rpm/-Stability: Experimental-Category: Distribution-Build-type: Simple-Synopsis: RPM package builder for Haskell Cabal source packages.-Description:- This package turns Haskell Cabal source packages into source and- binary RPM packages.-Cabal-version: >= 1.2.3.0+Name: cabal-rpm+Version: 0.6.0+Synopsis: RPM package creator for Haskell Cabal-based packages+Description: This package generates RPM spec files from Haskell Cabal packages.+Homepage: https://github.com/juhp/cabal-rpm+Bug-reports: https://github.com/juhp/cabal-rpm/issues+License: GPL-3+License-file: COPYING+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>+Category: Distribution+Build-type: Simple+Extra-source-files: README.md NEWS+Cabal-version: >=1.6 -Flag splitBase- Description: Choose the new, split-up base package.+source-repository head+ type: git+ location: https://github.com/juhp/cabal-rpm Executable cabal-rpm- if flag(splitBase)- Build-depends: base, Cabal >= 1.2.3.0 && < 1.3, directory, filepath,- old-locale, process, time, unix- else- Build-depends: base, Cabal >= 1.2.3.0 && < 1.3, filepath,- time >= 1.1, unix- Main-Is: CabalRpm.hs- Other-Modules:- Distribution.Package.Rpm,- Distribution.Package.Rpm.Bundled,- Distribution.Package.Rpm.Main,- Distribution.Package.Rpm.Setup- Hs-Source-Dirs: src- Extensions: CPP- GHC-options: -fwarn-missing-signatures -Wall+ Main-is: CabalRpm.hs+ Build-depends: base < 5,+ Cabal > 1.10,+ directory,+ filepath,+ old-locale,+ process,+ time,+ unix+ Other-modules:+ Distribution.Package.Rpm,+ Distribution.Package.Rpm.Main,+ Distribution.Package.Rpm.Setup+ Hs-Source-Dirs: src+ GHC-options: -fwarn-missing-signatures -Wall
src/Distribution/Package/Rpm.hs view
@@ -1,10 +1,8 @@-{-# LANGUAGE CPP #-}- -- | -- Module : Distribution.Package.Rpm -- Copyright : Bryan O'Sullivan 2007, 2008 ----- Maintainer : Bryan O'Sullivan <bos@serpentine.com>+-- Maintainer : Jens Petersen <petersen@fedoraproject.org> -- Stability : alpha -- Portability : portable --@@ -17,149 +15,144 @@ module Distribution.Package.Rpm ( createSpecFile , rpm- , rpmBuild+-- , rpmBuild ) where -import Control.Exception (bracket)-import Control.Monad (mapM, when, unless)+--import Control.Exception (bracket)+import Control.Monad (when, unless) import Data.Char (toLower)-import Data.List (intersperse, isPrefixOf, sort)-import Data.Maybe+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 (Version(..), showVersion)-import System.Cmd (system)-import System.Directory (canonicalizePath, createDirectoryIfMissing,- doesDirectoryExist, doesFileExist,+import Data.Version (showVersion)+--import System.Cmd (system)+import System.Directory (doesDirectoryExist, doesFileExist, getDirectoryContents)-import System.Exit (ExitCode(..))-import System.IO (IOMode(..), hClose, hGetLine, hPutStr, hPutStrLn, openFile)+--import System.Exit (ExitCode(..))+import System.IO (IOMode(..), hClose, hPutStrLn, openFile) import System.Locale (defaultTimeLocale)-import System.Process (runInteractiveCommand, waitForProcess)+--import System.Process (runInteractiveCommand, waitForProcess) -import System.FilePath ((</>))-import Distribution.Simple.Compiler (CompilerFlavor(..), Compiler(..),- compilerVersion)+--import System.FilePath ((</>))+import Distribution.Compiler (CompilerFlavor(..))+import Distribution.Simple.Compiler (Compiler(..))+import Distribution.System (Platform(..), buildOS, buildArch) import Distribution.License (License(..))-import Distribution.Package (PackageIdentifier(..))-import Distribution.Simple.PreProcess (knownSuffixHandlers)+import Distribution.Package (Dependency(..), PackageIdentifier(..), PackageName(..))+--import Distribution.Simple.PreProcess (knownSuffixHandlers) import Distribution.Simple.Program (defaultProgramConfiguration)-import Distribution.Simple.Configure (configCompiler, configure,- maybeGetPersistBuildConfig)-import Distribution.Simple.LocalBuildInfo (LocalBuildInfo, distPref)-import Distribution.Simple.SrcDist (createArchive, prepareTree, tarBallName)-import Distribution.Simple.Utils (copyDirectoryRecursiveVerbose,- copyFileVerbose, die, warn)-import Distribution.PackageDescription (BuildInfo(..),+import Distribution.Simple.Configure (configCompiler)+--import Distribution.Simple.LocalBuildInfo (LocalBuildInfo)+--import Distribution.Simple.SrcDist (createArchive, prepareTree)+import Distribution.Simple.Utils (die, warn)+import Distribution.PackageDescription (-- BuildInfo(..), GenericPackageDescription(..),- Library(..), PackageDescription(..),- emptyHookedBuildInfo,- exeName, finalizePackageDescription,- hasLibs, setupMessage, withExe,- withLib)-import Distribution.Verbosity (Verbosity)-import Distribution.Version (Dependency(..), VersionRange(..))-import Distribution.Simple.Setup (configConfigurationsFlags, emptyConfigFlags)-import Distribution.Package.Rpm.Bundled (bundledWith, isBundled)+ exeName,+ hasExes,+ hasLibs,+ withExe,+-- withLib+ )+import Distribution.PackageDescription.Configuration (finalizePackageDescription)+--import Distribution.Verbosity (Verbosity)+import Distribution.Version (VersionRange, foldVersionRange')+--import Distribution.Simple.Setup (configConfigurationsFlags, emptyConfigFlags) import Distribution.Package.Rpm.Setup (RpmFlags(..))-import System.Posix.Files (setFileCreationMask)+--import System.Posix.Files (setFileCreationMask) +import qualified Paths_cabal_rpm (version)++(+-+) :: String -> String -> String+"" +-+ s = s+s +-+ "" = s+s +-+ t = s ++ " " ++ t+ simplePackageDescription :: GenericPackageDescription -> RpmFlags- -> IO (Compiler, PackageDescription)+ -> IO PackageDescription simplePackageDescription genPkgDesc flags = do- (compiler, _) <- configCompiler (rpmCompiler flags) Nothing Nothing+ (compiler, _) <- configCompiler (Just GHC) Nothing Nothing defaultProgramConfiguration (rpmVerbosity flags)- let bundled = bundledWith compiler case finalizePackageDescription (rpmConfigurationsFlags flags)- bundled "" "" ("", Version [] []) genPkgDesc of- Left _ -> die "finalize failed"- Right (pd, _) -> return (compiler, pd)- + (const True) (Platform buildArch buildOS) (compilerId compiler)+ [] genPkgDesc of+ Left e -> die $ "finalize failed:" +-+ show e+ Right (pd, _) -> return pd+ rpm :: GenericPackageDescription -- ^info from the .cabal file -> RpmFlags -- ^rpm flags -> IO ()- rpm genPkgDesc flags = do- let comp = rpmCompiler flags- case comp of- Just GHC -> return ()- Just c -> die ("the " ++ show c ++ " compiler is not yet supported")- _ -> die "no compiler information provided"- if rpmGenSpec flags- then do- (compiler, pkgDesc) <- simplePackageDescription genPkgDesc flags- (name, extraDocs) <- createSpecFile False pkgDesc flags compiler "."- putStrLn $ "Spec file created: " ++ name- when ((not . null) extraDocs) $ do- putStrLn "NOTE: docs packaged, but not in .cabal file:"- mapM_ putStrLn $ sort extraDocs- return ()- else rpmBuild genPkgDesc flags+ pkgDesc <- simplePackageDescription genPkgDesc flags+ (_, extraDocs) <- createSpecFile pkgDesc flags+ unless (null extraDocs) $ do+ putStrLn "Docs not in .cabal packaged:"+ mapM_ putStrLn $ sort extraDocs+ return () -- | 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 :: 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+-- 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 :: 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)+-- 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) -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 })+-- 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 }) -rpmBuild :: GenericPackageDescription -> RpmFlags -> IO ()+-- rpmBuild :: GenericPackageDescription -> RpmFlags -> IO () -rpmBuild genPkgDesc flags = do- tgtPfx <- canonicalizePath (maybe distPref id $ 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 True 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 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) defaultRelease :: UTCTime -> IO String- defaultRelease now = do darcsRepo <- doesDirectoryExist "_darcs" return $ if darcsRepo@@ -167,467 +160,269 @@ else "1" rstrip :: (Char -> Bool) -> String -> String- rstrip p = reverse . dropWhile p . reverse -joinConfigurations :: [(String, Bool)] -> String-joinConfigurations = unwords . map warm- where warm (name, True) = name- warm (name, _) = '-' : name--createSpecFile :: Bool -- ^whether to forcibly create file- -> PackageDescription -- ^info from the .cabal file+createSpecFile :: PackageDescription -- ^info from the .cabal file -> RpmFlags -- ^rpm flags- -> Compiler -- ^compiler details- -> FilePath -- ^directory in which to create file -> IO (FilePath, [FilePath])--createSpecFile force pkgDesc flags compiler tgtPfx = do+createSpecFile pkgDesc flags = do now <- getCurrentTime defRelease <- defaultRelease now let pkg = package pkgDesc verbose = rpmVerbosity flags- origName = pkgName pkg- name = maybe (map toLower origName) id (rpmName flags)- version = maybe ((showVersion . pkgVersion) pkg) id (rpmVersion flags)- release = maybe defRelease id (rpmRelease flags)- specPath = tgtPfx </> name ++ ".spec"- group = "Development/Languages"- buildRoot = "%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)"- cmplrVersion = compilerVersion compiler- doHaddock = rpmHaddock flags && hasLibs pkgDesc- flavor = compilerFlavor compiler- isExec = isExecutable pkgDesc- subPackage = if isExec then "-n %{hsc_name}-%{f_pkg_name}" else ""- (cmplr, runner) <- case flavor of- GHC -> return ("ghc", "runghc")- Hugs -> return ("hugs", "runhugs")- JHC -> return ("jhc", "runjhc")- NHC -> return ("nhc", "runnhc")- (OtherCompiler s) -> return (s, "run" ++ s)- _ -> die $ show flavor ++ " is not supported"- unless force $ do- specAlreadyExists <- doesFileExist specPath- when specAlreadyExists $- die $ "spec file already exists: " ++ specPath- h <- openFile specPath WriteMode- buildReq <- showBuildReq verbose doHaddock compiler pkgDesc- runtimeReq <- showRuntimeReq verbose compiler pkgDesc- let putHdr hdr val = hPutStrLn h (hdr ++ ": " ++ val)- putHdr_ hdr val = when (not $ null val) $- hPutStrLn h (hdr ++ ": " ++ val)- putHdrD hdr val dfl = hPutStrLn h (hdr ++ ": " ++- if null val then dfl else val)+ PackageName packageName = pkgName pkg+ name = fromMaybe (if isExec then packageName else "ghc-" ++ packageName) (rpmName flags)+ pkg_name = if isExec then "%{name}" else "%{pkg_name}"+ version = fromMaybe ((showVersion . pkgVersion) pkg) (rpmVersion flags)+ release = fromMaybe defRelease (rpmRelease flags)+ specPath = name ++ ".spec"+ isExec = hasExes pkgDesc+ isLib = hasLibs pkgDesc+ specAlreadyExists <- doesFileExist specPath+ h <- openFile (specPath ++ if specAlreadyExists then ".cabal-rpm" 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+ putHdrD hdr val dfl = putHdr hdr (if null val then dfl else val) putNewline = hPutStrLn h ""- put s = hPutStrLn h s- putDef v s = put $ "%define " ++ v ++ ' ' : s- putSetup s = put $ runner ++ " Setup " ++ s- date = formatTime defaultTimeLocale "%a %b %d %Y" now- putDef "hsc_name" cmplr- putDef "hsc_version" $ showVersion cmplrVersion- put "#The first one might be upper case, the second one isn't."- putDef "h_pkg_name" origName- putDef "f_pkg_name" name- putDef "pkg_libdir" "%{_libdir}/%{hsc_name}-%{hsc_version}/%{h_pkg_name}-%{version}"- putDef "tar_dir" "%{_builddir}/%{?buildsubdir}"- putNewline- putDef "debug_package" "%{nil}"- put "#Haskell compilers do not traditionally emit DWARF data."+ put = hPutStrLn h+ putDef v s = put $ "%global" +-+ v +-+ s+ date = formatTime defaultTimeLocale "%a %b %e %Y" now++ put "# https://fedoraproject.org/wiki/PackagingDrafts/Haskell" putNewline- - when isExec $ do- putHdr "Name" "%{f_pkg_name}"- unless isExec $ do- putHdr "Name" "%{hsc_name}-%{f_pkg_name}"- putHdr "Version" version- putHdr "Release" $ release ++ "%{?dist}"- putHdr "License" $ (showLicense . license) pkgDesc- putHdr "Group" group- putHdr_ "URL" $ homepage pkgDesc- putHdr "Source" $ tarBallName pkgDesc+ -- Some packages conflate the synopsis and description fields. Ugh. let syn = synopsis pkgDesc (syn', synTooLong) <- case lines syn of (x:_) -> return (x, x /= syn) _ -> do warn verbose "This package has no synopsis."- return ("This package has no synopsis.", False)- let summary = if synTooLong- then syn' ++ " [...]"- else rstrip (== '.') syn'+ return ("Haskell" +-+ packageName +-+ "package", False)+ let common_summary = if synTooLong+ then syn' +-+ "[...]"+ else rstrip (== '.') syn' when synTooLong $- warn verbose "The synopsis for this package spans multiple lines."- putHdrD "Summary" summary "This package has no summary"- putHdr "BuildRoot" buildRoot- putHdr "BuildRequires" buildReq- -- External libraries incur both build-time and runtime- -- dependencies. The latter only need to be made explicit for the- -- built library, as RPM is smart enough to ferret out good- -- dependencies for binaries.- extDeps <- withLib pkgDesc [] (findLibDeps .libBuildInfo)- let extraReq = concat $ intersperse ", " extDeps- putHdr_ "BuildRequires" extraReq- unless isExec $ do- putHdr_ "Requires" extraReq- putHdr_ "Requires" runtimeReq- putHdr "Provides" "%{h_pkg_name}-%{hsc_name}-%{hsc_version} = %{version}"-- putNewline- putNewline+ warn verbose "The synopsis for this package spans multiple lines." - let putDesc = do- put $ if (null . description) pkgDesc+ let common_description = unlines . map (++ "\\") . lines $+ if (null . description) pkgDesc then if synTooLong then syn else "This package does not have a description." else description pkgDesc- put "%description"- putDesc- putNewline- putNewline - {- Compiler-specific library data goes into a package of its own.<-- Unlike a library for a traditional language, the library- packagen depends on the compiler, because when installed, it- has to register itself with the compiler's own package- management system. -}+ when isLib $ do+ putDef "pkg_name" packageName+ putNewline+ putDef "common_summary" common_summary+ putNewline+ putDef "common_description" common_description+ putNewline - when isExec $ withLib pkgDesc () $ \_ -> do- put "%package -n %{hsc_name}-%{f_pkg_name}"- putHdrD "Summary" summary "This library package has no summary"- putHdr "Group" "Development/Libraries"- putHdr "Requires" "%{hsc_name} = %{hsc_version}"- putHdr_ "Requires" extraReq- putHdr_ "Requires" runtimeReq- putHdr "Provides" "%{h_pkg_name}-%{hsc_name}-%{hsc_version} = %{version}"- putNewline- putNewline+ putHdr "Name" (if isExec then (if isLib then "%{pkg_name}" else name) else "ghc-%{pkg_name}")+ putHdr "Version" version+ putHdr "Release" $ release ++ "%{?dist}"+ if isLib+ then putHdr "Summary" "%{common_summary}"+ else putHdrD "Summary" common_summary "This package has no summary"+ 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"+ putNewline+ putHdr "BuildRequires" "ghc-Cabal-devel"+ putHdr "BuildRequires" $ "ghc-rpm-macros" ++ (if isLib then " %{!?without_hscolour:hscolour}" else "") - put "%description -n %{hsc_name}-%{f_pkg_name}"- putDesc- putNewline- put "This package contains libraries for %{hsc_name} %{hsc_version}."- putNewline- putNewline+ put "# Begin cabal-rpm deps:"+ let extDeps = map (nub . showDep) (buildDepends pkgDesc)+ mapM_ (putHdr "BuildRequires" . intercalate ", ") extDeps+ put "# End cabal-rpm deps" - when (rpmLibProf flags) $ do- put "%package -n %{hsc_name}-%{f_pkg_name}-prof"- putHdr "Summary" "Profiling libraries for %{hsc_name}-%{f_pkg_name}"- putHdr "Group" "Development/Libraries"- putHdr "Requires" "%{hsc_name}-%{f_pkg_name} = %{version}"- putHdr "Provides" "%{h_pkg_name}-%{hsc_name}-%{hsc_version}-prof = %{version}"- putNewline- putNewline+ putNewline - put "%description -n %{hsc_name}-%{f_pkg_name}-prof"- putDesc- putNewline- put "This package contains profiling libraries for %{hsc_name} %{hsc_version}."- putNewline- putNewline+ put "%description"+ put $ if isLib then "%{common_description}" else common_description+ putNewline+ putNewline put "%prep"- put $ "%setup -q -n %{h_pkg_name}-%{version}"+ put $ "%setup -q" ++ (if name /= packageName then " -n %{pkg_name}-%{version}" else "") putNewline putNewline put "%build"- put "if [ -f configure.ac -a ! -f configure ]; then autoreconf; fi"- putSetup ("configure --prefix=%{_prefix} --libdir=%{_libdir} " ++- "--docdir=%{_docdir}/%{hsc_name}-%{f_pkg_name}-%{version} " ++- "--libsubdir='$compiler/$pkgid' " ++- (let cfg = rpmConfigurationsFlags flags- in if null cfg- then ""- else "--flags='" ++ joinConfigurations cfg ++ "' ") ++- (if (rpmLibProf flags) then "--enable" else "--disable") ++- "-library-profiling --" ++ cmplr)- withLib pkgDesc () $ \_ -> do- hPutStr h "if "- putSetup "makefile -f cabal-rpm.mk"- put "then"- put " make -f cabal-rpm.mk %{_smp_mflags} || :"- put "fi"- putSetup "build"- withLib pkgDesc () $ \_ -> do- when doHaddock $- putSetup "haddock || :"- putSetup "register --gen-script"- putSetup "unregister --gen-script"+ let pkgType = if isLib then "lib" else "bin"+ put $ "%ghc_" ++ pkgType ++ "_build" putNewline putNewline - docs <- findDocs pkgDesc- put "%install"- put "rm -rf ${RPM_BUILD_ROOT}"- putSetup "copy --destdir=${RPM_BUILD_ROOT}"- withLib pkgDesc () $ \_ -> do- put "install -m 755 register.sh unregister.sh ${RPM_BUILD_ROOT}%{pkg_libdir}"- put "cd ${RPM_BUILD_ROOT}"- put "echo '%defattr(-,root,root,-)' > %{tar_dir}/%{name}-files.prof"- put "find .%{pkg_libdir} \\( -name '*_p.a' -o -name '*.p_hi' \\) | sed s/^.// >> %{tar_dir}/%{name}-files.prof"- put "echo '%defattr(-,root,root,-)' > %{tar_dir}/%{name}-files.nonprof"- put "find .%{pkg_libdir} -type d | sed 's/^./%dir /' >> %{tar_dir}/%{name}-files.nonprof"- put "find .%{pkg_libdir} ! \\( -type d -o -name '*_p.a' -o -name '*.p_hi' \\) | sed s/^.// >> %{tar_dir}/%{name}-files.nonprof"- put "sed 's,^/,%exclude /,' %{tar_dir}/%{name}-files.prof >> %{tar_dir}/%{name}-files.nonprof"- putNewline- put "cd ${RPM_BUILD_ROOT}/%{_datadir}/doc/%{hsc_name}-%{f_pkg_name}-%{version}"- put $ "rm -rf doc " ++ concat (intersperse " " docs)- putNewline- putNewline-- put "%clean"- put "rm -rf ${RPM_BUILD_ROOT}"+ put $ "%ghc_" ++ pkgType ++ "_install" putNewline putNewline - withLib pkgDesc () $ \_ -> do- {- If we're upgrading to a library with the same Cabal- name+version as the currently installed library (i.e. we've- just bumped the release number), we need to unregister the- old library first, so that the register script in %post may- succeed.-- Note that this command runs *before* the new package's- files are installed, and thus will execute the *previous*- version's unregister script, if the script exists in the- same location as the about-to-be-installed library's- script. -}-- put $ "%pre " ++ subPackage- put "[ \"$1\" = 2 ] && %{pkg_libdir}/unregister.sh >&/dev/null || :"- putNewline- putNewline-- put $ "%post " ++ subPackage- put "%{pkg_libdir}/register.sh >&/dev/null"- putNewline- putNewline-- {- We must unregister an old version during an upgrade as- well as during a normal removal, otherwise the Haskell- runtime's package system will be left with a phantom record- for a package it can no longer use. -}-- put $ "%preun " ++ subPackage- put "%{pkg_libdir}/unregister.sh >&/dev/null"- putNewline- putNewline-- {- If we're upgrading, the %preun step may have unregistered- the *new* version of the library (if it had an identical- Cabal name+version, even though the RPM release differs);- therefore, we must attempt to re-register it. -}+ when (isExec && isLib) $ do+ put "%ghc_package"+ putNewline+ put "%ghc_description"+ putNewline+ putNewline - put $ "%postun " ++ subPackage- put "[ \"$1\" = 1 ] && %{pkg_libdir}/register.sh >& /dev/null || :"- putNewline- putNewline+ when isLib $ do+ put "%ghc_devel_package"+ putNewline+ put "%ghc_devel_description"+ putNewline+ putNewline+ put "%ghc_devel_post_postun"+ putNewline+ putNewline - put $ "%files " ++ subPackage ++ " -f %{name}-files.nonprof"- when doHaddock $- put "%doc dist/doc/html"- when ((not . null) docs) $- put $ "%doc " ++ concat (intersperse " " docs)- putNewline- putNewline+ docs <- findDocs pkgDesc - when (rpmLibProf flags) $ do- put "%files -n %{hsc_name}-%{f_pkg_name}-prof -f %{name}-files.prof"- put $ "%%doc " ++ licenseFile pkgDesc- putNewline- putNewline- when isExec $ do put "%files"- put "%defattr(-,root,root,-)"- withExe pkgDesc $ \exe -> put $ "%{_bindir}/" ++ exeName exe- when (((not . null . dataFiles) pkgDesc) && isExec) $- put "%{_datadir}/%{f_pkg_name}-%{version}"+ -- Add the license file to the main package only if it wouldn't+ -- otherwise be empty.+ unless (null $ licenseFile pkgDesc) $+ put $ "%doc" +-+ licenseFile pkgDesc+ unless (null docs) $+ put $ "%doc" +-+ unwords docs - -- Add the license file to the main package only if it wouldn't- -- otherwise be empty.- when ((not . null . licenseFile) pkgDesc &&- isExecutable pkgDesc ||- (not . null . dataFiles) pkgDesc) $- put $ "%doc " ++ licenseFile pkgDesc- putNewline- putNewline+ withExe pkgDesc $ \exe ->+ let program = exeName exe in+ put $ "%{_bindir}/" ++ (if program == packageName then "%{name}" else program)+ unless (null (dataFiles pkgDesc) && isExec) $+ put "%{_datadir}/%{name}-%{version}" + putNewline+ putNewline++ when isLib $ do+ put $ "%ghc_files" +-+ licenseFile pkgDesc+ unless (null docs) $+ put $ "%doc" +-+ unwords docs+ putNewline+ putNewline+ put "%changelog"- put ("* " ++ date ++ " cabal-rpm <cabal-devel@haskell.org> - " ++- version ++ "-" ++ release)- put "- spec file autogenerated by cabal-rpm"+ 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, filter (`notElem` (extraSrcFiles pkgDesc)) docs)+ return (specPath, filter (`notElem` extraSrcFiles pkgDesc) docs) findDocs :: PackageDescription -> IO [FilePath]- findDocs pkgDesc = do contents <- getDirectoryContents "." let docs = filter likely contents- return $ if (null . licenseFile) pkgDesc+ return $ if null lf then docs- else let lf = licenseFile pkgDesc- in lf : filter (/= lf) docs+ else filter unlikely $ filter (/= lf) docs where names = ["author", "copying", "doc", "example", "licence", "license", "readme", "todo"] likely name = let lowerName = map toLower name in any (`isPrefixOf` lowerName) names---- | Take a Haskell package name, and turn it into a "virtual package"--- that encodes the compiler name and version used.--virtualPackage :: Compiler -> String -> String-virtualPackage compiler name = name ++ '-' : compilerNameVersion compiler--compilerNameVersion :: Compiler -> String-compilerNameVersion (Compiler flavour (PackageIdentifier _ version) _) =- name ++ squishedVersion- where name = case flavour of- GHC -> "ghc"- HBC -> "hbc"- Helium -> "helium"- Hugs -> "hugs"- JHC -> "jhc"- NHC -> "nhc"- OtherCompiler c -> c- squishedVersion = (concat . map show . versionBranch) version---- | Convert from license to RPM-friendly description. The strings are--- taken from TagsCheck.py in the rpmlint distribution.+ lf = licenseFile pkgDesc+ unlikely name = not $ any (`isSuffixOf` name) ["~"] showLicense :: License -> String-showLicense GPL = "GPL"-showLicense LGPL = "LGPL"+showLicense (GPL Nothing) = "GPL+"+showLicense (GPL (Just ver)) = "GPLv" ++ show ver ++ "+"+showLicense (LGPL Nothing) = "LGPLv2+"+showLicense (LGPL (Just ver)) = "LGPLv" ++ show ver ++ "+" showLicense BSD3 = "BSD"-showLicense BSD4 = "BSD-like"+showLicense BSD4 = "BSD"+showLicense MIT = "MIT" showLicense PublicDomain = "Public Domain" showLicense AllRightsReserved = "Proprietary"-showLicense OtherLicense = "Non-distributable"+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 -> Compiler -> PackageDescription -> IO String--showRuntimeReq verbose c pkgDesc = do- let externalDeps = filter (not . isBundled c)- (buildDepends pkgDesc)- clauses <- mapM (showRpmReq verbose (virtualPackage c)) externalDeps- return $ (concat . intersperse ", " . concat) clauses---- | Generate a string expressing package build dependencies, but only--- on package/version pairs not already "built into" a compiler--- distribution.--showBuildReq :: Verbosity -> Bool -> Compiler -> PackageDescription- -> IO String+-- showRuntimeReq :: Verbosity -> PackageDescription -> IO String -showBuildReq verbose haddock c pkgDesc = do- cPkg <- case compilerFlavor c of- GHC -> return "ghc"- Hugs -> return "hugs98"- _ -> die $ "cannot deal with compiler " ++ show c- let cVersion = pkgVersion $ compilerId c- myDeps = [Dependency cPkg (ThisVersion cVersion)] ++- if haddock then [Dependency "haddock" AnyVersion] else []- externalDeps = filter (not . isBundled c)- (buildDepends pkgDesc)- exReqs <- mapM (showRpmReq verbose (virtualPackage c)) externalDeps- myReqs <- mapM (showRpmReq verbose id) myDeps- return $ (concat . intersperse ", " . concat) (myReqs ++ exReqs)+-- showRuntimeReq verbose pkgDesc = do+-- let externalDeps = (buildDepends pkgDesc)+-- clauses <- mapM (showRpmReq verbose) externalDeps+-- return $ (commaSep . concat) clauses -- | Represent a dependency in a form suitable for an RPM spec file.--showRpmReq :: Verbosity -> (String -> String) -> Dependency -> IO [String]--showRpmReq _ f (Dependency pkg AnyVersion) =- return [f pkg]-showRpmReq _ f (Dependency pkg (ThisVersion v)) =- return [f pkg ++ " = " ++ showVersion v]-showRpmReq _ f (Dependency pkg (EarlierVersion v)) =- return [f pkg ++ " < " ++ showVersion v]-showRpmReq _ f (Dependency pkg (LaterVersion v)) =- return [f pkg ++ " > " ++ showVersion v]-showRpmReq _ f (Dependency pkg (UnionVersionRanges- (ThisVersion v1)- (LaterVersion v2)))- | v1 == v2 = return [f pkg ++ " >= " ++ showVersion v1]-showRpmReq _ f (Dependency pkg (UnionVersionRanges- (ThisVersion v1)- (EarlierVersion v2)))- | v1 == v2 = return [f pkg ++ " <= " ++ showVersion v1]-showRpmReq verbose f (Dependency pkg (UnionVersionRanges _ _)) = do- warn verbose ("Cannot accurately represent " ++- "dependency on package " ++ f pkg)- warn verbose " (uses version union, which RPM can't handle)"- return [f pkg]-showRpmReq verbose f (Dependency pkg (IntersectVersionRanges r1 r2)) = do- d1 <- showRpmReq verbose f (Dependency pkg r1)- d2 <- showRpmReq verbose f (Dependency pkg r2)- return (d1 ++ d2)+showDep :: Dependency -> [String]+showDep (Dependency (PackageName pkg) range) =+ map (ghc_devel +-+) (renderVersion range)+ where+ renderVersion :: VersionRange -> [String]+ renderVersion = foldVersionRange'+ [""] -- any+ (\ v -> ["=" +-+ showVersion v])+ (\ v -> [">" +-+ showVersion v])+ (\ v -> ["<" +-+ showVersion v])+ (\ v -> [">=" +-+ showVersion v])+ (\ v -> ["<=" +-+ showVersion v])+ (\ x y -> [">=" +-+ showVersion x , "<" +-+ showVersion y])+ (\ _ _ -> [""]) -- rpm can't handle ||+ (++)+ id+ ghc_devel = "ghc-" ++ pkg ++ "-devel" --- | 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]+-- -- | 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+-- 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 :: 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+-- 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 "+-- 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+--findLibDeps :: BuildInfo -> IO [String] -isExecutable :: PackageDescription -> Bool-isExecutable = not . null . executables+--findLibDeps buildInfo = findLibPaths buildInfo >>= mapM findRpmOwner
− src/Distribution/Package/Rpm/Bundled.hs
@@ -1,203 +0,0 @@--- |--- Module : Distribution.Package.Rpm.Bundled--- Copyright : Bryan O'Sullivan 2008------ Maintainer : Bryan O'Sullivan <bos@serpentine.com>--- Stability : alpha--- Portability : portable------ Determine whether a specific version of a Haskell package is--- bundled with into this particular version of the given compiler.---- This software may be used and distributed according to the terms of--- the GNU General Public License, incorporated herein by reference.--module Distribution.Package.Rpm.Bundled- (- bundledWith- , isBundled- ) where--import Data.List (find)-import Data.Version (Version(..))-import Distribution.Simple.Compiler (Compiler(..), CompilerFlavor(..))-import Distribution.Package (PackageIdentifier(..))-import Distribution.Version (Dependency(..), withinRange)---- | List the packages bundled with this version of the given--- compiler. If the answer is not known, return the empty list.-bundledWith :: Compiler -> Maybe [PackageIdentifier]-bundledWith c =- let cv = (compilerFlavor c, pkgVersion $ compilerId c)- in thd `fmap` find (\(n,v,_) -> (n,v) == cv) builtIns- where thd (_,_,x) = x---- | Determine whether a specific version of a Haskell package is--- bundled with into this particular version of the given compiler.-isBundled :: Compiler -> Dependency -> Bool-isBundled c (Dependency pkg version) = maybe False checkVersion $ do- let cv = (compilerFlavor c, pkgVersion $ compilerId c)- (_, _, cb) <- find (\(n, k, _) -> (n,k) == cv) builtIns- pkgVersion `fmap` find ((== pkg) . pkgName) cb- where checkVersion = flip withinRange version--builtIns :: [(CompilerFlavor, Version, [PackageIdentifier])]-builtIns = [- (GHC, Version [6,8,2] [], ghc682BuiltIns)- , (GHC, Version [6,8,1] [], ghc681BuiltIns)- , (GHC, Version [6,6,1] [], ghc661BuiltIns)- , (GHC, Version [6,6] [], ghc66BuiltIns)- ]--v :: String -> [Int] -> PackageIdentifier-v n x = PackageIdentifier n (Version x [])--ghc682BuiltIns :: [PackageIdentifier]-ghc682BuiltIns = [- v "Cabal" [1,2,3,0],- v "GLUT" [2,1,1,1],- v "HUnit" [1,2,0,0],- v "OpenAL" [1,3,1,1],- v "OpenGL" [2,2,1,1],- v "QuickCheck" [1,1,0,0],- v "array" [0,1,0,0],- v "base" [3,0,1,0],- v "bytestring" [0,9,0,1],- v "cgi" [3001,1,5,1],- v "containers" [0,1,0,1],- v "directory" [1,0,0,0],- v "fgl" [5,4,1,1],- v "filepath" [1,1,0,0],- v "haskell-src" [1,0,1,1],- v "haskell98" [1,0,1,0],- v "hpc" [0,5,0,0],- v "html" [1,0,1,1],- v "mtl" [1,1,0,0],- v "network" [2,1,0,0],- v "old-locale" [1,0,0,0],- v "old-time" [1,0,0,0],- v "packedstring" [0,1,0,0],- v "parallel" [1,0,0,0],- v "parsec" [2,1,0,0],- v "pretty" [1,0,0,0],- v "process" [1,0,0,0],- v "random" [1,0,0,0],- v "readline" [1,0,1,0],- v "regex-base" [0,72,0,1],- v "regex-compat" [0,71,0,1],- v "regex-posix" [0,72,0,2],- v "stm" [2,1,1,0],- v "template-haskell" [2,2,0,0],- v "time" [1,1,2,0],- v "unix" [2,3,0,0],- v "xhtml" [3000,0,2,1]- ]--ghc681BuiltIns :: [PackageIdentifier]-ghc681BuiltIns = [- v "base" [3,0,0,0],- v "Cabal" [1,2,2,0],- v "GLUT" [2,1,1,1],- v "HGL" [3,2,0,0],- v "HUnit" [1,2,0,0],- v "OpenAL" [1,3,1,1],- v "OpenGL" [2,2,1,1],- v "QuickCheck" [1,1,0,0],- v "X11" [1,2,3,1],- v "array" [0,1,0,0],- v "bytestring" [0,9,0,1],- v "cgi" [3001,1,5,1],- v "containers" [0,1,0,0],- v "directory" [1,0,0,0],- v "fgl" [5,4,1,1],- v "filepatch" [1,1,0,0],- v "haskell-src" [1,0,1,1],- v "haskell98" [1,0,1,0],- v "hpc" [0,5,0,0],- v "html" [1,0,1,1],- v "mtl" [1,1,0,0],- v "network" [2,1,0,0],- v "old-locale" [1,0,0,0],- v "old-time" [1,0,0,0],- v "packedstring" [0,1,0,0],- v "parallel" [1,0,0,0],- v "parsec" [2,1,0,0],- v "pretty" [1,0,0,0],- v "process" [1,0,0,0],- v "random" [1,0,0,0],- v "readline" [1,0,1,0],- v "regex-base" [0,72,0,1],- v "regex-compat" [0,71,0,1],- v "regex-posix" [0,72,0,1],- v "stm" [2,1,1,0],- v "template-haskell" [2,2,0,0],- v "time" [1,1,2,0],- v "unix" [2,2,0,0],- v "xhtml" [3000,0,2,1]- ]--ghc661BuiltIns :: [PackageIdentifier]-ghc661BuiltIns = [- v "base" [2,1,1],- v "Cabal" [1,1,6,2],- v "cgi" [3001,1,1],- v "fgl" [5,4,1],- v "filepath" [1,0],- v "ghc" [6,6,1],- v "GLUT" [2,1,1],- v "haskell98" [1,0],- v "haskell-src" [1,0,1],- v "HGL" [3,1,1],- v "html" [1,0,1],- v "HUnit" [1,1,1],- v "mtl" [1,0,1],- v "network" [2,0,1],- v "OpenAL" [1,3,1],- v "OpenGL" [2,2,1],- v "parsec" [2,0],- v "QuickCheck" [1,0,1],- v "readline" [1,0],- v "regex-base" [0,72],- v "regex-compat" [0,71],- v "regex-posix" [0,71],- v "rts" [1,0],- v "stm" [2,0],- v "template-haskell" [2,1],- v "time" [1,1,1],- v "unix" [2,1],- v "X11" [1,2,1],- v "xhtml" [3000,0,2]- ]--ghc66BuiltIns :: [PackageIdentifier]-ghc66BuiltIns = [- v "base" [2,0],- v "Cabal" [1,1,6],- v "cgi" [2006,9,6],- v "fgl" [5,2],- v "ghc" [6,6],- v "GLUT" [2,0],- v "haskell98" [1,0],- v "haskell-src" [1,0],- v "HGL" [3,1],- v "html" [1,0],- v "HTTP" [2006,7,7],- v "HUnit" [1,1],- v "mtl" [1,0],- v "network" [2,0],- v "OpenAL" [1,3],- v "OpenGL" [2,1],- v "parsec" [2,0],- v "QuickCheck" [1,0],- v "readline" [1,0],- v "regex-base" [0,71],- v "regex-compat" [0,71],- v "regex-posix" [0,71],- v "rts" [1,0],- v "stm" [2,0],- v "template-haskell" [2,0],- v "time" [1,0],- v "unix" [1,0],- v "X11" [1,1],- v "xhtml" [2006,9,13]- ]
src/Distribution/Package/Rpm/Main.hs view
@@ -2,7 +2,7 @@ -- Module : Distribution.Package.Rpm.Main -- Copyright : Bryan O'Sullivan 2007 ----- Maintainer : Bryan O'Sullivan <bos@serpentine.com>+-- Maintainer : Jens Petersen <petersen@fedoraproject.org> -- Stability : alpha -- Portability : portable --@@ -13,16 +13,47 @@ module Distribution.Package.Rpm.Main where -import Distribution.PackageDescription (readPackageDescription)+import Distribution.PackageDescription.Parse (readPackageDescription) import Distribution.Package.Rpm (rpm) import Distribution.Package.Rpm.Setup (RpmFlags (..), parseArgs)-import Distribution.Simple.Utils (defaultPackageDesc)+import Distribution.Simple.Utils (defaultPackageDesc, findPackageDesc)+import Control.Monad (unless)+import Data.Char (isDigit)+import System.Directory (doesDirectoryExist, doesFileExist) import System.Environment (getArgs)+import System.FilePath.Posix (takeExtension)+import System.Process (readProcess, system) main :: IO ()--main = do opts <- getArgs >>= parseArgs+main = do (opts, args) <- getArgs >>= parseArgs let verbosity = rpmVerbosity opts- descPath <- defaultPackageDesc verbosity+ descPath <- if null args then defaultPackageDesc verbosity else findCabalFile $ head args pkgDesc <- readPackageDescription verbosity descPath rpm pkgDesc opts++findCabalFile :: FilePath -> IO FilePath+findCabalFile path = do+ isdir <- doesDirectoryExist path+ if isdir+ then findPackageDesc path+ else do+ isfile <- doesFileExist path+ if not isfile+ then if '/' `notElem` path+ then tryUnpack path+ else error $ path ++ ": No such file or directory"+ else if takeExtension path /= ".cabal"+ then error $ path ++ ": file should have .cabal extension file."+ else return path++tryUnpack :: String -> IO FilePath+tryUnpack pkg = do+ pkgver <- if isDigit $ last pkg then return pkg+ else do+ pkgs <- readProcess "cabal" ["list", "--simple-output", pkg] []+ return $ last $ lines pkgs+ isdir <- doesDirectoryExist pkgver+ unless isdir $ do+ _ <- system $ "cabal unpack " ++ pkgver+ return ()+ findPackageDesc pkgver
src/Distribution/Package/Rpm/Setup.hs view
@@ -2,7 +2,7 @@ -- Module : Distribution.Package.Rpm.Setup -- Copyright : Bryan O'Sullivan 2007, 2008 ----- Maintainer : Bryan O'Sullivan <bos@serpentine.com>+-- Maintainer : Jens Petersen <petersen@fedoraproject.org> -- Stability : alpha -- Portability : portable --@@ -17,20 +17,20 @@ , parseArgs ) where -import Control.Monad (when)+import Control.Monad (when, unless) import Data.Char (toLower)-import Distribution.Simple.Setup (defaultCompilerFlavor, CompilerFlavor(..))-import Distribution.Verbosity (Verbosity, flagToVerbosity, normal)+-- import Distribution.Simple.Setup+import Distribution.PackageDescription (FlagName(..))+import Distribution.ReadE (readEOrFail)+import Distribution.Verbosity (Verbosity, normal, flagToVerbosity) import System.Console.GetOpt (ArgDescr (..), ArgOrder (..), OptDescr (..), usageInfo, getOpt') import System.Environment (getProgName)-import System.Exit (exitWith, ExitCode (..))-import System.IO (Handle, hPutStrLn, stderr, stdout)+import System.Exit (exitWith, ExitCode (..), exitSuccess)+import System.IO (Handle, hPutStrLn, hPutStr, stderr, stdout) data RpmFlags = RpmFlags- {- rpmCompiler :: Maybe CompilerFlavor- , rpmConfigurationsFlags :: [(String, Bool)]+ { rpmConfigurationsFlags :: [(FlagName, Bool)] , rpmGenSpec :: Bool , rpmHaddock :: Bool , rpmHelp :: Bool@@ -38,7 +38,6 @@ , rpmName :: Maybe String , rpmOptimisation :: Bool , rpmRelease :: Maybe String- , rpmSplitObjs :: Bool , rpmTopDir :: Maybe FilePath , rpmVerbosity :: Verbosity , rpmVersion :: Maybe String@@ -48,9 +47,7 @@ emptyRpmFlags :: RpmFlags emptyRpmFlags = RpmFlags- {- rpmCompiler = defaultCompilerFlavor- , rpmConfigurationsFlags = []+ { rpmConfigurationsFlags = [] , rpmGenSpec = False , rpmHaddock = True , rpmHelp = False@@ -58,7 +55,6 @@ , rpmName = Nothing , rpmOptimisation = True , rpmRelease = Nothing- , rpmSplitObjs = True , rpmTopDir = Nothing , rpmVerbosity = normal , rpmVersion = Nothing@@ -68,14 +64,6 @@ options = [- Option "" ["ghc"] (NoArg (\x -> x { rpmCompiler = Just GHC }))- "Compile with GHC",- Option "" ["hugs"] (NoArg (\x -> x { rpmCompiler = Just Hugs }))- "Compile with Hugs",- Option "" ["jhc"] (NoArg (\x -> x { rpmCompiler = Just JHC }))- "Compile with JHC",- Option "" ["nhc"] (NoArg (\x -> x { rpmCompiler = Just NHC }))- "Compile with NHC", Option "" ["gen-spec"] (NoArg (\x -> x { rpmGenSpec = True })) "Generate a spec file, nothing more", Option "h?" ["help"] (NoArg (\x -> x { rpmHelp = True }))@@ -88,51 +76,50 @@ "Don't generate profiling libraries", Option "" ["disable-optimization"] (NoArg (\x -> x { rpmOptimisation = False })) "Don't generate optimised code",- Option "" ["disable-split-objs"] (NoArg (\x -> x { rpmSplitObjs = False }))- "Don't split object files to save space", 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 = flagToVerbosity (Just verb) }) "n")+ 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" ] -- Lifted from Distribution.Simple.Setup, since it's not exported.-flagList :: String -> [(String, Bool)]+flagList :: String -> [(FlagName, Bool)] flagList = map tagWithValue . words- where tagWithValue ('-':name) = (map toLower name, False)- tagWithValue name = (map toLower name, True)+ where tagWithValue ('-':name) = (FlagName (map toLower name), False)+ tagWithValue name = (FlagName (map toLower name), True) printHelp :: Handle -> IO () printHelp h = do progName <- getProgName- let info = "Usage: " ++ progName ++ " [FLAGS]\n"+ let info = "Usage: " ++ progName ++ " [OPTION]... [PKGPATH]\n" +++ "Generate a RPM .spec file from " +++ "a .cabal file, dir, or package name\n" hPutStrLn h (usageInfo info options) -parseArgs :: [String] -> IO RpmFlags-+parseArgs :: [String] -> IO (RpmFlags, [String]) parseArgs args = do let (os, args', unknown, errs) = getOpt' RequireOrder options args opts = foldl (flip ($)) emptyRpmFlags os when (rpmHelp opts) $ do printHelp stdout- exitWith ExitSuccess- when (not (null errs)) $ do- hPutStrLn stderr "Errors:"+ exitSuccess+ unless (null errs) $ do+ hPutStrLn stderr "Error:" mapM_ (hPutStrLn stderr) errs exitWith (ExitFailure 1)- when (not (null unknown)) $ do- hPutStrLn stderr "Unrecognised options:"- mapM_ (hPutStrLn stderr) unknown+ unless (null unknown) $ do+ hPutStr stderr "Unrecognised options: "+ hPutStrLn stderr $ unwords unknown exitWith (ExitFailure 1)- when (not (null args')) $ do- hPutStrLn stderr "Unrecognised arguments:"- mapM_ (hPutStrLn stderr) args'+ when (length args' > 1) $ do+ hPutStr stderr "Too many arguments: "+ hPutStrLn stderr $ unwords args' exitWith (ExitFailure 1)- return opts+ return (opts, args')