URI: 
       tAdd update command - 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 aa3fbdeec22eabf826a6bf730f61d8df3d6f383e
   DIR parent 041b675684a7f17f2fb7ae14af0be4d53ee3aba9
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Mon, 23 Mar 2020 17:14:23 +0100
       
       Add update command
       
       Diffstat:
         M lumia.pl                            |      60 ++++++++++++++++++++++++-------
         M test/.lumidify_archive_cksums       |       4 ++--
         M test/.lumidify_archive_cksums.cksum |       2 +-
         M test/bob3                           |       2 +-
         M test/dir2/.lumidify_archive_cksums  |       1 +
         M test/dir2/.lumidify_archive_cksums… |       2 +-
         C test/bob3 -> test/dir2/meh          |       0 
         M test/fred2                          |       1 +
       
       8 files changed, 54 insertions(+), 18 deletions(-)
       ---
   DIR diff --git a/lumia.pl b/lumia.pl
       t@@ -235,8 +235,8 @@ sub check_files {
                my $iter = make_lumia_iter @_;
                while (my $file = $iter->()) {
                        if (-d $file) {
       -                        check_cksums $file, "$DOUBLE_CKSUM_FILE";
       -                        check_cksums $file, "$CKSUM_FILE";
       +                        check_cksums $file, $DOUBLE_CKSUM_FILE;
       +                        check_cksums $file, $CKSUM_FILE;
                        } else {
                                my $dir = dirname $file;
                                my $base = basename $file;
       t@@ -262,7 +262,7 @@ sub check_files {
        }
        
        # write the checksums of the special lumia files given as arguments
       -# to "$DOUBLE_CKSUM_FILE" in $dir
       +# to $DOUBLE_CKSUM_FILE in $dir
        sub write_special_cksums {
                my ($dir, @files) = @_;
                my $cksum_file = "$dir/$DOUBLE_CKSUM_FILE";
       t@@ -283,7 +283,7 @@ sub write_special_cksums {
        # - if $file_func is set, it is called for each new file
        # - if $before_dir_func is set, it is called before processing the
        #   files in each directory that has new files OR if a directory
       -#   is entirely new (well, it only checks if "$DOUBLE_CKSUM_FILE" exists)
       +#   is entirely new (well, it only checks if $DOUBLE_CKSUM_FILE exists)
        # - if $after_dir_func is set, it is called after processing the
        #   files in each directory that has new files
        sub check_new_files {
       t@@ -370,7 +370,7 @@ sub check_add_new_files {
                        print "Added \"$fullpath\"\n";
                }, sub {
                        if (-f "$_[0]/$DOUBLE_CKSUM_FILE") {
       -                        if (!check_cksums $_[0], "$DOUBLE_CKSUM_FILE", 1) {
       +                        if (!check_cksums $_[0], $DOUBLE_CKSUM_FILE, 1) {
                                        warn "Checksum files corrupt in \"$_[0]\", not adding new checksums!\n";
                                        return 0;
                                }
       t@@ -380,11 +380,11 @@ sub check_add_new_files {
                        return 1;
                }, sub {
                        if ($changed_dirs) {
       -                        write_special_cksums $_[0], "$DIR_FILE";
       +                        write_special_cksums $_[0], $DIR_FILE;
                                $changed_dirs = 0;
                        }
                        if ($changed_files) {
       -                        write_special_cksums $_[0], "$CKSUM_FILE";
       +                        write_special_cksums $_[0], $CKSUM_FILE;
                                $changed_files = 0;
                        }
                };
       t@@ -425,12 +425,12 @@ sub write_cksums {
                if ($files_modified) {
                        my %file_cksums = map {$_ => $contents->{$_}} grep({defined $contents->{$_}} keys %$contents);
                        write_cksum_file("$dir/$CKSUM_FILE", \%file_cksums);
       -                write_special_cksums $dir, "$CKSUM_FILE";
       +                write_special_cksums $dir, $CKSUM_FILE;
                }
                if ($dirs_modified) {
                        my %dir_cksums = map {$_ => undef} grep({!defined $contents->{$_}} keys %$contents);
                        write_file "$dir/$DIR_FILE", \%dir_cksums;
       -                write_special_cksums $dir, "$DIR_FILE";
       +                write_special_cksums $dir, $DIR_FILE;
                }
        }
        
       t@@ -465,7 +465,7 @@ sub remove_old_files {
                                        delete $lumia_dirs->{$child};
                                        write_file "$parent/$DIR_FILE", $lumia_dirs;
                                        print "Removed \"$dir\" from \"$parent/$DIR_FILE\"\n";
       -                                write_special_cksums $parent, "$DIR_FILE";
       +                                write_special_cksums $parent, $DIR_FILE;
                                }
                        } else {
                                my $cksums = read_cksum_file("$dir/$CKSUM_FILE", {}) // {};
       t@@ -479,7 +479,7 @@ sub remove_old_files {
                                }
                                if ($found) {
                                        write_cksum_file "$dir/$CKSUM_FILE", $cksums;
       -                                write_special_cksums $dir, "$CKSUM_FILE";
       +                                write_special_cksums $dir, $CKSUM_FILE;
                                }
                        }
                }
       t@@ -793,7 +793,7 @@ sub make_dirs {
                                $parent_dirs->{$dir} = "";
                        }
                        write_file "$parent/$DIR_FILE", $parent_dirs;
       -                write_special_cksums $parent, "$DIR_FILE";
       +                write_special_cksums $parent, $DIR_FILE;
                }
        }
        
       t@@ -815,8 +815,37 @@ sub extract {
                }
        }
        
       +# update the checksums of the given files
       +# ignores any directories given as arguments
       +sub update {
       +        my @files;
       +        foreach (@_) {
       +                if (-d $_) {
       +                        warn "Ignoring directory \"$_\"\n";
       +                } else {
       +                        push @files, $_;
       +                }
       +        }
       +        my $sorted_files = sort_by_dir @files;
       +        foreach my $dir (keys %$sorted_files) {
       +                my $cksums = read_cksum_file "$dir/$CKSUM_FILE", {};
       +                next if !defined $cksums;
       +                my $changed = 0;
       +                foreach my $file (@{$sorted_files->{$dir}}) {
       +                        my $cksum_output = get_cksum "$dir/$file";
       +                        next if !defined $cksum_output;
       +                        $cksums->{$file} = $cksum_output;
       +                        $changed = 1;
       +                }
       +                if ($changed) {
       +                        write_cksum_file "$dir/$CKSUM_FILE", $cksums;
       +                        write_special_cksums $dir, $CKSUM_FILE;
       +                }
       +        }
       +}
       +
        if ($#ARGV < 0) {
       -        die("USAGE: test.pl {init|check|clean|checknew|addnew|checkold|rmold|extract|cp|mv|rm|mkdir}\n");
       +        die("USAGE: test.pl {init|check|clean|checknew|addnew|checkold|rmold|extract|cp|mv|rm|mkdir|update}\n");
        }
        if ($ARGV[0] eq "mv") {
                if ($#ARGV < 2) {
       t@@ -895,4 +924,9 @@ if ($ARGV[0] eq "mv") {
                }
                my @dirs = @ARGV[1..$#ARGV];
                make_dirs(@dirs);
       +} elsif ($ARGV[0] eq "update") {
       +        if ($#ARGV < 1) {
       +                die "update requires at least one argument\n";
       +        }
       +        update @ARGV[1..$#ARGV];
        }
   DIR diff --git a/test/.lumidify_archive_cksums b/test/.lumidify_archive_cksums
       t@@ -1,4 +1,4 @@
       +2454254050 2 "fred2"
        2418082923 2 "bob1"
       -2418082923 2 "bob3"
       +2454254050 2 "bob3"
        4294967295 0 "bob2"
       -4294967295 0 "fred2"
   DIR diff --git a/test/.lumidify_archive_cksums.cksum b/test/.lumidify_archive_cksums.cksum
       t@@ -1,2 +1,2 @@
       +650526090 81 ".lumidify_archive_cksums"
        3971863640 21 ".lumidify_archive_dirs"
       -1556400735 81 ".lumidify_archive_cksums"
   DIR diff --git a/test/bob3 b/test/bob3
       t@@ -1 +1 @@
       -a
       +b
   DIR diff --git a/test/dir2/.lumidify_archive_cksums b/test/dir2/.lumidify_archive_cksums
       t@@ -0,0 +1 @@
       +2418082923 2 "meh"
   DIR diff --git a/test/dir2/.lumidify_archive_cksums.cksum b/test/dir2/.lumidify_archive_cksums.cksum
       t@@ -1,2 +1,2 @@
       -4294967295 0 ".lumidify_archive_cksums"
        137730780 6 ".lumidify_archive_dirs"
       +3978068116 19 ".lumidify_archive_cksums"
   DIR diff --git a/test/bob3 b/test/dir2/meh
   DIR diff --git a/test/fred2 b/test/fred2
       t@@ -0,0 +1 @@
       +b