|
@@ -119,6 +119,8 @@ Map a user/org on your baseurl to a mirror. Of the format base_user:mirror_doma
|
|
|
|
|
|
|
|
Obviously won't work if the mirror is on the same hostname as the baseurl; use a subdomain at the very least.
|
|
Obviously won't work if the mirror is on the same hostname as the baseurl; use a subdomain at the very least.
|
|
|
|
|
|
|
|
|
|
+Also used to alias --me in the case it's different on the primary and mirrors.
|
|
|
|
|
+
|
|
|
--alias george:sprockets.spacely.local:gjetson
|
|
--alias george:sprockets.spacely.local:gjetson
|
|
|
|
|
|
|
|
=head3 nossh
|
|
=head3 nossh
|
|
@@ -169,6 +171,11 @@ sub _help {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
my $domainRipper = qr{^\w+://([\w|\.]+)};
|
|
my $domainRipper = qr{^\w+://([\w|\.]+)};
|
|
|
|
|
+my $verbose;
|
|
|
|
|
+
|
|
|
|
|
+sub LOG {
|
|
|
|
|
+ print shift."\n" if $verbose;
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
sub main {
|
|
sub main {
|
|
|
my @args = @_;
|
|
my @args = @_;
|
|
@@ -189,6 +196,7 @@ sub main {
|
|
|
remote => 'origin',
|
|
remote => 'origin',
|
|
|
primary_user => undef,
|
|
primary_user => undef,
|
|
|
primary_org => undef,
|
|
primary_org => undef,
|
|
|
|
|
+ verbose => undef,
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
# Allow options to override configuration
|
|
# Allow options to override configuration
|
|
@@ -225,7 +233,9 @@ sub main {
|
|
|
'help' => \$options{help},
|
|
'help' => \$options{help},
|
|
|
'primary_user=s' => \$options{primary},
|
|
'primary_user=s' => \$options{primary},
|
|
|
'primary_org=s' => \$options{primary_org},
|
|
'primary_org=s' => \$options{primary_org},
|
|
|
|
|
+ 'verbose' => \$options{verbose},
|
|
|
);
|
|
);
|
|
|
|
|
+ $verbose = $options{verbose};
|
|
|
|
|
|
|
|
# Tiebreaker vote in the event of conflicting forks
|
|
# Tiebreaker vote in the event of conflicting forks
|
|
|
push(@{$options{users}}, $options{primary_user}) if $options{primary_user};
|
|
push(@{$options{users}}, $options{primary_user}) if $options{primary_user};
|
|
@@ -239,11 +249,12 @@ sub main {
|
|
|
return _help(3, "Must pass your username as --me") unless $options{me};
|
|
return _help(3, "Must pass your username as --me") unless $options{me};
|
|
|
|
|
|
|
|
# Parse Alias mappings
|
|
# Parse Alias mappings
|
|
|
- my %alias_map;
|
|
|
|
|
|
|
+ my (%alias_map, %alias_reverse);
|
|
|
foreach my $arg (@{$options{aliases}}) {
|
|
foreach my $arg (@{$options{aliases}}) {
|
|
|
my ($actual, $domain, $alias) = split(/:/, $arg);
|
|
my ($actual, $domain, $alias) = split(/:/, $arg);
|
|
|
return _help(3, "aliases must be of the form user:domain:alias") unless $actual && $domain && $alias;
|
|
return _help(3, "aliases must be of the form user:domain:alias") unless $actual && $domain && $alias;
|
|
|
$alias_map{$domain}{$actual} = $alias;
|
|
$alias_map{$domain}{$actual} = $alias;
|
|
|
|
|
+ $alias_reverse{$domain}{$alias} = $actual;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
# Parse tokens
|
|
# Parse tokens
|
|
@@ -297,21 +308,34 @@ sub main {
|
|
|
my @fetched = _fetch_all($mirror, $options{users}, $options{orgs}, \%alias_map, $field_name);
|
|
my @fetched = _fetch_all($mirror, $options{users}, $options{orgs}, \%alias_map, $field_name);
|
|
|
_help(7, "The provided server ($mirror_url) could not list repos!", $cleanup ) unless @fetched;
|
|
_help(7, "The provided server ($mirror_url) could not list repos!", $cleanup ) unless @fetched;
|
|
|
|
|
|
|
|
|
|
+ # GOGS will list all the repos the user *has access to* not all the ones they own.
|
|
|
|
|
+ @fetched = grep { $_->{owner}{login} eq $_->{user} } @fetched;
|
|
|
|
|
+
|
|
|
push(@repos, @fetched);
|
|
push(@repos, @fetched);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- #TODO actually differentiate between the various clones, build username/org remotes
|
|
|
|
|
-
|
|
|
|
|
- # Build a map of names to clone URIs
|
|
|
|
|
- my %names2clone = map { $_->{name} => $_->{$field_name} } @repos;
|
|
|
|
|
- my %upstreams = map { $_->{name} => $_->{upstream_uri} } @repos;
|
|
|
|
|
-
|
|
|
|
|
- # Figure out which repos are private so we don't mirror them unless instructed to.
|
|
|
|
|
- my @private_repos = map { $_->{name} } grep { $_->{private} } @repos;
|
|
|
|
|
|
|
+ my ($primary_domain) = $options{baseurl} =~ $domainRipper;
|
|
|
|
|
+
|
|
|
|
|
+ my %repodata;
|
|
|
|
|
+ foreach my $repo (@repos) {
|
|
|
|
|
+ $repodata{$repo->{name}} //= [];
|
|
|
|
|
+ my $reversed = $alias_reverse{$repo->{domain}} // {};
|
|
|
|
|
+ my $aliased = exists $reversed->{$repo->{owner}{login}} ? $reversed->{$repo->{owner}{login}} : $repo->{owner}{login};
|
|
|
|
|
+ my $repo_info = {
|
|
|
|
|
+ clone_uri => $repo->{$field_name},
|
|
|
|
|
+ upstream_uri => $repo->{upstream_uri},
|
|
|
|
|
+ private => $repo->{private},
|
|
|
|
|
+ is_primary_domain => $repo->{domain} eq $primary_domain,
|
|
|
|
|
+ domain => $repo->{domain},
|
|
|
|
|
+ is_primary_owner => $aliased eq $prime_name,
|
|
|
|
|
+ owner => $aliased,
|
|
|
|
|
+ };
|
|
|
|
|
+ push(@{$repodata{$repo->{name}}}, $repo_info);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
$cleanup->();
|
|
$cleanup->();
|
|
|
use Data::Dumper;
|
|
use Data::Dumper;
|
|
|
- die Dumper(\%names2clone, \%upstreams, \@private_repos);
|
|
|
|
|
|
|
+ die Dumper(\%repodata);
|
|
|
|
|
|
|
|
# Clean up
|
|
# Clean up
|
|
|
$cleanup->();
|
|
$cleanup->();
|
|
@@ -325,6 +349,7 @@ sub _fetch_upstream_uri {
|
|
|
my ($mirror, $field_name, $muser, $repo) = @_;
|
|
my ($mirror, $field_name, $muser, $repo) = @_;
|
|
|
my $upstream_uri;
|
|
my $upstream_uri;
|
|
|
if ($repo->{fork}) {
|
|
if ($repo->{fork}) {
|
|
|
|
|
+ LOG("Looking up what $repo->{name} was forked from...");
|
|
|
my $details = $mirror->repos->get( user => $muser, repo => $repo->{name});
|
|
my $details = $mirror->repos->get( user => $muser, repo => $repo->{name});
|
|
|
_help(9, "Could not fetch repository details for $repo->{name}") unless $details && $details->response->is_success();
|
|
_help(9, "Could not fetch repository details for $repo->{name}") unless $details && $details->response->is_success();
|
|
|
my $content = $details->content();
|
|
my $content = $details->content();
|
|
@@ -386,6 +411,7 @@ sub _fetch_all {
|
|
|
|
|
|
|
|
my @repos;
|
|
my @repos;
|
|
|
foreach my $user (@$users) {
|
|
foreach my $user (@$users) {
|
|
|
|
|
+ LOG("Fetching repos for $user...");
|
|
|
$user = $alias_map->{$domain}{$user} if exists $alias_map->{$domain}{$user};
|
|
$user = $alias_map->{$domain}{$user} if exists $alias_map->{$domain}{$user};
|
|
|
my $result = $api->repos->list( user => $user );
|
|
my $result = $api->repos->list( user => $user );
|
|
|
|
|
|
|
@@ -395,6 +421,7 @@ sub _fetch_all {
|
|
|
push(@repos, @fetched);
|
|
push(@repos, @fetched);
|
|
|
}
|
|
}
|
|
|
foreach my $org (@$orgs) {
|
|
foreach my $org (@$orgs) {
|
|
|
|
|
+ LOG("Fetching repos for $org...");
|
|
|
$org = $alias_map->{$domain}{$org} if exists $alias_map->{$domain}{$org};
|
|
$org = $alias_map->{$domain}{$org} if exists $alias_map->{$domain}{$org};
|
|
|
my $result = $api->repos->list( org => $org );
|
|
my $result = $api->repos->list( org => $org );
|
|
|
|
|
|
|
@@ -419,6 +446,7 @@ sub _augment_repos {
|
|
|
my $subj = $_;
|
|
my $subj = $_;
|
|
|
$subj->{domain} = $domain;
|
|
$subj->{domain} = $domain;
|
|
|
$subj->{upstream_uri} = _fetch_upstream_uri($mirror, $field_name, $muser, $subj);
|
|
$subj->{upstream_uri} = _fetch_upstream_uri($mirror, $field_name, $muser, $subj);
|
|
|
|
|
+ $subj->{user} = $muser;
|
|
|
$subj
|
|
$subj
|
|
|
} @fetched;
|
|
} @fetched;
|
|
|
return @fetched;
|
|
return @fetched;
|
|
@@ -426,6 +454,7 @@ sub _augment_repos {
|
|
|
|
|
|
|
|
sub _server_is_github {
|
|
sub _server_is_github {
|
|
|
my ($uri) = @_;
|
|
my ($uri) = @_;
|
|
|
|
|
+ LOG("Figuring out what kind of server $uri is...");
|
|
|
my $ua = HTTP::Tiny->new();
|
|
my $ua = HTTP::Tiny->new();
|
|
|
my $res = $ua->get($uri);
|
|
my $res = $ua->get($uri);
|
|
|
# GOGS will 404 it's api baseurl, github will not
|
|
# GOGS will 404 it's api baseurl, github will not
|