mirror of
https://github.com/arl/gitmux.git
synced 2026-09-10 07:26:18 -04:00
* Use flag.Duration instead roll-your-own duration * Remove deprecated cli flags (-q and --fmt) * parseOptions returns context cancellation function * In config_test.go do not import embed package anymore * Cosmetics * Cosmetics
144 lines
2.8 KiB
Go
144 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
|
|
"github.com/arl/gitstatus"
|
|
"gopkg.in/yaml.v3"
|
|
|
|
"github.com/arl/gitmux/json"
|
|
"github.com/arl/gitmux/tmux"
|
|
)
|
|
|
|
var version = "<<development version>>"
|
|
|
|
var _usage = `gitmux ` + version + `
|
|
Usage: gitmux [options] [dir]
|
|
|
|
gitmux prints the status of a Git working tree as a tmux format string.
|
|
If directory is not given, it default to the working directory.
|
|
|
|
Options:
|
|
-cfg cfgfile use cfgfile when printing git status.
|
|
-printcfg prints default configuration file.
|
|
-dbg outputs Git status as JSON and print errors.
|
|
-timeout DUR exits if still running after given duration (ex: 2s, 500ms).
|
|
-V prints gitmux version and exits.
|
|
`
|
|
|
|
// Config configures output formatting.
|
|
type Config struct{ Tmux tmux.Config }
|
|
|
|
var _defaultCfg = Config{Tmux: tmux.DefaultCfg}
|
|
|
|
func parseOptions() (ctx context.Context, cancel func(), dir string, dbg bool, cfg Config) {
|
|
var (
|
|
dbgOpt = flag.Bool("dbg", false, "")
|
|
cfgOpt = flag.String("cfg", "", "")
|
|
printCfgOpt = flag.Bool("printcfg", false, "")
|
|
versionOpt = flag.Bool("V", false, "")
|
|
timeoutOpt = flag.Duration("timeout", 0, "")
|
|
)
|
|
|
|
flag.Usage = func() {
|
|
fmt.Println(_usage)
|
|
}
|
|
flag.Parse()
|
|
|
|
dir = "."
|
|
if flag.NArg() > 0 {
|
|
dir = flag.Arg(0)
|
|
}
|
|
|
|
if *versionOpt {
|
|
fmt.Println(version)
|
|
os.Exit(0)
|
|
}
|
|
|
|
if *printCfgOpt {
|
|
enc := yaml.NewEncoder(os.Stdout)
|
|
check(enc.Encode(&_defaultCfg), *dbgOpt)
|
|
enc.Close()
|
|
os.Exit(0)
|
|
}
|
|
|
|
cfg = _defaultCfg
|
|
|
|
if *cfgOpt != "" {
|
|
f, err := os.Open(*cfgOpt)
|
|
check(err, *dbgOpt)
|
|
|
|
dec := yaml.NewDecoder(f)
|
|
check(dec.Decode(&cfg), *dbgOpt)
|
|
}
|
|
|
|
if *timeoutOpt != 0 {
|
|
ctx, cancel = context.WithTimeout(context.Background(), *timeoutOpt)
|
|
} else {
|
|
ctx, cancel = context.WithCancel(context.Background())
|
|
}
|
|
|
|
return ctx, cancel, dir, *dbgOpt, cfg
|
|
}
|
|
|
|
func pushdir(dir string) (popdir func() error, err error) {
|
|
pwd := ""
|
|
if pwd, err = os.Getwd(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err = os.Chdir(dir); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return func() error { return os.Chdir(pwd) }, nil
|
|
}
|
|
|
|
func check(err error, dbg bool) {
|
|
if err == nil {
|
|
return
|
|
}
|
|
|
|
if dbg {
|
|
fmt.Fprintln(os.Stderr, "error:", err)
|
|
}
|
|
|
|
os.Exit(1)
|
|
}
|
|
|
|
func main() {
|
|
ctx, cancel, dir, dbg, cfg := parseOptions()
|
|
defer cancel()
|
|
|
|
// Handle directory change.
|
|
if dir != "." {
|
|
popDir, err := pushdir(dir)
|
|
|
|
check(err, dbg)
|
|
defer func() {
|
|
check(popDir(), dbg)
|
|
}()
|
|
}
|
|
|
|
// Retrieve git status.
|
|
st, err := gitstatus.NewWithContext(ctx)
|
|
check(err, dbg)
|
|
|
|
// Interface that writes a particular representation of a gitstatus.Status
|
|
type formater interface {
|
|
Format(io.Writer, *gitstatus.Status) error
|
|
}
|
|
|
|
// Set defauit formater.
|
|
var fmter formater = &tmux.Formater{Config: cfg.Tmux}
|
|
if dbg {
|
|
fmter = &json.Formater{}
|
|
}
|
|
|
|
check(fmter.Format(os.Stdout, st), dbg)
|
|
}
|