Skip to content

Commit 39d9630

Browse files
committed
Generate a diff between two sets of options.
1 parent 2175f7b commit 39d9630

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

haskell-ci.cabal

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ library haskell-ci-internal
8181
HaskellCI.Config.CopyFields
8282
HaskellCI.Config.Docspec
8383
HaskellCI.Config.Doctest
84+
HaskellCI.Config.Diff
8485
HaskellCI.Config.Dump
8586
HaskellCI.Config.Empty
8687
HaskellCI.Config.Folds

src/HaskellCI/Config/Diff.hs

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
{-# LANGUAGE ConstraintKinds #-}
2+
{-# LANGUAGE DataKinds #-}
3+
{-# LANGUAGE FunctionalDependencies #-}
4+
{-# LANGUAGE OverloadedStrings #-}
5+
{-# LANGUAGE TypeApplications #-}
6+
module HaskellCI.Config.Diff where
7+
8+
import HaskellCI.Prelude
9+
10+
import Distribution.Simple.Utils (fromUTF8BS)
11+
import Distribution.Fields.Field (FieldName)
12+
import Distribution.Utils.ShortText (fromShortText)
13+
14+
import qualified Distribution.Compat.Lens as L
15+
import qualified Distribution.Compat.CharParsing as C
16+
import qualified Distribution.FieldGrammar as C
17+
import qualified Distribution.Parsec as C
18+
import qualified Distribution.Pretty as C
19+
import qualified Text.PrettyPrint as PP
20+
21+
import HaskellCI.OptionsGrammar
22+
23+
data ShowDiffOptions = ShowAllOptions | ShowChangedOptions
24+
deriving (Eq, Show, Generic, Binary)
25+
26+
instance C.Parsec ShowDiffOptions where
27+
parsec = ShowAllOptions <$ C.string "all"
28+
<|> ShowChangedOptions <$ C.string "changed"
29+
30+
instance C.Pretty ShowDiffOptions where
31+
pretty ShowAllOptions = PP.text "all"
32+
pretty ShowChangedOptions = PP.text "changed"
33+
34+
data DiffConfig = DiffConfig
35+
{ diffShowOptions :: ShowDiffOptions
36+
, diffShowOld :: Bool
37+
} deriving (Show, Generic, Binary)
38+
39+
diffConfigGrammar
40+
:: ( OptionsGrammar c g
41+
, Applicative (g DiffConfig)
42+
, c (Identity ShowDiffOptions))
43+
=> g DiffConfig DiffConfig
44+
diffConfigGrammar = DiffConfig
45+
<$> C.optionalFieldDef "diff-show-options" (field @"diffShowOptions") ShowChangedOptions
46+
^^^ help "Which fields to show"
47+
<*> C.booleanFieldDef "diff-show-old" (field @"diffShowOld") False
48+
^^^ help "Show the old values for every field"
49+
50+
newtype DiffOptions s a =
51+
DiffOptions { runDiffOptions :: (s, s) -> DiffConfig -> [String] }
52+
deriving Functor
53+
54+
instance Applicative (DiffOptions s) where
55+
pure _ = DiffOptions $ \_ _ -> []
56+
DiffOptions f <*> DiffOptions x = DiffOptions (f <> x)
57+
58+
diffConfigs :: DiffConfig -> DiffOptions a a -> a -> a -> [String]
59+
diffConfigs config grammar oldVal newVal =
60+
runDiffOptions grammar (oldVal, newVal) config
61+
62+
diffUnique
63+
:: Eq b
64+
=> (a -> b)
65+
-> (a -> String)
66+
-> FieldName
67+
-> L.ALens' s a
68+
-> (s, s)
69+
-> DiffConfig
70+
-> [String]
71+
diffUnique project render fn lens (diffOld, diffNew) opts =
72+
case diffShowOptions opts of
73+
ShowChangedOptions | notEqual -> []
74+
ShowAllOptions | notEqual -> newLine
75+
_ -> oldLine ++ newLine
76+
where
77+
notEqual = project oldValue == project newValue
78+
oldValue = L.aview lens $ diffOld
79+
newValue = L.aview lens $ diffNew
80+
81+
oldLine
82+
| diffShowOld opts = ["-- " ++ fromUTF8BS fn ++ ": " ++ render oldValue]
83+
| otherwise = []
84+
85+
newLine = [ fromUTF8BS fn ++ ": " ++ render newValue, ""]
86+
87+
88+
instance C.FieldGrammar C.Pretty DiffOptions where
89+
blurFieldGrammar lens (DiffOptions diff) =
90+
DiffOptions $ diff . bimap (L.aview lens) (L.aview lens)
91+
92+
uniqueFieldAla fn pack valueLens = DiffOptions $
93+
diffUnique (C.prettyShow . pack) (C.prettyShow . pack) fn valueLens
94+
95+
booleanFieldDef fn valueLens _ = DiffOptions $
96+
diffUnique id C.prettyShow fn valueLens
97+
98+
optionalFieldAla fn pack valueLens = DiffOptions $
99+
diffUnique toPretty toPretty fn valueLens
100+
where
101+
toPretty = maybe "" C.prettyShow . fmap pack
102+
103+
optionalFieldDefAla fn pack valueLens _ = DiffOptions $
104+
diffUnique id (C.prettyShow . pack) fn valueLens
105+
106+
monoidalFieldAla fn pack valueLens = DiffOptions $
107+
diffUnique (C.prettyShow . pack) (C.prettyShow . pack) fn valueLens
108+
109+
freeTextField fn valueLens = DiffOptions $
110+
diffUnique id (fromMaybe "") fn valueLens
111+
112+
freeTextFieldDef fn valueLens = DiffOptions $
113+
diffUnique id id fn valueLens
114+
115+
freeTextFieldDefST fn valueLens = DiffOptions $
116+
diffUnique id fromShortText fn valueLens
117+
118+
prefixedFields _ _ = pure []
119+
knownField _ = pure ()
120+
deprecatedSince _ _ = id
121+
availableSince _ _ = id
122+
removedIn _ _ = id
123+
hiddenField = id
124+
125+
instance OptionsGrammar C.Pretty DiffOptions where
126+
metahelp _ = help
127+
128+
help h (DiffOptions xs) = DiffOptions $ \vals config ->
129+
case xs vals config of
130+
[] -> []
131+
diffString -> ("-- " ++ h) : diffString

0 commit comments

Comments
 (0)