{-# LANGUAGE OverloadedStrings #-}
module CabalFmt.Fields.SourceFiles (
sourceFilesF,
fileFields,
) where
import System.FilePath.Posix (splitDirectories)
import qualified Distribution.Fields as C
import qualified Distribution.Parsec as C
import qualified Distribution.Parsec.Newtypes as C
import qualified Distribution.Pretty as C
import qualified Text.PrettyPrint as PP
import CabalFmt.Fields
import CabalFmt.Prelude
sourceFilesF :: [FieldDescrs () ()]
sourceFilesF =
[ singletonF f pretty parse
| f <- fileFields
]
fileFields :: [C.FieldName]
fileFields =
[ "extra-source-files"
, "extra-doc-files"
, "data-files"
, "license-files"
, "asm-sources"
, "cmm-sources"
, "c-sources"
, "cxx-sources"
, "js-sources"
, "includes"
, "install-includes"
]
parse :: C.CabalParsing m => m [FilePath]
parse = unpack' (C.alaList' C.VCat C.FilePathNT) <$> C.parsec
pretty :: [FilePath] -> PP.Doc
pretty
= PP.vcat . map C.showFilePath
. nub
. sortBy (cmp `on` map strToLower . splitDirectories)
where
cmp a b = case dropCommonPrefix a b of
([], []) -> EQ
([], _:_) -> LT
(_:_, []) -> GT
(a', b') -> compare a' b'
strToLower :: String -> String
strToLower = map toLower
dropCommonPrefix :: Eq a => [a] -> [a] -> ([a], [a])
dropCommonPrefix [] [] = ([], [])
dropCommonPrefix [] ys = ([], ys)
dropCommonPrefix xs [] = (xs, [])
dropCommonPrefix xs@(x:xs') ys@(y:ys')
| x == y = dropCommonPrefix xs' ys'
| otherwise = (xs, ys)