croak("\e[31mERROR\e[m ", @_, "\n\t");
}
# System utilities
- sub rm ($) {
- my ($file) = @_;
- debug(sub{"file="},$file);
- unlink($file)
- or error("rm $file");
- }
- sub mkdir ($) {
- my ($dir) = @_;
- debug(sub{"dir=\"$dir\"\n"});
- File::Path::make_path($dir, {verbose=>0, error => \my $error});
- if (@$error) {
- for my $diag (@$error) {
- my ($dir, $message) = %$diag;
- if ($dir eq '') {
- print "general error: $message\n";
- }
- else {
- print "problem mkdir $dir: $message\n";
+ sub rm (@) {
+ foreach my $file (@_) {
+ debug(sub{"file=$file\n"});
+ if (not -e $file) {
+ unlink($file)
+ or error("rm $file");
+ }
+ }
+ }
+ sub mkdir (@) {
+ foreach my $dir (@_) {
+ debug(sub{"dir=$dir\n"});
+ File::Path::make_path($dir, {verbose=>0, error => \my $error});
+ if (@$error) {
+ for my $diag (@$error) {
+ my ($dir, $message) = %$diag;
+ error("dir=$dir: $message");
}
}
}
return $clear;
}
# grg remote I/O
- sub grg_remote_fetch_file ($$$) {
- my ($ctx, $files, $fetch_files) = @_;
+ sub grg_remote_fetch_file ($) {
+ my ($ctx) = @_;
# NOTE: avoid File::Copy::copy().
- while (my ($file, undef) = each %$fetch_files) {
+ while (my ($file, undef) = each %{$ctx->{remote}->{fetch}}) {
my $path = File::Spec->catfile($ctx->{remote}->{uri}->file, $file);
- debug(sub{'test path='}, $path);
if (-r $path) {
- my $h = $fetch_files->{$file};
+ my $h = $ctx->{remote}->{fetch}->{$file};
$h->{path} = $path;
$h->{preserve} = 1;
}
}
return 1;
}
- sub grg_remote_fetch_rsync ($$$) {
- my ($ctx, $files, $fetch_files) = @_;
+ sub grg_remote_fetch_rsync ($) {
+ my ($ctx) = @_;
my $uri = $ctx->{remote}->{uri}->clone;
- $uri->scheme(undef);
- $uri->fragment(undef);
- $uri->query(undef);
- $uri = $uri->as_string;
+ my @src;
+ if ($uri->opaque =~ m{^//}) {
+ $uri->fragment(undef);
+ $uri->query(undef);
+ @src = map { $uri->path($_); $uri->as_string; }
+ (keys %{$ctx->{remote}->{fetch}});
+ }
+ else {
+ my ($authority, $path, $fragment)
+ = $uri->as_string =~ m|^rsync:(?:([^/#:]+):)?([^?#]*)(?:#(.*))?$|;
+ @src = map { "$authority:$path/$_" }
+ (keys %{$ctx->{remote}->{fetch}});
+ }
IPC::Run::run([@{$ctx->{config}->{rsync}}
- , '--verbose', '--ignore-times', '--inplace', '--progress'
- , (map { File::Spec->catfile($uri, $_) } @$files)
+ , '-i', '--ignore-times', '--inplace', '--progress'
+ , @src
, $ctx->{'dir-cache'}.'/']
, '>&2')
}
- sub grg_remote_fetch_sftp ($$$) {
- my ($ctx, $files, $fetch_files) = @_;
+ sub grg_remote_fetch_sftp ($) {
+ my ($ctx) = @_;
IPC::Run::run([@{$ctx->{config}->{curl}}
, '--show-error'
, '--output', File::Spec->catfile($ctx->{'dir-cache'}, '#1')
- , File::Spec->catfile($ctx->{remote}->{uri}, '{'.join(',',@$files).'}') ])
+ , File::Spec->catfile($ctx->{remote}->{uri}->as_string
+ , '{'.join(',', (keys %{$ctx->{remote}->{fetch}})).'}') ])
}
sub grg_remote_fetch ($$) {
my ($ctx, $files) = @_;
debug(sub{'files='}, $files);
my $scheme = $ctx->{remote}->{uri}->scheme;
- my $fetch_files = {map { $_ => { path => File::Spec->catfile($ctx->{'dir-cache'}, $_), preserve => 0 } } @$files};
+ $ctx->{remote}->{fetch}
+ = {map { $_ =>
+ { path => File::Spec->catfile($ctx->{'dir-cache'}, $_)
+ , preserve => 0 }
+ } @$files};
my $fct =
{ file => \&grg_remote_fetch_file
, rsync => \&grg_remote_fetch_rsync
}->{$scheme};
error("URL scheme not supported: `$scheme'")
unless $fct;
- debug(sub{'fetch_files='}, $fetch_files);
- $fct->($ctx, $files, $fetch_files)
- or $fetch_files = {};
- debug(sub{'fetch_files='}, $fetch_files);
- return $fetch_files;
+ $fct->($ctx)
+ or $ctx->{remote}->{fetch} = {};
+ return $ctx->{remote}->{fetch};
}
sub grg_remote_init_file ($) {
my ($ctx) = @_;
}
sub grg_remote_init_rsync ($) {
my ($ctx) = @_;
- my $tmp = File::Temp->tempdir(CLEANUP => 1);
- my $path = $ctx->{remote}->{uri}->path;
- my $uri = $ctx->{remote}->{uri}->clone;
- $uri->fragment(undef);
- $uri->path(undef);
- $uri->query(undef);
+ my $tmp = File::Temp->tempdir('grg_rsync_XXXXXXXX', CLEANUP => 1);
+ my $uri = $ctx->{remote}->{uri}->clone;
+ my ($path, $dst);
+ if ($uri->opaque =~ m{^//}) {
+ $uri->fragment(undef);
+ $uri->query(undef);
+ $path = $uri->path;
+ $dst = $uri->as_string;
+ }
+ else {
+ my ($authority, $fragment);
+ ($authority, $path, $fragment)
+ = $uri->as_string =~ m|^rsync:(?:([^/#:]+):)?([^?#]*)(?:#(.*))?$|;
+ $dst = "$authority:";
+ }
&mkdir(File::Spec->catdir($tmp, $path));
IPC::Run::run([@{$ctx->{config}->{rsync}}
- , '--verbose', '--recursive', '--relative'
+ , '-i', '--recursive', '--relative'
, '--exclude=*', '.'
- , File::Spec->catfile($uri->as_string)]
+ , $dst]
+ , '>&2'
, init => sub { chdir $tmp or die $!; })
}
sub grg_remote_init_sftp ($) {
or error("remote init failed");
return;
}
- sub grg_remote_push_file ($$) {
- my ($ctx, $files) = @_;
+ sub grg_remote_push_file ($) {
+ my ($ctx) = @_;
my $ok = 1;
- foreach my $file (@$files) {
+ foreach my $file (@{$ctx->{remote}->{push}}) {
my $src = File::Spec->catfile($ctx->{'dir-cache'}, $file);
my $dst = File::Spec->catfile($ctx->{remote}->{uri}->file, $file);
debug(sub{"File::Copy::move('$src', '$dst')\n"});
}
return $ok;
}
- sub grg_remote_push_rsync ($$) {
- my ($ctx, $files) = @_;
- my $uri = $ctx->{remote}->{uri}->clone;
- $uri->fragment('');
- $uri->query('');
+ sub grg_remote_push_rsync ($) {
+ my ($ctx) = @_;
+ my $uri = $ctx->{remote}->{uri}->clone;
+ $uri->fragment(undef);
+ $uri->query(undef);
+ my ($path, $dst);
+ if ($uri->opaque =~ m{^//}) {
+ $uri->fragment(undef);
+ $uri->query(undef);
+ $dst = $uri->as_string;
+ }
+ else {
+ my ($authority, $path, $fragment)
+ = $uri->as_string =~ m|^rsync:(?:([^/#:]+):)?([^?#]*)(?:#(.*))?$|;
+ $dst = "$authority:$path/";
+ }
IPC::Run::run([@{$ctx->{config}->{rsync}}
- , '--verbose', '--relative'
- , @$files
- , $uri->as_string])
+ , '-i', '--relative'
+ , (@{$ctx->{remote}->{push}})
+ , $dst]
+ , '>&2'
+ , init => sub { chdir $ctx->{'dir-cache'} or die $!; });
}
- sub grg_remote_push_sftp ($$) {
- my ($ctx, $files) = @_;
+ sub grg_remote_push_sftp ($) {
+ my ($ctx) = @_;
my $uri = $ctx->{remote}->{uri}->clone;
$uri->fragment('');
$uri->query('');
IPC::Run::run([@{$ctx->{config}->{curl}}
, '--show-error', '--ftp-create-dirs', '--upload-file'
- , '{'.join(',', @$files).'}'
+ , '{'.join(',', @{$ctx->{remote}->{push}}).'}'
, $uri->as_string.'/'])
}
sub grg_remote_push ($) {
}->{$scheme};
error("URL scheme not supported: `$scheme'")
unless $fct;
- $fct->($ctx, $ctx->{remote}->{push})
+ $fct->($ctx)
or error("remote push failed");
+ rm(map {File::Spec->catfile($ctx->{'dir-cache'}, $_)} @{$ctx->{remote}->{push}});
return 1;
}
sub grg_remote_remove ($) {
&mkdir($ctx->{'dir-cache'});
}
else {
- $ctx->{'dir-cache'} = File::Temp->tempdir(CLEANUP => 1);
+ $ctx->{'dir-cache'} = File::Temp->tempdir('grg_cache_XXXXXXXX', CLEANUP => 1);
}
debug(sub{"ctx="},$ctx);
grg_commands($ctx);
=head2 Via rsync(1)
-=item git remote add $remote gpg::rsync://${user:+$user@}$host/$path
+=item git remote add $remote gpg::rsync:${user:+$user@}$host:$path
+
+=item git remote add $remote gpg::rsync://${user:+$user@}$host${port:+:$port}/$path
=head2 Via curl(1)
-=item git remote add $remote gpg::sftp://${user:+$user@}$host/$path
+=item git remote add $remote gpg::sftp://${user:+$user@}$host${port:+:$port}/$path
=head2 Via File::Copy(3pm)