From dcedeb6034dbe88974528f5b72f2ad39ce6a0e8e Mon Sep 17 00:00:00 2001 From: Flawid DSouza Date: Sat, 13 Aug 2022 17:52:27 +0530 Subject: [PATCH] Into Git --- .editorconfig | 15 +++++ .gitignore | 2 + .goreleaser.yaml | 29 ++++++++ .tool-versions | 1 + README.md | 27 ++++++++ go.mod | 5 ++ go.sum | 4 ++ main.go | 136 ++++++++++++++++++++++++++++++++++++++ shortcommands-example.yml | 38 +++++++++++ 9 files changed, 257 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .goreleaser.yaml create mode 100644 .tool-versions create mode 100644 README.md create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 shortcommands-example.yml diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..2b04dad --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.go] +indent_style = tab + +[*.yml] +indent_size = 2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..224f6c1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +vendor/ +dist/ diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..e1eccd9 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,29 @@ +project_name: shortcommand +before: + hooks: + - go mod tidy + - go generate ./... +builds: + - env: + - CGO_ENABLED=0 + goos: + - linux + # - windows + - darwin +archives: + - replacements: + darwin: Darwin + linux: Linux + windows: Windows + 386: i386 + amd64: x86_64 +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ incpatch .Version }}-next" +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..1799f52 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +golang 1.19 diff --git a/README.md b/README.md new file mode 100644 index 0000000..79da335 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +## Testing +```bash +SHORTCOMMAND_CONFIG=shortcommands-example.yml go run . Test test +SHORTCOMMAND_CONFIG=shortcommands-example.yml go run . Test test2 +SHORTCOMMAND_CONFIG=shortcommands-example.yml go run . Test test3 +``` + +## Build Testing +```bash +goreleaser build --snapshot --rm-dist +``` + +## Build for release +```bash +go tag vX.X.X +git push origin vX.X.X +goreleaser release --rm-dist +``` + +## Installing on Linux (tested on Ubuntu) +```bash +wget https://github.com/flawiddsouza/shortcommand/releases/download/v0.0.1/shortcommand_0.0.1_Linux_x86_64.tar.gz +tar -xf shortcommand_0.0.1_Linux_x86_64.tar.gz +mv shortcommand ~/.local/bin +rm shortcommand_0.0.1_Linux_x86_64.tar.gz +``` +You should then be able to use the `shortcommand` command anywhere you are. diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7eea7bc --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/flawiddsouza/shortcommand + +go 1.19 + +require gopkg.in/yaml.v2 v2.4.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..dd0bc19 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/main.go b/main.go new file mode 100644 index 0000000..e976f09 --- /dev/null +++ b/main.go @@ -0,0 +1,136 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "os/exec" + "strings" + + "gopkg.in/yaml.v2" +) + +type Config struct { + ShortCommands []ShortCommand `yaml:"shortcommands"` +} + +type ShortCommand struct { + Name string `yaml:"name"` + Commands []Command `yaml:"commands"` +} + +type Command struct { + Name string `yaml:"name"` + Description string `yaml:"description"` + CurrentWorkingDirectory string `yaml:"cwd"` + Do []string `yaml:"do"` +} + +func fileExists(path string) bool { + _, err := os.Stat(path) + + if err == nil { + return true + } + + if os.IsNotExist(err) { + return false + } + + return false +} + +func executeCommand(commandToRun string, currentWorkingDirectory string) error { + colorReset := "\033[0m" + colorRed := "\033[31m" + colorGreen := "\033[32m" + + cmd := exec.Command("sh", "-c", commandToRun) + if currentWorkingDirectory != "" { + currentWorkingDirectoryResolved := os.ExpandEnv(currentWorkingDirectory) + if strings.HasPrefix(currentWorkingDirectoryResolved, "~") { + home, _ := os.UserHomeDir() + currentWorkingDirectoryResolved = home + currentWorkingDirectoryResolved[1:] + } + if !fileExists(currentWorkingDirectoryResolved) { + fmt.Printf("%sUnable to find given working directory: %s%s\n", colorRed, currentWorkingDirectory, colorReset) + } + cmd.Dir = currentWorkingDirectoryResolved + } + + cmdReader, _ := cmd.StdoutPipe() + + scanner := bufio.NewScanner(cmdReader) + go func() { + for scanner.Scan() { + fmt.Printf("%s--> %s\n%s", colorGreen, scanner.Text(), colorReset) + } + }() + + cmdReader2, _ := cmd.StderrPipe() + + scanner2 := bufio.NewScanner(cmdReader2) + go func() { + for scanner2.Scan() { + fmt.Printf("%s--> %s\n%s", colorRed, scanner2.Text(), colorReset) + } + }() + + cmd.Start() + + return cmd.Wait() +} + +func main() { + shortcommandPath := os.Getenv("SHORTCOMMAND_CONFIG") + + if shortcommandPath == "" { + fmt.Println("SHORTCOMMAND_CONFIG env not found or empty") + return + } + + yamlFile, err := os.ReadFile(shortcommandPath) + + if err != nil { + fmt.Println("Unable to find file specified in SHORTCOMMAND_CONFIG: ", shortcommandPath) + return + } + + if len(os.Args) < 3 { + fmt.Println("Two arguments need to passed to the command, first is your shortcommand and then the command under it") + return + } + + var parsedConfig Config + + err = yaml.Unmarshal(yamlFile, &parsedConfig) + if err != nil { + fmt.Println("Invalid config file given") + return + } + + for _, shortCommand := range parsedConfig.ShortCommands { + if shortCommand.Name == os.Args[1] { + for _, command := range shortCommand.Commands { + if command.Name == os.Args[2] { + fmt.Println(shortCommand.Name, ">", command.Name, ":", command.Description) + for i, commandToRun := range command.Do { + fmt.Println(">", commandToRun) + err = executeCommand(commandToRun, command.CurrentWorkingDirectory) + if err != nil { + if i < len(command.Do)-1 { + fmt.Println("Not continuing with the next command in do sequence as previous command errored out") + return + } + } + } + fmt.Println() + return + } + } + break + } + } + + fmt.Println("No matching command found for given arguments") +} diff --git a/shortcommands-example.yml b/shortcommands-example.yml new file mode 100644 index 0000000..911733e --- /dev/null +++ b/shortcommands-example.yml @@ -0,0 +1,38 @@ +shortcommands: + - name: Test + commands: + - name: test + description: This will fail midway through the do sequence + do: + - ls ~ + - rm ~/test-acat.txt + - ls ~ + - name: test2 + description: This will not fail and will execute all steps correctly + do: + - ls ~ + - echo "Test" > ~/test-cat.txt + - ls ~ + - cat ~/test-cat.txt + - rm ~/test-cat.txt + - ls ~ + - name: test3 + description: This will create a test file in the current directory and then remove it + cwd: . + do: + - ls + - echo "Test" > test-cat.txt + - ls + - cat test-cat.txt + - rm test-cat.txt + - ls + - name: test4 + description: This will create a test file in the home directory of the user and then remove it + cwd: "~" + do: + - ls + - echo "Test" > test-cat.txt + - ls + - cat test-cat.txt + - rm test-cat.txt + - ls