diff --git a/deps.nix b/deps.nix index 90505bd4..7a8c943d 100644 --- a/deps.nix +++ b/deps.nix @@ -20,6 +20,8 @@ with pkgs; perlPackages.DBDSQLite perlPackages.EmailSender perlPackages.TextTable + perlPackages.TextDiff + perlPackages.FileSlurp perlPackages.NetTwitterLite perlPackages.PadWalker perlPackages.DataDump diff --git a/src/lib/Hydra/Controller/API.pm b/src/lib/Hydra/Controller/API.pm index 630dfbda..f1ee9c81 100644 --- a/src/lib/Hydra/Controller/API.pm +++ b/src/lib/Hydra/Controller/API.pm @@ -10,6 +10,8 @@ use Hydra::Controller::Project; use JSON::Any; use DateTime; use Digest::SHA qw(sha256_hex); +use Text::Diff; +use File::Slurp; # !!! Rewrite this to use View::JSON. @@ -213,7 +215,7 @@ sub scmdiff : Chained('api') PathPart('scmdiff') Args(0) { if($type eq "hg") { my $clonePath = scmPath . "/" . sha256_hex($uri); die if ! -d $clonePath; - $diff .= `(cd $clonePath ; hg log -r $rev1:$rev2)`; + $diff .= `(cd $clonePath ; hg log -r $rev1 -r $rev2 -b $branch)`; $diff .= `(cd $clonePath ; hg diff -r $rev1:$rev2)`; } elsif ($type eq "git") { my $clonePath = scmPath . "/" . sha256_hex($uri.$branch); @@ -226,4 +228,37 @@ sub scmdiff : Chained('api') PathPart('scmdiff') Args(0) { $c->forward('Hydra::View::Plain'); } +sub readNormalizedLog { + my ($file) = @_; + my $res = read_file($file); + + $res =~ s/\/nix\/store\/[a-z0-9]*-/\/nix\/store\/...-/g; + $res =~ s/nix-build-[a-z0-9]*-/nix-build-...-/g; + $res =~ s/[0-9]{2}:[0-9]{2}:[0-9]{2}/00:00:00/g; + return $res; +} + +sub logdiff : Chained('api') PathPart('logdiff') Args(2) { + my ($self, $c, $buildid1, $buildid2) = @_; + + my $diff = ""; + + my $build1 = getBuild($c, $buildid1); + notFound($c, "Build with ID $buildid1 doesn't exist.") + if !defined $build1; + my $build2 = getBuild($c, $buildid2); + notFound($c, "Build with ID $buildid2 doesn't exist.") + if !defined $build2; + + if (-f $build1->resultInfo->logfile && -f $build2->resultInfo->logfile) { + my $logtext1 = readNormalizedLog($build1->resultInfo->logfile); + my $logtext2 = readNormalizedLog($build2->resultInfo->logfile); + $diff = diff \$logtext1, \$logtext2; + } else { + $c->response->status(404); + } + $c->stash->{'plain'} = { data => (scalar $diff) || " " }; + $c->forward('Hydra::View::Plain'); +} + 1; diff --git a/src/lib/Hydra/Controller/Root.pm b/src/lib/Hydra/Controller/Root.pm index d5977b36..8661007a 100644 --- a/src/lib/Hydra/Controller/Root.pm +++ b/src/lib/Hydra/Controller/Root.pm @@ -151,6 +151,7 @@ sub robots_txt : Path('robots.txt') { , uri_for('Root', 'status', []) , uri_for('Root', 'all', []) , uri_for('API', 'scmdiff', []) + , uri_for('API', 'logdiff', [],"*", "*") , uri_for('Project', 'all', ["*"]) , channelUris('Root', ["*"]) , channelUris('Project', ["*", "*"]) diff --git a/src/root/build.tt b/src/root/build.tt index 82920c0b..8b23e777 100644 --- a/src/root/build.tt +++ b/src/root/build.tt @@ -184,15 +184,19 @@ [% INCLUDE renderBuildSteps type="Failed" %] [% END %] - [% IF build.resultInfo.buildstatus != 0 && prevSuccessfulBuild %]
Last successful build [% INCLUDE renderDateTime timestamp = prevSuccessfulBuild.timestamp %] | - [% IF prevSuccessfulBuild && firstBrokenBuild && firstBrokenBuild.id != build.id %]First broken build [% INCLUDE renderDateTime timestamp = firstBrokenBuild.timestamp %] | [% END %] -This build [% INCLUDE renderDateTime timestamp = build.timestamp %] | + [% IF prevSuccessfulBuild && firstBrokenBuild && firstBrokenBuild.id != build.id %] +First broken build [% INCLUDE renderDateTime timestamp = firstBrokenBuild.timestamp %] + [ log diff ] + |
+ [% END %]
+ This build [% INCLUDE renderDateTime timestamp = build.timestamp %] + [ log diff ] + |
---|---|
[% INCLUDE renderBuildStatusIcon build=prevSuccessfulBuild size=32 %] [% INCLUDE renderFullBuildLink build=prevSuccessfulBuild %] | @@ -205,7 +209,6 @@[% INCLUDE renderInputDiff build1=prevSuccessfulBuild , build2=build %] |