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 )