module Cabal2Spec ( cabal2spec, createSpecFile, ForceBinary, RunTests, CopyrightYear ) where

import Control.Monad
import Data.Char
import Data.List
import Data.Time.Clock
import Data.Time.Format
import Distribution.Compiler
import Distribution.License
import Distribution.Package
import Distribution.PackageDescription
import Distribution.PackageDescription.Configuration
import Distribution.PackageDescription.Parsec
import Distribution.Pretty
import Distribution.System
import Distribution.Text
import Distribution.Types.ComponentRequestedSpec
import Distribution.Types.LegacyExeDependency
import Distribution.Types.PackageDescription
import Distribution.Types.PkgconfigDependency
import Distribution.Types.UnqualComponentName
import Distribution.Utils.ShortText ( fromShortText )
import Distribution.Verbosity
import Distribution.Version
import System.FilePath
import System.IO

type ForceBinary = Bool
type RunTests = Bool
type CopyrightYear = Int

cabal2spec :: Platform -> CompilerId -> FlagAssignment -> ForceBinary -> RunTests -> Maybe CopyrightYear
           -> FilePath -> FilePath -> IO ()
cabal2spec :: Platform
-> CompilerId
-> FlagAssignment
-> ForceBinary
-> ForceBinary
-> Maybe CopyrightYear
-> String
-> String
-> IO ()
cabal2spec Platform
platform CompilerId
compilerId FlagAssignment
flags ForceBinary
forceBinary ForceBinary
runTests Maybe CopyrightYear
copyrightYear String
cabalFile String
specFile = do
  GenericPackageDescription
gpd <- Verbosity -> String -> IO GenericPackageDescription
readGenericPackageDescription Verbosity
silent String
cabalFile
  case FlagAssignment
-> ComponentRequestedSpec
-> (Dependency -> ForceBinary)
-> Platform
-> CompilerInfo
-> [PackageVersionConstraint]
-> GenericPackageDescription
-> Either [Dependency] (PackageDescription, FlagAssignment)
finalizePD FlagAssignment
flags ComponentRequestedSpec
requestedComponents (ForceBinary -> Dependency -> ForceBinary
forall a b. a -> b -> a
const ForceBinary
True) Platform
platform (CompilerId -> AbiTag -> CompilerInfo
unknownCompilerInfo CompilerId
compilerId AbiTag
NoAbiTag) [] GenericPackageDescription
gpd of
    Left [Dependency]
missing -> String -> IO ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"finalizePD: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Dependency] -> String
forall a. Show a => a -> String
show [Dependency]
missing)
    Right (PackageDescription
pd,FlagAssignment
_) -> String
-> PackageDescription
-> ForceBinary
-> ForceBinary
-> FlagAssignment
-> Maybe CopyrightYear
-> IO ()
createSpecFile String
specFile PackageDescription
pd ForceBinary
forceBinary ForceBinary
runTests FlagAssignment
flags Maybe CopyrightYear
copyrightYear

requestedComponents :: ComponentRequestedSpec
requestedComponents :: ComponentRequestedSpec
requestedComponents = ComponentRequestedSpec
defaultComponentRequestedSpec

showPkgCfg :: String -> String
showPkgCfg :: String -> String
showPkgCfg String
p = String
"pkgconfig(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
p String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"

mkTools :: [String] -> [String]
mkTools :: [String] -> [String]
mkTools [String]
tools' = (String -> ForceBinary) -> [String] -> [String]
forall a. (a -> ForceBinary) -> [a] -> [a]
filter String -> ForceBinary
excludedTools ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ [String] -> [String]
forall a. Eq a => [a] -> [a]
nub ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
mapTools [String]
tools'
  where
    excludedTools :: String -> ForceBinary
excludedTools String
n = String
n String -> [String] -> ForceBinary
forall (t :: * -> *) a.
(Foldable t, Eq a) =>
a -> t a -> ForceBinary
`notElem` [String
"ghc", String
"hsc2hs", String
"perl"]
    mapTools :: String -> String
mapTools String
"gtk2hsC2hs" = String
"gtk2hs-buildtools"
    mapTools String
"gtk2hsHookGenerator" = String
"gtk2hs-buildtools"
    mapTools String
"gtk2hsTypeGen" = String
"gtk2hs-buildtools"
    mapTools String
tool = String
tool

createSpecFile :: FilePath -> PackageDescription -> ForceBinary -> RunTests -> FlagAssignment -> Maybe CopyrightYear -> IO ()
createSpecFile :: String
-> PackageDescription
-> ForceBinary
-> ForceBinary
-> FlagAssignment
-> Maybe CopyrightYear
-> IO ()
createSpecFile String
specFile PackageDescription
pkgDesc ForceBinary
forceBinary ForceBinary
runTests FlagAssignment
flagAssignment Maybe CopyrightYear
copyrightYear = do
  let deps :: [String]
      deps :: [String]
deps = (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
showDep [String]
deps'
      deps' :: [String]
      selfdep :: Bool
      ([String]
deps', ForceBinary
selfdep) = PackageDescription -> String -> ([String], ForceBinary)
buildDependencies PackageDescription
pkgDesc String
name
      pkgcfgs :: [String]
      pkgcfgs :: [String]
pkgcfgs = (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
showPkgCfg ([String] -> [String]
forall a. Eq a => [a] -> [a]
nub ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ (PkgconfigDependency -> String)
-> [PkgconfigDependency] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map PkgconfigDependency -> String
forall a. IsDependency a => a -> String
depName ([PkgconfigDependency] -> [String])
-> [PkgconfigDependency] -> [String]
forall a b. (a -> b) -> a -> b
$ (BuildInfo -> [PkgconfigDependency])
-> [BuildInfo] -> [PkgconfigDependency]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap BuildInfo -> [PkgconfigDependency]
pkgconfigDepends [BuildInfo]
buildinfo)
      buildinfo :: [BuildInfo]
      buildinfo :: [BuildInfo]
buildinfo = PackageDescription -> ComponentRequestedSpec -> [BuildInfo]
enabledBuildInfos PackageDescription
pkgDesc ComponentRequestedSpec
requestedComponents
      tools :: [String]
      tools :: [String]
tools = [String] -> [String]
mkTools ([String] -> [String]
forall a. Eq a => [a] -> [a]
nub ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ (LegacyExeDependency -> String)
-> [LegacyExeDependency] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map LegacyExeDependency -> String
forall a. IsDependency a => a -> String
depName ((BuildInfo -> [LegacyExeDependency])
-> [BuildInfo] -> [LegacyExeDependency]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap BuildInfo -> [LegacyExeDependency]
buildTools [BuildInfo]
buildinfo)) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
chrpath
      clibs :: [String]
      clibs :: [String]
clibs = [String] -> [String]
forall a. Eq a => [a] -> [a]
nub ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
resolveLib ((BuildInfo -> [String]) -> [BuildInfo] -> [String]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap BuildInfo -> [String]
extraLibs [BuildInfo]
buildinfo))
      chrpath :: [String]
      chrpath :: [String]
chrpath = [String
"chrpath" | ForceBinary
selfdep]

      pkg :: PackageIdentifier
pkg = PackageDescription -> PackageIdentifier
package PackageDescription
pkgDesc
      name :: String
name = PackageName -> String
unPackageName (PackageIdentifier -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName PackageIdentifier
pkg)
      hasExec :: ForceBinary
hasExec = PackageDescription -> ForceBinary
hasExes PackageDescription
pkgDesc
      hasLib :: ForceBinary
hasLib = PackageDescription -> ForceBinary
hasLibs PackageDescription
pkgDesc
      hasSubLib :: ForceBinary
hasSubLib = ForceBinary -> ForceBinary
not ([Library] -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null (PackageDescription -> [Library]
subLibraries PackageDescription
pkgDesc))
      hasPublicModules :: ForceBinary
hasPublicModules = ForceBinary
-> (Library -> ForceBinary) -> Maybe Library -> ForceBinary
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ForceBinary
False (ForceBinary -> ForceBinary
not (ForceBinary -> ForceBinary)
-> (Library -> ForceBinary) -> Library -> ForceBinary
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ModuleName] -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null ([ModuleName] -> ForceBinary)
-> (Library -> [ModuleName]) -> Library -> ForceBinary
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Library -> [ModuleName]
exposedModules) (PackageDescription -> Maybe Library
library PackageDescription
pkgDesc)
  (String
pkgname, ForceBinary
binlib) <- Maybe String
-> PackageDescription -> ForceBinary -> IO (String, ForceBinary)
getPkgName (String -> Maybe String
forall a. a -> Maybe a
Just String
specFile) PackageDescription
pkgDesc ForceBinary
forceBinary

  let pkg_name :: String
pkg_name = if String
pkgname String -> String -> ForceBinary
forall a. Eq a => a -> a -> ForceBinary
== String
name then String
"%{name}" else String
"%{pkg_name}"
      basename :: String
basename | ForceBinary
binlib = String
"%{pkg_name}"
               | ForceBinary
hasExecPkg = String
name
               | ForceBinary
otherwise = String
"ghc-%{pkg_name}"

      hasExecPkg :: ForceBinary
hasExecPkg = ForceBinary
binlib ForceBinary -> ForceBinary -> ForceBinary
|| (ForceBinary
hasExec ForceBinary -> ForceBinary -> ForceBinary
&& ForceBinary -> ForceBinary
not ForceBinary
hasLib)
  -- run commands before opening file to prevent empty file on error
  -- maybe shell commands should be in a monad or something

      testsuiteDeps :: [String]
testsuiteDeps = PackageDescription -> String -> [String]
testsuiteDependencies PackageDescription
pkgDesc String
name

  Handle
h <- String -> IOMode -> IO Handle
openFile String
specFile IOMode
WriteMode
  let putHdr :: String -> String -> IO ()
putHdr String
hdr String
val = Handle -> String -> IO ()
hPutStrLn Handle
h (String
hdr String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall {t :: * -> *} {a}. Foldable t => t a -> String
padding String
hdr String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
val)
      padding :: t a -> String
padding t a
hdr = CopyrightYear -> Char -> String
forall a. CopyrightYear -> a -> [a]
replicate (CopyrightYear
14 CopyrightYear -> CopyrightYear -> CopyrightYear
forall a. Num a => a -> a -> a
- t a -> CopyrightYear
forall (t :: * -> *) a. Foldable t => t a -> CopyrightYear
length t a
hdr) Char
' ' String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" "
      putNewline :: IO ()
putNewline = Handle -> String -> IO ()
hPutStrLn Handle
h String
""
      put :: String -> IO ()
put = Handle -> String -> IO ()
hPutStrLn Handle
h
      putDef :: String -> String -> IO ()
putDef String
v String
s = String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%global" String -> String -> String
+-+ String
v String -> String -> String
+-+ String
s
      ghcPkg :: String
ghcPkg = if ForceBinary
binlib then String
"-n ghc-%{name}" else String
""
      ghcPkgDevel :: String
ghcPkgDevel = if ForceBinary
binlib then String
"-n ghc-%{name}-devel" else String
"devel"

  do
    String
year <- case Maybe CopyrightYear
copyrightYear of
              Just CopyrightYear
y -> String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return (CopyrightYear -> String
forall a. Show a => a -> String
show CopyrightYear
y)
              Maybe CopyrightYear
Nothing -> TimeLocale -> String -> UTCTime -> String
forall t. FormatTime t => TimeLocale -> String -> t -> String
formatTime TimeLocale
defaultTimeLocale String
"%Y" (UTCTime -> String) -> IO UTCTime -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO UTCTime
getCurrentTime
    String -> IO ()
put String
"#"
    String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"# spec file for package " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pkgname
    String -> IO ()
put String
"#"
    String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"# Copyright (c) " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
year String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" SUSE LLC"
    String -> IO ()
put String
"#"
    String -> IO ()
put String
"# All modifications and additions to the file contributed by third parties"
    String -> IO ()
put String
"# remain the property of their copyright owners, unless otherwise agreed"
    String -> IO ()
put String
"# upon. The license for this file, and modifications and additions to the"
    String -> IO ()
put String
"# file, is the same license as for the pristine package itself (unless the"
    String -> IO ()
put String
"# license for the pristine package is not an Open Source License, in which"
    String -> IO ()
put String
"# case the license is the MIT License). An \"Open Source License\" is a"
    String -> IO ()
put String
"# license that conforms to the Open Source Definition (Version 1.9)"
    String -> IO ()
put String
"# published by the Open Source Initiative."
    IO ()
putNewline
    String -> IO ()
put String
"# Please submit bugfixes or comments via http://bugs.opensuse.org/"
    String -> IO ()
put String
"#"
  IO ()
putNewline
  IO ()
putNewline

  -- Some packages conflate the synopsis and description fields.  Ugh.
  let syn :: String
syn = ShortText -> String
fromShortText (PackageDescription -> ShortText
synopsis PackageDescription
pkgDesc)
  let initialCapital :: String -> String
initialCapital (Char
c:String
cs) = Char -> Char
toUpper Char
cChar -> String -> String
forall a. a -> [a] -> [a]
:String
cs
      initialCapital [] = []
  let syn' :: String
syn' = if String -> ForceBinary
badDescription String
syn then String
"FIXME" else ([String] -> String
unwords ([String] -> String) -> (String -> [String]) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
lines (String -> [String]) -> (String -> String) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
initialCapital) String
syn
  let summary :: String
summary = (Char -> ForceBinary) -> String -> String
rstrip (Char -> Char -> ForceBinary
forall a. Eq a => a -> a -> ForceBinary
== Char
'.') (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> ForceBinary) -> String -> String
rstrip Char -> ForceBinary
isSpace (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
syn'
  let descr :: String
descr = (Char -> ForceBinary) -> String -> String
rstrip Char -> ForceBinary
isSpace (ShortText -> String
fromShortText (PackageDescription -> ShortText
description PackageDescription
pkgDesc))
  let descLines :: [String]
descLines = (String -> [String]
formatParagraphs (String -> [String]) -> (String -> String) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
initialCapital (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
filterSymbols (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
finalPeriod) (String -> [String]) -> String -> [String]
forall a b. (a -> b) -> a -> b
$ if String -> ForceBinary
badDescription String
descr then String
syn' else String
descr
      finalPeriod :: String -> String
finalPeriod String
cs = if String -> Char
forall a. [a] -> a
last String
cs Char -> Char -> ForceBinary
forall a. Eq a => a -> a -> ForceBinary
== Char
'.' then String
cs else String
cs String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"."
      filterSymbols :: String -> String
filterSymbols (Char
c:String
cs) =
        if Char
c Char -> String -> ForceBinary
forall (t :: * -> *) a.
(Foldable t, Eq a) =>
a -> t a -> ForceBinary
`notElem` String
"@\\" then Char
cChar -> String -> String
forall a. a -> [a] -> [a]
: String -> String
filterSymbols String
cs
        else case Char
c of
          Char
'@' -> Char
'\''Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
filterSymbols String
cs
          Char
'\\' -> String -> Char
forall a. [a] -> a
head String
csChar -> String -> String
forall a. a -> [a] -> [a]
: String -> String
filterSymbols (String -> String
forall a. [a] -> [a]
tail String
cs)
          Char
_ -> Char
cChar -> String -> String
forall a. a -> [a] -> [a]
: String -> String
filterSymbols String
cs
      filterSymbols [] = []
  ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
when ForceBinary
hasLib (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
    String -> String -> IO ()
putDef String
"pkg_name" String
name

  ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
when ForceBinary
hasSubLib (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
    String -> String -> IO ()
putDef String
"has_internal_sub_libraries" String
"1"

  ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
unless ([String] -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null [String]
testsuiteDeps) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
    if ForceBinary
runTests
       then String -> IO ()
put String
"%bcond_without tests"
       else String -> IO ()
put String
"%bcond_with tests"

  let version :: Version
version = PackageIdentifier -> Version
forall pkg. Package pkg => pkg -> Version
packageVersion PackageIdentifier
pkg
      revision :: String
revision = CopyrightYear -> String
forall a. Show a => a -> String
show (CopyrightYear -> String) -> CopyrightYear -> String
forall a b. (a -> b) -> a -> b
$ CopyrightYear
-> (String -> CopyrightYear) -> Maybe String -> CopyrightYear
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (CopyrightYear
0::Int) String -> CopyrightYear
forall a. Read a => String -> a
read (String -> [(String, String)] -> Maybe String
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
"x-revision" (PackageDescription -> [(String, String)]
customFieldsPD PackageDescription
pkgDesc))
  String -> String -> IO ()
putHdr String
"Name" (if ForceBinary
binlib then String
"%{pkg_name}" else String
basename)
  String -> String -> IO ()
putHdr String
"Version" (Version -> String
forall a. Pretty a => a -> String
display Version
version)
  String -> String -> IO ()
putHdr String
"Release" String
"0"
  String -> String -> IO ()
putHdr String
"Summary" String
summary
  String -> String -> IO ()
putHdr String
"License" (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ (License -> String)
-> (License -> String) -> Either License License -> String
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Doc -> String
forall a. Show a => a -> String
show (Doc -> String) -> (License -> Doc) -> License -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. License -> Doc
forall a. Pretty a => a -> Doc
pretty) License -> String
showLicense (PackageDescription -> Either License License
licenseRaw PackageDescription
pkgDesc)
  String -> String -> IO ()
putHdr String
"URL" (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"https://hackage.haskell.org/package/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pkg_name
  String -> String -> IO ()
putHdr String
"Source0" (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"https://hackage.haskell.org/package/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pkg_name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-%{version}/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pkg_name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-%{version}.tar.gz"
  ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
when (String
revision String -> String -> ForceBinary
forall a. Eq a => a -> a -> ForceBinary
/= String
"0") (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
    String -> String -> IO ()
putHdr String
"Source1" (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"https://hackage.haskell.org/package/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pkg_name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-%{version}/revision/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
revision String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".cabal#/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pkg_name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".cabal"

  let fixedDeps :: [String]
fixedDeps = [String
"ghc-Cabal-devel", String
"ghc-rpm-macros"]
  let alldeps :: [String]
alldeps = [String] -> [String]
forall a. Ord a => [a] -> [a]
sort ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ [String]
fixedDeps [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
deps [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
tools [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
clibs [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
pkgcfgs [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String
"pkgconfig" | ForceBinary -> ForceBinary
not ([String] -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null [String]
pkgcfgs)]
  let extraTestDeps :: [String]
extraTestDeps = [String] -> [String]
forall a. Ord a => [a] -> [a]
sort ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ [String]
testsuiteDeps [String] -> [String] -> [String]
forall a. Eq a => [a] -> [a] -> [a]
\\ [String]
deps
  ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
unless ([String] -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null ([String] -> ForceBinary) -> [String] -> ForceBinary
forall a b. (a -> b) -> a -> b
$ [String]
alldeps [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
extraTestDeps) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
    (String -> IO ()) -> [String] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String -> String -> IO ()
putHdr String
"BuildRequires") [String]
alldeps
    ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
unless ([String] -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null [String]
extraTestDeps) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
      String -> IO ()
put String
"%if %{with tests}"
      (String -> IO ()) -> [String] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String -> String -> IO ()
putHdr String
"BuildRequires") [String]
extraTestDeps
      String -> IO ()
put String
"%endif"

  IO ()
putNewline

  String -> IO ()
put String
"%description"
  (String -> IO ()) -> [String] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ String -> IO ()
put [String]
descLines

  let wrapGenDesc :: String -> String
wrapGenDesc = CopyrightYear -> String -> String
wordwrap (CopyrightYear
79 CopyrightYear -> CopyrightYear -> CopyrightYear
forall a. Num a => a -> a -> a
- CopyrightYear -> CopyrightYear -> CopyrightYear
forall a. Ord a => a -> a -> a
max CopyrightYear
0 (String -> CopyrightYear
forall (t :: * -> *) a. Foldable t => t a -> CopyrightYear
length String
pkgname CopyrightYear -> CopyrightYear -> CopyrightYear
forall a. Num a => a -> a -> a
- String -> CopyrightYear
forall (t :: * -> *) a. Foldable t => t a -> CopyrightYear
length String
pkg_name))

  ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
when ForceBinary
hasLib (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
    ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
when ForceBinary
binlib (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
      String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%package" String -> String -> String
+-+ String
ghcPkg
      String -> String -> IO ()
putHdr String
"Summary" (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Haskell" String -> String -> String
+-+ String
pkg_name String -> String -> String
+-+ String
"library"
      IO ()
putNewline
      String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%description" String -> String -> String
+-+ String
ghcPkg
      String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> String
wrapGenDesc (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
"This package provides the Haskell" String -> String -> String
+-+ String
pkg_name String -> String -> String
+-+ String
"shared library."
    String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%package" String -> String -> String
+-+ String
ghcPkgDevel
    String -> String -> IO ()
putHdr String
"Summary" (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Haskell" String -> String -> String
+-+ String
pkg_name String -> String -> String
+-+ String
"library development files"
    String -> String -> IO ()
putHdr String
"Requires" (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ (if ForceBinary
binlib then String
"ghc-%{name}" else String
"%{name}") String -> String -> String
+-+ String
"= %{version}-%{release}"
    String -> String -> IO ()
putHdr String
"Requires" String
"ghc-compiler = %{ghc_version}"
    ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
unless ([String] -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null ([String] -> ForceBinary) -> [String] -> ForceBinary
forall a b. (a -> b) -> a -> b
$ [String]
clibs [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
pkgcfgs) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
      (String -> IO ()) -> [String] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String -> String -> IO ()
putHdr String
"Requires") ([String] -> IO ()) -> [String] -> IO ()
forall a b. (a -> b) -> a -> b
$ [String] -> [String]
forall a. Ord a => [a] -> [a]
sort ([String]
clibs [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
pkgcfgs [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String
"pkgconfig" | ForceBinary -> ForceBinary
not ([String] -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null [String]
pkgcfgs)])
    String -> String -> IO ()
putHdr String
"Requires(post)" String
"ghc-compiler = %{ghc_version}"
    String -> String -> IO ()
putHdr String
"Requires(postun)" String
"ghc-compiler = %{ghc_version}"
    IO ()
putNewline
    String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%description" String -> String -> String
+-+ String
ghcPkgDevel
    String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> String
wrapGenDesc (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
"This package provides the Haskell" String -> String -> String
+-+ String
pkg_name String -> String -> String
+-+ String
"library development files."

  String -> IO ()
put String
"%prep"
  String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%autosetup" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (if String
pkgname String -> String -> ForceBinary
forall a. Eq a => a -> a -> ForceBinary
/= String
name then String
" -n %{pkg_name}-%{version}" else String
"")
  ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
when (String
revision String -> String -> ForceBinary
forall a. Eq a => a -> a -> ForceBinary
/= String
"0") (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
    String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"cp -p %{SOURCE1}" String -> String -> String
+-+ String
pkg_name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".cabal"
  IO ()
putNewline

  String -> IO ()
put String
"%build"
  ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
when (FlagAssignment
flagAssignment FlagAssignment -> FlagAssignment -> ForceBinary
forall a. Eq a => a -> a -> ForceBinary
/= FlagAssignment
forall a. Monoid a => a
mempty) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
    let cabalFlags :: [String]
cabalFlags = [ String
"-f" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (if ForceBinary
b then String
"" else String
"-") String -> String -> String
forall a. [a] -> [a] -> [a]
++ FlagName -> String
unFlagName FlagName
n | (FlagName
n, ForceBinary
b) <- FlagAssignment -> [(FlagName, ForceBinary)]
unFlagAssignment FlagAssignment
flagAssignment ]
    String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%define cabal_configure_options " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [String] -> String
unwords ([String] -> [String]
forall a. Ord a => [a] -> [a]
sort [String]
cabalFlags)
  let pkgType :: String
pkgType = if ForceBinary
hasLib then String
"lib" else String
"bin"
      noHaddockModifier :: String
noHaddockModifier = if ForceBinary
hasSubLib ForceBinary -> ForceBinary -> ForceBinary
|| (ForceBinary
hasLib ForceBinary -> ForceBinary -> ForceBinary
&& ForceBinary -> ForceBinary
not ForceBinary
hasPublicModules) then String
"_without_haddock" else String
""
  String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%ghc_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pkgType String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"_build" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
noHaddockModifier -- https://github.com/haskell/cabal/issues/4969
  IO ()
putNewline

  String -> IO ()
put String
"%install"
  String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%ghc_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pkgType String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"_install"

  ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
when ForceBinary
selfdep (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
    String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%ghc_fix_rpath" String -> String -> String
+-+ String
"%{pkg_name}-%{version}"

  let licensefiles :: [String]
licensefiles = PackageDescription -> [String]
licenseFiles PackageDescription
pkgDesc

  -- remove docs from datafiles (#38)
  [String]
docsUnfiltered <- ([String] -> [String]) -> IO [String] -> IO [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [String] -> [String]
forall a. Ord a => [a] -> [a]
sort ([String] -> [String] -> IO [String]
findDocs (PackageDescription -> [String]
extraSrcFiles PackageDescription
pkgDesc [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ PackageDescription -> [String]
extraDocFiles PackageDescription
pkgDesc) [String]
licensefiles)
  let datafiles :: [String]
datafiles = PackageDescription -> [String]
dataFiles PackageDescription
pkgDesc
      dupdocs :: [String]
dupdocs   = [String]
docsUnfiltered [String] -> [String] -> [String]
forall a. Eq a => [a] -> [a] -> [a]
`intersect` [String]
datafiles
      docs :: [String]
docs      = [String]
docsUnfiltered [String] -> [String] -> [String]
forall a. Eq a => [a] -> [a] -> [a]
\\ [String]
datafiles
  ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
unless ([String] -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null [String]
dupdocs) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
    -- TODO: What does this warning accomplish?
    String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"*** " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pkgname String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": doc files found in datadir:" String -> String -> String
+-+ [String] -> String
unwords ([String] -> [String]
forall a. Ord a => [a] -> [a]
sort [String]
dupdocs)
  IO ()
putNewline

  ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
unless ([String] -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null [String]
testsuiteDeps) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
    String -> IO ()
put String
"%check"
    String -> IO ()
put String
"%cabal_test"
    IO ()
putNewline

  ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
when ForceBinary
hasLib (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
    let putInstallScript :: IO ()
putInstallScript = do
          String -> IO ()
put String
"%ghc_pkg_recache"
          IO ()
putNewline
    String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%post" String -> String -> String
+-+ String
ghcPkgDevel
    IO ()
putInstallScript
    String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%postun" String -> String -> String
+-+ String
ghcPkgDevel
    IO ()
putInstallScript

  let license_macro :: String
license_macro = String
"%license"
  let execs :: [String]
      execs :: [String]
execs = [String] -> [String]
forall a. Ord a => [a] -> [a]
sort ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ (Executable -> String) -> [Executable] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (UnqualComponentName -> String
unUnqualComponentName (UnqualComponentName -> String)
-> (Executable -> UnqualComponentName) -> Executable -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Executable -> UnqualComponentName
exeName) ([Executable] -> [String]) -> [Executable] -> [String]
forall a b. (a -> b) -> a -> b
$ (Executable -> ForceBinary) -> [Executable] -> [Executable]
forall a. (a -> ForceBinary) -> [a] -> [a]
filter Executable -> ForceBinary
isBuildable ([Executable] -> [Executable]) -> [Executable] -> [Executable]
forall a b. (a -> b) -> a -> b
$ PackageDescription -> [Executable]
executables PackageDescription
pkgDesc

  let listDataFiles :: IO ()
listDataFiles = ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
unless ([String] -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null (PackageDescription -> [String]
dataFiles PackageDescription
pkgDesc)) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
                        String -> IO ()
put (String
"%dir %{_datadir}/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pkg_name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-%{version}")
                        (String -> IO ()) -> [String] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String -> IO ()
put (String -> IO ()) -> (String -> String) -> String -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String
"%dir %{_datadir}/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pkg_name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-%{version}/")String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
avoidSquareBrackets) ([String] -> [String]
forall a. Ord a => [a] -> [a]
sort ([String] -> [String]
listDirs (PackageDescription -> [String]
dataFiles PackageDescription
pkgDesc)))
                        (String -> IO ()) -> [String] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String -> IO ()
put (String -> IO ()) -> (String -> String) -> String -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String
"%{_datadir}/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pkg_name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-%{version}/")String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
avoidSquareBrackets) ([String] -> [String]
forall a. Ord a => [a] -> [a]
sort (PackageDescription -> [String]
dataFiles PackageDescription
pkgDesc))

      listDirs :: [FilePath] -> [FilePath]
      listDirs :: [String] -> [String]
listDirs = [String] -> [String]
forall a. Eq a => [a] -> [a]
nub ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String] -> [String]) -> [[String]] -> [String]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (([String] -> String) -> [[String]] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map [String] -> String
joinPath ([[String]] -> [String])
-> ([String] -> [[String]]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[String]] -> [[String]]
forall a. [a] -> [a]
tail ([[String]] -> [[String]])
-> ([String] -> [[String]]) -> [String] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [[String]]
forall a. [a] -> [[a]]
inits) ([[String]] -> [String])
-> ([String] -> [[String]]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[String]] -> [[String]]
forall a. Eq a => [a] -> [a]
nub ([[String]] -> [[String]])
-> ([String] -> [[String]]) -> [String] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String] -> [String]) -> [[String]] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map [String] -> [String]
forall a. [a] -> [a]
init ([[String]] -> [[String]])
-> ([String] -> [[String]]) -> [String] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String] -> ForceBinary) -> [[String]] -> [[String]]
forall a. (a -> ForceBinary) -> [a] -> [a]
filter (\[String]
p -> [String] -> CopyrightYear
forall (t :: * -> *) a. Foldable t => t a -> CopyrightYear
length [String]
p CopyrightYear -> CopyrightYear -> ForceBinary
forall a. Ord a => a -> a -> ForceBinary
> CopyrightYear
1) ([[String]] -> [[String]])
-> ([String] -> [[String]]) -> [String] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> [String]) -> [String] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map String -> [String]
splitDirectories

  ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
when ForceBinary
hasExecPkg (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
    String -> IO ()
put String
"%files"
    -- Add the license file to the main package only if it wouldn't
    -- otherwise be empty.
    (String -> IO ()) -> [String] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\ String
l -> String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
license_macro String -> String -> String
+-+ String
l) ([String] -> [String]
forall a. Ord a => [a] -> [a]
sort [String]
licensefiles)
    ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
unless ([String] -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null [String]
docs) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
      String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%doc" String -> String -> String
+-+ [String] -> String
unwords ([String] -> [String]
forall a. Ord a => [a] -> [a]
sort [String]
docs)
    (String -> IO ()) -> [String] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\ String
p -> String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%{_bindir}/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (if String
p String -> String -> ForceBinary
forall a. Eq a => a -> a -> ForceBinary
== String
name then String
"%{name}" else String
p)) ([String] -> [String]
forall a. Ord a => [a] -> [a]
sort [String]
execs)
    IO ()
listDataFiles
    IO ()
putNewline

  ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
when ForceBinary
hasLib (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
    let baseFiles :: String
baseFiles = if ForceBinary
binlib then String
"-f ghc-%{name}.files" else String
"-f %{name}.files"
        develFiles :: String
develFiles = if ForceBinary
binlib then String
"-f ghc-%{name}-devel.files" else String
"-f %{name}-devel.files"
    String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%files" String -> String -> String
+-+ String
ghcPkg String -> String -> String
+-+ String
baseFiles
    (String -> IO ()) -> [String] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\ String
l -> String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
license_macro String -> String -> String
+-+ String
l) [String]
licensefiles
    ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
unless ForceBinary
binlib (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
      (String -> IO ()) -> [String] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\ String
p -> String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%{_bindir}/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (if String
p String -> String -> ForceBinary
forall a. Eq a => a -> a -> ForceBinary
== String
name then String
"%{pkg_name}" else String
p)) ([String] -> [String]
forall a. Ord a => [a] -> [a]
sort [String]
execs)
    ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
unless ForceBinary
hasExecPkg IO ()
listDataFiles
    IO ()
putNewline
    String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%files" String -> String -> String
+-+ String
ghcPkgDevel String -> String -> String
+-+ String
develFiles
    ForceBinary -> IO () -> IO ()
forall (f :: * -> *). Applicative f => ForceBinary -> f () -> f ()
unless ([String] -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null [String]
docs) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
      String -> IO ()
put (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"%doc" String -> String -> String
+-+ [String] -> String
unwords ([String] -> [String]
forall a. Ord a => [a] -> [a]
sort [String]
docs)
    IO ()
putNewline

  String -> IO ()
put String
"%changelog"
  Handle -> IO ()
hClose Handle
h


isBuildable :: Executable -> Bool
isBuildable :: Executable -> ForceBinary
isBuildable Executable
exe = BuildInfo -> ForceBinary
buildable (BuildInfo -> ForceBinary) -> BuildInfo -> ForceBinary
forall a b. (a -> b) -> a -> b
$ Executable -> BuildInfo
buildInfo Executable
exe

findDocs :: [FilePath] -> [FilePath] -> IO [FilePath]
findDocs :: [String] -> [String] -> IO [String]
findDocs [String]
contents [String]
licensefiles = do
  let docs :: [String]
docs = (String -> ForceBinary) -> [String] -> [String]
forall a. (a -> ForceBinary) -> [a] -> [a]
filter String -> ForceBinary
likely ([String] -> [String]
forall a. Ord a => [a] -> [a]
sort ([String] -> [String]
forall a. Eq a => [a] -> [a]
nub ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ([String] -> String
forall a. [a] -> a
head ([String] -> String) -> (String -> [String]) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
splitDirectories) [String]
contents)))
  [String] -> IO [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> IO [String]) -> [String] -> IO [String]
forall a b. (a -> b) -> a -> b
$ if [String] -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null [String]
licensefiles
           then [String]
docs
           else (String -> ForceBinary) -> [String] -> [String]
forall a. (a -> ForceBinary) -> [a] -> [a]
filter (String -> [String] -> ForceBinary
forall (t :: * -> *) a.
(Foldable t, Eq a) =>
a -> t a -> ForceBinary
`notElem` [String]
licensefiles) [String]
docs
  where names :: [String]
names = [String
"author", String
"changelog", String
"changes", String
"contributors", String
"copying", String
"doc",
                 String
"example", String
"licence", String
"license", String
"news", String
"readme", String
"todo"]
        likely :: String -> ForceBinary
likely String
name = let lowerName :: String
lowerName = (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
name
                      in (String -> ForceBinary) -> [String] -> ForceBinary
forall (t :: * -> *) a.
Foldable t =>
(a -> ForceBinary) -> t a -> ForceBinary
any (String -> String -> ForceBinary
forall a. Eq a => [a] -> [a] -> ForceBinary
`isPrefixOf` String
lowerName) [String]
names

normalizeVersion :: Version -> Version
normalizeVersion :: Version -> Version
normalizeVersion Version
v = case Version -> [CopyrightYear]
versionNumbers Version
v of
                       [CopyrightYear
i] -> [CopyrightYear] -> Version
mkVersion [CopyrightYear
i,CopyrightYear
0]
                       [CopyrightYear]
_   -> Version
v

showLicense :: License -> String
showLicense :: License -> String
showLicense (GPL Maybe Version
Nothing) = String
"GPL-1.0-or-later"
showLicense (GPL (Just Version
ver)) = String
"GPL-" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Version -> String
forall a. Pretty a => a -> String
display (Version -> Version
normalizeVersion Version
ver) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-or-later"
showLicense (LGPL Maybe Version
Nothing) = String
"LGPL-2.0-or-later"
showLicense (LGPL (Just Version
ver)) = String
"LGPL-" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Version -> String
forall a. Pretty a => a -> String
display (Version -> Version
normalizeVersion Version
ver) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-or-later"
showLicense License
BSD3 = String
"BSD-3-Clause"
showLicense License
BSD4 = String
"BSD-4-Clause"
showLicense License
MIT = String
"MIT"
showLicense License
PublicDomain = String
"SUSE-Public-Domain"
showLicense License
AllRightsReserved = String
"SUSE-NonFree"
showLicense License
OtherLicense = String
"Unknown"
showLicense (UnknownLicense String
l) = String
"Unknown" String -> String -> String
+-+ String
l
showLicense (Apache Maybe Version
Nothing) = String
"Apache-2.0"
showLicense (Apache (Just Version
ver)) = String
"Apache-" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Version -> String
forall a. Pretty a => a -> String
display (Version -> Version
normalizeVersion Version
ver)
showLicense (AGPL Maybe Version
Nothing) = String
"AGPL-1.0-or-later"
showLicense (AGPL (Just Version
ver)) = String
"AGPL-" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Version -> String
forall a. Pretty a => a -> String
display (Version -> Version
normalizeVersion Version
ver) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-or-later"
showLicense License
BSD2 = String
"BSD-2-Clause"
showLicense (MPL Version
ver) = String
"MPL-" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Version -> String
forall a. Pretty a => a -> String
display (Version -> Version
normalizeVersion Version
ver)
showLicense License
ISC = String
"ISC"
showLicense License
UnspecifiedLicense = String
"Unspecified license!"

-- http://rosettacode.org/wiki/Word_wrap#Haskell
wordwrap :: Int -> String -> String
wordwrap :: CopyrightYear -> String -> String
wordwrap CopyrightYear
maxlen = CopyrightYear -> ForceBinary -> [String] -> String
wrap_ CopyrightYear
0 ForceBinary
False ([String] -> String) -> (String -> [String]) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words
  where
    wrap_ :: CopyrightYear -> ForceBinary -> [String] -> String
wrap_ CopyrightYear
_ ForceBinary
_ [] = String
"\n"
    wrap_ CopyrightYear
pos ForceBinary
eos (String
w:[String]
ws)
      -- at line start: put down the word no matter what
      | CopyrightYear
pos CopyrightYear -> CopyrightYear -> ForceBinary
forall a. Eq a => a -> a -> ForceBinary
== CopyrightYear
0 = String
w String -> String -> String
forall a. [a] -> [a] -> [a]
++ CopyrightYear -> ForceBinary -> [String] -> String
wrap_ (CopyrightYear
pos CopyrightYear -> CopyrightYear -> CopyrightYear
forall a. Num a => a -> a -> a
+ CopyrightYear
lw) ForceBinary
endp [String]
ws
      | CopyrightYear
pos CopyrightYear -> CopyrightYear -> CopyrightYear
forall a. Num a => a -> a -> a
+ CopyrightYear
lw CopyrightYear -> CopyrightYear -> CopyrightYear
forall a. Num a => a -> a -> a
+ CopyrightYear
1 CopyrightYear -> CopyrightYear -> ForceBinary
forall a. Ord a => a -> a -> ForceBinary
> CopyrightYear
maxlen CopyrightYear -> CopyrightYear -> CopyrightYear
forall a. Num a => a -> a -> a
- CopyrightYear
9 ForceBinary -> ForceBinary -> ForceBinary
&& ForceBinary
eos = Char
'\n'Char -> String -> String
forall a. a -> [a] -> [a]
:CopyrightYear -> ForceBinary -> [String] -> String
wrap_ CopyrightYear
0 ForceBinary
endp (String
wString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
ws)
      | CopyrightYear
pos CopyrightYear -> CopyrightYear -> CopyrightYear
forall a. Num a => a -> a -> a
+ CopyrightYear
lw CopyrightYear -> CopyrightYear -> CopyrightYear
forall a. Num a => a -> a -> a
+ CopyrightYear
1 CopyrightYear -> CopyrightYear -> ForceBinary
forall a. Ord a => a -> a -> ForceBinary
> CopyrightYear
maxlen = Char
'\n'Char -> String -> String
forall a. a -> [a] -> [a]
:CopyrightYear -> ForceBinary -> [String] -> String
wrap_ CopyrightYear
0 ForceBinary
endp (String
wString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
ws)
      | ForceBinary
otherwise = String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
w String -> String -> String
forall a. [a] -> [a] -> [a]
++ CopyrightYear -> ForceBinary -> [String] -> String
wrap_ (CopyrightYear
pos CopyrightYear -> CopyrightYear -> CopyrightYear
forall a. Num a => a -> a -> a
+ CopyrightYear
lw CopyrightYear -> CopyrightYear -> CopyrightYear
forall a. Num a => a -> a -> a
+ CopyrightYear
1) ForceBinary
endp [String]
ws
      where
        lw :: CopyrightYear
lw = String -> CopyrightYear
forall (t :: * -> *) a. Foldable t => t a -> CopyrightYear
length String
w
        endp :: ForceBinary
endp = String -> Char
forall a. [a] -> a
last String
w Char -> Char -> ForceBinary
forall a. Eq a => a -> a -> ForceBinary
== Char
'.'

formatParagraphs :: String -> [String]
formatParagraphs :: String -> [String]
formatParagraphs = (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (CopyrightYear -> String -> String
wordwrap CopyrightYear
79) ([String] -> [String])
-> (String -> [String]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
paragraphs ([String] -> [String])
-> (String -> [String]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
lines
  where
    -- from http://stackoverflow.com/questions/930675/functional-paragraphs
    -- using split would be: map unlines . (Data.List.Split.splitWhen null)
    paragraphs :: [String] -> [String]
    paragraphs :: [String] -> [String]
paragraphs = ([String] -> String) -> [[String]] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ([String] -> String
unlines ([String] -> String)
-> ([String] -> [String]) -> [String] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> ForceBinary) -> [String] -> [String]
forall a. (a -> ForceBinary) -> [a] -> [a]
filter (ForceBinary -> ForceBinary
not (ForceBinary -> ForceBinary)
-> (String -> ForceBinary) -> String -> ForceBinary
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null)) ([[String]] -> [String])
-> ([String] -> [[String]]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String -> ForceBinary) -> [String] -> [[String]]
forall a. (a -> a -> ForceBinary) -> [a] -> [[a]]
groupBy ((String -> ForceBinary) -> String -> String -> ForceBinary
forall a b. a -> b -> a
const ((String -> ForceBinary) -> String -> String -> ForceBinary)
-> (String -> ForceBinary) -> String -> String -> ForceBinary
forall a b. (a -> b) -> a -> b
$ ForceBinary -> ForceBinary
not (ForceBinary -> ForceBinary)
-> (String -> ForceBinary) -> String -> ForceBinary
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null)

rstrip :: (Char -> Bool) -> String -> String
rstrip :: (Char -> ForceBinary) -> String -> String
rstrip Char -> ForceBinary
p = String -> String
forall a. [a] -> [a]
reverse (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> ForceBinary) -> String -> String
forall a. (a -> ForceBinary) -> [a] -> [a]
dropWhile Char -> ForceBinary
p (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. [a] -> [a]
reverse

getPkgName :: Maybe FilePath -> PackageDescription -> Bool -> IO (String, Bool)
getPkgName :: Maybe String
-> PackageDescription -> ForceBinary -> IO (String, ForceBinary)
getPkgName (Just String
spec) PackageDescription
pkgDesc ForceBinary
binary = do
  let name :: String
name = PackageName -> String
unPackageName (PackageIdentifier -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName (PackageDescription -> PackageIdentifier
package PackageDescription
pkgDesc))
      pkgname :: String
pkgname = String -> String
takeBaseName String
spec
      hasLib :: ForceBinary
hasLib = PackageDescription -> ForceBinary
hasLibs PackageDescription
pkgDesc
  (String, ForceBinary) -> IO (String, ForceBinary)
forall (m :: * -> *) a. Monad m => a -> m a
return ((String, ForceBinary) -> IO (String, ForceBinary))
-> (String, ForceBinary) -> IO (String, ForceBinary)
forall a b. (a -> b) -> a -> b
$ if String
name String -> String -> ForceBinary
forall a. Eq a => a -> a -> ForceBinary
== String
pkgname ForceBinary -> ForceBinary -> ForceBinary
|| ForceBinary
binary then (String
name, ForceBinary
hasLib) else (String
pkgname, ForceBinary
False)
getPkgName Maybe String
Nothing PackageDescription
pkgDesc ForceBinary
binary = do
  let name :: String
name = PackageName -> String
unPackageName (PackageIdentifier -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName (PackageDescription -> PackageIdentifier
package PackageDescription
pkgDesc))
      hasExec :: ForceBinary
hasExec = PackageDescription -> ForceBinary
hasExes PackageDescription
pkgDesc
      hasLib :: ForceBinary
hasLib = PackageDescription -> ForceBinary
hasLibs PackageDescription
pkgDesc
  (String, ForceBinary) -> IO (String, ForceBinary)
forall (m :: * -> *) a. Monad m => a -> m a
return ((String, ForceBinary) -> IO (String, ForceBinary))
-> (String, ForceBinary) -> IO (String, ForceBinary)
forall a b. (a -> b) -> a -> b
$ if ForceBinary
binary ForceBinary -> ForceBinary -> ForceBinary
|| ForceBinary
hasExec ForceBinary -> ForceBinary -> ForceBinary
&& ForceBinary -> ForceBinary
not ForceBinary
hasLib then (String
name, ForceBinary
hasLib) else (String
"ghc-" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name, ForceBinary
False)

infixr 4 +-+
(+-+) :: String -> String -> String
String
"" +-+ :: String -> String -> String
+-+ String
s = String
s
String
s +-+ String
"" = String
s
String
s +-+ String
t = String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
t

excludedPkgs :: PackageDescription -> String -> Bool
excludedPkgs :: PackageDescription -> String -> ForceBinary
excludedPkgs PackageDescription
pkgDesc = (String -> [String] -> ForceBinary)
-> [String] -> String -> ForceBinary
forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> [String] -> ForceBinary
forall (t :: * -> *) a.
(Foldable t, Eq a) =>
a -> t a -> ForceBinary
notElem ([String]
subLibs [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String
"Cabal", String
"base", String
"ghc-prim", String
"integer-gmp"])
  where
    subLibs :: [String]
    subLibs :: [String]
subLibs = [ UnqualComponentName -> String
unUnqualComponentName UnqualComponentName
ln | Library
l <- PackageDescription -> [Library]
subLibraries PackageDescription
pkgDesc, LSubLibName UnqualComponentName
ln <- [Library -> LibraryName
libName Library
l] ]

-- returns list of deps and whether package is self-dependent
buildDependencies :: PackageDescription -> String -> ([String], Bool)
buildDependencies :: PackageDescription -> String -> ([String], ForceBinary)
buildDependencies PackageDescription
pkgDesc String
self =
  let bis :: [BuildInfo]
bis   = (Library -> BuildInfo) -> [Library] -> [BuildInfo]
forall a b. (a -> b) -> [a] -> [b]
map Library -> BuildInfo
libBuildInfo (PackageDescription -> [Library]
allLibraries PackageDescription
pkgDesc) [BuildInfo] -> [BuildInfo] -> [BuildInfo]
forall a. [a] -> [a] -> [a]
++ (Executable -> BuildInfo) -> [Executable] -> [BuildInfo]
forall a b. (a -> b) -> [a] -> [b]
map Executable -> BuildInfo
buildInfo (PackageDescription -> [Executable]
executables PackageDescription
pkgDesc)
      bdeps :: [String]
bdeps = (Dependency -> String) -> [Dependency] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Dependency -> String
forall a. IsDependency a => a -> String
depName ((BuildInfo -> [Dependency]) -> [BuildInfo] -> [Dependency]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap BuildInfo -> [Dependency]
targetBuildDepends ((BuildInfo -> ForceBinary) -> [BuildInfo] -> [BuildInfo]
forall a. (a -> ForceBinary) -> [a] -> [a]
filter BuildInfo -> ForceBinary
buildable [BuildInfo]
bis))
      sdeps :: [String]
sdeps = [String]
-> (SetupBuildInfo -> [String]) -> Maybe SetupBuildInfo -> [String]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] ((Dependency -> String) -> [Dependency] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Dependency -> String
forall a. IsDependency a => a -> String
depName ([Dependency] -> [String])
-> (SetupBuildInfo -> [Dependency]) -> SetupBuildInfo -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SetupBuildInfo -> [Dependency]
setupDepends) (PackageDescription -> Maybe SetupBuildInfo
setupBuildInfo PackageDescription
pkgDesc)
      deps :: [String]
deps  = [String] -> [String]
forall a. Eq a => [a] -> [a]
nub ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ [String]
bdeps [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
sdeps
  in
    ((String -> ForceBinary) -> [String] -> [String]
forall a. (a -> ForceBinary) -> [a] -> [a]
filter (PackageDescription -> String -> ForceBinary
excludedPkgs PackageDescription
pkgDesc) (String -> [String] -> [String]
forall a. Eq a => a -> [a] -> [a]
delete String
self [String]
deps), String
self String -> [String] -> ForceBinary
forall (t :: * -> *) a.
(Foldable t, Eq a) =>
a -> t a -> ForceBinary
`elem` [String]
deps ForceBinary -> ForceBinary -> ForceBinary
&& PackageDescription -> ForceBinary
hasExes PackageDescription
pkgDesc)

class IsDependency a where
  depName :: a -> String

instance IsDependency Dependency where
  depName :: Dependency -> String
depName (Dependency PackageName
n VersionRange
_ NonEmptySet LibraryName
_) = PackageName -> String
unPackageName PackageName
n

instance IsDependency PkgconfigDependency where
  depName :: PkgconfigDependency -> String
depName (PkgconfigDependency PkgconfigName
n PkgconfigVersionRange
_) = PkgconfigName -> String
unPkgconfigName PkgconfigName
n

instance IsDependency LegacyExeDependency where
  depName :: LegacyExeDependency -> String
depName (LegacyExeDependency String
n VersionRange
_) = String
n

showDep :: String -> String
showDep :: String -> String
showDep String
p = String
"ghc-" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
p String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-devel"

resolveLib :: String -> String
resolveLib :: String -> String
resolveLib String
"alut" = String
"freealut-devel"
resolveLib String
"asound" = String
"alsa-devel"
resolveLib String
"blas" = String
"blas-devel"
resolveLib String
"bluetooth" = String
"bluez-devel"
resolveLib String
"clang" = String
"clang-devel"
resolveLib String
"crypt" = String
"glibc-devel"
resolveLib String
"crypto" = String
"libopenssl-devel"
resolveLib String
"fftw3" = String
"fftw3-devel"
resolveLib String
"FLAC" = String
"flac-devel"
resolveLib String
"fontconfig" = String
"fontconfig-devel"
resolveLib String
"freetype" = String
"freetype2-devel"
resolveLib String
"gd" = String
"gd-devel"
resolveLib String
"GL" = String
"Mesa-libGL-devel"
resolveLib String
"glib-2.0" = String
"glib2-devel"
resolveLib String
"GLU" = String
"glu-devel"
resolveLib String
"gmp" = String
"gmp-devel"
resolveLib String
"gsl" = String
"gsl-devel"
resolveLib String
"icudata" = String
"libicu-devel"
resolveLib String
"icui18n" = String
"libicu-devel"
resolveLib String
"icuuc" = String
"libicu-devel"
resolveLib String
"IL" = String
"DevIL-devel"
resolveLib String
"Imlib2" = String
"imlib2-devel"
resolveLib String
"lapack" = String
"lapack-devel"
resolveLib String
"leveldb" = String
"leveldb-devel"
resolveLib String
"lmdb" = String
"lmdb-devel"
resolveLib String
"lua" = String
"lua-devel"
resolveLib String
"luajit" = String
"luajit-devel"
resolveLib String
"lzma" = String
"xz-devel"
resolveLib String
"m" = String
"glibc-devel"
resolveLib String
"magic" = String
"file-devel"
resolveLib String
"mpfr" = String
"mpfr-devel"
resolveLib String
"odbc" = String
"unixODBC-devel"
resolveLib String
"openal" = String
"openal-soft-devel"
resolveLib String
"pcre" = String
"pcre-devel"
resolveLib String
"png" = String
"libpng16-compat-devel"
resolveLib String
"pq" = String
"postgresql-server-devel"
resolveLib String
"pthread" = String
"glibc-devel"
resolveLib String
"re2" = String
"re2-devel"
resolveLib String
"resolv" = String
"glibc-devel"
resolveLib String
"ruby" = String
"ruby-devel"
resolveLib String
"snappy" = String
"snappy-devel"
resolveLib String
"sqlite3" = String
"sqlite3-devel"
resolveLib String
"ssl" = String
"libopenssl-devel"
resolveLib String
"tag_c" = String
"libtag-devel"
resolveLib String
"z" = String
"zlib-devel"
resolveLib String
name | String
"lib" String -> String -> ForceBinary
forall a. Eq a => [a] -> [a] -> ForceBinary
`isPrefixOf` String
name = String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-devel"
                | ForceBinary
otherwise               = String
"lib" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-devel"

testsuiteDependencies :: PackageDescription -- ^pkg description
                      -> String             -- ^self
                      -> [String]           -- ^depends
testsuiteDependencies :: PackageDescription -> String -> [String]
testsuiteDependencies PackageDescription
pkgDesc String
self =
  (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
showDep ([String] -> [String])
-> ([Dependency] -> [String]) -> [Dependency] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> [String]
forall a. Eq a => a -> [a] -> [a]
delete String
self ([String] -> [String])
-> ([Dependency] -> [String]) -> [Dependency] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> ForceBinary) -> [String] -> [String]
forall a. (a -> ForceBinary) -> [a] -> [a]
filter (PackageDescription -> String -> ForceBinary
excludedPkgs PackageDescription
pkgDesc) ([String] -> [String])
-> ([Dependency] -> [String]) -> [Dependency] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
forall a. Eq a => [a] -> [a]
nub ([String] -> [String])
-> ([Dependency] -> [String]) -> [Dependency] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Dependency -> String) -> [Dependency] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Dependency -> String
forall a. IsDependency a => a -> String
depName ([Dependency] -> [String]) -> [Dependency] -> [String]
forall a b. (a -> b) -> a -> b
$ (BuildInfo -> [Dependency]) -> [BuildInfo] -> [Dependency]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap BuildInfo -> [Dependency]
targetBuildDepends ((BuildInfo -> ForceBinary) -> [BuildInfo] -> [BuildInfo]
forall a. (a -> ForceBinary) -> [a] -> [a]
filter BuildInfo -> ForceBinary
buildable ((TestSuite -> BuildInfo) -> [TestSuite] -> [BuildInfo]
forall a b. (a -> b) -> [a] -> [b]
map TestSuite -> BuildInfo
testBuildInfo (PackageDescription -> [TestSuite]
testSuites PackageDescription
pkgDesc)))

badDescription :: String -> Bool
badDescription :: String -> ForceBinary
badDescription String
s = String -> ForceBinary
forall (t :: * -> *) a. Foldable t => t a -> ForceBinary
null String
s
                ForceBinary -> ForceBinary -> ForceBinary
|| String
"please see readme" String -> String -> ForceBinary
forall a. Eq a => [a] -> [a] -> ForceBinary
`isPrefixOf` (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
s
                ForceBinary -> ForceBinary -> ForceBinary
|| String
"please see the readme" String -> String -> ForceBinary
forall a. Eq a => [a] -> [a] -> ForceBinary
`isPrefixOf` (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
s
                ForceBinary -> ForceBinary -> ForceBinary
|| String
"see readme" String -> String -> ForceBinary
forall a. Eq a => [a] -> [a] -> ForceBinary
`isPrefixOf` (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
s
                ForceBinary -> ForceBinary -> ForceBinary
|| String
"cf readme" String -> String -> ForceBinary
forall a. Eq a => [a] -> [a] -> ForceBinary
`isPrefixOf` (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
s
                ForceBinary -> ForceBinary -> ForceBinary
|| String
"please refer to readme" String -> String -> ForceBinary
forall a. Eq a => [a] -> [a] -> ForceBinary
`isPrefixOf` (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
s
                ForceBinary -> ForceBinary -> ForceBinary
|| String
"initial project template" String -> String -> ForceBinary
forall a. Eq a => [a] -> [a] -> ForceBinary
`isPrefixOf` (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
s

-- | @pandoc-2.2.1@ installs a file with square brackets in its name, and that
-- confuses RPM because it thinks those are shell specials.
--
-- TODO: Figure out how this code is supposed to interact with legitimate shell
-- globs, like '*'.

avoidSquareBrackets :: String -> String
avoidSquareBrackets :: String -> String
avoidSquareBrackets []     = []
avoidSquareBrackets (Char
x:String
xs)
  | Char
x Char -> String -> ForceBinary
forall (t :: * -> *) a.
(Foldable t, Eq a) =>
a -> t a -> ForceBinary
`elem` String
"[]"       = Char
'?' Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
avoidSquareBrackets String
xs
  | ForceBinary
otherwise           = Char
x Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
avoidSquareBrackets String
xs