cabal-rpm-0.8.11: src/Commands/RpmBuild.hs
-- |
-- Module : Commands.RpmBuild
-- Copyright : (C) 2007-2008 Bryan O'Sullivan
-- (C) 2012-2014 Jens Petersen
--
-- Maintainer : Jens Petersen <petersen@fedoraproject.org>
-- Stability : alpha
-- Portability : portable
--
-- Explanation: Support for building RPM packages. Can also generate
-- an RPM spec file if you need a basic one to hand-customize.
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
module Commands.RpmBuild (
rpmBuild, RpmStage (..)
) where
import Commands.Spec (createSpecFile)
import FileUtils (fileWithExtension, getDirectoryContents_)
import PackageUtils (isScmDir, missingPackages, packageName, packageVersion)
import Setup (RpmFlags (..))
import SysCmd (runSystem, yumInstall, (+-+))
--import Control.Exception (bracket)
import Control.Monad (filterM, unless, when)
import Distribution.PackageDescription (PackageDescription (..),
hasExes)
--import Distribution.Version (VersionRange, foldVersionRange')
import System.Directory (copyFile, doesFileExist, getCurrentDirectory)
import System.Environment (getEnv)
import System.FilePath (takeDirectory, (</>))
import System.Posix.Files (setFileMode, getFileStatus, fileMode)
-- autoreconf :: Verbosity -> PackageDescription -> IO ()
-- autoreconf verbose pkgDesc = do
-- ac <- doesFileExist "configure.ac"
-- when ac $ do
-- c <- doesFileExist "configure"
-- when (not c) $ do
-- setupMessage verbose "Running autoreconf" pkgDesc
-- runSystem "autoreconf"
data RpmStage = Binary | Source | Prep | BuildDep deriving Eq
rpmBuild :: FilePath -> PackageDescription -> RpmFlags -> RpmStage -> IO ()
rpmBuild cabalPath pkgDesc flags stage = do
-- let verbose = rpmVerbosity flags
-- bracket (setFileCreationMask 0o022) setFileCreationMask $ \ _ -> do
-- autoreconf verbose pkgDesc
mspcfile <- fileWithExtension "." ".spec"
specFile <- case mspcfile of
Just s -> return s
Nothing -> specFileName pkgDesc flags
specFileExists <- doesFileExist specFile
if specFileExists
then putStrLn $ "Using existing" +-+ specFile
else createSpecFile cabalPath pkgDesc flags Nothing
let pkg = package pkgDesc
name = packageName pkg
when (stage `elem` [Binary,BuildDep]) $ do
missing <- missingPackages pkgDesc name
yumInstall missing True
unless (stage == BuildDep) $ do
let version = packageVersion pkg
tarFile = name ++ "-" ++ version ++ ".tar.gz"
rpmCmd = case stage of
Binary -> "a"
Source -> "s"
Prep -> "p"
BuildDep -> "_"
tarFileExists <- doesFileExist tarFile
unless tarFileExists $ do
scmRepo <- isScmDir $ takeDirectory cabalPath
when scmRepo $
error "No tarball for source repo"
cwd <- getCurrentDirectory
copyTarball name version False
runSystem ("rpmbuild -b" ++ rpmCmd +-+
(if stage == Prep then "--nodeps" else "") +-+
"--define \"_rpmdir" +-+ cwd ++ "\"" +-+
"--define \"_srcrpmdir" +-+ cwd ++ "\"" +-+
"--define \"_sourcedir" +-+ cwd ++ "\"" +-+
specFile)
where
copyTarball :: String -> String -> Bool -> IO ()
copyTarball n v ranFetch = do
let tarfile = n ++ "-" ++ v ++ ".tar.gz"
already <- doesFileExist tarfile
unless already $ do
home <- getEnv "HOME"
let cacheparent = home </> ".cabal" </> "packages"
tarpath = n </> v </> tarfile
remotes <- getDirectoryContents_ cacheparent
let paths = map (\ repo -> cacheparent </> repo </> tarpath) remotes
-- if more than one tarball, should maybe warn if they are different
tarballs <- filterM doesFileExist paths
if null tarballs
then if ranFetch
then error $ "No" +-+ tarfile +-+ "found"
else do
runSystem ("cabal fetch -v0 --no-dependencies" +-+ n ++ "-" ++ v)
copyTarball n v True
else do
copyFile (head tarballs) tarfile
-- cabal fetch creates tarballs with mode 0600
stat <- getFileStatus tarfile
when (fileMode stat /= 0o100644) $
setFileMode tarfile 0o0644
specFileName :: PackageDescription -- ^pkg description
-> RpmFlags -- ^rpm flags
-> IO FilePath
specFileName pkgDesc flags = do
let pkg = package pkgDesc
name = packageName pkg
pkgname = if isExec then name else "ghc-" ++ name
isExec = not (rpmLibrary flags) && hasExes pkgDesc
return $ pkgname ++ ".spec"