{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -Wno-deprecations #-}
module CabalFmt.Fields.BuildDepends (
buildDependsF,
setupDependsF,
buildToolDependsF,
) where
import Data.List (dropWhileEnd)
import CabalFmt.Fields
import CabalFmt.Options
import CabalFmt.Prelude
import qualified Distribution.CabalSpecVersion as C
import qualified Distribution.Compat.NonEmptySet as NES
import qualified Distribution.FieldGrammar as C
import qualified Distribution.Parsec as C
import qualified Distribution.Pretty as C
import qualified Distribution.Types.Dependency as C
import qualified Distribution.Types.DependencyMap as C
import qualified Distribution.Types.ExeDependency as C
import qualified Distribution.Types.LibraryName as C
import qualified Distribution.Types.VersionRange as C
import qualified Text.PrettyPrint as PP
import VersionInterval
(ConversionProblem (..), normaliseVersionRange)
setupDependsF :: Options -> FieldDescrs () ()
setupDependsF :: Options -> FieldDescrs () ()
setupDependsF Options
opts = FieldName
-> ([Dependency] -> Doc)
-> (forall (m :: * -> *). CabalParsing m => m [Dependency])
-> FieldDescrs () ()
forall f s a.
FieldName
-> (f -> Doc)
-> (forall (m :: * -> *). CabalParsing m => m f)
-> FieldDescrs s a
singletonF FieldName
"setup-depends" (Options -> [Dependency] -> Doc
pretty Options
opts) m [Dependency]
forall (m :: * -> *). CabalParsing m => m [Dependency]
parse
buildDependsF :: Options -> FieldDescrs () ()
buildDependsF :: Options -> FieldDescrs () ()
buildDependsF Options
opts = FieldName
-> ([Dependency] -> Doc)
-> (forall (m :: * -> *). CabalParsing m => m [Dependency])
-> FieldDescrs () ()
forall f s a.
FieldName
-> (f -> Doc)
-> (forall (m :: * -> *). CabalParsing m => m f)
-> FieldDescrs s a
singletonF FieldName
"build-depends" (Options -> [Dependency] -> Doc
pretty Options
opts) m [Dependency]
forall (m :: * -> *). CabalParsing m => m [Dependency]
parse
buildToolDependsF :: Options -> FieldDescrs () ()
buildToolDependsF :: Options -> FieldDescrs () ()
buildToolDependsF Options
opts = FieldName
-> ([ExeDependency] -> Doc)
-> (forall (m :: * -> *). CabalParsing m => m [ExeDependency])
-> FieldDescrs () ()
forall f s a.
FieldName
-> (f -> Doc)
-> (forall (m :: * -> *). CabalParsing m => m f)
-> FieldDescrs s a
singletonF FieldName
"build-tool-depends" (Options -> [ExeDependency] -> Doc
prettyExe Options
opts) m [ExeDependency]
forall (m :: * -> *). CabalParsing m => m [ExeDependency]
parseExe
parse :: C.CabalParsing m => m [C.Dependency]
parse :: forall (m :: * -> *). CabalParsing m => m [Dependency]
parse = ([Dependency] -> List CommaVCat (Identity Dependency) Dependency)
-> List CommaVCat (Identity Dependency) Dependency -> [Dependency]
forall o n. Newtype o n => (o -> n) -> n -> o
unpack' (CommaVCat
-> [Dependency] -> List CommaVCat (Identity Dependency) Dependency
forall sep a. sep -> [a] -> List sep (Identity a) a
C.alaList CommaVCat
C.CommaVCat) (List CommaVCat (Identity Dependency) Dependency -> [Dependency])
-> m (List CommaVCat (Identity Dependency) Dependency)
-> m [Dependency]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (List CommaVCat (Identity Dependency) Dependency)
forall a (m :: * -> *). (Parsec a, CabalParsing m) => m a
forall (m :: * -> *).
CabalParsing m =>
m (List CommaVCat (Identity Dependency) Dependency)
C.parsec
parseExe :: C.CabalParsing m => m [C.ExeDependency]
parseExe :: forall (m :: * -> *). CabalParsing m => m [ExeDependency]
parseExe = ([ExeDependency]
-> List CommaVCat (Identity ExeDependency) ExeDependency)
-> List CommaVCat (Identity ExeDependency) ExeDependency
-> [ExeDependency]
forall o n. Newtype o n => (o -> n) -> n -> o
unpack' (CommaVCat
-> [ExeDependency]
-> List CommaVCat (Identity ExeDependency) ExeDependency
forall sep a. sep -> [a] -> List sep (Identity a) a
C.alaList CommaVCat
C.CommaVCat) (List CommaVCat (Identity ExeDependency) ExeDependency
-> [ExeDependency])
-> m (List CommaVCat (Identity ExeDependency) ExeDependency)
-> m [ExeDependency]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (List CommaVCat (Identity ExeDependency) ExeDependency)
forall a (m :: * -> *). (Parsec a, CabalParsing m) => m a
forall (m :: * -> *).
CabalParsing m =>
m (List CommaVCat (Identity ExeDependency) ExeDependency)
C.parsec
normaliseVersionRange' :: C.VersionRange -> C.VersionRange
normaliseVersionRange' :: VersionRange -> VersionRange
normaliseVersionRange' VersionRange
vr = (ConversionProblem -> VersionRange)
-> (VersionRange -> VersionRange)
-> Either ConversionProblem VersionRange
-> VersionRange
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ConversionProblem -> VersionRange
fromConversionProblem VersionRange -> VersionRange
forall a. a -> a
id (VersionRange -> Either ConversionProblem VersionRange
normaliseVersionRange VersionRange
vr) where
fromConversionProblem :: ConversionProblem -> C.VersionRange
fromConversionProblem :: ConversionProblem -> VersionRange
fromConversionProblem ConversionProblem
IntervalsEmpty = VersionRange
C.noVersion
fromConversionProblem ConversionProblem
OtherConversionProblem = VersionRange
vr
pretty :: Options -> [C.Dependency] -> PP.Doc
pretty :: Options -> [Dependency] -> Doc
pretty Options
opts [Dependency]
deps = case [Dependency]
deps' of
[] -> Doc
PP.empty
[Dependency
dep] -> [Char] -> Doc
PP.text (Dependency -> [Char]
prettyDepNoVersion Dependency
dep) Doc -> Doc -> Doc
PP.<+> VersionRange -> Doc
prettyVR VersionRange
vr'
where
vr' :: VersionRange
vr' = VersionRange -> VersionRange
normaliseVersionRange' (Dependency -> VersionRange
C.depVerRange Dependency
dep)
prettyVR :: VersionRange -> Doc
prettyVR VersionRange
vr | VersionRange
vr VersionRange -> VersionRange -> Bool
forall a. Eq a => a -> a -> Bool
== VersionRange
C.anyVersion = Doc
PP.empty
| VersionRange
vr VersionRange -> VersionRange -> Bool
forall a. Eq a => a -> a -> Bool
== VersionRange
C.noVersion = [Char] -> Doc
PP.text [Char]
"<0"
| Bool
otherwise = VersionRange -> Doc
forall a. Pretty a => a -> Doc
C.pretty VersionRange
vr
[Dependency]
_ -> Options -> [([Char], VersionRange)] -> Doc
prettyMany Options
opts [([Char], VersionRange)]
deps''
where
deps'' :: [(String, C.VersionRange)]
deps'' :: [([Char], VersionRange)]
deps'' =
(([Char], VersionRange) -> [Char])
-> [([Char], VersionRange)] -> [([Char], VersionRange)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn ((Char -> Char) -> [Char] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower ([Char] -> [Char])
-> (([Char], VersionRange) -> [Char])
-> ([Char], VersionRange)
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char], VersionRange) -> [Char]
forall a b. (a, b) -> a
fst) ([([Char], VersionRange)] -> [([Char], VersionRange)])
-> [([Char], VersionRange)] -> [([Char], VersionRange)]
forall a b. (a -> b) -> a -> b
$
(Dependency -> ([Char], VersionRange))
-> [Dependency] -> [([Char], VersionRange)]
forall a b. (a -> b) -> [a] -> [b]
map (Dependency -> [Char]
prettyDepNoVersion (Dependency -> [Char])
-> (Dependency -> VersionRange)
-> Dependency
-> ([Char], VersionRange)
forall b c c'. (b -> c) -> (b -> c') -> b -> (c, c')
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& Dependency -> VersionRange
C.depVerRange) [Dependency]
deps'
where
deps' :: [C.Dependency]
deps' :: [Dependency]
deps' = (Dependency -> [Dependency]) -> [Dependency] -> [Dependency]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Dependency -> [Dependency]
expandDep ([Dependency] -> [Dependency]) -> [Dependency] -> [Dependency]
forall a b. (a -> b) -> a -> b
$ DependencyMap -> [Dependency]
C.fromDepMap (DependencyMap -> [Dependency]) -> DependencyMap -> [Dependency]
forall a b. (a -> b) -> a -> b
$ [Dependency] -> DependencyMap
C.toDepMap [Dependency]
deps
prettyDepNoVersion :: C.Dependency -> String
prettyDepNoVersion :: Dependency -> [Char]
prettyDepNoVersion (C.Dependency PackageName
pkg VersionRange
_ NonEmptySet LibraryName
libs) =
Dependency -> [Char]
forall a. Pretty a => a -> [Char]
C.prettyShow (PackageName
-> VersionRange -> NonEmptySet LibraryName -> Dependency
C.Dependency PackageName
pkg VersionRange
C.anyVersion NonEmptySet LibraryName
libs)
expandDep :: C.Dependency -> [C.Dependency]
expandDep :: Dependency -> [Dependency]
expandDep (C.Dependency PackageName
pkg VersionRange
vr NonEmptySet LibraryName
libs) = [LibraryName] -> [Dependency]
makeDep ([LibraryName] -> [Dependency]) -> [LibraryName] -> [Dependency]
forall a b. (a -> b) -> a -> b
$ (LibraryName -> Maybe [Char]) -> [LibraryName] -> [LibraryName]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn LibraryName -> Maybe [Char]
f (NonEmptySet LibraryName -> [LibraryName]
forall a. NonEmptySet a -> [a]
NES.toList NonEmptySet LibraryName
libs)
where
f :: LibraryName -> Maybe [Char]
f LibraryName
C.LMainLibName = Maybe [Char]
forall a. Maybe a
Nothing
f (C.LSubLibName UnqualComponentName
n) = [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just ((Char -> Char) -> [Char] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower (UnqualComponentName -> [Char]
forall a. Pretty a => a -> [Char]
C.prettyShow UnqualComponentName
n))
makeDep :: [C.LibraryName] -> [C.Dependency]
makeDep :: [LibraryName] -> [Dependency]
makeDep [] = []
makeDep (LibraryName
ln : [LibraryName]
lns) =
PackageName
-> VersionRange -> NonEmptySet LibraryName -> Dependency
C.Dependency PackageName
pkg VersionRange
vr (LibraryName -> NonEmptySet LibraryName
forall a. a -> NonEmptySet a
NES.singleton LibraryName
ln) Dependency -> [Dependency] -> [Dependency]
forall a. a -> [a] -> [a]
:
(LibraryName -> Dependency) -> [LibraryName] -> [Dependency]
forall a b. (a -> b) -> [a] -> [b]
map (\LibraryName
ln' -> PackageName
-> VersionRange -> NonEmptySet LibraryName -> Dependency
C.Dependency PackageName
pkg VersionRange
C.anyVersion (LibraryName -> NonEmptySet LibraryName
forall a. a -> NonEmptySet a
NES.singleton LibraryName
ln')) [LibraryName]
lns
prettyExe :: Options -> [C.ExeDependency] -> PP.Doc
prettyExe :: Options -> [ExeDependency] -> Doc
prettyExe Options
opts [ExeDependency]
deps = case [ExeDependency]
deps of
[] -> Doc
PP.empty
[ExeDependency
dep] -> [Char] -> Doc
PP.text (ExeDependency -> [Char]
exeDepExeName ExeDependency
dep) Doc -> Doc -> Doc
PP.<+> VersionRange -> Doc
prettyVR VersionRange
vr'
where
vr' :: VersionRange
vr' = VersionRange -> VersionRange
normaliseVersionRange' (ExeDependency -> VersionRange
exeDepVerRange ExeDependency
dep)
prettyVR :: VersionRange -> Doc
prettyVR VersionRange
vr | VersionRange
vr VersionRange -> VersionRange -> Bool
forall a. Eq a => a -> a -> Bool
== VersionRange
C.anyVersion = Doc
PP.empty
| VersionRange
vr VersionRange -> VersionRange -> Bool
forall a. Eq a => a -> a -> Bool
== VersionRange
C.noVersion = [Char] -> Doc
PP.text [Char]
"<0"
| Bool
otherwise = VersionRange -> Doc
forall a. Pretty a => a -> Doc
C.pretty VersionRange
vr
[ExeDependency]
_ -> Options -> [([Char], VersionRange)] -> Doc
prettyMany Options
opts [([Char], VersionRange)]
deps'
where
deps' :: [(String, C.VersionRange)]
deps' :: [([Char], VersionRange)]
deps' = (([Char], VersionRange) -> [Char])
-> [([Char], VersionRange)] -> [([Char], VersionRange)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn ((Char -> Char) -> [Char] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower ([Char] -> [Char])
-> (([Char], VersionRange) -> [Char])
-> ([Char], VersionRange)
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char], VersionRange) -> [Char]
forall a b. (a, b) -> a
fst)
([([Char], VersionRange)] -> [([Char], VersionRange)])
-> [([Char], VersionRange)] -> [([Char], VersionRange)]
forall a b. (a -> b) -> a -> b
$ (ExeDependency -> ([Char], VersionRange))
-> [ExeDependency] -> [([Char], VersionRange)]
forall a b. (a -> b) -> [a] -> [b]
map (ExeDependency -> [Char]
exeDepExeName (ExeDependency -> [Char])
-> (ExeDependency -> VersionRange)
-> ExeDependency
-> ([Char], VersionRange)
forall b c c'. (b -> c) -> (b -> c') -> b -> (c, c')
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& ExeDependency -> VersionRange
exeDepVerRange)
([ExeDependency] -> [([Char], VersionRange)])
-> [ExeDependency] -> [([Char], VersionRange)]
forall a b. (a -> b) -> a -> b
$ [ExeDependency]
deps
exeDepExeName :: C.ExeDependency -> String
exeDepExeName :: ExeDependency -> [Char]
exeDepExeName (C.ExeDependency PackageName
name UnqualComponentName
exe VersionRange
_) =
PackageName -> [Char]
forall a. Pretty a => a -> [Char]
C.prettyShow PackageName
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
":" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ UnqualComponentName -> [Char]
forall a. Pretty a => a -> [Char]
C.prettyShow UnqualComponentName
exe
exeDepVerRange :: C.ExeDependency -> C.VersionRange
exeDepVerRange :: ExeDependency -> VersionRange
exeDepVerRange (C.ExeDependency PackageName
_ UnqualComponentName
_ VersionRange
vr) = VersionRange
vr
prettyMany :: Options -> [(String, C.VersionRange)] -> PP.Doc
prettyMany :: Options -> [([Char], VersionRange)] -> Doc
prettyMany Options { optSpecVersion :: Options -> CabalSpecVersion
optSpecVersion = CabalSpecVersion
v, optTabular :: Options -> Bool
optTabular = Bool
tab } [([Char], VersionRange)]
deps'
= [Doc] -> Doc
PP.vcat
([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ ([Char] -> Doc) -> [[Char]] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> Doc
PP.text
([[Char]] -> [Doc]) -> [[Char]] -> [Doc]
forall a b. (a -> b) -> a -> b
$ [[[Char]]] -> [[Char]]
tbl
([[[Char]]] -> [[Char]]) -> [[[Char]]] -> [[Char]]
forall a b. (a -> b) -> a -> b
$ (Bool -> ([Char], VersionRange) -> [[Char]])
-> [Bool] -> [([Char], VersionRange)] -> [[[Char]]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Bool -> ([Char], VersionRange) -> [[Char]]
cols (Bool
True Bool -> [Bool] -> [Bool]
forall a. a -> [a] -> [a]
: Bool -> [Bool]
forall a. a -> [a]
repeat Bool
False) [([Char], VersionRange)]
deps'
where
cols :: Bool -> (String, C.VersionRange) -> [String]
cols :: Bool -> ([Char], VersionRange) -> [[Char]]
cols Bool
isFirst ([Char]
name, VersionRange
vr)
| VersionRange -> Bool
full VersionRange
vr' = [[Char]
comma, [Char]
name]
| Bool
otherwise = [Char]
comma [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: [Char]
name [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: [Char]
"" [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: [Char] -> [[Char]]
words (VersionRange -> [Char]
forall a. Pretty a => a -> [Char]
C.prettyShow VersionRange
vr')
where
vr' :: VersionRange
vr' = VersionRange -> VersionRange
normaliseVersionRange' VersionRange
vr
comma :: [Char]
comma | Bool
isFirst, CabalSpecVersion
v CabalSpecVersion -> CabalSpecVersion -> Bool
forall a. Ord a => a -> a -> Bool
< CabalSpecVersion
C.CabalSpecV2_2 = [Char]
" "
| Bool
otherwise = [Char]
","
full :: C.VersionRange -> Bool
full :: VersionRange -> Bool
full VersionRange
vr = VersionRange
vr VersionRange -> VersionRange -> Bool
forall a. Eq a => a -> a -> Bool
== VersionRange
C.anyVersion
tbl :: [[String]] -> [String]
tbl :: [[[Char]]] -> [[Char]]
tbl = if Bool
tab then [[[Char]]] -> [[Char]]
table else ([[Char]] -> [Char]) -> [[[Char]]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> [Char]
concatSpaces ([Char] -> [Char]) -> ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Char]] -> [Char]
unwords)
table :: [[String]] -> [String]
table :: [[[Char]]] -> [[Char]]
table [[[Char]]]
cells = ([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> [Char]
strip [[Char]]
rows
where
cols :: Int
rowWidths :: [Int]
rows :: [String]
(Int
cols, [Int]
rowWidths, [[Char]]
rows) = ([[Char]] -> (Int, [Int], [[Char]]) -> (Int, [Int], [[Char]]))
-> (Int, [Int], [[Char]]) -> [[[Char]]] -> (Int, [Int], [[Char]])
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr [[Char]] -> (Int, [Int], [[Char]]) -> (Int, [Int], [[Char]])
go (Int
0, Int -> [Int]
forall a. a -> [a]
repeat Int
0, []) [[[Char]]]
cells
go :: [String] -> (Int, [Int], [String]) -> (Int, [Int], [String])
go :: [[Char]] -> (Int, [Int], [[Char]]) -> (Int, [Int], [[Char]])
go [[Char]]
xs (Int
c, [Int]
w, [[Char]]
yss) =
( Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
c ([[Char]] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [[Char]]
xs)
, (Int -> Int -> Int) -> [Int] -> [Int] -> [Int]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> Int -> Int
forall a. Ord a => a -> a -> a
max [Int]
w (([Char] -> Int) -> [[Char]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [[Char]]
xs [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ Int -> [Int]
forall a. a -> [a]
repeat Int
0)
, [[Char]] -> [Char]
unwords (Int -> [[Char]] -> [[Char]]
forall a. Int -> [a] -> [a]
take Int
cols (([Char] -> Int -> [Char]) -> [[Char]] -> [Int] -> [[Char]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith [Char] -> Int -> [Char]
fill [[Char]]
xs [Int]
rowWidths))
[Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: [[Char]]
yss
)
fill :: String -> Int -> String
fill :: [Char] -> Int -> [Char]
fill [Char]
s Int
n = [Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- [Char] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Char]
s) Char
' '
strip :: String -> String
strip :: [Char] -> [Char]
strip = (Char -> Bool) -> [Char] -> [Char]
forall a. (a -> Bool) -> [a] -> [a]
dropWhileEnd (Char
' ' Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==)
concatSpaces :: String -> String
concatSpaces :: [Char] -> [Char]
concatSpaces [] = []
concatSpaces (Char
' ' : [Char]
s) = Char
' ' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char] -> [Char]
concatSpaces [Char]
s
concatSpaces (Char
c0 : [Char]
s0) = Char
c0 Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char] -> [Char]
go [Char]
s0 where
go :: [Char] -> [Char]
go (Char
' ' : Char
' ' : [Char]
s) = [Char] -> [Char]
go (Char
' ' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char]
s)
go (Char
c:[Char]
s) = Char
c Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char] -> [Char]
go [Char]
s
go [] = []