{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE CPP #-}
module Hpack.Render (
renderPackage
, renderPackageWith
, defaultRenderSettings
, RenderSettings(..)
, Alignment(..)
, CommaStyle(..)
#ifdef TEST
, renderConditional
, renderDependencies
, renderLibraryFields
, renderExecutableFields
, renderFlag
, renderSourceRepository
, renderDirectories
, formatDescription
#endif
) where
import Imports
import Data.Char
import Data.Maybe
import Data.Map.Lazy (Map)
import qualified Data.Map.Lazy as Map
import Hpack.Util
import Hpack.Config
import Hpack.Render.Hints
import Hpack.Render.Dsl hiding (sortFieldsBy)
import qualified Hpack.Render.Dsl as Dsl
renderPackage :: [String] -> Package -> String
renderPackage :: [String] -> Package -> String
renderPackage [String]
oldCabalFile = RenderSettings
-> Alignment
-> [String]
-> [(String, [String])]
-> Package
-> String
renderPackageWith RenderSettings
settings Alignment
headerFieldsAlignment [String]
formattingHintsFieldOrder [(String, [String])]
formattingHintsSectionsFieldOrder
where
FormattingHints{[String]
[(String, [String])]
Maybe Alignment
RenderSettings
formattingHintsRenderSettings :: FormattingHints -> RenderSettings
formattingHintsAlignment :: FormattingHints -> Maybe Alignment
formattingHintsSectionsFieldOrder :: FormattingHints -> [(String, [String])]
formattingHintsFieldOrder :: FormattingHints -> [String]
formattingHintsRenderSettings :: RenderSettings
formattingHintsAlignment :: Maybe Alignment
formattingHintsSectionsFieldOrder :: [(String, [String])]
formattingHintsFieldOrder :: [String]
..} = [String] -> FormattingHints
sniffFormattingHints [String]
oldCabalFile
headerFieldsAlignment :: Alignment
headerFieldsAlignment = forall a. a -> Maybe a -> a
fromMaybe Alignment
16 Maybe Alignment
formattingHintsAlignment
settings :: RenderSettings
settings = RenderSettings
formattingHintsRenderSettings
renderPackageWith :: RenderSettings -> Alignment -> [String] -> [(String, [String])] -> Package -> String
renderPackageWith :: RenderSettings
-> Alignment
-> [String]
-> [(String, [String])]
-> Package
-> String
renderPackageWith RenderSettings
settings Alignment
headerFieldsAlignment [String]
existingFieldOrder [(String, [String])]
sectionsFieldOrder Package{String
[String]
[Path]
[Flag]
[Verbatim]
Maybe String
Maybe SourceRepository
Maybe (Section Library)
Maybe CustomSetup
Map String (Section Executable)
Map String (Section Library)
BuildType
packageVerbatim :: Package -> [Verbatim]
packageBenchmarks :: Package -> Map String (Section Executable)
packageTests :: Package -> Map String (Section Executable)
packageExecutables :: Package -> Map String (Section Executable)
packageInternalLibraries :: Package -> Map String (Section Library)
packageLibrary :: Package -> Maybe (Section Library)
packageCustomSetup :: Package -> Maybe CustomSetup
packageSourceRepository :: Package -> Maybe SourceRepository
packageDataDir :: Package -> Maybe String
packageDataFiles :: Package -> [Path]
packageExtraDocFiles :: Package -> [Path]
packageExtraSourceFiles :: Package -> [Path]
packageFlags :: Package -> [Flag]
packageTestedWith :: Package -> [String]
packageLicenseFile :: Package -> [String]
packageLicense :: Package -> Maybe String
packageBuildType :: Package -> BuildType
packageCopyright :: Package -> [String]
packageMaintainer :: Package -> [String]
packageAuthor :: Package -> [String]
packageStability :: Package -> Maybe String
packageCategory :: Package -> Maybe String
packageBugReports :: Package -> Maybe String
packageHomepage :: Package -> Maybe String
packageDescription :: Package -> Maybe String
packageSynopsis :: Package -> Maybe String
packageVersion :: Package -> String
packageName :: Package -> String
packageVerbatim :: [Verbatim]
packageBenchmarks :: Map String (Section Executable)
packageTests :: Map String (Section Executable)
packageExecutables :: Map String (Section Executable)
packageInternalLibraries :: Map String (Section Library)
packageLibrary :: Maybe (Section Library)
packageCustomSetup :: Maybe CustomSetup
packageSourceRepository :: Maybe SourceRepository
packageDataDir :: Maybe String
packageDataFiles :: [Path]
packageExtraDocFiles :: [Path]
packageExtraSourceFiles :: [Path]
packageFlags :: [Flag]
packageTestedWith :: [String]
packageLicenseFile :: [String]
packageLicense :: Maybe String
packageBuildType :: BuildType
packageCopyright :: [String]
packageMaintainer :: [String]
packageAuthor :: [String]
packageStability :: Maybe String
packageCategory :: Maybe String
packageBugReports :: Maybe String
packageHomepage :: Maybe String
packageDescription :: Maybe String
packageSynopsis :: Maybe String
packageVersion :: String
packageName :: String
..} = forall a. [a] -> [[a]] -> [a]
intercalate String
"\n" ([String] -> String
unlines [String]
header forall a. a -> [a] -> [a]
: [String]
chunks)
where
chunks :: [String]
chunks :: [String]
chunks = forall a b. (a -> b) -> [a] -> [b]
map [String] -> String
unlines forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> Bool
null) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (RenderSettings -> Nesting -> Element -> [String]
render RenderSettings
settings Nesting
0) forall a b. (a -> b) -> a -> b
$ [(String, [String])] -> [Element] -> [Element]
sortStanzaFields [(String, [String])]
sectionsFieldOrder [Element]
stanzas
header :: [String]
header :: [String]
header = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (RenderSettings -> Nesting -> Element -> [String]
render RenderSettings
settings {renderSettingsFieldAlignment :: Alignment
renderSettingsFieldAlignment = Alignment
headerFieldsAlignment} Nesting
0) [Element]
packageFields
packageFields :: [Element]
packageFields :: [Element]
packageFields = [Verbatim] -> [Element] -> [Element]
addVerbatim [Verbatim]
packageVerbatim forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [Element] -> [Element]
sortFieldsBy [String]
existingFieldOrder forall a b. (a -> b) -> a -> b
$
[Element]
headerFields forall a. [a] -> [a] -> [a]
++ [
String -> Value -> Element
Field String
"tested-with" forall a b. (a -> b) -> a -> b
$ [String] -> Value
CommaSeparatedList [String]
packageTestedWith
, String -> Value -> Element
Field String
"extra-source-files" ([Path] -> Value
renderPaths [Path]
packageExtraSourceFiles)
, String -> Value -> Element
Field String
"extra-doc-files" ([Path] -> Value
renderPaths [Path]
packageExtraDocFiles)
, String -> Value -> Element
Field String
"data-files" ([Path] -> Value
renderPaths [Path]
packageDataFiles)
] forall a. [a] -> [a] -> [a]
++ forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value -> Element
Field String
"data-dir" forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value
Literal) Maybe String
packageDataDir
sourceRepository :: [Element]
sourceRepository :: [Element]
sourceRepository = forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourceRepository -> Element
renderSourceRepository) Maybe SourceRepository
packageSourceRepository
customSetup :: [Element]
customSetup :: [Element]
customSetup = forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. CustomSetup -> Element
renderCustomSetup) Maybe CustomSetup
packageCustomSetup
library :: [Element]
library :: [Element]
library = forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. Section Library -> Element
renderLibrary) Maybe (Section Library)
packageLibrary
stanzas :: [Element]
stanzas :: [Element]
stanzas = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [
[Element]
sourceRepository
, [Element]
customSetup
, forall a b. (a -> b) -> [a] -> [b]
map Flag -> Element
renderFlag [Flag]
packageFlags
, [Element]
library
, Map String (Section Library) -> [Element]
renderInternalLibraries Map String (Section Library)
packageInternalLibraries
, Map String (Section Executable) -> [Element]
renderExecutables Map String (Section Executable)
packageExecutables
, Map String (Section Executable) -> [Element]
renderTests Map String (Section Executable)
packageTests
, Map String (Section Executable) -> [Element]
renderBenchmarks Map String (Section Executable)
packageBenchmarks
]
headerFields :: [Element]
headerFields :: [Element]
headerFields = forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (\(String
name, Maybe String
value) -> String -> Value -> Element
Field String
name forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value
Literal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe String
value) forall a b. (a -> b) -> a -> b
$ [
(String
"name", forall a. a -> Maybe a
Just String
packageName)
, (String
"version", forall a. a -> Maybe a
Just String
packageVersion)
, (String
"synopsis", Maybe String
packageSynopsis)
, (String
"description", (Alignment -> String -> String
formatDescription Alignment
headerFieldsAlignment forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe String
packageDescription))
, (String
"category", Maybe String
packageCategory)
, (String
"stability", Maybe String
packageStability)
, (String
"homepage", Maybe String
packageHomepage)
, (String
"bug-reports", Maybe String
packageBugReports)
, (String
"author", [String] -> Maybe String
formatList [String]
packageAuthor)
, (String
"maintainer", [String] -> Maybe String
formatList [String]
packageMaintainer)
, (String
"copyright", [String] -> Maybe String
formatList [String]
packageCopyright)
, (String
"license", Maybe String
packageLicense)
, case [String]
packageLicenseFile of
[String
file] -> (String
"license-file", forall a. a -> Maybe a
Just String
file)
[String]
files -> (String
"license-files", [String] -> Maybe String
formatList [String]
files)
, (String
"build-type", forall a. a -> Maybe a
Just (forall a. Show a => a -> String
show BuildType
packageBuildType))
]
formatList :: [String] -> Maybe String
formatList :: [String] -> Maybe String
formatList [String]
xs = forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
xs) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [[a]] -> [a]
intercalate String
separator [String]
xs)
where
separator :: String
separator = let Alignment Int
n = Alignment
headerFieldsAlignment in String
",\n" forall a. [a] -> [a] -> [a]
++ forall a. Int -> a -> [a]
replicate Int
n Char
' '
sortStanzaFields :: [(String, [String])] -> [Element] -> [Element]
sortStanzaFields :: [(String, [String])] -> [Element] -> [Element]
sortStanzaFields [(String, [String])]
sectionsFieldOrder = [Element] -> [Element]
go
where
go :: [Element] -> [Element]
go [Element]
sections = case [Element]
sections of
[] -> []
Stanza String
name [Element]
fields : [Element]
xs | Just [String]
fieldOrder <- forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
name [(String, [String])]
sectionsFieldOrder -> String -> [Element] -> Element
Stanza String
name ([String] -> [Element] -> [Element]
sortFieldsBy [String]
fieldOrder [Element]
fields) forall a. a -> [a] -> [a]
: [Element] -> [Element]
go [Element]
xs
Element
x : [Element]
xs -> Element
x forall a. a -> [a] -> [a]
: [Element] -> [Element]
go [Element]
xs
formatDescription :: Alignment -> String -> String
formatDescription :: Alignment -> String -> String
formatDescription (Alignment Int
alignment) String
description = case forall a b. (a -> b) -> [a] -> [b]
map String -> String
emptyLineToDot forall a b. (a -> b) -> a -> b
$ String -> [String]
lines String
description of
String
x : [String]
xs -> forall a. [a] -> [[a]] -> [a]
intercalate String
"\n" (String
x forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map (String
indentation forall a. [a] -> [a] -> [a]
++) [String]
xs)
[] -> String
""
where
n :: Int
n = forall a. Ord a => a -> a -> a
max Int
alignment (forall (t :: * -> *) a. Foldable t => t a -> Int
length (String
"description: " :: String))
indentation :: String
indentation = forall a. Int -> a -> [a]
replicate Int
n Char
' '
emptyLineToDot :: String -> String
emptyLineToDot String
xs
| String -> Bool
isEmptyLine String
xs = String
"."
| Bool
otherwise = String
xs
isEmptyLine :: String -> Bool
isEmptyLine = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isSpace
renderSourceRepository :: SourceRepository -> Element
renderSourceRepository :: SourceRepository -> Element
renderSourceRepository SourceRepository{String
Maybe String
sourceRepositorySubdir :: SourceRepository -> Maybe String
sourceRepositoryUrl :: SourceRepository -> String
sourceRepositorySubdir :: Maybe String
sourceRepositoryUrl :: String
..} = String -> [Element] -> Element
Stanza String
"source-repository head" [
String -> Value -> Element
Field String
"type" Value
"git"
, String -> Value -> Element
Field String
"location" (String -> Value
Literal String
sourceRepositoryUrl)
, String -> Value -> Element
Field String
"subdir" (forall b a. b -> (a -> b) -> Maybe a -> b
maybe Value
"" String -> Value
Literal Maybe String
sourceRepositorySubdir)
]
renderFlag :: Flag -> Element
renderFlag :: Flag -> Element
renderFlag Flag {Bool
String
Maybe String
flagDefault :: Flag -> Bool
flagManual :: Flag -> Bool
flagDescription :: Flag -> Maybe String
flagName :: Flag -> String
flagDefault :: Bool
flagManual :: Bool
flagDescription :: Maybe String
flagName :: String
..} = String -> [Element] -> Element
Stanza (String
"flag " forall a. [a] -> [a] -> [a]
++ String
flagName) forall a b. (a -> b) -> a -> b
$ [Element]
description forall a. [a] -> [a] -> [a]
++ [
String -> Value -> Element
Field String
"manual" (String -> Value
Literal forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Bool
flagManual)
, String -> Value -> Element
Field String
"default" (String -> Value
Literal forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Bool
flagDefault)
]
where
description :: [Element]
description = forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value -> Element
Field String
"description" forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value
Literal) Maybe String
flagDescription
renderInternalLibraries :: Map String (Section Library) -> [Element]
renderInternalLibraries :: Map String (Section Library) -> [Element]
renderInternalLibraries = forall a b. (a -> b) -> [a] -> [b]
map (String, Section Library) -> Element
renderInternalLibrary forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [(k, a)]
Map.toList
renderInternalLibrary :: (String, Section Library) -> Element
renderInternalLibrary :: (String, Section Library) -> Element
renderInternalLibrary (String
name, Section Library
sect) =
String -> [Element] -> Element
Stanza (String
"library " forall a. [a] -> [a] -> [a]
++ String
name) (Section Library -> [Element]
renderLibrarySection Section Library
sect)
renderExecutables :: Map String (Section Executable) -> [Element]
renderExecutables :: Map String (Section Executable) -> [Element]
renderExecutables = forall a b. (a -> b) -> [a] -> [b]
map (String, Section Executable) -> Element
renderExecutable forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [(k, a)]
Map.toList
renderExecutable :: (String, Section Executable) -> Element
renderExecutable :: (String, Section Executable) -> Element
renderExecutable (String
name, Section Executable
sect) =
String -> [Element] -> Element
Stanza (String
"executable " forall a. [a] -> [a] -> [a]
++ String
name) ([Element] -> Section Executable -> [Element]
renderExecutableSection [] Section Executable
sect)
renderTests :: Map String (Section Executable) -> [Element]
renderTests :: Map String (Section Executable) -> [Element]
renderTests = forall a b. (a -> b) -> [a] -> [b]
map (String, Section Executable) -> Element
renderTest forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [(k, a)]
Map.toList
renderTest :: (String, Section Executable) -> Element
renderTest :: (String, Section Executable) -> Element
renderTest (String
name, Section Executable
sect) =
String -> [Element] -> Element
Stanza (String
"test-suite " forall a. [a] -> [a] -> [a]
++ String
name)
([Element] -> Section Executable -> [Element]
renderExecutableSection [String -> Value -> Element
Field String
"type" Value
"exitcode-stdio-1.0"] Section Executable
sect)
renderBenchmarks :: Map String (Section Executable) -> [Element]
renderBenchmarks :: Map String (Section Executable) -> [Element]
renderBenchmarks = forall a b. (a -> b) -> [a] -> [b]
map (String, Section Executable) -> Element
renderBenchmark forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [(k, a)]
Map.toList
renderBenchmark :: (String, Section Executable) -> Element
renderBenchmark :: (String, Section Executable) -> Element
renderBenchmark (String
name, Section Executable
sect) =
String -> [Element] -> Element
Stanza (String
"benchmark " forall a. [a] -> [a] -> [a]
++ String
name)
([Element] -> Section Executable -> [Element]
renderExecutableSection [String -> Value -> Element
Field String
"type" Value
"exitcode-stdio-1.0"] Section Executable
sect)
renderExecutableSection :: [Element] -> Section Executable -> [Element]
renderExecutableSection :: [Element] -> Section Executable -> [Element]
renderExecutableSection [Element]
extraFields = forall a. (a -> [Element]) -> [Element] -> Section a -> [Element]
renderSection Executable -> [Element]
renderExecutableFields [Element]
extraFields
renderExecutableFields :: Executable -> [Element]
renderExecutableFields :: Executable -> [Element]
renderExecutableFields Executable{[Module]
Maybe String
executableGeneratedModules :: Executable -> [Module]
executableOtherModules :: Executable -> [Module]
executableMain :: Executable -> Maybe String
executableGeneratedModules :: [Module]
executableOtherModules :: [Module]
executableMain :: Maybe String
..} = [Element]
mainIs forall a. [a] -> [a] -> [a]
++ [Element
otherModules, Element
generatedModules]
where
mainIs :: [Element]
mainIs = forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value -> Element
Field String
"main-is" forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value
Literal) Maybe String
executableMain
otherModules :: Element
otherModules = [Module] -> Element
renderOtherModules [Module]
executableOtherModules
generatedModules :: Element
generatedModules = [Module] -> Element
renderGeneratedModules [Module]
executableGeneratedModules
renderCustomSetup :: CustomSetup -> Element
renderCustomSetup :: CustomSetup -> Element
renderCustomSetup CustomSetup{Dependencies
customSetupDependencies :: CustomSetup -> Dependencies
customSetupDependencies :: Dependencies
..} =
String -> [Element] -> Element
Stanza String
"custom-setup" forall a b. (a -> b) -> a -> b
$ String -> Dependencies -> [Element]
renderDependencies String
"setup-depends" Dependencies
customSetupDependencies
renderLibrary :: Section Library -> Element
renderLibrary :: Section Library -> Element
renderLibrary Section Library
sect = String -> [Element] -> Element
Stanza String
"library" forall a b. (a -> b) -> a -> b
$ Section Library -> [Element]
renderLibrarySection Section Library
sect
renderLibrarySection :: Section Library -> [Element]
renderLibrarySection :: Section Library -> [Element]
renderLibrarySection = forall a. (a -> [Element]) -> [Element] -> Section a -> [Element]
renderSection Library -> [Element]
renderLibraryFields []
renderLibraryFields :: Library -> [Element]
renderLibraryFields :: Library -> [Element]
renderLibraryFields Library{[String]
[Module]
Maybe Bool
Maybe String
librarySignatures :: Library -> [String]
libraryReexportedModules :: Library -> [String]
libraryGeneratedModules :: Library -> [Module]
libraryOtherModules :: Library -> [Module]
libraryExposedModules :: Library -> [Module]
libraryVisibility :: Library -> Maybe String
libraryExposed :: Library -> Maybe Bool
librarySignatures :: [String]
libraryReexportedModules :: [String]
libraryGeneratedModules :: [Module]
libraryOtherModules :: [Module]
libraryExposedModules :: [Module]
libraryVisibility :: Maybe String
libraryExposed :: Maybe Bool
..} =
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Element
renderExposed) Maybe Bool
libraryExposed forall a. [a] -> [a] -> [a]
++
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Element
renderVisibility) Maybe String
libraryVisibility forall a. [a] -> [a] -> [a]
++ [
[Module] -> Element
renderExposedModules [Module]
libraryExposedModules
, [Module] -> Element
renderOtherModules [Module]
libraryOtherModules
, [Module] -> Element
renderGeneratedModules [Module]
libraryGeneratedModules
, [String] -> Element
renderReexportedModules [String]
libraryReexportedModules
, [String] -> Element
renderSignatures [String]
librarySignatures
]
renderExposed :: Bool -> Element
renderExposed :: Bool -> Element
renderExposed = String -> Value -> Element
Field String
"exposed" forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value
Literal forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show
renderVisibility :: String -> Element
renderVisibility :: String -> Element
renderVisibility = String -> Value -> Element
Field String
"visibility" forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value
Literal
renderSection :: (a -> [Element]) -> [Element] -> Section a -> [Element]
renderSection :: forall a. (a -> [Element]) -> [Element] -> Section a -> [Element]
renderSection a -> [Element]
renderSectionData [Element]
extraFieldsStart Section{a
[String]
[Path]
[Conditional (Section a)]
[Verbatim]
Maybe Bool
Maybe Language
Map BuildTool DependencyVersion
Dependencies
SystemBuildTools
sectionVerbatim :: forall a. Section a -> [Verbatim]
sectionSystemBuildTools :: forall a. Section a -> SystemBuildTools
sectionBuildTools :: forall a. Section a -> Map BuildTool DependencyVersion
sectionConditionals :: forall a. Section a -> [Conditional (Section a)]
sectionBuildable :: forall a. Section a -> Maybe Bool
sectionLdOptions :: forall a. Section a -> [String]
sectionInstallIncludes :: forall a. Section a -> [String]
sectionIncludeDirs :: forall a. Section a -> [String]
sectionFrameworks :: forall a. Section a -> [String]
sectionExtraFrameworksDirs :: forall a. Section a -> [String]
sectionExtraLibraries :: forall a. Section a -> [String]
sectionExtraLibDirs :: forall a. Section a -> [String]
sectionJsSources :: forall a. Section a -> [Path]
sectionCxxSources :: forall a. Section a -> [Path]
sectionCxxOptions :: forall a. Section a -> [String]
sectionCSources :: forall a. Section a -> [Path]
sectionCcOptions :: forall a. Section a -> [String]
sectionCppOptions :: forall a. Section a -> [String]
sectionGhcjsOptions :: forall a. Section a -> [String]
sectionGhcSharedOptions :: forall a. Section a -> [String]
sectionGhcProfOptions :: forall a. Section a -> [String]
sectionGhcOptions :: forall a. Section a -> [String]
sectionLanguage :: forall a. Section a -> Maybe Language
sectionOtherExtensions :: forall a. Section a -> [String]
sectionDefaultExtensions :: forall a. Section a -> [String]
sectionPkgConfigDependencies :: forall a. Section a -> [String]
sectionDependencies :: forall a. Section a -> Dependencies
sectionSourceDirs :: forall a. Section a -> [String]
sectionData :: forall a. Section a -> a
sectionVerbatim :: [Verbatim]
sectionSystemBuildTools :: SystemBuildTools
sectionBuildTools :: Map BuildTool DependencyVersion
sectionConditionals :: [Conditional (Section a)]
sectionBuildable :: Maybe Bool
sectionLdOptions :: [String]
sectionInstallIncludes :: [String]
sectionIncludeDirs :: [String]
sectionFrameworks :: [String]
sectionExtraFrameworksDirs :: [String]
sectionExtraLibraries :: [String]
sectionExtraLibDirs :: [String]
sectionJsSources :: [Path]
sectionCxxSources :: [Path]
sectionCxxOptions :: [String]
sectionCSources :: [Path]
sectionCcOptions :: [String]
sectionCppOptions :: [String]
sectionGhcjsOptions :: [String]
sectionGhcSharedOptions :: [String]
sectionGhcProfOptions :: [String]
sectionGhcOptions :: [String]
sectionLanguage :: Maybe Language
sectionOtherExtensions :: [String]
sectionDefaultExtensions :: [String]
sectionPkgConfigDependencies :: [String]
sectionDependencies :: Dependencies
sectionSourceDirs :: [String]
sectionData :: a
..} = [Verbatim] -> [Element] -> [Element]
addVerbatim [Verbatim]
sectionVerbatim forall a b. (a -> b) -> a -> b
$
[Element]
extraFieldsStart
forall a. [a] -> [a] -> [a]
++ a -> [Element]
renderSectionData a
sectionData forall a. [a] -> [a] -> [a]
++ [
String -> [String] -> Element
renderDirectories String
"hs-source-dirs" [String]
sectionSourceDirs
, [String] -> Element
renderDefaultExtensions [String]
sectionDefaultExtensions
, [String] -> Element
renderOtherExtensions [String]
sectionOtherExtensions
, [String] -> Element
renderGhcOptions [String]
sectionGhcOptions
, [String] -> Element
renderGhcProfOptions [String]
sectionGhcProfOptions
, [String] -> Element
renderGhcSharedOptions [String]
sectionGhcSharedOptions
, [String] -> Element
renderGhcjsOptions [String]
sectionGhcjsOptions
, [String] -> Element
renderCppOptions [String]
sectionCppOptions
, [String] -> Element
renderCcOptions [String]
sectionCcOptions
, [String] -> Element
renderCxxOptions [String]
sectionCxxOptions
, String -> [String] -> Element
renderDirectories String
"include-dirs" [String]
sectionIncludeDirs
, String -> Value -> Element
Field String
"install-includes" ([String] -> Value
LineSeparatedList [String]
sectionInstallIncludes)
, String -> Value -> Element
Field String
"c-sources" ([Path] -> Value
renderPaths [Path]
sectionCSources)
, String -> Value -> Element
Field String
"cxx-sources" ([Path] -> Value
renderPaths [Path]
sectionCxxSources)
, String -> Value -> Element
Field String
"js-sources" ([Path] -> Value
renderPaths [Path]
sectionJsSources)
, String -> [String] -> Element
renderDirectories String
"extra-lib-dirs" [String]
sectionExtraLibDirs
, String -> Value -> Element
Field String
"extra-libraries" ([String] -> Value
LineSeparatedList [String]
sectionExtraLibraries)
, String -> [String] -> Element
renderDirectories String
"extra-frameworks-dirs" [String]
sectionExtraFrameworksDirs
, String -> Value -> Element
Field String
"frameworks" ([String] -> Value
LineSeparatedList [String]
sectionFrameworks)
, [String] -> Element
renderLdOptions [String]
sectionLdOptions
, String -> Value -> Element
Field String
"pkgconfig-depends" ([String] -> Value
CommaSeparatedList [String]
sectionPkgConfigDependencies)
]
forall a. [a] -> [a] -> [a]
++ Map BuildTool DependencyVersion -> SystemBuildTools -> [Element]
renderBuildTools Map BuildTool DependencyVersion
sectionBuildTools SystemBuildTools
sectionSystemBuildTools
forall a. [a] -> [a] -> [a]
++ String -> Dependencies -> [Element]
renderDependencies String
"build-depends" Dependencies
sectionDependencies
forall a. [a] -> [a] -> [a]
++ forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Element
renderBuildable) Maybe Bool
sectionBuildable
forall a. [a] -> [a] -> [a]
++ forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. Language -> Element
renderLanguage) Maybe Language
sectionLanguage
forall a. [a] -> [a] -> [a]
++ forall a b. (a -> b) -> [a] -> [b]
map (forall a. (a -> [Element]) -> Conditional (Section a) -> Element
renderConditional a -> [Element]
renderSectionData) [Conditional (Section a)]
sectionConditionals
addVerbatim :: [Verbatim] -> [Element] -> [Element]
addVerbatim :: [Verbatim] -> [Element] -> [Element]
addVerbatim [Verbatim]
verbatim [Element]
fields = [Verbatim] -> [Element] -> [Element]
filterVerbatim [Verbatim]
verbatim [Element]
fields forall a. [a] -> [a] -> [a]
++ [Verbatim] -> [Element]
renderVerbatim [Verbatim]
verbatim
filterVerbatim :: [Verbatim] -> [Element] -> [Element]
filterVerbatim :: [Verbatim] -> [Element] -> [Element]
filterVerbatim [Verbatim]
verbatim = forall a. (a -> Bool) -> [a] -> [a]
filter Element -> Bool
p
where
p :: Element -> Bool
p :: Element -> Bool
p = \ case
Field String
name Value
_ -> String
name forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [String]
fields
Element
_ -> Bool
True
fields :: [String]
fields = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Verbatim -> [String]
verbatimFieldNames [Verbatim]
verbatim
verbatimFieldNames :: Verbatim -> [String]
verbatimFieldNames :: Verbatim -> [String]
verbatimFieldNames Verbatim
verbatim = case Verbatim
verbatim of
VerbatimLiteral String
_ -> []
VerbatimObject Map String VerbatimValue
o -> forall k a. Map k a -> [k]
Map.keys Map String VerbatimValue
o
renderVerbatim :: [Verbatim] -> [Element]
renderVerbatim :: [Verbatim] -> [Element]
renderVerbatim = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap forall a b. (a -> b) -> a -> b
$ \ case
VerbatimLiteral String
s -> [String -> Element
Verbatim String
s]
VerbatimObject Map String VerbatimValue
o -> Map String VerbatimValue -> [Element]
renderVerbatimObject Map String VerbatimValue
o
renderVerbatimObject :: Map String VerbatimValue -> [Element]
renderVerbatimObject :: Map String VerbatimValue -> [Element]
renderVerbatimObject = forall a b. (a -> b) -> [a] -> [b]
map (String, VerbatimValue) -> Element
renderPair forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [(k, a)]
Map.toList
where
renderPair :: (String, VerbatimValue) -> Element
renderPair (String
key, VerbatimValue
value) = case String -> [String]
lines (VerbatimValue -> String
verbatimValueToString VerbatimValue
value) of
[String
x] -> String -> Value -> Element
Field String
key (String -> Value
Literal String
x)
[String]
xs -> String -> Value -> Element
Field String
key ([String] -> Value
LineSeparatedList [String]
xs)
renderConditional :: (a -> [Element]) -> Conditional (Section a) -> Element
renderConditional :: forall a. (a -> [Element]) -> Conditional (Section a) -> Element
renderConditional a -> [Element]
renderSectionData (Conditional Cond
condition Section a
sect Maybe (Section a)
mElse) = case Maybe (Section a)
mElse of
Maybe (Section a)
Nothing -> Element
if_
Just Section a
else_ -> Element -> Element -> Element
Group Element
if_ (String -> [Element] -> Element
Stanza String
"else" forall a b. (a -> b) -> a -> b
$ forall a. (a -> [Element]) -> [Element] -> Section a -> [Element]
renderSection a -> [Element]
renderSectionData [] Section a
else_)
where
if_ :: Element
if_ = String -> [Element] -> Element
Stanza (String
"if " forall a. [a] -> [a] -> [a]
++ Cond -> String
renderCond Cond
condition) (forall a. (a -> [Element]) -> [Element] -> Section a -> [Element]
renderSection a -> [Element]
renderSectionData [] Section a
sect)
renderCond :: Cond -> String
renderCond :: Cond -> String
renderCond = \ case
CondExpression String
c -> String
c
CondBool Bool
True -> String
"true"
CondBool Bool
False -> String
"false"
renderDirectories :: String -> [String] -> Element
renderDirectories :: String -> [String] -> Element
renderDirectories String
name = String -> Value -> Element
Field String
name forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
LineSeparatedList forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
replaceDots
where
replaceDots :: [String] -> [String]
replaceDots = forall a b. (a -> b) -> [a] -> [b]
map forall {a}. (Eq a, IsString a) => a -> a
replaceDot
replaceDot :: a -> a
replaceDot a
xs = case a
xs of
a
"." -> a
"./"
a
_ -> a
xs
renderExposedModules :: [Module] -> Element
renderExposedModules :: [Module] -> Element
renderExposedModules = String -> Value -> Element
Field String
"exposed-modules" forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
LineSeparatedList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map Module -> String
unModule
renderOtherModules :: [Module] -> Element
renderOtherModules :: [Module] -> Element
renderOtherModules = String -> Value -> Element
Field String
"other-modules" forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
LineSeparatedList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map Module -> String
unModule
renderGeneratedModules :: [Module] -> Element
renderGeneratedModules :: [Module] -> Element
renderGeneratedModules = String -> Value -> Element
Field String
"autogen-modules" forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
LineSeparatedList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map Module -> String
unModule
renderReexportedModules :: [String] -> Element
renderReexportedModules :: [String] -> Element
renderReexportedModules = String -> Value -> Element
Field String
"reexported-modules" forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
CommaSeparatedList
renderSignatures :: [String] -> Element
renderSignatures :: [String] -> Element
renderSignatures = String -> Value -> Element
Field String
"signatures" forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
CommaSeparatedList
renderDependencies :: String -> Dependencies -> [Element]
renderDependencies :: String -> Dependencies -> [Element]
renderDependencies String
name Dependencies
deps = [
String -> Value -> Element
Field String
name ([String] -> Value
CommaSeparatedList [String]
renderedDeps)
, String -> Value -> Element
Field String
"mixins" ([String] -> Value
CommaSeparatedList forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[String]]
mixins)
]
where
([String]
renderedDeps, [[String]]
mixins) = forall a b. [(a, b)] -> ([a], [b])
unzip forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (String, DependencyInfo) -> (String, [String])
renderDependency forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [(k, a)]
Map.toList forall a b. (a -> b) -> a -> b
$ Dependencies -> Map String DependencyInfo
unDependencies Dependencies
deps
renderDependency :: (String, DependencyInfo) -> (String, [String])
renderDependency :: (String, DependencyInfo) -> (String, [String])
renderDependency (String
name, DependencyInfo [String]
mixins DependencyVersion
version) = (
String
name forall a. [a] -> [a] -> [a]
++ DependencyVersion -> String
renderVersion DependencyVersion
version
, [ String
name forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ String
mixin | String
mixin <- [String]
mixins ]
)
renderVersion :: DependencyVersion -> String
renderVersion :: DependencyVersion -> String
renderVersion (DependencyVersion Maybe SourceDependency
_ VersionConstraint
c) = VersionConstraint -> String
renderVersionConstraint VersionConstraint
c
renderVersionConstraint :: VersionConstraint -> String
renderVersionConstraint :: VersionConstraint -> String
renderVersionConstraint VersionConstraint
version = case VersionConstraint
version of
VersionConstraint
AnyVersion -> String
""
VersionRange String
x -> String
" " forall a. [a] -> [a] -> [a]
++ String
x
renderBuildTools :: Map BuildTool DependencyVersion -> SystemBuildTools -> [Element]
renderBuildTools :: Map BuildTool DependencyVersion -> SystemBuildTools -> [Element]
renderBuildTools (forall a b. (a -> b) -> [a] -> [b]
map (BuildTool, DependencyVersion) -> RenderBuildTool
renderBuildTool forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [(k, a)]
Map.toList -> [RenderBuildTool]
xs) SystemBuildTools
systemBuildTools = [
String -> Value -> Element
Field String
"build-tools" ([String] -> Value
CommaSeparatedList forall a b. (a -> b) -> a -> b
$ [String
x | BuildTools String
x <- [RenderBuildTool]
xs] forall a. [a] -> [a] -> [a]
++ SystemBuildTools -> [String]
renderSystemBuildTools SystemBuildTools
systemBuildTools)
, String -> Value -> Element
Field String
"build-tool-depends" ([String] -> Value
CommaSeparatedList [String
x | BuildToolDepends String
x <- [RenderBuildTool]
xs])
]
data RenderBuildTool = BuildTools String | BuildToolDepends String
renderBuildTool :: (BuildTool, DependencyVersion) -> RenderBuildTool
renderBuildTool :: (BuildTool, DependencyVersion) -> RenderBuildTool
renderBuildTool (BuildTool
buildTool, DependencyVersion -> String
renderVersion -> String
version) = case BuildTool
buildTool of
LocalBuildTool String
executable -> String -> RenderBuildTool
BuildTools (String
executable forall a. [a] -> [a] -> [a]
++ String
version)
BuildTool String
pkg String
executable
| String
pkg forall a. Eq a => a -> a -> Bool
== String
executable Bool -> Bool -> Bool
&& String
executable forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
knownBuildTools -> String -> RenderBuildTool
BuildTools (String
executable forall a. [a] -> [a] -> [a]
++ String
version)
| Bool
otherwise -> String -> RenderBuildTool
BuildToolDepends (String
pkg forall a. [a] -> [a] -> [a]
++ String
":" forall a. [a] -> [a] -> [a]
++ String
executable forall a. [a] -> [a] -> [a]
++ String
version)
where
knownBuildTools :: [String]
knownBuildTools :: [String]
knownBuildTools = [
String
"alex"
, String
"c2hs"
, String
"cpphs"
, String
"greencard"
, String
"haddock"
, String
"happy"
, String
"hsc2hs"
, String
"hscolour"
]
renderSystemBuildTools :: SystemBuildTools -> [String]
renderSystemBuildTools :: SystemBuildTools -> [String]
renderSystemBuildTools = forall a b. (a -> b) -> [a] -> [b]
map (String, VersionConstraint) -> String
renderSystemBuildTool forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [(k, a)]
Map.toList forall b c a. (b -> c) -> (a -> b) -> a -> c
. SystemBuildTools -> Map String VersionConstraint
unSystemBuildTools
renderSystemBuildTool :: (String, VersionConstraint) -> String
renderSystemBuildTool :: (String, VersionConstraint) -> String
renderSystemBuildTool (String
name, VersionConstraint
constraint) = String
name forall a. [a] -> [a] -> [a]
++ VersionConstraint -> String
renderVersionConstraint VersionConstraint
constraint
renderLanguage :: Language -> Element
renderLanguage :: Language -> Element
renderLanguage (Language String
lang) = String -> Value -> Element
Field String
"default-language" (String -> Value
Literal String
lang)
renderGhcOptions :: [GhcOption] -> Element
renderGhcOptions :: [String] -> Element
renderGhcOptions = String -> Value -> Element
Field String
"ghc-options" forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList
renderGhcProfOptions :: [GhcProfOption] -> Element
renderGhcProfOptions :: [String] -> Element
renderGhcProfOptions = String -> Value -> Element
Field String
"ghc-prof-options" forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList
renderGhcSharedOptions :: [GhcOption] -> Element
renderGhcSharedOptions :: [String] -> Element
renderGhcSharedOptions = String -> Value -> Element
Field String
"ghc-shared-options" forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList
renderGhcjsOptions :: [GhcjsOption] -> Element
renderGhcjsOptions :: [String] -> Element
renderGhcjsOptions = String -> Value -> Element
Field String
"ghcjs-options" forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList
renderCppOptions :: [CppOption] -> Element
renderCppOptions :: [String] -> Element
renderCppOptions = String -> Value -> Element
Field String
"cpp-options" forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList
renderCcOptions :: [CcOption] -> Element
renderCcOptions :: [String] -> Element
renderCcOptions = String -> Value -> Element
Field String
"cc-options" forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList
renderCxxOptions :: [CxxOption] -> Element
renderCxxOptions :: [String] -> Element
renderCxxOptions = String -> Value -> Element
Field String
"cxx-options" forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList
renderLdOptions :: [LdOption] -> Element
renderLdOptions :: [String] -> Element
renderLdOptions = String -> Value -> Element
Field String
"ld-options" forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList
renderBuildable :: Bool -> Element
renderBuildable :: Bool -> Element
renderBuildable = String -> Value -> Element
Field String
"buildable" forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value
Literal forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show
renderDefaultExtensions :: [String] -> Element
renderDefaultExtensions :: [String] -> Element
renderDefaultExtensions = String -> Value -> Element
Field String
"default-extensions" forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
LineSeparatedList
renderOtherExtensions :: [String] -> Element
renderOtherExtensions :: [String] -> Element
renderOtherExtensions = String -> Value -> Element
Field String
"other-extensions" forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
LineSeparatedList
renderPaths :: [Path] -> Value
renderPaths :: [Path] -> Value
renderPaths = [String] -> Value
LineSeparatedList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map Path -> String
renderPath
where
renderPath :: Path -> FilePath
renderPath :: Path -> String
renderPath (Path String
path)
| String -> Bool
needsQuoting String
path = forall a. Show a => a -> String
show String
path
| Bool
otherwise = String
path
needsQuoting :: FilePath -> Bool
needsQuoting :: String -> Bool
needsQuoting = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\Char
x -> Char -> Bool
isSpace Char
x Bool -> Bool -> Bool
|| Char
x forall a. Eq a => a -> a -> Bool
== Char
',')
sortFieldsBy :: [String] -> [Element] -> [Element]
sortFieldsBy :: [String] -> [Element] -> [Element]
sortFieldsBy [String]
existingFieldOrder = [String] -> [Element] -> [Element]
Dsl.sortFieldsBy (String
"import" forall a. a -> [a] -> [a]
: [String]
existingFieldOrder)