module Nix.Diff.Transformations where
import qualified Patience
import Data.Generics.Uniplate.Data ( transformBi )
import Nix.Diff.Types
import qualified Data.Set as Set
import Data.Text (Text)
foldAlreadyComparedSubTrees :: DerivationDiff -> DerivationDiff
foldAlreadyComparedSubTrees :: DerivationDiff -> DerivationDiff
foldAlreadyComparedSubTrees DerivationDiff
dd = case DerivationDiff
dd of
  DerivationDiff
DerivationsAreTheSame -> DerivationDiff
dd
  DerivationDiff
AlreadyCompared -> DerivationDiff
dd
  OnlyAlreadyComparedBelow{} -> DerivationDiff
dd
  NamesDontMatch{} -> DerivationDiff
dd
  OutputsDontMatch{} -> DerivationDiff
dd
  DerivationDiff{Maybe EnvironmentDiff
Maybe ArgumentsDiff
Maybe (Changed Text)
InputsDiff
SourcesDiff
OutputsDiff
Changed OutputStructure
outputStructure :: Changed OutputStructure
outputsDiff :: OutputsDiff
platformDiff :: Maybe (Changed Text)
builderDiff :: Maybe (Changed Text)
argumentsDiff :: Maybe ArgumentsDiff
sourcesDiff :: SourcesDiff
inputsDiff :: InputsDiff
envDiff :: Maybe EnvironmentDiff
$sel:outputStructure:DerivationsAreTheSame :: DerivationDiff -> Changed OutputStructure
$sel:outputsDiff:DerivationsAreTheSame :: DerivationDiff -> OutputsDiff
$sel:platformDiff:DerivationsAreTheSame :: DerivationDiff -> Maybe (Changed Text)
$sel:builderDiff:DerivationsAreTheSame :: DerivationDiff -> Maybe (Changed Text)
$sel:argumentsDiff:DerivationsAreTheSame :: DerivationDiff -> Maybe ArgumentsDiff
$sel:sourcesDiff:DerivationsAreTheSame :: DerivationDiff -> SourcesDiff
$sel:inputsDiff:DerivationsAreTheSame :: DerivationDiff -> InputsDiff
$sel:envDiff:DerivationsAreTheSame :: DerivationDiff -> Maybe EnvironmentDiff
..} -> if
      | OutputsDiff Maybe (Changed (Map Text (DerivationOutput StorePath Text)))
Nothing [] <- OutputsDiff
outputsDiff
      , Maybe (Changed Text)
Nothing <- Maybe (Changed Text)
platformDiff
      , Maybe (Changed Text)
Nothing <- Maybe (Changed Text)
builderDiff
      , Maybe ArgumentsDiff
Nothing <- Maybe ArgumentsDiff
argumentsDiff
      , SourcesDiff Maybe (Changed (Set Text))
Nothing [] <- SourcesDiff
sourcesDiff
      , InputsDiff Maybe (Changed (Set Text))
Nothing [InputDerivationsDiff]
inputs <- InputsDiff
inputsDiff'
      , (InputDerivationsDiff -> Bool) -> [InputDerivationsDiff] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all InputDerivationsDiff -> Bool
alreadyComparedBelow [InputDerivationsDiff]
inputs
      , Maybe EnvironmentDiff -> Bool
envSkippedOrUnchanged Maybe EnvironmentDiff
envDiff
          -> Changed OutputStructure -> DerivationDiff
OnlyAlreadyComparedBelow Changed OutputStructure
outputStructure
      | Bool
otherwise -> DerivationDiff
          { Changed OutputStructure
outputStructure :: Changed OutputStructure
$sel:outputStructure:DerivationsAreTheSame :: Changed OutputStructure
outputStructure
          , OutputsDiff
outputsDiff :: OutputsDiff
$sel:outputsDiff:DerivationsAreTheSame :: OutputsDiff
outputsDiff
          , Maybe (Changed Text)
platformDiff :: Maybe (Changed Text)
$sel:platformDiff:DerivationsAreTheSame :: Maybe (Changed Text)
platformDiff
          , Maybe (Changed Text)
builderDiff :: Maybe (Changed Text)
$sel:builderDiff:DerivationsAreTheSame :: Maybe (Changed Text)
builderDiff
          , Maybe ArgumentsDiff
argumentsDiff :: Maybe ArgumentsDiff
$sel:argumentsDiff:DerivationsAreTheSame :: Maybe ArgumentsDiff
argumentsDiff
          , SourcesDiff
sourcesDiff :: SourcesDiff
$sel:sourcesDiff:DerivationsAreTheSame :: SourcesDiff
sourcesDiff
          , $sel:inputsDiff:DerivationsAreTheSame :: InputsDiff
inputsDiff = InputsDiff
inputsDiff'
          , Maybe EnvironmentDiff
envDiff :: Maybe EnvironmentDiff
$sel:envDiff:DerivationsAreTheSame :: Maybe EnvironmentDiff
envDiff
          }
    where
      inputsDiff' :: InputsDiff
inputsDiff' = (DerivationDiff -> DerivationDiff) -> InputsDiff -> InputsDiff
transformNestedDerivationDiffs
            DerivationDiff -> DerivationDiff
foldAlreadyComparedSubTrees
            InputsDiff
inputsDiff
foldManyInputDerivationsAlreadyCompared :: DerivationDiff -> DerivationDiff
foldManyInputDerivationsAlreadyCompared :: DerivationDiff -> DerivationDiff
foldManyInputDerivationsAlreadyCompared DerivationDiff
dd = case DerivationDiff
dd of
  DerivationDiff
DerivationsAreTheSame -> DerivationDiff
dd
  DerivationDiff
AlreadyCompared -> DerivationDiff
dd
  OnlyAlreadyComparedBelow{} -> DerivationDiff
dd
  NamesDontMatch{} -> DerivationDiff
dd
  OutputsDontMatch{} -> DerivationDiff
dd
  DerivationDiff{Maybe EnvironmentDiff
Maybe ArgumentsDiff
Maybe (Changed Text)
InputsDiff
SourcesDiff
OutputsDiff
Changed OutputStructure
$sel:outputStructure:DerivationsAreTheSame :: DerivationDiff -> Changed OutputStructure
$sel:outputsDiff:DerivationsAreTheSame :: DerivationDiff -> OutputsDiff
$sel:platformDiff:DerivationsAreTheSame :: DerivationDiff -> Maybe (Changed Text)
$sel:builderDiff:DerivationsAreTheSame :: DerivationDiff -> Maybe (Changed Text)
$sel:argumentsDiff:DerivationsAreTheSame :: DerivationDiff -> Maybe ArgumentsDiff
$sel:sourcesDiff:DerivationsAreTheSame :: DerivationDiff -> SourcesDiff
$sel:inputsDiff:DerivationsAreTheSame :: DerivationDiff -> InputsDiff
$sel:envDiff:DerivationsAreTheSame :: DerivationDiff -> Maybe EnvironmentDiff
outputStructure :: Changed OutputStructure
outputsDiff :: OutputsDiff
platformDiff :: Maybe (Changed Text)
builderDiff :: Maybe (Changed Text)
argumentsDiff :: Maybe ArgumentsDiff
sourcesDiff :: SourcesDiff
inputsDiff :: InputsDiff
envDiff :: Maybe EnvironmentDiff
..} ->
    let inputsDiff' :: InputsDiff
inputsDiff' = (DerivationDiff -> DerivationDiff) -> InputsDiff -> InputsDiff
transformNestedDerivationDiffs
                        DerivationDiff -> DerivationDiff
foldManyInputDerivationsAlreadyCompared
                        InputsDiff
inputsDiff
        helper :: [Text] -> [InputDerivationsDiff] -> [InputDerivationsDiff]
        helper :: [Text] -> [InputDerivationsDiff] -> [InputDerivationsDiff]
helper [] [] = []
        helper [Text]
names [] =
          [ManyDerivationsAlreadyComparedDiff
            { $sel:drvNames:OneDerivationDiff :: Set Text
drvNames = [Text] -> Set Text
forall a. Ord a => [a] -> Set a
Set.fromList [Text]
names
            }]
        helper [Text]
names (InputDerivationsDiff
input:[InputDerivationsDiff]
inputs) =
          case InputDerivationsDiff
input of
            OneDerivationDiff
              { Text
drvName :: Text
$sel:drvName:OneDerivationDiff :: InputDerivationsDiff -> Text
drvName
              , $sel:drvDiff:OneDerivationDiff :: InputDerivationsDiff -> DerivationDiff
drvDiff = DerivationDiff
AlreadyCompared
              } -> [Text] -> [InputDerivationsDiff] -> [InputDerivationsDiff]
helper
                    (Text
drvNameText -> [Text] -> [Text]
forall a. a -> [a] -> [a]
:[Text]
names)
                    [InputDerivationsDiff]
inputs
            OneDerivationDiff{} -> InputDerivationsDiff
input InputDerivationsDiff
-> [InputDerivationsDiff] -> [InputDerivationsDiff]
forall a. a -> [a] -> [a]
: [Text] -> [InputDerivationsDiff] -> [InputDerivationsDiff]
helper [Text]
names [InputDerivationsDiff]
inputs
            SomeDerivationsDiff{} -> InputDerivationsDiff
input InputDerivationsDiff
-> [InputDerivationsDiff] -> [InputDerivationsDiff]
forall a. a -> [a] -> [a]
: [Text] -> [InputDerivationsDiff] -> [InputDerivationsDiff]
helper [Text]
names [InputDerivationsDiff]
inputs
            ManyDerivationsAlreadyComparedDiff{} -> [Char] -> [InputDerivationsDiff]
forall a. HasCallStack => [Char] -> a
error [Char]
"unreachable"
     in DerivationDiff
       { $sel:inputsDiff:DerivationsAreTheSame :: InputsDiff
inputsDiff =
           InputsDiff
inputsDiff'
             { inputDerivationDiffs =
                 helper [] inputsDiff'.inputDerivationDiffs
             }
       , Maybe EnvironmentDiff
Maybe ArgumentsDiff
Maybe (Changed Text)
SourcesDiff
OutputsDiff
Changed OutputStructure
$sel:outputStructure:DerivationsAreTheSame :: Changed OutputStructure
$sel:outputsDiff:DerivationsAreTheSame :: OutputsDiff
$sel:platformDiff:DerivationsAreTheSame :: Maybe (Changed Text)
$sel:builderDiff:DerivationsAreTheSame :: Maybe (Changed Text)
$sel:argumentsDiff:DerivationsAreTheSame :: Maybe ArgumentsDiff
$sel:sourcesDiff:DerivationsAreTheSame :: SourcesDiff
$sel:envDiff:DerivationsAreTheSame :: Maybe EnvironmentDiff
outputStructure :: Changed OutputStructure
outputsDiff :: OutputsDiff
platformDiff :: Maybe (Changed Text)
builderDiff :: Maybe (Changed Text)
argumentsDiff :: Maybe ArgumentsDiff
sourcesDiff :: SourcesDiff
envDiff :: Maybe EnvironmentDiff
..
       }
squashSourcesAndEnvsDiff :: DerivationDiff -> DerivationDiff
squashSourcesAndEnvsDiff :: DerivationDiff -> DerivationDiff
squashSourcesAndEnvsDiff = (TextDiff -> TextDiff) -> DerivationDiff -> DerivationDiff
forall from to. Biplate from to => (to -> to) -> from -> from
transformBi
    \(TextDiff [Item Text]
x) -> [Item Text] -> TextDiff
TextDiff ([Item Text] -> [Item Text]
forall {a}. Semigroup a => [Item a] -> [Item a]
squashDiff [Item Text]
x)
  where
    squashDiff :: [Item a] -> [Item a]
squashDiff (Patience.Old a
a : Patience.Old a
b : [Item a]
xs) =
      [Item a] -> [Item a]
squashDiff (a -> Item a
forall a. a -> Item a
Patience.Old (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b) Item a -> [Item a] -> [Item a]
forall a. a -> [a] -> [a]
: [Item a]
xs)
    squashDiff (Patience.New a
a : Patience.New a
b : [Item a]
xs) =
      [Item a] -> [Item a]
squashDiff (a -> Item a
forall a. a -> Item a
Patience.New (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b) Item a -> [Item a] -> [Item a]
forall a. a -> [a] -> [a]
: [Item a]
xs)
    squashDiff (Patience.Both a
a a
_ : Patience.Both a
b a
_ : [Item a]
xs) =
      let ab :: a
ab = a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b in [Item a] -> [Item a]
squashDiff (a -> a -> Item a
forall a. a -> a -> Item a
Patience.Both a
ab a
ab Item a -> [Item a] -> [Item a]
forall a. a -> [a] -> [a]
: [Item a]
xs)
    squashDiff (Item a
x : [Item a]
xs) = Item a
x Item a -> [Item a] -> [Item a]
forall a. a -> [a] -> [a]
: [Item a] -> [Item a]
squashDiff [Item a]
xs
    squashDiff [] = []
transformNestedDerivationDiffs
  :: (DerivationDiff -> DerivationDiff)
  -> InputsDiff
  -> InputsDiff
transformNestedDerivationDiffs :: (DerivationDiff -> DerivationDiff) -> InputsDiff -> InputsDiff
transformNestedDerivationDiffs DerivationDiff -> DerivationDiff
f InputsDiff{[InputDerivationsDiff]
Maybe (Changed (Set Text))
$sel:inputDerivationDiffs:InputsDiff :: InputsDiff -> [InputDerivationsDiff]
inputExtraNames :: Maybe (Changed (Set Text))
inputDerivationDiffs :: [InputDerivationsDiff]
$sel:inputExtraNames:InputsDiff :: InputsDiff -> Maybe (Changed (Set Text))
..} = InputsDiff
  { Maybe (Changed (Set Text))
inputExtraNames :: Maybe (Changed (Set Text))
$sel:inputExtraNames:InputsDiff :: Maybe (Changed (Set Text))
inputExtraNames
  , $sel:inputDerivationDiffs:InputsDiff :: [InputDerivationsDiff]
inputDerivationDiffs = (InputDerivationsDiff -> InputDerivationsDiff)
-> [InputDerivationsDiff] -> [InputDerivationsDiff]
forall a b. (a -> b) -> [a] -> [b]
map InputDerivationsDiff -> InputDerivationsDiff
changeDerivation [InputDerivationsDiff]
inputDerivationDiffs
  }
  where
    changeDerivation :: InputDerivationsDiff -> InputDerivationsDiff
changeDerivation InputDerivationsDiff
idd = case InputDerivationsDiff
idd of
      OneDerivationDiff Text
name DerivationDiff
dd ->
        Text -> DerivationDiff -> InputDerivationsDiff
OneDerivationDiff Text
name (DerivationDiff -> DerivationDiff
f DerivationDiff
dd)
      SomeDerivationsDiff {} -> InputDerivationsDiff
idd
      ManyDerivationsAlreadyComparedDiff {} -> InputDerivationsDiff
idd
envSkippedOrUnchanged :: Maybe EnvironmentDiff -> Bool
envSkippedOrUnchanged :: Maybe EnvironmentDiff -> Bool
envSkippedOrUnchanged = \case
  Maybe EnvironmentDiff
Nothing -> Bool
True
  Just EnvironmentDiff
EnvironmentsAreEqual -> Bool
True
  Maybe EnvironmentDiff
_ -> Bool
False
alreadyComparedBelow :: InputDerivationsDiff -> Bool
alreadyComparedBelow :: InputDerivationsDiff -> Bool
alreadyComparedBelow = \case
  OneDerivationDiff Text
_ DerivationDiff
AlreadyCompared -> Bool
True
  OneDerivationDiff Text
_ OnlyAlreadyComparedBelow{} -> Bool
True
  InputDerivationsDiff
_ -> Bool
False
transformIf :: Bool -> (DerivationDiff -> DerivationDiff) -> DerivationDiff -> DerivationDiff
transformIf :: Bool
-> (DerivationDiff -> DerivationDiff)
-> DerivationDiff
-> DerivationDiff
transformIf Bool
False DerivationDiff -> DerivationDiff
_ = DerivationDiff -> DerivationDiff
forall a. a -> a
id
transformIf Bool
True DerivationDiff -> DerivationDiff
f = DerivationDiff -> DerivationDiff
f