Skip to content

Commit

Permalink
Merge pull request #14 from rm3l/force-sync
Browse files Browse the repository at this point in the history
  • Loading branch information
rm3l authored Sep 24, 2022
2 parents fbd4b7b + 87fbe40 commit c5b10e3
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 9 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
## Installation

- Install the `gh` CLI. See [https://github.com/cli/cli#installation](https://github.com/cli/cli#installation) for further details.
- If not done already, also install [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) of course.
- If not done already, also install [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git).
- To be able to clone private repos you have access to inside the Organization, authenticate with your GitHub account by running `gh auth login`. Alternatively, the CLI will respect the `GITHUB_TOKEN` [environment variable](https://cli.github.com/manual/gh_help_environment).
- Install the extension:

Expand All @@ -31,6 +31,9 @@ Options:
-dry-run
dry run mode. to display the repositories that will get cloned or updated,
without actually performing those actions
-force
whether to force sync repositories.
Caution: this will hard-reset the branch of the destination repository to match the source repository.
-output string
the output path (default ".")
-protocol string
Expand Down
24 changes: 19 additions & 5 deletions internal/reposync/repo_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,15 @@ const (
// HandleRepository determines whether a directory with the repository name does exist.
// If it does, it checks out its default branch and updates it locally.
// Otherwise, it clones it.
func HandleRepository(_ context.Context, dryRun bool, output, organization string, repositoryInfo github.RepositoryInfo, protocol CloneProtocol) error {
func HandleRepository(
_ context.Context,
dryRun bool,
output,
organization string,
repositoryInfo github.RepositoryInfo,
protocol CloneProtocol,
force bool,
) error {
repository := repositoryInfo.Name
repoPath, err := safeAbsPath(fmt.Sprintf("%s/%s", output, repository))
if err != nil {
Expand Down Expand Up @@ -62,7 +70,7 @@ func HandleRepository(_ context.Context, dryRun bool, output, organization strin
return nil
}
log.Println("[debug] updating local clone for repo:", repoPath)
return updateLocalClone(repoPath, organization, repositoryInfo)
return updateLocalClone(repoPath, organization, repositoryInfo, force)
}

func clone(output, organization string, repository string, protocol CloneProtocol) error {
Expand All @@ -88,13 +96,13 @@ func clone(output, organization string, repository string, protocol CloneProtoco
return err
}

func updateLocalClone(outputPath, organization string, repositoryInfo github.RepositoryInfo) error {
func updateLocalClone(outputPath, organization string, repositoryInfo github.RepositoryInfo, force bool) error {
repository := repositoryInfo.Name
repoPath, err := safeAbsPath(outputPath)
if err != nil {
return err
}
err = fetchAllRemotes(repoPath)
err = fetchAllRemotes(repoPath, force)
if err != nil {
return err
}
Expand All @@ -103,16 +111,22 @@ func updateLocalClone(outputPath, organization string, repositoryInfo github.Rep
return nil
}
args := []string{"repo", "sync", "--source", fmt.Sprintf("%s/%s", organization, repository)}
if force {
args = append(args, "--force")
}
_, _, err = github.RunGhCliInDir(repoPath, nil, args...)
return err
}

func fetchAllRemotes(outputPath string) error {
func fetchAllRemotes(outputPath string, force bool) error {
repoPath, err := safeAbsPath(outputPath)
if err != nil {
return err
}
args := []string{"fetch", "--all", "--prune", "--tags", "--recurse-submodules"}
if force {
args = append(args, "--force")
}
_, _, err = cli.RunCommandInDir("git", repoPath, nil, args...)
return err
}
Expand Down
11 changes: 8 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func main() {
var batchSize int
var output string
var protocol string
var force bool
flag.BoolVar(&dryRun, "dry-run", false,
`dry run mode. to display the repos that will get cloned or updated,
without actually performing those actions`)
Expand All @@ -41,6 +42,10 @@ See https://bit.ly/3HurHe3 for more details on the search syntax`)
fmt.Sprintf("the protocol to use for cloning. Possible values: %s, %s, %s.", reposync.SystemProtocol,
reposync.SSHProtocol, reposync.HTTPSProtocol))
flag.StringVar(&output, "output", ".", "the output path")
flag.BoolVar(&force, "force", false,
`whether to force sync repositories.
Caution: this will hard-reset the branch of the destination repository to match the source repository.`)

flag.Usage = func() {
//goland:noinspection GoUnhandledErrorResult
fmt.Fprintln(os.Stderr, "Usage: gh org-repo-sync <organization> [options]")
Expand Down Expand Up @@ -87,11 +92,11 @@ See https://bit.ly/3HurHe3 for more details on the search syntax`)
for _, repository := range repositories {
g.Go(func(repo github.RepositoryInfo) func() error {
return func() error {
err := reposync.HandleRepository(ctx, dryRun, output, organization, repo, cloneProtocol)
err := reposync.HandleRepository(ctx, dryRun, output, organization, repo, cloneProtocol, force)
if err != nil {
log.Println(fmt.Sprintf("[warn] an error occurred while handling repo %q:", repo.Name), err)
return fmt.Errorf("error while handling repo %q: %w", repo.Name, err)
}
return err
return nil
}
}(repository))
}
Expand Down

0 comments on commit c5b10e3

Please sign in to comment.