URI: 
       tFix extract; add checkold and rmold - lumia - Archive checksum manager
  HTML git clone git://lumidify.org/git/lumia.git
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 9c5afc6b5d09f269a33c30bb8567157e1967533a
   DIR parent e9a4386e8fe18457c0d154d655ff6159ecae1ab9
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Mon, 23 Mar 2020 13:13:38 +0100
       
       Fix extract; add checkold and rmold
       
       Diffstat:
         M lumia.pl                            |     107 +++++++++++++++++++------------
         M test/.lumidify_archive_cksums       |       3 +--
         M test/.lumidify_archive_cksums.cksum |       4 ++--
         M test/.lumidify_archive_dirs         |       6 +++---
         R test/bob -> test/bob1               |       0 
         R test/dir1/.lumidify_archive_cksums… |       0 
         R test/dir1/.lumidify_archive_cksums… |       0 
         R test/dir1/.lumidify_archive_dirs -… |       0 
         R test/dir1/bob -> test/dir4/bob      |       0 
         R test/dir1/dir/.lumidify_archive_ck… |       0 
         R test/dir1/dir/.lumidify_archive_ck… |       0 
         R test/dir1/dir/.lumidify_archive_di… |       0 
         R test/dir1/dir/bob -> test/dir4/dir… |       0 
         D test/fred                           |       0 
       
       14 files changed, 71 insertions(+), 49 deletions(-)
       ---
   DIR diff --git a/lumia.pl b/lumia.pl
       t@@ -23,7 +23,7 @@
        
        use strict;
        use warnings;
       -use File::Spec::Functions qw(catfile catdir splitpath splitdir);
       +use File::Spec::Functions qw(catfile catdir splitpath splitdir abs2rel);
        use File::Basename qw(basename dirname);
        use File::Copy qw(move copy);
        use File::Path qw(remove_tree make_path);
       t@@ -85,9 +85,9 @@ sub make_lumia_iter {
                                my $dir_path = "$_[0]/$dir";
                                if (!-d $dir_path) {
                                        warn "ERROR: Directory \"$dir_path\" mentioned in \"$path\" does not exist or is not directory.\n";
       -                        } else {
       -                                push @new_dirs, $dir_path;
                                }
       +                        # still push it even when it doesn't exist so rmold can work properly
       +                        push @new_dirs, $dir_path;
                        }
                        return \@new_dirs;
                }, @_;
       t@@ -347,16 +347,6 @@ sub check_add_new_files {
                };
        }
        
       -sub check_old_files {
       -        my $dir = shift;
       -        my $iter = make_lumia_iter $dir;
       -        while (my $file = $iter->()) {
       -                if (!-e $file) {
       -                        warn "Nonexistent file or directory: \"$file\"!";
       -                }
       -        }
       -}
       -
        sub write_file {
                my ($path, $contents, $is_cksum_file) = @_;
                my $fh;
       t@@ -393,25 +383,48 @@ sub write_cksums {
                }
        }
        
       +sub check_old_files {
       +        my $top_dir = shift;
       +        my $iter = make_lumia_iter $top_dir;
       +        while (my $dir = $iter->()) {
       +                # if $dir doesn't exist, the iterator already issued a warning
       +                if (-e $dir) {
       +                        my $cksums = read_cksum_file("$dir/.lumidify_archive_cksums", {}) // {};
       +                        foreach my $file (keys %$cksums) {
       +                                if (!-e "$dir/$file") {
       +                                        warn "Nonexistent file: \"$dir/$file\"!\n";
       +                                }
       +                        }
       +                }
       +        }
       +}
       +
        sub remove_old_files {
       -        my $dir = shift;
       -        my $iter = make_lumia_iter $dir;
       -        while (my $file = $iter->()) {
       -                if (!-e $file) {
       -                        my $dir = dirname $file;
       -                        my $filename = basename $file;
       -                        my $lumia_dirs = read_file "$dir/.lumidify_archive_dirs", {};
       -                        if (defined $lumia_dirs && exists $lumia_dirs->{$filename}) {
       -                                delete $lumia_dirs->{$filename};
       -                                write_file $dir, $lumia_dirs;
       -                                print "Removed \"$file\" from \"$dir/.lumidify_archive_dirs\"\n";
       -                                write_special_cksums $dir, ".lumidify_archive_dirs";
       -                        } else {
       -                                my $lumia_files = read_cksum_file "$dir/.lumidify_archive_cksums", {};
       -                                next if !defined $lumia_files;
       -                                delete $lumia_files->{$filename};
       -                                write_cksum_file $dir, $lumia_files;
       -                                print "Removed \"$file\" from \"$dir/.lumidify_archive_cksums\"\n";
       +        my $top_dir = shift;
       +        my $iter = make_lumia_iter $top_dir;
       +        while (my $dir = $iter->()) {
       +                if (!-e $dir) {
       +                        my $parent = dirname $dir;
       +                        my $child = basename $dir;
       +                        my $lumia_dirs = read_file("$parent/.lumidify_archive_dirs", {}) // {};
       +                        if (exists $lumia_dirs->{$child}) {
       +                                delete $lumia_dirs->{$child};
       +                                write_file "$parent/.lumidify_archive_dirs", $lumia_dirs;
       +                                print "Removed \"$dir\" from \"$parent/.lumidify_archive_dirs\"\n";
       +                                write_special_cksums $parent, ".lumidify_archive_dirs";
       +                        }
       +                } else {
       +                        my $cksums = read_cksum_file("$dir/.lumidify_archive_cksums", {}) // {};
       +                        my $found = 0;
       +                        foreach my $file (keys %$cksums) {
       +                                if (!-e "$dir/$file") {
       +                                        delete $cksums->{$file};
       +                                        print "Removed \"$dir/$file\" from \"$dir/.lumidify_archive_cksums\"\n";
       +                                        $found = 1;
       +                                }
       +                        }
       +                        if ($found) {
       +                                write_cksum_file "$dir/.lumidify_archive_cksums", $cksums;
                                        write_special_cksums $dir, ".lumidify_archive_cksums";
                                }
                        }
       t@@ -694,22 +707,20 @@ sub make_dirs {
                }
        }
        
       +# extract all special lumia files from $src_dir to $dst_dir, recreating the
       +# entire directory structure in the process
        sub extract {
                my ($src_dir, $dst_dir) = @_;
       -        # clean trailing slashes so removing the prefix later works
       -        $src_dir =~ s/\/*$//;
       -        # after cleaning the slashes, $src_dir is at the beginning of all
       -        # dirs returned by the iterator, but we also need to remove the
       -        # slash that comes right after the prefix
       -        my $prefix_length = length $src_dir;
                my $iter = make_lumia_iter $src_dir;
                while (my $dir = $iter->()) {
       -                # just returns "" for the original dir itself
       -                my $final_dir = substr($dir, $prefix_length);
       +                my $final_dir = abs2rel $dir, $src_dir;
       +                my $fulldir = catfile $dst_dir, $final_dir;
       +                system("mkdir", "-p", $fulldir);
                        foreach my $file (keys %SPECIAL_FILES) {
       -                        my $fulldir = "$dst_dir/$final_dir";
       -                        system("mkdir", "-p", $fulldir);
       -                        system("cp", "-aiv", "$dir/$file", "$fulldir/$file");
       +                        my $filepath = catfile $dir, $file;
       +                        if (-e $filepath) {
       +                                system("cp", "-aiv", $filepath, catfile($fulldir, $file));
       +                        }
                        }
                }
        }
       t@@ -740,6 +751,18 @@ if ($ARGV[0] eq "mv") {
                        $dir = $ARGV[1];
                }
                check_new_files $dir;
       +} elsif ($ARGV[0] eq "checkold") {
       +        my $dir = ".";
       +        if ($#ARGV > 0) {
       +                $dir = $ARGV[1];
       +        }
       +        check_old_files $dir;
       +} elsif ($ARGV[0] eq "rmold") {
       +        my $dir = ".";
       +        if ($#ARGV > 0) {
       +                $dir = $ARGV[1];
       +        }
       +        remove_old_files $dir;
        } elsif ($ARGV[0] eq "check") {
                my $dir = ".";
                if ($#ARGV > 0) {
   DIR diff --git a/test/.lumidify_archive_cksums b/test/.lumidify_archive_cksums
       t@@ -1,3 +1,2 @@
       -4294967295 0 "bob"
        4294967295 0 "fred2"
       -4294967295 0 "fred"
       +4294967295 0 "bob1"
   DIR diff --git a/test/.lumidify_archive_cksums.cksum b/test/.lumidify_archive_cksums.cksum
       t@@ -1,2 +1,2 @@
       -2175384240 27 ".lumidify_archive_dirs"
       -2227479197 60 ".lumidify_archive_cksums"
       +2507213385 41 ".lumidify_archive_cksums"
       +1201997706 27 ".lumidify_archive_dirs"
   DIR diff --git a/test/.lumidify_archive_dirs b/test/.lumidify_archive_dirs
       t@@ -1,4 +1,4 @@
       -"dir3"
       -"dir2"
       -"dir1"
        "dir"
       +"dir2"
       +"dir3"
       +"dir4"
   DIR diff --git a/test/bob b/test/bob1
   DIR diff --git a/test/dir1/.lumidify_archive_cksums b/test/dir4/.lumidify_archive_cksums
   DIR diff --git a/test/dir1/.lumidify_archive_cksums.cksum b/test/dir4/.lumidify_archive_cksums.cksum
   DIR diff --git a/test/dir1/.lumidify_archive_dirs b/test/dir4/.lumidify_archive_dirs
   DIR diff --git a/test/dir1/bob b/test/dir4/bob
   DIR diff --git a/test/dir1/dir/.lumidify_archive_cksums b/test/dir4/dir/.lumidify_archive_cksums
   DIR diff --git a/test/dir1/dir/.lumidify_archive_cksums.cksum b/test/dir4/dir/.lumidify_archive_cksums.cksum
   DIR diff --git a/test/dir1/dir/.lumidify_archive_dirs b/test/dir4/dir/.lumidify_archive_dirs
   DIR diff --git a/test/dir1/dir/bob b/test/dir4/dir/bob
   DIR diff --git a/test/fred b/test/fred