Compare commits

..

1 commit

Author SHA1 Message Date
Félix Baylac-Jacqué 39b98f330a
Add Haskell script trying to reproduce the build
We add a Haskell script in charge of reproducing the build.
2020-05-26 18:04:47 +02:00
3 changed files with 49 additions and 11 deletions

View file

@ -2,6 +2,7 @@
#!nix-shell -i runhaskell -p "haskellPackages.ghcWithPackages(p: with p; [ relude optparse-applicative process ])" -p nix -p diffoscope
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE BangPatterns #-}
import Relude
@ -18,8 +19,11 @@ import System.Process
data Config = Config
{ pkgName :: Text,
ghcPath :: Text }
{ pkgName :: Text,
ghcPath :: Text,
diffOutDir :: Text,
nbRepro :: Int
}
data ReproStatus = ReproStatus IsReproducible ReproPaths
type IsReproducible = Bool
@ -33,8 +37,11 @@ main = do
rs <- runExceptT $ repro c
case rs of
Left err -> T.putStrLn err >> exitFailure
Right (ReproStatus True xs) -> T.putStrLn "SUCCESS" >> exitSuccess
Right (ReproStatus False xs) -> T.putStr $ "Cannot Reproduce build:\n" <> unwords xs
Right (ReproStatus True xs) -> T.putStrLn "The build seems to be reproducible" >> exitSuccess
Right (ReproStatus False xs) -> do
runDiffoscope c xs
T.putStrLn $ "Cannot Reproduce build.\n" <> unwords xs
T.putStrLn $ "See diffoscope report for more details: " <> diffOutDir c
where
opts = info (configParser <**> helper)
( fullDesc
@ -43,8 +50,10 @@ main = do
configParser :: Parser Config
configParser = Config
<$> strOption (long "package-name" <> short 'p' <> help "Hackage package to test")
<$> strOption (long "package-name" <> short 'p' <> help "Hackage package to test.")
<*> strOption (long "ghc-nixexpr-path" <> short 'e' <> help "Path to the nix derivation retrieving the custom GHC checkpout you want to use.")
<*> strOption (long "report-dir" <> short 'o' <> help "Directory in which you want to store the diff output in case of a failing test." <> showDefault <> value "./diff-out")
<*> option auto (long "nb-repro" <> short 'n' <> help "How much reproduction iterations we want to perform." <> showDefault <> value 3)
repro :: (MonadIO m) => Config -> ExceptT NixError m ReproStatus
repro c = do
@ -59,15 +68,23 @@ repro c = do
(_, p1) <- streamRunCmd "nix-store"
["--realise", "--quiet", drvPath] True
-- 3. nix-store --realize --check /nix/store/xxx.drv
(ecr2, p2) <- streamRunCmd "nix-store"
["--realise", "--quiet", "-K", "--check", drvPath] False
(ecr2, p2) <- repeatRepro c drvPath
-- 4. If exit code > 1 => Just two repro paths
pure $ ReproStatus (ecr2 == E.ExitSuccess) [p1, p2]
runDiffoscope :: ReproPaths -> IO StorePath
runDiffoscope = undefined
-- Take the two different paths.
-- Run diffoscope on them.
repeatRepro :: (MonadIO m) => Config -> Text -> ExceptT NixError m (E.ExitCode, StorePath)
repeatRepro c drv = go $ nbRepro c
where
go (!i) = do
(ecr2, p2) <- streamRunCmd "nix-store"
["--realise", "--quiet", "-K", "--check", drv] False
if ecr2 /= E.ExitSuccess || i < 1
then pure (ecr2, p2)
else go $ i - 1
runDiffoscope :: Config -> ReproPaths -> IO ()
runDiffoscope c rp = callProcess "diffoscope"
$ unpack <$> [ "--html-dir", diffOutDir c ] <> rp
-- Partially vendored from Shask
-- TODO:

7
examples/ghc-src.nix Normal file
View file

@ -0,0 +1,7 @@
let
pkgs = import (import ../nix/sources.nix).nixpkgs {};
in pkgs.fetchgit {
url = "https://gitlab.haskell.org/ghc/ghc.git/";
rev = "40c71c2cf38b4e134d81b7184a4d5e02949ae70c";
sha256 = "04h9rcyzm9w3an1z00hjs062dp7dl19b8pkyxjsypr7a2i9dmvkb";
}

14
repro.nix Normal file
View file

@ -0,0 +1,14 @@
{
hs-pkg-name ? "wcwidth",
ghcSrcDrv ? ./examples/ghc.nix
}:
let
ghcSrc = import ghcSrcDrv;
ghcOverlay =
import ./overlays/ghc.nix {
inherit ghcSrc pkgs;
};
nixpkgsConfig = { overlays = [ ghcOverlay ]; };
nixpkgsSrc = (import ./nix/sources.nix).nixpkgs;
pkgs = import nixpkgsSrc nixpkgsConfig;
in pkgs.haskellPackages."${hs-pkg-name}"