|  | 
|  | 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