summaryrefslogtreecommitdiff
path: root/Pristine
diff options
context:
space:
mode:
authorJoey Hess <joey@kitenet.net>2010-07-23 20:57:51 -0400
committerJoey Hess <joey@kitenet.net>2010-07-23 20:57:51 -0400
commitf77b09cef158cb2060bd9921820a31174439f3ee (patch)
tree246b5a303de544f89fb01c713aec611b6bf6439a /Pristine
parent39f7d64c6438d213a3dfee7190f0331099f116e0 (diff)
downloadpristine-tar-f77b09cef158cb2060bd9921820a31174439f3ee.tar.gz
pristine-tar-f77b09cef158cb2060bd9921820a31174439f3ee.tar.bz2
pristine-tar-f77b09cef158cb2060bd9921820a31174439f3ee.zip
modularize the delta writing code
This will make it easy to add support for flat deltas, etc.
Diffstat (limited to 'Pristine')
-rw-r--r--Pristine/Tar/Delta.pm73
-rw-r--r--Pristine/Tar/Delta/Tarball.pm63
2 files changed, 94 insertions, 42 deletions
diff --git a/Pristine/Tar/Delta.pm b/Pristine/Tar/Delta.pm
index 50ecf76..c5e6572 100644
--- a/Pristine/Tar/Delta.pm
+++ b/Pristine/Tar/Delta.pm
@@ -1,21 +1,38 @@
#!/usr/bin/perl
# pristine-tar delta file library
+# See delta-format.txt for details about the contents of delta files.
package Pristine::Tar::Delta;
use Pristine::Tar;
use warnings;
use strict;
-use File::Basename;
-# See delta-format.txt for details about the contents of delta files.
-#
-# Some of the delta contents are treated as files. Things not listed here
-# are treated as fields with short values.
+# Checks if a field of a delta should be stored in the delta hash using
+# a filename. (Normally the hash stores the whole field value, but
+# using filenames makes sense for a few fields.)
my %delta_files=map { $_ => 1 } qw(manifest delta wrapper);
+sub is_filename {
+ my $field=shift;
+ return $delta_files{$field};
+}
-# After the filename to create, this takes a hashref containing
-# the contents of the delta file to create.
+sub handler {
+ my $action=shift;
+ my $type=shift;
+
+ my $class="Pristine::Tar::Delta::$type";
+ eval "use $class";
+ if ($@) {
+ error "unsupported delta file format $type";
+ }
+ $class->$action(@_);
+}
+
+# After the type of delta and the file to create (which can be "-"
+# to send it to stdout), this takes a hashref containing the contents of
+# the delta to write.
sub write {
+ my $type=shift;
my $deltafile=shift;
my $delta=shift;
@@ -26,19 +43,8 @@ sub write {
$stdout=1;
$deltafile="$tempdir/tmpout";
}
-
- foreach my $field (keys %$delta) {
- if ($delta_files{$field}) {
- link($delta->{$field}, "$tempdir/$field") || die "link $tempdir/$field: $!";
- }
- else {
- open (my $out, ">", "$tempdir/$field") || die "$tempdir/$field: $!";
- print $out $delta->{$field}."\n";
- close $out;
- }
- }
-
- doit("tar", "czf", $deltafile, "-C", $tempdir, keys %$delta);
+
+ handler('write', $type, $deltafile, $delta);
if ($stdout) {
doit("cat", $deltafile);
@@ -50,6 +56,7 @@ sub write {
# Returns a hashref of the contents of the delta.
sub read {
+ my $type=shift;
my $deltafile=shift;
my $tempdir=tempdir();
@@ -63,30 +70,12 @@ sub read {
}
close $out;
}
- doit("tar", "xf", File::Spec->rel2abs($deltafile), "-C", $tempdir);
- unlink($deltafile) if $stdin;
- my %delta;
- foreach my $file (glob("$tempdir/*")) {
- if (-f $file) {
- my $field=basename($file);
- if ($delta_files{$field}) {
- $delta{$field}=$file;
- }
- else {
- open (my $in, "<", $file) || die "$file: $!";
- {
- local $/=undef;
- $delta{$field}=<$in>;
- }
- chomp $delta{$field};
- close $in;
- }
- }
- }
- # TODO read all files
+ my $delta=handler('read', $type, $deltafile);
- return \%delta;
+ unlink($deltafile) if $stdin;
+
+ return $delta;
}
# Checks the type, maxversion, minversion of a delta hashref.
diff --git a/Pristine/Tar/Delta/Tarball.pm b/Pristine/Tar/Delta/Tarball.pm
new file mode 100644
index 0000000..ab38935
--- /dev/null
+++ b/Pristine/Tar/Delta/Tarball.pm
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+# pristine-tar delta files formatted as tarballs
+package Pristine::Tar::Delta::Tarball;
+
+use Pristine::Tar;
+use Pristine::Tar::Delta;
+use File::Basename;
+use warnings;
+use strict;
+
+sub write {
+ my $class=shift;
+ my $deltafile=shift;
+ my $delta=shift;
+
+ my $tempdir=tempdir();
+
+ foreach my $field (keys %$delta) {
+ if (Pristine::Tar::Delta::is_filename($field)) {
+ link($delta->{$field}, "$tempdir/$field") || die "link $tempdir/$field: $!";
+ }
+ else {
+ open (my $out, ">", "$tempdir/$field") || die "$tempdir/$field: $!";
+ print $out $delta->{$field}."\n";
+ close $out;
+ }
+ }
+
+ doit("tar", "czf", $deltafile, "-C", $tempdir, keys %$delta);
+
+ return $delta;
+}
+
+sub read {
+ my $class=shift;
+ my $deltafile=shift;
+
+ my $tempdir=tempdir();
+ doit("tar", "xf", File::Spec->rel2abs($deltafile), "-C", $tempdir);
+
+ my %delta;
+ foreach my $file (glob("$tempdir/*")) {
+ if (-f $file) {
+ my $field=basename($file);
+ if (Pristine::Tar::Delta::is_filename($field)) {
+ $delta{$field}=$file;
+ }
+ else {
+ open (my $in, "<", $file) || die "$file: $!";
+ {
+ local $/=undef;
+ $delta{$field}=<$in>;
+ }
+ chomp $delta{$field};
+ close $in;
+ }
+ }
+ }
+
+ return \%delta;
+}
+
+1