diff options
| author | Sadeep Madurange <sadeep@asciimx.com> | 2026-03-13 23:48:27 +0800 |
|---|---|---|
| committer | Sadeep Madurange <sadeep@asciimx.com> | 2026-03-13 23:48:27 +0800 |
| commit | f0c0e52b896c549007425f42e5fa7d81fa034041 (patch) | |
| tree | dabe7c83e289884c4a1d0a980a5733a06bbf8ae6 | |
| parent | 28676469ba7bb4bb9e6fcf316f48bf7fb3b0a080 (diff) | |
| download | cvn-f0c0e52b896c549007425f42e5fa7d81fa034041.tar.gz | |
Update status to show staged files.
| -rw-r--r-- | vcx | 87 |
1 files changed, 65 insertions, 22 deletions
@@ -13,6 +13,7 @@ use constant VCX_DIR => '.vcx'; use constant BSE_DIR => VCX_DIR . '/bse'; use constant OBJ_DIR => VCX_DIR . '/obj'; use constant TMP_DIR => VCX_DIR . '/tmp'; +use constant IGNORE_FILE => '.vcxignore'; my $cmd = $ARGV[0] // ''; my $path = $ARGV[1] // ''; @@ -35,30 +36,59 @@ sub init_repo { } sub run_status { - my $diff_cmd = "diff -x " . VCX_DIR . " -rq " . BSE_DIR . " ."; - $diff_cmd .= " -X .vcxignore" if -e ".vcxignore"; + # We define a helper to handle the logic for each file encountered + my $compare_file = sub { + return if $File::Find::name =~ /^\.\/\Q${\VCX_DIR}\E/; # Skip .vcx + return if -d $File::Find::name; # Directories aren't files + + my $path = File::Spec->abs2rel($File::Find::name, '.'); + my $base_path = BSE_DIR . "/$path"; + my $tmp_path = TMP_DIR . "/$path"; + + if (-e $base_path) { + # File exists in both (or was deleted). + # We check diff to see if it's modified. + if (system("diff -q '$File::Find::name' '$base_path' > /dev/null") != 0) { + my $staged = check_staged_status($path, 'M'); + print "[M] $path" . ($staged ? " (staged)" : "") . "\n"; + } + } else { + # New File + my $staged = check_staged_status($path, 'N'); + print "[N] $path" . ($staged ? " (staged)" : "") . "\n"; + } + }; + + # Walk the working directory + find({ wanted => $compare_file, no_chdir => 1 }, '.'); + + # Now, find files in BSE_DIR that no longer exist in . (Deletions) + find({ + wanted => sub { + return if -d $_; + my $rel = File::Spec->abs2rel($_, BSE_DIR); + if (!-e $rel) { + my $staged = check_staged_status($rel, 'D'); + print "[D] $rel" . ($staged ? " (staged)" : "") . "\n"; + } + }, + no_chdir => 1 + }, BSE_DIR); +} - my @output = `$diff_cmd`; +sub check_staged_status { + my ($path, $type) = @_; + my $tmp = TMP_DIR . "/$path"; - foreach my $line (@output) { - chomp $line; - # Format output - if ($line =~ /^Only in \Q@{[BSE_DIR]}\E: (.+)$/) { - print "[D] $1\n"; - } elsif ($line =~ /^Only in \.: (.+)$/) { - print "[N] $1\n"; - } elsif ($line =~ /^Files \Q@{[BSE_DIR]}\E\/(.+) and \.\/(.+) differ$/) { - print "[M] $1\n"; - } - } + if ($type eq 'N' || $type eq 'M') { return -e $tmp; } + if ($type eq 'D') { return !-e $tmp; } + return 0; } sub run_add { my ($target) = @_; # Copy BSE_DIR to TMP_DIR - remove_tree(TMP_DIR); - make_path(TMP_DIR); if (glob(BSE_DIR . "/*")) { system("cp -R '" . BSE_DIR . "/.' '" . TMP_DIR . "/'"); } @@ -111,19 +141,32 @@ sub _sync_new_file { make_path(dirname($obj)); make_path(dirname($tmp)); copy($src, $obj); - # Symlink from tmp/path/to/file to obj/path/to/file - # Note: symlink target is relative to the symlink's location - symlink("../../obj/" . $src, $tmp); + + my $abs_obj = File::Spec->rel2abs($obj); + my $abs_tmp = File::Spec->rel2abs($tmp); + my $rel_target = File::Spec->abs2rel($abs_obj, dirname($abs_tmp)); + + unlink($tmp) if -e $tmp || -l $tmp; + symlink($rel_target, $tmp); print "[Add New] $src\n"; } sub _sync_modified_file { my ($src, $obj, $tmp) = @_; - my $tmp_obj = "$obj.tmp"; + my $tmp_obj = "$obj.tmp"; # The modified version in obj/ + make_path(dirname($tmp_obj)); copy($src, $tmp_obj); - unlink($tmp) if -l $tmp; - symlink("../../obj/" . $src . ".tmp", $tmp); + + unlink($tmp) if -e $tmp || -l $tmp; # Ensure clean slate + + # RELATIVE PATH FIX: + # Link: .vcx/tmp/path/to/file (at least 2+ levels deep) + # Target: .vcx/obj/path/to/file.tmp + # We need to get out of tmp/ and into obj/ + my $rel_target = "../obj/" . $src . ".tmp"; + + symlink($rel_target, $tmp); print "[Add Mod] $src\n"; } |
