commit 9c5afc6b5d09f269a33c30bb8567157e1967533a
parent e9a4386e8fe18457c0d154d655ff6159ecae1ab9
Author: lumidify <nobody@lumidify.org>
Date:   Mon, 23 Mar 2020 13:13:38 +0100
Fix extract; add checkold and rmold
Diffstat:
14 files changed, 71 insertions(+), 49 deletions(-)
diff --git a/lumia.pl b/lumia.pl
@@ -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);
@@ -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;
 	}, @_;
@@ -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;
@@ -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";
 			}
 		}
@@ -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));
+			}
 		}
 	}
 }
@@ -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) {
diff --git a/test/.lumidify_archive_cksums b/test/.lumidify_archive_cksums
@@ -1,3 +1,2 @@
-4294967295 0 "bob"
 4294967295 0 "fred2"
-4294967295 0 "fred"
+4294967295 0 "bob1"
diff --git a/test/.lumidify_archive_cksums.cksum b/test/.lumidify_archive_cksums.cksum
@@ -1,2 +1,2 @@
-2175384240 27 ".lumidify_archive_dirs"
-2227479197 60 ".lumidify_archive_cksums"
+2507213385 41 ".lumidify_archive_cksums"
+1201997706 27 ".lumidify_archive_dirs"
diff --git a/test/.lumidify_archive_dirs b/test/.lumidify_archive_dirs
@@ -1,4 +1,4 @@
-"dir3"
-"dir2"
-"dir1"
 "dir"
+"dir2"
+"dir3"
+"dir4"
diff --git a/test/bob b/test/bob1
diff --git a/test/dir1/.lumidify_archive_cksums b/test/dir4/.lumidify_archive_cksums
diff --git a/test/dir1/.lumidify_archive_cksums.cksum b/test/dir4/.lumidify_archive_cksums.cksum
diff --git a/test/dir1/.lumidify_archive_dirs b/test/dir4/.lumidify_archive_dirs
diff --git a/test/dir1/bob b/test/dir4/bob
diff --git a/test/dir1/dir/.lumidify_archive_cksums b/test/dir4/dir/.lumidify_archive_cksums
diff --git a/test/dir1/dir/.lumidify_archive_cksums.cksum b/test/dir4/dir/.lumidify_archive_cksums.cksum
diff --git a/test/dir1/dir/.lumidify_archive_dirs b/test/dir4/dir/.lumidify_archive_dirs
diff --git a/test/dir1/dir/bob b/test/dir4/dir/bob
diff --git a/test/fred b/test/fred