forked from norm/homedir
/
patch_app
executable file
·125 lines (94 loc) · 2.85 KB
/
patch_app
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/ports/bin/perl
# -*- Mode: Perl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
use strict;
use warnings;
use File::Basename;
use FileHandle;
use Pod::Usage;
use Readonly;
Readonly my $REPOSITORY => "$ENV{'HOME'}/source/patches";
Readonly my $DELETE_FILE => 'delete.list';
Readonly my $RSYNC => "rsync -avPH --exclude ${DELETE_FILE} ";
Readonly my $APP_BASE => '/Applications';
pod2usage() unless my $application = shift;
# if the path isn't absolute, try and find a match
if ( q(/) ne substr( $application, 0, 1 ) ) {
my @matches = get_matching_applications( $application );
my $count = scalar @matches;
if ($count < 1) {
print "No application matches ${application}.\n";
exit 1;
}
elsif ($count > 1) {
print "More than one application matches '${application}':\n";
foreach my $app (@matches) {
print " * $app\n";
}
exit 1;
}
$application = shift @matches;
}
# add new files
my $app_directory = basename( $application );
chdir "${REPOSITORY}/${app_directory}"
or die "${REPOSITORY}/${app_directory}: $!";
my $command = "${RSYNC} . '${application}/.' |";
my $handle = new FileHandle $command
or die "Cannot rsync: $!";
while ( my $line = <$handle> ) {
print $line;
}
undef $handle;
# remove files
$handle = new FileHandle ${DELETE_FILE};
if ( defined $handle ) {
my $exclusions;
while ( my $line = <$handle> ) {
chomp $line;
$exclusions .= " --exclude '${line}'";
}
# application dir repeated twice to form a no-op sync,
# which facilitates deleting without any side-effects
my $command = "${RSYNC} --delete-excluded ${exclusions}"
. " '${application}/.' '${application}/.' |";
my $handle = new FileHandle $command
or die "Cannot rsync: $!";
while (my $line = <$handle>) {
print $line;
}
}
# done
exit;
sub get_matching_applications {
my $match = shift;
my @list;
push @list,
get_applications_for_directory( "${APP_BASE}" ),
get_applications_for_directory( "${APP_BASE}/Utilities" );
get_applications_for_directory( "$ENV{'HOME'}${APP_BASE}/Utilities" );
@list = grep m{$match}i, @list;
return @list;
}
sub get_applications_for_directory {
my $directory = shift;
my @list;
my $handle;
opendir $handle, $directory;
if ( defined $handle ) {
while ( my $file = readdir $handle ) {
if ( $file =~ m{ .app $}x ) {
push @list, "${directory}/${file}"
}
}
return @list;
}
return;
}
__END__
=head1 NAME
B<patch_app> - add/delete files from application packages
=head1 SYNOPSIS
B<patch_app> I<application>
=head1 DESCRIPTION
=head1 AUTHOR
Mark Norman Francis L<http://marknormanfrancis.com/>