From: Joey Hess Date: Sat, 24 Jul 2010 00:57:51 +0000 (-0400) Subject: modularize the delta writing code X-Git-Tag: 1.11~15 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f77b09cef158cb2060bd9921820a31174439f3ee;p=tools%2Fpristine-tar.git modularize the delta writing code This will make it easy to add support for flat deltas, etc. --- 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 diff --git a/pristine-bz2 b/pristine-bz2 index ed55fb6..1c69c91 100755 --- a/pristine-bz2 +++ b/pristine-bz2 @@ -244,7 +244,7 @@ sub genbz2 { my $deltafile=shift; my $file=shift; - my $delta=Pristine::Tar::Delta::read($deltafile); + my $delta=Pristine::Tar::Delta::read(Tarball => $deltafile); Pristine::Tar::Delta::assert($delta, type => "bz2", maxversion => 2, fields => [qw{params program}]); @@ -276,7 +276,7 @@ sub gendelta { my ($program, @params) = reproducebzip2($bzip2file); - Pristine::Tar::Delta::write($deltafile, { + Pristine::Tar::Delta::write(Tarball => $deltafile, { version => '2.0', type => 'bz2', params => "@params", diff --git a/pristine-gz b/pristine-gz index 7356d37..9687c49 100755 --- a/pristine-gz +++ b/pristine-gz @@ -267,7 +267,7 @@ sub gengz { my $deltafile=shift; my $file=shift; - my $delta=Pristine::Tar::Delta::read($deltafile); + my $delta=Pristine::Tar::Delta::read(Tarball => $deltafile); Pristine::Tar::Delta::assert($delta, type => "gz", maxversion => 3, fields => [qw{params filename timestamp}]); @@ -312,7 +312,7 @@ sub gendelta { my ($filename, $timestamp, $xdelta, @params)= reproducegz($gzfile, $tempdir, "$tempdir/test"); - Pristine::Tar::Delta::write($deltafile, { + Pristine::Tar::Delta::write(Tarball => $deltafile, { version => (defined $xdelta ? "3.0" : "2.0"), type => 'gz', params => "@params", diff --git a/pristine-tar b/pristine-tar index 82d9045..a741b92 100755 --- a/pristine-tar +++ b/pristine-tar @@ -327,7 +327,7 @@ sub gentar { my $tarball=shift; my %opts=@_; - my $delta=Pristine::Tar::Delta::read($deltafile); + my $delta=Pristine::Tar::Delta::read(Tarball => $deltafile); Pristine::Tar::Delta::assert($delta, type => "tar", maxversion => 2, minversion => 2, fields => [qw{manifest delta}]); @@ -338,7 +338,7 @@ sub gentar { doit("xdelta", "patch", $delta->{delta}, $recreatetarball, $out); if (defined $delta->{wrapper}) { - my $delta_wrapper=Pristine::Tar::Delta::read($delta->{wrapper}); + my $delta_wrapper=Pristine::Tar::Delta::read(Tarball => $delta->{wrapper}); if ($delta_wrapper->{type} eq 'gz') { doit("pristine-gz", ($verbose ? "-v" : "--no-verbose"), @@ -457,7 +457,7 @@ sub gendelta { error "xdelta failed with return code $ret"; } - Pristine::Tar::Delta::write($deltafile, { + Pristine::Tar::Delta::write(Tarball => $deltafile, { version => 2, type => 'tar', %delta,