├── CNAME ├── debian ├── compat ├── source │ └── format ├── gbp.conf ├── rules ├── changelog ├── watch ├── copyright └── control ├── examples └── example.gsh ├── CODEOWNERS ├── renovate.json ├── .github ├── images │ └── example.png ├── ISSUE_TEMPLATE │ ├── features.md │ └── bug_report.md ├── workflows │ ├── dockerbuild.yml │ ├── dockerimage.yml │ └── homebrew.yml ├── CONTRIBUTING.md └── CODE-OF-CONDUCT.md ├── tools ├── setup.sh ├── stats.txt ├── setup2.0.bash └── install ├── internal ├── email.go ├── environment.go ├── touch.go ├── mkdir.go ├── executeCommand.go ├── help.go ├── pipe.go ├── history.go ├── prompt.go ├── errors.go ├── complete.go ├── ls.go └── shell.go ├── Makefile ├── Dockerfile ├── .gitpod.Dockerfile ├── .gitignore ├── pkg └── utils.go ├── go.mod ├── .cirrus.yml ├── .gitpod.yml ├── test └── command_test.go ├── LICENSE ├── main.go ├── README.md └── go.sum /CNAME: -------------------------------------------------------------------------------- 1 | hellum.dev 2 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 11 2 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /examples/example.gsh: -------------------------------------------------------------------------------- 1 | l 2 | s; 3 | ps 4 | -------------------------------------------------------------------------------- /debian/gbp.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | pristine-tar = True 3 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @JesterOrNot @thecla1 2 | .cirrus.yml @RDIL 3 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.github/images/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosh-terminal/gosh/HEAD/.github/images/example.png -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/features.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | 8 | -------------------------------------------------------------------------------- /tools/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd src 3 | go get -v -t -d ./... 4 | go build -o gosh *.go 5 | touch "$GOPATH"/bin/history.txt 6 | cp gosh "$GOPATH"/bin 7 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | override_dh_auto_install: 4 | dh_auto_install -- --no-source 5 | 6 | %: 7 | dh $@ --buildsystem=golang --with=golang 8 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | gosh (0.021-alpha+git20191218.4893d3e-1) UNRELEASED; urgency=medium 2 | 3 | * Initial release 4 | -- Sean Hellum Wed, 18 Dec 2019 18:22:00 +0200 5 | -------------------------------------------------------------------------------- /internal/email.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | // SignIn sign in to your email 4 | func SignIn() { 5 | // WIP 6 | } 7 | 8 | // Send send email 9 | func Send(to, from, message string) { 10 | // WIP 11 | } 12 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | go build -o gosh main.go 3 | .PHONY: build 4 | 5 | run: 6 | ./gosh 7 | .PHONY: run 8 | 9 | test: 10 | go test gosh/test 11 | .PHONY: test 12 | 13 | clean: 14 | rm gosh 15 | .PHONY: clean 16 | -------------------------------------------------------------------------------- /debian/watch: -------------------------------------------------------------------------------- 1 | version=4 2 | opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/gosh-\$1\.tar\.gz/,\ 3 | uversionmangle=s/(\d)[_\.\-\+]?(RC|rc|pre|dev|beta|alpha)[.]?(\d*)$/\$1~\$2\$3/ \ 4 | https://github.com/gosh-terminal/gosh/tags .*/v?(\d\S*)\.tar\.gz 5 | -------------------------------------------------------------------------------- /internal/environment.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | util "gosh/pkg" 5 | ) 6 | 7 | func validateBooleanVariable(b string) bool { 8 | yesOpts := [3]string{"yes", "1", "true"} 9 | 10 | return util.ItemExists(yesOpts, b) 11 | } 12 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:stretch@sha256:3205a5663200801ed336b619c4386f4afaeb6f6f2e72b94da17296a6907e49e8 AS build 2 | WORKDIR / 3 | RUN git clone "https://github.com/gosh-terminal/gosh.git" /app 4 | WORKDIR /app 5 | RUN go build -o gosh main.go 6 | FROM debian:jessie-slim 7 | COPY --from=build /app/gosh /bin 8 | -------------------------------------------------------------------------------- /.gitpod.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gitpod/workspace-full@sha256:881c732a9b82a99725620e9b5154620bbb7c0683e3cd9e21fbe246c14d2c4b67 2 | USER root 3 | ENV DEBIAN_FRONTEND noninteractive 4 | RUN apt-get update \ 5 | && apt-get install -y \ 6 | dh-make-golang --no-install-recommends \ 7 | && rm -rf /var/lib/apt/lists/* 8 | -------------------------------------------------------------------------------- /.github/workflows/dockerbuild.yml: -------------------------------------------------------------------------------- 1 | name: Docker Build CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | 7 | build: 8 | 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v1 13 | - name: Build the Docker image 14 | run: docker build . --file Dockerfile --tag gosh-terminal/gosh/gosh 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | *.txt 14 | !tools/stats.txt 15 | bin/* 16 | #*/src/commands/history.txt 17 | src/gosh 18 | -------------------------------------------------------------------------------- /pkg/utils.go: -------------------------------------------------------------------------------- 1 | package pkg 2 | 3 | import ( 4 | "reflect" 5 | ) 6 | 7 | // ItemExists Check if item exists in array 8 | func ItemExists(arrayType interface{}, item interface{}) bool { 9 | arr := reflect.ValueOf(arrayType) 10 | 11 | for i := 0; i < arr.Len(); i++ { 12 | if arr.Index(i).Interface() == item { 13 | return true 14 | } 15 | } 16 | 17 | return false 18 | } 19 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: gosh 3 | Source: https://github.com/gosh-terminal/gosh 4 | Files-Excluded: 5 | Godeps/_workspace 6 | 7 | Files: * 8 | Copyright: 2019 gosh 9 | License: MIT 10 | 11 | Files: debian/* 12 | Copyright: 2019 Wednsday 13 | License: MIT 14 | Comment: Debian packaging is licensed under the same terms as upstream 15 | 16 | License: MIT 17 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module gosh 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/c-bata/go-prompt v0.2.3 7 | github.com/gizak/termui/v3 v3.1.0 8 | github.com/manifoldco/promptui v0.7.0 9 | github.com/mattn/go-isatty v0.0.12 10 | github.com/mattn/go-runewidth v0.0.7 // indirect 11 | github.com/mattn/go-tty v0.0.3 // indirect 12 | github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 // indirect 13 | golang.org/x/crypto v0.0.0-20200420104511-884d27f42877 14 | gopkg.in/src-d/go-git.v4 v4.13.1 15 | ) 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | 9 | 10 | **To Reproduce** 11 | 12 | 13 | **Expected behavior** 14 | 15 | 16 | **Additional Information** 17 | 18 | -------------------------------------------------------------------------------- /.cirrus.yml: -------------------------------------------------------------------------------- 1 | task: 2 | matrix: 3 | - name: CI - Go@1.12 4 | container: 5 | image: golang:1.12-buster 6 | - name: CI - Go@1.13 7 | container: 8 | image: golang:1.13 9 | env: 10 | GOPROXY: https://proxy.golang.org 11 | populate_dependencies_script: | 12 | go get -v -t -d ./... 13 | build_script: | 14 | go build -o gosh *.go 15 | touch ${GOPATH}/bin/history.txt 16 | mv gosh ${GOPATH}/bin 17 | 18 | docker_builder: 19 | name: Docker Build 20 | build_script: | 21 | docker build --tag gosh:latest . 22 | -------------------------------------------------------------------------------- /internal/touch.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strings" 7 | ) 8 | 9 | // Touch Create File 10 | func Touch(filename string) { 11 | filenames := strings.Split(filename, " ") 12 | if len(filenames) <= 1 { 13 | InvalidNumberOfArgs(filename) 14 | return 15 | } 16 | for i := 1; i < len(filenames); i++ { 17 | os.Create(filenames[i]) 18 | } 19 | if len(filenames) >= 3 { 20 | fmt.Println("\033[0;33mThe files have been created! ✔\033[0m") 21 | } else { 22 | fmt.Println("\033[0;33m"+filenames[1], "has been created! ✔\033[0m") 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.github/workflows/dockerimage.yml: -------------------------------------------------------------------------------- 1 | name: Build Nightly Docker Image 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * *" 6 | 7 | jobs: 8 | 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v1 15 | - name: Publish Docker 16 | uses: elgohr/Publish-Docker-Github-Action@2.11 17 | with: 18 | name: gosh-terminal/gosh/gosh 19 | username: ${{ secrets.DOCKER_USERNAME }} 20 | password: ${{ secrets.DOCKER_PASSWORD }} 21 | registry: docker.pkg.github.com 22 | dockerfile: Dockerfile 23 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | image: 2 | file: .gitpod.Dockerfile 3 | tasks: 4 | - init: go install && export GOSH_HOME=/workspace/go/bin 5 | command: gosh 6 | vscode: 7 | extensions: 8 | - DavidAnson.vscode-markdownlint@0.32.0:gujQ1foJzJ2yxCOgDqFfXw== 9 | - mdickin.markdown-shortcuts@0.12.0:h8L11R6NpkgnCtbr8QLlUw== 10 | - timonwong.shellcheck@0.8.1:16BMw7Jrwd/KkAhJrkHwqQ== 11 | - premparihar.gotestexplorer@0.1.10:jvUM8akrQ67vQxfjaxCgCg== 12 | github: 13 | prebuilds: 14 | addBadge: true 15 | branches: true 16 | pullRequestsFromForks: true 17 | addLabel: prebuilt 18 | -------------------------------------------------------------------------------- /internal/mkdir.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strings" 7 | ) 8 | 9 | // Mkdir create directory 10 | func Mkdir(dirnames string) { 11 | dirname := strings.Split(dirnames, " ") 12 | if len(dirname) <= 1 { 13 | InvalidNumberOfArgs(dirnames) 14 | return 15 | } 16 | for i := 1; i < len(dirname); i++ { 17 | os.Mkdir(dirname[i], 0655) 18 | } 19 | if len(dirname) >= 3 { 20 | fmt.Println("\033[0;33mThe directories have been created! ✔\033[0m") 21 | } else { 22 | fmt.Println("\033[0;33mDirectory", dirname[1], "has been created! ✔\033[0m") 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /internal/executeCommand.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "os" 5 | "os/exec" 6 | "strings" 7 | ) 8 | 9 | // ExecuteCommand executes a command string 10 | func ExecuteCommand(theCommand string) error { 11 | args := strings.Split(theCommand, " ") 12 | cmd := exec.Command(args[0], args[1:]...) 13 | cmd.Stdout = os.Stdout 14 | cmd.Stderr = os.Stderr 15 | cmd.Stdin = os.Stdin 16 | return cmd.Run() 17 | } 18 | 19 | // GetArg Get argument from commandString 20 | func GetArg(commandString string) string { 21 | var s []string = strings.Split(commandString, " ") 22 | if len(s) >= 1 { 23 | return s[1] 24 | } 25 | return "error" 26 | } 27 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Welcome to gosh! 2 | 3 | For speedy contributions open it in Gitpod, gosh will be pre-installed with the 4 | latest build in a VSCode like editor all from your browser. 5 | 6 | [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/JesterOrNot/gosh) 7 | 8 | File an issue or request more features here on 9 | [GitHub](https://github.com/JesterOrNot/gosh/issues/new/choose)! 10 | 11 | **Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 12 | -------------------------------------------------------------------------------- /.github/workflows/homebrew.yml: -------------------------------------------------------------------------------- 1 | name: Homebrew CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | - name: Install Homebrew 13 | run: | 14 | sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)" 15 | test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv) 16 | test -d /home/linuxbrew/.linuxbrew && eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv) 17 | test -r ~/.bash_profile && echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.bash_profile 18 | echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile 19 | brew tap gosh-terminal/homebrew-gosh 20 | brew install gosh-terminal/homebrew-gosh/gosh 21 | -------------------------------------------------------------------------------- /tools/stats.txt: -------------------------------------------------------------------------------- 1 | Go based dependencies --: 2 | github.com/c-bata/go-prompt --: 3 | files that depend on it --: 4 | * internal/shell.go 5 | * internal/complete.go 6 | why we use it --: 7 | * Auto-Completion 8 | * Key Listeners 9 | github.com/manifoldco/promptui --: 10 | files that depend on it --: 11 | * internal/prompt.go 12 | why we use it --: 13 | * The one confirmation thing 14 | github.com/internal-d/go-git --: 15 | files that depend on it --: 16 | * internal/prompt.go 17 | why we use it --: 18 | * git operations 19 | github.com/gizak/termui/v3 --: 20 | files that depend on it --: 21 | * internal/ls.go 22 | why we use it --: 23 | * tui stuff 24 | 25 | As of Friday January 10th 2020 there are 685 lines of code 26 | -------------------------------------------------------------------------------- /internal/help.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // Help the help function 8 | func Help() { 9 | fmt.Println(" \033[0;32m# command description\033[0m") 10 | fmt.Println(" ╭━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╮") 11 | fmt.Println(" │ \033[0;32m1\033[0m │ exit │ exits gosh │") 12 | fmt.Println(" │ \033[0;32m2\033[0m │ history │ displays commands you have previously run │") 13 | fmt.Println(" │ \033[0;32m3\033[0m │ clearhist │ clears your command history │") 14 | fmt.Println(" │ \033[0;32m4\033[0m │ tree │ shows files as tree view │") 15 | fmt.Println(" │ \033[0;32m5\033[0m │ touch │ creates an new file │") 16 | fmt.Println(" │ \033[0;32m6\033[0m │ mkdir │ creates an new directory │") 17 | fmt.Println(" ╰━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╯") 18 | } 19 | -------------------------------------------------------------------------------- /test/command_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "fmt" 5 | shell "gosh/internal" 6 | "testing" 7 | ) 8 | 9 | func TestGetArg(t *testing.T) { 10 | gotArray := []string{shell.GetArg("ls data"), shell.GetArg("cd ")} 11 | wantArray := []string{"data", ""} 12 | if gotArray[0] != wantArray[0] { 13 | t.Errorf("got %q want %q", gotArray[0], wantArray[0]) 14 | } 15 | if gotArray[1] != wantArray[1] { 16 | t.Errorf("got %q want %q", gotArray[1], wantArray[1]) 17 | } 18 | fmt.Println("Passed") 19 | } 20 | 21 | func TestSplitCommand(t *testing.T) { 22 | got := shell.ClearHistory() 23 | want := "History has been cleared ✔\n" 24 | if got != want { 25 | t.Errorf("got %q want %q", got, want) 26 | } 27 | fmt.Println("Passed") 28 | } 29 | 30 | func testCaptureOutput(t *testing.T) { 31 | got, err := shell.CaptureOutput("cat ci/data") 32 | want := "test\n" 33 | if err != nil { 34 | t.Errorf("got %q want %q", got, want) 35 | } 36 | if string(got) != want { 37 | t.Errorf("got %q want %q", got, want) 38 | } 39 | fmt.Println("Passed") 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-present Sean Hellum & the gosh team 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "golang.org/x/crypto/ssh/terminal" 7 | shell "gosh/internal" 8 | util "gosh/pkg" 9 | "io/ioutil" 10 | "os" 11 | "regexp" 12 | "strings" 13 | ) 14 | 15 | func init() { 16 | if os.Getenv("GOSH_HOME") == "" { 17 | os.Setenv("GOSH_HOME", os.Getenv("HOME")) 18 | } 19 | } 20 | 21 | func main() { 22 | quiet := false 23 | 24 | if util.ItemExists(os.Args, "-q") || util.ItemExists(os.Args, "--quiet") { 25 | quiet = true 26 | } 27 | 28 | if util.ItemExists(os.Args, "-v") { 29 | fmt.Println("gosh v0.06-alpha") 30 | } else if util.ItemExists(os.Args, "-c") { 31 | if len(os.Args) >= 3 { 32 | shell.Evaluate(os.Args[2]) 33 | } else { 34 | shell.InvalidNumberOfArgs(os.Args[1]) 35 | } 36 | } else if util.ItemExists(os.Args, "run") { 37 | f, _ := ioutil.ReadFile(os.Args[2]) 38 | f1 := string(f) 39 | f1 = strings.ReplaceAll(f1, "\n", "") 40 | content := strings.Split(string(f1), ";") 41 | for _, i := range content { 42 | isMatch, _ := regexp.MatchString(" *", i) 43 | if len(i) == 0 || !isMatch { 44 | continue 45 | } 46 | shell.Evaluate(i) 47 | } 48 | } else { 49 | if terminal.IsTerminal(int(os.Stdin.Fd())) { 50 | shell.Shell(quiet) 51 | } else { 52 | reader := bufio.NewReader(os.Stdin) 53 | text, _ := reader.ReadString('\n') 54 | shell.Evaluate(strings.Trim(text, "\n")) 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /internal/pipe.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "io/ioutil" 7 | "os" 8 | "os/exec" 9 | "strings" 10 | ) 11 | 12 | // RedirectToFile redorect the output of command to file 13 | func RedirectToFile(commandOneOut []byte, fileName string) { 14 | err := ioutil.WriteFile(fileName, commandOneOut, 0655) 15 | if err != nil { 16 | os.Create(fileName) 17 | RedirectToFile(commandOneOut, fileName) 18 | } 19 | } 20 | 21 | // CaptureOutput capture the output of one command 22 | func CaptureOutput(command string) ([]byte, error) { 23 | return exec.Command(command).Output() 24 | } 25 | 26 | // Pipe pipes output of one command to another 27 | func Pipe(from []byte, to string) error { 28 | cmd := exec.Command(to) 29 | 30 | buffer := bytes.Buffer{} 31 | buffer.Write(from) 32 | 33 | cmd.Stdout = os.Stdout 34 | cmd.Stdin = &buffer 35 | cmd.Stderr = os.Stderr 36 | 37 | err1 := cmd.Run() 38 | if err1 != nil { 39 | return err1 40 | } 41 | return nil 42 | } 43 | 44 | // SplitCommands split pipes by ` | ` 45 | func SplitCommands(command string) ([]string, error) { 46 | splitStr := strings.Split(command, " | ") 47 | if len(splitStr) == 2 && splitStr[1] != "" && len(strings.TrimSpace(splitStr[1])) != 0 { 48 | return splitStr, nil 49 | } 50 | return splitStr, errors.New("Must specify a file") 51 | } 52 | 53 | // SplitCommandFile split the command and file by ` > ` 54 | func SplitCommandFile(command string) ([]string, error) { 55 | splitStr := strings.Split(command, " > ") 56 | if len(splitStr) == 2 && splitStr[1] != "" && len(strings.TrimSpace(splitStr[1])) != 0 { 57 | return splitStr, nil 58 | } 59 | return splitStr, errors.New("Must specify a file") 60 | } 61 | -------------------------------------------------------------------------------- /internal/history.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "log" 7 | "os" 8 | "strconv" 9 | "strings" 10 | ) 11 | 12 | // ClearHistory clears the command history 13 | func ClearHistory() string { 14 | var gopath string = os.Getenv("GOSH_HOME") 15 | f, _ := os.OpenFile(gopath+"/history.txt", 16 | os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 17 | f.Truncate(0) 18 | fmt.Println("\033[0;32mHistory has been cleared ✔\033[0m") 19 | return "History has been cleared ✔\n" 20 | } 21 | 22 | // History the history command 23 | func History() { 24 | var gopath string = os.Getenv("GOSH_HOME") 25 | file, _ := os.Open(gopath + "/history.txt") 26 | scanner := bufio.NewScanner(file) 27 | var num = 1 28 | fmt.Println(" \033[0;32m# command\033[0m") 29 | fmt.Println(" ╭━━━━━━━━━━━━━━━━━━━╮") 30 | for scanner.Scan() { 31 | z := 14 - len(scanner.Text()) 32 | spaces := "" 33 | if z >= 0 { 34 | spaces = strings.Repeat(" ", z) 35 | } 36 | if strings.Compare(string(scanner.Text()), "") == 0 { 37 | continue 38 | } 39 | if num < 10 { 40 | fmt.Println(" │ \033[0;32m" + strconv.Itoa(num) + " \033[0m │ " + scanner.Text() + spaces + "│") 41 | } else { 42 | fmt.Println(" │ \033[0;32m" + strconv.Itoa(num) + " \033[0m│ " + scanner.Text() + spaces + "│") 43 | } 44 | num++ 45 | } 46 | fmt.Println(" ╰━━━━━━━━━━━━━━━━━━━╯") 47 | } 48 | 49 | // UpdateHistory update the command history 50 | func UpdateHistory(command string) { 51 | if validateBooleanVariable(os.Getenv("GOSH_NO_HISTORY")) { 52 | return 53 | } 54 | 55 | var gopath string = os.Getenv("GOSH_HOME") 56 | 57 | f, err := os.OpenFile( 58 | gopath + "/history.txt", 59 | os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 60 | 61 | if err != nil { 62 | log.Println(err) 63 | } 64 | 65 | defer f.Close() 66 | 67 | if _, err := f.WriteString("\n" + command); err != nil { 68 | log.Println(err) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: gosh 2 | Section: devel 3 | Priority: optional 4 | Maintainer: Debian Go Packaging Team 5 | Uploaders: JesterOrNot 6 | Build-Depends: debhelper (>= 11), 7 | dh-golang, 8 | golang-any, 9 | golang-github-c-bata-go-prompt-dev 10 | Standards-Version: 4.2.1 11 | Homepage: https://github.com/gosh-terminal/gosh 12 | Vcs-Browser: https://salsa.debian.org/go-team/packages/gosh 13 | Vcs-Git: https://salsa.debian.org/go-team/packages/gosh.git 14 | XS-Go-Import-Path: github.com/gosh-terminal/gosh 15 | Testsuite: autopkgtest-pkg-go 16 | 17 | Package: gosh 18 | Architecture: any 19 | Built-Using: ${misc:Built-Using} 20 | Depends: ${misc:Depends}, 21 | ${shlibs:Depends} 22 | Description: Do everything from the terminal 23 | gosh Codacy Badge 24 | (https://www.codacy.com/manual/seanhellum45/gosh?utm_source=github.com&utm_medium=referral&utm_content=gosh-terminal/gosh&utm_campaign=Badge_Grade) 25 | Setup Automated (https://gitpod.io/from-referrer/) Pull Requests Welcome 26 | (http://makeapullrequest.com) 27 | . 28 | Open in Gitpod (https://gitpod.io/#https://github.com/gosh-terminal/gosh) 29 | . 30 | The end goal of this project is to allow you to use your terminal for 31 | everything! Be able to do things from math, playing music, sending emails 32 | to searching the web but have these things be built into your terminal. 33 | Install dependencies bash sudo make install_deps 34 | . 35 | InstallBuild from sourceInstall with setup script bash git clone 36 | https://github.com/gosh-terminal/gosh.git cd gosh ./setup.sh 37 | . 38 | Install with Make bash git clone https://github.com/gosh-terminal/gosh.git 39 | cd gosh make install 40 | . 41 | One-line curl installer (Recommended) bash curl -s 42 | "https://raw.githubusercontent.com/gosh-terminal/gosh/master/tools/install" 43 | | sh 44 | . 45 | . 46 | Example of goshell 47 | -------------------------------------------------------------------------------- /internal/prompt.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | ui "github.com/manifoldco/promptui" 7 | git "gopkg.in/src-d/go-git.v4" 8 | "io/ioutil" 9 | "os" 10 | "regexp" 11 | "strings" 12 | ) 13 | 14 | // ThePrompt This function is for the main prompt of the shell 15 | func ThePrompt() { 16 | isGitRepo := false 17 | dir, _ := os.Getwd() 18 | r, err := git.PlainOpenWithOptions(".git", &git.PlainOpenOptions{DetectDotGit: true}) 19 | if err == nil { 20 | isGitRepo = true 21 | } else { 22 | fmt.Printf("\033[0;36m(" + dir + ") \033[0;32mgosh \033[0;34mλ \033[0m") 23 | return 24 | } 25 | regex, _ := regexp.Compile("https://.*/.*/(.*)\\.git") 26 | list, _ := r.Remotes() 27 | repoName := regex.FindStringSubmatch(list[0].String())[1] 28 | files, err := ioutil.ReadDir(".") 29 | if err != nil { 30 | fmt.Println("ERROR") 31 | } 32 | for _, file := range files { 33 | if strings.HasSuffix(file.Name(), ".goshc") { 34 | file1, _ := os.Open(file.Name()) 35 | scanner := bufio.NewScanner(file1) 36 | for scanner.Scan() { 37 | if strings.HasPrefix(scanner.Text(), "prompt ") { 38 | testArray := strings.Split(scanner.Text(), "prompt ") 39 | fmt.Print(testArray[1]) 40 | return 41 | } 42 | } 43 | } 44 | } 45 | if isGitRepo { 46 | Rawhead, _ := r.Head() 47 | head1 := strings.Split(Rawhead.String(), "/") 48 | head := head1[len(head1)-1] 49 | fmt.Print("\033[0;36m(" + dir + ") \033[0;35m" + repoName + "@\033[0;33m" + head + "\033[0;34 \033[032m gosh \033[0;34mλ \033[0m") 50 | return 51 | } 52 | fmt.Printf("\033[0;36m(" + dir + ")\033[0;32mgosh \033[0;34mλ \033[0m") 53 | } 54 | 55 | // Exit This function exits the program 56 | func Exit() { 57 | prompt := ui.Select{ 58 | Label: "Are you sure?", 59 | Items: []string{"Yes", "No"}, 60 | } 61 | _, result, err := prompt.Run() 62 | if err != nil { 63 | println("Error, exiting...") 64 | os.Exit(1) 65 | } 66 | if result == "Yes" { 67 | os.Exit(0) 68 | } else { 69 | return 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gosh 2 | 3 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/51f0c37b6e3c4e559389f2e6fec985f2)](https://www.codacy.com/manual/gosh-terminal/gosh_2?utm_source=github.com&utm_medium=referral&utm_content=gosh-terminal/gosh&utm_campaign=Badge_Grade) 4 | [![Setup Automated](https://img.shields.io/badge/setup-automated-blue?logo=gitpod)](https://gitpod.io/from-referrer/) 5 | [![Pull Requests Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com) 6 | [![CodeFactor](https://www.codefactor.io/repository/github/gosh-terminal/gosh/badge)](https://www.codefactor.io/repository/github/gosh-terminal/gosh) 7 | ![GitHub repo size](https://img.shields.io/github/repo-size/gosh-terminal/gosh) 8 | ![GitHub language count](https://img.shields.io/github/languages/count/gosh-terminal/gosh) 9 | 10 | Welcome to gosh! The end goal of this project is to allow you to use the 11 | terminal for everything! Do anything from math, playing music, sending emails, 12 | to searching the web, but have these things be built into your terminal. 13 | 14 | ## Install 15 | 16 | ### Homebrew (Recommend) 17 | 18 | ```bash 19 | brew install gosh-terminal/homebrew-gosh/gosh 20 | ``` 21 | 22 | ### Gitpod 23 | 24 | Use Gitpod, everything is preinstalled. 25 | 26 | [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/gosh-terminal/gosh) 27 | 28 | ### One-line curl installer 29 | 30 | ```bash 31 | curl -s "https://raw.githubusercontent.com/gosh-terminal/gosh/master/tools/setup2.0.bash" | bash 32 | source ~/.bashrc 33 | ``` 34 | 35 | ### Go Module 36 | 37 | ```bash 38 | git clone "https://github.com/gosh-terminal/gosh.git" 39 | cd gosh 40 | go install 41 | echo "export GOSH_HOME=\"$GOPATH/bin\"" >>~/.bashrc 42 | source ~/.bashrc 43 | ``` 44 | 45 | ## DH Make 46 | 47 | ```bash 48 | git clone "https://github.com/gosh-terminal/gosh.git" 49 | cd gosh 50 | dh_auto_install 51 | ``` 52 | 53 | ![Example of gosh](https://github.com/gosh-terminal/gosh/blob/master/.github/images/example.png?raw=true) 54 | -------------------------------------------------------------------------------- /internal/errors.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | // InvalidNumberOfArgs Invalid args error 9 | func InvalidNumberOfArgs(command string) { 10 | stringLen := len(command) 11 | highlightThing := strings.Repeat("^", stringLen) 12 | fmt.Print("\033[0;34m1 | ") 13 | fmt.Println("\033[0;31m❌ gosh: " + command + "\033[0m") 14 | fmt.Print("\033[0;34m | ") 15 | fmt.Print("\033[1;34m " + highlightThing + "\033[0m") 16 | fmt.Print("\033[0;31m Error: \033[0m") 17 | fmt.Println("Invalid number of arguments!") 18 | } 19 | 20 | // CommandNotFound command not found error 21 | func CommandNotFound(command string) { 22 | stringLen := len(command) 23 | highlightThing := strings.Repeat("^", stringLen) 24 | fmt.Print("\033[0;34m1 | ") 25 | fmt.Println("\033[0;31m❌ gosh: " + command + "\033[0m") 26 | fmt.Print("\033[0;34m | ") 27 | fmt.Print("\033[1;34m " + highlightThing + "\033[0m") 28 | fmt.Print("\033[0;31m Error: \033[0m") 29 | fmt.Println("Command not found!") 30 | } 31 | 32 | // DirectoryNotFound directory not found error 33 | func DirectoryNotFound(dir string) { 34 | stringLen := len(dir) 35 | highlightThing := strings.Repeat("^", stringLen) 36 | fmt.Print("\033[0;34m1 | ") 37 | fmt.Println("\033[0;31m❌ gosh: '" + dir + "' not found!\033[0m") 38 | fmt.Print("\033[0;34m | ") 39 | fmt.Print("\033[1;34m " + highlightThing + "\033[0m") 40 | fmt.Print("\033[0;31m Error: \033[0m") 41 | fmt.Println("Directory not found!") 42 | } 43 | 44 | // PipeError pipe error 45 | func PipeError(command string) { 46 | indexOf := strings.Index(command, " > ") 47 | highlightThing := strings.Repeat("^", len(command[indexOf+3:])+1) 48 | spaces := strings.Repeat(" ", len(command[:indexOf])+1) 49 | fmt.Print("\033[0;34m1 | ") 50 | fmt.Println("\033[0;31m❌ gosh: " + " " + command + "\033[0m") 51 | fmt.Print("\033[0;34m | ") 52 | fmt.Print(spaces + " \033[1;34m " + highlightThing + "\033[0m") 53 | fmt.Print("\033[0;31m Error: \033[0m") 54 | fmt.Println("Pipe error!") 55 | } 56 | -------------------------------------------------------------------------------- /internal/complete.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "bufio" 5 | "io/ioutil" 6 | "os" 7 | "strings" 8 | 9 | "github.com/c-bata/go-prompt" 10 | "github.com/c-bata/go-prompt/completer" 11 | ) 12 | 13 | var filePathCompleter = completer.FilePathCompleter{ 14 | IgnoreCase: true, 15 | } 16 | 17 | // Unique remove prompt suggestion duplicates 18 | func Unique(intSlice []prompt.Suggest) []prompt.Suggest { 19 | keys := make(map[prompt.Suggest]bool) 20 | list := []prompt.Suggest{} 21 | for _, entry := range intSlice { 22 | if _, value := keys[entry]; !value { 23 | keys[entry] = true 24 | list = append(list, entry) 25 | } 26 | } 27 | return list 28 | } 29 | 30 | // Completer complete commands 31 | func Completer(d prompt.Document) []prompt.Suggest { 32 | s := []prompt.Suggest{{Text: "help", Description: "gosh"}, {Text: "exit", Description: "gosh"}, {Text: "history", Description: "gosh"}, {Text: "clearhist", Description: "gosh"}, {Text: "tree", Description: "gosh"}, {Text: "touch", Description: "gosh"}, {Text: "mkdir", Description: "gosh"}} 33 | var gopath string = os.Getenv("GOSH_HOME") 34 | file, _ := os.Open(gopath + "/history.txt") 35 | scanner := bufio.NewScanner(file) 36 | for scanner.Scan() { 37 | if strings.Compare(string(scanner.Text()), "") == 0 { 38 | continue 39 | } 40 | s = append(s, prompt.Suggest{Text: scanner.Text(), Description: "History"}) 41 | } 42 | files, _ := ioutil.ReadDir("/usr/bin") 43 | for _, file := range files { 44 | s = append(s, prompt.Suggest{Text: file.Name(), Description: "Command"}) 45 | } 46 | completions := filePathCompleter.Complete(d) 47 | for i := range completions { 48 | completions[i].Description = "File" 49 | } 50 | for _, i := range prompt.FilterHasPrefix(Unique(s), d.CurrentLine(), true) { 51 | completions = append(completions, i) 52 | } 53 | return completions 54 | } 55 | 56 | // GetCommandHist Get command History 57 | func GetCommandHist() []string { 58 | s := []string{} 59 | var gopath string = os.Getenv("GOSH_HOME") 60 | file, _ := os.Open(gopath + "/history.txt") 61 | scanner := bufio.NewScanner(file) 62 | for scanner.Scan() { 63 | if strings.Compare(string(scanner.Text()), "") == 0 { 64 | continue 65 | } 66 | s = append(s, scanner.Text()) 67 | } 68 | return s 69 | } 70 | -------------------------------------------------------------------------------- /tools/setup2.0.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function install() { 4 | echo -e "\nStarting checks..." 5 | if [ command -v sudo ] 2>/dev/null; then 6 | echo "sudo not installed on main system aborting" 7 | exit 1 8 | fi 9 | if [ ! -d "$HOME"/.gosh ]; then 10 | echo "Directory: $HOME/.gosh does not already exist. Creating..." 11 | mkdir "$HOME"/.gosh 12 | else 13 | echo "Directory: ($HOME/.gosh) already exists!" 14 | fi 15 | if [ command -v go ] 2>/dev/null; then 16 | echo "Go is not yet installed. Installing..." 17 | if [ command -v apt-get ] 2>/dev/null; then 18 | sudo apt-get && sudo apt-get install -y golang 19 | elif [ command -v apt ] 2>/dev/null; then 20 | sudo apt && sudo apt install -y golang 21 | elif [ command -v dnf ] 2>/dev/null; then 22 | sudo dnf install -y golang 23 | elif [ command -v rpm 2>/dev/null && command -v yum 2>/dev/null && command -v curl ] 2>/dev/null; then 24 | sudo rpm --import https://mirror.go-repo.io/centos/RPM-GPG-KEY-GO-REPO 25 | curl -s https://mirror.go-repo.io/centos/go-repo.repo | sudo tee /etc/yum.repos.d/go-repo.repo 26 | sudo yum install golang 27 | elif [ command -v apk ] 2>/dev/null; then 28 | sudo apk add --no-cache --virtual .build-deps bash gcc musl-dev openssl go 29 | elif [ command -v brew ] 2>/dev/null; then 30 | brew install golang 31 | fi 32 | fi 33 | if [ command -v git ] 2>/dev/null; then 34 | echo "Git is not yet installed. Installing..." 35 | if [ command -v apt-get ] 2>/dev/null; then 36 | sudo apt-get && sudo apt-get install -y git 37 | elif [ command -v apt ] 2>/dev/null; then 38 | sudo apt && sudo apt install -y git 39 | elif [ command -v dnf ] 2>/dev/null; then 40 | sudo dnf install -y git 41 | elif [ command -v rpm 2>/dev/null && command -v yum 2>/dev/null && command -v curl ] 2>/dev/null; then 42 | sudo yum install git 43 | elif [ command -v apk ] 2>/dev/null; then 44 | sudo apk add --no-cache --virtual .build-deps bash git 45 | elif [ command -v brew ] 2>/dev/null; then 46 | brew install git 47 | fi 48 | fi 49 | git clone https://github.com/gosh-terminal/gosh.git 50 | oldwd=$PWD 51 | cd gosh 52 | echo "building gosh" 53 | go build -o gosh main.go 54 | echo "Moving files" 55 | mv gosh "$HOME/.gosh" 56 | touch history.txt "$HOME/.gosh" 57 | mv history.txt "$HOME/.gosh" 58 | echo "Removing old stuff" 59 | cd "$HOME/.gosh" 60 | echo "Setting ENV Vars" 61 | echo "Setting \$PATH" 62 | echo "export PATH=$PATH:$PWD" >>~/.bashrc 63 | echo "Setting \$GOSH_HOME" 64 | echo "export GOSH_HOME=$PWD" >>~/.bashrc 65 | echo -e "\nDone!!\n\nPlease open a new terminal, or run the following in the existing one:\n . ~/.bashrc\n\n" 66 | echo "Remove old stuff" 67 | cd "$oldwd" 68 | rm -rf gosh 69 | } 70 | install 71 | -------------------------------------------------------------------------------- /internal/ls.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "fmt" 5 | ui "github.com/gizak/termui/v3" 6 | "github.com/gizak/termui/v3/widgets" 7 | "io/ioutil" 8 | "log" 9 | "strconv" 10 | "strings" 11 | ) 12 | 13 | // Ls this is the ls command for gosh 14 | func Ls(path string) { 15 | files, err := ioutil.ReadDir(path) 16 | if err != nil { 17 | DirectoryNotFound(path) 18 | return 19 | } 20 | fmt.Println(" \033[0;32m# name type \033[0m") 21 | fmt.Println(" ╭━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━╮") 22 | for i, file := range files { 23 | i++ 24 | x := 3 - len(string(i)) 25 | z := 33 - len(file.Name()) 26 | spaces := strings.Repeat(" ", z) 27 | spaces2 := strings.Repeat(" ", x) 28 | if file.IsDir() { 29 | if i >= 10 { 30 | fmt.Println(" │ \033[0;32m" + strconv.Itoa(i) + spaces2 + "\033[0m│ \033[0;36m" + 31 | file.Name() + spaces + "\033[0m│ Directory \033[0m│") 32 | } else { 33 | fmt.Println(" │ \033[0;32m" + strconv.Itoa(i) + spaces2 + "\033[0m │ \033[0;36m" + 34 | file.Name() + spaces + "\033[0m│ Directory \033[0m│") 35 | } 36 | } else { 37 | if i >= 10 { 38 | fmt.Println(" │ \033[0;32m" + strconv.Itoa(i) + spaces2 + "\033[0m│ " + file.Name() + spaces + 39 | "\033[0m│ File \033[0m│") 40 | } else { 41 | fmt.Println(" │ \033[0;32m" + strconv.Itoa(i) + spaces2 + "\033[0m │ " + file.Name() + spaces + 42 | "\033[0m│ File \033[0m│") 43 | } 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | } 53 | } 54 | fmt.Println(" ╰━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━╯") 55 | } 56 | 57 | type nodeValue string 58 | 59 | func (nv nodeValue) String() string { 60 | return string(nv) 61 | } 62 | 63 | func getFiles(path string) []*widgets.TreeNode { 64 | nodes := []*widgets.TreeNode{} 65 | // Gets an array of files in the current directory 66 | files, _ := ioutil.ReadDir(path) 67 | for _, file := range files { 68 | // Create a file item 69 | tmp := widgets.TreeNode{} 70 | tmp.Value = nodeValue(file.Name()) 71 | // If its a directory recursivly recurse the subdirectories 72 | if file.IsDir() { 73 | tmp1 := getFiles(path + "/" + file.Name()) 74 | tmp.Nodes = tmp1 75 | } 76 | // When the file item is done being processed add it to the file list 77 | nodes = append(nodes, &tmp) 78 | } 79 | return nodes 80 | } 81 | 82 | // TreeView tree view command 83 | func TreeView(path string, tabNumbers int) { 84 | if err := ui.Init(); err != nil { 85 | log.Printf("failed to initialize termui: %v", err) 86 | } 87 | defer ui.Close() 88 | // This will hide the cursor 89 | fmt.Print("\033[?25l") 90 | nodes := getFiles(path) 91 | l := widgets.NewTree() 92 | l.TextStyle = ui.NewStyle(ui.ColorCyan) 93 | l.WrapText = false 94 | l.SetNodes(nodes) 95 | 96 | x, y := ui.TerminalDimensions() 97 | 98 | l.SetRect(0, 0, x, y) 99 | 100 | ui.Render(l) 101 | 102 | previousKey := "" 103 | uiEvents := ui.PollEvents() 104 | for { 105 | e := <-uiEvents 106 | switch e.ID { 107 | case "q", "": 108 | return 109 | case "": 110 | l.ScrollDown() 111 | case "": 112 | l.ScrollUp() 113 | case "": 114 | l.ToggleExpand() 115 | case "": 116 | x, y := ui.TerminalDimensions() 117 | l.SetRect(0, 0, x, y) 118 | } 119 | 120 | if previousKey == "g" { 121 | previousKey = "" 122 | } else { 123 | previousKey = e.ID 124 | } 125 | 126 | ui.Render(l) 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /.github/CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at seanhellum45@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /internal/shell.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "regexp" 7 | "strings" 8 | 9 | "github.com/c-bata/go-prompt" 10 | "github.com/c-bata/go-prompt/completer" 11 | "github.com/mattn/go-isatty" 12 | ) 13 | 14 | 15 | // Shell gosh shell 16 | func Shell(quiet bool) { 17 | if !quiet { 18 | fmt.Println("Welcome to gosh, the Go Shell!") 19 | fmt.Println("------------------------------") 20 | } 21 | for { 22 | if !interactive() { 23 | fmt.Print( 24 | "\033[0;31m❌ gosh: This isn't an interactive terminal! Try `gosh -c COMMAND`.", 25 | ) 26 | } 27 | ThePrompt() 28 | command := prompt.Input("", Completer, prompt.OptionHistory(GetCommandHist()), prompt.OptionSuggestionBGColor(prompt.DefaultColor), 29 | prompt.OptionInputTextColor(prompt.Cyan), 30 | prompt.OptionMaxSuggestion(6), 31 | prompt.OptionTitle("gosh"), 32 | prompt.OptionCompletionWordSeparator(completer.FilePathCompletionSeparator), 33 | prompt.OptionAddKeyBind(prompt.KeyBind{ 34 | Key: prompt.ControlC, 35 | Fn: func(buf *prompt.Buffer) { 36 | ThePrompt() 37 | }}), 38 | prompt.OptionPreviewSuggestionTextColor(prompt.DefaultColor), 39 | prompt.OptionScrollbarBGColor(prompt.DefaultColor)) 40 | command = strings.Replace(command, "\n", "", -1) 41 | if strings.Contains(command, "~") { 42 | command = strings.ReplaceAll(command, "~", os.Getenv("HOME")) 43 | } else if strings.Contains(command, "$") { 44 | regex, _ := regexp.Compile(".*\\$(.*).*") 45 | matches := regex.FindAllStringSubmatch(command, -1) 46 | for i, j := range matches { 47 | command1 := strings.Replace(command, j[i+1][0:], os.Getenv(j[i+1]), -1) 48 | command = strings.Replace(command1, "$", "", -1) 49 | Evaluate(command) 50 | } 51 | } else if strings.Contains(command, " > ") { 52 | data, err := SplitCommandFile(command) 53 | if err != nil { 54 | PipeError(command) 55 | UpdateHistory(command) 56 | continue 57 | } 58 | CaptureOutput, err := CaptureOutput(data[0]) 59 | if err != nil { 60 | CommandNotFound(command) 61 | } 62 | RedirectToFile(CaptureOutput, data[1]) 63 | UpdateHistory(command) 64 | continue 65 | } else if strings.Contains(command, " | ") { 66 | data, err := SplitCommands(command) 67 | if err != nil { 68 | PipeError(command) 69 | UpdateHistory(command) 70 | continue 71 | } 72 | CaptureOutput, err := CaptureOutput(data[0]) 73 | if err != nil { 74 | CommandNotFound(command) 75 | } 76 | Pipe(CaptureOutput, data[1]) 77 | UpdateHistory(command) 78 | continue 79 | } else if strings.Compare("help", command) == 0 { 80 | Help() 81 | UpdateHistory(command) 82 | } else if strings.Compare("exit", command) == 0 { 83 | Exit() 84 | } else if strings.Compare("ls", command) == 0 { 85 | Ls(".") 86 | UpdateHistory(command) 87 | } else if strings.HasPrefix(command, "ls ") { 88 | var dir string = GetArg(command) 89 | if len(dir) == 0 { 90 | InvalidNumberOfArgs(command) 91 | continue 92 | } 93 | Ls(dir) 94 | UpdateHistory(command) 95 | } else if strings.Compare("", command) == 0 { 96 | continue 97 | } else if strings.HasPrefix(command, "cd ") { 98 | var dir string = GetArg(command) 99 | if dir == "error" { 100 | DirectoryNotFound(dir) 101 | } 102 | err := os.Chdir(dir) 103 | if err != nil { 104 | if strings.HasSuffix(string(err.Error()), "file or directory") { 105 | DirectoryNotFound(dir) 106 | } 107 | } 108 | UpdateHistory(command) 109 | continue 110 | } else if strings.HasPrefix("cd", command) { 111 | InvalidNumberOfArgs(command) 112 | continue 113 | } else if strings.HasPrefix(command, "history") { 114 | History() 115 | continue 116 | } else if strings.Compare(command, "clearhist") == 0 { 117 | ClearHistory() 118 | } else if command == "tree" { 119 | TreeView(".", 0) 120 | UpdateHistory(command) 121 | continue 122 | } else if strings.HasPrefix(command, "touch") { 123 | Touch(command) 124 | UpdateHistory(command) 125 | continue 126 | } else if strings.HasPrefix(command, "mkdir") { 127 | Mkdir(command) 128 | UpdateHistory(command) 129 | continue 130 | } else { 131 | if err := ExecuteCommand(command); err != nil { 132 | if strings.HasSuffix(string(err.Error()), "executable file not found in $PATH") { 133 | CommandNotFound(command) 134 | } 135 | } 136 | UpdateHistory(command) 137 | } 138 | } 139 | } 140 | 141 | // Evaluate evaluate function 142 | func Evaluate(command string) { 143 | if len(strings.Trim(command, " ")) == 0 { 144 | fmt.Println("Error input empty") 145 | return 146 | } 147 | if strings.Compare("help", command) == 0 { 148 | Help() 149 | UpdateHistory(command) 150 | } else if strings.Compare("exit", command) == 0 { 151 | Exit() 152 | } else if strings.Compare("ls", command) == 0 { 153 | Ls(".") 154 | UpdateHistory(command) 155 | } else if strings.HasPrefix(command, "ls ") { 156 | var dir string = GetArg(command) 157 | Ls(dir) 158 | UpdateHistory(command) 159 | } else if strings.Compare("", command) == 0 { 160 | return 161 | } else if strings.HasPrefix(command, "cd ") { 162 | var dir string = GetArg(command) 163 | if dir == "error" { 164 | DirectoryNotFound(dir) 165 | } 166 | err := os.Chdir(dir) 167 | if err != nil { 168 | if strings.HasSuffix(string(err.Error()), "file or directory") { 169 | DirectoryNotFound(dir) 170 | } 171 | } 172 | UpdateHistory(command) 173 | return 174 | } else if strings.HasPrefix(command, "history") { 175 | History() 176 | return 177 | } else if strings.Compare(command, "clearhist") == 0 { 178 | ClearHistory() 179 | } else if strings.Contains(command, " > ") { 180 | data, err := SplitCommandFile(command) 181 | if err != nil { 182 | PipeError(command) 183 | UpdateHistory(command) 184 | return 185 | } 186 | CaptureOutput, err := CaptureOutput(data[0]) 187 | if err != nil { 188 | CommandNotFound(command) 189 | } 190 | RedirectToFile(CaptureOutput, data[1]) 191 | UpdateHistory(command) 192 | return 193 | } else if command == "tree" { 194 | TreeView(".", 0) 195 | UpdateHistory(command) 196 | return 197 | } else if strings.HasPrefix(command, "touch") { 198 | Touch(command) 199 | UpdateHistory(command) 200 | return 201 | } else if strings.HasPrefix(command, "mkdir") { 202 | Mkdir(command) 203 | UpdateHistory(command) 204 | return 205 | } else { 206 | if err := ExecuteCommand(command); err != nil { 207 | if strings.HasSuffix(string(err.Error()), "executable file not found in $PATH") { 208 | CommandNotFound(command) 209 | } 210 | } 211 | UpdateHistory(command) 212 | } 213 | } 214 | 215 | func interactive() bool { 216 | return isatty.IsCygwinTerminal(os.Stdout.Fd()) || isatty.IsTerminal(os.Stdout.Fd()) 217 | } 218 | -------------------------------------------------------------------------------- /tools/install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | randNum=$((1 + RANDOM % 20)) 3 | if [ $randNum -eq 1 ]; then 4 | echo -e "\e[1m\e[92m 5 | GGGGGGGGGGGGG hhhhhhh 6 | GGG::::::::::::G h:::::h 7 | GG:::::::::::::::G h:::::h 8 | G:::::GGGGGGGG::::G h:::::h 9 | G:::::G GGGGGG ooooooooooo ssssssssss h::::h hhhhh 10 | G:::::G oo:::::::::::oo ss::::::::::s h::::hh:::::hhh 11 | G:::::G o:::::::::::::::oss:::::::::::::s h::::::::::::::hh 12 | G:::::G GGGGGGGGGGo:::::ooooo:::::os::::::ssss:::::sh:::::::hhh::::::h 13 | G:::::G G::::::::Go::::o o::::o s:::::s ssssss h::::::h h::::::h 14 | G:::::G GGGGG::::Go::::o o::::o s::::::s h:::::h h:::::h 15 | G:::::G G::::Go::::o o::::o s::::::s h:::::h h:::::h 16 | G:::::G G::::Go::::o o::::ossssss s:::::s h:::::h h:::::h 17 | G:::::GGGGGGGG::::Go:::::ooooo:::::os:::::ssss::::::sh:::::h h:::::h 18 | GG:::::::::::::::Go:::::::::::::::os::::::::::::::s h:::::h h:::::h 19 | GGG::::::GGG:::G oo:::::::::::oo s:::::::::::ss h:::::h h:::::h 20 | GGGGGG GGGG ooooooooooo sssssssssss hhhhhhh hhhhhhh 21 | \e[39m" 22 | elif [ $randNum -eq 2 ]; then 23 | echo -e "\e[1m\e[92m 24 | ____ _ 25 | / ___| ___ ___| |__ 26 | | | _ / _ \/ __| '_ \\ 27 | | |_| | (_) \__ \ | | | 28 | \____|\___/|___/_| |_| 29 | \e[39m" 30 | elif [ $randNum -eq 3 ]; then 31 | echo -e "\e[1m\e[92m 32 | ______ __ 33 | / ____/___ _____/ /_ 34 | / / __/ __ \\/ ___/ __ \\ 35 | / /_/ / /_/ (__ ) / / / 36 | \\____/\\____/____/_/ /_/ 37 | \e[39m" 38 | elif [ $randNum -eq 4 ]; then 39 | echo -e "\e[1m\e[92m 40 | // ) ) 41 | // ___ ___ / __ 42 | // ____ // ) ) (( ) ) // ) ) 43 | // / / // / / \ \ // / / 44 | ((____/ / ((___/ / // ) ) // / / 45 | \e[39m" 46 | elif [ $randNum -eq 5 ]; then 47 | echo -e "\e[1m\e[92m 48 | >===> 49 | >> >=> >=> 50 | >=> >=> >===> >=> 51 | >=> >=> >=> >=> >=>>=> 52 | >=> >===> >=> >=> >==> >=> >=> 53 | >=> >> >=> >=> >=> >> >=> 54 | >====> >=> >=> >=> >=> >=> 55 | 56 | \e[39m" 57 | elif [ $randNum -eq 6 ]; then 58 | echo -e '\e[1m\e[92m 59 | /\\\\ 60 | /\ /\\ /\\ 61 | /\\ /\\ /\\\\ /\\ 62 | /\\ /\\ /\\ /\\ /\ /\ 63 | /\\ /\\\\ /\\ /\\ /\\\ /\\ /\\ 64 | /\\ /\ /\\ /\\ /\\ /\ /\\ 65 | /\\\\\ /\\ /\\ /\\ /\\ /\\ 66 | \e[39m' 67 | elif [ $randNum -eq 7 ]; then 68 | echo -e '\e[1m\e[92m 69 | _____ _ 70 | | __ \ | | 71 | | | \/ ___ ___ | |__ 72 | | | __ / _ \ / __| | _ \\\ 73 | | |_\ \ | (_) | \__ \ | | | | 74 | \____/ \___/ |___/ |_| |_| 75 | \e[39m' 76 | elif [ $randNum -eq 8 ]; then 77 | echo -e '\e[1m\e[92m 78 | _ (_)(_)(_) _ (_) 79 | (_) (_) _ _ _ _ _ _ _ (_) _ _ _ 80 | (_) _ _ _ _ (_)(_)(_) _ _(_)(_)(_)(_) (_)(_)(_)(_)_ 81 | (_) (_)(_)(_)(_) (_)(_)_ _ _ _ (_) (_) 82 | (_) (_)(_) (_) (_)(_)(_)(_)_ (_) (_) 83 | (_) _ _ _ (_)(_) _ _ _ (_) _ _ _ _(_)(_) (_) 84 | (_)(_)(_)(_) (_)(_)(_) (_)(_)(_)(_) (_) (_) 85 | 86 | \e[39m' 87 | elif [ $randNum -eq 9 ]; then 88 | echo -e '\e[1m\e[92m 89 | ___ _ 90 | / _> ___ ___ | |_ 91 | | <_/\ / . \ <_-< | . | 92 | `____/ \___/ /__/ |_|_| 93 | \e[39m' 94 | elif [ $randNum -eq 10 ]; then 95 | echo -e '\e[1m\e[92m 96 | _______ _______ _______ 97 | ( ____ \ ( ___ ) ( ____ \ |\ /| 98 | | ( \/ | ( ) | | ( \/ | ) ( | 99 | | | | | | | | (_____ | (___) | 100 | | | ____ | | | | (_____ ) | ___ | 101 | | | \_ ) | | | | ) | | ( ) | 102 | | (___) | | (___) | /\____) | | ) ( | 103 | (_______) (_______) \_______) |/ \| 104 | \e[39m' 105 | elif [ $randNum -eq 11 ]; then 106 | echo -e '\e[1m\e[92m 107 | dBBBBb dBBBBP.dBBBBP dBP dBP 108 | dBP.BP BP 109 | d BBBB dBP.BP BBBBb dBBBBBP 110 | dB BB dBP.BP dBP dBP dBP 111 | dBBBBBB dBBBBP dBBBBP dBP dBP 112 | \e[39m' 113 | elif [ $randNum -eq 12 ]; then 114 | echo -e '\e[1m\e[92m 115 | eeeee eeeee eeeee e e 116 | 8 8 8 88 8 " 8 8 117 | 8e 8 8 8eeee 8eee8 118 | 88 "8 8 8 88 88 8 119 | 88ee8 8eee8 8ee88 88 8 120 | \e[39m' 121 | elif [ $randNum -eq 13 ]; then 122 | echo -e '\e[1m\e[92m 123 | # 124 | # 125 | ### ## ### ### 126 | # # # # ## # # 127 | # # # # # # # 128 | #### ## ### # # 129 | # 130 | #### 131 | \e[39m' 132 | elif [ $randNum -eq 14 ]; then 133 | echo -e '\e[1m\e[92m 134 | [.. 135 | [.. [.. [.... [.. 136 | [.. [.. [.. [.. [.. [. [. 137 | [.. [..[.. [.. [... [.. [.. 138 | [.. [.. [.. [.. [..[. [.. 139 | [.. [.. [.. [..[.. [.. 140 | [.. 141 | \e[39m' 142 | elif [ $randNum -eq 15 ]; then 143 | echo -e '\e[1m\e[92m 144 | ______ _____ _______ _ _ 145 | | ____ | | |______ |_____| 146 | |_____| |_____| ______| | | 147 | \e[39m' 148 | elif [ $randNum -eq 16 ]; then 149 | echo -e '\e[1m\e[92m 150 | oooo 151 | 8888 152 | .oooooooo .ooooo. .oooo.o 888 .oo. 153 | 8888 888b d888 888b d88( 88 888P8Y88b 154 | 888 888 888 888 88Y88b. 888 888 155 | 888bod8P8 888 888 o. )88b 888 888 156 | 88oooooo. 8Y8bod8P8 888888P8 o888o o888o 157 | d8 YD 158 | 8Y88888P8 159 | \e[39m' 160 | elif [ $randNum -eq 17 ]; then 161 | echo -e '\e[1m\e[92m 162 | / 163 | / 164 | ____ ____ ____ / __ 165 | / ) / )--/ )--/ ) 166 | / / / / ---, / / 167 | (___,/(__(___,/ (___,/ / /(__ 168 | / 169 | / / 170 | (___,/ 171 | \e[39m' 172 | elif [ $randNum -eq 18 ]; then 173 | echo -e '\e[1m\e[92m 174 | ___ __ ____ _ _ 175 | / __) / \ / ___)/ )( \ 176 | ( (_ \( O )\___ \) __ ( 177 | \___/ \__/ (____/\_)(_/ 178 | \e[39m' 179 | elif [ $randNum -eq 19 ]; then 180 | echo -e '\e[1m\e[92m 181 | ___ ___ ___ ___ 182 | /\ \ /\ \ /\ \ /\__\ 183 | /::\ \ /::\ \ /::\ \ /:/ / 184 | /:/\:\ \ /:/\:\ \ /:/\ \ \ /:/__/ 185 | /:/ \:\ \ /:/ \:\ \ _\:\~\ \ \ /::\ \ ___ 186 | /:/__/_\:\__\ /:/__/ \:\__\ /\ \:\ \ \__\ /:/\:\ /\__\ 187 | \:\ /\ \/__/ \:\ \ /:/ / \:\ \:\ \/__/ \/__\:\/:/ / 188 | \:\ \:\__\ \:\ /:/ / \:\ \:\__\ \::/ / 189 | \:\/:/ / \:\/:/ / \:\/:/ / /:/ / 190 | \::/ / \::/ / \::/ / /:/ / 191 | \/__/ \/__/ \/__/ \/__/ 192 | \e[39m' 193 | 194 | else 195 | echo -e "\e[1m\e[92m 196 | :::::::: :::::::: :::::::: ::: ::: 197 | :+: :+: :+: :+: :+: :+: :+: :+: 198 | +:+ +:+ +:+ +:+ +:+ +:+ 199 | :#: +#+ +:+ +#++:++#++ +#++:++#++ 200 | +#+ +#+# +#+ +#+ +#+ +#+ +#+ 201 | #+# #+# #+# #+# #+# #+# #+# #+# 202 | ######## ######## ######## ### ### 203 | \e[39m" 204 | fi 205 | git clone https://github.com/gosh-terminal/gosh.git 206 | cd gosh/src || exit 207 | go get -v -t -d ./... 208 | go build -o gosh -- *.go 209 | touch history.txt 210 | mv history.txt "$GOPATH"/bin 211 | mv gosh "$GOPATH"/bin 212 | cd ../.. 213 | rm -rf gosh 214 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= 2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 3 | github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= 4 | github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= 5 | github.com/alecthomas/gometalinter v3.0.0+incompatible h1:e9Zfvfytsw/e6Kd/PYd75wggK+/kX5Xn8IYDUKyc5fU= 6 | github.com/alecthomas/gometalinter v3.0.0+incompatible/go.mod h1:qfIpQGGz3d+NmgyPBqv+LSh50emm1pt72EtcX2vKYQk= 7 | github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= 8 | github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= 9 | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= 10 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 11 | github.com/c-bata/go-prompt v0.2.3 h1:jjCS+QhG/sULBhAaBdjb2PlMRVaKXQgn+4yzaauvs2s= 12 | github.com/c-bata/go-prompt v0.2.3/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= 13 | github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= 14 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 15 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= 16 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 17 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= 18 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 19 | github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= 20 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 21 | github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= 22 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 23 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 24 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 25 | github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= 26 | github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= 27 | github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= 28 | github.com/gizak/termui/v3 v3.1.0 h1:ZZmVDgwHl7gR7elfKf1xc4IudXZ5qqfDh4wExk4Iajc= 29 | github.com/gizak/termui/v3 v3.1.0/go.mod h1:bXQEBkJpzxUAKf0+xq9MSWAvWZlE7c+aidmyFlkYTrY= 30 | github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= 31 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 32 | github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg= 33 | github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE= 34 | github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc h1:cJlkeAx1QYgO5N80aF5xRGstVsRQwgLR7uA2FnP1ZjY= 35 | github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= 36 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= 37 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= 38 | github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 39 | github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU= 40 | github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= 41 | github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= 42 | github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= 43 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 44 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 45 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 46 | github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= 47 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 48 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 49 | github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a h1:weJVJJRzAJBFRlAiJQROKQs8oC9vOxvm4rZmBBk0ONw= 50 | github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= 51 | github.com/manifoldco/promptui v0.6.0 h1:GuXmIdl5lhlamnWf3NbsKWYlaWyHABeStbD1LLsQMuA= 52 | github.com/manifoldco/promptui v0.6.0/go.mod h1:o9/C5VV8IPXxjxpl9au84MtQGIi5dwn7eldAgEdePPs= 53 | github.com/manifoldco/promptui v0.7.0 h1:3l11YT8tm9MnwGFQ4kETwkzpAwY2Jt9lCrumCUW4+z4= 54 | github.com/manifoldco/promptui v0.7.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ= 55 | github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= 56 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= 57 | github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= 58 | github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 59 | github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= 60 | github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 61 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 62 | github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10= 63 | github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= 64 | github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= 65 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 66 | github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= 67 | github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 68 | github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54= 69 | github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 70 | github.com/mattn/go-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI= 71 | github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0= 72 | github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= 73 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 74 | github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM= 75 | github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= 76 | github.com/nicksnyder/go-i18n v1.10.1 h1:isfg77E/aCD7+0lD/D00ebR2MV5vgeQ276WYyDaCRQc= 77 | github.com/nicksnyder/go-i18n v1.10.1/go.mod h1:e4Di5xjP9oTVrC6y3C7C0HoSYXjSbhh/dU0eUV32nB4= 78 | github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d h1:x3S6kxmy49zXVVyhcnrFqxvNVCBPb2KZ9hV2RBdS840= 79 | github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ= 80 | github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= 81 | github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= 82 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 83 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 84 | github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 h1:A7GG7zcGjl3jqAqGPmcNjd/D9hzL95SuoOQAaFNdLU0= 85 | github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= 86 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 87 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 88 | github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= 89 | github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= 90 | github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= 91 | github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= 92 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 93 | github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= 94 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 95 | github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= 96 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 97 | github.com/tsenart/deadcode v0.0.0-20160724212837-210d2dc333e9 h1:vY5WqiEon0ZSTGM3ayVVi+twaHKHDFUVloaQ/wug9/c= 98 | github.com/tsenart/deadcode v0.0.0-20160724212837-210d2dc333e9/go.mod h1:q+QjxYvZ+fpjMXqs+XEriussHjSYqeXVnAdSV1tkMYk= 99 | github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= 100 | github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= 101 | golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 102 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 103 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= 104 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 105 | golang.org/x/crypto v0.0.0-20200406173513-056763e48d71 h1:DOmugCavvUtnUD114C1Wh+UgTgQZ4pMLzXxi1pSt+/Y= 106 | golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 107 | golang.org/x/crypto v0.0.0-20200414155820-4f8f47aa7992 h1:B4Wjn2mWOWzjcWfyRYlf00lQ1/9h5vRKmQnhIKhMFR0= 108 | golang.org/x/crypto v0.0.0-20200414155820-4f8f47aa7992/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 109 | golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8= 110 | golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 111 | golang.org/x/crypto v0.0.0-20200420104511-884d27f42877 h1:IhZPbxNd1UjBCaD5AfpSSbJTRlp+ZSuyuH5uoksNS04= 112 | golang.org/x/crypto v0.0.0-20200420104511-884d27f42877/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 113 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3 h1:x/bBzNauLQAlE3fLku/xy92Y8QwKX5HZymrMz2IiKFc= 114 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 115 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 116 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 117 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= 118 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 119 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 120 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 121 | golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b h1:MQE+LT/ABUuuvEZ+YQAMSXindAdUh7slEmAkup74op4= 122 | golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 123 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 124 | golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 125 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 126 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 127 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 128 | golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 129 | golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= 130 | golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 131 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= 132 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 133 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 134 | golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= 135 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 136 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 137 | golang.org/x/tools v0.0.0-20181122213734-04b5d21e00f1 h1:bsEj/LXbv3BCtkp/rBj9Wi/0Nde4OMaraIZpndHAhdI= 138 | golang.org/x/tools v0.0.0-20181122213734-04b5d21e00f1/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 139 | golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= 140 | gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20171010053543-63abe20a23e2 h1:5zOHKFi4LqGWG+3d+isqpbPrN/2yhDJnlO+BhRiuR6U= 141 | gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20171010053543-63abe20a23e2/go.mod h1:3HH7i1SgMqlzxCcBmUHW657sD4Kvv9sC3HpL3YukzwA= 142 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 143 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 144 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 145 | gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg= 146 | gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= 147 | gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg= 148 | gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= 149 | gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE= 150 | gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= 151 | gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= 152 | gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= 153 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 154 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= 155 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 156 | --------------------------------------------------------------------------------