bin/run-mirrors: Run post scripts after mirror jobs.
[mirror-admin] / bin / dircombine
CommitLineData
db2c5b8b
MW
1#!/usr/bin/perl
2# Uses symlinks to merge the files contained in a set of vcs
3# checkouts to into a single directory. Keeps track of when files are
4# removed from the merged directories and removes the symlinks.
5#
6# Only merges files that match the specified pattern.
7#
8# Note that the directories given to merge should be paths that will work
9# for symlink targets from the destination directory (so either full paths,
10# or they should be right inside the destination directory).
11#
12# Note that other files in the destination directory will be left as-is.
13#
14# Copyright 2006 by Joey Hess, licensed under the GPL.
15
16if (! @ARGV) {
17 die "usage: dircombine include-pattern dest dir1 [dir2 ...]\n";
18}
19
20my $pattern=shift;
21my $dest=shift;
22
23foreach my $dir (@ARGV) {
24 my %known;
25
26 # Link in each thing from the dir.
27 opendir(DIR, $dir) || die "opendir: $!";
28 while ($_=readdir(DIR)) {
29 next if $_ eq '.' || $_ eq '..' || $_ eq 'known' || $_ eq '.svn' || $_ eq '.git' || $_ eq '.gitignore' || $_ eq '_darcs';
30 next unless /$pattern/;
31
32 $known{$_}=1;
33
34 if (! -l "$dest/$_" && -e "$dest/$_") {
35 print STDERR "$_ in $dir is also in $dest\n";
36 }
37 elsif (! -l "$dest/$_") {
38 system("ln", "-svf", "$dir/$_", $dest);
39 }
40 }
41 closedir(DIR);
42
43 # Remove anything that was previously linked in but is not in the
44 # dir anymore.
45 if (-e "$dir/known") {
46 open(KNOWN, "$dir/known") || die "open $dir/known: $!";
47 while (<KNOWN>) {
48 chomp;
49 if (! $known{$_}) {
50 system("rm", "-vf", "$dest/$_");
51 }
52 }
53 close KNOWN;
54 }
55
56 # Save state for next time.
57 open(KNOWN, ">$dir/known") || die "write $dir/known: $!";
58 foreach my $file (sort keys %known) {
59 print KNOWN "$file\n";
60 }
61 close KNOWN;
62}