├── .dockerignore ├── .gitignore ├── .gitlab-ci.yml ├── .gitmodules ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── cmd └── semver │ ├── bump │ ├── main.go │ ├── major │ │ └── major.go │ ├── minor │ │ └── minor.go │ ├── patch │ │ └── patch.go │ ├── prerelease │ │ └── prerelease.go │ └── utils │ │ └── utils.go │ ├── common │ └── config.go │ ├── main.go │ └── main_test.go ├── deploy ├── Dockerfile └── Dockerfile.yaml ├── go.mod ├── go.sum ├── init ├── .gitignore └── install.sh └── internal ├── repo ├── git.go └── git_test.go └── utils ├── semver.go └── semver_test.go /.dockerignore: -------------------------------------------------------------------------------- 1 | bin 2 | deploy 3 | vendor 4 | *.md 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dev artifacts 2 | bin 3 | c.out 4 | vendor 5 | 6 | # make artifacts 7 | .publish_origin 8 | .ssh 9 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: golang:1.14 2 | stages: 3 | - init 4 | - test & build 5 | - release 6 | - package 7 | - publish 8 | 9 | init: 10 | stage: init 11 | image: usvc/ci:go-dependencies 12 | cache: 13 | key: ${CI_COMMIT_REF_NAME} 14 | paths: ["./vendor"] 15 | artifacts: 16 | paths: ["./vendor"] 17 | script: ["entrypoint"] 18 | 19 | unit test: 20 | stage: test & build 21 | image: usvc/ci:go-test 22 | dependencies: ["init"] 23 | artifacts: 24 | paths: ["./c.out"] 25 | script: ["entrypoint"] 26 | 27 | .build: 28 | image: usvc/ci:go-build-production 29 | stage: test & build 30 | dependencies: ["init"] 31 | artifacts: 32 | paths: ["./bin/*"] 33 | variables: 34 | BIN_NAME: semver 35 | before_script: ["git fetch"] 36 | script: ["entrypoint"] 37 | .build_linux: 38 | extends: .build 39 | variables: 40 | GOOS: linux 41 | GOARCH: amd64 42 | build linux (test): 43 | extends: .build_linux 44 | only: ["master"] 45 | build linux: 46 | extends: .build_linux 47 | only: ["tags"] 48 | .build_macos: 49 | extends: .build 50 | variables: 51 | GOOS: darwin 52 | GOARCH: amd64 53 | build macos (test): 54 | extends: .build_macos 55 | only: ["master"] 56 | build macos: 57 | extends: .build_macos 58 | only: ["tags"] 59 | .build_windows: 60 | extends: .build 61 | variables: 62 | GOOS: windows 63 | GOARCH: "386" 64 | build windows (test): 65 | extends: .build_windows 66 | only: ["master"] 67 | build windows: 68 | extends: .build_windows 69 | only: ["tags"] 70 | 71 | version bump: 72 | stage: release 73 | only: ["master"] 74 | image: usvc/ci:version-bump-gitlab 75 | script: ["entrypoint"] 76 | 77 | coverage report: 78 | allow_failure: true 79 | stage: release 80 | dependencies: ["unit test"] 81 | image: usvc/ci:go-coverage-code-climate 82 | script: ["entrypoint"] 83 | 84 | compress: 85 | stage: package 86 | only: ["tags"] 87 | # allow failure because it's not necessary to always compress 88 | # even though that would be nice 89 | allow_failure: true 90 | dependencies: ["build linux", "build macos", "build windows"] 91 | artifacts: 92 | paths: ["./bin/*"] 93 | before_script: 94 | - apt-get update && apt-get upgrade -y 95 | - apt-get install -y make g++ upx 96 | script: 97 | - GOOS=linux GOARCH=amd64 make compress 98 | - GOOS=darwin GOARCH=amd64 make compress 99 | - GOOS=windows GOARCH=386 BIN_EXT=.exe make compress 100 | 101 | dockerize: 102 | stage: package 103 | only: ["tags"] 104 | services: ["docker:19.03.1-dind"] 105 | image: usvc/ci:docker-build 106 | artifacts: 107 | paths: ["./build/*"] 108 | variables: 109 | DOCKER_IMAGE_URL: usvc/semver 110 | script: ["entrypoint"] 111 | 112 | dockerhub: 113 | stage: publish 114 | only: ["tags"] 115 | services: ["docker:19.03.1-dind"] 116 | image: usvc/ci:docker-publish 117 | dependencies: ["dockerize"] 118 | variables: 119 | DOCKER_IMAGE_URL: usvc/semver 120 | script: ["entrypoint"] 121 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "scripts/versioning"] 2 | path = scripts/versioning 3 | url = https://gitlab.com/usvc/dev/go-generate-version.git 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | git: 3 | submodules: true 4 | quiet: false 5 | language: go 6 | go: 7 | - 1.14.x 8 | deploy: 9 | provider: releases 10 | api_key: "${RELEASE_TOKEN}" 11 | file_glob: true 12 | file: ./bin/* 13 | skip_cleanup: true 14 | on: 15 | branch: master 16 | tags: true 17 | before_script: 18 | - sudo apt-get update 19 | - sudo apt-get install -y make git g++ upx 20 | script: 21 | - make deps 22 | - GOOS=linux GOARCH=amd64 make build_production 23 | - GOOS=darwin GOARCH=amd64 make build_production 24 | - GOOS=windows GOARCH=386 BIN_EXT=.exe make build_production 25 | - GOOS=linux GOARCH=amd64 make compress || true 26 | - GOOS=darwin GOARCH=amd64 make compress || true 27 | - GOOS=windows GOARCH=386 BIN_EXT=.exe make compress || true 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-present Joseph Matthias Goh 4 | 5 | All rights reserved. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CMD_ROOT=semver 2 | DOCKER_NAMESPACE=usvc 3 | DOCKER_IMAGE_NAME=semver 4 | PROJECT_NAME=semver 5 | GIT_COMMIT=$$(git rev-parse --verify HEAD) 6 | GIT_TAG=$$(git describe --tag $$(git rev-list --tags --max-count=1)) 7 | TIMESTAMP=$(shell date +'%Y%m%d%H%M%S') 8 | 9 | -include ./makefile.properties 10 | 11 | BIN_PATH=$(CMD_ROOT)_$$(go env GOOS)_$$(go env GOARCH)${BIN_EXT} 12 | 13 | deps: 14 | go mod vendor -v 15 | go mod tidy -v 16 | run: 17 | go run ./cmd/$(CMD_ROOT) 18 | test: 19 | go test -v ./... -cover -coverprofile c.out 20 | build: 21 | go build \ 22 | -o ./bin/$(BIN_PATH) \ 23 | ./cmd/$(CMD_ROOT) 24 | build_production: 25 | CGO_ENABLED=0 \ 26 | go build -a -v \ 27 | -ldflags "-X main.Commit=$(GIT_COMMIT) \ 28 | -X main.Version=$(GIT_TAG) \ 29 | -X main.Timestamp=$(TIMESTAMP) \ 30 | -extldflags 'static' \ 31 | -s -w" \ 32 | -o ./bin/$(BIN_PATH) \ 33 | ./cmd/$(CMD_ROOT) 34 | sha256sum -b ./bin/$(BIN_PATH) \ 35 | | cut -f 1 -d ' ' > ./bin/$(BIN_PATH).sha256 36 | ls -lah ./bin/$(BIN_PATH)* 37 | compress: 38 | ls -lah ./bin/$(BIN_PATH) 39 | upx -9 -v -o ./bin/.$(BIN_PATH) \ 40 | ./bin/$(BIN_PATH) 41 | upx -t ./bin/.$(BIN_PATH) 42 | rm -rf ./bin/$(BIN_PATH) 43 | mv ./bin/.$(BIN_PATH) \ 44 | ./bin/$(BIN_PATH) 45 | sha256sum -b ./bin/$(BIN_PATH) \ 46 | | cut -f 1 -d ' ' > ./bin/$(BIN_PATH).sha256 47 | ls -lah ./bin/$(BIN_PATH) 48 | 49 | image: 50 | docker build \ 51 | --build-arg GIT_COMMIT_ID=$(GIT_COMMIT) \ 52 | --build-arg GIT_TAG=$(GIT_TAG) \ 53 | --build-arg BUILD_TIMESTAMP=$(TIMESTAMP) \ 54 | --file ./deploy/Dockerfile \ 55 | --tag $(DOCKER_NAMESPACE)/$(DOCKER_IMAGE_NAME):latest \ 56 | . 57 | test_image: 58 | container-structure-test test \ 59 | --config ./deploy/Dockerfile.yaml \ 60 | --image $(DOCKER_NAMESPACE)/$(DOCKER_IMAGE_NAME):latest 61 | save: 62 | mkdir -p ./build 63 | docker save --output ./build/$(PROJECT_NAME).tar.gz $(DOCKER_NAMESPACE)/$(DOCKER_IMAGE_NAME):latest 64 | load: 65 | docker load --input ./build/$(PROJECT_NAME).tar.gz 66 | dockerhub: 67 | docker push $(DOCKER_NAMESPACE)/$(DOCKER_IMAGE_NAME):latest 68 | git fetch 69 | docker tag $(DOCKER_NAMESPACE)/$(DOCKER_IMAGE_NAME):latest \ 70 | $(DOCKER_NAMESPACE)/$(DOCKER_IMAGE_NAME):$$(git describe --tag $$(git rev-list --tags --max-count=1)) 71 | docker push $(DOCKER_NAMESPACE)/$(DOCKER_IMAGE_NAME):$$(git describe --tag $$(git rev-list --tags --max-count=1)) 72 | 73 | see_ci: 74 | xdg-open https://gitlab.com/usvc/modules/go/semver/pipelines 75 | 76 | .ssh: 77 | mkdir -p ./.ssh 78 | ssh-keygen -t rsa -b 8192 -f ./.ssh/id_rsa -q -N "" 79 | cat ./.ssh/id_rsa | base64 -w 0 > ./.ssh/id_rsa.base64 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Semver 2 | 3 | [![release github](https://badge.fury.io/gh/usvc%2Fsemver.svg)](https://github.com/usvc/semver/releases) 4 | [![pipeline status](https://gitlab.com/usvc/utils/semver/badges/master/pipeline.svg)](https://gitlab.com/usvc/utils/semver/commits/master) 5 | [![build btatus](https://travis-ci.org/usvc/semver.svg?branch=master)](https://travis-ci.org/usvc/semver) 6 | [![Test Coverage](https://api.codeclimate.com/v1/badges/5b9ad81dab4d4e4ddd1c/test_coverage)](https://codeclimate.com/github/usvc/semver/test_coverage) 7 | [![Maintainability](https://api.codeclimate.com/v1/badges/5b9ad81dab4d4e4ddd1c/maintainability)](https://codeclimate.com/github/usvc/semver/maintainability) 8 | 9 | An easy-peasy CLI tool to bump semver versions. 10 | 11 | | | | 12 | | --- | --- | 13 | | Github | [https://github.com/usvc/semver](https://github.com/usvc/semver) | 14 | | Gitlab | [https://gitlab.com/usvc/utils/semver](https://gitlab.com/usvc/utils/semver) | 15 | 16 | - - - 17 | 18 | - [Semver](#semver) 19 | - [Installation](#installation) 20 | - [Via Go Get](#via-go-get) 21 | - [Binary Download](#binary-download) 22 | - [Via cURL](#via-curl) 23 | - [Via `/bin/sh`](#via-binsh) 24 | - [Usage](#usage) 25 | - [CLI Help](#cli-help) 26 | - [Bump a provided version](#bump-a-provided-version) 27 | - [Bump a version using Git tags](#bump-a-version-using-git-tags) 28 | - [Bump Git tag version](#bump-git-tag-version) 29 | - [Usage via Dockerfile](#usage-via-dockerfile) 30 | - [Usage in a CI pipeline](#usage-in-a-ci-pipeline) 31 | - [GitLab CI (Automated)](#gitlab-ci-automated) 32 | - [GitLab CI (Manual)](#gitlab-ci-manual) 33 | - [Usage notes](#usage-notes) 34 | - [Development](#development) 35 | - [Install dependencies](#install-dependencies) 36 | - [Run tests](#run-tests) 37 | - [Run the Go code](#run-the-go-code) 38 | - [Without arguments](#without-arguments) 39 | - [With arguments](#with-arguments) 40 | - [Create semver binary](#create-semver-binary) 41 | - [Development Runbook](#development-runbook) 42 | - [Getting Started](#getting-started) 43 | - [Continuous Integration (CI) Pipeline](#continuous-integration-ci-pipeline) 44 | - [On Github](#on-github) 45 | - [Releasing](#releasing) 46 | - [On Gitlab](#on-gitlab) 47 | - [Version Bumping](#version-bumping) 48 | - [DockerHub Publishing](#dockerhub-publishing) 49 | - [License](#license) 50 | 51 | - - - 52 | 53 | # Installation 54 | 55 | ## Via Go Get 56 | 57 | ```sh 58 | go get -v -u github.com/usvc/semver/cmd/semver 59 | ``` 60 | 61 | ## Binary Download 62 | 63 | Get the latest binary for your operating system from [https://github.com/usvc/semver/releases](https://github.com/usvc/semver/releases). 64 | 65 | ## Via cURL 66 | 67 | ```sh 68 | # linux 69 | curl -oL https://github.com/usvc/semver/releases/download/v0.3.17/semver_linux_amd64 70 | 71 | # macos 72 | curl -oL https://github.com/usvc/semver/releases/download/v0.3.17/semver_darwin_amd64 73 | 74 | # windows 75 | curl -oL https://github.com/usvc/semver/releases/download/v0.3.17/semver_windows_386.exe 76 | ``` 77 | 78 | ## Via `/bin/sh` 79 | 80 | ```sh 81 | curl -L https://raw.githubusercontent.com/usvc/semver/master/init/install.sh | sh 82 | ``` 83 | 84 | > This script downloads the latest binary to your working directory. 85 | 86 | - - - 87 | 88 | # Usage 89 | 90 | ## CLI Help 91 | 92 | **Use Case** - As a developer, I'd like to find out how to use `semver` from the CLI 93 | 94 | ```sh 95 | semver -h 96 | ``` 97 | 98 | ## Bump a provided version 99 | 100 | **Use Case** - As a developer, I'd like to do a bump of a semver version string and receive the next version as the output. 101 | 102 | ```sh 103 | # major version bump: 104 | semver bump major 1.2.3-label.1 105 | # > 2.0.0 106 | 107 | # minor version bump: 108 | semver bump minor 1.2.3-label.1 109 | # > 1.3.0 110 | 111 | # patch version bump 112 | semver bump patch 1.2.3-label.1 113 | # OR simply... 114 | semver bump 1.2.3-label.1 115 | # > 1.2.4 116 | 117 | # prerelease iteration bump 118 | semver bump 1.2.3-prerelease.1 -l 119 | # > 1.2.3-prerelease.2 120 | ``` 121 | 122 | ## Bump a version using Git tags 123 | 124 | **Use Case** - As a developer, I'd like to receive an output of the bumped version, using the latest semver version in a Git repository's tags as input. 125 | 126 | ```sh 127 | # bump the major version (assuming git tag 'v1.2.3' exists): 128 | semver bump major --git 129 | # > v2.0.0 130 | 131 | # bump the minor version (assuming git tag 'v1.2.3' exists): 132 | semver bump minor --git 133 | # > v1.3.0 134 | 135 | # bump the patch version (assuming git tag 'v1.2.3' exists): 136 | semver bump patch --git 137 | # OR simply... 138 | semver bump --git 139 | # > v1.2.4 140 | 141 | # bump the prerelease version (assuming git tag 'v1.2.3-prerelease.0' exists): 142 | semver bump --git 143 | # > v1.2.3-prerelease.1 144 | ``` 145 | 146 | ## Bump Git tag version 147 | 148 | **Use Case** - As a developer, I'd like to run a single command that gets the latest semver version in a Git repository's tags, bumps it, and adds it to the repository's tags. 149 | 150 | ```sh 151 | # bump the major version: 152 | semver bump --git --apply -M 153 | # > added git tag 'vX.0.0' 154 | 155 | # bump the minor version: 156 | semver bump --git --apply -m 157 | # > added git tag 'vX.Y.0' 158 | 159 | # bump the patch version: 160 | semver bump --git --apply -p 161 | # > added git tag 'vX.Y.Z' 162 | 163 | # bump the label version: 164 | semver bump --git --apply -l 165 | # > added git tag 'vX.Y.Z-label.A' 166 | ``` 167 | 168 | ## Usage via Dockerfile 169 | 170 | ```sh 171 | docker run -it -v $(pwd):/repo usvc/semver:latest ${SUBCOMMANDS_AND_FLAGS} 172 | ``` 173 | 174 | > Replace `${SUBCOMMANDS_AND_FLAGS}` with whatever you would run behind the main `semver` command. 175 | 176 | ## Usage in a CI pipeline 177 | 178 | ### GitLab CI (Automated) 179 | 180 | To use the inbuilt scripts, you need to define the following variables in your CI pipeline: 181 | 182 | | Key | Description | 183 | | ---: | :--- | 184 | | `BASE64_DEPLOY_KEY` | Base64-encoded deploy key | 185 | | `GIT_EMAIL` | Email of the Git user to use to push | 186 | | `GIT_NAME` | Name of the Git user to use to push | 187 | | `REPO_HOSTNAME` | Hostname of the repository | 188 | | `REPO_URL` | Repository clone URL (the SSH one) | 189 | 190 | Then use the following job specification: 191 | 192 | ```yaml 193 | bump: 194 | only: ["master"] 195 | stage: versioning 196 | image: usvc/semver:gitlab-latest 197 | before_script: 198 | - bump-before 199 | script: 200 | - bump-script 201 | after_script: 202 | - bump-after 203 | ``` 204 | 205 | ### GitLab CI (Manual) 206 | 207 | An example version bump job together with pushing back to the repository can be as such: 208 | 209 | ```yaml 210 | bump: 211 | only: ["master"] 212 | stage: versioning 213 | before_script: 214 | - mkdir -p ~/.ssh 215 | - 'printf -- "${DEPLOY_KEY}" | base64 -d > ~/.ssh/id_rsa' 216 | - chmod 600 -R ~/.ssh/id_rsa 217 | - ssh-keyscan -t rsa gitlab.com >> ~/.ssh/known_hosts 218 | script: 219 | - git remote set-url origin "${DEPLOY_URL}" 220 | - git checkout master 221 | - docker run -v $(pwd):/repo usvc/semver:latest + --git --apply 222 | - git push origin master --verbose --tags 223 | after_script: 224 | - rm -rf ~/.ssh/* 225 | ``` 226 | 227 | Set the `DEPLOY_KEY` environment variable from your CI/CD settings to a base64 encoded version of your private key. To generate a private/public key pair, use `ssh-keygen -t rsa -b 4096`. To encode it into base64 without line breaks, `cat` it and pipe it to `base64 -w 0` (eg. `cat ./path/to/id_rsa | base64 -w 0 > ./path/to/id_rsa.b64`). 228 | 229 | Set the `DEPLOY_URL` environment variable from your CI/CD settings to the SSH clone URL of the repository you'd like to push to. 230 | 231 | ## Usage notes 232 | 233 | - If the major (`-M`), minor (`-m`), patch (`-p`), or label (`-l`) flag is not specified, the patch will be bumped by default. 234 | - If more than one instance of a version indicator flag is specified, the lowest priority will be executed. For example, if both `-M` and `-m` is specified, `-m` will be applied. 235 | 236 | - - - 237 | 238 | # Development 239 | 240 | Canonical repository URL: https://gitlab.com/usvc/utils/semver 241 | Public URL: https://github.com/usvc/semver 242 | 243 | ## Install dependencies 244 | 245 | ```sh 246 | make dep 247 | ``` 248 | 249 | ## Run tests 250 | 251 | ```sh 252 | make test 253 | ``` 254 | 255 | ## Run the Go code 256 | 257 | ### Without arguments 258 | 259 | ```sh 260 | make semver_run 261 | ``` 262 | 263 | ### With arguments 264 | 265 | ```sh 266 | make semver_run ARGS="bump 1.2.3 -m" 267 | ``` 268 | 269 | ## Create semver binary 270 | 271 | ```sh 272 | make semver 273 | ``` 274 | 275 | - - - 276 | 277 | ## Development Runbook 278 | 279 | ### Getting Started 280 | 281 | 1. Clone this repository 282 | 2. Run `make deps` to pull in external dependencies 283 | 3. Write some awesome stuff 284 | 4. Run `make test` to ensure unit tests are passing 285 | 5. Push 286 | 287 | ### Continuous Integration (CI) Pipeline 288 | 289 | #### On Github 290 | 291 | Github is used to deploy binaries/libraries because of it's ease of access by other developers. 292 | 293 | ##### Releasing 294 | 295 | Releasing of the binaries can be done via Travis CI. 296 | 297 | 1. On Github, navigate to the [tokens settings page](https://github.com/settings/tokens) (by clicking on your profile picture, selecting **Settings**, selecting **Developer settings** on the left navigation menu, then **Personal Access Tokens** again on the left navigation menu) 298 | 2. Click on **Generate new token**, give the token an appropriate name and check the checkbox on **`public_repo`** within the **repo** header 299 | 3. Copy the generated token 300 | 4. Navigate to [travis-ci.org](https://travis-ci.org) and access the cooresponding repository there. Click on the **More options** button on the top right of the repository page and select **Settings** 301 | 5. Scroll down to the section on **Environment Variables** and enter in a new **NAME** with `RELEASE_TOKEN` and the **VALUE** field cooresponding to the generated personal access token, and hit **Add** 302 | 303 | #### On Gitlab 304 | 305 | Gitlab is used to run tests and ensure that builds run correctly. 306 | 307 | ##### Version Bumping 308 | 309 | 1. Run `make .ssh` 310 | 2. Copy the contents of the file generated at `./.ssh/id_rsa.base64` into an environment variable named **`DEPLOY_KEY`** in **Settings > CI/CD > Variables** 311 | 3. Navigate to the **Deploy Keys** section of the **Settings > Repository > Deploy Keys** and paste in the contents of the file generated at `./.ssh/id_rsa.pub` with the **Write access allowed** checkbox enabled 312 | 313 | - **`DEPLOY_KEY`**: generate this by running `make .ssh` and copying the contents of the file generated at `./.ssh/id_rsa.base64` 314 | 315 | ##### DockerHub Publishing 316 | 317 | 1. Login to [https://hub.docker.com](https://hub.docker.com), or if you're using your own private one, log into yours 318 | 2. Navigate to [your security settings at the `/settings/security` endpoint](https://hub.docker.com/settings/security) 319 | 3. Click on **Create Access Token**, type in a name for the new token, and click on **Create** 320 | 4. Copy the generated token that will be displayed on the screen 321 | 5. Enter the following varialbes into the CI/CD Variables page at **Settings > CI/CD > Variables** in your Gitlab repository: 322 | 323 | - **`DOCKER_REGISTRY_URL`**: The hostname of the Docker registry (defaults to `docker.io` if not specified) 324 | - **`DOCKER_REGISTRY_USERNAME`**: The username you used to login to the Docker registry 325 | - **`DOCKER_REGISTRY_PASSWORD`**: The generated access token 326 | 327 | # License 328 | 329 | This project is licensed under the MIT license. [See the full text](./LICENSE). 330 | -------------------------------------------------------------------------------- /cmd/semver/bump/main.go: -------------------------------------------------------------------------------- 1 | package bump 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/usvc/go-logger" 6 | "gitlab.com/usvc/utils/semver/cmd/semver/bump/major" 7 | "gitlab.com/usvc/utils/semver/cmd/semver/bump/minor" 8 | "gitlab.com/usvc/utils/semver/cmd/semver/bump/patch" 9 | "gitlab.com/usvc/utils/semver/cmd/semver/bump/prerelease" 10 | "gitlab.com/usvc/utils/semver/cmd/semver/common" 11 | ) 12 | 13 | var ( 14 | cmd *cobra.Command 15 | log logger.Logger 16 | ) 17 | 18 | func GetCommand() *cobra.Command { 19 | if cmd == nil { 20 | log = logger.New(logger.Options{}) 21 | cmd = &cobra.Command{ 22 | Use: "bump ", 23 | Run: func(command *cobra.Command, args []string) { 24 | command.Run(patch.GetCommand(), args) 25 | }, 26 | } 27 | common.Config.ApplyToCobra(cmd) 28 | cmd.AddCommand(major.GetCommand()) 29 | cmd.AddCommand(minor.GetCommand()) 30 | cmd.AddCommand(patch.GetCommand()) 31 | cmd.AddCommand(prerelease.GetCommand()) 32 | } 33 | return cmd 34 | } 35 | -------------------------------------------------------------------------------- /cmd/semver/bump/major/major.go: -------------------------------------------------------------------------------- 1 | package major 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/spf13/cobra" 7 | "github.com/usvc/go-logger" 8 | "github.com/usvc/go-semver" 9 | bumpUtils "gitlab.com/usvc/utils/semver/cmd/semver/bump/utils" 10 | "gitlab.com/usvc/utils/semver/cmd/semver/common" 11 | "gitlab.com/usvc/utils/semver/internal/utils" 12 | ) 13 | 14 | var ( 15 | cmd *cobra.Command 16 | errorLog = logger.New(logger.Options{ 17 | Type: logger.TypeStdout, 18 | Output: logger.OutputStderr, 19 | }) 20 | log = logger.New(logger.Options{ 21 | Type: logger.TypeStdout, 22 | }) 23 | ) 24 | 25 | func GetCommand() *cobra.Command { 26 | if cmd == nil { 27 | cmd = &cobra.Command{ 28 | Use: "major ", 29 | Run: func(command *cobra.Command, args []string) { 30 | hasArguments := (len(args) > 0) 31 | retrieveFromGit := common.Config.GetBool("git") 32 | applyToGit := common.Config.GetBool("apply") 33 | var version *semver.Semver 34 | var err error 35 | switch true { 36 | case retrieveFromGit: 37 | version, err = bumpUtils.GetCurrentRepositoryLatestSemver() 38 | case hasArguments: 39 | version, err = utils.GetSemverFromArguments(args) 40 | default: 41 | command.Help() 42 | return 43 | } 44 | if err != nil { 45 | errorLog.Errorf("failed to retrieve latest version: '%s'", err) 46 | os.Exit(1) 47 | } 48 | version.BumpMajor() 49 | log.Info(version.String()) 50 | if retrieveFromGit && applyToGit { 51 | log.Debugf("adding git tag '%s' to repository...", version.String()) 52 | if err = bumpUtils.SetCurrentRepositorySemver(version); err != nil { 53 | errorLog.Errorf("failed add tag to repository: '%s'", err) 54 | os.Exit(1) 55 | } 56 | log.Infof("added tag '%s'", version.String()) 57 | } 58 | }, 59 | } 60 | common.Config.ApplyToCobra(cmd) 61 | } 62 | return cmd 63 | } 64 | -------------------------------------------------------------------------------- /cmd/semver/bump/minor/minor.go: -------------------------------------------------------------------------------- 1 | package minor 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/spf13/cobra" 7 | "github.com/usvc/go-logger" 8 | "github.com/usvc/go-semver" 9 | bumpUtils "gitlab.com/usvc/utils/semver/cmd/semver/bump/utils" 10 | "gitlab.com/usvc/utils/semver/cmd/semver/common" 11 | "gitlab.com/usvc/utils/semver/internal/utils" 12 | ) 13 | 14 | var ( 15 | cmd *cobra.Command 16 | errorLog = logger.New(logger.Options{ 17 | Type: logger.TypeStdout, 18 | Output: logger.OutputStderr, 19 | }) 20 | log = logger.New(logger.Options{ 21 | Type: logger.TypeStdout, 22 | }) 23 | ) 24 | 25 | func GetCommand() *cobra.Command { 26 | if cmd == nil { 27 | cmd = &cobra.Command{ 28 | Use: "minor ", 29 | Run: func(command *cobra.Command, args []string) { 30 | hasArguments := (len(args) > 0) 31 | retrieveFromGit := common.Config.GetBool("git") 32 | applyToGit := common.Config.GetBool("apply") 33 | var version *semver.Semver 34 | var err error 35 | switch true { 36 | case retrieveFromGit: 37 | version, err = bumpUtils.GetCurrentRepositoryLatestSemver() 38 | case hasArguments: 39 | version, err = utils.GetSemverFromArguments(args) 40 | default: 41 | command.Help() 42 | return 43 | } 44 | if err != nil { 45 | errorLog.Errorf("failed to retrieve latest version: '%s'", err) 46 | os.Exit(1) 47 | } 48 | version.BumpMinor() 49 | log.Info(version.String()) 50 | if retrieveFromGit && applyToGit { 51 | log.Debugf("adding git tag '%s' to repository...", version.String()) 52 | if err = bumpUtils.SetCurrentRepositorySemver(version); err != nil { 53 | errorLog.Errorf("failed add tag to repository: '%s'", err) 54 | os.Exit(1) 55 | } 56 | log.Infof("added tag '%s'", version.String()) 57 | } 58 | }, 59 | } 60 | common.Config.ApplyToCobra(cmd) 61 | } 62 | return cmd 63 | } 64 | -------------------------------------------------------------------------------- /cmd/semver/bump/patch/patch.go: -------------------------------------------------------------------------------- 1 | package patch 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/spf13/cobra" 7 | "github.com/usvc/go-logger" 8 | "github.com/usvc/go-semver" 9 | bumpUtils "gitlab.com/usvc/utils/semver/cmd/semver/bump/utils" 10 | "gitlab.com/usvc/utils/semver/cmd/semver/common" 11 | "gitlab.com/usvc/utils/semver/internal/utils" 12 | ) 13 | 14 | var ( 15 | cmd *cobra.Command 16 | errorLog = logger.New(logger.Options{ 17 | Type: logger.TypeStdout, 18 | Output: logger.OutputStderr, 19 | }) 20 | log = logger.New(logger.Options{ 21 | Type: logger.TypeStdout, 22 | }) 23 | ) 24 | 25 | func GetCommand() *cobra.Command { 26 | if cmd == nil { 27 | cmd = &cobra.Command{ 28 | Use: "patch ", 29 | Run: func(command *cobra.Command, args []string) { 30 | hasArguments := (len(args) > 0) 31 | retrieveFromGit := common.Config.GetBool("git") 32 | applyToGit := common.Config.GetBool("apply") 33 | var version *semver.Semver 34 | var err error 35 | switch true { 36 | case retrieveFromGit: 37 | version, err = bumpUtils.GetCurrentRepositoryLatestSemver() 38 | case hasArguments: 39 | version, err = utils.GetSemverFromArguments(args) 40 | default: 41 | command.Help() 42 | return 43 | } 44 | if err != nil { 45 | errorLog.Errorf("failed to retrieve latest version: '%s'", err) 46 | os.Exit(1) 47 | } 48 | version.BumpPatch() 49 | log.Info(version.String()) 50 | if retrieveFromGit && applyToGit { 51 | log.Debugf("adding git tag '%s' to repository...", version.String()) 52 | if err = bumpUtils.SetCurrentRepositorySemver(version); err != nil { 53 | errorLog.Errorf("failed add tag to repository: '%s'", err) 54 | os.Exit(1) 55 | } 56 | log.Infof("added tag '%s'", version.String()) 57 | } 58 | }, 59 | } 60 | common.Config.ApplyToCobra(cmd) 61 | } 62 | return cmd 63 | } 64 | -------------------------------------------------------------------------------- /cmd/semver/bump/prerelease/prerelease.go: -------------------------------------------------------------------------------- 1 | package prerelease 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/spf13/cobra" 7 | "github.com/usvc/go-logger" 8 | "github.com/usvc/go-semver" 9 | bumpUtils "gitlab.com/usvc/utils/semver/cmd/semver/bump/utils" 10 | "gitlab.com/usvc/utils/semver/cmd/semver/common" 11 | "gitlab.com/usvc/utils/semver/internal/utils" 12 | ) 13 | 14 | var ( 15 | cmd *cobra.Command 16 | errorLog = logger.New(logger.Options{ 17 | Type: logger.TypeStdout, 18 | Output: logger.OutputStderr, 19 | }) 20 | log = logger.New(logger.Options{ 21 | Type: logger.TypeStdout, 22 | }) 23 | ) 24 | 25 | func GetCommand() *cobra.Command { 26 | if cmd == nil { 27 | cmd = &cobra.Command{ 28 | Use: "prerelease ", 29 | Run: func(command *cobra.Command, args []string) { 30 | hasArguments := (len(args) > 0) 31 | retrieveFromGit := common.Config.GetBool("git") 32 | applyToGit := common.Config.GetBool("apply") 33 | var version *semver.Semver 34 | var err error 35 | switch true { 36 | case retrieveFromGit: 37 | version, err = bumpUtils.GetCurrentRepositoryLatestSemver() 38 | case hasArguments: 39 | version, err = utils.GetSemverFromArguments(args) 40 | default: 41 | command.Help() 42 | return 43 | } 44 | if err != nil { 45 | errorLog.Errorf("failed to retrieve latest version: '%s'", err) 46 | os.Exit(1) 47 | } 48 | version.BumpPreRelease() 49 | log.Info(version.String()) 50 | if retrieveFromGit && applyToGit { 51 | log.Debugf("adding git tag '%s' to repository...", version.String()) 52 | if err = bumpUtils.SetCurrentRepositorySemver(version); err != nil { 53 | errorLog.Errorf("failed add tag to repository: '%s'", err) 54 | os.Exit(1) 55 | } 56 | log.Infof("added tag '%s'", version.String()) 57 | } 58 | }, 59 | } 60 | common.Config.ApplyToCobra(cmd) 61 | } 62 | return cmd 63 | } 64 | -------------------------------------------------------------------------------- /cmd/semver/bump/utils/utils.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/usvc/go-semver" 8 | "gitlab.com/usvc/utils/semver/internal/repo" 9 | ) 10 | 11 | func GetCurrentRepositoryLatestSemver() (*semver.Semver, error) { 12 | var ( 13 | currentDirectory string 14 | err error 15 | version *semver.Semver 16 | ) 17 | currentDirectory, err = os.Getwd() 18 | if err != nil { 19 | return nil, fmt.Errorf("failed to get current working directory: '%s'", err) 20 | } 21 | version, err = repo.GetLatestSemverFromGitRepository(currentDirectory) 22 | if err != nil { 23 | return nil, fmt.Errorf("failed to retrieve latest semver tag: '%s'", err) 24 | } 25 | return version, nil 26 | } 27 | 28 | func SetCurrentRepositorySemver(version *semver.Semver) error { 29 | currentDirectory, err := os.Getwd() 30 | if err != nil { 31 | return fmt.Errorf("failed to getting current working directory: '%s'", err) 32 | } 33 | err = repo.TagCurrentGitCommit(version.String(), currentDirectory) 34 | if err != nil { 35 | return fmt.Errorf("failed to add tag '%s' to repository at '%s': '%s'", version.String(), currentDirectory, err) 36 | } 37 | return nil 38 | } 39 | -------------------------------------------------------------------------------- /cmd/semver/common/config.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import "github.com/usvc/config" 4 | 5 | var ( 6 | Config = config.Map{ 7 | "git": &config.Bool{Shorthand: "g"}, 8 | "apply": &config.Bool{Shorthand: "A"}, 9 | } 10 | ) 11 | -------------------------------------------------------------------------------- /cmd/semver/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/spf13/cobra" 7 | "gitlab.com/usvc/utils/semver/cmd/semver/bump" 8 | ) 9 | 10 | var ( 11 | Version string 12 | Commit string 13 | Timestamp string 14 | ) 15 | 16 | func run(command *cobra.Command, args []string) { 17 | command.Help() 18 | } 19 | 20 | func GetCommand() *cobra.Command { 21 | cmd := &cobra.Command{ 22 | Use: "semver", 23 | Version: fmt.Sprintf("%s-%s %s", Version, Commit, Timestamp), 24 | Run: run, 25 | } 26 | cmd.AddCommand(bump.GetCommand()) 27 | return cmd 28 | } 29 | 30 | func main() { 31 | GetCommand().Execute() 32 | } 33 | -------------------------------------------------------------------------------- /cmd/semver/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/suite" 7 | ) 8 | 9 | type mainTest struct { 10 | suite.Suite 11 | } 12 | 13 | func Test_main(t *testing.T) { 14 | suite.Run(t, &mainTest{}) 15 | } 16 | 17 | func (s *mainTest) TestGetCommand() { 18 | cmd := GetCommand() 19 | s.Equal("semver", cmd.Use) 20 | s.NotNil(cmd.Run) 21 | s.Len(cmd.Commands(), 1) 22 | } 23 | -------------------------------------------------------------------------------- /deploy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.14-buster AS builder 2 | RUN apt-get update \ 3 | && apt-get upgrade -y 4 | RUN apt-get install -y git make upx 5 | WORKDIR /app 6 | COPY . . 7 | RUN make deps 8 | RUN make build_production 9 | RUN make compress 10 | 11 | FROM gcr.io/distroless/base-debian10 AS production 12 | ARG GIT_COMMIT_ID="undefined" 13 | ARG GIT_TAG="undefined" 14 | ARG BUILD_TIMESTAMP="undefined" 15 | ENV PATH=/bin 16 | COPY --from=builder /app/bin/semver_linux_amd64 /bin/semver 17 | ENTRYPOINT ["/bin/semver"] 18 | LABEL maintainer "zephinzer" 19 | LABEL repository_github "https://github.com/usvc/semver" 20 | LABEL repository_gitlab "https://gitlab.com/usvc/utils/semver" 21 | LABEL git_commit_id ${GIT_COMMIT_ID} 22 | LABEL git_tag ${GIT_TAG} 23 | LABEL build_timestamp ${BUILD_TIMESTAMP} 24 | -------------------------------------------------------------------------------- /deploy/Dockerfile.yaml: -------------------------------------------------------------------------------- 1 | schemaVersion: "2.0.0" 2 | fileExistenceTests: 3 | - name: "binary" 4 | path: "/bin/semver" 5 | shouldExist: true 6 | commandTests: 7 | - name: "binary is in path" 8 | command: "/bin/semver" 9 | args: ["--version"] 10 | expectedOutput: ["semver version"] 11 | metadataTest: 12 | entrypoint: ["/bin/semver"] 13 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module gitlab.com/usvc/utils/semver 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/spf13/cobra v0.0.6 7 | github.com/stretchr/testify v1.5.1 8 | github.com/usvc/config v0.1.8 9 | github.com/usvc/go-logger v0.3.1 10 | github.com/usvc/go-semver v0.0.13 11 | gopkg.in/src-d/go-git.v4 v4.13.1 12 | ) 13 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= 3 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 4 | github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= 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/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 8 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 9 | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= 10 | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= 11 | github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= 12 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= 13 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 14 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 15 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 16 | github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= 17 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 18 | github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= 19 | github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= 20 | github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= 21 | github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= 22 | github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= 23 | github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 24 | github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= 25 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 26 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 27 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 28 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 29 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= 30 | github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= 31 | github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= 32 | github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= 33 | github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= 34 | github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= 35 | github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= 36 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 37 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 38 | github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= 39 | github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= 40 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 41 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 42 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 43 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 44 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 45 | github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= 46 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 47 | github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 48 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 49 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 50 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 51 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 52 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 53 | github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= 54 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 55 | github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= 56 | github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= 57 | github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= 58 | github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= 59 | github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= 60 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 61 | github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= 62 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 63 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= 64 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= 65 | github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 66 | github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= 67 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 68 | github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= 69 | github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= 70 | github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= 71 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 72 | github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= 73 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 74 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 75 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 76 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 77 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 78 | github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= 79 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 80 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 81 | github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= 82 | github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= 83 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 84 | github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= 85 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 86 | github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= 87 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 88 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 89 | github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= 90 | github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA= 91 | github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= 92 | github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= 93 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 94 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 95 | github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= 96 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 97 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 98 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 99 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 100 | github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= 101 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 102 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 103 | github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= 104 | github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 105 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 106 | github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 107 | github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= 108 | github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= 109 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 110 | github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= 111 | github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= 112 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 113 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 114 | github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= 115 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 116 | github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= 117 | github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= 118 | github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= 119 | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= 120 | github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= 121 | github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 122 | github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs= 123 | github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= 124 | github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= 125 | github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= 126 | github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= 127 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 128 | github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= 129 | github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= 130 | github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= 131 | github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= 132 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 133 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 134 | github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= 135 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 136 | github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= 137 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 138 | github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= 139 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 140 | github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= 141 | github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= 142 | github.com/usvc/config v0.1.8 h1:jbETkjn0+OsGFhdnmq+o31MV0IAe1uLnr07yqvg6JVo= 143 | github.com/usvc/config v0.1.8/go.mod h1:1CRMnDCACF5McNUGsMiEYM7w+2scm1rC+IiUnmU+UYY= 144 | github.com/usvc/go-logger v0.3.1 h1:m8RdB4/XYuF4EtPuOelfu6Cdupw8najCeW6149MiLhA= 145 | github.com/usvc/go-logger v0.3.1/go.mod h1:JmE5o8jBa0hKk+pmNMh56f0zkoCyPNJKNk+kQN8DXHw= 146 | github.com/usvc/go-semver v0.0.13 h1:ctMV/hoQZXj9grlLPzBQopfupCuJlIWOhfo66soW85Q= 147 | github.com/usvc/go-semver v0.0.13/go.mod h1:5TscL1PIhL7Cc8wELjNwQvpUZQ5tDagYYb2cechKbK8= 148 | github.com/usvc/logger v0.2.2 h1:1tdce4j1JGfb8g65u4sWDdcENNntnKp9flws7Lj8UUo= 149 | github.com/usvc/logger v0.2.2/go.mod h1:c3a4nh3MvdED2gTyIMAqh+vwKNjM4UtULz/aB9EU9R0= 150 | github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= 151 | github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= 152 | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= 153 | github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= 154 | go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= 155 | go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= 156 | go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= 157 | go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= 158 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 159 | golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 160 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 161 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= 162 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 163 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 164 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 165 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 166 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 167 | golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 168 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 169 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 170 | golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 171 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 172 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= 173 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 174 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 175 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 176 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 177 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 178 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 179 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 180 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 181 | golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 182 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 183 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 184 | golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 185 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 186 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= 187 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 188 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e h1:D5TXcfTk7xF7hvieo4QErS3qqCB4teTffacDWr7CI+0= 189 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 190 | golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= 191 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 192 | golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= 193 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 194 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 195 | golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 196 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 197 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 198 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 199 | golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= 200 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 201 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 202 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 203 | google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 204 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 205 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 206 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 207 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 208 | gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= 209 | gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg= 210 | gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= 211 | gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg= 212 | gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= 213 | gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE= 214 | gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= 215 | gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= 216 | gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= 217 | gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= 218 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 219 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= 220 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 221 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 222 | -------------------------------------------------------------------------------- /init/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !install.sh 4 | -------------------------------------------------------------------------------- /init/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e; 3 | printf -- '\n'; 4 | 5 | # get user confirmation 6 | printf -- 'this script downloads the latest `semver` binary from https://github.com/usvc/semver/releases.\n'; 7 | printf -- " > hit ctrl+c to exit within 5 seconds if that's not what you want...\n"; 8 | N=5; while [ $N -gt 0 ]; do 9 | sleep 1; printf -- "."; 10 | N=$(($N-1)) 11 | done; 12 | printf -- '\n\n'; 13 | 14 | # check for write permissions 15 | printf -- "checking for write permissions at $(pwd)...\n" 16 | touch ./__do_we_have_write_permissions; 17 | rm -rf ./__do_we_have_write_permissions; 18 | printf -- 'we have permission\n\n'; 19 | 20 | # determine system environment 21 | printf -- 'getting system information...\n'; 22 | SYSTEM="$(uname -s)"; 23 | ARCHITECTURE="$(uname -p)"; 24 | case $SYSTEM in 25 | *inux) OS=linux; ;; 26 | *arwin) OS=darwin; ;; 27 | *) OS=windows; 28 | BIN_EXT=.exe; ;; 29 | esac 30 | case $ARCHITECTURE in 31 | x86_64) ARCH=amd64; ;; 32 | *86) ARCH=386; ;; 33 | arm*) ARCH=arm; ;; 34 | esac 35 | printf -- "os: ${OS}, architecture: ${ARCH}\n\n"; 36 | 37 | # retrieve latest version 38 | printf -- 'retrieving latest version info...\n' 39 | curl -s https://api.github.com/repos/usvc/semver/releases > ./.version_info; 40 | cat ./.version_info | jq '.[].tag_name' -r | egrep "^v[0-9]+\.[0-9]+\.[0-9]+$" | sed -e 's/v//g' | sort -V | tail -n 1 > ./.version_latest; 41 | BIN_URL="https://github.com/usvc/semver/releases/download/v$(cat ./.version_latest)/semver-${OS}-${ARCH}${BIN_EXT}"; 42 | BIN_PATH="./semver-v$(cat ./.version_latest)${BIN_EXT}"; 43 | printf -- "latest version: $(cat ./.version_latest)\n\n"; 44 | rm -rf ./.verison_info; 45 | rm -rf ./.version_latest; 46 | 47 | # download it 48 | printf -- "retrieving binary from ${BIN_URL}\n" 49 | printf -- " > downloading to ${BIN_PATH}...\n" 50 | curl -Lo "${BIN_PATH}" "${BIN_URL}"; 51 | chmod +x "${BIN_PATH}"; 52 | printf -- "done.\n\n"; 53 | 54 | # done 55 | printf -- "run '${BIN_PATH} --help' for more information\n"; 56 | printf -- '- to include it in your path:\n'; 57 | printf -- " 1. sudo mv '${BIN_PATH}' /bin/semver\n"; 58 | printf -- ' 2. sudo ln -s $(pwd)'; 59 | printf -- "/${BIN_PATH} /bin/semver\n"; 60 | 61 | printf -- '\nthanks for using usvc/semver (:\n'; 62 | -------------------------------------------------------------------------------- /internal/repo/git.go: -------------------------------------------------------------------------------- 1 | package repo 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | 7 | "github.com/usvc/go-semver" 8 | "gopkg.in/src-d/go-git.v4" 9 | "gopkg.in/src-d/go-git.v4/plumbing" 10 | ) 11 | 12 | func TagCurrentGitCommit(withTag string, pathToRepository string) error { 13 | repository, err := git.PlainOpen(pathToRepository) 14 | if err != nil { 15 | return fmt.Errorf("failed to open the directory '%s' as a git repository: '%s'", pathToRepository, err) 16 | } 17 | head, err := repository.Head() 18 | if err != nil { 19 | return fmt.Errorf("failed to get HEAD of git repository: '%s'", err) 20 | } 21 | headCommitHash := head.Hash() 22 | _, err = repository.CreateTag(withTag, headCommitHash, nil) 23 | return err 24 | } 25 | 26 | func GetLatestSemverFromGitRepository(pathToRepository string) (*semver.Semver, error) { 27 | repository, err := git.PlainOpen(pathToRepository) 28 | if err != nil { 29 | return nil, fmt.Errorf("failed to open the directory '%s' as a git repository: '%s'", pathToRepository, err) 30 | } 31 | tags, err := repository.Tags() 32 | if err != nil { 33 | return nil, fmt.Errorf("failed to get tags from git repository at '%s': '%s'", pathToRepository, err) 34 | } 35 | var versions semver.Semvers 36 | tags.ForEach(func(tag *plumbing.Reference) error { 37 | tagName := tag.Name().Short() 38 | if semver.IsValid(tagName) { 39 | versions = append(versions, semver.Parse(tagName)) 40 | } 41 | return nil 42 | }) 43 | if versions.Len() == 0 { 44 | return &semver.Semver{ 45 | Prefix: "v", 46 | }, nil 47 | } 48 | sort.Sort(versions) 49 | return versions[versions.Len()-1], nil 50 | } 51 | -------------------------------------------------------------------------------- /internal/repo/git_test.go: -------------------------------------------------------------------------------- 1 | package repo 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/suite" 9 | "gopkg.in/src-d/go-git.v4" 10 | "gopkg.in/src-d/go-git.v4/plumbing" 11 | ) 12 | 13 | type GitTests struct { 14 | suite.Suite 15 | } 16 | 17 | func TestGit(t *testing.T) { 18 | suite.Run(t, &GitTests{}) 19 | } 20 | 21 | func (s *GitTests) TestTagCurrentGitCommit() { 22 | expectedTag := "test_tag_current_git_commit" 23 | tempDir, err := ioutil.TempDir("", expectedTag) 24 | defer func() { 25 | os.RemoveAll(tempDir) 26 | }() 27 | s.Nil(err) 28 | repository, err := git.PlainClone(tempDir, false, &git.CloneOptions{ 29 | URL: "https://gitlab.com/usvc/utils/semver.git", 30 | }) 31 | s.Nil(err) 32 | s.NotNil(repository) 33 | err = TagCurrentGitCommit(expectedTag, tempDir) 34 | s.Nil(err) 35 | tags, err := repository.Tags() 36 | s.Nil(err) 37 | var tagsAsStrings []string 38 | tags.ForEach(func(tag *plumbing.Reference) error { 39 | tagsAsStrings = append(tagsAsStrings, tag.Name().Short()) 40 | return nil 41 | }) 42 | s.Contains(tagsAsStrings, expectedTag) 43 | } 44 | 45 | func (s *GitTests) TestGetLatestSemverFromGitRepository() { 46 | directoryName := "test_get_latest_semver_from_git_repository" 47 | expectedTag := "123456.78.90" 48 | tempDir, err := ioutil.TempDir("", directoryName) 49 | defer func() { 50 | os.RemoveAll(tempDir) 51 | }() 52 | s.Nil(err) 53 | repository, err := git.PlainClone(tempDir, false, &git.CloneOptions{ 54 | URL: "https://gitlab.com/usvc/utils/semver.git", 55 | }) 56 | s.Nil(err) 57 | s.NotNil(repository) 58 | err = TagCurrentGitCommit(expectedTag, tempDir) 59 | s.Nil(err) 60 | latest, err := GetLatestSemverFromGitRepository(tempDir) 61 | s.Nil(err) 62 | s.Equal(uint(123456), latest.VersionCore.Major) 63 | s.Equal(uint(78), latest.VersionCore.Minor) 64 | s.Equal(uint(90), latest.VersionCore.Patch) 65 | } 66 | -------------------------------------------------------------------------------- /internal/utils/semver.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/usvc/go-semver" 8 | ) 9 | 10 | func GetSemverFromArguments(args []string) (*semver.Semver, error) { 11 | versionFromArguments := strings.Join(args, ".") 12 | if !semver.IsValid(versionFromArguments) { 13 | return nil, fmt.Errorf("parsed input '%s' is not a valid semver string", versionFromArguments) 14 | } 15 | return semver.Parse(versionFromArguments), nil 16 | } 17 | -------------------------------------------------------------------------------- /internal/utils/semver_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/suite" 7 | ) 8 | 9 | type SemverTests struct { 10 | suite.Suite 11 | } 12 | 13 | func TestSemver(t *testing.T) { 14 | suite.Run(t, &SemverTests{}) 15 | } 16 | 17 | func (s *SemverTests) TestGetSemverFromArguments() { 18 | semver, err := GetSemverFromArguments([]string{"1", "2", "3"}) 19 | s.Nil(err) 20 | s.Equal("1.2.3", semver.String()) 21 | semver, err = GetSemverFromArguments([]string{"10", "20", "30"}) 22 | s.Nil(err) 23 | s.Equal("10.20.30", semver.String()) 24 | } 25 | 26 | func (s *SemverTests) TestGetSemverFromArguments_error() { 27 | semver, err := GetSemverFromArguments([]string{"a", "2", "3"}) 28 | s.Nil(semver) 29 | s.NotNil(err) 30 | s.Contains(err.Error(), "not a valid semver") 31 | semver, err = GetSemverFromArguments([]string{"1", "b", "3"}) 32 | s.Nil(semver) 33 | s.NotNil(err) 34 | s.Contains(err.Error(), "not a valid semver") 35 | semver, err = GetSemverFromArguments([]string{"1", "2", "c"}) 36 | s.Nil(semver) 37 | s.NotNil(err) 38 | s.Contains(err.Error(), "not a valid semver") 39 | } 40 | --------------------------------------------------------------------------------