{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE CPP #-}
module Hpack.Render (
-- | /__NOTE:__/ This module is exposed to allow integration of Hpack into
-- other tools.  It is not meant for general use by end users.  The following
-- caveats apply:
--
-- * The API is undocumented, consult the source instead.
--
-- * The exposed types and functions primarily serve Hpack's own needs, not
-- that of a public API.  Breaking changes can happen as Hpack evolves.
--
-- As an Hpack user you either want to use the @hpack@ executable or a build
-- tool that supports Hpack (e.g. @stack@ or @cabal2nix@).

  renderPackage
, renderPackageWith
, defaultRenderSettings
, RenderSettings(..)
, Alignment(..)
, CommaStyle(..)
#ifdef TEST
, renderConditional
, renderDependencies
, renderLibraryFields
, renderExecutableFields
, renderFlag
, renderSourceRepository
, renderDirectories
, formatDescription
#endif
) where

import           Control.Monad
import           Data.Char
import           Data.Maybe
import           Data.List
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

renderPackage :: [String] -> Package -> String
renderPackage :: [String] -> Package -> String
renderPackage oldCabalFile :: [String]
oldCabalFile = RenderSettings
-> Alignment
-> [String]
-> [(String, [String])]
-> Package
-> String
renderPackageWith RenderSettings
settings Alignment
alignment [String]
formattingHintsFieldOrder [(String, [String])]
formattingHintsSectionsFieldOrder
  where
    FormattingHints{..} = [String] -> FormattingHints
sniffFormattingHints [String]
oldCabalFile
    alignment :: Alignment
alignment = Alignment -> Maybe Alignment -> Alignment
forall a. a -> Maybe a -> a
fromMaybe 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 settings :: RenderSettings
settings headerFieldsAlignment :: Alignment
headerFieldsAlignment existingFieldOrder :: [String]
existingFieldOrder sectionsFieldOrder :: [(String, [String])]
sectionsFieldOrder Package{..} = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate "\n" ([String] -> String
unlines [String]
header String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
chunks)
  where
    chunks :: [String]
    chunks :: [String]
chunks = ([String] -> String) -> [[String]] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map [String] -> String
unlines ([[String]] -> [String])
-> ([Element] -> [[String]]) -> [Element] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String] -> Bool) -> [[String]] -> [[String]]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> ([String] -> Bool) -> [String] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null) ([[String]] -> [[String]])
-> ([Element] -> [[String]]) -> [Element] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Element -> [String]) -> [Element] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map (RenderSettings -> Nesting -> Element -> [String]
render RenderSettings
settings 0) ([Element] -> [String]) -> [Element] -> [String]
forall a b. (a -> b) -> a -> b
$ [(String, [String])] -> [Element] -> [Element]
sortStanzaFields [(String, [String])]
sectionsFieldOrder [Element]
stanzas

    header :: [String]
    header :: [String]
header = (Element -> [String]) -> [Element] -> [String]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (RenderSettings -> Nesting -> Element -> [String]
render RenderSettings
settings {renderSettingsFieldAlignment :: Alignment
renderSettingsFieldAlignment = Alignment
headerFieldsAlignment} 0) [Element]
packageFields

    packageFields :: [Element]
    packageFields :: [Element]
packageFields = [Verbatim] -> [Element] -> [Element]
addVerbatim [Verbatim]
packageVerbatim ([Element] -> [Element])
-> ([Element] -> [Element]) -> [Element] -> [Element]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [Element] -> [Element]
sortFieldsBy [String]
existingFieldOrder ([Element] -> [Element]) -> [Element] -> [Element]
forall a b. (a -> b) -> a -> b
$
      [Element]
headerFields [Element] -> [Element] -> [Element]
forall a. [a] -> [a] -> [a]
++ [
        String -> Value -> Element
Field "extra-source-files" ([Path] -> Value
renderPaths [Path]
packageExtraSourceFiles)
      , String -> Value -> Element
Field "extra-doc-files" ([Path] -> Value
renderPaths [Path]
packageExtraDocFiles)
      , String -> Value -> Element
Field "data-files" ([Path] -> Value
renderPaths [Path]
packageDataFiles)
      ] [Element] -> [Element] -> [Element]
forall a. [a] -> [a] -> [a]
++ [Element] -> (String -> [Element]) -> Maybe String -> [Element]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Element -> [Element]
forall (m :: * -> *) a. Monad m => a -> m a
return (Element -> [Element])
-> (String -> Element) -> String -> [Element]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value -> Element
Field "data-dir" (Value -> Element) -> (String -> Value) -> String -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value
Literal) Maybe String
packageDataDir

    sourceRepository :: [Element]
    sourceRepository :: [Element]
sourceRepository = [Element]
-> (SourceRepository -> [Element])
-> Maybe SourceRepository
-> [Element]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Element -> [Element]
forall (m :: * -> *) a. Monad m => a -> m a
return (Element -> [Element])
-> (SourceRepository -> Element) -> SourceRepository -> [Element]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourceRepository -> Element
renderSourceRepository) Maybe SourceRepository
packageSourceRepository

    customSetup :: [Element]
    customSetup :: [Element]
customSetup = [Element]
-> (CustomSetup -> [Element]) -> Maybe CustomSetup -> [Element]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Element -> [Element]
forall (m :: * -> *) a. Monad m => a -> m a
return (Element -> [Element])
-> (CustomSetup -> Element) -> CustomSetup -> [Element]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CustomSetup -> Element
renderCustomSetup) Maybe CustomSetup
packageCustomSetup

    library :: [Element]
    library :: [Element]
library = [Element]
-> (Section Library -> [Element])
-> Maybe (Section Library)
-> [Element]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Element -> [Element]
forall (m :: * -> *) a. Monad m => a -> m a
return (Element -> [Element])
-> (Section Library -> Element) -> Section Library -> [Element]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Section Library -> Element
renderLibrary) Maybe (Section Library)
packageLibrary

    stanzas :: [Element]
    stanzas :: [Element]
stanzas = [[Element]] -> [Element]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [
        [Element]
sourceRepository
      , [Element]
customSetup
      , (Flag -> Element) -> [Flag] -> [Element]
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 = ((String, Maybe String) -> Maybe Element)
-> [(String, Maybe String)] -> [Element]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (\(name :: String
name, value :: Maybe String
value) -> String -> Value -> Element
Field String
name (Value -> Element) -> (String -> Value) -> String -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value
Literal (String -> Element) -> Maybe String -> Maybe Element
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe String
value) ([(String, Maybe String)] -> [Element])
-> [(String, Maybe String)] -> [Element]
forall a b. (a -> b) -> a -> b
$ [
        ("name", String -> Maybe String
forall a. a -> Maybe a
Just String
packageName)
      , ("version", String -> Maybe String
forall a. a -> Maybe a
Just String
packageVersion)
      , ("synopsis", Maybe String
packageSynopsis)
      , ("description", (Alignment -> String -> String
formatDescription Alignment
headerFieldsAlignment (String -> String) -> Maybe String -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe String
packageDescription))
      , ("category", Maybe String
packageCategory)
      , ("stability", Maybe String
packageStability)
      , ("homepage", Maybe String
packageHomepage)
      , ("bug-reports", Maybe String
packageBugReports)
      , ("author", [String] -> Maybe String
formatList [String]
packageAuthor)
      , ("maintainer", [String] -> Maybe String
formatList [String]
packageMaintainer)
      , ("copyright", [String] -> Maybe String
formatList [String]
packageCopyright)
      , ("license", Maybe String
packageLicense)
      , case [String]
packageLicenseFile of
          [file :: String
file] -> ("license-file", String -> Maybe String
forall a. a -> Maybe a
Just String
file)
          files :: [String]
files  -> ("license-files", [String] -> Maybe String
formatList [String]
files)
      , ("tested-with", Maybe String
packageTestedWith)
      , ("build-type", String -> Maybe String
forall a. a -> Maybe a
Just (BuildType -> String
forall a. Show a => a -> String
show BuildType
packageBuildType))
      ]

    formatList :: [String] -> Maybe String
    formatList :: [String] -> Maybe String
formatList xs :: [String]
xs = Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
xs) Maybe () -> Maybe String -> Maybe String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
separator [String]
xs)
      where
        separator :: String
separator = let Alignment n :: Int
n = Alignment
headerFieldsAlignment in ",\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
n ' '

sortStanzaFields :: [(String, [String])] -> [Element] -> [Element]
sortStanzaFields :: [(String, [String])] -> [Element] -> [Element]
sortStanzaFields sectionsFieldOrder :: [(String, [String])]
sectionsFieldOrder = [Element] -> [Element]
go
  where
    go :: [Element] -> [Element]
go sections :: [Element]
sections = case [Element]
sections of
      [] -> []
      Stanza name :: String
name fields :: [Element]
fields : xs :: [Element]
xs | Just fieldOrder :: [String]
fieldOrder <- String -> [(String, [String])] -> Maybe [String]
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) Element -> [Element] -> [Element]
forall a. a -> [a] -> [a]
: [Element] -> [Element]
go [Element]
xs
      x :: Element
x : xs :: [Element]
xs -> Element
x Element -> [Element] -> [Element]
forall a. a -> [a] -> [a]
: [Element] -> [Element]
go [Element]
xs

formatDescription :: Alignment -> String -> String
formatDescription :: Alignment -> String -> String
formatDescription (Alignment alignment :: Int
alignment) description :: String
description = case (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
emptyLineToDot ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ String -> [String]
lines String
description of
  x :: String
x : xs :: [String]
xs -> String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate "\n" (String
x String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String
indentation String -> String -> String
forall a. [a] -> [a] -> [a]
++) [String]
xs)
  [] -> ""
  where
    n :: Int
n = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
alignment (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ("description: " :: String))
    indentation :: String
indentation = Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
n ' '

    emptyLineToDot :: String -> String
emptyLineToDot xs :: String
xs
      | String -> Bool
isEmptyLine String
xs = "."
      | Bool
otherwise = String
xs

    isEmptyLine :: String -> Bool
isEmptyLine = (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isSpace

renderSourceRepository :: SourceRepository -> Element
renderSourceRepository :: SourceRepository -> Element
renderSourceRepository SourceRepository{..} = String -> [Element] -> Element
Stanza "source-repository head" [
    String -> Value -> Element
Field "type" "git"
  , String -> Value -> Element
Field "location" (String -> Value
Literal String
sourceRepositoryUrl)
  , String -> Value -> Element
Field "subdir" (Value -> (String -> Value) -> Maybe String -> Value
forall b a. b -> (a -> b) -> Maybe a -> b
maybe "" String -> Value
Literal Maybe String
sourceRepositorySubdir)
  ]

renderFlag :: Flag -> Element
renderFlag :: Flag -> Element
renderFlag Flag {..} = String -> [Element] -> Element
Stanza ("flag " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
flagName) ([Element] -> Element) -> [Element] -> Element
forall a b. (a -> b) -> a -> b
$ [Element]
description [Element] -> [Element] -> [Element]
forall a. [a] -> [a] -> [a]
++ [
    String -> Value -> Element
Field "manual" (String -> Value
Literal (String -> Value) -> String -> Value
forall a b. (a -> b) -> a -> b
$ Bool -> String
forall a. Show a => a -> String
show Bool
flagManual)
  , String -> Value -> Element
Field "default" (String -> Value
Literal (String -> Value) -> String -> Value
forall a b. (a -> b) -> a -> b
$ Bool -> String
forall a. Show a => a -> String
show Bool
flagDefault)
  ]
  where
    description :: [Element]
description = [Element] -> (String -> [Element]) -> Maybe String -> [Element]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Element -> [Element]
forall (m :: * -> *) a. Monad m => a -> m a
return (Element -> [Element])
-> (String -> Element) -> String -> [Element]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value -> Element
Field "description" (Value -> Element) -> (String -> Value) -> String -> Element
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 = ((String, Section Library) -> Element)
-> [(String, Section Library)] -> [Element]
forall a b. (a -> b) -> [a] -> [b]
map (String, Section Library) -> Element
renderInternalLibrary ([(String, Section Library)] -> [Element])
-> (Map String (Section Library) -> [(String, Section Library)])
-> Map String (Section Library)
-> [Element]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map String (Section Library) -> [(String, Section Library)]
forall k a. Map k a -> [(k, a)]
Map.toList

renderInternalLibrary :: (String, Section Library) -> Element
renderInternalLibrary :: (String, Section Library) -> Element
renderInternalLibrary (name :: String
name, sect :: Section Library
sect) =
  String -> [Element] -> Element
Stanza ("library " String -> String -> String
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 = ((String, Section Executable) -> Element)
-> [(String, Section Executable)] -> [Element]
forall a b. (a -> b) -> [a] -> [b]
map (String, Section Executable) -> Element
renderExecutable ([(String, Section Executable)] -> [Element])
-> (Map String (Section Executable)
    -> [(String, Section Executable)])
-> Map String (Section Executable)
-> [Element]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map String (Section Executable) -> [(String, Section Executable)]
forall k a. Map k a -> [(k, a)]
Map.toList

renderExecutable :: (String, Section Executable) -> Element
renderExecutable :: (String, Section Executable) -> Element
renderExecutable (name :: String
name, sect :: Section Executable
sect@(Section Executable -> Executable
forall a. Section a -> a
sectionData -> Executable{..})) =
  String -> [Element] -> Element
Stanza ("executable " String -> String -> String
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 = ((String, Section Executable) -> Element)
-> [(String, Section Executable)] -> [Element]
forall a b. (a -> b) -> [a] -> [b]
map (String, Section Executable) -> Element
renderTest ([(String, Section Executable)] -> [Element])
-> (Map String (Section Executable)
    -> [(String, Section Executable)])
-> Map String (Section Executable)
-> [Element]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map String (Section Executable) -> [(String, Section Executable)]
forall k a. Map k a -> [(k, a)]
Map.toList

renderTest :: (String, Section Executable) -> Element
renderTest :: (String, Section Executable) -> Element
renderTest (name :: String
name, sect :: Section Executable
sect) =
  String -> [Element] -> Element
Stanza ("test-suite " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name)
    ([Element] -> Section Executable -> [Element]
renderExecutableSection [String -> Value -> Element
Field "type" "exitcode-stdio-1.0"] Section Executable
sect)

renderBenchmarks :: Map String (Section Executable) -> [Element]
renderBenchmarks :: Map String (Section Executable) -> [Element]
renderBenchmarks = ((String, Section Executable) -> Element)
-> [(String, Section Executable)] -> [Element]
forall a b. (a -> b) -> [a] -> [b]
map (String, Section Executable) -> Element
renderBenchmark ([(String, Section Executable)] -> [Element])
-> (Map String (Section Executable)
    -> [(String, Section Executable)])
-> Map String (Section Executable)
-> [Element]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map String (Section Executable) -> [(String, Section Executable)]
forall k a. Map k a -> [(k, a)]
Map.toList

renderBenchmark :: (String, Section Executable) -> Element
renderBenchmark :: (String, Section Executable) -> Element
renderBenchmark (name :: String
name, sect :: Section Executable
sect) =
  String -> [Element] -> Element
Stanza ("benchmark " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name)
    ([Element] -> Section Executable -> [Element]
renderExecutableSection [String -> Value -> Element
Field "type" "exitcode-stdio-1.0"] Section Executable
sect)

renderExecutableSection :: [Element] -> Section Executable -> [Element]
renderExecutableSection :: [Element] -> Section Executable -> [Element]
renderExecutableSection extraFields :: [Element]
extraFields = (Executable -> [Element])
-> [Element] -> [Element] -> Section Executable -> [Element]
forall a.
(a -> [Element])
-> [Element] -> [Element] -> Section a -> [Element]
renderSection Executable -> [Element]
renderExecutableFields [Element]
extraFields [Element
defaultLanguage]

renderExecutableFields :: Executable -> [Element]
renderExecutableFields :: Executable -> [Element]
renderExecutableFields Executable{..} = [Element]
mainIs [Element] -> [Element] -> [Element]
forall a. [a] -> [a] -> [a]
++ [Element
otherModules, Element
generatedModules]
  where
    mainIs :: [Element]
mainIs = [Element] -> (String -> [Element]) -> Maybe String -> [Element]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Element -> [Element]
forall (m :: * -> *) a. Monad m => a -> m a
return (Element -> [Element])
-> (String -> Element) -> String -> [Element]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value -> Element
Field "main-is" (Value -> Element) -> (String -> Value) -> String -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value
Literal) Maybe String
executableMain
    otherModules :: Element
otherModules = [String] -> Element
renderOtherModules [String]
executableOtherModules
    generatedModules :: Element
generatedModules = [String] -> Element
renderGeneratedModules [String]
executableGeneratedModules

renderCustomSetup :: CustomSetup -> Element
renderCustomSetup :: CustomSetup -> Element
renderCustomSetup CustomSetup{..} =
  String -> [Element] -> Element
Stanza "custom-setup" ([Element] -> Element) -> [Element] -> Element
forall a b. (a -> b) -> a -> b
$ String -> Dependencies -> [Element]
renderDependencies "setup-depends" Dependencies
customSetupDependencies

renderLibrary :: Section Library -> Element
renderLibrary :: Section Library -> Element
renderLibrary sect :: Section Library
sect = String -> [Element] -> Element
Stanza "library" ([Element] -> Element) -> [Element] -> Element
forall a b. (a -> b) -> a -> b
$ Section Library -> [Element]
renderLibrarySection Section Library
sect

renderLibrarySection :: Section Library -> [Element]
renderLibrarySection :: Section Library -> [Element]
renderLibrarySection = (Library -> [Element])
-> [Element] -> [Element] -> Section Library -> [Element]
forall a.
(a -> [Element])
-> [Element] -> [Element] -> Section a -> [Element]
renderSection Library -> [Element]
renderLibraryFields [] [Element
defaultLanguage]

renderLibraryFields :: Library -> [Element]
renderLibraryFields :: Library -> [Element]
renderLibraryFields Library{..} =
  [Element] -> (Bool -> [Element]) -> Maybe Bool -> [Element]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Element -> [Element]
forall (m :: * -> *) a. Monad m => a -> m a
return (Element -> [Element]) -> (Bool -> Element) -> Bool -> [Element]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Element
renderExposed) Maybe Bool
libraryExposed [Element] -> [Element] -> [Element]
forall a. [a] -> [a] -> [a]
++ [
    [String] -> Element
renderExposedModules [String]
libraryExposedModules
  , [String] -> Element
renderOtherModules [String]
libraryOtherModules
  , [String] -> Element
renderGeneratedModules [String]
libraryGeneratedModules
  , [String] -> Element
renderReexportedModules [String]
libraryReexportedModules
  , [String] -> Element
renderSignatures [String]
librarySignatures
  ]

renderExposed :: Bool -> Element
renderExposed :: Bool -> Element
renderExposed = String -> Value -> Element
Field "exposed" (Value -> Element) -> (Bool -> Value) -> Bool -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value
Literal (String -> Value) -> (Bool -> String) -> Bool -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> String
forall a. Show a => a -> String
show

renderSection :: (a -> [Element]) -> [Element] -> [Element] -> Section a -> [Element]
renderSection :: (a -> [Element])
-> [Element] -> [Element] -> Section a -> [Element]
renderSection renderSectionData :: a -> [Element]
renderSectionData extraFieldsStart :: [Element]
extraFieldsStart extraFieldsEnd :: [Element]
extraFieldsEnd Section{..} = [Verbatim] -> [Element] -> [Element]
addVerbatim [Verbatim]
sectionVerbatim ([Element] -> [Element]) -> [Element] -> [Element]
forall a b. (a -> b) -> a -> b
$
     [Element]
extraFieldsStart
  [Element] -> [Element] -> [Element]
forall a. [a] -> [a] -> [a]
++ a -> [Element]
renderSectionData a
sectionData [Element] -> [Element] -> [Element]
forall a. [a] -> [a] -> [a]
++ [
    String -> [String] -> Element
renderDirectories "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
renderGhcjsOptions [String]
sectionGhcjsOptions
  , [String] -> Element
renderCppOptions [String]
sectionCppOptions
  , [String] -> Element
renderCcOptions [String]
sectionCcOptions
  , [String] -> Element
renderCxxOptions [String]
sectionCxxOptions
  , String -> [String] -> Element
renderDirectories "include-dirs" [String]
sectionIncludeDirs
  , String -> Value -> Element
Field "install-includes" ([String] -> Value
LineSeparatedList [String]
sectionInstallIncludes)
  , String -> Value -> Element
Field "c-sources" ([Path] -> Value
renderPaths [Path]
sectionCSources)
  , String -> Value -> Element
Field "cxx-sources" ([Path] -> Value
renderPaths [Path]
sectionCxxSources)
  , String -> Value -> Element
Field "js-sources" ([Path] -> Value
renderPaths [Path]
sectionJsSources)
  , String -> [String] -> Element
renderDirectories "extra-lib-dirs" [String]
sectionExtraLibDirs
  , String -> Value -> Element
Field "extra-libraries" ([String] -> Value
LineSeparatedList [String]
sectionExtraLibraries)
  , String -> [String] -> Element
renderDirectories "extra-frameworks-dirs" [String]
sectionExtraFrameworksDirs
  , String -> Value -> Element
Field "frameworks" ([String] -> Value
LineSeparatedList [String]
sectionFrameworks)
  , [String] -> Element
renderLdOptions [String]
sectionLdOptions
  , String -> Value -> Element
Field "pkgconfig-depends" ([String] -> Value
CommaSeparatedList [String]
sectionPkgConfigDependencies)
  ]
  [Element] -> [Element] -> [Element]
forall a. [a] -> [a] -> [a]
++ Map BuildTool DependencyVersion -> SystemBuildTools -> [Element]
renderBuildTools Map BuildTool DependencyVersion
sectionBuildTools SystemBuildTools
sectionSystemBuildTools
  [Element] -> [Element] -> [Element]
forall a. [a] -> [a] -> [a]
++ String -> Dependencies -> [Element]
renderDependencies "build-depends" Dependencies
sectionDependencies
  [Element] -> [Element] -> [Element]
forall a. [a] -> [a] -> [a]
++ [Element] -> (Bool -> [Element]) -> Maybe Bool -> [Element]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Element -> [Element]
forall (m :: * -> *) a. Monad m => a -> m a
return (Element -> [Element]) -> (Bool -> Element) -> Bool -> [Element]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Element
renderBuildable) Maybe Bool
sectionBuildable
  [Element] -> [Element] -> [Element]
forall a. [a] -> [a] -> [a]
++ (Conditional (Section a) -> Element)
-> [Conditional (Section a)] -> [Element]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> [Element]) -> Conditional (Section a) -> Element
forall a. (a -> [Element]) -> Conditional (Section a) -> Element
renderConditional a -> [Element]
renderSectionData) [Conditional (Section a)]
sectionConditionals
  [Element] -> [Element] -> [Element]
forall a. [a] -> [a] -> [a]
++ [Element]
extraFieldsEnd

addVerbatim :: [Verbatim] -> [Element] -> [Element]
addVerbatim :: [Verbatim] -> [Element] -> [Element]
addVerbatim verbatim :: [Verbatim]
verbatim fields :: [Element]
fields = [Verbatim] -> [Element] -> [Element]
filterVerbatim [Verbatim]
verbatim [Element]
fields [Element] -> [Element] -> [Element]
forall a. [a] -> [a] -> [a]
++ [Verbatim] -> [Element]
renderVerbatim [Verbatim]
verbatim

filterVerbatim :: [Verbatim] -> [Element] -> [Element]
filterVerbatim :: [Verbatim] -> [Element] -> [Element]
filterVerbatim verbatim :: [Verbatim]
verbatim = (Element -> Bool) -> [Element] -> [Element]
forall a. (a -> Bool) -> [a] -> [a]
filter Element -> Bool
p
  where
    p :: Element -> Bool
    p :: Element -> Bool
p = \ case
      Field name :: String
name _ -> String
name String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [String]
fields
      _ -> Bool
True
    fields :: [String]
fields = (Verbatim -> [String]) -> [Verbatim] -> [String]
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
verbatim = case Verbatim
verbatim of
  VerbatimLiteral _ -> []
  VerbatimObject o :: Map String VerbatimValue
o -> Map String VerbatimValue -> [String]
forall k a. Map k a -> [k]
Map.keys Map String VerbatimValue
o

renderVerbatim :: [Verbatim] -> [Element]
renderVerbatim :: [Verbatim] -> [Element]
renderVerbatim = (Verbatim -> [Element]) -> [Verbatim] -> [Element]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Verbatim -> [Element]) -> [Verbatim] -> [Element])
-> (Verbatim -> [Element]) -> [Verbatim] -> [Element]
forall a b. (a -> b) -> a -> b
$ \ case
  VerbatimLiteral s :: String
s -> [String -> Element
Verbatim String
s]
  VerbatimObject o :: Map String VerbatimValue
o -> Map String VerbatimValue -> [Element]
renderVerbatimObject Map String VerbatimValue
o

renderVerbatimObject :: Map String VerbatimValue -> [Element]
renderVerbatimObject :: Map String VerbatimValue -> [Element]
renderVerbatimObject = ((String, VerbatimValue) -> Element)
-> [(String, VerbatimValue)] -> [Element]
forall a b. (a -> b) -> [a] -> [b]
map (String, VerbatimValue) -> Element
renderPair ([(String, VerbatimValue)] -> [Element])
-> (Map String VerbatimValue -> [(String, VerbatimValue)])
-> Map String VerbatimValue
-> [Element]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map String VerbatimValue -> [(String, VerbatimValue)]
forall k a. Map k a -> [(k, a)]
Map.toList
  where
    renderPair :: (String, VerbatimValue) -> Element
renderPair (key :: String
key, value :: VerbatimValue
value) = case String -> [String]
lines (VerbatimValue -> String
verbatimValueToString VerbatimValue
value) of
      [x :: String
x] -> String -> Value -> Element
Field String
key (String -> Value
Literal String
x)
      xs :: [String]
xs -> String -> Value -> Element
Field String
key ([String] -> Value
LineSeparatedList [String]
xs)

renderConditional :: (a -> [Element]) -> Conditional (Section a) -> Element
renderConditional :: (a -> [Element]) -> Conditional (Section a) -> Element
renderConditional renderSectionData :: a -> [Element]
renderSectionData (Conditional condition :: String
condition sect :: Section a
sect mElse :: Maybe (Section a)
mElse) = case Maybe (Section a)
mElse of
  Nothing -> Element
if_
  Just else_ :: Section a
else_ -> Element -> Element -> Element
Group Element
if_ (String -> [Element] -> Element
Stanza "else" ([Element] -> Element) -> [Element] -> Element
forall a b. (a -> b) -> a -> b
$ (a -> [Element])
-> [Element] -> [Element] -> Section a -> [Element]
forall a.
(a -> [Element])
-> [Element] -> [Element] -> Section a -> [Element]
renderSection a -> [Element]
renderSectionData [] [] Section a
else_)
  where
    if_ :: Element
if_ = String -> [Element] -> Element
Stanza ("if " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
condition) ((a -> [Element])
-> [Element] -> [Element] -> Section a -> [Element]
forall a.
(a -> [Element])
-> [Element] -> [Element] -> Section a -> [Element]
renderSection a -> [Element]
renderSectionData [] [] Section a
sect)

defaultLanguage :: Element
defaultLanguage :: Element
defaultLanguage = String -> Value -> Element
Field "default-language" "Haskell2010"

renderDirectories :: String -> [String] -> Element
renderDirectories :: String -> [String] -> Element
renderDirectories name :: String
name = String -> Value -> Element
Field String
name (Value -> Element) -> ([String] -> Value) -> [String] -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
LineSeparatedList ([String] -> Value) -> ([String] -> [String]) -> [String] -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
replaceDots
  where
    replaceDots :: [String] -> [String]
replaceDots = (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall p. (Eq p, IsString p) => p -> p
replaceDot
    replaceDot :: p -> p
replaceDot xs :: p
xs = case p
xs of
      "." -> "./."
      _ -> p
xs

renderExposedModules :: [String] -> Element
renderExposedModules :: [String] -> Element
renderExposedModules = String -> Value -> Element
Field "exposed-modules" (Value -> Element) -> ([String] -> Value) -> [String] -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
LineSeparatedList

renderOtherModules :: [String] -> Element
renderOtherModules :: [String] -> Element
renderOtherModules = String -> Value -> Element
Field "other-modules" (Value -> Element) -> ([String] -> Value) -> [String] -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
LineSeparatedList

renderGeneratedModules :: [String] -> Element
renderGeneratedModules :: [String] -> Element
renderGeneratedModules = String -> Value -> Element
Field "autogen-modules" (Value -> Element) -> ([String] -> Value) -> [String] -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
LineSeparatedList

renderReexportedModules :: [String] -> Element
renderReexportedModules :: [String] -> Element
renderReexportedModules = String -> Value -> Element
Field "reexported-modules" (Value -> Element) -> ([String] -> Value) -> [String] -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
CommaSeparatedList

renderSignatures :: [String] -> Element
renderSignatures :: [String] -> Element
renderSignatures = String -> Value -> Element
Field "signatures" (Value -> Element) -> ([String] -> Value) -> [String] -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
CommaSeparatedList

renderDependencies :: String -> Dependencies -> [Element]
renderDependencies :: String -> Dependencies -> [Element]
renderDependencies name :: String
name deps :: Dependencies
deps = [
    String -> Value -> Element
Field String
name ([String] -> Value
CommaSeparatedList [String]
renderedDeps)
  , String -> Value -> Element
Field "mixins" ([String] -> Value
CommaSeparatedList ([String] -> Value) -> [String] -> Value
forall a b. (a -> b) -> a -> b
$ [[String]] -> [String]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[String]]
mixins)
  ]
  where
    (renderedDeps :: [String]
renderedDeps, mixins :: [[String]]
mixins) = [(String, [String])] -> ([String], [[String]])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(String, [String])] -> ([String], [[String]]))
-> (Map String DependencyInfo -> [(String, [String])])
-> Map String DependencyInfo
-> ([String], [[String]])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, DependencyInfo) -> (String, [String]))
-> [(String, DependencyInfo)] -> [(String, [String])]
forall a b. (a -> b) -> [a] -> [b]
map (String, DependencyInfo) -> (String, [String])
renderDependency ([(String, DependencyInfo)] -> [(String, [String])])
-> (Map String DependencyInfo -> [(String, DependencyInfo)])
-> Map String DependencyInfo
-> [(String, [String])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map String DependencyInfo -> [(String, DependencyInfo)]
forall k a. Map k a -> [(k, a)]
Map.toList (Map String DependencyInfo -> ([String], [[String]]))
-> Map String DependencyInfo -> ([String], [[String]])
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 (name :: String
name, DependencyInfo mixins :: [String]
mixins version :: DependencyVersion
version) = (
      String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ DependencyVersion -> String
renderVersion DependencyVersion
version
    , [ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ " " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
mixin | String
mixin <- [String]
mixins ]
    )

renderVersion :: DependencyVersion -> String
renderVersion :: DependencyVersion -> String
renderVersion (DependencyVersion _ c :: VersionConstraint
c) = VersionConstraint -> String
renderVersionConstraint VersionConstraint
c

renderVersionConstraint :: VersionConstraint -> String
renderVersionConstraint :: VersionConstraint -> String
renderVersionConstraint version :: VersionConstraint
version = case VersionConstraint
version of
  AnyVersion -> ""
  VersionRange x :: String
x -> " " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
x

renderBuildTools :: Map BuildTool DependencyVersion -> SystemBuildTools -> [Element]
renderBuildTools :: Map BuildTool DependencyVersion -> SystemBuildTools -> [Element]
renderBuildTools (((BuildTool, DependencyVersion) -> RenderBuildTool)
-> [(BuildTool, DependencyVersion)] -> [RenderBuildTool]
forall a b. (a -> b) -> [a] -> [b]
map (BuildTool, DependencyVersion) -> RenderBuildTool
renderBuildTool ([(BuildTool, DependencyVersion)] -> [RenderBuildTool])
-> (Map BuildTool DependencyVersion
    -> [(BuildTool, DependencyVersion)])
-> Map BuildTool DependencyVersion
-> [RenderBuildTool]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map BuildTool DependencyVersion -> [(BuildTool, DependencyVersion)]
forall k a. Map k a -> [(k, a)]
Map.toList -> [RenderBuildTool]
xs) systemBuildTools :: SystemBuildTools
systemBuildTools = [
    String -> Value -> Element
Field "build-tools" ([String] -> Value
CommaSeparatedList ([String] -> Value) -> [String] -> Value
forall a b. (a -> b) -> a -> b
$ [String
x | BuildTools x :: String
x <- [RenderBuildTool]
xs] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ SystemBuildTools -> [String]
renderSystemBuildTools SystemBuildTools
systemBuildTools)
  , String -> Value -> Element
Field "build-tool-depends" ([String] -> Value
CommaSeparatedList [String
x | BuildToolDepends x :: String
x <- [RenderBuildTool]
xs])
  ]

data RenderBuildTool = BuildTools String | BuildToolDepends String

renderBuildTool :: (BuildTool,  DependencyVersion) -> RenderBuildTool
renderBuildTool :: (BuildTool, DependencyVersion) -> RenderBuildTool
renderBuildTool (buildTool :: BuildTool
buildTool, DependencyVersion -> String
renderVersion -> String
version) = case BuildTool
buildTool of
  LocalBuildTool executable :: String
executable -> String -> RenderBuildTool
BuildTools (String
executable String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
version)
  BuildTool pkg :: String
pkg executable :: String
executable
    | String
pkg String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
executable Bool -> Bool -> Bool
&& String
executable String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
knownBuildTools -> String -> RenderBuildTool
BuildTools (String
executable String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
version)
    | Bool
otherwise -> String -> RenderBuildTool
BuildToolDepends (String
pkg String -> String -> String
forall a. [a] -> [a] -> [a]
++ ":" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
executable String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
version)
  where
    knownBuildTools :: [String]
    knownBuildTools :: [String]
knownBuildTools = [
        "alex"
      , "c2hs"
      , "cpphs"
      , "greencard"
      , "haddock"
      , "happy"
      , "hsc2hs"
      , "hscolour"
      ]

renderSystemBuildTools :: SystemBuildTools -> [String]
renderSystemBuildTools :: SystemBuildTools -> [String]
renderSystemBuildTools = ((String, VersionConstraint) -> String)
-> [(String, VersionConstraint)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, VersionConstraint) -> String
renderSystemBuildTool ([(String, VersionConstraint)] -> [String])
-> (SystemBuildTools -> [(String, VersionConstraint)])
-> SystemBuildTools
-> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map String VersionConstraint -> [(String, VersionConstraint)]
forall k a. Map k a -> [(k, a)]
Map.toList (Map String VersionConstraint -> [(String, VersionConstraint)])
-> (SystemBuildTools -> Map String VersionConstraint)
-> SystemBuildTools
-> [(String, VersionConstraint)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SystemBuildTools -> Map String VersionConstraint
unSystemBuildTools

renderSystemBuildTool :: (String, VersionConstraint) -> String
renderSystemBuildTool :: (String, VersionConstraint) -> String
renderSystemBuildTool (name :: String
name, constraint :: VersionConstraint
constraint) = String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ VersionConstraint -> String
renderVersionConstraint VersionConstraint
constraint

renderGhcOptions :: [GhcOption] -> Element
renderGhcOptions :: [String] -> Element
renderGhcOptions = String -> Value -> Element
Field "ghc-options" (Value -> Element) -> ([String] -> Value) -> [String] -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList

renderGhcProfOptions :: [GhcProfOption] -> Element
renderGhcProfOptions :: [String] -> Element
renderGhcProfOptions = String -> Value -> Element
Field "ghc-prof-options" (Value -> Element) -> ([String] -> Value) -> [String] -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList

renderGhcjsOptions :: [GhcjsOption] -> Element
renderGhcjsOptions :: [String] -> Element
renderGhcjsOptions = String -> Value -> Element
Field "ghcjs-options" (Value -> Element) -> ([String] -> Value) -> [String] -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList

renderCppOptions :: [CppOption] -> Element
renderCppOptions :: [String] -> Element
renderCppOptions = String -> Value -> Element
Field "cpp-options" (Value -> Element) -> ([String] -> Value) -> [String] -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList

renderCcOptions :: [CcOption] -> Element
renderCcOptions :: [String] -> Element
renderCcOptions = String -> Value -> Element
Field "cc-options" (Value -> Element) -> ([String] -> Value) -> [String] -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList

renderCxxOptions :: [CxxOption] -> Element
renderCxxOptions :: [String] -> Element
renderCxxOptions = String -> Value -> Element
Field "cxx-options" (Value -> Element) -> ([String] -> Value) -> [String] -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList

renderLdOptions :: [LdOption] -> Element
renderLdOptions :: [String] -> Element
renderLdOptions = String -> Value -> Element
Field "ld-options" (Value -> Element) -> ([String] -> Value) -> [String] -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList

renderBuildable :: Bool -> Element
renderBuildable :: Bool -> Element
renderBuildable = String -> Value -> Element
Field "buildable" (Value -> Element) -> (Bool -> Value) -> Bool -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Value
Literal (String -> Value) -> (Bool -> String) -> Bool -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> String
forall a. Show a => a -> String
show

renderDefaultExtensions :: [String] -> Element
renderDefaultExtensions :: [String] -> Element
renderDefaultExtensions = String -> Value -> Element
Field "default-extensions" (Value -> Element) -> ([String] -> Value) -> [String] -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList

renderOtherExtensions :: [String] -> Element
renderOtherExtensions :: [String] -> Element
renderOtherExtensions = String -> Value -> Element
Field "other-extensions" (Value -> Element) -> ([String] -> Value) -> [String] -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Value
WordList

renderPaths :: [Path] -> Value
renderPaths :: [Path] -> Value
renderPaths = [String] -> Value
LineSeparatedList ([String] -> Value) -> ([Path] -> [String]) -> [Path] -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Path -> String) -> [Path] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Path -> String
renderPath
  where
    renderPath :: Path -> FilePath
    renderPath :: Path -> String
renderPath (Path path :: String
path)
      | String -> Bool
needsQuoting String
path = String -> String
forall a. Show a => a -> String
show String
path
      | Bool
otherwise = String
path

    needsQuoting :: FilePath -> Bool
    needsQuoting :: String -> Bool
needsQuoting = (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\x :: Char
x -> Char -> Bool
isSpace Char
x Bool -> Bool -> Bool
|| Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== ',')