forked from lix-project/hydra
82 lines
2.6 KiB
Perl
82 lines
2.6 KiB
Perl
package Hydra::Plugin::PathInput;
|
|
|
|
use strict;
|
|
use parent 'Hydra::Plugin';
|
|
use POSIX qw(strftime);
|
|
use Hydra::Helper::Nix;
|
|
use Nix::Store;
|
|
|
|
sub supportedInputTypes {
|
|
my ($self, $inputTypes) = @_;
|
|
$inputTypes->{'path'} = 'Local path';
|
|
}
|
|
|
|
sub fetchInput {
|
|
my ($self, $type, $name, $value) = @_;
|
|
|
|
return undef if $type ne "path";
|
|
|
|
my $uri = $value;
|
|
|
|
my $timestamp = time;
|
|
my $sha256;
|
|
my $storePath;
|
|
|
|
# Some simple caching: don't check a path more than once every N seconds.
|
|
(my $cachedInput) = $self->{db}->resultset('CachedPathInputs')->search(
|
|
{srcpath => $uri, lastseen => {">", $timestamp - 30}},
|
|
{rows => 1, order_by => "lastseen DESC"});
|
|
|
|
if (defined $cachedInput && isValidPath($cachedInput->storepath)) {
|
|
$storePath = $cachedInput->storepath;
|
|
$sha256 = $cachedInput->sha256hash;
|
|
$timestamp = $cachedInput->timestamp;
|
|
} else {
|
|
|
|
print STDERR "copying input ", $name, " from $uri\n";
|
|
if ( $uri =~ /^\// ) {
|
|
$storePath = `nix-store --add "$uri"`
|
|
or die "cannot copy path $uri to the Nix store.\n";
|
|
} else {
|
|
$storePath = `PRINT_PATH=1 nix-prefetch-url "$uri" | tail -n 1`
|
|
or die "cannot fetch $uri to the Nix store.\n";
|
|
}
|
|
chomp $storePath;
|
|
|
|
$sha256 = (queryPathInfo($storePath, 0))[1] or die;
|
|
|
|
($cachedInput) = $self->{db}->resultset('CachedPathInputs')->search(
|
|
{srcpath => $uri, sha256hash => $sha256});
|
|
|
|
# Path inputs don't have a natural notion of a "revision", so
|
|
# we simulate it by using the timestamp that we first saw this
|
|
# path have this SHA-256 hash. So if the contents of the path
|
|
# changes, we get a new "revision", but if it doesn't change
|
|
# (or changes back), we don't get a new "revision".
|
|
if (!defined $cachedInput) {
|
|
txn_do($self->{db}, sub {
|
|
$self->{db}->resultset('CachedPathInputs')->update_or_create(
|
|
{ srcpath => $uri
|
|
, timestamp => $timestamp
|
|
, lastseen => $timestamp
|
|
, sha256hash => $sha256
|
|
, storepath => $storePath
|
|
});
|
|
});
|
|
} else {
|
|
$timestamp = $cachedInput->timestamp;
|
|
txn_do($self->{db}, sub {
|
|
$cachedInput->update({lastseen => time});
|
|
});
|
|
}
|
|
}
|
|
|
|
return
|
|
{ uri => $uri
|
|
, storePath => $storePath
|
|
, sha256hash => $sha256
|
|
, revision => strftime "%Y%m%d%H%M%S", gmtime($timestamp)
|
|
};
|
|
}
|
|
|
|
1;
|