new tool
[hband-tools.git] / user-tools / visymlinks
blob63cfa064167b68ab37aeacf942a327e19e20f34b
1 #!/usr/bin/env perl
3 =pod
5 =head1 NAME
7 visymlinks - Bulk edit target of symlinks
9 =head1 SYNOPSIS
11 visymlinks [<PATH> [<PATH> [...]]]
13 =head1 DESCRIPTION
15 Open up your default editor (see sensible-editor(1)) to edit the targets of I<PATH> symlinks
16 given in command arguments.
17 If no I<PATH> given, all symlinks will be edited in the current working directory.
18 Once finished in the editor, changes the target of those symlinks which were edited.
19 Contrary to visymlinks(1)'s relative, vidir(1),
20 if a I<PATH> symlink is removed in the editor, it won't be removed from the filesystem.
22 =head1 RETURN VALUE
24 Returns zero if everything went fine.
25 Returns the exit status of the editor if it was not zero (also skip changing symlinks).
26 Returns the error code of symlink(2) if any of such calls failed.
28 =head1 SEE ALSO
30 vidir(1) from moreutils, vifiles(1)
32 =cut
35 use File::Temp qw/tempfile/;
36 use Carp qw/croak/;
38 $0 =~ s/.*\/([^\/]+)$/$1/;
40 ($fh, $filename) = tempfile( "visymlinks-XXXXXX", TMPDIR => 1 );
42 push @ARGV, glob '*' unless @ARGV;
43 for my $path (@ARGV)
45 if(-l $path)
47 printf {$fh} ("%s\t%s\n", $path, readlink $path) or croak "$0: $filename: write: $!";
51 close $fh or croak "$0: $filename: close: $!";
53 system "sensible-editor", $filename;
54 $editor_err = $?;
56 if($editor_err == 0)
58 open my $fh, '<', $filename or "$0: $filename: open: $!";
59 while(<$fh>)
61 chomp;
62 my ($path, $new_target) = split /\t/;
63 if(-e $path and !-l $path)
65 warn "$0: $path: no longer a symlink!\n";
67 else
69 my $old_target = readlink $path;
70 if($old_target ne $new_target)
72 warn "$0: $path: old target: $old_target\n";
73 warn "$0: $path: new target: $new_target\n";
74 unlink $path;
75 symlink $new_target, $path or croak "$0: $path: symlink: $!";
81 exit $editor_err;