module Golden.Utils where import qualified Data.ByteString.Lazy.Char8 as BS import qualified Data.Set import qualified Control.Monad.Reader import qualified Control.Monad.State import Control.Monad (unless) import Control.Exception ( throwIO, ErrorCall(ErrorCall) ) import System.Process.Typed import Nix.Diff ( diff, Diff(unDiff), DiffContext, Status(Status) ) import Nix.Diff.Types ( DerivationDiff, OutputNames(OutputNames) ) import Nix.Diff.Store ( StorePath(StorePath) ) data TestableDerivations = TestableDerivations { oldDerivation :: StorePath , newDerivation :: StorePath } deriving Show initSimpleDerivations :: IO TestableDerivations initSimpleDerivations = do (oExit, o) <- readProcessStdout (nixInstantiate "./golden-tests/derivations/simple/old/drv.nix") (nExit, n) <- readProcessStdout (nixInstantiate "./golden-tests/derivations/simple/new/drv.nix") unless (oExit == ExitSuccess || nExit == ExitSuccess) (throwIO (ErrorCall "Can't instantiate simple derivations")) pure (TestableDerivations (storePathFromCLI o) (storePathFromCLI n)) initComplexDerivations :: IO TestableDerivations initComplexDerivations = do (oExit, o) <- readProcessStdout (nixPathInfo "./golden-tests/derivations/complex/old/") (nExit, n) <- readProcessStdout (nixPathInfo "./golden-tests/derivations/complex/new/") unless (oExit == ExitSuccess || nExit == ExitSuccess) (throwIO (ErrorCall "Can't instantiate complex derivations")) pure (TestableDerivations (storePathFromCLI o) (storePathFromCLI n)) nixInstantiate :: FilePath -> ProcessConfig () () () nixInstantiate fp = shell ("nix-instantiate " <> fp) nixPathInfo :: FilePath -> ProcessConfig () () () nixPathInfo fp = shell ("nix path-info --experimental-features 'nix-command flakes' --derivation " <> fp <> "#packages.x86_64-linux.default") makeDiffTree :: TestableDerivations -> DiffContext -> IO DerivationDiff makeDiffTree TestableDerivations{..} diffContext = do let status = Status Data.Set.empty let action = diff True oldDerivation (OutputNames (Data.Set.singleton "out")) newDerivation (OutputNames (Data.Set.singleton "out")) Control.Monad.State.evalStateT (Control.Monad.Reader.runReaderT action.unDiff diffContext) status -- | Drop conventional stdout newline, convert to StorePath storePathFromCLI :: BS.ByteString -> StorePath storePathFromCLI = StorePath . BS.unpack . BS.init -- drop new-line char