Skip to content

Instantly share code, notes, and snippets.

@zmughal
Last active November 7, 2021 02:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save zmughal/6478600 to your computer and use it in GitHub Desktop.
Save zmughal/6478600 to your computer and use it in GitHub Desktop.
Retrieves MetaCPAN favourites and gets the associated GitHub repositories.
Checks if repository is starred and prompts to star the GitHub repository if
not already starred.
requires 'CHI';
requires 'MetaCPAN::Client';
requires 'Modern::Perl';
requires 'Try::Tiny';
requires 'Term::ProgressBar';
requires 'List::Util' => 1.45;
requires 'File::Which';
requires 'Term::Clui';
requires 'Capture::Tiny';
requires 'utf8::all';
requires 'Pod::Usage';
#!/usr/bin/env perl
# PODNAME: metacpan-favourite-to-github
# ABSTRACT: Star GitHub repos in MetaCPAN favourites list
use utf8;
use strict;
use warnings;
use utf8::all;
use Modern::Perl;
use MetaCPAN::Client;
use Try::Tiny;
use CHI;
use FindBin;
use File::Spec;
use List::Util 1.45 qw(uniqstr);
use Term::ProgressBar;
use Term::Clui;
use File::Which;
use Capture::Tiny qw(capture);
use Pod::Usage;
die "Need to have gh CLI <https://cli.github.com/>" unless which('gh');
my $user_arg = $ARGV[0];
pod2usage(
-msg => "Missing user ID",
-exitval => 1 ) unless $user_arg;
my $cache = CHI->new( driver => 'File',
root_dir => File::Spec->catfile($FindBin::Bin, 'cache'),
);
use constant SIZE => 1000;
my $mcpan = MetaCPAN::Client->new();
my $user;
if( $user_arg =~ /^PAUSE:(.*)/) { # get user ID from PAUSE info
my $pause_id = $1;
my $author = $mcpan->author( $pause_id );
$user = $author->user;
if( ! $user ) {
die "PAUSE ID $pause_id does not have MetaCPAN account.\n";
}
} else {
$user = $user_arg;
}
my $fav_dist_results = $mcpan->favorite(
{ user => $user },
{ fields => [ qw/distribution/ ] }
);
if( $fav_dist_results->total == 0 ) {
warn "No MetaCPAN favourites\n";
exit;
}
my $progress = Term::ProgressBar->new({ count => $fav_dist_results->total });
my $cpan_to_github;
my $count = 0;
while( my $dist = $fav_dist_results->next ) {
$progress->update(++$count);
#say $dist->distribution;
my $release_resources = try {
$cache->compute( $dist->distribution, undef, sub {
my $release = $mcpan->release(
$dist->distribution,
{ fields => [ qw/resources.repository.url resources.repository.web/ ] }
);
$release->resources;
});
} catch {
};
next unless $release_resources;
my $res = $release_resources->{repository};
my @urls = map {
my $url = $_;
# normalise to https:// URL
$url =~ s/^http:/https:/;
$url =~ s/^git:/https:/;
$url =~ s/\.git$//;
$url;
} map {
exists $res->{$_} && $res->{$_} =~ /github\.com/ ? $res->{$_} : ()
} qw(web url);
next unless @urls;
$cpan_to_github->{$dist->distribution} = [ uniqstr @urls ];
}
if( 0 ) {
my %multiple = map { $_ => $cpan_to_github->{$_} }
grep { @{ $cpan_to_github->{$_} } > 1 }
keys %$cpan_to_github;
}
sub is_starred {
my ($org, $repo) = @_;
my (undef, undef, $exit) = capture {
system(
qw(gh api --silent -X GET), "/user/starred/$org/$repo"
);
};
$exit == 0;
}
sub star_repo {
my ($org, $repo) = @_;
my (undef, undef, $exit) = capture {
system(
qw(gh api --silent -X PUT), "/user/starred/$org/$repo"
);
};
$exit == 0;
}
for my $dist (sort keys %$cpan_to_github) {
my $url = $cpan_to_github->{$dist}[0];
if( $url !~ m,^\Qhttps://github.com\E/(?<org>[^/]+)/(?<repo>[^/]+), ) {
warn "Could not identify repo for URL <$url>";
next;
}
my ($org, $repo) = ( $+{org},$+{repo} );
my $slug = "$org/$repo";
if( is_starred($org, $repo) ) {
say "✓ $dist @ $slug";
} else {
say "✗ $dist @ $slug";
if( confirm("Star repo $slug?") ) {
star_repo( $org, $repo );
}
}
}
__END__
=head1 SYNOPSIS
metacpan-favourite-to-github [MetaCPAN user ID]
metacpan-favourite-to-github PAUSE:[PAUSE ID]
=head1 DESCRIPTION
Retrieves MetaCPAN favourites and gets the associated GitHub repositories.
Checks if repository is starred and prompts to star the GitHub repository if
not already starred.
You can get your MetaCPAN user ID from the C<id> field at
L<https://fastapi.metacpan.org/user>. You may need to login first at
L<https://fastapi.metacpan.org/login>.
@zmughal
Copy link
Author

zmughal commented Jan 5, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment