From cbd7a80c6a4ce5a9ab1b43a5554da633c1fd5d2d Mon Sep 17 00:00:00 2001 From: Devlin Hitchcock Date: Thu, 8 Feb 2024 08:14:13 +0200 Subject: [PATCH] Reduce code and remove additional structs where possible --- Makefile | 2 +- cmd/config/main.go | 26 +---- command/command.go | 23 ----- command/git.go | 71 ------------- command/init.go | 128 ------------------------ logger/logger.go | 13 --- pkg/cli/cli.go | 34 +++++++ pkg/command/git.go | 40 ++++++++ pkg/command/init.go | 87 ++++++++++++++++ pkg/configs/config.go | 36 +++++++ configs/config.go => pkg/configs/git.go | 52 ++-------- 11 files changed, 211 insertions(+), 301 deletions(-) delete mode 100644 command/command.go delete mode 100644 command/git.go delete mode 100644 command/init.go delete mode 100644 logger/logger.go create mode 100644 pkg/cli/cli.go create mode 100644 pkg/command/git.go create mode 100644 pkg/command/init.go create mode 100644 pkg/configs/config.go rename configs/config.go => pkg/configs/git.go (57%) diff --git a/Makefile b/Makefile index dbdf647..e127d28 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ build-release: .PHONY: gofmt gofmt: - gofmt -l -s -w ./cmd/config + gofmt -l -s -w ./cmd/config ./pkg .PHONY: mod mod: diff --git a/cmd/config/main.go b/cmd/config/main.go index ae11489..7a8e3ca 100644 --- a/cmd/config/main.go +++ b/cmd/config/main.go @@ -4,9 +4,7 @@ import ( "fmt" "os" - "github.com/dmhdeveloper/config/command" - "github.com/dmhdeveloper/config/configs" - "github.com/dmhdeveloper/config/logger" + "github.com/dmhdeveloper/config/pkg/cli" ) var ( @@ -15,29 +13,11 @@ var ( Version string ) -var log = logger.FmtLogger{} - func main() { if len(os.Args) == 1 { - log.Println(fmt.Sprint("Config version: ", Version, ", Build time: ", BuildTime, ", Git hash: ", GitHash)) + fmt.Println(fmt.Sprint("Config version: ", Version, ", Build time: ", BuildTime, ", Git hash: ", GitHash)) os.Exit(0) } - conf, err := configs.LoadConfig() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - switch os.Args[1] { - case "init": - command := command.NewInitCmd(log) - os.Exit(command.Run(os.Args[2:]...)) - case "-h": - helpMessage := command.RunHelp(command.InitCmd{}.Help, command.GitCmd{}.Help) - log.Println(helpMessage) - default: - command := command.NewGitCmd(conf.GitDir, conf.WorkTree, os.Stdout) - os.Exit(command.Run(os.Args[1:]...)) - } + os.Exit(cli.RunConfig(os.Args)) } diff --git a/command/command.go b/command/command.go deleted file mode 100644 index 19782ef..0000000 --- a/command/command.go +++ /dev/null @@ -1,23 +0,0 @@ -package command - -import "fmt" - -const ( - defaultHelpMessage = `usage: config -h - - Display this help message. -` -) - -type Command interface { - Run(args ...string) int - Help() string -} - -func RunHelp(help ...func() string) string { - var helpMessage string - for _, f := range help { - helpMessage = fmt.Sprint(helpMessage, "\n", f()) - } - return fmt.Sprint(defaultHelpMessage, helpMessage) -} diff --git a/command/git.go b/command/git.go deleted file mode 100644 index cbd0bfd..0000000 --- a/command/git.go +++ /dev/null @@ -1,71 +0,0 @@ -package command - -import ( - "bytes" - "fmt" - "io" - "os" - "os/exec" - "strings" -) - -type GitCmd struct { - gitDir string - workTree string - writer io.Writer -} - -func NewGitCmd( - gitDir string, - workTree string, - writer io.Writer, -) GitCmd { - return GitCmd{ - gitDir: gitDir, - workTree: workTree, - writer: writer, - } -} - -func (g GitCmd) Run(args ...string) int { - defaults := []string{"--git-dir", g.gitDir, "--work-tree", g.workTree} - defaults = append(defaults, args...) - cmd := exec.Command("git", defaults...) - cmd.Stdout = g.writer - cmd.Stdin = os.Stdin - cmd.Stderr = os.Stderr - - err := cmd.Start() - if err != nil { - return err.(*exec.ExitError).ExitCode() - } - - err = cmd.Wait() - if err != nil { - return err.(*exec.ExitError).ExitCode() - } - return 0 -} - -func (g GitCmd) Help() string { - buf := bytes.NewBuffer(make([]byte, 0)) - cmd := exec.Command("git", "-h") - cmd.Stdout = buf - - err := cmd.Start() - if err != nil { - return err.Error() - } - - err = cmd.Wait() - if err != nil { - return err.Error() - } - return fmt.Sprint( - "This is a git wrapper, besides the list of commands above, all other flags are treated as git flags and passed to git.", - "\n", - "For git commands, see below: ", - "\n\n", - strings.Replace(buf.String(), "[-h | --help]", "--help", 1), - ) -} diff --git a/command/init.go b/command/init.go deleted file mode 100644 index 14cefaf..0000000 --- a/command/init.go +++ /dev/null @@ -1,128 +0,0 @@ -package command - -import ( - "bytes" - "flag" - "fmt" - "io" - "os" - "os/exec" - "strings" - - "github.com/dmhdeveloper/config/configs" - "github.com/dmhdeveloper/config/logger" -) - -var ( - url string - gitDir string - workTree string - sshKey string - debug bool -) - -type InitCmd struct { - log logger.Logger - flags *flag.FlagSet -} - -func NewInitCmd(log logger.Logger) InitCmd { - flags := createInitFlags() - return InitCmd{ - log: log, - flags: flags, - } -} - -func createInitFlags() *flag.FlagSet { - flags := flag.NewFlagSet("init", flag.ExitOnError) - flags.StringVar(&url, "url", "", "The git remote repository URL that stores your system configuration files.") - flags.StringVar(&gitDir, "git.dir", "~/.dotfiles", "The git bare directory location.") - flags.StringVar(&workTree, "work.tree", "~/", "All system config files should be discoverable within this root directory.") - flags.StringVar(&sshKey, "ssh.key", "~/.ssh/id_rsa", "The ssh key used to interact with your git repository storing your configuration files.") - flags.BoolVar(&debug, "debug", false, "Output any errors in full during initialisation.") - return flags -} - -func (i InitCmd) Run(args ...string) int { - err := i.flags.Parse(args) - if err != nil { - if debug { - i.log.Println(err) - } - return 1 - } - - conf := configs.CLIConfig{ - GitDir: gitDir, - WorkTree: workTree, - } - _, err = configs.UpdateConfig(conf) - if err != nil { - if debug { - i.log.Println(err) - } - return 1 - } - if err := runGit(os.Stdout, "init", "--bare", gitDir); err != nil { - if debug { - i.log.Println(err) - } - return 1 - } - - buf := bytes.NewBuffer(make([]byte, 0)) - if err := runGit(buf, "--git-dir", gitDir, "remote", "show"); err != nil { - if debug { - i.log.Println(err) - } - return 1 - } - - // We are re-initialising the repo, the origin might already be set - if strings.TrimSpace(buf.String()) != "origin" { - if err := runGit(os.Stdout, "--git-dir", gitDir, "remote", "add", "origin", url); err != nil { - if debug { - i.log.Println(err) - } - return 1 - } - } else { - if err := runGit(os.Stdout, "--git-dir", gitDir, "remote", "set-url", "origin", url); err != nil { - if debug { - i.log.Println(err) - } - return 1 - } - } - - if err := runGit(os.Stdout, "--git-dir", gitDir, "config", "--local", "status.showUntrackedFiles", "no"); err != nil { - if debug { - i.log.Println(err) - } - return 1 - } - if err := runGit(os.Stdout, "--git-dir", gitDir, "config", "--local", "core.sshCommand", fmt.Sprintf("ssh -i %s", sshKey)); err != nil { - if debug { - i.log.Println(err) - } - return 1 - } - return 0 -} - -func (i InitCmd) Help() string { - flags := createInitFlags() - buf := bytes.NewBuffer(make([]byte, 0)) - flags.SetOutput(buf) - flags.PrintDefaults() - return fmt.Sprint("usage: config init ", "\n\n", buf.String()) -} - -func runGit(out io.Writer, args ...string) error { - cmd := exec.Command("git", args...) - cmd.Stdout = out - cmd.Stderr = os.Stderr - cmd.Stdin = os.Stdin - return cmd.Run() -} diff --git a/logger/logger.go b/logger/logger.go deleted file mode 100644 index 6d6c25d..0000000 --- a/logger/logger.go +++ /dev/null @@ -1,13 +0,0 @@ -package logger - -import "fmt" - -type Logger interface { - Println(v ...any) -} - -type FmtLogger struct{} - -func (f FmtLogger) Println(v ...any) { - fmt.Println(v...) -} diff --git a/pkg/cli/cli.go b/pkg/cli/cli.go new file mode 100644 index 0000000..2887122 --- /dev/null +++ b/pkg/cli/cli.go @@ -0,0 +1,34 @@ +package cli + +import ( + "fmt" + + "github.com/dmhdeveloper/config/pkg/command" +) + +const helpMessage = "" + +func RunConfig( + args []string, +) int { + // No arguments passed, return help message + if len(args) == 0 { + fmt.Println(helpMessage) + return 0 + } + + switch args[1] { + case "help", "-h", "--help": + fmt.Println(helpMessage) + case "init": + return command.RunInit(args[2:]) + case "git": + return command.RunGit(args[2:]) + default: + fmt.Printf("Uknown command: %s\n\n", args[1]) + fmt.Println(helpMessage) + } + + // No error + return 0 +} diff --git a/pkg/command/git.go b/pkg/command/git.go new file mode 100644 index 0000000..7880edb --- /dev/null +++ b/pkg/command/git.go @@ -0,0 +1,40 @@ +package command + +import ( + "fmt" + "os" + "os/exec" + + "github.com/dmhdeveloper/config/pkg/configs" +) + +func RunGit( + args []string, +) int { + conf, err := configs.LoadGitConfig() + if err != nil { + fmt.Println(err) + return 1 + } + + defaults := []string{"--git-dir", conf.GitDir, "--work-tree", conf.WorkTree} + defaults = append(defaults, args...) + cmd := exec.Command("git", defaults...) + cmd.Stdout = os.Stdout + cmd.Stdin = os.Stdin + cmd.Stderr = os.Stderr + + err = cmd.Start() + if err != nil { + fmt.Println(err) + return 1 + } + + err = cmd.Wait() + if err != nil { + fmt.Println(err) + return 1 + } + + return 0 +} diff --git a/pkg/command/init.go b/pkg/command/init.go new file mode 100644 index 0000000..eb41ab5 --- /dev/null +++ b/pkg/command/init.go @@ -0,0 +1,87 @@ +package command + +import ( + "bytes" + "flag" + "fmt" + "io" + "os" + "os/exec" + "strings" + + "github.com/dmhdeveloper/config/pkg/configs" +) + +func RunInit( + args []string, +) int { + var ( + url string + gitDir string + workTree string + sshKey string + ) + + flags := flag.NewFlagSet("init", flag.ExitOnError) + flags.StringVar(&url, "url", "", "(Required) The git remote repository URL that stores your system configuration files.") + flags.StringVar(&gitDir, "git.dir", "(Required) ~/.dotfiles", "The git bare directory location.") + flags.StringVar(&workTree, "work.tree", "~/", "(Required) All system config files should be discoverable within this root directory.") + flags.StringVar(&sshKey, "ssh.key", "~/.ssh/id_rsa", "(Required) The ssh key used to interact with your git repository storing your configuration files.") + + err := flags.Parse(args) + if err != nil { + fmt.Println(err) + return 1 + } + + conf := configs.Git{ + GitDir: gitDir, + WorkTree: workTree, + } + _, err = configs.UpdateGitConfig(conf) + if err != nil { + fmt.Println(err) + return 1 + } + if err := runGit(os.Stdout, "init", "--bare", gitDir); err != nil { + fmt.Println(err) + return 1 + } + + buf := bytes.NewBuffer(make([]byte, 0)) + if err := runGit(buf, "--git-dir", gitDir, "remote", "show"); err != nil { + fmt.Println(err) + return 1 + } + + // We are re-initialising the repo, the origin might already be set + if strings.TrimSpace(buf.String()) != "origin" { + if err := runGit(os.Stdout, "--git-dir", gitDir, "remote", "add", "origin", url); err != nil { + fmt.Println(err) + return 1 + } + } else { + if err := runGit(os.Stdout, "--git-dir", gitDir, "remote", "set-url", "origin", url); err != nil { + fmt.Println(err) + return 1 + } + } + + if err := runGit(os.Stdout, "--git-dir", gitDir, "config", "--local", "status.showUntrackedFiles", "no"); err != nil { + fmt.Println(err) + return 1 + } + if err := runGit(os.Stdout, "--git-dir", gitDir, "config", "--local", "core.sshCommand", fmt.Sprintf("ssh -i %s", sshKey)); err != nil { + fmt.Println(err) + return 1 + } + return 0 +} + +func runGit(out io.Writer, args ...string) error { + cmd := exec.Command("git", args...) + cmd.Stdout = out + cmd.Stderr = os.Stderr + cmd.Stdin = os.Stdin + return cmd.Run() +} diff --git a/pkg/configs/config.go b/pkg/configs/config.go new file mode 100644 index 0000000..ac76ccd --- /dev/null +++ b/pkg/configs/config.go @@ -0,0 +1,36 @@ +package configs + +import ( + "io" + "os" + + "gopkg.in/yaml.v3" +) + +func read(filepath string, v interface{}) error { + fi, err := os.Open(filepath) + if err != nil { + return err + } + + contents, err := io.ReadAll(fi) + if err != nil { + return err + } + + err = yaml.Unmarshal(contents, v) + if err != nil { + return err + } + + return nil +} + +func write(filepath string, v interface{}) error { + content, err := yaml.Marshal(v) + if err != nil { + return err + } + + return os.WriteFile(filepath, content, 0644) +} diff --git a/configs/config.go b/pkg/configs/git.go similarity index 57% rename from configs/config.go rename to pkg/configs/git.go index 01288b9..9c1e60e 100644 --- a/configs/config.go +++ b/pkg/configs/git.go @@ -2,12 +2,9 @@ package configs import ( "fmt" - "io" "os" "os/user" "strings" - - "gopkg.in/yaml.v3" ) const ( @@ -15,13 +12,13 @@ const ( gitConfigFile = "git.yaml" ) -type CLIConfig struct { +type Git struct { GitDir string `yaml:"gitDir"` WorkTree string `yaml:"workTree"` } -func LoadConfig() (CLIConfig, error) { - var conf CLIConfig +func LoadGitConfig() (Git, error) { + var conf Git usr, err := user.Current() if err != nil { return conf, err @@ -35,47 +32,23 @@ func LoadConfig() (CLIConfig, error) { return conf, err } - fi, err := os.Create(fullPath) + _, err := os.Create(fullPath) if err != nil { return conf, err } - contents, err := yaml.Marshal(conf) + err = write(fullPath, &conf) if err != nil { return conf, err } - - _, err = fi.Write(contents) - if err != nil { - return conf, err - } - - err = fi.Close() - if err != nil { - return conf, err - } - } - - fi, err := os.Open(fullPath) - if err != nil { - return conf, err } - contents, err := io.ReadAll(fi) - if err != nil { - return conf, err - } - - err = yaml.Unmarshal(contents, &conf) - if err != nil { - return conf, err - } - - return conf, nil + err = read(fullPath, &conf) + return conf, err } -func UpdateConfig(conf CLIConfig) (CLIConfig, error) { - current, err := LoadConfig() +func UpdateGitConfig(conf Git) (Git, error) { + current, err := LoadGitConfig() if err != nil { return conf, err } @@ -88,17 +61,12 @@ func UpdateConfig(conf CLIConfig) (CLIConfig, error) { current.WorkTree = conf.WorkTree } - content, err := yaml.Marshal(current) - if err != nil { - return conf, err - } - usr, err := user.Current() if err != nil { return conf, err } fullPath := fmt.Sprint(usr.HomeDir, "/", configDir, "/", gitConfigFile) - err = os.WriteFile(fullPath, content, 0644) + err = write(fullPath, ¤t) return current, err }