Skip to content

Instantly share code, notes, and snippets.

@neilb
Last active August 29, 2015 13:56
Show Gist options
  • Save neilb/8840715 to your computer and use it in GitHub Desktop.
Save neilb/8840715 to your computer and use it in GitHub Desktop.
Find CPAN distributions that look like they've been adopted at some point in their history
#!/usr/local/bin/perl
#
# Iterate over CPAN release history, looking for dists that appear to have been adopted one or more times.
# An adoption is guessed at if we saw one or more releases from PERSONA, then a gap of at least 180 days,
# then one or more releases from PERSONB and we never see PERSONA again.
#
use strict;
use warnings;
use CPAN::ReleaseHistory 0.02;
# look for gaps of 180 days or more between different authors;
my $GAP_SIZE = 180 * 24 * 60 * 60;
my $iterator = CPAN::ReleaseHistory->new()->release_iterator();
my ($distname, $author);
my ($previous_distname, $previous_author, $previous_time);
my %seen;
my %adopted_by;
my $creator;
my $adoption_count = 0;
RELEASE:
while (my $release = $iterator->next_release) {
next unless defined($release->distinfo);
next unless defined($distname = $release->distinfo->dist);
next unless defined($author = $release->distinfo->cpanid);
$creator //= $author;
if (defined($previous_distname) && $previous_distname ne $distname) {
if (keys(%adopted_by) > 0) {
++$adoption_count;
print "$previous_distname created by $creator, adopted by ",
join(', ', keys %adopted_by), "\n";
}
%seen = ();
%adopted_by = ();
$creator = undef;
$previous_author = $author;
$previous_distname = $distname;
$previous_time = $release->timestamp;
next RELEASE;
}
if (defined($previous_author) && $previous_distname eq $distname && $previous_author eq $author) {
$previous_time = $release->timestamp;
next RELEASE;
}
if (defined($previous_author) && $previous_author ne $author) {
if (not exists($seen{ $author })) {
$seen{ $previous_author } = 1;
$adopted_by{ $author } = 1 if $author ne $creator
&& $release->timestamp - $previous_time > $GAP_SIZE;
} elsif ($adopted_by{ $previous_author }) {
delete $adopted_by{ $previous_author };
$seen{ $previous_author } = 1;
}
}
$previous_author = $author;
$previous_time = $release->timestamp;
$previous_distname = $distname;
}
print "adoptions seen for $adoption_count dists\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment