summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSadeep Madurange <sadeep@asciimx.com>2026-03-27 16:50:53 +0800
committerSadeep Madurange <sadeep@asciimx.com>2026-03-27 16:50:53 +0800
commit3b9af22464af7f29110a5e0ff86c7b1f43fa6dad (patch)
tree517ec69040bf48b9fda2866043104baccb916c0b
parentb322fe254bffa08481427230403c4d9b3a58623a (diff)
downloadcvn-3b9af22464af7f29110a5e0ff86c7b1f43fa6dad.tar.gz
Accept multiple paths in add.
-rw-r--r--vcx106
1 files changed, 61 insertions, 45 deletions
diff --git a/vcx b/vcx
index 1fcbd09..3d7f6f4 100644
--- a/vcx
+++ b/vcx
@@ -16,16 +16,16 @@ 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] // '';
+my $cmd = shift @ARGV // '';
+my @paths = @ARGV;
if ($cmd eq 'init') {
init_repo();
} elsif ($cmd eq 'status') {
run_status();
} elsif ($cmd eq 'add') {
- die "Usage: $0 add [path]\n" unless $path;
- run_add($path);
+ die "Usage: $0 add [path1] [path2] ...\n" unless @paths;
+ run_add(@paths);
} else {
print "Usage: $0 [init|status|add]\n";
exit 1;
@@ -91,53 +91,54 @@ sub check_staged_status {
}
sub run_add {
- my ($target) = @_;
- my @targets = ($target eq '.') ? ('.') : bsd_glob($target);
-
- foreach my $t (@targets) {
- find({
- wanted => sub {
- return if $File::Find::name =~ /^\.\/\Q${\VCX_DIR}\E/;
- my $rel = File::Spec->abs2rel($File::Find::name, '.');
- $rel =~ s|^\./||;
-
- my $tmp_link = File::Spec->catfile(TMP_DIR, $rel);
- my $base_link = File::Spec->catfile(BSE_DIR, $rel);
-
- if (-f $File::Find::name && !-l $File::Find::name) {
- my $obj_path = File::Spec->catfile(OBJ_DIR, $rel . ".tmp");
- _sync_file_to_obj($File::Find::name, $obj_path, $tmp_link);
- }
- elsif (-l $File::Find::name) {
- _sync_symlink_to_tmp($File::Find::name, $tmp_link);
- }
- },
- no_chdir => 1,
- }, $t) if -e $t;
-
- _handle_deletions($t);
+ my (@targets) = @_;
+
+ foreach my $target (@targets) {
+ # Expand globs (e.g., *.txt) for each target
+ my @expanded = ($target eq '.') ? ('.') : bsd_glob($target);
+
+ foreach my $t (@expanded) {
+ next unless -e $t; # Skip if file doesn't exist
+ find({
+ wanted => sub {
+ return if $File::Find::name =~ /^\.\/\Q${\VCX_DIR}\E/;
+ my $rel = File::Spec->abs2rel($File::Find::name, '.');
+ $rel =~ s|^\./||;
+
+ my $tmp_link = File::Spec->catfile(TMP_DIR, $rel);
+
+ if (-f $File::Find::name && !-l $File::Find::name) {
+ _sync_file_to_obj($File::Find::name, undef, $tmp_link);
+ }
+ elsif (-l $File::Find::name) {
+ _sync_symlink_to_tmp($File::Find::name, $tmp_link);
+ }
+ },
+ no_chdir => 1,
+ }, $t);
+
+ _handle_deletions($t);
+ }
}
}
# For Regular Files: Copy to OBJ and link to TMP
sub _sync_file_to_obj {
- my ($src, $obj_path_not_used, $tmp) = @_;
-
- my $rel_path = File::Spec->abs2rel($src, '.');
- $rel_path =~ s|^\./||;
+ my ($src, $obj_path_not_used, $tmp) = @_;
+
+ my $rel_path = File::Spec->abs2rel($src, '.');
+ $rel_path =~ s|^\./||;
- my $filename = sha1_hex($rel_path);
- my $obj = File::Spec->catfile(OBJ_DIR, $filename);
+ my $filename = sha1_hex($rel_path) . ".tmp";
+ my $obj = File::Spec->catfile(OBJ_DIR, $filename);
- make_path(dirname($tmp));
- copy($src, $obj) or die "Copy failed: $!";
+ make_path(dirname($tmp));
+ copy($src, $obj) or die "Copy failed: $!";
my $target = File::Spec->abs2rel($obj, dirname($tmp));
-
- unlink($tmp) if -e $tmp || -l $tmp;
- symlink($target, $tmp) or die "Symlink failed: $!";
-
- print "[Add File] $src (stored as $filename)\n";
+
+ unlink($tmp) if -e $tmp || -l $tmp;
+ symlink($target, $tmp) or die "Symlink failed: $!";
}
# For Symlinks: Mirror the symlink into TMP
@@ -153,9 +154,24 @@ sub _sync_symlink_to_tmp {
sub _handle_deletions {
my ($target) = @_;
+
+ # If target is '.', search the whole BSE_DIR. Otherwise, search the specific path in BSE_DIR.
my $search = ($target eq '.') ? BSE_DIR : File::Spec->catfile(BSE_DIR, $target);
+
return unless -d $search || -e $search;
- find({ wanted => sub { return if -d $_; my $rel = File::Spec->abs2rel($_, BSE_DIR);
- if (!-e $rel) { unlink(File::Spec->catfile(OBJ_DIR, $rel), $_); print "[Deleted] $rel\n"; }
- }, no_chdir => 1 }, $search);
+
+ find({
+ wanted => sub {
+ return if -d $_; # Skip directories
+
+ my $rel = File::Spec->abs2rel($_, BSE_DIR);
+ if (!-e $rel) {
+ my $tmp_link = File::Spec->catfile(TMP_DIR, $rel);
+ if (-l $tmp_link || -e $tmp_link) {
+ unlink($tmp_link);
+ }
+ }
+ },
+ no_chdir => 1
+ }, $search);
}