App-SnerpVortex
view release on metacpan or search on metacpan
bin/snerp-projector view on Meta::CPAN
#!/usr/bin/env perl
use warnings;
use strict;
use lib qw(./lib);
use YAML;
use SVN::Analysis;
use Git::Repository;
use Getopt::Long;
my $last_log_time = $^T;
my ($map_file_name, $db_file_name, $git_base, $new_base, $help_me, $verbose);
my $getopt_okay = GetOptions(
'map=s', \$map_file_name,
'db=s', \$db_file_name,
'from=s', \$git_base,
'into=s', \$new_base,
'help', \$help_me,
'verbose', \$verbose,
);
if ($help_me or !$getopt_okay) {
die(
"$0 usage:\n",
" --map=FILENAME location of project map file\n",
" --db=FILENAME location of snanalyze sqlite3 database\n",
" --from=GIT_BASE_DIR location of monolithic git checkout\n",
" --into=NEW_PARENT_DIR directory to be created for projects\n",
" --verbose explain what's going on\n",
" --help you're soaking in it.\n",
);
}
die "$0: Destination directory $new_base shouldn't pre-exist.\n" if (
-e $new_base
);
die "$0: Source git directory $git_base must pre-exist.\n" unless (
-e $git_base
);
my $analysis = SVN::Analysis->new(
db_file_name => $db_file_name,
verbose => $verbose,
);
# Acquire the projects.
my $projects = YAML::LoadFile($map_file_name);
unless (scalar keys %$projects) {
print "No projects in $map_file_name. I guess we're done.\n";
}
# Set up the target projects.
mkdir $new_base or die "mkdir $new_base failed: $!";
my @project_names = sort keys %$projects;
foreach (@project_names) {
my $clone_path = "$new_base/$_";
chdir $git_base or die $!;
mkdir $clone_path or die $!;
_log("Cloning $git_base into $clone_path.");
my $project = $projects->{$_};
system("pax", "-rw", "-pe", "-X", ".", $clone_path) and die $!;
$project->{git} = Git::Repository->new(work_tree => $clone_path) or die $!;
# http://lists.zerezo.com/git/msg654051.html
# "in some cases git-filter-branch refuses to run unless git-status
# is invoked first". This seems to be one of those times.
$project->{git}->run("status");
$project->{git_base_dir} = $clone_path;
}
# Find the last outside contributions to each project.
# O(N^2) unfortunately.
my %copy_into;
foreach my $src_name (@project_names) {
foreach my $dst_name (@project_names) {
next if $src_name eq $dst_name;
my $copy = $analysis->get_last_copy_into_tree(
$projects->{$src_name}{svndir},
$projects->{$dst_name}{svndir},
);
# There was no copy
next unless $copy;
$copy_into{$dst_name}{$src_name} = $copy;
# Tag the source so we can filter-branch by tag.
# Tags are revised during filter-branch, but revs just break.
$projects->{$dst_name}{git}->run(
'tag', 'svn-r-' . $copy->src_rev(),
$analysis->get_other_rev_from_svn($copy->src_rev())
);
}
}
# Repositories that don't exist in %copy_into are stand-alone.
( run in 1.367 second using v1.01-cache-2.11-cpan-39bf76dae61 )