diff --git a/release.nix b/release.nix index 20f75f3a..8360c394 100644 --- a/release.nix +++ b/release.nix @@ -76,7 +76,7 @@ rec { hydraPath = stdenv.lib.concatStringsSep ":" (map (p: "${p}/bin") ( [ libxslt sqlite subversion openssh nix coreutils findutils - gzip bzip2 lzma gnutar unzip git + gzip bzip2 lzma gnutar unzip git mercurial gnused graphviz ] ++ ( if stdenv.isLinux then [rpm dpkg cdrkit] else [] ))); @@ -90,6 +90,7 @@ rec { cp ${"${nixpkgs}/pkgs/build-support/fetchsvn/nix-prefetch-svn"} $out/bin/nix-prefetch-svn cp ${"${nixpkgs}/pkgs/build-support/fetchgit/nix-prefetch-git"} $out/bin/nix-prefetch-git + cp ${"${nixpkgs}/pkgs/build-support/fetchhg/nix-prefetch-hg"} $out/bin/nix-prefetch-hg make -C src/c NIX=${nix} ATERM=${aterm} cp src/c/hydra_eval_jobs $out/bin diff --git a/src/lib/Hydra/Helper/AddBuilds.pm b/src/lib/Hydra/Helper/AddBuilds.pm index 3abc84ff..71e71207 100644 --- a/src/lib/Hydra/Helper/AddBuilds.pm +++ b/src/lib/Hydra/Helper/AddBuilds.pm @@ -6,6 +6,8 @@ use XML::Simple; use POSIX qw(strftime); use IPC::Run; use Hydra::Helper::Nix; +use Digest::SHA qw(sha256_hex); +use File::Path; our @ISA = qw(Exporter); our @EXPORT = qw(fetchInput evalJobs checkBuild inputsToArgs captureStdoutStderr); @@ -354,9 +356,82 @@ sub fetchInputGit { }; } +sub scmPath { + return getHydraPath . "/scm" ; +} -sub fetchInputCVS { +sub fetchInputHg { my ($db, $project, $jobset, $name, $type, $value) = @_; + + (my $uri, my $branch) = split ' ', $value; + $branch = defined $branch ? $branch : "default"; + + # init local hg clone + + my $stdout; my $stderr; + my $clonePath; + mkpath(scmPath); + $clonePath = scmPath . "/" . sha256_hex($uri); + + if (! -d $clonePath) { + (my $res, $stdout, $stderr) = captureStdoutStderr(600, + ("hg", "clone", $uri, $clonePath)); + die "Error cloning mercurial repo at `$uri':\n$stderr" unless $res; + } + + # hg pull + check rev + chdir $clonePath or die $!; + (my $res, $stdout, $stderr) = captureStdoutStderr(600, + ("hg", "pull")); + die "Error pulling latest change mercurial repo at `$uri':\n$stderr" unless $res; + + (my $res1, $stdout, $stderr) = captureStdoutStderr(600, + ("hg", "heads", $branch)); + die "Error getting head of $branch from `$uri':\n$stderr" unless $res; + + $stdout =~ m/[0-9]+:([0-9A-Fa-f]{12})/; + my $revision = $1; + die "Could not determine head revision of branch $branch" unless $revision; + + my $storePath; + my $sha256; + (my $cachedInput) = $db->resultset('CachedHgInputs')->search( + {uri => $uri, branch => $branch, revision => $revision}); + + if (defined $cachedInput && isValidPath($cachedInput->storepath)) { + $storePath = $cachedInput->storepath; + $sha256 = $cachedInput->sha256hash; + } else { + print STDERR "checking out Mercurial input from $uri $branch revision $revision\n"; + $ENV{"NIX_HASH_ALGO"} = "sha256"; + $ENV{"PRINT_PATH"} = "1"; + + (my $res, $stdout, $stderr) = captureStdoutStderr(600, + ("nix-prefetch-hg", $uri, $revision)); + die "Cannot check out Mercurial repository `$uri':\n$stderr" unless $res; + + ($sha256, $storePath) = split ' ', $stdout; + + txn_do($db, sub { + $db->resultset('CachedHgInputs')->create( + { uri => $uri + , branch => $branch + , revision => $revision + , sha256hash => $sha256 + , storepath => $storePath + }); + }); + } + + return + { type => $type + , uri => $uri + , branch => $branch + , storePath => $storePath + , sha256hash => $sha256 + , revision => $revision + }; + } @@ -411,7 +486,7 @@ sub inputsToArgs { when ("boolean") { push @res, "--arg", $input, $alt->{value}; } - when (["svn", "svn-checkout", "path", "build", "git", "cvs", "sysbuild"]) { + when (["svn", "svn-checkout", "path", "build", "git", "hg", "sysbuild"]) { push @res, "--arg", $input, ( "{ outPath = builtins.storePath " . $alt->{storePath} . "" . (defined $alt->{revision} ? "; rev = \"" . $alt->{revision} . "\"" : "") . diff --git a/src/root/common.tt b/src/root/common.tt index fa95d882..5b4c8425 100644 --- a/src/root/common.tt +++ b/src/root/common.tt @@ -8,6 +8,7 @@ , "svn-checkout" = "Subversion checkout" , "git" = "Git checkout" , "tarball" = "Download of a tarball" + , "hg" = "Mercurial checkout" , "string" = "String value" , "boolean" = "Boolean" , "path" = "Local path" diff --git a/src/sql/hydra.sql b/src/sql/hydra.sql index 7a09f2d9..5be50c56 100644 --- a/src/sql/hydra.sql +++ b/src/sql/hydra.sql @@ -318,6 +318,15 @@ create table CachedGitInputs ( primary key (uri, branch, revision) ); +create table CachedHgInputs ( + uri text not null, + branch text not null, + revision text not null, + sha256hash text not null, + storePath text not null, + primary key (uri, branch, revision) +); + create table CachedCVSInputs ( uri text not null, module text not null, @@ -495,6 +504,7 @@ create index IndexBuildsOnJobset on Builds(project, jobset); create index IndexBuildsOnProject on Builds(project); create index IndexBuildsOnTimestamp on Builds(timestamp); create index IndexBuildsOnJobFinishedId on builds(project, jobset, job, system, finished, id DESC); +create index IndexCachedHgInputsOnHash on CachedHgInputs(uri, branch, sha256hash); create index IndexCachedGitInputsOnHash on CachedGitInputs(uri, branch, sha256hash); create index IndexCachedGitInputsOnLastSeen on CachedGitInputs(uri, branch, lastSeen); create index IndexCachedSubversionInputsOnUriRevision on CachedSubversionInputs(uri, revision);