| #!/usr/bin/perl |
| |
| use strict; |
| use warnings; |
| use File::Find; |
| use File::Spec; |
| use Cwd; |
| |
| sub usage() |
| { |
| my $name = (File::Spec->splitpath($0))[2]; |
| print <<EOT |
| Usage: |
| |
| $name destination |
| EOT |
| ; |
| exit 0; |
| } |
| |
| sub get_first_subdir($$) |
| { |
| my @path = File::Spec->splitdir(File::Spec->rel2abs(shift)); |
| my @base = File::Spec->splitdir(File::Spec->rel2abs(shift)); |
| |
| while (@path and @base and $path[0] eq $base[0]) |
| { |
| shift @path; |
| shift @base; |
| } |
| |
| @base ? '' : $path[0]; |
| } |
| |
| my $dst = shift; |
| |
| if (not defined $dst or $dst eq '') |
| { |
| usage(); |
| } |
| |
| my $src = File::Spec->rel2abs(cwd()); |
| |
| $dst = File::Spec->rel2abs($dst); |
| |
| if (! -d $dst) |
| { |
| my $path = ''; |
| foreach my $d (File::Spec->splitdir($dst)) |
| { |
| $path = File::Spec->catdir($path, $d); |
| if (! -d $path) |
| { |
| mkdir $path or die "Can't create directory $path: $!"; |
| } |
| } |
| } |
| |
| my $subdir = File::Spec->rel2abs(get_first_subdir($dst, $src), $src); |
| my @path = File::Spec->splitdir($dst); |
| my $curdir = File::Spec->catdir(@path); |
| |
| find { |
| wanted => sub { |
| if ($File::Find::name eq $subdir or /^(CVS(?:\.adm)?|RCS|SCCS)$/) |
| { |
| $File::Find::prune = 1; |
| return; |
| } |
| elsif ($_ eq File::Spec->curdir) |
| { |
| return; |
| } |
| elsif (-d) |
| { |
| push @path, $_; |
| $curdir = File::Spec->catdir(@path); |
| mkdir $curdir unless -d $curdir; |
| } |
| else |
| { |
| my $basename = (File::Spec->splitpath($File::Find::name))[2]; |
| my $filename = File::Spec->catfile($curdir, $basename); |
| unlink $filename; |
| symlink File::Spec->abs2rel($File::Find::name, $curdir), $filename; |
| } |
| }, |
| postprocess => sub { |
| pop @path; |
| } |
| }, $src; |