Skip to content

Commit

Permalink
add some git helpers
Browse files Browse the repository at this point in the history
Signed-off-by: Stephen Gutekanst <[email protected]>
  • Loading branch information
emidoots committed Jul 13, 2023
1 parent 527cf70 commit 3b45283
Show file tree
Hide file tree
Showing 6 changed files with 300 additions and 0 deletions.
53 changes: 53 additions & 0 deletions git.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package main

import (
"flag"
"fmt"

"github.com/hexops/cmder"
)

// gitCommands contains all registered 'wrench git' subcommands.
var gitCommands cmder.Commander

var (
gitFlagSet = flag.NewFlagSet("git", flag.ExitOnError)
)

func init() {
const usage = `wrench git: manage git repositories
Usage:
wrench git <command> [arguments]
The commands are:
clone clone all repositories
status status all repositories
commitpush commit and push all repositories
resethard git reset --hard all repositories
Use "wrench git <command> -h" for more information about a command.
`

usageFunc := func() {
fmt.Printf("%s", usage)
}
gitFlagSet.Usage = usageFunc

// Handles calls to our subcommand.
handler := func(args []string) error {
_ = gitFlagSet.Parse(args)
gitCommands.Run(gitFlagSet, "wrench git", usage, args)
return nil
}

// Register the command.
commands = append(commands, &cmder.Command{
FlagSet: gitFlagSet,
Aliases: []string{},
Handler: handler,
UsageFunc: usageFunc,
})
}
53 changes: 53 additions & 0 deletions git_clone.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package main

import (
"flag"
"fmt"
"os"
"strings"

"github.com/hexops/cmder"
"github.com/hexops/wrench/internal/wrench/scripts"
)

func init() {
const usage = `
Examples:
Clone all repositories:
$ wrench git clone
`

// Parse flags for our subcommand.
flagSet := flag.NewFlagSet("clone", flag.ExitOnError)

// Handles calls to our subcommand.
handler := func(args []string) error {
_ = flagSet.Parse(args)

for _, repo := range scripts.AllRepos {
repoName := strings.Split(repo.Name, "/")[1]
if _, err := os.Stat(repoName); os.IsNotExist(err) {
err := scripts.ExecArgs("git", []string{"clone", "[email protected]:" + repo.Name, repoName})(os.Stderr)
if err != nil {
return err
}
}
}
return nil
}

// Register the command.
gitCommands = append(gitCommands, &cmder.Command{
FlagSet: flagSet,
Aliases: []string{},
Handler: handler,
UsageFunc: func() {
fmt.Fprintf(flag.CommandLine.Output(), "Usage of 'wrench git clone %s':\n", flagSet.Name())
flagSet.PrintDefaults()
fmt.Printf("%s", usage)
},
})
}
72 changes: 72 additions & 0 deletions git_commitpush.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package main

import (
"flag"
"fmt"
"os"
"strings"

"github.com/hexops/cmder"
"github.com/hexops/wrench/internal/wrench/scripts"
)

func init() {
const usage = `
Examples:
Git commit & push all repositories:
$ wrench git commitpush
`

// Parse flags for our subcommand.
flagSet := flag.NewFlagSet("commitpush", flag.ExitOnError)
excludeSet := flagSet.String("exclude", "", "comma separated list of repositories to exclude")
accept := flagSet.Bool("accept", false, "Actually run the commands (do not run in dry-run mode)")

// Handles calls to our subcommand.
handler := func(args []string) error {
_ = flagSet.Parse(args)

commitMessage := flagSet.Arg(0)

excludedRepos := map[string]struct{}{}
for _, excluded := range strings.FieldsFunc(*excludeSet, func(r rune) bool {
return r == ','
}) {
excludedRepos[excluded] = struct{}{}
}

for _, repo := range scripts.AllRepos {
repoName := strings.Split(repo.Name, "/")[1]
if _, err := os.Stat(repoName); err != nil {
continue
}
if _, excluded := excludedRepos[repoName]; excluded {
continue
}
if !*accept {
fmt.Printf("$ cd %s/ && git add . && git commit -s -m '%s' && git push\n", repoName, commitMessage)
} else {
_ = scripts.ExecArgs("git", []string{"pull"}, scripts.WorkDir(repoName))(os.Stderr)
_ = scripts.ExecArgs("git", []string{"add", "."}, scripts.WorkDir(repoName))(os.Stderr)
_ = scripts.ExecArgs("git", []string{"commit", "-s", "-m", commitMessage}, scripts.WorkDir(repoName))(os.Stderr)
_ = scripts.ExecArgs("git", []string{"push"}, scripts.WorkDir(repoName))(os.Stderr)
}
}
return nil
}

// Register the command.
gitCommands = append(gitCommands, &cmder.Command{
FlagSet: flagSet,
Aliases: []string{},
Handler: handler,
UsageFunc: func() {
fmt.Fprintf(flag.CommandLine.Output(), "Usage of 'wrench git status %s':\n", flagSet.Name())
flagSet.PrintDefaults()
fmt.Printf("%s", usage)
},
})
}
67 changes: 67 additions & 0 deletions git_reset_hard.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package main

import (
"flag"
"fmt"
"os"
"strings"

"github.com/hexops/cmder"
"github.com/hexops/wrench/internal/wrench/scripts"
)

func init() {
const usage = `
Examples:
Git reset hard all repositories:
$ wrench git resethard
`

// Parse flags for our subcommand.
flagSet := flag.NewFlagSet("resethard", flag.ExitOnError)
excludeSet := flagSet.String("exclude", "", "comma separated list of repositories to exclude")
accept := flagSet.Bool("accept", false, "Actually run the commands (do not run in dry-run mode)")

// Handles calls to our subcommand.
handler := func(args []string) error {
_ = flagSet.Parse(args)

excludedRepos := map[string]struct{}{}
for _, excluded := range strings.FieldsFunc(*excludeSet, func(r rune) bool {
return r == ','
}) {
excludedRepos[excluded] = struct{}{}
}

for _, repo := range scripts.AllRepos {
repoName := strings.Split(repo.Name, "/")[1]
if _, err := os.Stat(repoName); err != nil {
continue
}
if _, excluded := excludedRepos[repoName]; excluded {
continue
}
if !*accept {
fmt.Printf("$ cd %s/ && git reset --hard origin/main\n", repoName)
} else {
_ = scripts.ExecArgs("git", []string{"reset", "--hard", "origin/main"}, scripts.WorkDir(repoName))(os.Stderr)
}
}
return nil
}

// Register the command.
gitCommands = append(gitCommands, &cmder.Command{
FlagSet: flagSet,
Aliases: []string{},
Handler: handler,
UsageFunc: func() {
fmt.Fprintf(flag.CommandLine.Output(), "Usage of 'wrench git status %s':\n", flagSet.Name())
flagSet.PrintDefaults()
fmt.Printf("%s", usage)
},
})
}
54 changes: 54 additions & 0 deletions git_status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package main

import (
"flag"
"fmt"
"os"
"strings"

"github.com/hexops/cmder"
"github.com/hexops/wrench/internal/wrench/scripts"
)

func init() {
const usage = `
Examples:
Git status all repositories:
$ wrench git status
`

// Parse flags for our subcommand.
flagSet := flag.NewFlagSet("status", flag.ExitOnError)

// Handles calls to our subcommand.
handler := func(args []string) error {
_ = flagSet.Parse(args)

for _, repo := range scripts.AllRepos {
repoName := strings.Split(repo.Name, "/")[1]
if _, err := os.Stat(repoName); err != nil {
continue
}
err := scripts.ExecArgs("git", []string{"status", "-s"}, scripts.WorkDir(repoName))(os.Stderr)
if err != nil {
return err
}
}
return nil
}

// Register the command.
gitCommands = append(gitCommands, &cmder.Command{
FlagSet: flagSet,
Aliases: []string{},
Handler: handler,
UsageFunc: func() {
fmt.Fprintf(flag.CommandLine.Output(), "Usage of 'wrench git status %s':\n", flagSet.Name())
flagSet.PrintDefaults()
fmt.Printf("%s", usage)
},
})
}
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ The commands are:
script execute a script built-in to wrench
runners (remote) list registered runners
secret (remote) manage secrets
git manage local git repositories
Use "wrench <command> -h" for more information about a command.
`
Expand Down

0 comments on commit 3b45283

Please sign in to comment.