├── .gitignore ├── demo.png ├── go.mod ├── .github └── workflows │ └── release.yml ├── .goreleaser.yml ├── README.md ├── main_test.go ├── main.go └── go.sum /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ -------------------------------------------------------------------------------- /demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/babarot/git-bump/HEAD/demo.png -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/b4b4r07/git-bump 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/Masterminds/semver/v3 v3.0.3 7 | github.com/Songmu/gitconfig v0.0.3 8 | github.com/jessevdk/go-flags v1.4.0 9 | github.com/manifoldco/promptui v0.7.0 10 | github.com/mattn/go-colorable v0.1.4 // indirect 11 | golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d // indirect 12 | gopkg.in/src-d/go-git.v4 v4.13.1 13 | ) 14 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | on: 3 | push: 4 | tags: 5 | - "v[0-9]+.[0-9]+.[0-9]+" 6 | jobs: 7 | goreleaser: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v1 12 | with: 13 | fetch-depth: 1 14 | - name: Setup Go 15 | uses: actions/setup-go@v1 16 | with: 17 | go-version: 1.13 18 | - name: Run GoReleaser 19 | uses: goreleaser/goreleaser-action@v1 20 | with: 21 | version: latest 22 | args: release --rm-dist 23 | env: 24 | GITHUB_TOKEN: ${{ secrets.github_token }} 25 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | project_name: git-bump 2 | env: 3 | - GO111MODULE=on 4 | before: 5 | hooks: 6 | - go mod tidy 7 | builds: 8 | - main: . 9 | binary: git-bump 10 | ldflags: 11 | - -s -w 12 | - -X main.Version={{.Version}} 13 | - -X main.Revision={{.ShortCommit}} 14 | env: 15 | - CGO_ENABLED=0 16 | archives: 17 | - name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}' 18 | replacements: 19 | darwin: darwin 20 | linux: linux 21 | windows: windows 22 | 386: i386 23 | amd64: x86_64 24 | format_overrides: 25 | - goos: windows 26 | format: zip 27 | release: 28 | prerelease: auto 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | git-bump 2 | ======== 3 | 4 | Bump version (git tag) to next one with [semver](https://semver.org/). 5 | 6 | ![](demo.png) 7 | 8 | ## Usage 9 | 10 | ```console 11 | $ git bump 12 | Tags: 13 | - v0.1.0 14 | - v0.1.1 15 | - v0.1.2 16 | - v0.2.0 17 | - v0.2.1 18 | - v1.0.0 19 | - v2.0.0 20 | - v2.0.1 (current version) 21 | 22 | Use the arrow keys to navigate: ↓ ↑ → ← 23 | ? Current tag is "v2.0.1". Next is?: 24 | ▸ patch 25 | minor 26 | major 27 | ``` 28 | 29 | ## Installation 30 | 31 | Download the binary from [GitHub Releases][release] and drop it in your `$PATH`. 32 | 33 | - [Darwin / Mac][release] 34 | - [Linux][release] 35 | 36 | ## License 37 | 38 | [MIT][license] 39 | 40 | [release]: https://github.com/b4b4r07/git-bump/releases/latest 41 | [license]: https://b4b4r07.mit-license.org 42 | -------------------------------------------------------------------------------- /main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "testing" 6 | ) 7 | 8 | type testPair struct { 9 | tags []string 10 | nextVersion string 11 | } 12 | 13 | var tests = []testPair{ 14 | {[]string{"0.0.1"}, "0.0.2"}, 15 | {[]string{"v0.0.1", "v0.0.2"}, "v0.0.3"}, 16 | {[]string{"v0.0.1", "0.0.2"}, "0.0.3"}, 17 | } 18 | 19 | var testsMetaIntel = []testPair{ 20 | {[]string{"0.0.1+amd", "0.0.1+intel", "0.0.2+amd", "0.0.3+amd"}, "0.0.2+intel"}, 21 | } 22 | 23 | var testsMetaAmd = []testPair{ 24 | {[]string{"0.0.1+amd", "0.0.1+intel", "0.0.2+amd", "0.0.3+amd"}, "0.0.4+amd"}, 25 | } 26 | 27 | func TestFindCurrentTag(t *testing.T) { 28 | createCli("").runScenarios(t, tests) 29 | } 30 | 31 | func TestFindCurrentTagForMeta(t *testing.T) { 32 | createCli("intel").runScenarios(t, testsMetaIntel) 33 | createCli("amd").runScenarios(t, testsMetaAmd) 34 | } 35 | 36 | func (c *CLI) runScenarios(t *testing.T, scenarios []testPair) { 37 | for _, pair := range scenarios { 38 | currentVersion, _ := c.findCurrentVersion(pair.tags) 39 | nextVersion, _ := c.createNextVersion(currentVersion) 40 | if nextVersion != pair.nextVersion { 41 | t.Error( 42 | "For", pair.tags, 43 | "expected", pair.nextVersion, 44 | "got", nextVersion, 45 | ) 46 | } 47 | } 48 | } 49 | 50 | func createCli(meta string) *CLI { 51 | cli := CLI{ 52 | Stdout: ioutil.Discard, 53 | Stderr: ioutil.Discard, 54 | Repo: nil, 55 | Option: Option{Major: false, Minor: false, Patch: true, Meta: meta, Quiet: true}, 56 | } 57 | return &cli 58 | } 59 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io" 7 | "io/ioutil" 8 | "os" 9 | "sort" 10 | "strings" 11 | 12 | "github.com/Masterminds/semver/v3" 13 | "github.com/Songmu/gitconfig" 14 | "github.com/jessevdk/go-flags" 15 | "github.com/manifoldco/promptui" 16 | "gopkg.in/src-d/go-git.v4" 17 | "gopkg.in/src-d/go-git.v4/config" 18 | "gopkg.in/src-d/go-git.v4/plumbing" 19 | "gopkg.in/src-d/go-git.v4/plumbing/object" 20 | "gopkg.in/src-d/go-git.v4/plumbing/transport/http" 21 | ) 22 | 23 | // These variables are set in build step 24 | var ( 25 | Version = "unset" 26 | Revision = "unset" 27 | ) 28 | 29 | const ( 30 | Prefix string = "v" 31 | ) 32 | 33 | type Spec int 34 | 35 | const ( 36 | Major Spec = iota 37 | Minor 38 | Patch 39 | ) 40 | 41 | type CLI struct { 42 | Option Option 43 | Stdout io.Writer 44 | Stderr io.Writer 45 | Repo *git.Repository 46 | 47 | initial *semver.Version 48 | } 49 | 50 | type Option struct { 51 | Major bool `long:"major" description:"Bump up major version"` 52 | Minor bool `long:"minor" description:"Bump up minor version"` 53 | Patch bool `long:"patch" description:"Bump up patch version"` 54 | 55 | Meta string `short:"m" long:"meta" description:"Version metadata" optional:"yes" default:""` 56 | 57 | Quiet bool `short:"q" long:"quiet" description:"Be quiet"` 58 | } 59 | 60 | func main() { 61 | os.Exit(run(os.Args[1:])) 62 | } 63 | 64 | func run(args []string) int { 65 | var opt Option 66 | args, err := flags.ParseArgs(&opt, args) 67 | if err != nil { 68 | return 1 69 | } 70 | cli := CLI{ 71 | Option: opt, 72 | Stdout: os.Stdout, 73 | Stderr: os.Stderr, 74 | Repo: nil, 75 | } 76 | if err := cli.Run(args); err != nil { 77 | fmt.Fprintf(os.Stderr, "[ERROR] %v\n", err) 78 | return 1 79 | } 80 | return 0 81 | } 82 | 83 | func (c *CLI) Run(args []string) error { 84 | if c.Option.Quiet { 85 | c.Stdout, c.Stderr = ioutil.Discard, ioutil.Discard 86 | } 87 | 88 | var wd string 89 | switch len(args) { 90 | case 0: 91 | wd = "." 92 | default: 93 | wd = args[0] 94 | } 95 | 96 | r, err := git.PlainOpen(wd) 97 | if err != nil { 98 | if errors.Is(err, git.ErrRepositoryNotExists) { 99 | // make error message git-like 100 | return errors.New("fatal: not a git repository") 101 | } 102 | return err 103 | } 104 | c.Repo = r 105 | 106 | current, err := c.currentVersion() 107 | if err != nil { 108 | return err 109 | } 110 | 111 | tag, err := c.createNextVersion(current) 112 | if err != nil { 113 | return err 114 | } 115 | 116 | return c.PushTag(tag) 117 | } 118 | 119 | func (c *CLI) createNextVersion(current *semver.Version) (string, error) { 120 | next, err := c.nextVersion(current) 121 | if err != nil { 122 | return "", err 123 | } 124 | 125 | tag := next.String() 126 | if strings.HasPrefix(current.Original(), Prefix) { 127 | tag = Prefix + next.String() 128 | } 129 | 130 | if len(c.Option.Meta) != 0 { 131 | if strings.HasSuffix(current.Original(), c.Option.Meta) { 132 | tag = next.String() + "+" + c.Option.Meta 133 | } 134 | } 135 | return tag, nil 136 | } 137 | 138 | func (c Spec) String() string { 139 | switch c { 140 | case Major: 141 | return "major" 142 | case Minor: 143 | return "minor" 144 | case Patch: 145 | return "patch" 146 | default: 147 | return "unknown" 148 | } 149 | } 150 | 151 | func (c *CLI) PushTag(tag string) error { 152 | head, err := c.Repo.Head() 153 | if err != nil { 154 | return err 155 | } 156 | 157 | commit, err := c.Repo.CommitObject(head.Hash()) 158 | if err != nil { 159 | return err 160 | } 161 | 162 | user, err := gitconfig.User() 163 | if err != nil { 164 | return err 165 | } 166 | 167 | email, err := gitconfig.Email() 168 | if err != nil { 169 | return err 170 | } 171 | 172 | opts := &git.CreateTagOptions{ 173 | Tagger: &object.Signature{ 174 | Name: user, 175 | Email: email, 176 | When: commit.Committer.When, 177 | }, 178 | Message: commit.Message, 179 | // SignKey: TODO: set gpg sign key 180 | } 181 | 182 | _, err = c.Repo.CreateTag(tag, head.Hash(), opts) 183 | if err != nil { 184 | return err 185 | } 186 | 187 | fmt.Fprintf(c.Stdout, "Bump version to %q.\n", tag) 188 | 189 | // TODO: set if all tags 190 | // rs := config.RefSpec("refs/tags/*:refs/tags/*") 191 | rs := config.RefSpec(fmt.Sprintf("refs/tags/%s:refs/tags/%s", tag, tag)) 192 | 193 | defer fmt.Fprintf(c.Stdout, "Pushed to origin.\n") 194 | return c.Repo.Push(&git.PushOptions{ 195 | Auth: &http.BasicAuth{ 196 | Username: user, 197 | Password: os.Getenv("GITHUB_TOKEN"), 198 | }, 199 | RemoteName: "origin", 200 | RefSpecs: []config.RefSpec{rs}, 201 | Progress: c.Stdout, 202 | }) 203 | } 204 | 205 | func (c *CLI) newVersion() (*semver.Version, error) { 206 | validate := func(input string) error { 207 | _, err := semver.NewVersion(input) 208 | return err 209 | } 210 | 211 | prompt := promptui.Prompt{ 212 | Label: "New version", 213 | Validate: validate, 214 | } 215 | 216 | v, err := prompt.Run() 217 | if err != nil { 218 | return nil, err 219 | } 220 | 221 | return semver.NewVersion(v) 222 | } 223 | 224 | func (c *CLI) currentVersion() (*semver.Version, error) { 225 | var current *semver.Version 226 | 227 | tagrefs, err := c.Repo.Tags() 228 | if err != nil { 229 | return current, err 230 | } 231 | 232 | var tags []string 233 | err = tagrefs.ForEach(func(t *plumbing.Reference) error { 234 | tag := t.Name() 235 | if tag.IsTag() { 236 | tags = append(tags, tag.Short()) 237 | } 238 | return nil 239 | }) 240 | if err != nil { 241 | return current, err 242 | } 243 | 244 | return c.findCurrentVersion(tags) 245 | } 246 | 247 | func (c *CLI) findCurrentVersion(tags []string) (*semver.Version, error) { 248 | var current *semver.Version 249 | 250 | tags = filterTagsWithMeta(tags, c.Option.Meta) 251 | 252 | // No tags found 253 | if len(tags) == 0 { 254 | v, err := c.newVersion() 255 | if err != nil { 256 | return current, fmt.Errorf("%w: cannot create new version", err) 257 | } 258 | c.initial = v 259 | return v, nil 260 | } 261 | 262 | vs := make([]*semver.Version, 0) 263 | for _, tag := range tags { 264 | v, err := semver.NewVersion(tag) 265 | if err != nil { 266 | continue 267 | } 268 | vs = append(vs, v) 269 | } 270 | 271 | sort.Sort(semver.Collection(vs)) 272 | 273 | last := len(vs) - 1 274 | current = vs[last] 275 | 276 | fmt.Fprintln(c.Stdout, "Tags:") 277 | for i, v := range vs { 278 | msg := fmt.Sprintf("- %s", v.Original()) 279 | if i == last { 280 | msg = fmt.Sprintf("- %s (current version)", v.Original()) 281 | } 282 | fmt.Fprintln(c.Stdout, msg) 283 | } 284 | fmt.Fprintln(c.Stdout) 285 | 286 | return current, nil 287 | } 288 | 289 | func filterTagsWithMeta(tags []string, meta string) []string { 290 | var filteredTags []string 291 | for _, tag := range tags { 292 | if strings.HasSuffix(tag, meta) { 293 | filteredTags = append(filteredTags, tag) 294 | } 295 | } 296 | return filteredTags 297 | } 298 | 299 | func (c *CLI) prompt(label string, items []Spec) (Spec, error) { 300 | prompt := promptui.Select{ 301 | Label: label, 302 | Items: items, 303 | HideSelected: true, 304 | } 305 | i, _, err := prompt.Run() 306 | return items[i], err 307 | } 308 | 309 | func (c *CLI) nextVersion(current *semver.Version) (semver.Version, error) { 310 | var next semver.Version 311 | 312 | if c.initial != nil { 313 | return *c.initial, nil 314 | } 315 | 316 | specs := []Spec{} 317 | if c.Option.Major { 318 | specs = append(specs, Major) 319 | } 320 | if c.Option.Minor { 321 | specs = append(specs, Minor) 322 | } 323 | if c.Option.Patch { 324 | specs = append(specs, Patch) 325 | } 326 | 327 | label := fmt.Sprintf("Current tag is %q. Next is?", current.Original()) 328 | 329 | var spec Spec 330 | var err error 331 | switch len(specs) { 332 | case 0: 333 | // No flags specified 334 | spec, err = c.prompt(label, []Spec{Patch, Minor, Major}) 335 | if err != nil { 336 | return next, fmt.Errorf("%w: failed to select valid semver spec", err) 337 | } 338 | case 1: 339 | // One flag 340 | spec = specs[0] 341 | default: 342 | // Multiple: e.g. --major --patch 343 | spec, err = c.prompt(label, specs) 344 | if err != nil { 345 | return next, fmt.Errorf("%w: failed to select valid semver spec", err) 346 | } 347 | } 348 | 349 | switch spec { 350 | case Major: 351 | next = current.IncMajor() 352 | case Minor: 353 | next = current.IncMinor() 354 | case Patch: 355 | next = current.IncPatch() 356 | default: 357 | return next, errors.New("invalid semver") 358 | } 359 | 360 | return next, nil 361 | } 362 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/Masterminds/semver/v3 v3.0.3 h1:znjIyLfpXEDQjOIEWh+ehwpTU14UzUPub3c3sm36u14= 2 | github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= 3 | github.com/Songmu/gitconfig v0.0.3 h1:mLLrCol+zLOxbX/0Pp+O8VgEjBPEMu3bZyw+vs/wBY8= 4 | github.com/Songmu/gitconfig v0.0.3/go.mod h1:0b3ML3J86L0tp1SB7qU4vZfezHS2s+PIczPsf23GAdk= 5 | github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= 6 | github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= 7 | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= 8 | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= 9 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= 10 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 11 | github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= 12 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 13 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= 14 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 15 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= 16 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 17 | github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= 18 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 19 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 20 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 21 | github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= 22 | github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= 23 | github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= 24 | github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= 25 | github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= 26 | github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= 27 | github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= 28 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 29 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= 30 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= 31 | github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= 32 | github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 33 | github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU= 34 | github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= 35 | github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= 36 | github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= 37 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 38 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 39 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 40 | github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= 41 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 42 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 43 | github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a h1:weJVJJRzAJBFRlAiJQROKQs8oC9vOxvm4rZmBBk0ONw= 44 | github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= 45 | github.com/manifoldco/promptui v0.7.0 h1:3l11YT8tm9MnwGFQ4kETwkzpAwY2Jt9lCrumCUW4+z4= 46 | github.com/manifoldco/promptui v0.7.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ= 47 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= 48 | github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= 49 | github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 50 | github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 51 | github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= 52 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 53 | github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= 54 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 55 | github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= 56 | github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= 57 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 58 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 59 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 60 | github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= 61 | github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= 62 | github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= 63 | github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= 64 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 65 | github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= 66 | github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= 67 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 68 | github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= 69 | github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= 70 | golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 71 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 72 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= 73 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 74 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 75 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 76 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= 77 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 78 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 79 | golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 80 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 81 | golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 82 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 83 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 84 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 85 | golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d h1:/m5NbqQelATgoSPVC2Z23sR4kVNokFwDDyWh/3rGY+I= 86 | golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 87 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 88 | golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= 89 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 90 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 91 | golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= 92 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 93 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 94 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 95 | gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg= 96 | gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= 97 | gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg= 98 | gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= 99 | gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE= 100 | gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= 101 | gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= 102 | gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= 103 | gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= 104 | gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 105 | --------------------------------------------------------------------------------