Bläddra i källkod

parse and setup remotes

George Baugh 1 år sedan
förälder
incheckning
d9b560e80c
1 ändrade filer med 57 tillägg och 17 borttagningar
  1. 57 17
      bin/git-clone-entity

+ 57 - 17
bin/git-clone-entity

@@ -282,35 +282,60 @@ sub main {
 	# Build a map of names to clone URIs
 	my $field_name = $options{nossh} ? 'clone_url' : 'ssh_url';
 	my %names2clone = map { $_->{name} => $_->{$field_name} } @repos_local;
+
+	# Figure out which repos are private so we don't mirror them unless instructed to.
+	my @private_repos = map { $_->{name} } grep { $_->{private} } @repos_local;
+
+	# Grab all the mirrors push uris
 	my %mirror_uris;
 	foreach my $repo (@repos_mirror) {
 		$mirror_uris{$repo->{name}} //= [];
 		push( @{$mirror_uris{$repo->{name}}}, $repo->{$field_name});
 	}
 
-	$cleanup->();
-
-    use Data::Dumper;
-    die Dumper(\%names2clone, \%mirror_uris);
-
-	my @to_create;
 	foreach my $to_clone (keys(%names2clone)) {
-		my $res = Git::command_oneline([ 'clone', $names2clone{$to_clone} ]);
+		#XXX testing removme
+		next unless $to_clone eq 'perl-Gogs';
+
+		# Don't clone it if it is already present.
+		my $already_exists=1;
+		if (!-d $to_clone) {
+			$already_exists=0;
+			my $res = Git::command_oneline([ 'clone', $names2clone{$to_clone} ]);
+		}
 		my $repo = Git->repository(Directory => $to_clone);
 
-		#TODO check privacy field
+		# Figure out what the remotes look like
+		my $res = $repo->command(qw{remote -v});
+		my %remotes = _parse_remotes($res);
 
-		if (!exists $mirror_uris{$to_clone}) {
-			#TODO push into @to_create if $create
-			next;
-		}
-		# TODO check if the repo is missing on just *some* of the mirrors and add to @to_create if $create
+		# TODO add specific remotes for the baseurl and mirrors.  This way we can manually push to each if we need to sync.
+
+		# Ensure that origin is correctly the local one for those that already exist
+		if ($remotes{origin}{fetch} ne $names2clone{$to_clone}) {
+			print "Incorrect origin in $to_clone, correcting...\n";
+			$res = $repo->command(qw{remote set-url --fetch origin}, $names2clone{$to_clone});
+			# TODO error handling
 
-		foreach my $mirror (@{$mirror_uris{$to_clone}}) {
-			# The real "magic" here -- you can have many push urls.
-			$repo->command(qw{git remote set-url --add --push}, 'origin', $mirror);
-			#TODO make sure they are all synced up if --sync
+			# We don't care if push uri already there
+			next if any { $_ eq $names2clone{$to_clone} } @{$remotes{origin}{push}};
+
+			print "Lacking push URI for $to_clone, correcting...\n";
+			$res = $repo->command(qw{remote set-url --add --push origin}, $names2clone{$to_clone});
+			#TODO error handling
+		}
+		# TODO figure out which mirrors are missing, and add them if needed (consider privacy)
+
+		foreach my $mirror_uri ($mirror_uris{$to_clone}) {
+			# We don't care if it's already there
+			next if any { $_ eq $mirror_uri } @{$remotes{origin}{push}};
+			next if !$options{private} && any { $_ eq $to_clone } @private_repos;
+			print "Lacking push URI $mirror_uri, adding to origin...\n";
+			$res = $repo->command(qw{remote set-url --add --push origin}, $mirror_uri);
+			#TODO error handling
 		}
+
+		# Finally, sync up the mirrors if instructed.  This is important, as push URIs which aren't in sync will leave git in an inconsistent state.
 	}
 
 	# Clean up
@@ -318,6 +343,21 @@ sub main {
 	return 0;
 }
 
+sub _parse_remotes {
+	my ($raw) = shift;
+	my %parsed;
+	foreach my $line (split(/\n/, $raw)) {
+		my ($name, $uri, $type) = $line =~ m/^(.+)\s+(.+)\s+\((.+)\)$/;
+		if ($type eq 'fetch') {
+			$parsed{$name}{$type} = $uri;
+		} else {
+			$parsed{$name}{$type} //= [];
+			push(@{$parsed{$name}{$type}}, $uri);
+		}
+	}
+	return %parsed;
+}
+
 sub _cleanup_token {
 	my ( $api, $password, $insecure ) = @_;
 	my $result = $api->delete_token( sha1 => $api->token, password => $password, insecure => $insecure );