Ver Fonte

Better data structure

George Baugh há 1 ano atrás
pai
commit
9b4e1e013d
1 ficheiros alterados com 39 adições e 10 exclusões
  1. 39 10
      bin/git-clone-entity

+ 39 - 10
bin/git-clone-entity

@@ -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.
 
+Also used to alias --me in the case it's different on the primary and mirrors.
+
 	--alias george:sprockets.spacely.local:gjetson
 
 =head3 nossh
@@ -169,6 +171,11 @@ sub _help {
 }
 
 my $domainRipper = qr{^\w+://([\w|\.]+)};
+my $verbose;
+
+sub LOG {
+	print shift."\n" if $verbose;
+}
 
 sub main {
     my @args = @_;
@@ -189,6 +196,7 @@ sub main {
 		remote   => 'origin',
 		primary_user  => undef,
 		primary_org   => undef,
+		verbose       => undef,
 	);
 
 	# Allow options to override configuration
@@ -225,7 +233,9 @@ sub main {
         'help'      => \$options{help},
 		'primary_user=s' => \$options{primary},
 		'primary_org=s'  => \$options{primary_org},
+		'verbose'        => \$options{verbose},
     );
+	$verbose = $options{verbose};
 
 	# Tiebreaker vote in the event of conflicting forks
 	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};
 
     # Parse Alias mappings
-    my %alias_map;
+    my (%alias_map, %alias_reverse);
 	foreach my $arg (@{$options{aliases}}) {
 		my ($actual, $domain, $alias) = split(/:/, $arg);
 		return _help(3, "aliases must be of the form user:domain:alias") unless $actual && $domain && $alias;
 		$alias_map{$domain}{$actual} = $alias;
+		$alias_reverse{$domain}{$alias} = $actual;
 	}
 
 	# Parse tokens
@@ -297,21 +308,34 @@ sub main {
 		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;
 
+		# 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);
     }
 
-	#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->();
 	use Data::Dumper;
-	die Dumper(\%names2clone, \%upstreams, \@private_repos);
+	die Dumper(\%repodata);
 
 	# Clean up
 	$cleanup->();
@@ -325,6 +349,7 @@ sub _fetch_upstream_uri {
 	my ($mirror, $field_name, $muser, $repo) = @_;
 	my $upstream_uri;
 	if ($repo->{fork}) {
+		LOG("Looking up what $repo->{name} was forked from...");
 		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();
 		my $content = $details->content();
@@ -386,6 +411,7 @@ sub _fetch_all {
 
     my @repos;
     foreach my $user (@$users) {
+		LOG("Fetching repos for $user...");
         $user = $alias_map->{$domain}{$user} if exists $alias_map->{$domain}{$user};
         my $result = $api->repos->list( user => $user );
 
@@ -395,6 +421,7 @@ sub _fetch_all {
         push(@repos, @fetched);
     }
     foreach my $org (@$orgs) {
+		LOG("Fetching repos for $org...");
         $org = $alias_map->{$domain}{$org} if exists $alias_map->{$domain}{$org};
         my $result = $api->repos->list( org => $org );
 
@@ -419,6 +446,7 @@ sub _augment_repos {
 		my $subj = $_;
 		$subj->{domain} = $domain;
 		$subj->{upstream_uri} = _fetch_upstream_uri($mirror, $field_name, $muser, $subj);
+		$subj->{user} = $muser;
 		$subj
 	} @fetched;
 	return @fetched;
@@ -426,6 +454,7 @@ sub _augment_repos {
 
 sub _server_is_github {
 	my ($uri) = @_;
+	LOG("Figuring out what kind of server $uri is...");
 	my $ua = HTTP::Tiny->new();
 	my $res = $ua->get($uri);
 	# GOGS will 404 it's api baseurl, github will not