Skip to content

Commit

Permalink
Simplify the result code
Browse files Browse the repository at this point in the history
  • Loading branch information
telemachus committed Nov 4, 2024
1 parent 4a6a0c0 commit e565bf9
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 55 deletions.
38 changes: 18 additions & 20 deletions cli/initialize.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"
)

const (
Expand Down Expand Up @@ -34,49 +33,48 @@ func (app *App) Initialize(repos []Repo) {
app.ExitValue = exitFailure
return
}
ch := make(chan Publisher)
ch := make(chan result)
for _, repo := range repos {
go app.initialize(repo, ch)
}
for range repos {
result := <-ch
result.Publish(app.QuietWanted)
res := <-ch
res.publish(app.QuietWanted)
}
}

func (app *App) initialize(repo Repo, ch chan<- Publisher) {
func (app *App) initialize(repo Repo, ch chan<- result) {
// Normally, it is a bad idea to check whether a directory exists
// before trying an operation. However, this case is an exception.
// git clone --mirror /path/to/existing/repo.git will fail with an
// error, but for the purpose of this app, there is no error.
// If a directory with the same name already exists, I simply want
// to send a Success on the channel and return.
// If a directory with the repo's name exists, I simply want to send
// a result saying that the repo exists.
repoPath := filepath.Join(app.HomeDir, defaultStorage, repo.Name)
storagePath := filepath.Join(app.HomeDir, defaultStorage)
if _, err := os.Stat(repoPath); err == nil {
ch <- Success{
msg: fmt.Sprintf(
"%s: %s already exists",
app.CmdName,
app.PrettyPath(repoPath),
),
ch <- result{
isErr: false,
msg: fmt.Sprintf("%s: already present in %s", repo.Name, storagePath),
}
return
}
args := []string{"clone", "--mirror", repo.URL, repo.Name}
cmd := exec.Command("git", args...)
cmd.Dir = filepath.Join(app.HomeDir, defaultStorage)
cmdString := fmt.Sprintf(
"git %s (in %s)",
strings.Join(args, " "),
app.PrettyPath(cmd.Dir),
)
err := cmd.Run()
if err != nil {
app.ExitValue = exitFailure
ch <- Failure{msg: fmt.Sprintf("%s: %s: %s", app.CmdName, cmdString, err)}
ch <- result{
isErr: true,
msg: fmt.Sprintf("%s: %s", repo.Name, err),
}
return
}
ch <- Success{msg: fmt.Sprintf("%s: %s", app.CmdName, cmdString)}
ch <- result{
isErr: false,
msg: fmt.Sprintf("%s: successfully cloned", repo.Name),
}
}

// InitRun clones requested repos locally for mirroring.
Expand Down
32 changes: 10 additions & 22 deletions cli/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,18 @@ import (
"os"
)

// Publisher is the interface that wraps the Publish method.
type Publisher interface {
Publish(quietWanted bool)
type result struct {
msg string
isErr bool
}

// Success represents `git push --mirror` when nothing goes wrong.
type Success struct {
msg string
}

// Failure represents `git push --mirror` when something goes wrong.
type Failure struct {
msg string
}

// Publish prints a Success's message to stdout unless the user passed -quiet.
func (s Success) Publish(quietWanted bool) {
if quietWanted {
func (r result) publish(quiet bool) {
if r.isErr {
fmt.Fprintln(os.Stderr, r.msg)
return
}
fmt.Fprintln(os.Stdout, s.msg)
}

// Publish unconditionally prints a Failure's message to stderr.
func (f Failure) Publish(_ bool) {
fmt.Fprintln(os.Stderr, f.msg)
if quiet {
return
}
fmt.Fprintln(os.Stdout, r.msg)
}
25 changes: 12 additions & 13 deletions cli/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"os/exec"
"path/filepath"
"strings"
)

const (
Expand All @@ -27,32 +26,32 @@ func (app *App) Update(repos []Repo) {
if app.NoOp() {
return
}
ch := make(chan Publisher)
ch := make(chan result)
for _, repo := range repos {
go app.update(repo, ch)
}
for range repos {
result := <-ch
result.Publish(app.QuietWanted)
res := <-ch
res.publish(app.QuietWanted)
}
}

func (app *App) update(repo Repo, ch chan<- Publisher) {
func (app *App) update(repo Repo, ch chan<- result) {
args := []string{"remote", "update"}
cmd := exec.Command("git", args...)
cmd.Dir = filepath.Join(app.HomeDir, defaultStorage, repo.Name)
cmdString := fmt.Sprintf(
"git %s (in %s)",
strings.Join(args, " "),
app.PrettyPath(cmd.Dir),
)
err := cmd.Run()
if err != nil {
app.ExitValue = exitFailure
ch <- Failure{msg: fmt.Sprintf("%s: %s: %s", app.CmdName, cmdString, err)}
ch <- result{
isErr: true,
msg: fmt.Sprintf("%s: %s", repo.Name, err),
}
return
}
ch <- Success{msg: fmt.Sprintf("%s: %s", app.CmdName, cmdString)}
ch <- result{
isErr: false,
msg: fmt.Sprintf("%s: up to date", repo.Name),
}
}

// CmdUpdate runs `git remote update` on repos listed in a config file.
Expand Down

0 comments on commit e565bf9

Please sign in to comment.