Add Haskell script trying to reproduce the build

We add a Haskell script in charge of reproducing the build.

We currently handle quite poorly the progress update: stderr isn't
streamed to the console. Knowing that a GHC build takes ~30 minutes,
it'll be good to at least show some kind of progress to the user while
building.
This commit is contained in:
Félix Baylac-Jacqué 2020-05-25 13:19:21 +02:00
parent 4ce91a2379
commit 3cd9149b29
No known key found for this signature in database
GPG Key ID: EFD315F31848DBA4
2 changed files with 70 additions and 9 deletions

68
ReproTest.hs Executable file
View File

@ -0,0 +1,68 @@
#!/usr/bin/env nix-shell
#!nix-shell -i runhaskell -p "haskellPackages.ghcWithPackages(p: with p; [ optparse-applicative text process ])" -p nix -p diffoscope
import Options.Applicative
import Data.Text hiding (filter)
import System.Exit
import System.Process
data Config = Config
{ pkgName :: Text,
ghcPath :: Text }
type ReproPaths = [Text]
type StorePath = Text
main :: IO ()
main = do
c <- execParser opts
mdp <- repro c
print mdp
pure ()
where
opts = info (configParser <**> helper)
( fullDesc
<> header "ReproTest.hs - Test the GHC binary reproducibility for a hackage package"
)
repro :: Config -> IO (Maybe ReproPaths)
repro c = do
-- 1. Nix instantiate derivation
(eci, drvPathDirty, err) <- readProcessWithExitCode "nix-instantiate"
[
"--arg", "hs-pkg-name", "\"" ++ unpack (pkgName c) ++ "\"",
"--arg", "ghcSrc", unpack $ ghcPath c,
"./repro.nix"
] ""
let drvPath = filter (/= '\n') drvPathDirty
print err
print drvPath
print eci
-- 2. nix-store --realize /nix/store/xxx.drv
(ecr1, p1, err1) <- readProcessWithExitCode "nix-store"
[ "--realise", "--quiet", filter (/= '\n') drvPath ] ""
print ecr1
print p1
print err1
-- 3. nix-store --realize --check /nix/store/xxx.drv
(ecr2, p2, err2) <- readProcessWithExitCode "nix-store"
[ "--realise", "--quiet", "-K", "--check", drvPath ] ""
print ecr2
print p2
print ecr2
-- 4. If exit code > 1 => Just two repro paths
if ecr2 == ExitSuccess
then pure Nothing
else pure $ Just [ pack p1, pack p2 ]
runDiffoscope :: ReproPaths -> IO StorePath
runDiffoscope = undefined
-- Take the two different paths.
-- Run diffoscope on them.
configParser :: Parser Config
configParser = Config
<$> strOption (long "package-name" <> short 'p' <> help "Hackage package to test")
<*> (strOption (long "ghc-path" <> short 'g' <> help "Path to the local GHC checkpoint")
<|> strOption (long "ghc-nixexpr-path" <> short 'e' <> help "Path to the nix expression generating the GHC binary"))

View File

@ -2,12 +2,5 @@
hs-pkg-name ? "wcwidth",
ghcSrc ? /home/ninjatrappeur/Code/perso/haskell/ghc
}:
let
ghcOverlay =
import ./overlays/ghc.nix {
inherit ghcSrc pkgs;
};
nixpkgsConfig = { overlays = [ ghcOverlay ]; };
nixpkgsSrc = (import ./nix/sources.nix).nixpkgs;
pkgs = import nixpkgsSrc nixpkgsConfig;
in pkgs.customGhcHEAD."${hs-pkg-name}"
import ./repro.nix { inherit hs-pkg-name ghcSrc; }