-
Notifications
You must be signed in to change notification settings - Fork 0
/
install.pm
74 lines (65 loc) · 2.37 KB
/
install.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# -*- mode: cperl; -*-
use strict;
use warnings;
use File::Basename qw/dirname/;
use File::Listing qw/parse_dir/;
use File::Copy qw/move/;
sub dolink {
my ($reference_file, $target_file, $backup_file) = @_;
if (-e $target_file) {
print "Move aside $target_file -> $backup_file\n";
die "Backup file $backup_file exists" if (-e $backup_file);
die unless move($target_file, $backup_file);
}
print "Link $reference_file -> $target_file\n";
die "Target file $target_file exists" if (-e $target_file);
die if system "ln -s $reference_file $target_file";
}
sub rmlink {
my ($reference_file, $target_file, $backup_file) = @_;
if (-l $target_file) {
print "Remove symlink $target_file\n";
system "rm $target_file";
}
}
# Given two linked directories, a reference and a target, put the
# reference into the target. Simple files will be symlinked, directories
# will be copied, directories that begin with an underscore will have the
# rest of their name prepended to their immediate children.
# Recurse into subdirs.
#
# mkdir_or_link(<file action>, <prefix>, <reference dir>, <target dir>, <backup dir>)
sub mkdir_or_link {
my ($action, $prefix, $reference, $target, $backup) = @_;
foreach my $dir (parse_dir(`ls -l $reference`)) {
my ($name, $type, $size, $mtime, $mode) = @$dir;
my $reference_file = "$reference/$name";
my $target_file = "$target/${prefix}${name}";
my $backup_file = "$backup/${prefix}${name}";
if ($type eq "f") { # simple file
$action->($reference_file, $target_file, $backup_file);
} elsif ($type eq "d") {
if (substr($name, 0, 1) eq "_") {
mkdir_or_link($action, substr($name, 1), $reference_file, $target, $backup);
} else {
die if system "mkdir -p $target_file";
mkdir_or_link($action, "", $reference_file, $target_file, $backup_file);
}
}
}
}
my $HOME = $ENV{HOME} or die "Can't figure out your HOME";
my $oldfiles = "$HOME/old-settings";
my $settingsdir = "$ENV{PWD}/".dirname($0);
my $command = shift or die "Usage: $0 <install|unlink>\n";
if ($command eq 'install') {
if (-e $oldfiles) {
die "Directory of old settings already exists: $oldfiles";
}
die unless mkdir $oldfiles;
mkdir_or_link(\&dolink, "", $settingsdir, $HOME, $oldfiles);
} elsif ($command eq 'unlink') {
mkdir_or_link(\&rmlink, "", $settingsdir, $HOME, $oldfiles);
} else {
die "Usage $0 <install|unlink>\n";
}