Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This might be a good starting point for a good Perl program. It does what the question asked for though.</p> <p>It was just hacked together, and ignores most of the best practices for Perl.</p> <pre> perl test.pl full \ Downloads/update-dnsomatic-0.1.2.tar.gz \ Downloads/ \ update-dnsomatic-0.1.2 </pre> <pre><code>#! /usr/bin/env perl use strict; use 5.010; use warnings; use autodie; use Archive::Tar; use File::Spec::Functions qw'catfile catdir'; my($action,$file,$directory,$special_dir) = @ARGV; if( @ARGV == 1 ){ $file = *STDOUT{IO}; } if( @ARGV == 3 ){ $special_dir = ''; } sub has_file(_); sub same_size($$); sub find_missing(\%$); given( lc $action ){ # only compare names when( @{[qw'simple name names']} ){ my @list = Archive::Tar-&gt;list_archive($file); say qq'missing file: "$_"' for grep{ ! has_file } @list; } # compare names, sizes, contents when( @{[qw'full aggressive']} ){ my $next = Archive::Tar-&gt;iter($file); my( %visited ); while( my $file = $next-&gt;() ){ next unless $file-&gt;is_file; my $name = $file-&gt;name; $visited{$name} = 1; unless( has_file($name) ){ say qq'missing file: "$name"' ; next; } unless( same_size( $name, $file-&gt;size ) ){ say qq'different size: "$name"'; next; } next unless $file-&gt;size; unless( same_checksum( $name, $file-&gt;get_content ) ){ say qq'different checksums: "$name"'; next; } } say qq'file not in archive: "$_"' for find_missing %visited, $special_dir; } } sub has_file(_){ my($file) = @_; if( -e catfile $directory, $file ){ return 1; } return; } sub same_size($$){ my($file,$size) = @_; if( -s catfile($directory,$file) == $size ){ return $size || '0 but true'; } return; # empty list/undefined } sub same_checksum{ my($file,$contents) = @_; require Digest::SHA1; my($outside,$inside); my $sha1 = Digest::SHA1-&gt;new; { open my $io, '&lt;', catfile $directory, $file; $sha1-&gt;addfile($io); close $io; $outside = $sha1-&gt;digest; } $sha1-&gt;add($contents); $inside = $sha1-&gt;digest; return 1 if $inside eq $outside; return; } sub find_missing(\%$){ my($found,$current_dir) = @_; my(@dirs,@files); { my $open_dir = catdir($directory,$current_dir); opendir my($h), $open_dir; while( my $elem = readdir $h ){ next if $elem =~ /^[.]{1,2}[\\\/]?$/; my $path = catfile $current_dir, $elem; my $open_path = catfile $open_dir, $elem; given($open_path){ when( -d ){ push @dirs, $path; } when( -f ){ push @files, $path, unless $found-&gt;{$path}; } default{ die qq'not a file or a directory: "$path"'; } } } } for my $path ( @dirs ){ push @files, find_missing %$found, $path; } return @files; } </code></pre> <p>After renaming <code>config</code> to <code>config.rm</code>, adding an extra char to <code>README</code>, changing a char in <code>install.sh</code>, and adding a file <code>.test</code>. This is what it outputted:</p> <pre> missing file: "update-dnsomatic-0.1.2/config" different size: "update-dnsomatic-0.1.2/README" different checksums: "update-dnsomatic-0.1.2/install.sh" file not in archive: "update-dnsomatic-0.1.2/config.rm" file not in archive: "update-dnsomatic-0.1.2/.test" </pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload