Compare commits
	
		
			46 Commits
		
	
	
		
			v0.8.0
			...
			bc28fe186f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | bc28fe186f | ||
|  | 19062e27f0 | ||
|  | 322ad2d3c4 | ||
|  | 9e34636c29 | ||
|  | b4b13dc3ca | ||
|  | e5a6132b9d | ||
|  | d71cbbd0b6 | ||
|  | 0a85957c50 | ||
|  | f87515a453 | ||
|  | 0e8aa2bf9b | ||
|  | 1162650a73 | ||
|  | abc332958b | ||
|  | 6ce5f8bf9f | ||
|  | 1c80699599 | ||
|  | 84c9110a24 | ||
|  | ad2692136f | ||
| 4f33464489 | |||
| 2c787bd532 | |||
| feacbf5a3f | |||
| d6160c596b | |||
| 9799416352 | |||
| 8095c2a513 | |||
|  | 14c1a11417 | ||
|  | 8a805faa72 | ||
|  | 32ad02fa73 | ||
| edd03aca2f | |||
| 0fe94d7dc1 | |||
|  | d6f60fb0a7 | ||
|  | 282cd097f9 | ||
|  | 683a051502 | ||
|  | 32278f74cc | ||
|  | b4859cda6b | ||
|  | ad07770b6b | ||
| 3dd609864b | |||
| 13d3ed85ad | |||
| b23c36a25f | |||
|  | 87d8cfd2e5 | ||
|  | 85b869d28b | ||
| 04f842cdfe | |||
| c72fcb3a49 | |||
| 9c819ad4c2 | |||
| 6d5439a00a | |||
| 6d0bd5906a | |||
|  | f3c0793a88 | ||
|  | e99be27300 | ||
|  | 480994bfa9 | 
| @@ -30,6 +30,7 @@ steps: | |||||||
|   - name: build |   - name: build | ||||||
|     image: goreleaser/goreleaser |     image: goreleaser/goreleaser | ||||||
|     commands: |     commands: | ||||||
|  |       - curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin v0.64.0 | ||||||
|       - goreleaser build --snapshot |       - goreleaser build --snapshot | ||||||
|     when: |     when: | ||||||
|       event: |       event: | ||||||
| @@ -59,6 +60,7 @@ steps: | |||||||
|       GPG_PRIVATE_KEY_BASE64: |       GPG_PRIVATE_KEY_BASE64: | ||||||
|         from_secret: GPG_PRIVATE_KEY_BASE64 |         from_secret: GPG_PRIVATE_KEY_BASE64 | ||||||
|     commands: |     commands: | ||||||
|  |       - curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin v0.64.0 | ||||||
|       - apk add gpg-agent |       - apk add gpg-agent | ||||||
|       - gpg-agent --daemon --default-cache-ttl 7200 |       - gpg-agent --daemon --default-cache-ttl 7200 | ||||||
|       - echo $GPG_PRIVATE_KEY_BASE64 | base64 -d | gpg --import --batch --no-tty |       - echo $GPG_PRIVATE_KEY_BASE64 | base64 -d | gpg --import --batch --no-tty | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | # To get started with Dependabot version updates, you'll need to specify which | ||||||
|  | # package ecosystems to update and where the package manifests are located. | ||||||
|  | # Please see the documentation for all configuration options: | ||||||
|  | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates | ||||||
|  |  | ||||||
|  | version: 2 | ||||||
|  | updates: | ||||||
|  |   - package-ecosystem: "gomod" | ||||||
|  |     directory: "/" | ||||||
|  |     schedule: | ||||||
|  |       interval: "weekly" | ||||||
|  |   - package-ecosystem: "github-actions" | ||||||
|  |     directory: "/" | ||||||
|  |     schedule: | ||||||
|  |       interval: "weekly" | ||||||
							
								
								
									
										25
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -18,27 +18,26 @@ jobs: | |||||||
|   goreleaser: |   goreleaser: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - |       - name: Checkout | ||||||
|         name: Checkout |  | ||||||
|         uses: actions/checkout@v3 |         uses: actions/checkout@v3 | ||||||
|       - |       - name: Unshallow | ||||||
|         name: Unshallow |  | ||||||
|         run: git fetch --prune --unshallow |         run: git fetch --prune --unshallow | ||||||
|       - |       - name: Set up Go | ||||||
|         name: Set up Go |         uses: actions/setup-go@v4 | ||||||
|         uses: actions/setup-go@v2 |  | ||||||
|         with: |         with: | ||||||
|           go-version: 1.18 |           go-version: 1.18 | ||||||
|       - |       - name: Import GPG key | ||||||
|         name: Import GPG key |  | ||||||
|         id: import_gpg |         id: import_gpg | ||||||
|         uses: crazy-max/ghaction-import-gpg@v5.0.0 |         uses: crazy-max/ghaction-import-gpg@v5.3.0 | ||||||
|         with: |         with: | ||||||
|           gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} |           gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} | ||||||
|           passphrase: ${{ secrets.PASSPHRASE }} |           passphrase: ${{ secrets.PASSPHRASE }} | ||||||
|       - |       - name: setup-syft | ||||||
|         name: Run GoReleaser |         run: | | ||||||
|         uses: goreleaser/goreleaser-action@v3.0.0 |           curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | \ | ||||||
|  |           sh -s -- -b /usr/local/bin v0.64.0 | ||||||
|  |       - name: Run GoReleaser | ||||||
|  |         uses: goreleaser/goreleaser-action@v4.2.0 | ||||||
|         with: |         with: | ||||||
|           version: latest |           version: latest | ||||||
|           args: release --rm-dist |           args: release --rm-dist | ||||||
|   | |||||||
| @@ -41,6 +41,8 @@ checksum: | |||||||
|       name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' |       name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' | ||||||
|   name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' |   name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' | ||||||
|   algorithm: sha256 |   algorithm: sha256 | ||||||
|  | sboms: | ||||||
|  |   - artifacts: archive | ||||||
| signs: | signs: | ||||||
|   - artifacts: checksum |   - artifacts: checksum | ||||||
|     args: |     args: | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								Makefile
									
									
									
									
									
								
							| @@ -1,9 +1,11 @@ | |||||||
| TEST?=./gitea | TEST?=./gitea | ||||||
| GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor) | GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor) | ||||||
|  | ARCH?=$$(uname -m) | ||||||
|  | KERNEL?=$$(uname -s | tr '[:upper:]' '[:lower:]') | ||||||
|  |  | ||||||
| GOFMT ?= gofmt -s | GOFMT ?= gofmt -s | ||||||
|  |  | ||||||
| VERSION = 0.8.0 | VERSION = 0.13.0 | ||||||
|  |  | ||||||
| test: fmt-check | test: fmt-check | ||||||
| 	go test -i $(TEST) || exit 1 | 	go test -i $(TEST) || exit 1 | ||||||
| @@ -34,8 +36,8 @@ build: | |||||||
| 	go build -ldflags="-X 'main.Version=${VERSION}'" -o terraform-provider-gitea_${VERSION} | 	go build -ldflags="-X 'main.Version=${VERSION}'" -o terraform-provider-gitea_${VERSION} | ||||||
| install: build  | install: build  | ||||||
| 	@echo installing to  | 	@echo installing to  | ||||||
| 	@echo ~/.terraform.d/plugins/terraform.local/lerentis/gitea/${VERSION}/linux_amd64/terraform-provider-gitea_${VERSION} | 	@echo ~/.terraform.d/plugins/terraform.local/lerentis/gitea/${VERSION}/${KERNEL}_${ARCH}/terraform-provider-gitea_${VERSION} | ||||||
| 	@mkdir -p ~/.terraform.d/plugins/terraform.local/lerentis/gitea/${VERSION}/linux_amd64 | 	@mkdir -p ~/.terraform.d/plugins/terraform.local/lerentis/gitea/${VERSION}/${KERNEL}_${ARCH} | ||||||
| 	@mv terraform-provider-gitea_${VERSION} ~/.terraform.d/plugins/terraform.local/lerentis/gitea/${VERSION}/linux_amd64/terraform-provider-gitea_${VERSION} | 	@mv terraform-provider-gitea_${VERSION} ~/.terraform.d/plugins/terraform.local/lerentis/gitea/${VERSION}/${KERNEL}_${ARCH}/terraform-provider-gitea_${VERSION} | ||||||
| doc: | doc: | ||||||
| 	tfplugindocs | 	tfplugindocs | ||||||
| @@ -17,7 +17,7 @@ terraform { | |||||||
|   required_providers { |   required_providers { | ||||||
|     gitea = { |     gitea = { | ||||||
|       source = "Lerentis/gitea" |       source = "Lerentis/gitea" | ||||||
|       version = "0.8.0" |       version = "0.13.0" | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ terraform { | |||||||
|   required_providers { |   required_providers { | ||||||
|     gitea = { |     gitea = { | ||||||
|       source = "Lerentis/gitea" |       source = "Lerentis/gitea" | ||||||
|       version = "0.8.0" |       version = "0.13.0" | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										61
									
								
								docs/resources/fork.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								docs/resources/fork.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | |||||||
|  | --- | ||||||
|  | # generated by https://github.com/hashicorp/terraform-plugin-docs | ||||||
|  | page_title: "gitea_fork Resource - terraform-provider-gitea" | ||||||
|  | subcategory: "" | ||||||
|  | description: |- | ||||||
|  |   gitea_fork manages repository fork to the current user or an organisation | ||||||
|  |   Forking a repository to a dedicated user is currently unsupported | ||||||
|  |   Creating a fork using this resource without an organisation will create the fork in the executors name | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | # gitea_fork (Resource) | ||||||
|  |  | ||||||
|  | `gitea_fork` manages repository fork to the current user or an organisation | ||||||
|  | Forking a repository to a dedicated user is currently unsupported | ||||||
|  | Creating a fork using this resource without an organisation will create the fork in the executors name | ||||||
|  |  | ||||||
|  | ## Example Usage | ||||||
|  |  | ||||||
|  | ```terraform | ||||||
|  | resource "gitea_org" "org1" { | ||||||
|  |   name = "org1" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_org" "org2" { | ||||||
|  |   name = "org2" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_repository" "repo1_in_org1" { | ||||||
|  |   username = gitea_org.org1.name | ||||||
|  |   name     = "repo1-in-org1" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_fork" "user_fork_of_repo1_in_org1" { | ||||||
|  |   owner = gitea_org.org1.name | ||||||
|  |   repo  = gitea_repository.repo1_in_org1.name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_fork" "org2_fork_of_repo1_in_org1" { | ||||||
|  |   owner        = gitea_org.org1.name | ||||||
|  |   repo         = gitea_repository.repo1_in_org1.name | ||||||
|  |   organization = gitea_org.org2.name | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | <!-- schema generated by tfplugindocs --> | ||||||
|  | ## Schema | ||||||
|  |  | ||||||
|  | ### Required | ||||||
|  |  | ||||||
|  | - `owner` (String) The owner or owning organization of the repository to fork | ||||||
|  | - `repo` (String) The name of the repository to fork | ||||||
|  |  | ||||||
|  | ### Optional | ||||||
|  |  | ||||||
|  | - `organization` (String) The organization that owns the forked repo | ||||||
|  |  | ||||||
|  | ### Read-Only | ||||||
|  |  | ||||||
|  | - `id` (String) The ID of this resource. | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -7,6 +7,7 @@ description: |- | |||||||
|   Per default this repository will be initializiled with the provided configuration (gitignore, License etc.). |   Per default this repository will be initializiled with the provided configuration (gitignore, License etc.). | ||||||
|   If the username property is set to a organisation name, the provider will try to look if this organisation exists and create the repository under the organisation scope. |   If the username property is set to a organisation name, the provider will try to look if this organisation exists and create the repository under the organisation scope. | ||||||
|   Repository migrations have some properties that are not available to regular repositories. These are all prefixed with migration_. |   Repository migrations have some properties that are not available to regular repositories. These are all prefixed with migration_. | ||||||
|  |   Codeberg.org does currently not allow mirrors to be created. See FAQ Section of CodeBerg for more information: https://docs.codeberg.org/getting-started/faq/#why-am-i-not-allowed-to-set-up-an-automatic-mirror | ||||||
| --- | --- | ||||||
|  |  | ||||||
| # gitea_repository (Resource) | # gitea_repository (Resource) | ||||||
| @@ -17,6 +18,7 @@ Per default this repository will be initializiled with the provided configuratio | |||||||
| If the `username` property is set to a organisation name, the provider will try to look if this organisation exists and create the repository under the organisation scope. | If the `username` property is set to a organisation name, the provider will try to look if this organisation exists and create the repository under the organisation scope. | ||||||
|  |  | ||||||
| Repository migrations have some properties that are not available to regular repositories. These are all prefixed with `migration_`. | Repository migrations have some properties that are not available to regular repositories. These are all prefixed with `migration_`. | ||||||
|  | Codeberg.org does currently not allow mirrors to be created. See FAQ Section of CodeBerg for more information: https://docs.codeberg.org/getting-started/faq/#why-am-i-not-allowed-to-set-up-an-automatic-mirror | ||||||
|  |  | ||||||
| ## Example Usage | ## Example Usage | ||||||
|  |  | ||||||
| @@ -92,11 +94,14 @@ Need to exist in the gitea instance | |||||||
|  |  | ||||||
| ### Read-Only | ### Read-Only | ||||||
|  |  | ||||||
|  | - `clone_url` (String) | ||||||
| - `created` (String) | - `created` (String) | ||||||
|  | - `html_url` (String) | ||||||
| - `id` (String) The ID of this resource. | - `id` (String) The ID of this resource. | ||||||
| - `permission_admin` (Boolean) | - `permission_admin` (Boolean) | ||||||
| - `permission_pull` (Boolean) | - `permission_pull` (Boolean) | ||||||
| - `permission_push` (Boolean) | - `permission_push` (Boolean) | ||||||
|  | - `ssh_url` (String) | ||||||
| - `updated` (String) | - `updated` (String) | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										63
									
								
								docs/resources/repository_key.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								docs/resources/repository_key.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | |||||||
|  | --- | ||||||
|  | # generated by https://github.com/hashicorp/terraform-plugin-docs | ||||||
|  | page_title: "gitea_repository_key Resource - terraform-provider-gitea" | ||||||
|  | subcategory: "" | ||||||
|  | description: |- | ||||||
|  |   gitea_repository_key manages a deploy key for a single gitea_repository. | ||||||
|  |   Every key needs a unique name and unique key, i.e. no key can be added twice to the same repo | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | # gitea_repository_key (Resource) | ||||||
|  |  | ||||||
|  | `gitea_repository_key` manages a deploy key for a single gitea_repository. | ||||||
|  |  | ||||||
|  | Every key needs a unique name and unique key, i.e. no key can be added twice to the same repo | ||||||
|  |  | ||||||
|  | ## Example Usage | ||||||
|  |  | ||||||
|  | ```terraform | ||||||
|  | terraform { | ||||||
|  |   required_providers { | ||||||
|  |     tls = { | ||||||
|  |       source = "hashicorp/tls" | ||||||
|  |       version = "4.0.4" | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "tls_private_key" "example" { | ||||||
|  |   type = "RSA" | ||||||
|  |   rsa_bits = 4096 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_repository" "example" { | ||||||
|  |   name = "example" | ||||||
|  |   private = true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_repository_key" "example" { | ||||||
|  |   repository = gitea_repository.example.id | ||||||
|  |   title = "Example Deploy Key" | ||||||
|  |   read_only = true | ||||||
|  |   key = tls_private_key.example.public_key_openssh | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | <!-- schema generated by tfplugindocs --> | ||||||
|  | ## Schema | ||||||
|  |  | ||||||
|  | ### Required | ||||||
|  |  | ||||||
|  | - `key` (String) Armored SSH key to add | ||||||
|  | - `repository` (Number) The ID of the repository where the deploy key belongs to | ||||||
|  | - `title` (String) Name of the deploy key | ||||||
|  |  | ||||||
|  | ### Optional | ||||||
|  |  | ||||||
|  | - `read_only` (Boolean) Whether this key has read or read/write access | ||||||
|  |  | ||||||
|  | ### Read-Only | ||||||
|  |  | ||||||
|  | - `id` (String) The ID of this resource. | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -34,6 +34,26 @@ resource "gitea_team" "test_team" { | |||||||
|   permission   = "write" |   permission   = "write" | ||||||
|   members      = [gitea_user.test.username] |   members      = [gitea_user.test.username] | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | resource "gitea_repository" "test" { | ||||||
|  |   username     = gitea_org.test_org.name | ||||||
|  |   name         = "test" | ||||||
|  |   private      = true | ||||||
|  |   issue_labels = "Default" | ||||||
|  |   license      = "MIT" | ||||||
|  |   gitignores   = "Go" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_team" "test_team_restricted" { | ||||||
|  |   name                     = "Restricted Devs" | ||||||
|  |   organisation             = gitea_org.test_org.name | ||||||
|  |   description              = "Restricted Devs of Test Org" | ||||||
|  |   permission               = "write" | ||||||
|  |   members                  = [gitea_user.test.username] | ||||||
|  |   include_all_repositories = false | ||||||
|  |   repositories             = [gitea_repository.test.name] | ||||||
|  | } | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| <!-- schema generated by tfplugindocs --> | <!-- schema generated by tfplugindocs --> | ||||||
| @@ -52,6 +72,7 @@ resource "gitea_team" "test_team" { | |||||||
| - `members` (List of String) List of Users that should be part of this team | - `members` (List of String) List of Users that should be part of this team | ||||||
| - `permission` (String) Permissions associated with this Team | - `permission` (String) Permissions associated with this Team | ||||||
| Can be `none`, `read`, `write`, `admin` or `owner` | Can be `none`, `read`, `write`, `admin` or `owner` | ||||||
|  | - `repositories` (List of String) List of Repositories that should be part of this team | ||||||
| - `units` (String) List of types of Repositories that should be allowed to be created from Team members. | - `units` (String) List of types of Repositories that should be allowed to be created from Team members. | ||||||
| Can be `repo.code`, `repo.issues`, `repo.ext_issues`, `repo.wiki`, `repo.pulls`, `repo.releases`, `repo.projects` and/or `repo.ext_wiki` | Can be `repo.code`, `repo.issues`, `repo.ext_issues`, `repo.wiki`, `repo.pulls`, `repo.releases`, `repo.projects` and/or `repo.ext_wiki` | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										67
									
								
								docs/resources/token.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								docs/resources/token.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | |||||||
|  | --- | ||||||
|  | # generated by https://github.com/hashicorp/terraform-plugin-docs | ||||||
|  | page_title: "gitea_token Resource - terraform-provider-gitea" | ||||||
|  | subcategory: "" | ||||||
|  | description: |- | ||||||
|  |   gitea_token manages gitea Access Tokens. | ||||||
|  |   Due to upstream limitations (see https://gitea.com/gitea/go-sdk/issues/610) this resource | ||||||
|  |   can only be used with username/password provider configuration. | ||||||
|  |   WARNING: | ||||||
|  |   Tokens will be stored in the terraform state! | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | # gitea_token (Resource) | ||||||
|  |  | ||||||
|  | `gitea_token` manages gitea Access Tokens. | ||||||
|  |  | ||||||
|  | Due to upstream limitations (see https://gitea.com/gitea/go-sdk/issues/610) this resource | ||||||
|  | can only be used with username/password provider configuration. | ||||||
|  |  | ||||||
|  | WARNING: | ||||||
|  | Tokens will be stored in the terraform state! | ||||||
|  |  | ||||||
|  | ## Example Usage | ||||||
|  |  | ||||||
|  | ```terraform | ||||||
|  | provider "gitea" { | ||||||
|  |   base_url = var.gitea_url | ||||||
|  |   # Token Auth can not be used with this resource | ||||||
|  |   username = var.gitea_username | ||||||
|  |   password = var.gitea_password | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_user" "test" { | ||||||
|  |   username             = "test" | ||||||
|  |   login_name           = "test" | ||||||
|  |   password             = "Geheim1!" | ||||||
|  |   email                = "test@user.dev" | ||||||
|  |   must_change_password = false | ||||||
|  |   admin                = true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_token" "test_token" { | ||||||
|  |   username = resource.gitea_user.test.username | ||||||
|  |   name     = "test-token" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | output "token" { | ||||||
|  |   value     = resource.gitea_token.test_token.token | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | <!-- schema generated by tfplugindocs --> | ||||||
|  | ## Schema | ||||||
|  |  | ||||||
|  | ### Required | ||||||
|  |  | ||||||
|  | - `name` (String) The name of the Access Token | ||||||
|  | - `username` (String) The owner of the Access Token | ||||||
|  |  | ||||||
|  | ### Read-Only | ||||||
|  |  | ||||||
|  | - `id` (String) The ID of this resource. | ||||||
|  | - `last_eight` (String) | ||||||
|  | - `token` (String, Sensitive) The actual Access Token | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -71,3 +71,55 @@ resource "gitea_git_hook" "org_repo_pre_receive" { | |||||||
|   repo    = gitea_repository.org_repo.name |   repo    = gitea_repository.org_repo.name | ||||||
|   content = file("${path.module}/pre-receive.sh") |   content = file("${path.module}/pre-receive.sh") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | resource "gitea_org" "org1" { | ||||||
|  |   name = "org1" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_org" "org2" { | ||||||
|  |   name = "org2" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_repository" "repo1_in_org1" { | ||||||
|  |   username = gitea_org.org1.name | ||||||
|  |   name     = "repo1-in-org1" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_fork" "user_fork_of_repo1_in_org1" { | ||||||
|  |   owner = gitea_org.org1.name | ||||||
|  |   repo  = gitea_repository.repo1_in_org1.name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_fork" "org2_fork_of_repo1_in_org1" { | ||||||
|  |   owner        = gitea_org.org1.name | ||||||
|  |   repo         = gitea_repository.repo1_in_org1.name | ||||||
|  |   organization = gitea_org.org2.name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_token" "test_token" { | ||||||
|  |   username = data.gitea_user.me.username | ||||||
|  |   name     = "test-token" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_repository" "test_existing_user" { | ||||||
|  |   username     = "testuser2" | ||||||
|  |   name         = "testExistingUser" | ||||||
|  |   private      = true | ||||||
|  |   issue_labels = "Default" | ||||||
|  |   license      = "MIT" | ||||||
|  |   gitignores   = "Go" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //resource "gitea_repository" "test_bs_user" { | ||||||
|  | //  username     = "manualTest" | ||||||
|  | //  name         = "testBullshitUser" | ||||||
|  | //  private      = true | ||||||
|  | //  issue_labels = "Default" | ||||||
|  | //  license      = "MIT" | ||||||
|  | //  gitignores   = "Go" | ||||||
|  | //} | ||||||
|  |  | ||||||
|  | output "token" { | ||||||
|  |   value = resource.gitea_token.test_token.token | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|   | |||||||
| @@ -2,12 +2,14 @@ terraform { | |||||||
|   required_providers { |   required_providers { | ||||||
|     gitea = { |     gitea = { | ||||||
|       source = "terraform.local/lerentis/gitea" |       source = "terraform.local/lerentis/gitea" | ||||||
|       version = "0.8.0" |       version = "0.13.0" | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| provider "gitea" { | provider "gitea" { | ||||||
|   base_url = var.gitea_url |   base_url = var.gitea_url | ||||||
|   token    = var.gitea_token |   username = "lerentis" | ||||||
|  |   password = var.gitea_password | ||||||
|  |   #token    = var.gitea_token | ||||||
| } | } | ||||||
| @@ -2,7 +2,7 @@ terraform { | |||||||
|   required_providers { |   required_providers { | ||||||
|     gitea = { |     gitea = { | ||||||
|       source = "Lerentis/gitea" |       source = "Lerentis/gitea" | ||||||
|       version = "0.8.0" |       version = "0.13.0" | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										23
									
								
								examples/resources/gitea_fork/resource.tf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								examples/resources/gitea_fork/resource.tf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | resource "gitea_org" "org1" { | ||||||
|  |   name = "org1" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_org" "org2" { | ||||||
|  |   name = "org2" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_repository" "repo1_in_org1" { | ||||||
|  |   username = gitea_org.org1.name | ||||||
|  |   name     = "repo1-in-org1" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_fork" "user_fork_of_repo1_in_org1" { | ||||||
|  |   owner = gitea_org.org1.name | ||||||
|  |   repo  = gitea_repository.repo1_in_org1.name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_fork" "org2_fork_of_repo1_in_org1" { | ||||||
|  |   owner        = gitea_org.org1.name | ||||||
|  |   repo         = gitea_repository.repo1_in_org1.name | ||||||
|  |   organization = gitea_org.org2.name | ||||||
|  | } | ||||||
							
								
								
									
										25
									
								
								examples/resources/gitea_repository_key/resource.tf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								examples/resources/gitea_repository_key/resource.tf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | terraform { | ||||||
|  |   required_providers { | ||||||
|  |     tls = { | ||||||
|  |       source = "hashicorp/tls" | ||||||
|  |       version = "4.0.4" | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "tls_private_key" "example" { | ||||||
|  |   type = "RSA" | ||||||
|  |   rsa_bits = 4096 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_repository" "example" { | ||||||
|  |   name = "example" | ||||||
|  |   private = true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_repository_key" "example" { | ||||||
|  |   repository = gitea_repository.example.id | ||||||
|  |   title = "Example Deploy Key" | ||||||
|  |   read_only = true | ||||||
|  |   key = tls_private_key.example.public_key_openssh | ||||||
|  | } | ||||||
| @@ -19,3 +19,23 @@ resource "gitea_team" "test_team" { | |||||||
|   permission   = "write" |   permission   = "write" | ||||||
|   members      = [gitea_user.test.username] |   members      = [gitea_user.test.username] | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | resource "gitea_repository" "test" { | ||||||
|  |   username     = gitea_org.test_org.name | ||||||
|  |   name         = "test" | ||||||
|  |   private      = true | ||||||
|  |   issue_labels = "Default" | ||||||
|  |   license      = "MIT" | ||||||
|  |   gitignores   = "Go" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_team" "test_team_restricted" { | ||||||
|  |   name                     = "Restricted Devs" | ||||||
|  |   organisation             = gitea_org.test_org.name | ||||||
|  |   description              = "Restricted Devs of Test Org" | ||||||
|  |   permission               = "write" | ||||||
|  |   members                  = [gitea_user.test.username] | ||||||
|  |   include_all_repositories = false | ||||||
|  |   repositories             = [gitea_repository.test.name] | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										25
									
								
								examples/resources/gitea_token/resource.tf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								examples/resources/gitea_token/resource.tf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | provider "gitea" { | ||||||
|  |   base_url = var.gitea_url | ||||||
|  |   # Token Auth can not be used with this resource | ||||||
|  |   username = var.gitea_username | ||||||
|  |   password = var.gitea_password | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_user" "test" { | ||||||
|  |   username             = "test" | ||||||
|  |   login_name           = "test" | ||||||
|  |   password             = "Geheim1!" | ||||||
|  |   email                = "test@user.dev" | ||||||
|  |   must_change_password = false | ||||||
|  |   admin                = true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_token" "test_token" { | ||||||
|  |   username = resource.gitea_user.test.username | ||||||
|  |   name     = "test-token" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | output "token" { | ||||||
|  |   value     = resource.gitea_token.test_token.token | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
| @@ -9,3 +9,7 @@ variable "gitea_token" { | |||||||
| variable "gitea_mirror_token" { | variable "gitea_mirror_token" { | ||||||
|    |    | ||||||
| } | } | ||||||
|  |  | ||||||
|  | variable "gitea_password" { | ||||||
|  |    | ||||||
|  | } | ||||||
| @@ -6,6 +6,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/sdk/gitea" | 	"code.gitea.io/sdk/gitea" | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging" | ||||||
| @@ -28,8 +29,7 @@ func (c *Config) Client() (interface{}, error) { | |||||||
| 		return nil, fmt.Errorf("either a token or a username needs to be used") | 		return nil, fmt.Errorf("either a token or a username needs to be used") | ||||||
| 	} | 	} | ||||||
| 	// Configure TLS/SSL | 	// Configure TLS/SSL | ||||||
| 	tlsConfig := &tls.Config{} | 	var tlsConfig tls.Config | ||||||
|  |  | ||||||
| 	// If a CACertFile has been specified, use that for cert validation | 	// If a CACertFile has been specified, use that for cert validation | ||||||
| 	if c.CACertFile != "" { | 	if c.CACertFile != "" { | ||||||
| 		caCert, err := ioutil.ReadFile(c.CACertFile) | 		caCert, err := ioutil.ReadFile(c.CACertFile) | ||||||
| @@ -43,13 +43,12 @@ func (c *Config) Client() (interface{}, error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// If configured as insecure, turn off SSL verification | 	// If configured as insecure, turn off SSL verification | ||||||
| 	if c.Insecure { | 	tlsConfig.InsecureSkipVerify = c.Insecure | ||||||
| 		tlsConfig.InsecureSkipVerify = true |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	t := http.DefaultTransport.(*http.Transport).Clone() | 	t := http.DefaultTransport.(*http.Transport).Clone() | ||||||
| 	t.TLSClientConfig = tlsConfig | 	t.TLSClientConfig = &tlsConfig | ||||||
| 	t.MaxIdleConnsPerHost = 100 | 	t.MaxIdleConnsPerHost = 100 | ||||||
|  | 	t.TLSHandshakeTimeout = 10 * time.Second | ||||||
|  |  | ||||||
| 	httpClient := &http.Client{ | 	httpClient := &http.Client{ | ||||||
| 		Transport: logging.NewTransport("Gitea", t), | 		Transport: logging.NewTransport("Gitea", t), | ||||||
| @@ -60,16 +59,23 @@ func (c *Config) Client() (interface{}, error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var client *gitea.Client | 	var client *gitea.Client | ||||||
|  | 	var err error | ||||||
| 	if c.Token != "" { | 	if c.Token != "" { | ||||||
| 		client, _ = gitea.NewClient(c.BaseURL, gitea.SetToken(c.Token), gitea.SetHTTPClient(httpClient)) | 		client, err = gitea.NewClient(c.BaseURL, gitea.SetToken(c.Token), gitea.SetHTTPClient(httpClient)) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if c.Username != "" { | 	if c.Username != "" { | ||||||
| 		client, _ = gitea.NewClient(c.BaseURL, gitea.SetBasicAuth(c.Username, c.Password), gitea.SetHTTPClient(httpClient)) | 		client, err = gitea.NewClient(c.BaseURL, gitea.SetBasicAuth(c.Username, c.Password), gitea.SetHTTPClient(httpClient)) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Test the credentials by checking we can get information about the authenticated user. | 	// Test the credentials by checking we can get information about the authenticated user. | ||||||
| 	_, _, err := client.GetMyUserInfo() | 	_, _, err = client.GetMyUserInfo() | ||||||
|  |  | ||||||
| 	return client, err | 	return client, err | ||||||
| } | } | ||||||
|   | |||||||
| @@ -116,7 +116,7 @@ func dataSourceGiteaRepoRead(d *schema.ResourceData, meta interface{}) error { | |||||||
| 	} | 	} | ||||||
| 	username := strings.ToLower(usernameData.(string)) | 	username := strings.ToLower(usernameData.(string)) | ||||||
|  |  | ||||||
| 	nameData, nameOk := d.GetOk("username") | 	nameData, nameOk := d.GetOk("name") | ||||||
| 	if !nameOk { | 	if !nameOk { | ||||||
| 		return fmt.Errorf("name of repo must be passed") | 		return fmt.Errorf("name of repo must be passed") | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -73,14 +73,17 @@ func Provider() *schema.Provider { | |||||||
|  |  | ||||||
| 		ResourcesMap: map[string]*schema.Resource{ | 		ResourcesMap: map[string]*schema.Resource{ | ||||||
| 			"gitea_org": resourceGiteaOrg(), | 			"gitea_org": resourceGiteaOrg(), | ||||||
| 			// "gitea_team": resourceGiteaTeam(), | 			// "gitea_team":       resourceGiteaTeam(), | ||||||
| 			// "gitea_repo": resourceGiteaRepo(), | 			// "gitea_repo":       resourceGiteaRepo(), | ||||||
| 			"gitea_user":       resourceGiteaUser(), | 			"gitea_user":           resourceGiteaUser(), | ||||||
| 			"gitea_oauth2_app": resourceGiteaOauthApp(), | 			"gitea_oauth2_app":     resourceGiteaOauthApp(), | ||||||
| 			"gitea_repository": resourceGiteaRepository(), | 			"gitea_repository":     resourceGiteaRepository(), | ||||||
| 			"gitea_public_key": resourceGiteaPublicKey(), | 			"gitea_fork":           resourceGiteaFork(), | ||||||
| 			"gitea_team":       resourceGiteaTeam(), | 			"gitea_public_key":     resourceGiteaPublicKey(), | ||||||
| 			"gitea_git_hook":   resourceGiteaGitHook(), | 			"gitea_team":           resourceGiteaTeam(), | ||||||
|  | 			"gitea_git_hook":       resourceGiteaGitHook(), | ||||||
|  | 			"gitea_token":          resourceGiteaToken(), | ||||||
|  | 			"gitea_repository_key": resourceGiteaRepositoryKey(), | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		ConfigureFunc: providerConfigure, | 		ConfigureFunc: providerConfigure, | ||||||
|   | |||||||
							
								
								
									
										127
									
								
								gitea/resource_gitea_fork.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								gitea/resource_gitea_fork.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | |||||||
|  | package gitea | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/sdk/gitea" | ||||||
|  | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	forkOwner        string = "owner" | ||||||
|  | 	forkRepo         string = "repo" | ||||||
|  | 	forkOrganization string = "organization" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func resourceForkCreate(d *schema.ResourceData, meta interface{}) (err error) { | ||||||
|  | 	client := meta.(*gitea.Client) | ||||||
|  |  | ||||||
|  | 	var opts gitea.CreateForkOption | ||||||
|  | 	var org string | ||||||
|  | 	org = d.Get(forkOrganization).(string) | ||||||
|  | 	if org != "" { | ||||||
|  | 		opts.Organization = &org | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	repo, _, err := client.CreateFork(d.Get(forkOwner).(string), | ||||||
|  | 		d.Get(forkRepo).(string), | ||||||
|  | 		opts) | ||||||
|  | 	if err == nil { | ||||||
|  | 		err = setForkResourceData(repo, d) | ||||||
|  | 	} | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func resourceForkRead(d *schema.ResourceData, meta interface{}) (err error) { | ||||||
|  | 	client := meta.(*gitea.Client) | ||||||
|  |  | ||||||
|  | 	id, err := strconv.ParseInt(d.Id(), 10, 64) | ||||||
|  | 	var resp *gitea.Response | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	repo, resp, err := client.GetRepoByID(id) | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		if resp.StatusCode == 404 { | ||||||
|  | 			d.SetId("") | ||||||
|  | 			return nil | ||||||
|  | 		} else { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err = setForkResourceData(repo, d) | ||||||
|  |  | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func resourceForkDelete(d *schema.ResourceData, meta interface{}) (err error) { | ||||||
|  | 	client := meta.(*gitea.Client) | ||||||
|  |  | ||||||
|  | 	id, err := strconv.ParseInt(d.Id(), 10, 64) | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	repo, _, err := client.GetRepoByID(id) | ||||||
|  | 	var resp *gitea.Response | ||||||
|  |  | ||||||
|  | 	resp, err = client.DeleteRepo(repo.Owner.UserName, repo.Name) | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		if resp.StatusCode == 404 { | ||||||
|  | 			return | ||||||
|  | 		} else { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func setForkResourceData(repo *gitea.Repository, d *schema.ResourceData) (err error) { | ||||||
|  |  | ||||||
|  | 	d.SetId(fmt.Sprintf("%d", repo.ID)) | ||||||
|  |  | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func resourceGiteaFork() *schema.Resource { | ||||||
|  | 	return &schema.Resource{ | ||||||
|  | 		Read:   resourceForkRead, | ||||||
|  | 		Create: resourceForkCreate, | ||||||
|  | 		Delete: resourceForkDelete, | ||||||
|  | 		Importer: &schema.ResourceImporter{ | ||||||
|  | 			StateContext: schema.ImportStatePassthroughContext, | ||||||
|  | 		}, | ||||||
|  | 		Schema: map[string]*schema.Schema{ | ||||||
|  | 			"owner": { | ||||||
|  | 				Type:        schema.TypeString, | ||||||
|  | 				Required:    true, | ||||||
|  | 				ForceNew:    true, | ||||||
|  | 				Description: "The owner or owning organization of the repository to fork", | ||||||
|  | 			}, | ||||||
|  | 			"repo": { | ||||||
|  | 				Type:        schema.TypeString, | ||||||
|  | 				Required:    true, | ||||||
|  | 				ForceNew:    true, | ||||||
|  | 				Description: "The name of the repository to fork", | ||||||
|  | 			}, | ||||||
|  | 			"organization": { | ||||||
|  | 				Type:        schema.TypeString, | ||||||
|  | 				Required:    false, | ||||||
|  | 				Optional:    true, | ||||||
|  | 				ForceNew:    true, | ||||||
|  | 				Description: "The organization that owns the forked repo", | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		Description: "`gitea_fork` manages repository fork to the current user or an organisation\n" + | ||||||
|  | 			"Forking a repository to a dedicated user is currently unsupported\n" + | ||||||
|  | 			"Creating a fork using this resource without an organisation will create the fork in the executors name", | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -58,7 +58,8 @@ func resourceOrgRead(d *schema.ResourceData, meta interface{}) (err error) { | |||||||
| 	org, err = searchOrgByClientId(client, id) | 	org, err = searchOrgByClientId(client, id) | ||||||
|  |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		d.SetId("") | ||||||
|  | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err = setOrgResourceData(org, d) | 	err = setOrgResourceData(org, d) | ||||||
|   | |||||||
| @@ -1,10 +1,14 @@ | |||||||
| package gitea | package gitea | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strconv" | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
| 	"code.gitea.io/sdk/gitea" | 	"code.gitea.io/sdk/gitea" | ||||||
|  | 	"github.com/hashicorp/terraform-plugin-log/tflog" | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -48,6 +52,34 @@ const ( | |||||||
| 	migrationLFSEndpoint         string = "migration_lfs_endpoint" | 	migrationLFSEndpoint         string = "migration_lfs_endpoint" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | func searchUserByName(c *gitea.Client, name string) (res *gitea.User, err error) { | ||||||
|  | 	page := 1 | ||||||
|  |  | ||||||
|  | 	for { | ||||||
|  | 		users, _, err := c.AdminListUsers(gitea.AdminListUsersOptions{ | ||||||
|  | 			ListOptions: gitea.ListOptions{ | ||||||
|  | 				Page:     page, | ||||||
|  | 				PageSize: 50, | ||||||
|  | 			}, | ||||||
|  | 		}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if len(users) == 0 { | ||||||
|  | 			return nil, fmt.Errorf("User with name %s could not be found", name) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		for _, user := range users { | ||||||
|  | 			if user.UserName == name { | ||||||
|  | 				return user, nil | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		page += 1 | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func resourceRepoRead(d *schema.ResourceData, meta interface{}) (err error) { | func resourceRepoRead(d *schema.ResourceData, meta interface{}) (err error) { | ||||||
| 	client := meta.(*gitea.Client) | 	client := meta.(*gitea.Client) | ||||||
|  |  | ||||||
| @@ -79,11 +111,21 @@ func resourceRepoCreate(d *schema.ResourceData, meta interface{}) (err error) { | |||||||
|  |  | ||||||
| 	var repo *gitea.Repository | 	var repo *gitea.Repository | ||||||
| 	var resp *gitea.Response | 	var resp *gitea.Response | ||||||
| 	var orgRepo bool | 	var orgRepo, hasAdmin bool | ||||||
|  |  | ||||||
| 	_, resp, err = client.GetOrg(d.Get(repoOwner).(string)) | 	_, resp, err = client.GetOrg(d.Get(repoOwner).(string)) | ||||||
|  |  | ||||||
| 	if resp.StatusCode == 404 { | 	if resp.StatusCode == 404 { | ||||||
|  | 		_, err := searchUserByName(client, d.Get(repoOwner).(string)) | ||||||
|  | 		if err != nil { | ||||||
|  | 			if strings.Contains(err.Error(), "could not be found") { | ||||||
|  | 				return errors.New(fmt.Sprintf("Creation of repository cound not proceed as owner %s is not present in gitea", d.Get(repoOwner).(string))) | ||||||
|  | 			} | ||||||
|  | 			tflog.Warn(context.Background(), "Error query for users. Assuming missing permissions and proceding with user permissions") | ||||||
|  | 			hasAdmin = false | ||||||
|  | 		} else { | ||||||
|  | 			hasAdmin = true | ||||||
|  | 		} | ||||||
| 		orgRepo = false | 		orgRepo = false | ||||||
| 	} else { | 	} else { | ||||||
| 		orgRepo = true | 		orgRepo = true | ||||||
| @@ -147,12 +189,16 @@ func resourceRepoCreate(d *schema.ResourceData, meta interface{}) (err error) { | |||||||
| 		if orgRepo { | 		if orgRepo { | ||||||
| 			repo, _, err = client.CreateOrgRepo(d.Get(repoOwner).(string), opts) | 			repo, _, err = client.CreateOrgRepo(d.Get(repoOwner).(string), opts) | ||||||
| 		} else { | 		} else { | ||||||
| 			repo, _, err = client.CreateRepo(opts) | 			if hasAdmin { | ||||||
|  | 				repo, _, err = client.AdminCreateRepo(d.Get(repoOwner).(string), opts) | ||||||
|  | 			} else { | ||||||
|  | 				repo, _, err = client.CreateRepo(opts) | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err = setRepoResourceData(repo, d) | 	err = setRepoResourceData(repo, d) | ||||||
| @@ -530,11 +576,25 @@ func resourceGiteaRepository() *schema.Resource { | |||||||
| 				Optional: true, | 				Optional: true, | ||||||
| 				Default:  "", | 				Default:  "", | ||||||
| 			}, | 			}, | ||||||
|  | 			"clone_url": { | ||||||
|  | 				Type:     schema.TypeString, | ||||||
|  | 				Computed: true, | ||||||
|  | 			}, | ||||||
|  | 			"html_url": { | ||||||
|  | 				Type:     schema.TypeString, | ||||||
|  | 				Computed: true, | ||||||
|  | 			}, | ||||||
|  | 			"ssh_url": { | ||||||
|  | 				Type:     schema.TypeString, | ||||||
|  | 				Computed: true, | ||||||
|  | 			}, | ||||||
| 		}, | 		}, | ||||||
| 		Description: "`gitea_repository` manages a gitea repository.\n\n" + | 		Description: "`gitea_repository` manages a gitea repository.\n\n" + | ||||||
| 			"Per default this repository will be initializiled with the provided configuration (gitignore, License etc.).\n" + | 			"Per default this repository will be initializiled with the provided configuration (gitignore, License etc.).\n" + | ||||||
| 			"If the `username` property is set to a organisation name, the provider will try to look if this organisation exists " + | 			"If the `username` property is set to a organisation name, the provider will try to look if this organisation exists " + | ||||||
| 			"and create the repository under the organisation scope.\n\n" + | 			"and create the repository under the organisation scope.\n\n" + | ||||||
| 			"Repository migrations have some properties that are not available to regular repositories. These are all prefixed with `migration_`.", | 			"Repository migrations have some properties that are not available to regular repositories. These are all prefixed with `migration_`.\n" + | ||||||
|  | 			"Codeberg.org does currently not allow mirrors to be created. See FAQ Section of CodeBerg for more information: " + | ||||||
|  | 			"https://docs.codeberg.org/getting-started/faq/#why-am-i-not-allowed-to-set-up-an-automatic-mirror", | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										169
									
								
								gitea/resource_gitea_repository_key.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								gitea/resource_gitea_repository_key.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,169 @@ | |||||||
|  | package gitea | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/sdk/gitea" | ||||||
|  | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	deployKeyRepoId   string = "repository" | ||||||
|  | 	deployKeyName     string = "title" | ||||||
|  | 	deployKeyKey      string = "key" | ||||||
|  | 	deployKeyReadOnly string = "read_only" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func resourceRepoKeyIdParts(d *schema.ResourceData) (bool, int64, int64, error) { | ||||||
|  | 	parts := strings.Split(d.Id(), "/") | ||||||
|  | 	if len(parts) != 2 { | ||||||
|  | 		return false, 0, 0, nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	repoId, err := strconv.ParseInt(parts[0], 10, 64) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, 0, 0, err | ||||||
|  | 	} | ||||||
|  | 	keyId, err := strconv.ParseInt(parts[1], 10, 64) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, 0, 0, err | ||||||
|  | 	} | ||||||
|  | 	return true, repoId, keyId, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func resourceRepoKeyRead(d *schema.ResourceData, meta interface{}) (err error) { | ||||||
|  | 	client := meta.(*gitea.Client) | ||||||
|  |  | ||||||
|  | 	hasId, repoId, keyId, err := resourceRepoKeyIdParts(d) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	if !hasId { | ||||||
|  | 		d.SetId("") | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	repo, resp, err := client.GetRepoByID(repoId) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if resp.StatusCode == 404 { | ||||||
|  | 			d.SetId("") | ||||||
|  | 			return nil | ||||||
|  | 		} else { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	key, resp, err := client.GetDeployKey(repo.Owner.UserName, repo.Name, keyId) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if resp.StatusCode == 404 { | ||||||
|  | 			d.SetId("") | ||||||
|  | 			return nil | ||||||
|  | 		} else { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err = setRepoKeyResourceData(key, repoId, d) | ||||||
|  |  | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func resourceRepoKeyCreate(d *schema.ResourceData, meta interface{}) (err error) { | ||||||
|  | 	client := meta.(*gitea.Client) | ||||||
|  |  | ||||||
|  | 	repo, _, err := client.GetRepoByID(int64(d.Get(deployKeyRepoId).(int))) | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dk, _, err := client.CreateDeployKey(repo.Owner.UserName, repo.Name, gitea.CreateKeyOption{ | ||||||
|  | 		Title:    d.Get(deployKeyName).(string), | ||||||
|  | 		ReadOnly: d.Get(deployKeyReadOnly).(bool), | ||||||
|  | 		Key:      d.Get(deployKeyKey).(string), | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	setRepoKeyResourceData(dk, repo.ID, d) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func respurceRepoKeyDelete(d *schema.ResourceData, meta interface{}) (err error) { | ||||||
|  | 	client := meta.(*gitea.Client) | ||||||
|  |  | ||||||
|  | 	hasId, repoId, keyId, err := resourceRepoKeyIdParts(d) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	if !hasId { | ||||||
|  | 		d.SetId("") | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	repo, resp, err := client.GetRepoByID(repoId) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if resp.StatusCode == 404 { | ||||||
|  | 			d.SetId("") | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	client.DeleteDeployKey(repo.Owner.UserName, repo.Name, keyId) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func setRepoKeyResourceData(dk *gitea.DeployKey, repoId int64, d *schema.ResourceData) (err error) { | ||||||
|  | 	d.SetId(fmt.Sprintf("%d/%d", repoId, dk.ID)) | ||||||
|  | 	d.Set(deployKeyRepoId, repoId) | ||||||
|  | 	d.Set(deployKeyReadOnly, dk.ReadOnly) | ||||||
|  | 	d.Set(deployKeyKey, dk.Key) | ||||||
|  | 	d.Set(deployKeyName, dk.Title) | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func resourceGiteaRepositoryKey() *schema.Resource { | ||||||
|  | 	return &schema.Resource{ | ||||||
|  | 		Read:   resourceRepoKeyRead, | ||||||
|  | 		Create: resourceRepoKeyCreate, | ||||||
|  | 		Delete: respurceRepoKeyDelete, | ||||||
|  | 		Importer: &schema.ResourceImporter{ | ||||||
|  | 			StateContext: schema.ImportStatePassthroughContext, | ||||||
|  | 		}, | ||||||
|  | 		Schema: map[string]*schema.Schema{ | ||||||
|  | 			deployKeyRepoId: { | ||||||
|  | 				Type:        schema.TypeInt, | ||||||
|  | 				Required:    true, | ||||||
|  | 				ForceNew:    true, | ||||||
|  | 				Description: "The ID of the repository where the deploy key belongs to", | ||||||
|  | 			}, | ||||||
|  | 			deployKeyKey: { | ||||||
|  | 				Type:        schema.TypeString, | ||||||
|  | 				Required:    true, | ||||||
|  | 				ForceNew:    true, | ||||||
|  | 				Description: "Armored SSH key to add", | ||||||
|  | 			}, | ||||||
|  | 			deployKeyReadOnly: { | ||||||
|  | 				Type:        schema.TypeBool, | ||||||
|  | 				Required:    false, | ||||||
|  | 				Optional:    true, | ||||||
|  | 				Default:     true, | ||||||
|  | 				ForceNew:    true, | ||||||
|  | 				Description: "Whether this key has read or read/write access", | ||||||
|  | 			}, | ||||||
|  | 			deployKeyName: { | ||||||
|  | 				Type:        schema.TypeString, | ||||||
|  | 				Required:    true, | ||||||
|  | 				ForceNew:    true, | ||||||
|  | 				Description: "Name of the deploy key", | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		Description: "`gitea_repository_key` manages a deploy key for a single gitea_repository.\n\n" + | ||||||
|  | 			"Every key needs a unique name and unique key, i.e. no key can be added twice to the same repo", | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -1,6 +1,7 @@ | |||||||
| package gitea | package gitea | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| @@ -18,6 +19,7 @@ const ( | |||||||
| 	TeamIncludeAllReposFlag string = "include_all_repositories" | 	TeamIncludeAllReposFlag string = "include_all_repositories" | ||||||
| 	TeamUnits               string = "units" | 	TeamUnits               string = "units" | ||||||
| 	TeamMembers             string = "members" | 	TeamMembers             string = "members" | ||||||
|  | 	TeamRepositories        string = "repositories" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func resourceTeamRead(d *schema.ResourceData, meta interface{}) (err error) { | func resourceTeamRead(d *schema.ResourceData, meta interface{}) (err error) { | ||||||
| @@ -75,12 +77,14 @@ func resourceTeamCreate(d *schema.ResourceData, meta interface{}) (err error) { | |||||||
| 		units = append(units, gitea.RepoUnitProjects) | 		units = append(units, gitea.RepoUnitProjects) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	includeAllRepos := d.Get(TeamIncludeAllReposFlag).(bool) | ||||||
|  |  | ||||||
| 	opts := gitea.CreateTeamOption{ | 	opts := gitea.CreateTeamOption{ | ||||||
| 		Name:                    d.Get(TeamName).(string), | 		Name:                    d.Get(TeamName).(string), | ||||||
| 		Description:             d.Get(TeamDescription).(string), | 		Description:             d.Get(TeamDescription).(string), | ||||||
| 		Permission:              gitea.AccessMode(d.Get(TeamPermissions).(string)), | 		Permission:              gitea.AccessMode(d.Get(TeamPermissions).(string)), | ||||||
| 		CanCreateOrgRepo:        d.Get(TeamCreateRepoFlag).(bool), | 		CanCreateOrgRepo:        d.Get(TeamCreateRepoFlag).(bool), | ||||||
| 		IncludesAllRepositories: d.Get(TeamIncludeAllReposFlag).(bool), | 		IncludesAllRepositories: includeAllRepos, | ||||||
| 		Units:                   units, | 		Units:                   units, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -101,6 +105,13 @@ func resourceTeamCreate(d *schema.ResourceData, meta interface{}) (err error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if !includeAllRepos { | ||||||
|  | 		err = setTeamRepositories(team, d, meta, false) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	err = setTeamResourceData(team, d) | 	err = setTeamResourceData(team, d) | ||||||
|  |  | ||||||
| 	return | 	return | ||||||
| @@ -181,6 +192,13 @@ func resourceTeamUpdate(d *schema.ResourceData, meta interface{}) (err error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if !includeAllRepos { | ||||||
|  | 		err = setTeamRepositories(team, d, meta, true) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	team, _, _ = client.GetTeam(id) | 	team, _, _ = client.GetTeam(id) | ||||||
|  |  | ||||||
| 	err = setTeamResourceData(team, d) | 	err = setTeamResourceData(team, d) | ||||||
| @@ -218,6 +236,7 @@ func setTeamResourceData(team *gitea.Team, d *schema.ResourceData) (err error) { | |||||||
| 	d.Set(TeamUnits, d.Get(TeamUnits).(string)) | 	d.Set(TeamUnits, d.Get(TeamUnits).(string)) | ||||||
| 	d.Set(TeamOrg, d.Get(TeamOrg).(string)) | 	d.Set(TeamOrg, d.Get(TeamOrg).(string)) | ||||||
| 	d.Set(TeamMembers, d.Get(TeamMembers)) | 	d.Set(TeamMembers, d.Get(TeamMembers)) | ||||||
|  | 	d.Set(TeamRepositories, d.Get(TeamRepositories)) | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -290,7 +309,75 @@ func resourceGiteaTeam() *schema.Resource { | |||||||
| 				Computed:    true, | 				Computed:    true, | ||||||
| 				Description: "List of Users that should be part of this team", | 				Description: "List of Users that should be part of this team", | ||||||
| 			}, | 			}, | ||||||
|  | 			"repositories": { | ||||||
|  | 				Type: schema.TypeList, | ||||||
|  | 				Elem: &schema.Schema{ | ||||||
|  | 					Type: schema.TypeString, | ||||||
|  | 				}, | ||||||
|  | 				Optional:    true, | ||||||
|  | 				Required:    false, | ||||||
|  | 				Computed:    true, | ||||||
|  | 				Description: "List of Repositories that should be part of this team", | ||||||
|  | 			}, | ||||||
| 		}, | 		}, | ||||||
| 		Description: "`gitea_team` manages Team that are part of an organisation.", | 		Description: "`gitea_team` manages Team that are part of an organisation.", | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func setTeamRepositories(team *gitea.Team, d *schema.ResourceData, meta interface{}, update bool) (err error) { | ||||||
|  | 	client := meta.(*gitea.Client) | ||||||
|  |  | ||||||
|  | 	org := d.Get(TeamOrg).(string) | ||||||
|  |  | ||||||
|  | 	repositories := make(map[string]bool) | ||||||
|  | 	for _, repo := range d.Get(TeamRepositories).([]interface{}) { | ||||||
|  | 		if repo != "" { | ||||||
|  | 			repositories[repo.(string)] = true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if update { | ||||||
|  | 		page := 1 | ||||||
|  |  | ||||||
|  | 		for { | ||||||
|  | 			var existingRepositories []*gitea.Repository | ||||||
|  | 			existingRepositories, _, err = client.ListTeamRepositories(team.ID, gitea.ListTeamRepositoriesOptions{ | ||||||
|  | 				ListOptions: gitea.ListOptions{ | ||||||
|  | 					Page:     page, | ||||||
|  | 					PageSize: 50, | ||||||
|  | 				}, | ||||||
|  | 			}) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return errors.New(fmt.Sprintf("[ERROR] Error listeng team repositories: %s", err)) | ||||||
|  | 			} | ||||||
|  | 			if len(existingRepositories) == 0 { | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			for _, exr := range existingRepositories { | ||||||
|  | 				_, exists := repositories[exr.Name] | ||||||
|  | 				if exists { | ||||||
|  | 					repositories[exr.Name] = false | ||||||
|  | 				} else { | ||||||
|  | 					_, err = client.RemoveTeamRepository(team.ID, org, exr.Name) | ||||||
|  | 					if err != nil { | ||||||
|  | 						return errors.New(fmt.Sprintf("[ERROR] Error removing team repository %q: %s", exr.Name, err)) | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			page += 1 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for repo, flag := range repositories { | ||||||
|  | 		if flag { | ||||||
|  | 			_, err = client.AddTeamRepository(team.ID, org, repo) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return errors.New(fmt.Sprintf("[ERROR] Error adding team repository %q: %s", repo, err)) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										151
									
								
								gitea/resource_gitea_token.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								gitea/resource_gitea_token.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,151 @@ | |||||||
|  | package gitea | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/sdk/gitea" | ||||||
|  | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	TokenUsername  string = "username" | ||||||
|  | 	TokenName      string = "name" | ||||||
|  | 	TokenHash      string = "token" | ||||||
|  | 	TokenLastEight string = "last_eight" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func searchTokenById(c *gitea.Client, id int64) (res *gitea.AccessToken, err error) { | ||||||
|  | 	page := 1 | ||||||
|  |  | ||||||
|  | 	for { | ||||||
|  | 		tokens, _, err := c.ListAccessTokens(gitea.ListAccessTokensOptions{ | ||||||
|  | 			ListOptions: gitea.ListOptions{ | ||||||
|  | 				Page:     page, | ||||||
|  | 				PageSize: 50, | ||||||
|  | 			}, | ||||||
|  | 		}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if len(tokens) == 0 { | ||||||
|  | 			return nil, fmt.Errorf("Token with ID %d could not be found", id) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		for _, token := range tokens { | ||||||
|  | 			if token.ID == id { | ||||||
|  | 				return token, nil | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		page += 1 | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func resourceTokenCreate(d *schema.ResourceData, meta interface{}) (err error) { | ||||||
|  |  | ||||||
|  | 	client := meta.(*gitea.Client) | ||||||
|  |  | ||||||
|  | 	var opt gitea.CreateAccessTokenOption | ||||||
|  | 	opt.Name = d.Get(TokenName).(string) | ||||||
|  |  | ||||||
|  | 	token, _, err := client.CreateAccessToken(opt) | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err = setTokenResourceData(token, d) | ||||||
|  |  | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func resourceTokenRead(d *schema.ResourceData, meta interface{}) (err error) { | ||||||
|  |  | ||||||
|  | 	client := meta.(*gitea.Client) | ||||||
|  |  | ||||||
|  | 	var token *gitea.AccessToken | ||||||
|  |  | ||||||
|  | 	id, err := strconv.ParseInt(d.Id(), 10, 64) | ||||||
|  |  | ||||||
|  | 	token, err = searchTokenById(client, id) | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err = setTokenResourceData(token, d) | ||||||
|  |  | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func resourceTokenDelete(d *schema.ResourceData, meta interface{}) (err error) { | ||||||
|  |  | ||||||
|  | 	client := meta.(*gitea.Client) | ||||||
|  | 	var resp *gitea.Response | ||||||
|  |  | ||||||
|  | 	resp, err = client.DeleteAccessToken(d.Get(TokenName).(string)) | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		if resp.StatusCode == 404 { | ||||||
|  | 			return | ||||||
|  | 		} else { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func setTokenResourceData(token *gitea.AccessToken, d *schema.ResourceData) (err error) { | ||||||
|  |  | ||||||
|  | 	d.SetId(fmt.Sprintf("%d", token.ID)) | ||||||
|  | 	d.Set(TokenName, token.Name) | ||||||
|  | 	if token.Token != "" { | ||||||
|  | 		d.Set(TokenHash, token.Token) | ||||||
|  | 	} | ||||||
|  | 	d.Set(TokenLastEight, token.TokenLastEight) | ||||||
|  |  | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func resourceGiteaToken() *schema.Resource { | ||||||
|  | 	return &schema.Resource{ | ||||||
|  | 		Read:   resourceTokenRead, | ||||||
|  | 		Create: resourceTokenCreate, | ||||||
|  | 		Delete: resourceTokenDelete, | ||||||
|  | 		Importer: &schema.ResourceImporter{ | ||||||
|  | 			StateContext: schema.ImportStatePassthroughContext, | ||||||
|  | 		}, | ||||||
|  | 		Schema: map[string]*schema.Schema{ | ||||||
|  | 			"username": { | ||||||
|  | 				Type:        schema.TypeString, | ||||||
|  | 				Required:    true, | ||||||
|  | 				ForceNew:    true, | ||||||
|  | 				Description: "The owner of the Access Token", | ||||||
|  | 			}, | ||||||
|  | 			"name": { | ||||||
|  | 				Type:        schema.TypeString, | ||||||
|  | 				Required:    true, | ||||||
|  | 				ForceNew:    true, | ||||||
|  | 				Description: "The name of the Access Token", | ||||||
|  | 			}, | ||||||
|  | 			"token": { | ||||||
|  | 				Type:        schema.TypeString, | ||||||
|  | 				Computed:    true, | ||||||
|  | 				Sensitive:   true, | ||||||
|  | 				Description: "The actual Access Token", | ||||||
|  | 			}, | ||||||
|  | 			"last_eight": { | ||||||
|  | 				Type:     schema.TypeString, | ||||||
|  | 				Computed: true, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		Description: "`gitea_token` manages gitea Access Tokens.\n\n" + | ||||||
|  | 			"Due to upstream limitations (see https://gitea.com/gitea/go-sdk/issues/610) this resource\n" + | ||||||
|  | 			"can only be used with username/password provider configuration.\n\n" + | ||||||
|  | 			"WARNING:\n" + | ||||||
|  | 			"Tokens will be stored in the terraform state!", | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										64
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								go.mod
									
									
									
									
									
								
							| @@ -4,65 +4,67 @@ go 1.18 | |||||||
|  |  | ||||||
| require ( | require ( | ||||||
| 	code.gitea.io/sdk/gitea v0.15.1 | 	code.gitea.io/sdk/gitea v0.15.1 | ||||||
| 	github.com/hashicorp/terraform-plugin-docs v0.7.0 | 	github.com/hashicorp/terraform-plugin-docs v0.14.1 | ||||||
| 	github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 | 	github.com/hashicorp/terraform-plugin-log v0.8.0 | ||||||
|  | 	github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1 | ||||||
| ) | ) | ||||||
|  |  | ||||||
| require ( | require ( | ||||||
| 	github.com/Masterminds/goutils v1.1.0 // indirect | 	github.com/Masterminds/goutils v1.1.1 // indirect | ||||||
| 	github.com/Masterminds/semver v1.5.0 // indirect | 	github.com/Masterminds/semver/v3 v3.1.1 // indirect | ||||||
| 	github.com/Masterminds/sprig v2.22.0+incompatible // indirect | 	github.com/Masterminds/sprig/v3 v3.2.2 // indirect | ||||||
| 	github.com/agext/levenshtein v1.2.2 // indirect | 	github.com/agext/levenshtein v1.2.2 // indirect | ||||||
| 	github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect | 	github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect | ||||||
| 	github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 // indirect | 	github.com/armon/go-radix v1.0.0 // indirect | ||||||
| 	github.com/bgentry/speakeasy v0.1.0 // indirect | 	github.com/bgentry/speakeasy v0.1.0 // indirect | ||||||
| 	github.com/davecgh/go-spew v1.1.1 // indirect |  | ||||||
| 	github.com/fatih/color v1.13.0 // indirect | 	github.com/fatih/color v1.13.0 // indirect | ||||||
| 	github.com/golang/protobuf v1.5.2 // indirect | 	github.com/golang/protobuf v1.5.2 // indirect | ||||||
| 	github.com/google/go-cmp v0.5.8 // indirect | 	github.com/google/go-cmp v0.5.9 // indirect | ||||||
| 	github.com/google/uuid v1.1.2 // indirect | 	github.com/google/uuid v1.3.0 // indirect | ||||||
| 	github.com/hashicorp/errwrap v1.0.0 // indirect | 	github.com/hashicorp/errwrap v1.1.0 // indirect | ||||||
| 	github.com/hashicorp/go-checkpoint v0.5.0 // indirect | 	github.com/hashicorp/go-checkpoint v0.5.0 // indirect | ||||||
| 	github.com/hashicorp/go-cleanhttp v0.5.2 // indirect | 	github.com/hashicorp/go-cleanhttp v0.5.2 // indirect | ||||||
| 	github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect | 	github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect | ||||||
| 	github.com/hashicorp/go-hclog v1.2.1 // indirect | 	github.com/hashicorp/go-hclog v1.4.0 // indirect | ||||||
| 	github.com/hashicorp/go-multierror v1.1.1 // indirect | 	github.com/hashicorp/go-multierror v1.1.1 // indirect | ||||||
| 	github.com/hashicorp/go-plugin v1.4.4 // indirect | 	github.com/hashicorp/go-plugin v1.4.8 // indirect | ||||||
| 	github.com/hashicorp/go-uuid v1.0.3 // indirect | 	github.com/hashicorp/go-uuid v1.0.3 // indirect | ||||||
| 	github.com/hashicorp/go-version v1.6.0 // indirect | 	github.com/hashicorp/go-version v1.6.0 // indirect | ||||||
| 	github.com/hashicorp/hc-install v0.4.0 // indirect | 	github.com/hashicorp/hc-install v0.5.0 // indirect | ||||||
| 	github.com/hashicorp/hcl/v2 v2.13.0 // indirect | 	github.com/hashicorp/hcl/v2 v2.16.2 // indirect | ||||||
| 	github.com/hashicorp/logutils v1.0.0 // indirect | 	github.com/hashicorp/logutils v1.0.0 // indirect | ||||||
| 	github.com/hashicorp/terraform-exec v0.17.2 // indirect | 	github.com/hashicorp/terraform-exec v0.18.1 // indirect | ||||||
| 	github.com/hashicorp/terraform-json v0.14.0 // indirect | 	github.com/hashicorp/terraform-json v0.16.0 // indirect | ||||||
| 	github.com/hashicorp/terraform-plugin-go v0.12.0 // indirect | 	github.com/hashicorp/terraform-plugin-go v0.14.3 // indirect | ||||||
| 	github.com/hashicorp/terraform-plugin-log v0.7.0 // indirect | 	github.com/hashicorp/terraform-registry-address v0.1.0 // indirect | ||||||
| 	github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c // indirect |  | ||||||
| 	github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 // indirect | 	github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 // indirect | ||||||
| 	github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect | 	github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect | ||||||
| 	github.com/huandu/xstrings v1.3.2 // indirect | 	github.com/huandu/xstrings v1.3.2 // indirect | ||||||
| 	github.com/imdario/mergo v0.3.12 // indirect | 	github.com/imdario/mergo v0.3.13 // indirect | ||||||
| 	github.com/mattn/go-colorable v0.1.12 // indirect | 	github.com/mattn/go-colorable v0.1.13 // indirect | ||||||
| 	github.com/mattn/go-isatty v0.0.14 // indirect | 	github.com/mattn/go-isatty v0.0.16 // indirect | ||||||
| 	github.com/mitchellh/cli v1.1.2 // indirect | 	github.com/mitchellh/cli v1.1.5 // indirect | ||||||
| 	github.com/mitchellh/copystructure v1.2.0 // indirect | 	github.com/mitchellh/copystructure v1.2.0 // indirect | ||||||
| 	github.com/mitchellh/go-testing-interface v1.14.1 // indirect | 	github.com/mitchellh/go-testing-interface v1.14.1 // indirect | ||||||
| 	github.com/mitchellh/go-wordwrap v1.0.0 // indirect | 	github.com/mitchellh/go-wordwrap v1.0.0 // indirect | ||||||
| 	github.com/mitchellh/mapstructure v1.5.0 // indirect | 	github.com/mitchellh/mapstructure v1.5.0 // indirect | ||||||
| 	github.com/mitchellh/reflectwalk v1.0.2 // indirect | 	github.com/mitchellh/reflectwalk v1.0.2 // indirect | ||||||
| 	github.com/oklog/run v1.0.0 // indirect | 	github.com/oklog/run v1.0.0 // indirect | ||||||
| 	github.com/posener/complete v1.1.1 // indirect | 	github.com/posener/complete v1.2.3 // indirect | ||||||
| 	github.com/russross/blackfriday v1.6.0 // indirect | 	github.com/russross/blackfriday v1.6.0 // indirect | ||||||
|  | 	github.com/shopspring/decimal v1.3.1 // indirect | ||||||
|  | 	github.com/spf13/cast v1.5.0 // indirect | ||||||
| 	github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect | 	github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect | ||||||
| 	github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect | 	github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect | ||||||
| 	github.com/vmihailenco/tagparser v0.1.1 // indirect | 	github.com/vmihailenco/tagparser v0.1.1 // indirect | ||||||
| 	github.com/zclconf/go-cty v1.10.0 // indirect | 	github.com/zclconf/go-cty v1.13.1 // indirect | ||||||
| 	golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 // indirect | 	golang.org/x/crypto v0.7.0 // indirect | ||||||
| 	golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect | 	golang.org/x/mod v0.8.0 // indirect | ||||||
| 	golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect | 	golang.org/x/net v0.8.0 // indirect | ||||||
| 	golang.org/x/text v0.3.7 // indirect | 	golang.org/x/sys v0.6.0 // indirect | ||||||
|  | 	golang.org/x/text v0.8.0 // indirect | ||||||
| 	google.golang.org/appengine v1.6.6 // indirect | 	google.golang.org/appengine v1.6.6 // indirect | ||||||
| 	google.golang.org/genproto v0.0.0-20200711021454-869866162049 // indirect | 	google.golang.org/genproto v0.0.0-20200711021454-869866162049 // indirect | ||||||
| 	google.golang.org/grpc v1.48.0 // indirect | 	google.golang.org/grpc v1.51.0 // indirect | ||||||
| 	google.golang.org/protobuf v1.28.0 // indirect | 	google.golang.org/protobuf v1.28.1 // indirect | ||||||
| ) | ) | ||||||
|   | |||||||
							
								
								
									
										192
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										192
									
								
								go.sum
									
									
									
									
									
								
							| @@ -4,12 +4,13 @@ code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFj | |||||||
| code.gitea.io/sdk/gitea v0.15.1 h1:WJreC7YYuxbn0UDaPuWIe/mtiNKTvLN8MLkaw71yx/M= | code.gitea.io/sdk/gitea v0.15.1 h1:WJreC7YYuxbn0UDaPuWIe/mtiNKTvLN8MLkaw71yx/M= | ||||||
| code.gitea.io/sdk/gitea v0.15.1/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA= | code.gitea.io/sdk/gitea v0.15.1/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA= | ||||||
| github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||||||
| github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= | github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= | ||||||
| github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= | github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= | ||||||
| github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= | github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= | ||||||
| github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= | github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= | ||||||
| github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= | github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= | ||||||
| github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= | github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= | ||||||
|  | github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= | ||||||
| github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= | github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= | ||||||
| github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= | github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= | ||||||
| github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= | github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= | ||||||
| @@ -20,43 +21,31 @@ github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ | |||||||
| github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= | github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= | ||||||
| github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= | github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= | ||||||
| github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= | ||||||
| github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= |  | ||||||
| github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I= |  | ||||||
| github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= | github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= | ||||||
| github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= | github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= | ||||||
| github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= | github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= | ||||||
| github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= | github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= | ||||||
| github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to= |  | ||||||
| github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= | github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= | ||||||
|  | github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= | ||||||
|  | github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= | ||||||
| github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= | ||||||
| github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= | github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= | ||||||
| github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= | ||||||
| github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | ||||||
| github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= |  | ||||||
| github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= | ||||||
| github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= |  | ||||||
| github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= |  | ||||||
| github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= |  | ||||||
| github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= |  | ||||||
| github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= |  | ||||||
| github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= |  | ||||||
| github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= | ||||||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||||
| github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||||||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||||
| github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= | github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= | ||||||
| github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= | github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= | ||||||
| github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= |  | ||||||
| github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= | ||||||
| github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= |  | ||||||
| github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= |  | ||||||
| github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= |  | ||||||
| github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= | ||||||
| github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= | ||||||
| github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= | github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= | ||||||
| github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= | github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= | ||||||
| github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= | github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= | ||||||
| github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= | github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= | ||||||
| github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= | github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= | ||||||
| github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= | github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= | ||||||
| github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= | github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= | ||||||
| @@ -73,7 +62,6 @@ github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y | |||||||
| github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||||
| github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||||
| github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||||
| github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= |  | ||||||
| github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= | ||||||
| github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= | ||||||
| github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= | ||||||
| @@ -81,8 +69,6 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU | |||||||
| github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= | ||||||
| github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= | ||||||
| github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= | ||||||
| github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= |  | ||||||
| github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= |  | ||||||
| github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= | ||||||
| github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= | ||||||
| github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= | ||||||
| @@ -90,16 +76,16 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a | |||||||
| github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= |  | ||||||
| github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||||
| github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= | ||||||
| github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | ||||||
| github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||||||
| github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= |  | ||||||
| github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||||||
| github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= | ||||||
| github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||||||
| github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= | ||||||
|  | github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= | ||||||
|  | github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= | ||||||
| github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= | github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= | ||||||
| github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= | github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= | ||||||
| github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= | github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= | ||||||
| @@ -108,50 +94,51 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n | |||||||
| github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= | github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= | ||||||
| github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= | github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= | ||||||
| github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= | github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= | ||||||
| github.com/hashicorp/go-hclog v1.2.1 h1:YQsLlGDJgwhXFpucSPyVbCBviQtjlHv3jLTlp8YmtEw= | github.com/hashicorp/go-hclog v1.4.0 h1:ctuWFGrhFha8BnnzxqeRGidlEcQkDyL5u8J8t5eA11I= | ||||||
| github.com/hashicorp/go-hclog v1.2.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= | github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= | ||||||
| github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= | github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= | ||||||
| github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= | github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= | ||||||
| github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= | github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= | ||||||
| github.com/hashicorp/go-plugin v1.4.4 h1:NVdrSdFRt3SkZtNckJ6tog7gbpRrcbOjQi/rgF7JYWQ= | github.com/hashicorp/go-plugin v1.4.8 h1:CHGwpxYDOttQOY7HOWgETU9dyVjOXzniXDqJcYJE1zM= | ||||||
| github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= | github.com/hashicorp/go-plugin v1.4.8/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= | ||||||
| github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||||
| github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= | github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= | ||||||
| github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||||
| github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | ||||||
| github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | ||||||
| github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= |  | ||||||
| github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= | github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= | ||||||
| github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | ||||||
| github.com/hashicorp/hc-install v0.4.0 h1:cZkRFr1WVa0Ty6x5fTvL1TuO1flul231rWkGH92oYYk= | github.com/hashicorp/hc-install v0.5.0 h1:D9bl4KayIYKEeJ4vUDe9L5huqxZXczKaykSRcmQ0xY0= | ||||||
| github.com/hashicorp/hc-install v0.4.0/go.mod h1:5d155H8EC5ewegao9A4PUTMNPZaq+TbOzkJJZ4vrXeI= | github.com/hashicorp/hc-install v0.5.0/go.mod h1:JyzMfbzfSBSjoDCRPna1vi/24BEDxFaCPfdHtM5SCdo= | ||||||
| github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc= | github.com/hashicorp/hcl/v2 v2.16.2 h1:mpkHZh/Tv+xet3sy3F9Ld4FyI2tUpWe9x3XtPx9f1a0= | ||||||
| github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0= | github.com/hashicorp/hcl/v2 v2.16.2/go.mod h1:JRmR89jycNkrrqnMmvPDMd56n1rQJ2Q6KocSLCMCXng= | ||||||
| github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= | github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= | ||||||
| github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= | github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= | ||||||
| github.com/hashicorp/terraform-exec v0.17.2 h1:EU7i3Fh7vDUI9nNRdMATCEfnm9axzTnad8zszYZ73Go= | github.com/hashicorp/terraform-exec v0.18.1 h1:LAbfDvNQU1l0NOQlTuudjczVhHj061fNX5H8XZxHlH4= | ||||||
| github.com/hashicorp/terraform-exec v0.17.2/go.mod h1:tuIbsL2l4MlwwIZx9HPM+LOV9vVyEfBYu2GsO1uH3/8= | github.com/hashicorp/terraform-exec v0.18.1/go.mod h1:58wg4IeuAJ6LVsLUeD2DWZZoc/bYi6dzhLHzxM41980= | ||||||
| github.com/hashicorp/terraform-json v0.14.0 h1:sh9iZ1Y8IFJLx+xQiKHGud6/TSUCM0N8e17dKDpqV7s= | github.com/hashicorp/terraform-json v0.16.0 h1:UKkeWRWb23do5LNAFlh/K3N0ymn1qTOO8c+85Albo3s= | ||||||
| github.com/hashicorp/terraform-json v0.14.0/go.mod h1:5A9HIWPkk4e5aeeXIBbkcOvaZbIYnAIkEyqP2pNSckM= | github.com/hashicorp/terraform-json v0.16.0/go.mod h1:v0Ufk9jJnk6tcIZvScHvetlKfiNTC+WS21mnXIlc0B0= | ||||||
| github.com/hashicorp/terraform-plugin-docs v0.7.0 h1:7XKAOYHAxghe7q4/vx468X43X9GikdQ2dxtmcu2gQv0= | github.com/hashicorp/terraform-plugin-docs v0.14.1 h1:MikFi59KxrP/ewrZoaowrB9he5Vu4FtvhamZFustiA4= | ||||||
| github.com/hashicorp/terraform-plugin-docs v0.7.0/go.mod h1:57CICKfW7/KbW4lPhKOledyT6vu1LeAOzuvWXsVaxUE= | github.com/hashicorp/terraform-plugin-docs v0.14.1/go.mod h1:k2NW8+t113jAus6bb5tQYQgEAX/KueE/u8X2Z45V1GM= | ||||||
| github.com/hashicorp/terraform-plugin-go v0.12.0 h1:6wW9mT1dSs0Xq4LR6HXj1heQ5ovr5GxXNJwkErZzpJw= | github.com/hashicorp/terraform-plugin-go v0.14.3 h1:nlnJ1GXKdMwsC8g1Nh05tK2wsC3+3BL/DBBxFEki+j0= | ||||||
| github.com/hashicorp/terraform-plugin-go v0.12.0/go.mod h1:kwhmaWHNDvT1B3QiSJdAtrB/D4RaKSY/v3r2BuoWK4M= | github.com/hashicorp/terraform-plugin-go v0.14.3/go.mod h1:7ees7DMZ263q8wQ6E4RdIdR6nHHJtrdt4ogX5lPkX1A= | ||||||
| github.com/hashicorp/terraform-plugin-log v0.7.0 h1:SDxJUyT8TwN4l5b5/VkiTIaQgY6R+Y2BQ0sRZftGKQs= | github.com/hashicorp/terraform-plugin-log v0.8.0 h1:pX2VQ/TGKu+UU1rCay0OlzosNKe4Nz1pepLXj95oyy0= | ||||||
| github.com/hashicorp/terraform-plugin-log v0.7.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4= | github.com/hashicorp/terraform-plugin-log v0.8.0/go.mod h1:1myFrhVsBLeylQzYYEV17VVjtG8oYPRFdaZs7xdW2xs= | ||||||
| github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 h1:+KxZULPsbjpAVoP0WNj/8aVW6EqpcX5JcUcQ5wl7Da4= | github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1 h1:G9WAfb8LHeCxu7Ae8nc1agZlQOSCUWsb610iAogBhCs= | ||||||
| github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0/go.mod h1:DwGJG3KNxIPluVk6hexvDfYR/MS/eKGpiztJoT3Bbbw= | github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1/go.mod h1:xcOSYlRVdPLmDUoqPhO9fiO/YCN/l6MGYeTzGt5jgkQ= | ||||||
| github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c h1:D8aRO6+mTqHfLsK/BC3j5OAoogv1WLRWzY1AaTo3rBg= | github.com/hashicorp/terraform-registry-address v0.1.0 h1:W6JkV9wbum+m516rCl5/NjKxCyTVaaUBbzYcMzBDO3U= | ||||||
| github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c/go.mod h1:Wn3Na71knbXc1G8Lh+yu/dQWWJeFQEpDeJMtWMtlmNI= | github.com/hashicorp/terraform-registry-address v0.1.0/go.mod h1:EnyO2jYO6j29DTHbJcm00E5nQTFeTtyZH3H5ycydQ5A= | ||||||
| github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 h1:HKLsbzeOsfXmKNpr3GiT18XAblV0BjCbzL8KQAMZGa0= | github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 h1:HKLsbzeOsfXmKNpr3GiT18XAblV0BjCbzL8KQAMZGa0= | ||||||
| github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg= | github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg= | ||||||
| github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= | github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= | ||||||
| github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= | github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= | ||||||
|  | github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= | ||||||
| github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= | github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= | ||||||
| github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= | github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= | ||||||
| github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= | github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= | ||||||
| github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= |  | ||||||
| github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= | github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= | ||||||
|  | github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= | ||||||
|  | github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= | ||||||
| github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= | ||||||
| github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= | ||||||
| github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= | github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= | ||||||
| @@ -160,8 +147,8 @@ github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgy | |||||||
| github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= | github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= | ||||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | ||||||
| github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | ||||||
| github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= |  | ||||||
| github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= | ||||||
|  | github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= | ||||||
| github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||||||
| github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||||||
| github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||||||
| @@ -171,14 +158,16 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 | |||||||
| github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= | github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= | ||||||
| github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= | ||||||
| github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= | github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= | ||||||
| github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= |  | ||||||
| github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= | github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= | ||||||
|  | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= | ||||||
|  | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= | ||||||
| github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= | github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= | ||||||
| github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= | ||||||
| github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= |  | ||||||
| github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= | ||||||
| github.com/mitchellh/cli v1.1.2 h1:PvH+lL2B7IQ101xQL63Of8yFS2y+aDlsFcsqNc+u/Kw= | github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= | ||||||
| github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= | ||||||
|  | github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng= | ||||||
|  | github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= | ||||||
| github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= | github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= | ||||||
| github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= | github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= | ||||||
| github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= | github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= | ||||||
| @@ -194,27 +183,31 @@ github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx | |||||||
| github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= | github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= | ||||||
| github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= | github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= | ||||||
| github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= | ||||||
| github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758= |  | ||||||
| github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= | github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= | ||||||
| github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= | github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= | ||||||
| github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||||
| github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||||
| github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||||||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||||
| github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= |  | ||||||
| github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= | github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= | ||||||
|  | github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= | ||||||
|  | github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= | ||||||
| github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | ||||||
| github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= | github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= | ||||||
| github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= | github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= | ||||||
| github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= | github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= | ||||||
| github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= |  | ||||||
| github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= | github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= | ||||||
| github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= | github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= | ||||||
|  | github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= | ||||||
|  | github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= | ||||||
|  | github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= | ||||||
| github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= | github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= | ||||||
|  | github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= | ||||||
|  | github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= | ||||||
|  | github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= | ||||||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||||
| github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||||
| github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | ||||||
| github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= |  | ||||||
| github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||||||
| github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= | ||||||
| github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||||
| @@ -231,27 +224,30 @@ github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgq | |||||||
| github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= | github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= | ||||||
| github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= | github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= | ||||||
| github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||||
|  | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= | ||||||
| github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= | github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= | ||||||
| github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= | github.com/zclconf/go-cty v1.13.1 h1:0a6bRwuiSHtAmqCqNOE+c2oHgepv0ctoxU4FUe43kwc= | ||||||
| github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0= | github.com/zclconf/go-cty v1.13.1/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= | ||||||
| github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= |  | ||||||
| github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= |  | ||||||
| go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= |  | ||||||
| golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||||
| golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||||
| golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||||
| golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||||
| golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= | golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= | ||||||
| golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= | golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= | ||||||
| golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | ||||||
| golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 h1:O8uGbHCqlTp2P6QJSLmCojM4mN6UemYv8K+dCnmHmu0= | golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= | ||||||
| golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= | golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= | ||||||
|  | golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= | ||||||
| golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | ||||||
| golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | ||||||
| golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= | ||||||
| golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= | ||||||
| golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||||||
|  | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= | ||||||
|  | golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= | ||||||
|  | golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= | ||||||
|  | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= | ||||||
| golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||||
| golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||||
| golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||||
| @@ -264,21 +260,21 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL | |||||||
| golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
| golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
| golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
| golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= |  | ||||||
| golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= |  | ||||||
| golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||||
| golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||||
| golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= | golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= | ||||||
| golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= | ||||||
| golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= | ||||||
|  | golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= | ||||||
|  | golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= | ||||||
| golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= | ||||||
| golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | ||||||
| golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= |  | ||||||
| golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
|  | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
| golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
| @@ -288,25 +284,30 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w | |||||||
| golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |  | ||||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |  | ||||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |  | ||||||
| golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60= |  | ||||||
| golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
|  | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
|  | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
|  | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
|  | golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
|  | golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= | ||||||
|  | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||||
|  | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | ||||||
|  | golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= | ||||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||||
| golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||||||
| golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||||
| golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= |  | ||||||
| golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= |  | ||||||
| golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | ||||||
|  | golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= | ||||||
|  | golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= | ||||||
|  | golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= | ||||||
| golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||||
| golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||||
| golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= | ||||||
| @@ -314,10 +315,10 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 | |||||||
| golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= | ||||||
| golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||||||
| golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= | golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= | ||||||
|  | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= | ||||||
| golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||||
| golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||||
| golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||||
| golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |  | ||||||
| google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= | ||||||
| google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= | ||||||
| google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= | ||||||
| @@ -325,33 +326,26 @@ google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuh | |||||||
| google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= | google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= | ||||||
| google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= | ||||||
| google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= | ||||||
| google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= |  | ||||||
| google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= | ||||||
| google.golang.org/genproto v0.0.0-20200711021454-869866162049 h1:YFTFpQhgvrLrmxtiIncJxFXeCyq84ixuKWVCaCAi9Oc= | google.golang.org/genproto v0.0.0-20200711021454-869866162049 h1:YFTFpQhgvrLrmxtiIncJxFXeCyq84ixuKWVCaCAi9Oc= | ||||||
| google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= | google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= | ||||||
| google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= | ||||||
| google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= | ||||||
| google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= |  | ||||||
| google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= | ||||||
| google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= | google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= | ||||||
| google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= | google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= | ||||||
| google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= |  | ||||||
| google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= |  | ||||||
| google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= | ||||||
| google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= | ||||||
| google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= | ||||||
| google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= | ||||||
| google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= | ||||||
| google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= | ||||||
| google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= |  | ||||||
| google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= | ||||||
| google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= | ||||||
| google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= |  | ||||||
| google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= | ||||||
| google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= | ||||||
| google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= | google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= | ||||||
| google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= | google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | ||||||
| google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= |  | ||||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||||
| gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||||
| gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||||
| @@ -361,11 +355,11 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV | |||||||
| gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= | gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= | ||||||
| gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= | gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= | ||||||
| gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
| gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |  | ||||||
| gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
| gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= |  | ||||||
| gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
| gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||||
|  | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||||
|  | gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||||
| gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||||||
| gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||||
| honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||||
|   | |||||||
							
								
								
									
										25
									
								
								vendor/github.com/Masterminds/goutils/cryptorandomstringutils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								vendor/github.com/Masterminds/goutils/cryptorandomstringutils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -21,7 +21,6 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"math" | 	"math" | ||||||
| 	"math/big" | 	"math/big" | ||||||
| 	"regexp" |  | ||||||
| 	"unicode" | 	"unicode" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -99,27 +98,7 @@ Returns: | |||||||
| 	error - an error stemming from an invalid parameter within underlying function, CryptoRandom(...) | 	error - an error stemming from an invalid parameter within underlying function, CryptoRandom(...) | ||||||
| */ | */ | ||||||
| func CryptoRandomAlphaNumeric(count int) (string, error) { | func CryptoRandomAlphaNumeric(count int) (string, error) { | ||||||
| 	if count == 0 { | 	return CryptoRandom(count, 0, 0, true, true) | ||||||
| 		return "", nil |  | ||||||
| 	} |  | ||||||
| 	RandomString, err := CryptoRandom(count, 0, 0, true, true) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return "", fmt.Errorf("Error: %s", err) |  | ||||||
| 	} |  | ||||||
| 	match, err := regexp.MatchString("([0-9]+)", RandomString) |  | ||||||
| 	if err != nil { |  | ||||||
| 		panic(err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if !match { |  | ||||||
| 		//Get the position between 0 and the length of the string-1  to insert a random number |  | ||||||
| 		position := getCryptoRandomInt(count) |  | ||||||
| 		//Insert a random number between [0-9] in the position |  | ||||||
| 		RandomString = RandomString[:position] + string('0' + getCryptoRandomInt(10)) + RandomString[position + 1:] |  | ||||||
| 		return RandomString, err |  | ||||||
| 	} |  | ||||||
| 	return RandomString, err |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -204,7 +183,7 @@ func CryptoRandom(count int, start int, end int, letters bool, numbers bool, cha | |||||||
| 		if chars == nil { | 		if chars == nil { | ||||||
| 			ch = rune(getCryptoRandomInt(gap) + int64(start)) | 			ch = rune(getCryptoRandomInt(gap) + int64(start)) | ||||||
| 		} else { | 		} else { | ||||||
| 			ch = chars[getCryptoRandomInt(gap) + int64(start)] | 			ch = chars[getCryptoRandomInt(gap)+int64(start)] | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if letters && unicode.IsLetter(ch) || numbers && unicode.IsDigit(ch) || !letters && !numbers { | 		if letters && unicode.IsLetter(ch) || numbers && unicode.IsDigit(ch) || !letters && !numbers { | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								vendor/github.com/Masterminds/goutils/randomstringutils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/Masterminds/goutils/randomstringutils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -20,7 +20,6 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"math" | 	"math" | ||||||
| 	"math/rand" | 	"math/rand" | ||||||
| 	"regexp" |  | ||||||
| 	"time" | 	"time" | ||||||
| 	"unicode" | 	"unicode" | ||||||
| ) | ) | ||||||
| @@ -75,12 +74,10 @@ func RandomNumeric(count int) (string, error) { | |||||||
|  |  | ||||||
| /* | /* | ||||||
| RandomAlphabetic creates a random string whose length is the number of characters specified. | RandomAlphabetic creates a random string whose length is the number of characters specified. | ||||||
| Characters will be chosen from the set of alpha-numeric characters as indicated by the arguments. | Characters will be chosen from the set of alphabetic characters. | ||||||
|  |  | ||||||
| Parameters: | Parameters: | ||||||
| 	count - the length of random string to create | 	count - the length of random string to create | ||||||
| 	letters - if true, generated string may include alphabetic characters |  | ||||||
| 	numbers - if true, generated string may include numeric characters |  | ||||||
|  |  | ||||||
| Returns: | Returns: | ||||||
| 	string - the random string | 	string - the random string | ||||||
| @@ -102,24 +99,7 @@ Returns: | |||||||
| 	error - an error stemming from an invalid parameter within underlying function, RandomSeed(...) | 	error - an error stemming from an invalid parameter within underlying function, RandomSeed(...) | ||||||
| */ | */ | ||||||
| func RandomAlphaNumeric(count int) (string, error) { | func RandomAlphaNumeric(count int) (string, error) { | ||||||
| 	RandomString, err := Random(count, 0, 0, true, true) | 	return Random(count, 0, 0, true, true) | ||||||
| 	if err != nil { |  | ||||||
| 		return "", fmt.Errorf("Error: %s", err) |  | ||||||
| 	} |  | ||||||
| 	match, err := regexp.MatchString("([0-9]+)", RandomString) |  | ||||||
| 	if err != nil { |  | ||||||
| 		panic(err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if !match { |  | ||||||
| 		//Get the position between 0 and the length of the string-1  to insert a random number |  | ||||||
| 		position := rand.Intn(count) |  | ||||||
| 		//Insert a random number between [0-9] in the position |  | ||||||
| 		RandomString = RandomString[:position] + string('0'+rand.Intn(10)) + RandomString[position+1:] |  | ||||||
| 		return RandomString, err |  | ||||||
| 	} |  | ||||||
| 	return RandomString, err |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								vendor/github.com/Masterminds/goutils/stringutils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/Masterminds/goutils/stringutils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -222,3 +222,19 @@ func IndexOf(str string, sub string, start int) int { | |||||||
| func IsEmpty(str string) bool { | func IsEmpty(str string) bool { | ||||||
| 	return len(str) == 0 | 	return len(str) == 0 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Returns either the passed in string, or if the string is empty, the value of defaultStr. | ||||||
|  | func DefaultString(str string, defaultStr string) string { | ||||||
|  | 	if IsEmpty(str) { | ||||||
|  | 		return defaultStr | ||||||
|  | 	} | ||||||
|  | 	return str | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Returns either the passed in string, or if the string is whitespace, empty (""), the value of defaultStr. | ||||||
|  | func DefaultIfBlank(str string, defaultStr string) string { | ||||||
|  | 	if IsBlank(str) { | ||||||
|  | 		return defaultStr | ||||||
|  | 	} | ||||||
|  | 	return str | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										29
									
								
								vendor/github.com/Masterminds/semver/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/Masterminds/semver/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,29 +0,0 @@ | |||||||
| language: go |  | ||||||
|  |  | ||||||
| go: |  | ||||||
|   - 1.6.x |  | ||||||
|   - 1.7.x |  | ||||||
|   - 1.8.x |  | ||||||
|   - 1.9.x |  | ||||||
|   - 1.10.x |  | ||||||
|   - 1.11.x |  | ||||||
|   - 1.12.x |  | ||||||
|   - tip |  | ||||||
|  |  | ||||||
| # Setting sudo access to false will let Travis CI use containers rather than |  | ||||||
| # VMs to run the tests. For more details see: |  | ||||||
| # - http://docs.travis-ci.com/user/workers/container-based-infrastructure/ |  | ||||||
| # - http://docs.travis-ci.com/user/workers/standard-infrastructure/ |  | ||||||
| sudo: false |  | ||||||
|  |  | ||||||
| script: |  | ||||||
|   - make setup |  | ||||||
|   - make test |  | ||||||
|  |  | ||||||
| notifications: |  | ||||||
|   webhooks: |  | ||||||
|     urls: |  | ||||||
|       - https://webhooks.gitter.im/e/06e3328629952dabe3e0 |  | ||||||
|     on_success: change  # options: [always|never|change] default: always |  | ||||||
|     on_failure: always  # options: [always|never|change] default: always |  | ||||||
|     on_start: never     # options: [always|never|change] default: always |  | ||||||
							
								
								
									
										109
									
								
								vendor/github.com/Masterminds/semver/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										109
									
								
								vendor/github.com/Masterminds/semver/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,109 +0,0 @@ | |||||||
| # 1.5.0 (2019-09-11) |  | ||||||
|  |  | ||||||
| ## Added |  | ||||||
|  |  | ||||||
| - #103: Add basic fuzzing for `NewVersion()` (thanks @jesse-c) |  | ||||||
|  |  | ||||||
| ## Changed |  | ||||||
|  |  | ||||||
| - #82: Clarify wildcard meaning in range constraints and update tests for it (thanks @greysteil) |  | ||||||
| - #83: Clarify caret operator range for pre-1.0.0 dependencies (thanks @greysteil) |  | ||||||
| - #72: Adding docs comment pointing to vert for a cli |  | ||||||
| - #71: Update the docs on pre-release comparator handling |  | ||||||
| - #89: Test with new go versions (thanks @thedevsaddam) |  | ||||||
| - #87: Added $ to ValidPrerelease for better validation (thanks @jeremycarroll) |  | ||||||
|  |  | ||||||
| ## Fixed |  | ||||||
|  |  | ||||||
| - #78: Fix unchecked error in example code (thanks @ravron) |  | ||||||
| - #70: Fix the handling of pre-releases and the 0.0.0 release edge case |  | ||||||
| - #97: Fixed copyright file for proper display on GitHub |  | ||||||
| - #107: Fix handling prerelease when sorting alphanum and num  |  | ||||||
| - #109: Fixed where Validate sometimes returns wrong message on error |  | ||||||
|  |  | ||||||
| # 1.4.2 (2018-04-10) |  | ||||||
|  |  | ||||||
| ## Changed |  | ||||||
| - #72: Updated the docs to point to vert for a console appliaction |  | ||||||
| - #71: Update the docs on pre-release comparator handling |  | ||||||
|  |  | ||||||
| ## Fixed |  | ||||||
| - #70: Fix the handling of pre-releases and the 0.0.0 release edge case |  | ||||||
|  |  | ||||||
| # 1.4.1 (2018-04-02) |  | ||||||
|  |  | ||||||
| ## Fixed |  | ||||||
| - Fixed #64: Fix pre-release precedence issue (thanks @uudashr) |  | ||||||
|  |  | ||||||
| # 1.4.0 (2017-10-04) |  | ||||||
|  |  | ||||||
| ## Changed |  | ||||||
| - #61: Update NewVersion to parse ints with a 64bit int size (thanks @zknill) |  | ||||||
|  |  | ||||||
| # 1.3.1 (2017-07-10) |  | ||||||
|  |  | ||||||
| ## Fixed |  | ||||||
| - Fixed #57: number comparisons in prerelease sometimes inaccurate |  | ||||||
|  |  | ||||||
| # 1.3.0 (2017-05-02) |  | ||||||
|  |  | ||||||
| ## Added |  | ||||||
| - #45: Added json (un)marshaling support (thanks @mh-cbon) |  | ||||||
| - Stability marker. See https://masterminds.github.io/stability/ |  | ||||||
|  |  | ||||||
| ## Fixed |  | ||||||
| - #51: Fix handling of single digit tilde constraint (thanks @dgodd) |  | ||||||
|  |  | ||||||
| ## Changed |  | ||||||
| - #55: The godoc icon moved from png to svg |  | ||||||
|  |  | ||||||
| # 1.2.3 (2017-04-03) |  | ||||||
|  |  | ||||||
| ## Fixed |  | ||||||
| - #46: Fixed 0.x.x and 0.0.x in constraints being treated as * |  | ||||||
|  |  | ||||||
| # Release 1.2.2 (2016-12-13) |  | ||||||
|  |  | ||||||
| ## Fixed |  | ||||||
| - #34: Fixed issue where hyphen range was not working with pre-release parsing. |  | ||||||
|  |  | ||||||
| # Release 1.2.1 (2016-11-28) |  | ||||||
|  |  | ||||||
| ## Fixed |  | ||||||
| - #24: Fixed edge case issue where constraint "> 0" does not handle "0.0.1-alpha" |  | ||||||
|   properly. |  | ||||||
|  |  | ||||||
| # Release 1.2.0 (2016-11-04) |  | ||||||
|  |  | ||||||
| ## Added |  | ||||||
| - #20: Added MustParse function for versions (thanks @adamreese) |  | ||||||
| - #15: Added increment methods on versions (thanks @mh-cbon) |  | ||||||
|  |  | ||||||
| ## Fixed |  | ||||||
| - Issue #21: Per the SemVer spec (section 9) a pre-release is unstable and |  | ||||||
|   might not satisfy the intended compatibility. The change here ignores pre-releases |  | ||||||
|   on constraint checks (e.g., ~ or ^) when a pre-release is not part of the |  | ||||||
|   constraint. For example, `^1.2.3` will ignore pre-releases while |  | ||||||
|   `^1.2.3-alpha` will include them. |  | ||||||
|  |  | ||||||
| # Release 1.1.1 (2016-06-30) |  | ||||||
|  |  | ||||||
| ## Changed |  | ||||||
| - Issue #9: Speed up version comparison performance (thanks @sdboyer) |  | ||||||
| - Issue #8: Added benchmarks (thanks @sdboyer) |  | ||||||
| - Updated Go Report Card URL to new location |  | ||||||
| - Updated Readme to add code snippet formatting (thanks @mh-cbon) |  | ||||||
| - Updating tagging to v[SemVer] structure for compatibility with other tools. |  | ||||||
|  |  | ||||||
| # Release 1.1.0 (2016-03-11) |  | ||||||
|  |  | ||||||
| - Issue #2: Implemented validation to provide reasons a versions failed a |  | ||||||
|   constraint. |  | ||||||
|  |  | ||||||
| # Release 1.0.1 (2015-12-31) |  | ||||||
|  |  | ||||||
| - Fixed #1: * constraint failing on valid versions. |  | ||||||
|  |  | ||||||
| # Release 1.0.0 (2015-10-20) |  | ||||||
|  |  | ||||||
| - Initial release |  | ||||||
							
								
								
									
										36
									
								
								vendor/github.com/Masterminds/semver/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								vendor/github.com/Masterminds/semver/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,36 +0,0 @@ | |||||||
| .PHONY: setup |  | ||||||
| setup: |  | ||||||
| 	go get -u gopkg.in/alecthomas/gometalinter.v1 |  | ||||||
| 	gometalinter.v1 --install |  | ||||||
|  |  | ||||||
| .PHONY: test |  | ||||||
| test: validate lint |  | ||||||
| 	@echo "==> Running tests" |  | ||||||
| 	go test -v |  | ||||||
|  |  | ||||||
| .PHONY: validate |  | ||||||
| validate: |  | ||||||
| 	@echo "==> Running static validations" |  | ||||||
| 	@gometalinter.v1 \ |  | ||||||
| 	  --disable-all \ |  | ||||||
| 	  --enable deadcode \ |  | ||||||
| 	  --severity deadcode:error \ |  | ||||||
| 	  --enable gofmt \ |  | ||||||
| 	  --enable gosimple \ |  | ||||||
| 	  --enable ineffassign \ |  | ||||||
| 	  --enable misspell \ |  | ||||||
| 	  --enable vet \ |  | ||||||
| 	  --tests \ |  | ||||||
| 	  --vendor \ |  | ||||||
| 	  --deadline 60s \ |  | ||||||
| 	  ./... || exit_code=1 |  | ||||||
|  |  | ||||||
| .PHONY: lint |  | ||||||
| lint: |  | ||||||
| 	@echo "==> Running linters" |  | ||||||
| 	@gometalinter.v1 \ |  | ||||||
| 	  --disable-all \ |  | ||||||
| 	  --enable golint \ |  | ||||||
| 	  --vendor \ |  | ||||||
| 	  --deadline 60s \ |  | ||||||
| 	  ./... || : |  | ||||||
							
								
								
									
										194
									
								
								vendor/github.com/Masterminds/semver/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										194
									
								
								vendor/github.com/Masterminds/semver/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,194 +0,0 @@ | |||||||
| # SemVer |  | ||||||
|  |  | ||||||
| The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to: |  | ||||||
|  |  | ||||||
| * Parse semantic versions |  | ||||||
| * Sort semantic versions |  | ||||||
| * Check if a semantic version fits within a set of constraints |  | ||||||
| * Optionally work with a `v` prefix |  | ||||||
|  |  | ||||||
| [](https://masterminds.github.io/stability/active.html) |  | ||||||
| [](https://travis-ci.org/Masterminds/semver) [](https://ci.appveyor.com/project/mattfarina/semver/branch/master) [](https://godoc.org/github.com/Masterminds/semver) [](https://goreportcard.com/report/github.com/Masterminds/semver) |  | ||||||
|  |  | ||||||
| If you are looking for a command line tool for version comparisons please see |  | ||||||
| [vert](https://github.com/Masterminds/vert) which uses this library. |  | ||||||
|  |  | ||||||
| ## Parsing Semantic Versions |  | ||||||
|  |  | ||||||
| To parse a semantic version use the `NewVersion` function. For example, |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
|     v, err := semver.NewVersion("1.2.3-beta.1+build345") |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| If there is an error the version wasn't parseable. The version object has methods |  | ||||||
| to get the parts of the version, compare it to other versions, convert the |  | ||||||
| version back into a string, and get the original string. For more details |  | ||||||
| please see the [documentation](https://godoc.org/github.com/Masterminds/semver). |  | ||||||
|  |  | ||||||
| ## Sorting Semantic Versions |  | ||||||
|  |  | ||||||
| A set of versions can be sorted using the [`sort`](https://golang.org/pkg/sort/) |  | ||||||
| package from the standard library. For example, |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
|     raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} |  | ||||||
|     vs := make([]*semver.Version, len(raw)) |  | ||||||
| 	for i, r := range raw { |  | ||||||
| 		v, err := semver.NewVersion(r) |  | ||||||
| 		if err != nil { |  | ||||||
| 			t.Errorf("Error parsing version: %s", err) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		vs[i] = v |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	sort.Sort(semver.Collection(vs)) |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## Checking Version Constraints |  | ||||||
|  |  | ||||||
| Checking a version against version constraints is one of the most featureful |  | ||||||
| parts of the package. |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
|     c, err := semver.NewConstraint(">= 1.2.3") |  | ||||||
|     if err != nil { |  | ||||||
|         // Handle constraint not being parseable. |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     v, _ := semver.NewVersion("1.3") |  | ||||||
|     if err != nil { |  | ||||||
|         // Handle version not being parseable. |  | ||||||
|     } |  | ||||||
|     // Check if the version meets the constraints. The a variable will be true. |  | ||||||
|     a := c.Check(v) |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## Basic Comparisons |  | ||||||
|  |  | ||||||
| There are two elements to the comparisons. First, a comparison string is a list |  | ||||||
| of comma separated and comparisons. These are then separated by || separated or |  | ||||||
| comparisons. For example, `">= 1.2, < 3.0.0 || >= 4.2.3"` is looking for a |  | ||||||
| comparison that's greater than or equal to 1.2 and less than 3.0.0 or is |  | ||||||
| greater than or equal to 4.2.3. |  | ||||||
|  |  | ||||||
| The basic comparisons are: |  | ||||||
|  |  | ||||||
| * `=`: equal (aliased to no operator) |  | ||||||
| * `!=`: not equal |  | ||||||
| * `>`: greater than |  | ||||||
| * `<`: less than |  | ||||||
| * `>=`: greater than or equal to |  | ||||||
| * `<=`: less than or equal to |  | ||||||
|  |  | ||||||
| ## Working With Pre-release Versions |  | ||||||
|  |  | ||||||
| Pre-releases, for those not familiar with them, are used for software releases |  | ||||||
| prior to stable or generally available releases. Examples of pre-releases include |  | ||||||
| development, alpha, beta, and release candidate releases. A pre-release may be |  | ||||||
| a version such as `1.2.3-beta.1` while the stable release would be `1.2.3`. In the |  | ||||||
| order of precidence, pre-releases come before their associated releases. In this |  | ||||||
| example `1.2.3-beta.1 < 1.2.3`. |  | ||||||
|  |  | ||||||
| According to the Semantic Version specification pre-releases may not be |  | ||||||
| API compliant with their release counterpart. It says, |  | ||||||
|  |  | ||||||
| > A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. |  | ||||||
|  |  | ||||||
| SemVer comparisons without a pre-release comparator will skip pre-release versions. |  | ||||||
| For example, `>=1.2.3` will skip pre-releases when looking at a list of releases |  | ||||||
| while `>=1.2.3-0` will evaluate and find pre-releases. |  | ||||||
|  |  | ||||||
| The reason for the `0` as a pre-release version in the example comparison is |  | ||||||
| because pre-releases can only contain ASCII alphanumerics and hyphens (along with |  | ||||||
| `.` separators), per the spec. Sorting happens in ASCII sort order, again per the spec. The lowest character is a `0` in ASCII sort order (see an [ASCII Table](http://www.asciitable.com/)) |  | ||||||
|  |  | ||||||
| Understanding ASCII sort ordering is important because A-Z comes before a-z. That |  | ||||||
| means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case |  | ||||||
| sensitivity doesn't apply here. This is due to ASCII sort ordering which is what |  | ||||||
| the spec specifies. |  | ||||||
|  |  | ||||||
| ## Hyphen Range Comparisons |  | ||||||
|  |  | ||||||
| There are multiple methods to handle ranges and the first is hyphens ranges. |  | ||||||
| These look like: |  | ||||||
|  |  | ||||||
| * `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5` |  | ||||||
| * `2.3.4 - 4.5` which is equivalent to `>= 2.3.4, <= 4.5` |  | ||||||
|  |  | ||||||
| ## Wildcards In Comparisons |  | ||||||
|  |  | ||||||
| The `x`, `X`, and `*` characters can be used as a wildcard character. This works |  | ||||||
| for all comparison operators. When used on the `=` operator it falls |  | ||||||
| back to the pack level comparison (see tilde below). For example, |  | ||||||
|  |  | ||||||
| * `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` |  | ||||||
| * `>= 1.2.x` is equivalent to `>= 1.2.0` |  | ||||||
| * `<= 2.x` is equivalent to `< 3` |  | ||||||
| * `*` is equivalent to `>= 0.0.0` |  | ||||||
|  |  | ||||||
| ## Tilde Range Comparisons (Patch) |  | ||||||
|  |  | ||||||
| The tilde (`~`) comparison operator is for patch level ranges when a minor |  | ||||||
| version is specified and major level changes when the minor number is missing. |  | ||||||
| For example, |  | ||||||
|  |  | ||||||
| * `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0` |  | ||||||
| * `~1` is equivalent to `>= 1, < 2` |  | ||||||
| * `~2.3` is equivalent to `>= 2.3, < 2.4` |  | ||||||
| * `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` |  | ||||||
| * `~1.x` is equivalent to `>= 1, < 2` |  | ||||||
|  |  | ||||||
| ## Caret Range Comparisons (Major) |  | ||||||
|  |  | ||||||
| The caret (`^`) comparison operator is for major level changes. This is useful |  | ||||||
| when comparisons of API versions as a major change is API breaking. For example, |  | ||||||
|  |  | ||||||
| * `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` |  | ||||||
| * `^0.0.1` is equivalent to `>= 0.0.1, < 1.0.0` |  | ||||||
| * `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` |  | ||||||
| * `^2.3` is equivalent to `>= 2.3, < 3` |  | ||||||
| * `^2.x` is equivalent to `>= 2.0.0, < 3` |  | ||||||
|  |  | ||||||
| # Validation |  | ||||||
|  |  | ||||||
| In addition to testing a version against a constraint, a version can be validated |  | ||||||
| against a constraint. When validation fails a slice of errors containing why a |  | ||||||
| version didn't meet the constraint is returned. For example, |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
|     c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") |  | ||||||
|     if err != nil { |  | ||||||
|         // Handle constraint not being parseable. |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     v, _ := semver.NewVersion("1.3") |  | ||||||
|     if err != nil { |  | ||||||
|         // Handle version not being parseable. |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Validate a version against a constraint. |  | ||||||
|     a, msgs := c.Validate(v) |  | ||||||
|     // a is false |  | ||||||
|     for _, m := range msgs { |  | ||||||
|         fmt.Println(m) |  | ||||||
|  |  | ||||||
|         // Loops over the errors which would read |  | ||||||
|         // "1.3 is greater than 1.2.3" |  | ||||||
|         // "1.3 is less than 1.4" |  | ||||||
|     } |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| # Fuzzing |  | ||||||
|  |  | ||||||
|  [dvyukov/go-fuzz](https://github.com/dvyukov/go-fuzz) is used for fuzzing. |  | ||||||
|  |  | ||||||
| 1. `go-fuzz-build` |  | ||||||
| 2. `go-fuzz -workdir=fuzz` |  | ||||||
|  |  | ||||||
| # Contribute |  | ||||||
|  |  | ||||||
| If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues) |  | ||||||
| or [create a pull request](https://github.com/Masterminds/semver/pulls). |  | ||||||
							
								
								
									
										44
									
								
								vendor/github.com/Masterminds/semver/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										44
									
								
								vendor/github.com/Masterminds/semver/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,44 +0,0 @@ | |||||||
| version: build-{build}.{branch} |  | ||||||
|  |  | ||||||
| clone_folder: C:\gopath\src\github.com\Masterminds\semver |  | ||||||
| shallow_clone: true |  | ||||||
|  |  | ||||||
| environment: |  | ||||||
|   GOPATH: C:\gopath |  | ||||||
|  |  | ||||||
| platform: |  | ||||||
|   - x64 |  | ||||||
|  |  | ||||||
| install: |  | ||||||
|   - go version |  | ||||||
|   - go env |  | ||||||
|   - go get -u gopkg.in/alecthomas/gometalinter.v1 |  | ||||||
|   - set PATH=%PATH%;%GOPATH%\bin |  | ||||||
|   - gometalinter.v1.exe --install |  | ||||||
|  |  | ||||||
| build_script: |  | ||||||
|   - go install -v ./... |  | ||||||
|  |  | ||||||
| test_script: |  | ||||||
|   - "gometalinter.v1 \ |  | ||||||
|     --disable-all \ |  | ||||||
|     --enable deadcode \ |  | ||||||
|     --severity deadcode:error \ |  | ||||||
|     --enable gofmt \ |  | ||||||
|     --enable gosimple \ |  | ||||||
|     --enable ineffassign \ |  | ||||||
|     --enable misspell \ |  | ||||||
|     --enable vet \ |  | ||||||
|     --tests \ |  | ||||||
|     --vendor \ |  | ||||||
|     --deadline 60s \ |  | ||||||
|     ./... || exit_code=1" |  | ||||||
|   - "gometalinter.v1 \ |  | ||||||
|     --disable-all \ |  | ||||||
|     --enable golint \ |  | ||||||
|     --vendor \ |  | ||||||
|     --deadline 60s \ |  | ||||||
|     ./... || :" |  | ||||||
|   - go test -v |  | ||||||
|  |  | ||||||
| deploy: off |  | ||||||
							
								
								
									
										423
									
								
								vendor/github.com/Masterminds/semver/constraints.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										423
									
								
								vendor/github.com/Masterminds/semver/constraints.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,423 +0,0 @@ | |||||||
| package semver |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"regexp" |  | ||||||
| 	"strings" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // Constraints is one or more constraint that a semantic version can be |  | ||||||
| // checked against. |  | ||||||
| type Constraints struct { |  | ||||||
| 	constraints [][]*constraint |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // NewConstraint returns a Constraints instance that a Version instance can |  | ||||||
| // be checked against. If there is a parse error it will be returned. |  | ||||||
| func NewConstraint(c string) (*Constraints, error) { |  | ||||||
|  |  | ||||||
| 	// Rewrite - ranges into a comparison operation. |  | ||||||
| 	c = rewriteRange(c) |  | ||||||
|  |  | ||||||
| 	ors := strings.Split(c, "||") |  | ||||||
| 	or := make([][]*constraint, len(ors)) |  | ||||||
| 	for k, v := range ors { |  | ||||||
| 		cs := strings.Split(v, ",") |  | ||||||
| 		result := make([]*constraint, len(cs)) |  | ||||||
| 		for i, s := range cs { |  | ||||||
| 			pc, err := parseConstraint(s) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return nil, err |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			result[i] = pc |  | ||||||
| 		} |  | ||||||
| 		or[k] = result |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	o := &Constraints{constraints: or} |  | ||||||
| 	return o, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Check tests if a version satisfies the constraints. |  | ||||||
| func (cs Constraints) Check(v *Version) bool { |  | ||||||
| 	// loop over the ORs and check the inner ANDs |  | ||||||
| 	for _, o := range cs.constraints { |  | ||||||
| 		joy := true |  | ||||||
| 		for _, c := range o { |  | ||||||
| 			if !c.check(v) { |  | ||||||
| 				joy = false |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if joy { |  | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Validate checks if a version satisfies a constraint. If not a slice of |  | ||||||
| // reasons for the failure are returned in addition to a bool. |  | ||||||
| func (cs Constraints) Validate(v *Version) (bool, []error) { |  | ||||||
| 	// loop over the ORs and check the inner ANDs |  | ||||||
| 	var e []error |  | ||||||
|  |  | ||||||
| 	// Capture the prerelease message only once. When it happens the first time |  | ||||||
| 	// this var is marked |  | ||||||
| 	var prerelesase bool |  | ||||||
| 	for _, o := range cs.constraints { |  | ||||||
| 		joy := true |  | ||||||
| 		for _, c := range o { |  | ||||||
| 			// Before running the check handle the case there the version is |  | ||||||
| 			// a prerelease and the check is not searching for prereleases. |  | ||||||
| 			if c.con.pre == "" && v.pre != "" { |  | ||||||
| 				if !prerelesase { |  | ||||||
| 					em := fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) |  | ||||||
| 					e = append(e, em) |  | ||||||
| 					prerelesase = true |  | ||||||
| 				} |  | ||||||
| 				joy = false |  | ||||||
|  |  | ||||||
| 			} else { |  | ||||||
|  |  | ||||||
| 				if !c.check(v) { |  | ||||||
| 					em := fmt.Errorf(c.msg, v, c.orig) |  | ||||||
| 					e = append(e, em) |  | ||||||
| 					joy = false |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if joy { |  | ||||||
| 			return true, []error{} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return false, e |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var constraintOps map[string]cfunc |  | ||||||
| var constraintMsg map[string]string |  | ||||||
| var constraintRegex *regexp.Regexp |  | ||||||
|  |  | ||||||
| func init() { |  | ||||||
| 	constraintOps = map[string]cfunc{ |  | ||||||
| 		"":   constraintTildeOrEqual, |  | ||||||
| 		"=":  constraintTildeOrEqual, |  | ||||||
| 		"!=": constraintNotEqual, |  | ||||||
| 		">":  constraintGreaterThan, |  | ||||||
| 		"<":  constraintLessThan, |  | ||||||
| 		">=": constraintGreaterThanEqual, |  | ||||||
| 		"=>": constraintGreaterThanEqual, |  | ||||||
| 		"<=": constraintLessThanEqual, |  | ||||||
| 		"=<": constraintLessThanEqual, |  | ||||||
| 		"~":  constraintTilde, |  | ||||||
| 		"~>": constraintTilde, |  | ||||||
| 		"^":  constraintCaret, |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	constraintMsg = map[string]string{ |  | ||||||
| 		"":   "%s is not equal to %s", |  | ||||||
| 		"=":  "%s is not equal to %s", |  | ||||||
| 		"!=": "%s is equal to %s", |  | ||||||
| 		">":  "%s is less than or equal to %s", |  | ||||||
| 		"<":  "%s is greater than or equal to %s", |  | ||||||
| 		">=": "%s is less than %s", |  | ||||||
| 		"=>": "%s is less than %s", |  | ||||||
| 		"<=": "%s is greater than %s", |  | ||||||
| 		"=<": "%s is greater than %s", |  | ||||||
| 		"~":  "%s does not have same major and minor version as %s", |  | ||||||
| 		"~>": "%s does not have same major and minor version as %s", |  | ||||||
| 		"^":  "%s does not have same major version as %s", |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ops := make([]string, 0, len(constraintOps)) |  | ||||||
| 	for k := range constraintOps { |  | ||||||
| 		ops = append(ops, regexp.QuoteMeta(k)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	constraintRegex = regexp.MustCompile(fmt.Sprintf( |  | ||||||
| 		`^\s*(%s)\s*(%s)\s*$`, |  | ||||||
| 		strings.Join(ops, "|"), |  | ||||||
| 		cvRegex)) |  | ||||||
|  |  | ||||||
| 	constraintRangeRegex = regexp.MustCompile(fmt.Sprintf( |  | ||||||
| 		`\s*(%s)\s+-\s+(%s)\s*`, |  | ||||||
| 		cvRegex, cvRegex)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // An individual constraint |  | ||||||
| type constraint struct { |  | ||||||
| 	// The callback function for the restraint. It performs the logic for |  | ||||||
| 	// the constraint. |  | ||||||
| 	function cfunc |  | ||||||
|  |  | ||||||
| 	msg string |  | ||||||
|  |  | ||||||
| 	// The version used in the constraint check. For example, if a constraint |  | ||||||
| 	// is '<= 2.0.0' the con a version instance representing 2.0.0. |  | ||||||
| 	con *Version |  | ||||||
|  |  | ||||||
| 	// The original parsed version (e.g., 4.x from != 4.x) |  | ||||||
| 	orig string |  | ||||||
|  |  | ||||||
| 	// When an x is used as part of the version (e.g., 1.x) |  | ||||||
| 	minorDirty bool |  | ||||||
| 	dirty      bool |  | ||||||
| 	patchDirty bool |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Check if a version meets the constraint |  | ||||||
| func (c *constraint) check(v *Version) bool { |  | ||||||
| 	return c.function(v, c) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type cfunc func(v *Version, c *constraint) bool |  | ||||||
|  |  | ||||||
| func parseConstraint(c string) (*constraint, error) { |  | ||||||
| 	m := constraintRegex.FindStringSubmatch(c) |  | ||||||
| 	if m == nil { |  | ||||||
| 		return nil, fmt.Errorf("improper constraint: %s", c) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ver := m[2] |  | ||||||
| 	orig := ver |  | ||||||
| 	minorDirty := false |  | ||||||
| 	patchDirty := false |  | ||||||
| 	dirty := false |  | ||||||
| 	if isX(m[3]) { |  | ||||||
| 		ver = "0.0.0" |  | ||||||
| 		dirty = true |  | ||||||
| 	} else if isX(strings.TrimPrefix(m[4], ".")) || m[4] == "" { |  | ||||||
| 		minorDirty = true |  | ||||||
| 		dirty = true |  | ||||||
| 		ver = fmt.Sprintf("%s.0.0%s", m[3], m[6]) |  | ||||||
| 	} else if isX(strings.TrimPrefix(m[5], ".")) { |  | ||||||
| 		dirty = true |  | ||||||
| 		patchDirty = true |  | ||||||
| 		ver = fmt.Sprintf("%s%s.0%s", m[3], m[4], m[6]) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	con, err := NewVersion(ver) |  | ||||||
| 	if err != nil { |  | ||||||
|  |  | ||||||
| 		// The constraintRegex should catch any regex parsing errors. So, |  | ||||||
| 		// we should never get here. |  | ||||||
| 		return nil, errors.New("constraint Parser Error") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	cs := &constraint{ |  | ||||||
| 		function:   constraintOps[m[1]], |  | ||||||
| 		msg:        constraintMsg[m[1]], |  | ||||||
| 		con:        con, |  | ||||||
| 		orig:       orig, |  | ||||||
| 		minorDirty: minorDirty, |  | ||||||
| 		patchDirty: patchDirty, |  | ||||||
| 		dirty:      dirty, |  | ||||||
| 	} |  | ||||||
| 	return cs, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Constraint functions |  | ||||||
| func constraintNotEqual(v *Version, c *constraint) bool { |  | ||||||
| 	if c.dirty { |  | ||||||
|  |  | ||||||
| 		// If there is a pre-release on the version but the constraint isn't looking |  | ||||||
| 		// for them assume that pre-releases are not compatible. See issue 21 for |  | ||||||
| 		// more details. |  | ||||||
| 		if v.Prerelease() != "" && c.con.Prerelease() == "" { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if c.con.Major() != v.Major() { |  | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 		if c.con.Minor() != v.Minor() && !c.minorDirty { |  | ||||||
| 			return true |  | ||||||
| 		} else if c.minorDirty { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return !v.Equal(c.con) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func constraintGreaterThan(v *Version, c *constraint) bool { |  | ||||||
|  |  | ||||||
| 	// If there is a pre-release on the version but the constraint isn't looking |  | ||||||
| 	// for them assume that pre-releases are not compatible. See issue 21 for |  | ||||||
| 	// more details. |  | ||||||
| 	if v.Prerelease() != "" && c.con.Prerelease() == "" { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return v.Compare(c.con) == 1 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func constraintLessThan(v *Version, c *constraint) bool { |  | ||||||
| 	// If there is a pre-release on the version but the constraint isn't looking |  | ||||||
| 	// for them assume that pre-releases are not compatible. See issue 21 for |  | ||||||
| 	// more details. |  | ||||||
| 	if v.Prerelease() != "" && c.con.Prerelease() == "" { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if !c.dirty { |  | ||||||
| 		return v.Compare(c.con) < 0 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if v.Major() > c.con.Major() { |  | ||||||
| 		return false |  | ||||||
| 	} else if v.Minor() > c.con.Minor() && !c.minorDirty { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func constraintGreaterThanEqual(v *Version, c *constraint) bool { |  | ||||||
|  |  | ||||||
| 	// If there is a pre-release on the version but the constraint isn't looking |  | ||||||
| 	// for them assume that pre-releases are not compatible. See issue 21 for |  | ||||||
| 	// more details. |  | ||||||
| 	if v.Prerelease() != "" && c.con.Prerelease() == "" { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return v.Compare(c.con) >= 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func constraintLessThanEqual(v *Version, c *constraint) bool { |  | ||||||
| 	// If there is a pre-release on the version but the constraint isn't looking |  | ||||||
| 	// for them assume that pre-releases are not compatible. See issue 21 for |  | ||||||
| 	// more details. |  | ||||||
| 	if v.Prerelease() != "" && c.con.Prerelease() == "" { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if !c.dirty { |  | ||||||
| 		return v.Compare(c.con) <= 0 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if v.Major() > c.con.Major() { |  | ||||||
| 		return false |  | ||||||
| 	} else if v.Minor() > c.con.Minor() && !c.minorDirty { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ~*, ~>* --> >= 0.0.0 (any) |  | ||||||
| // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0, <3.0.0 |  | ||||||
| // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0, <2.1.0 |  | ||||||
| // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0 |  | ||||||
| // ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0 |  | ||||||
| // ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0 |  | ||||||
| func constraintTilde(v *Version, c *constraint) bool { |  | ||||||
| 	// If there is a pre-release on the version but the constraint isn't looking |  | ||||||
| 	// for them assume that pre-releases are not compatible. See issue 21 for |  | ||||||
| 	// more details. |  | ||||||
| 	if v.Prerelease() != "" && c.con.Prerelease() == "" { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if v.LessThan(c.con) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// ~0.0.0 is a special case where all constraints are accepted. It's |  | ||||||
| 	// equivalent to >= 0.0.0. |  | ||||||
| 	if c.con.Major() == 0 && c.con.Minor() == 0 && c.con.Patch() == 0 && |  | ||||||
| 		!c.minorDirty && !c.patchDirty { |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if v.Major() != c.con.Major() { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if v.Minor() != c.con.Minor() && !c.minorDirty { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // When there is a .x (dirty) status it automatically opts in to ~. Otherwise |  | ||||||
| // it's a straight = |  | ||||||
| func constraintTildeOrEqual(v *Version, c *constraint) bool { |  | ||||||
| 	// If there is a pre-release on the version but the constraint isn't looking |  | ||||||
| 	// for them assume that pre-releases are not compatible. See issue 21 for |  | ||||||
| 	// more details. |  | ||||||
| 	if v.Prerelease() != "" && c.con.Prerelease() == "" { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if c.dirty { |  | ||||||
| 		c.msg = constraintMsg["~"] |  | ||||||
| 		return constraintTilde(v, c) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return v.Equal(c.con) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ^* --> (any) |  | ||||||
| // ^2, ^2.x, ^2.x.x --> >=2.0.0, <3.0.0 |  | ||||||
| // ^2.0, ^2.0.x --> >=2.0.0, <3.0.0 |  | ||||||
| // ^1.2, ^1.2.x --> >=1.2.0, <2.0.0 |  | ||||||
| // ^1.2.3 --> >=1.2.3, <2.0.0 |  | ||||||
| // ^1.2.0 --> >=1.2.0, <2.0.0 |  | ||||||
| func constraintCaret(v *Version, c *constraint) bool { |  | ||||||
| 	// If there is a pre-release on the version but the constraint isn't looking |  | ||||||
| 	// for them assume that pre-releases are not compatible. See issue 21 for |  | ||||||
| 	// more details. |  | ||||||
| 	if v.Prerelease() != "" && c.con.Prerelease() == "" { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if v.LessThan(c.con) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if v.Major() != c.con.Major() { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var constraintRangeRegex *regexp.Regexp |  | ||||||
|  |  | ||||||
| const cvRegex string = `v?([0-9|x|X|\*]+)(\.[0-9|x|X|\*]+)?(\.[0-9|x|X|\*]+)?` + |  | ||||||
| 	`(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + |  | ||||||
| 	`(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` |  | ||||||
|  |  | ||||||
| func isX(x string) bool { |  | ||||||
| 	switch x { |  | ||||||
| 	case "x", "*", "X": |  | ||||||
| 		return true |  | ||||||
| 	default: |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func rewriteRange(i string) string { |  | ||||||
| 	m := constraintRangeRegex.FindAllStringSubmatch(i, -1) |  | ||||||
| 	if m == nil { |  | ||||||
| 		return i |  | ||||||
| 	} |  | ||||||
| 	o := i |  | ||||||
| 	for _, v := range m { |  | ||||||
| 		t := fmt.Sprintf(">= %s, <= %s", v[1], v[11]) |  | ||||||
| 		o = strings.Replace(o, v[0], t, 1) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return o |  | ||||||
| } |  | ||||||
							
								
								
									
										115
									
								
								vendor/github.com/Masterminds/semver/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										115
									
								
								vendor/github.com/Masterminds/semver/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,115 +0,0 @@ | |||||||
| /* |  | ||||||
| Package semver provides the ability to work with Semantic Versions (http://semver.org) in Go. |  | ||||||
|  |  | ||||||
| Specifically it provides the ability to: |  | ||||||
|  |  | ||||||
|     * Parse semantic versions |  | ||||||
|     * Sort semantic versions |  | ||||||
|     * Check if a semantic version fits within a set of constraints |  | ||||||
|     * Optionally work with a `v` prefix |  | ||||||
|  |  | ||||||
| Parsing Semantic Versions |  | ||||||
|  |  | ||||||
| To parse a semantic version use the `NewVersion` function. For example, |  | ||||||
|  |  | ||||||
|     v, err := semver.NewVersion("1.2.3-beta.1+build345") |  | ||||||
|  |  | ||||||
| If there is an error the version wasn't parseable. The version object has methods |  | ||||||
| to get the parts of the version, compare it to other versions, convert the |  | ||||||
| version back into a string, and get the original string. For more details |  | ||||||
| please see the documentation at https://godoc.org/github.com/Masterminds/semver. |  | ||||||
|  |  | ||||||
| Sorting Semantic Versions |  | ||||||
|  |  | ||||||
| A set of versions can be sorted using the `sort` package from the standard library. |  | ||||||
| For example, |  | ||||||
|  |  | ||||||
|     raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} |  | ||||||
|     vs := make([]*semver.Version, len(raw)) |  | ||||||
| 	for i, r := range raw { |  | ||||||
| 		v, err := semver.NewVersion(r) |  | ||||||
| 		if err != nil { |  | ||||||
| 			t.Errorf("Error parsing version: %s", err) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		vs[i] = v |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	sort.Sort(semver.Collection(vs)) |  | ||||||
|  |  | ||||||
| Checking Version Constraints |  | ||||||
|  |  | ||||||
| Checking a version against version constraints is one of the most featureful |  | ||||||
| parts of the package. |  | ||||||
|  |  | ||||||
|     c, err := semver.NewConstraint(">= 1.2.3") |  | ||||||
|     if err != nil { |  | ||||||
|         // Handle constraint not being parseable. |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     v, err := semver.NewVersion("1.3") |  | ||||||
|     if err != nil { |  | ||||||
|         // Handle version not being parseable. |  | ||||||
|     } |  | ||||||
|     // Check if the version meets the constraints. The a variable will be true. |  | ||||||
|     a := c.Check(v) |  | ||||||
|  |  | ||||||
| Basic Comparisons |  | ||||||
|  |  | ||||||
| There are two elements to the comparisons. First, a comparison string is a list |  | ||||||
| of comma separated and comparisons. These are then separated by || separated or |  | ||||||
| comparisons. For example, `">= 1.2, < 3.0.0 || >= 4.2.3"` is looking for a |  | ||||||
| comparison that's greater than or equal to 1.2 and less than 3.0.0 or is |  | ||||||
| greater than or equal to 4.2.3. |  | ||||||
|  |  | ||||||
| The basic comparisons are: |  | ||||||
|  |  | ||||||
|     * `=`: equal (aliased to no operator) |  | ||||||
|     * `!=`: not equal |  | ||||||
|     * `>`: greater than |  | ||||||
|     * `<`: less than |  | ||||||
|     * `>=`: greater than or equal to |  | ||||||
|     * `<=`: less than or equal to |  | ||||||
|  |  | ||||||
| Hyphen Range Comparisons |  | ||||||
|  |  | ||||||
| There are multiple methods to handle ranges and the first is hyphens ranges. |  | ||||||
| These look like: |  | ||||||
|  |  | ||||||
|     * `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5` |  | ||||||
|     * `2.3.4 - 4.5` which is equivalent to `>= 2.3.4, <= 4.5` |  | ||||||
|  |  | ||||||
| Wildcards In Comparisons |  | ||||||
|  |  | ||||||
| The `x`, `X`, and `*` characters can be used as a wildcard character. This works |  | ||||||
| for all comparison operators. When used on the `=` operator it falls |  | ||||||
| back to the pack level comparison (see tilde below). For example, |  | ||||||
|  |  | ||||||
|     * `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` |  | ||||||
|     * `>= 1.2.x` is equivalent to `>= 1.2.0` |  | ||||||
|     * `<= 2.x` is equivalent to `<= 3` |  | ||||||
|     * `*` is equivalent to `>= 0.0.0` |  | ||||||
|  |  | ||||||
| Tilde Range Comparisons (Patch) |  | ||||||
|  |  | ||||||
| The tilde (`~`) comparison operator is for patch level ranges when a minor |  | ||||||
| version is specified and major level changes when the minor number is missing. |  | ||||||
| For example, |  | ||||||
|  |  | ||||||
|     * `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0` |  | ||||||
|     * `~1` is equivalent to `>= 1, < 2` |  | ||||||
|     * `~2.3` is equivalent to `>= 2.3, < 2.4` |  | ||||||
|     * `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` |  | ||||||
|     * `~1.x` is equivalent to `>= 1, < 2` |  | ||||||
|  |  | ||||||
| Caret Range Comparisons (Major) |  | ||||||
|  |  | ||||||
| The caret (`^`) comparison operator is for major level changes. This is useful |  | ||||||
| when comparisons of API versions as a major change is API breaking. For example, |  | ||||||
|  |  | ||||||
|     * `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` |  | ||||||
|     * `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` |  | ||||||
|     * `^2.3` is equivalent to `>= 2.3, < 3` |  | ||||||
|     * `^2.x` is equivalent to `>= 2.0.0, < 3` |  | ||||||
| */ |  | ||||||
| package semver |  | ||||||
							
								
								
									
										1
									
								
								vendor/github.com/Masterminds/semver/v3/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/Masterminds/semver/v3/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | _fuzz/ | ||||||
							
								
								
									
										26
									
								
								vendor/github.com/Masterminds/semver/v3/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/Masterminds/semver/v3/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | run: | ||||||
|  |   deadline: 2m | ||||||
|  |  | ||||||
|  | linters: | ||||||
|  |   disable-all: true | ||||||
|  |   enable: | ||||||
|  |     - deadcode | ||||||
|  |     - dupl | ||||||
|  |     - errcheck | ||||||
|  |     - gofmt | ||||||
|  |     - goimports | ||||||
|  |     - golint | ||||||
|  |     - gosimple | ||||||
|  |     - govet | ||||||
|  |     - ineffassign | ||||||
|  |     - misspell | ||||||
|  |     - nakedret | ||||||
|  |     - structcheck | ||||||
|  |     - unused | ||||||
|  |     - varcheck | ||||||
|  |  | ||||||
|  | linters-settings: | ||||||
|  |   gofmt: | ||||||
|  |     simplify: true | ||||||
|  |   dupl: | ||||||
|  |     threshold: 400 | ||||||
							
								
								
									
										194
									
								
								vendor/github.com/Masterminds/semver/v3/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								vendor/github.com/Masterminds/semver/v3/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,194 @@ | |||||||
|  | # Changelog | ||||||
|  |  | ||||||
|  | ## 3.1.1 (2020-11-23) | ||||||
|  |  | ||||||
|  | ### Fixed | ||||||
|  |  | ||||||
|  | - #158: Fixed issue with generated regex operation order that could cause problem | ||||||
|  |  | ||||||
|  | ## 3.1.0 (2020-04-15) | ||||||
|  |  | ||||||
|  | ### Added | ||||||
|  |  | ||||||
|  | - #131: Add support for serializing/deserializing SQL (thanks @ryancurrah) | ||||||
|  |  | ||||||
|  | ### Changed | ||||||
|  |  | ||||||
|  | - #148: More accurate validation messages on constraints | ||||||
|  |  | ||||||
|  | ## 3.0.3 (2019-12-13) | ||||||
|  |  | ||||||
|  | ### Fixed | ||||||
|  |  | ||||||
|  | - #141: Fixed issue with <= comparison | ||||||
|  |  | ||||||
|  | ## 3.0.2 (2019-11-14) | ||||||
|  |  | ||||||
|  | ### Fixed | ||||||
|  |  | ||||||
|  | - #134: Fixed broken constraint checking with ^0.0 (thanks @krmichelos) | ||||||
|  |  | ||||||
|  | ## 3.0.1 (2019-09-13) | ||||||
|  |  | ||||||
|  | ### Fixed | ||||||
|  |  | ||||||
|  | - #125: Fixes issue with module path for v3 | ||||||
|  |  | ||||||
|  | ## 3.0.0 (2019-09-12) | ||||||
|  |  | ||||||
|  | This is a major release of the semver package which includes API changes. The Go | ||||||
|  | API is compatible with ^1. The Go API was not changed because many people are using | ||||||
|  | `go get` without Go modules for their applications and API breaking changes cause | ||||||
|  | errors which we have or would need to support. | ||||||
|  |  | ||||||
|  | The changes in this release are the handling based on the data passed into the | ||||||
|  | functions. These are described in the added and changed sections below. | ||||||
|  |  | ||||||
|  | ### Added | ||||||
|  |  | ||||||
|  | - StrictNewVersion function. This is similar to NewVersion but will return an | ||||||
|  |   error if the version passed in is not a strict semantic version. For example, | ||||||
|  |   1.2.3 would pass but v1.2.3 or 1.2 would fail because they are not strictly | ||||||
|  |   speaking semantic versions. This function is faster, performs fewer operations, | ||||||
|  |   and uses fewer allocations than NewVersion. | ||||||
|  | - Fuzzing has been performed on NewVersion, StrictNewVersion, and NewConstraint. | ||||||
|  |   The Makefile contains the operations used. For more information on you can start | ||||||
|  |   on Wikipedia at https://en.wikipedia.org/wiki/Fuzzing | ||||||
|  | - Now using Go modules | ||||||
|  |  | ||||||
|  | ### Changed | ||||||
|  |  | ||||||
|  | - NewVersion has proper prerelease and metadata validation with error messages | ||||||
|  |   to signal an issue with either of them | ||||||
|  | - ^ now operates using a similar set of rules to npm/js and Rust/Cargo. If the | ||||||
|  |   version is >=1 the ^ ranges works the same as v1. For major versions of 0 the | ||||||
|  |   rules have changed. The minor version is treated as the stable version unless | ||||||
|  |   a patch is specified and then it is equivalent to =. One difference from npm/js | ||||||
|  |   is that prereleases there are only to a specific version (e.g. 1.2.3). | ||||||
|  |   Prereleases here look over multiple versions and follow semantic version | ||||||
|  |   ordering rules. This pattern now follows along with the expected and requested | ||||||
|  |   handling of this packaged by numerous users. | ||||||
|  |  | ||||||
|  | ## 1.5.0 (2019-09-11) | ||||||
|  |  | ||||||
|  | ### Added | ||||||
|  |  | ||||||
|  | - #103: Add basic fuzzing for `NewVersion()` (thanks @jesse-c) | ||||||
|  |  | ||||||
|  | ### Changed | ||||||
|  |  | ||||||
|  | - #82: Clarify wildcard meaning in range constraints and update tests for it (thanks @greysteil) | ||||||
|  | - #83: Clarify caret operator range for pre-1.0.0 dependencies (thanks @greysteil) | ||||||
|  | - #72: Adding docs comment pointing to vert for a cli | ||||||
|  | - #71: Update the docs on pre-release comparator handling | ||||||
|  | - #89: Test with new go versions (thanks @thedevsaddam) | ||||||
|  | - #87: Added $ to ValidPrerelease for better validation (thanks @jeremycarroll) | ||||||
|  |  | ||||||
|  | ### Fixed | ||||||
|  |  | ||||||
|  | - #78: Fix unchecked error in example code (thanks @ravron) | ||||||
|  | - #70: Fix the handling of pre-releases and the 0.0.0 release edge case | ||||||
|  | - #97: Fixed copyright file for proper display on GitHub | ||||||
|  | - #107: Fix handling prerelease when sorting alphanum and num  | ||||||
|  | - #109: Fixed where Validate sometimes returns wrong message on error | ||||||
|  |  | ||||||
|  | ## 1.4.2 (2018-04-10) | ||||||
|  |  | ||||||
|  | ### Changed | ||||||
|  |  | ||||||
|  | - #72: Updated the docs to point to vert for a console appliaction | ||||||
|  | - #71: Update the docs on pre-release comparator handling | ||||||
|  |  | ||||||
|  | ### Fixed | ||||||
|  |  | ||||||
|  | - #70: Fix the handling of pre-releases and the 0.0.0 release edge case | ||||||
|  |  | ||||||
|  | ## 1.4.1 (2018-04-02) | ||||||
|  |  | ||||||
|  | ### Fixed | ||||||
|  |  | ||||||
|  | - Fixed #64: Fix pre-release precedence issue (thanks @uudashr) | ||||||
|  |  | ||||||
|  | ## 1.4.0 (2017-10-04) | ||||||
|  |  | ||||||
|  | ### Changed | ||||||
|  |  | ||||||
|  | - #61: Update NewVersion to parse ints with a 64bit int size (thanks @zknill) | ||||||
|  |  | ||||||
|  | ## 1.3.1 (2017-07-10) | ||||||
|  |  | ||||||
|  | ### Fixed | ||||||
|  |  | ||||||
|  | - Fixed #57: number comparisons in prerelease sometimes inaccurate | ||||||
|  |  | ||||||
|  | ## 1.3.0 (2017-05-02) | ||||||
|  |  | ||||||
|  | ### Added | ||||||
|  |  | ||||||
|  | - #45: Added json (un)marshaling support (thanks @mh-cbon) | ||||||
|  | - Stability marker. See https://masterminds.github.io/stability/ | ||||||
|  |  | ||||||
|  | ### Fixed | ||||||
|  |  | ||||||
|  | - #51: Fix handling of single digit tilde constraint (thanks @dgodd) | ||||||
|  |  | ||||||
|  | ### Changed | ||||||
|  |  | ||||||
|  | - #55: The godoc icon moved from png to svg | ||||||
|  |  | ||||||
|  | ## 1.2.3 (2017-04-03) | ||||||
|  |  | ||||||
|  | ### Fixed | ||||||
|  |  | ||||||
|  | - #46: Fixed 0.x.x and 0.0.x in constraints being treated as * | ||||||
|  |  | ||||||
|  | ## Release 1.2.2 (2016-12-13) | ||||||
|  |  | ||||||
|  | ### Fixed | ||||||
|  |  | ||||||
|  | - #34: Fixed issue where hyphen range was not working with pre-release parsing. | ||||||
|  |  | ||||||
|  | ## Release 1.2.1 (2016-11-28) | ||||||
|  |  | ||||||
|  | ### Fixed | ||||||
|  |  | ||||||
|  | - #24: Fixed edge case issue where constraint "> 0" does not handle "0.0.1-alpha" | ||||||
|  |   properly. | ||||||
|  |  | ||||||
|  | ## Release 1.2.0 (2016-11-04) | ||||||
|  |  | ||||||
|  | ### Added | ||||||
|  |  | ||||||
|  | - #20: Added MustParse function for versions (thanks @adamreese) | ||||||
|  | - #15: Added increment methods on versions (thanks @mh-cbon) | ||||||
|  |  | ||||||
|  | ### Fixed | ||||||
|  |  | ||||||
|  | - Issue #21: Per the SemVer spec (section 9) a pre-release is unstable and | ||||||
|  |   might not satisfy the intended compatibility. The change here ignores pre-releases | ||||||
|  |   on constraint checks (e.g., ~ or ^) when a pre-release is not part of the | ||||||
|  |   constraint. For example, `^1.2.3` will ignore pre-releases while | ||||||
|  |   `^1.2.3-alpha` will include them. | ||||||
|  |  | ||||||
|  | ## Release 1.1.1 (2016-06-30) | ||||||
|  |  | ||||||
|  | ### Changed | ||||||
|  |  | ||||||
|  | - Issue #9: Speed up version comparison performance (thanks @sdboyer) | ||||||
|  | - Issue #8: Added benchmarks (thanks @sdboyer) | ||||||
|  | - Updated Go Report Card URL to new location | ||||||
|  | - Updated Readme to add code snippet formatting (thanks @mh-cbon) | ||||||
|  | - Updating tagging to v[SemVer] structure for compatibility with other tools. | ||||||
|  |  | ||||||
|  | ## Release 1.1.0 (2016-03-11) | ||||||
|  |  | ||||||
|  | - Issue #2: Implemented validation to provide reasons a versions failed a | ||||||
|  |   constraint. | ||||||
|  |  | ||||||
|  | ## Release 1.0.1 (2015-12-31) | ||||||
|  |  | ||||||
|  | - Fixed #1: * constraint failing on valid versions. | ||||||
|  |  | ||||||
|  | ## Release 1.0.0 (2015-10-20) | ||||||
|  |  | ||||||
|  | - Initial release | ||||||
							
								
								
									
										37
									
								
								vendor/github.com/Masterminds/semver/v3/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/Masterminds/semver/v3/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | GOPATH=$(shell go env GOPATH) | ||||||
|  | GOLANGCI_LINT=$(GOPATH)/bin/golangci-lint | ||||||
|  | GOFUZZBUILD = $(GOPATH)/bin/go-fuzz-build | ||||||
|  | GOFUZZ = $(GOPATH)/bin/go-fuzz | ||||||
|  |  | ||||||
|  | .PHONY: lint | ||||||
|  | lint: $(GOLANGCI_LINT) | ||||||
|  | 	@echo "==> Linting codebase" | ||||||
|  | 	@$(GOLANGCI_LINT) run | ||||||
|  |  | ||||||
|  | .PHONY: test | ||||||
|  | test: | ||||||
|  | 	@echo "==> Running tests" | ||||||
|  | 	GO111MODULE=on go test -v | ||||||
|  |  | ||||||
|  | .PHONY: test-cover | ||||||
|  | test-cover: | ||||||
|  | 	@echo "==> Running Tests with coverage" | ||||||
|  | 	GO111MODULE=on go test -cover . | ||||||
|  |  | ||||||
|  | .PHONY: fuzz | ||||||
|  | fuzz: $(GOFUZZBUILD) $(GOFUZZ) | ||||||
|  | 	@echo "==> Fuzz testing" | ||||||
|  | 	$(GOFUZZBUILD) | ||||||
|  | 	$(GOFUZZ) -workdir=_fuzz | ||||||
|  |  | ||||||
|  | $(GOLANGCI_LINT): | ||||||
|  | 	# Install golangci-lint. The configuration for it is in the .golangci.yml | ||||||
|  | 	# file in the root of the repository | ||||||
|  | 	echo ${GOPATH} | ||||||
|  | 	curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.17.1 | ||||||
|  |  | ||||||
|  | $(GOFUZZBUILD): | ||||||
|  | 	cd / && go get -u github.com/dvyukov/go-fuzz/go-fuzz-build | ||||||
|  |  | ||||||
|  | $(GOFUZZ): | ||||||
|  | 	cd / && go get -u github.com/dvyukov/go-fuzz/go-fuzz github.com/dvyukov/go-fuzz/go-fuzz-dep | ||||||
							
								
								
									
										244
									
								
								vendor/github.com/Masterminds/semver/v3/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								vendor/github.com/Masterminds/semver/v3/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | |||||||
|  | # SemVer | ||||||
|  |  | ||||||
|  | The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to: | ||||||
|  |  | ||||||
|  | * Parse semantic versions | ||||||
|  | * Sort semantic versions | ||||||
|  | * Check if a semantic version fits within a set of constraints | ||||||
|  | * Optionally work with a `v` prefix | ||||||
|  |  | ||||||
|  | [](https://masterminds.github.io/stability/active.html) | ||||||
|  | [](https://github.com/Masterminds/semver/actions) | ||||||
|  | [](https://pkg.go.dev/github.com/Masterminds/semver/v3) | ||||||
|  | [](https://goreportcard.com/report/github.com/Masterminds/semver) | ||||||
|  |  | ||||||
|  | If you are looking for a command line tool for version comparisons please see | ||||||
|  | [vert](https://github.com/Masterminds/vert) which uses this library. | ||||||
|  |  | ||||||
|  | ## Package Versions | ||||||
|  |  | ||||||
|  | There are three major versions fo the `semver` package. | ||||||
|  |  | ||||||
|  | * 3.x.x is the new stable and active version. This version is focused on constraint | ||||||
|  |   compatibility for range handling in other tools from other languages. It has | ||||||
|  |   a similar API to the v1 releases. The development of this version is on the master | ||||||
|  |   branch. The documentation for this version is below. | ||||||
|  | * 2.x was developed primarily for [dep](https://github.com/golang/dep). There are | ||||||
|  |   no tagged releases and the development was performed by [@sdboyer](https://github.com/sdboyer). | ||||||
|  |   There are API breaking changes from v1. This version lives on the [2.x branch](https://github.com/Masterminds/semver/tree/2.x). | ||||||
|  | * 1.x.x is the most widely used version with numerous tagged releases. This is the | ||||||
|  |   previous stable and is still maintained for bug fixes. The development, to fix | ||||||
|  |   bugs, occurs on the release-1 branch. You can read the documentation [here](https://github.com/Masterminds/semver/blob/release-1/README.md). | ||||||
|  |  | ||||||
|  | ## Parsing Semantic Versions | ||||||
|  |  | ||||||
|  | There are two functions that can parse semantic versions. The `StrictNewVersion` | ||||||
|  | function only parses valid version 2 semantic versions as outlined in the | ||||||
|  | specification. The `NewVersion` function attempts to coerce a version into a | ||||||
|  | semantic version and parse it. For example, if there is a leading v or a version | ||||||
|  | listed without all 3 parts (e.g. `v1.2`) it will attempt to coerce it into a valid | ||||||
|  | semantic version (e.g., 1.2.0). In both cases a `Version` object is returned | ||||||
|  | that can be sorted, compared, and used in constraints. | ||||||
|  |  | ||||||
|  | When parsing a version an error is returned if there is an issue parsing the | ||||||
|  | version. For example, | ||||||
|  |  | ||||||
|  |     v, err := semver.NewVersion("1.2.3-beta.1+build345") | ||||||
|  |  | ||||||
|  | The version object has methods to get the parts of the version, compare it to | ||||||
|  | other versions, convert the version back into a string, and get the original | ||||||
|  | string. Getting the original string is useful if the semantic version was coerced | ||||||
|  | into a valid form. | ||||||
|  |  | ||||||
|  | ## Sorting Semantic Versions | ||||||
|  |  | ||||||
|  | A set of versions can be sorted using the `sort` package from the standard library. | ||||||
|  | For example, | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} | ||||||
|  | vs := make([]*semver.Version, len(raw)) | ||||||
|  | for i, r := range raw { | ||||||
|  |     v, err := semver.NewVersion(r) | ||||||
|  |     if err != nil { | ||||||
|  |         t.Errorf("Error parsing version: %s", err) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     vs[i] = v | ||||||
|  | } | ||||||
|  |  | ||||||
|  | sort.Sort(semver.Collection(vs)) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Checking Version Constraints | ||||||
|  |  | ||||||
|  | There are two methods for comparing versions. One uses comparison methods on | ||||||
|  | `Version` instances and the other uses `Constraints`. There are some important | ||||||
|  | differences to notes between these two methods of comparison. | ||||||
|  |  | ||||||
|  | 1. When two versions are compared using functions such as `Compare`, `LessThan`, | ||||||
|  |    and others it will follow the specification and always include prereleases | ||||||
|  |    within the comparison. It will provide an answer that is valid with the | ||||||
|  |    comparison section of the spec at https://semver.org/#spec-item-11 | ||||||
|  | 2. When constraint checking is used for checks or validation it will follow a | ||||||
|  |    different set of rules that are common for ranges with tools like npm/js | ||||||
|  |    and Rust/Cargo. This includes considering prereleases to be invalid if the | ||||||
|  |    ranges does not include one. If you want to have it include pre-releases a | ||||||
|  |    simple solution is to include `-0` in your range. | ||||||
|  | 3. Constraint ranges can have some complex rules including the shorthand use of | ||||||
|  |    ~ and ^. For more details on those see the options below. | ||||||
|  |  | ||||||
|  | There are differences between the two methods or checking versions because the | ||||||
|  | comparison methods on `Version` follow the specification while comparison ranges | ||||||
|  | are not part of the specification. Different packages and tools have taken it | ||||||
|  | upon themselves to come up with range rules. This has resulted in differences. | ||||||
|  | For example, npm/js and Cargo/Rust follow similar patterns while PHP has a | ||||||
|  | different pattern for ^. The comparison features in this package follow the | ||||||
|  | npm/js and Cargo/Rust lead because applications using it have followed similar | ||||||
|  | patters with their versions. | ||||||
|  |  | ||||||
|  | Checking a version against version constraints is one of the most featureful | ||||||
|  | parts of the package. | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | c, err := semver.NewConstraint(">= 1.2.3") | ||||||
|  | if err != nil { | ||||||
|  |     // Handle constraint not being parsable. | ||||||
|  | } | ||||||
|  |  | ||||||
|  | v, err := semver.NewVersion("1.3") | ||||||
|  | if err != nil { | ||||||
|  |     // Handle version not being parsable. | ||||||
|  | } | ||||||
|  | // Check if the version meets the constraints. The a variable will be true. | ||||||
|  | a := c.Check(v) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Basic Comparisons | ||||||
|  |  | ||||||
|  | There are two elements to the comparisons. First, a comparison string is a list | ||||||
|  | of space or comma separated AND comparisons. These are then separated by || (OR) | ||||||
|  | comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a | ||||||
|  | comparison that's greater than or equal to 1.2 and less than 3.0.0 or is | ||||||
|  | greater than or equal to 4.2.3. | ||||||
|  |  | ||||||
|  | The basic comparisons are: | ||||||
|  |  | ||||||
|  | * `=`: equal (aliased to no operator) | ||||||
|  | * `!=`: not equal | ||||||
|  | * `>`: greater than | ||||||
|  | * `<`: less than | ||||||
|  | * `>=`: greater than or equal to | ||||||
|  | * `<=`: less than or equal to | ||||||
|  |  | ||||||
|  | ### Working With Prerelease Versions | ||||||
|  |  | ||||||
|  | Pre-releases, for those not familiar with them, are used for software releases | ||||||
|  | prior to stable or generally available releases. Examples of prereleases include | ||||||
|  | development, alpha, beta, and release candidate releases. A prerelease may be | ||||||
|  | a version such as `1.2.3-beta.1` while the stable release would be `1.2.3`. In the | ||||||
|  | order of precedence, prereleases come before their associated releases. In this | ||||||
|  | example `1.2.3-beta.1 < 1.2.3`. | ||||||
|  |  | ||||||
|  | According to the Semantic Version specification prereleases may not be | ||||||
|  | API compliant with their release counterpart. It says, | ||||||
|  |  | ||||||
|  | > A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. | ||||||
|  |  | ||||||
|  | SemVer comparisons using constraints without a prerelease comparator will skip | ||||||
|  | prerelease versions. For example, `>=1.2.3` will skip prereleases when looking | ||||||
|  | at a list of releases while `>=1.2.3-0` will evaluate and find prereleases. | ||||||
|  |  | ||||||
|  | The reason for the `0` as a pre-release version in the example comparison is | ||||||
|  | because pre-releases can only contain ASCII alphanumerics and hyphens (along with | ||||||
|  | `.` separators), per the spec. Sorting happens in ASCII sort order, again per the | ||||||
|  | spec. The lowest character is a `0` in ASCII sort order | ||||||
|  | (see an [ASCII Table](http://www.asciitable.com/)) | ||||||
|  |  | ||||||
|  | Understanding ASCII sort ordering is important because A-Z comes before a-z. That | ||||||
|  | means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case | ||||||
|  | sensitivity doesn't apply here. This is due to ASCII sort ordering which is what | ||||||
|  | the spec specifies. | ||||||
|  |  | ||||||
|  | ### Hyphen Range Comparisons | ||||||
|  |  | ||||||
|  | There are multiple methods to handle ranges and the first is hyphens ranges. | ||||||
|  | These look like: | ||||||
|  |  | ||||||
|  | * `1.2 - 1.4.5` which is equivalent to `>= 1.2 <= 1.4.5` | ||||||
|  | * `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` | ||||||
|  |  | ||||||
|  | ### Wildcards In Comparisons | ||||||
|  |  | ||||||
|  | The `x`, `X`, and `*` characters can be used as a wildcard character. This works | ||||||
|  | for all comparison operators. When used on the `=` operator it falls | ||||||
|  | back to the patch level comparison (see tilde below). For example, | ||||||
|  |  | ||||||
|  | * `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` | ||||||
|  | * `>= 1.2.x` is equivalent to `>= 1.2.0` | ||||||
|  | * `<= 2.x` is equivalent to `< 3` | ||||||
|  | * `*` is equivalent to `>= 0.0.0` | ||||||
|  |  | ||||||
|  | ### Tilde Range Comparisons (Patch) | ||||||
|  |  | ||||||
|  | The tilde (`~`) comparison operator is for patch level ranges when a minor | ||||||
|  | version is specified and major level changes when the minor number is missing. | ||||||
|  | For example, | ||||||
|  |  | ||||||
|  | * `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0` | ||||||
|  | * `~1` is equivalent to `>= 1, < 2` | ||||||
|  | * `~2.3` is equivalent to `>= 2.3, < 2.4` | ||||||
|  | * `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` | ||||||
|  | * `~1.x` is equivalent to `>= 1, < 2` | ||||||
|  |  | ||||||
|  | ### Caret Range Comparisons (Major) | ||||||
|  |  | ||||||
|  | The caret (`^`) comparison operator is for major level changes once a stable | ||||||
|  | (1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts | ||||||
|  | as the API stability level. This is useful when comparisons of API versions as a | ||||||
|  | major change is API breaking. For example, | ||||||
|  |  | ||||||
|  | * `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` | ||||||
|  | * `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` | ||||||
|  | * `^2.3` is equivalent to `>= 2.3, < 3` | ||||||
|  | * `^2.x` is equivalent to `>= 2.0.0, < 3` | ||||||
|  | * `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` | ||||||
|  | * `^0.2` is equivalent to `>=0.2.0 <0.3.0` | ||||||
|  | * `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` | ||||||
|  | * `^0.0` is equivalent to `>=0.0.0 <0.1.0` | ||||||
|  | * `^0` is equivalent to `>=0.0.0 <1.0.0` | ||||||
|  |  | ||||||
|  | ## Validation | ||||||
|  |  | ||||||
|  | In addition to testing a version against a constraint, a version can be validated | ||||||
|  | against a constraint. When validation fails a slice of errors containing why a | ||||||
|  | version didn't meet the constraint is returned. For example, | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") | ||||||
|  | if err != nil { | ||||||
|  |     // Handle constraint not being parseable. | ||||||
|  | } | ||||||
|  |  | ||||||
|  | v, err := semver.NewVersion("1.3") | ||||||
|  | if err != nil { | ||||||
|  |     // Handle version not being parseable. | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Validate a version against a constraint. | ||||||
|  | a, msgs := c.Validate(v) | ||||||
|  | // a is false | ||||||
|  | for _, m := range msgs { | ||||||
|  |     fmt.Println(m) | ||||||
|  |  | ||||||
|  |     // Loops over the errors which would read | ||||||
|  |     // "1.3 is greater than 1.2.3" | ||||||
|  |     // "1.3 is less than 1.4" | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Contribute | ||||||
|  |  | ||||||
|  | If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues) | ||||||
|  | or [create a pull request](https://github.com/Masterminds/semver/pulls). | ||||||
							
								
								
									
										568
									
								
								vendor/github.com/Masterminds/semver/v3/constraints.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										568
									
								
								vendor/github.com/Masterminds/semver/v3/constraints.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,568 @@ | |||||||
|  | package semver | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"regexp" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Constraints is one or more constraint that a semantic version can be | ||||||
|  | // checked against. | ||||||
|  | type Constraints struct { | ||||||
|  | 	constraints [][]*constraint | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewConstraint returns a Constraints instance that a Version instance can | ||||||
|  | // be checked against. If there is a parse error it will be returned. | ||||||
|  | func NewConstraint(c string) (*Constraints, error) { | ||||||
|  |  | ||||||
|  | 	// Rewrite - ranges into a comparison operation. | ||||||
|  | 	c = rewriteRange(c) | ||||||
|  |  | ||||||
|  | 	ors := strings.Split(c, "||") | ||||||
|  | 	or := make([][]*constraint, len(ors)) | ||||||
|  | 	for k, v := range ors { | ||||||
|  |  | ||||||
|  | 		// TODO: Find a way to validate and fetch all the constraints in a simpler form | ||||||
|  |  | ||||||
|  | 		// Validate the segment | ||||||
|  | 		if !validConstraintRegex.MatchString(v) { | ||||||
|  | 			return nil, fmt.Errorf("improper constraint: %s", v) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		cs := findConstraintRegex.FindAllString(v, -1) | ||||||
|  | 		if cs == nil { | ||||||
|  | 			cs = append(cs, v) | ||||||
|  | 		} | ||||||
|  | 		result := make([]*constraint, len(cs)) | ||||||
|  | 		for i, s := range cs { | ||||||
|  | 			pc, err := parseConstraint(s) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return nil, err | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			result[i] = pc | ||||||
|  | 		} | ||||||
|  | 		or[k] = result | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	o := &Constraints{constraints: or} | ||||||
|  | 	return o, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Check tests if a version satisfies the constraints. | ||||||
|  | func (cs Constraints) Check(v *Version) bool { | ||||||
|  | 	// TODO(mattfarina): For v4 of this library consolidate the Check and Validate | ||||||
|  | 	// functions as the underlying functions make that possible now. | ||||||
|  | 	// loop over the ORs and check the inner ANDs | ||||||
|  | 	for _, o := range cs.constraints { | ||||||
|  | 		joy := true | ||||||
|  | 		for _, c := range o { | ||||||
|  | 			if check, _ := c.check(v); !check { | ||||||
|  | 				joy = false | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if joy { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Validate checks if a version satisfies a constraint. If not a slice of | ||||||
|  | // reasons for the failure are returned in addition to a bool. | ||||||
|  | func (cs Constraints) Validate(v *Version) (bool, []error) { | ||||||
|  | 	// loop over the ORs and check the inner ANDs | ||||||
|  | 	var e []error | ||||||
|  |  | ||||||
|  | 	// Capture the prerelease message only once. When it happens the first time | ||||||
|  | 	// this var is marked | ||||||
|  | 	var prerelesase bool | ||||||
|  | 	for _, o := range cs.constraints { | ||||||
|  | 		joy := true | ||||||
|  | 		for _, c := range o { | ||||||
|  | 			// Before running the check handle the case there the version is | ||||||
|  | 			// a prerelease and the check is not searching for prereleases. | ||||||
|  | 			if c.con.pre == "" && v.pre != "" { | ||||||
|  | 				if !prerelesase { | ||||||
|  | 					em := fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) | ||||||
|  | 					e = append(e, em) | ||||||
|  | 					prerelesase = true | ||||||
|  | 				} | ||||||
|  | 				joy = false | ||||||
|  |  | ||||||
|  | 			} else { | ||||||
|  |  | ||||||
|  | 				if _, err := c.check(v); err != nil { | ||||||
|  | 					e = append(e, err) | ||||||
|  | 					joy = false | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if joy { | ||||||
|  | 			return true, []error{} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return false, e | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (cs Constraints) String() string { | ||||||
|  | 	buf := make([]string, len(cs.constraints)) | ||||||
|  | 	var tmp bytes.Buffer | ||||||
|  |  | ||||||
|  | 	for k, v := range cs.constraints { | ||||||
|  | 		tmp.Reset() | ||||||
|  | 		vlen := len(v) | ||||||
|  | 		for kk, c := range v { | ||||||
|  | 			tmp.WriteString(c.string()) | ||||||
|  |  | ||||||
|  | 			// Space separate the AND conditions | ||||||
|  | 			if vlen > 1 && kk < vlen-1 { | ||||||
|  | 				tmp.WriteString(" ") | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		buf[k] = tmp.String() | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return strings.Join(buf, " || ") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var constraintOps map[string]cfunc | ||||||
|  | var constraintRegex *regexp.Regexp | ||||||
|  | var constraintRangeRegex *regexp.Regexp | ||||||
|  |  | ||||||
|  | // Used to find individual constraints within a multi-constraint string | ||||||
|  | var findConstraintRegex *regexp.Regexp | ||||||
|  |  | ||||||
|  | // Used to validate an segment of ANDs is valid | ||||||
|  | var validConstraintRegex *regexp.Regexp | ||||||
|  |  | ||||||
|  | const cvRegex string = `v?([0-9|x|X|\*]+)(\.[0-9|x|X|\*]+)?(\.[0-9|x|X|\*]+)?` + | ||||||
|  | 	`(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + | ||||||
|  | 	`(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` | ||||||
|  |  | ||||||
|  | func init() { | ||||||
|  | 	constraintOps = map[string]cfunc{ | ||||||
|  | 		"":   constraintTildeOrEqual, | ||||||
|  | 		"=":  constraintTildeOrEqual, | ||||||
|  | 		"!=": constraintNotEqual, | ||||||
|  | 		">":  constraintGreaterThan, | ||||||
|  | 		"<":  constraintLessThan, | ||||||
|  | 		">=": constraintGreaterThanEqual, | ||||||
|  | 		"=>": constraintGreaterThanEqual, | ||||||
|  | 		"<=": constraintLessThanEqual, | ||||||
|  | 		"=<": constraintLessThanEqual, | ||||||
|  | 		"~":  constraintTilde, | ||||||
|  | 		"~>": constraintTilde, | ||||||
|  | 		"^":  constraintCaret, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ops := `=||!=|>|<|>=|=>|<=|=<|~|~>|\^` | ||||||
|  |  | ||||||
|  | 	constraintRegex = regexp.MustCompile(fmt.Sprintf( | ||||||
|  | 		`^\s*(%s)\s*(%s)\s*$`, | ||||||
|  | 		ops, | ||||||
|  | 		cvRegex)) | ||||||
|  |  | ||||||
|  | 	constraintRangeRegex = regexp.MustCompile(fmt.Sprintf( | ||||||
|  | 		`\s*(%s)\s+-\s+(%s)\s*`, | ||||||
|  | 		cvRegex, cvRegex)) | ||||||
|  |  | ||||||
|  | 	findConstraintRegex = regexp.MustCompile(fmt.Sprintf( | ||||||
|  | 		`(%s)\s*(%s)`, | ||||||
|  | 		ops, | ||||||
|  | 		cvRegex)) | ||||||
|  |  | ||||||
|  | 	validConstraintRegex = regexp.MustCompile(fmt.Sprintf( | ||||||
|  | 		`^(\s*(%s)\s*(%s)\s*\,?)+$`, | ||||||
|  | 		ops, | ||||||
|  | 		cvRegex)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // An individual constraint | ||||||
|  | type constraint struct { | ||||||
|  | 	// The version used in the constraint check. For example, if a constraint | ||||||
|  | 	// is '<= 2.0.0' the con a version instance representing 2.0.0. | ||||||
|  | 	con *Version | ||||||
|  |  | ||||||
|  | 	// The original parsed version (e.g., 4.x from != 4.x) | ||||||
|  | 	orig string | ||||||
|  |  | ||||||
|  | 	// The original operator for the constraint | ||||||
|  | 	origfunc string | ||||||
|  |  | ||||||
|  | 	// When an x is used as part of the version (e.g., 1.x) | ||||||
|  | 	minorDirty bool | ||||||
|  | 	dirty      bool | ||||||
|  | 	patchDirty bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Check if a version meets the constraint | ||||||
|  | func (c *constraint) check(v *Version) (bool, error) { | ||||||
|  | 	return constraintOps[c.origfunc](v, c) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String prints an individual constraint into a string | ||||||
|  | func (c *constraint) string() string { | ||||||
|  | 	return c.origfunc + c.orig | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type cfunc func(v *Version, c *constraint) (bool, error) | ||||||
|  |  | ||||||
|  | func parseConstraint(c string) (*constraint, error) { | ||||||
|  | 	if len(c) > 0 { | ||||||
|  | 		m := constraintRegex.FindStringSubmatch(c) | ||||||
|  | 		if m == nil { | ||||||
|  | 			return nil, fmt.Errorf("improper constraint: %s", c) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		cs := &constraint{ | ||||||
|  | 			orig:     m[2], | ||||||
|  | 			origfunc: m[1], | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		ver := m[2] | ||||||
|  | 		minorDirty := false | ||||||
|  | 		patchDirty := false | ||||||
|  | 		dirty := false | ||||||
|  | 		if isX(m[3]) || m[3] == "" { | ||||||
|  | 			ver = "0.0.0" | ||||||
|  | 			dirty = true | ||||||
|  | 		} else if isX(strings.TrimPrefix(m[4], ".")) || m[4] == "" { | ||||||
|  | 			minorDirty = true | ||||||
|  | 			dirty = true | ||||||
|  | 			ver = fmt.Sprintf("%s.0.0%s", m[3], m[6]) | ||||||
|  | 		} else if isX(strings.TrimPrefix(m[5], ".")) || m[5] == "" { | ||||||
|  | 			dirty = true | ||||||
|  | 			patchDirty = true | ||||||
|  | 			ver = fmt.Sprintf("%s%s.0%s", m[3], m[4], m[6]) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		con, err := NewVersion(ver) | ||||||
|  | 		if err != nil { | ||||||
|  |  | ||||||
|  | 			// The constraintRegex should catch any regex parsing errors. So, | ||||||
|  | 			// we should never get here. | ||||||
|  | 			return nil, errors.New("constraint Parser Error") | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		cs.con = con | ||||||
|  | 		cs.minorDirty = minorDirty | ||||||
|  | 		cs.patchDirty = patchDirty | ||||||
|  | 		cs.dirty = dirty | ||||||
|  |  | ||||||
|  | 		return cs, nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// The rest is the special case where an empty string was passed in which | ||||||
|  | 	// is equivalent to * or >=0.0.0 | ||||||
|  | 	con, err := StrictNewVersion("0.0.0") | ||||||
|  | 	if err != nil { | ||||||
|  |  | ||||||
|  | 		// The constraintRegex should catch any regex parsing errors. So, | ||||||
|  | 		// we should never get here. | ||||||
|  | 		return nil, errors.New("constraint Parser Error") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	cs := &constraint{ | ||||||
|  | 		con:        con, | ||||||
|  | 		orig:       c, | ||||||
|  | 		origfunc:   "", | ||||||
|  | 		minorDirty: false, | ||||||
|  | 		patchDirty: false, | ||||||
|  | 		dirty:      true, | ||||||
|  | 	} | ||||||
|  | 	return cs, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Constraint functions | ||||||
|  | func constraintNotEqual(v *Version, c *constraint) (bool, error) { | ||||||
|  | 	if c.dirty { | ||||||
|  |  | ||||||
|  | 		// If there is a pre-release on the version but the constraint isn't looking | ||||||
|  | 		// for them assume that pre-releases are not compatible. See issue 21 for | ||||||
|  | 		// more details. | ||||||
|  | 		if v.Prerelease() != "" && c.con.Prerelease() == "" { | ||||||
|  | 			return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if c.con.Major() != v.Major() { | ||||||
|  | 			return true, nil | ||||||
|  | 		} | ||||||
|  | 		if c.con.Minor() != v.Minor() && !c.minorDirty { | ||||||
|  | 			return true, nil | ||||||
|  | 		} else if c.minorDirty { | ||||||
|  | 			return false, fmt.Errorf("%s is equal to %s", v, c.orig) | ||||||
|  | 		} else if c.con.Patch() != v.Patch() && !c.patchDirty { | ||||||
|  | 			return true, nil | ||||||
|  | 		} else if c.patchDirty { | ||||||
|  | 			// Need to handle prereleases if present | ||||||
|  | 			if v.Prerelease() != "" || c.con.Prerelease() != "" { | ||||||
|  | 				eq := comparePrerelease(v.Prerelease(), c.con.Prerelease()) != 0 | ||||||
|  | 				if eq { | ||||||
|  | 					return true, nil | ||||||
|  | 				} | ||||||
|  | 				return false, fmt.Errorf("%s is equal to %s", v, c.orig) | ||||||
|  | 			} | ||||||
|  | 			return false, fmt.Errorf("%s is equal to %s", v, c.orig) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eq := v.Equal(c.con) | ||||||
|  | 	if eq { | ||||||
|  | 		return false, fmt.Errorf("%s is equal to %s", v, c.orig) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return true, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func constraintGreaterThan(v *Version, c *constraint) (bool, error) { | ||||||
|  |  | ||||||
|  | 	// If there is a pre-release on the version but the constraint isn't looking | ||||||
|  | 	// for them assume that pre-releases are not compatible. See issue 21 for | ||||||
|  | 	// more details. | ||||||
|  | 	if v.Prerelease() != "" && c.con.Prerelease() == "" { | ||||||
|  | 		return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var eq bool | ||||||
|  |  | ||||||
|  | 	if !c.dirty { | ||||||
|  | 		eq = v.Compare(c.con) == 1 | ||||||
|  | 		if eq { | ||||||
|  | 			return true, nil | ||||||
|  | 		} | ||||||
|  | 		return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if v.Major() > c.con.Major() { | ||||||
|  | 		return true, nil | ||||||
|  | 	} else if v.Major() < c.con.Major() { | ||||||
|  | 		return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) | ||||||
|  | 	} else if c.minorDirty { | ||||||
|  | 		// This is a range case such as >11. When the version is something like | ||||||
|  | 		// 11.1.0 is it not > 11. For that we would need 12 or higher | ||||||
|  | 		return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) | ||||||
|  | 	} else if c.patchDirty { | ||||||
|  | 		// This is for ranges such as >11.1. A version of 11.1.1 is not greater | ||||||
|  | 		// which one of 11.2.1 is greater | ||||||
|  | 		eq = v.Minor() > c.con.Minor() | ||||||
|  | 		if eq { | ||||||
|  | 			return true, nil | ||||||
|  | 		} | ||||||
|  | 		return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// If we have gotten here we are not comparing pre-preleases and can use the | ||||||
|  | 	// Compare function to accomplish that. | ||||||
|  | 	eq = v.Compare(c.con) == 1 | ||||||
|  | 	if eq { | ||||||
|  | 		return true, nil | ||||||
|  | 	} | ||||||
|  | 	return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func constraintLessThan(v *Version, c *constraint) (bool, error) { | ||||||
|  | 	// If there is a pre-release on the version but the constraint isn't looking | ||||||
|  | 	// for them assume that pre-releases are not compatible. See issue 21 for | ||||||
|  | 	// more details. | ||||||
|  | 	if v.Prerelease() != "" && c.con.Prerelease() == "" { | ||||||
|  | 		return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eq := v.Compare(c.con) < 0 | ||||||
|  | 	if eq { | ||||||
|  | 		return true, nil | ||||||
|  | 	} | ||||||
|  | 	return false, fmt.Errorf("%s is greater than or equal to %s", v, c.orig) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func constraintGreaterThanEqual(v *Version, c *constraint) (bool, error) { | ||||||
|  |  | ||||||
|  | 	// If there is a pre-release on the version but the constraint isn't looking | ||||||
|  | 	// for them assume that pre-releases are not compatible. See issue 21 for | ||||||
|  | 	// more details. | ||||||
|  | 	if v.Prerelease() != "" && c.con.Prerelease() == "" { | ||||||
|  | 		return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eq := v.Compare(c.con) >= 0 | ||||||
|  | 	if eq { | ||||||
|  | 		return true, nil | ||||||
|  | 	} | ||||||
|  | 	return false, fmt.Errorf("%s is less than %s", v, c.orig) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func constraintLessThanEqual(v *Version, c *constraint) (bool, error) { | ||||||
|  | 	// If there is a pre-release on the version but the constraint isn't looking | ||||||
|  | 	// for them assume that pre-releases are not compatible. See issue 21 for | ||||||
|  | 	// more details. | ||||||
|  | 	if v.Prerelease() != "" && c.con.Prerelease() == "" { | ||||||
|  | 		return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var eq bool | ||||||
|  |  | ||||||
|  | 	if !c.dirty { | ||||||
|  | 		eq = v.Compare(c.con) <= 0 | ||||||
|  | 		if eq { | ||||||
|  | 			return true, nil | ||||||
|  | 		} | ||||||
|  | 		return false, fmt.Errorf("%s is greater than %s", v, c.orig) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if v.Major() > c.con.Major() { | ||||||
|  | 		return false, fmt.Errorf("%s is greater than %s", v, c.orig) | ||||||
|  | 	} else if v.Major() == c.con.Major() && v.Minor() > c.con.Minor() && !c.minorDirty { | ||||||
|  | 		return false, fmt.Errorf("%s is greater than %s", v, c.orig) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return true, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ~*, ~>* --> >= 0.0.0 (any) | ||||||
|  | // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0, <3.0.0 | ||||||
|  | // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0, <2.1.0 | ||||||
|  | // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0 | ||||||
|  | // ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0 | ||||||
|  | // ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0 | ||||||
|  | func constraintTilde(v *Version, c *constraint) (bool, error) { | ||||||
|  | 	// If there is a pre-release on the version but the constraint isn't looking | ||||||
|  | 	// for them assume that pre-releases are not compatible. See issue 21 for | ||||||
|  | 	// more details. | ||||||
|  | 	if v.Prerelease() != "" && c.con.Prerelease() == "" { | ||||||
|  | 		return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if v.LessThan(c.con) { | ||||||
|  | 		return false, fmt.Errorf("%s is less than %s", v, c.orig) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// ~0.0.0 is a special case where all constraints are accepted. It's | ||||||
|  | 	// equivalent to >= 0.0.0. | ||||||
|  | 	if c.con.Major() == 0 && c.con.Minor() == 0 && c.con.Patch() == 0 && | ||||||
|  | 		!c.minorDirty && !c.patchDirty { | ||||||
|  | 		return true, nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if v.Major() != c.con.Major() { | ||||||
|  | 		return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if v.Minor() != c.con.Minor() && !c.minorDirty { | ||||||
|  | 		return false, fmt.Errorf("%s does not have same major and minor version as %s", v, c.orig) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return true, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // When there is a .x (dirty) status it automatically opts in to ~. Otherwise | ||||||
|  | // it's a straight = | ||||||
|  | func constraintTildeOrEqual(v *Version, c *constraint) (bool, error) { | ||||||
|  | 	// If there is a pre-release on the version but the constraint isn't looking | ||||||
|  | 	// for them assume that pre-releases are not compatible. See issue 21 for | ||||||
|  | 	// more details. | ||||||
|  | 	if v.Prerelease() != "" && c.con.Prerelease() == "" { | ||||||
|  | 		return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if c.dirty { | ||||||
|  | 		return constraintTilde(v, c) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eq := v.Equal(c.con) | ||||||
|  | 	if eq { | ||||||
|  | 		return true, nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return false, fmt.Errorf("%s is not equal to %s", v, c.orig) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ^*      -->  (any) | ||||||
|  | // ^1.2.3  -->  >=1.2.3 <2.0.0 | ||||||
|  | // ^1.2    -->  >=1.2.0 <2.0.0 | ||||||
|  | // ^1      -->  >=1.0.0 <2.0.0 | ||||||
|  | // ^0.2.3  -->  >=0.2.3 <0.3.0 | ||||||
|  | // ^0.2    -->  >=0.2.0 <0.3.0 | ||||||
|  | // ^0.0.3  -->  >=0.0.3 <0.0.4 | ||||||
|  | // ^0.0    -->  >=0.0.0 <0.1.0 | ||||||
|  | // ^0      -->  >=0.0.0 <1.0.0 | ||||||
|  | func constraintCaret(v *Version, c *constraint) (bool, error) { | ||||||
|  | 	// If there is a pre-release on the version but the constraint isn't looking | ||||||
|  | 	// for them assume that pre-releases are not compatible. See issue 21 for | ||||||
|  | 	// more details. | ||||||
|  | 	if v.Prerelease() != "" && c.con.Prerelease() == "" { | ||||||
|  | 		return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// This less than handles prereleases | ||||||
|  | 	if v.LessThan(c.con) { | ||||||
|  | 		return false, fmt.Errorf("%s is less than %s", v, c.orig) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var eq bool | ||||||
|  |  | ||||||
|  | 	// ^ when the major > 0 is >=x.y.z < x+1 | ||||||
|  | 	if c.con.Major() > 0 || c.minorDirty { | ||||||
|  |  | ||||||
|  | 		// ^ has to be within a major range for > 0. Everything less than was | ||||||
|  | 		// filtered out with the LessThan call above. This filters out those | ||||||
|  | 		// that greater but not within the same major range. | ||||||
|  | 		eq = v.Major() == c.con.Major() | ||||||
|  | 		if eq { | ||||||
|  | 			return true, nil | ||||||
|  | 		} | ||||||
|  | 		return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// ^ when the major is 0 and minor > 0 is >=0.y.z < 0.y+1 | ||||||
|  | 	if c.con.Major() == 0 && v.Major() > 0 { | ||||||
|  | 		return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig) | ||||||
|  | 	} | ||||||
|  | 	// If the con Minor is > 0 it is not dirty | ||||||
|  | 	if c.con.Minor() > 0 || c.patchDirty { | ||||||
|  | 		eq = v.Minor() == c.con.Minor() | ||||||
|  | 		if eq { | ||||||
|  | 			return true, nil | ||||||
|  | 		} | ||||||
|  | 		return false, fmt.Errorf("%s does not have same minor version as %s. Expected minor versions to match when constraint major version is 0", v, c.orig) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// At this point the major is 0 and the minor is 0 and not dirty. The patch | ||||||
|  | 	// is not dirty so we need to check if they are equal. If they are not equal | ||||||
|  | 	eq = c.con.Patch() == v.Patch() | ||||||
|  | 	if eq { | ||||||
|  | 		return true, nil | ||||||
|  | 	} | ||||||
|  | 	return false, fmt.Errorf("%s does not equal %s. Expect version and constraint to equal when major and minor versions are 0", v, c.orig) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func isX(x string) bool { | ||||||
|  | 	switch x { | ||||||
|  | 	case "x", "*", "X": | ||||||
|  | 		return true | ||||||
|  | 	default: | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func rewriteRange(i string) string { | ||||||
|  | 	m := constraintRangeRegex.FindAllStringSubmatch(i, -1) | ||||||
|  | 	if m == nil { | ||||||
|  | 		return i | ||||||
|  | 	} | ||||||
|  | 	o := i | ||||||
|  | 	for _, v := range m { | ||||||
|  | 		t := fmt.Sprintf(">= %s, <= %s", v[1], v[11]) | ||||||
|  | 		o = strings.Replace(o, v[0], t, 1) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return o | ||||||
|  | } | ||||||
							
								
								
									
										184
									
								
								vendor/github.com/Masterminds/semver/v3/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								vendor/github.com/Masterminds/semver/v3/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,184 @@ | |||||||
|  | /* | ||||||
|  | Package semver provides the ability to work with Semantic Versions (http://semver.org) in Go. | ||||||
|  |  | ||||||
|  | Specifically it provides the ability to: | ||||||
|  |  | ||||||
|  |     * Parse semantic versions | ||||||
|  |     * Sort semantic versions | ||||||
|  |     * Check if a semantic version fits within a set of constraints | ||||||
|  |     * Optionally work with a `v` prefix | ||||||
|  |  | ||||||
|  | Parsing Semantic Versions | ||||||
|  |  | ||||||
|  | There are two functions that can parse semantic versions. The `StrictNewVersion` | ||||||
|  | function only parses valid version 2 semantic versions as outlined in the | ||||||
|  | specification. The `NewVersion` function attempts to coerce a version into a | ||||||
|  | semantic version and parse it. For example, if there is a leading v or a version | ||||||
|  | listed without all 3 parts (e.g. 1.2) it will attempt to coerce it into a valid | ||||||
|  | semantic version (e.g., 1.2.0). In both cases a `Version` object is returned | ||||||
|  | that can be sorted, compared, and used in constraints. | ||||||
|  |  | ||||||
|  | When parsing a version an optional error can be returned if there is an issue | ||||||
|  | parsing the version. For example, | ||||||
|  |  | ||||||
|  |     v, err := semver.NewVersion("1.2.3-beta.1+b345") | ||||||
|  |  | ||||||
|  | The version object has methods to get the parts of the version, compare it to | ||||||
|  | other versions, convert the version back into a string, and get the original | ||||||
|  | string. For more details please see the documentation | ||||||
|  | at https://godoc.org/github.com/Masterminds/semver. | ||||||
|  |  | ||||||
|  | Sorting Semantic Versions | ||||||
|  |  | ||||||
|  | A set of versions can be sorted using the `sort` package from the standard library. | ||||||
|  | For example, | ||||||
|  |  | ||||||
|  |     raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} | ||||||
|  |     vs := make([]*semver.Version, len(raw)) | ||||||
|  | 	for i, r := range raw { | ||||||
|  | 		v, err := semver.NewVersion(r) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Errorf("Error parsing version: %s", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		vs[i] = v | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	sort.Sort(semver.Collection(vs)) | ||||||
|  |  | ||||||
|  | Checking Version Constraints and Comparing Versions | ||||||
|  |  | ||||||
|  | There are two methods for comparing versions. One uses comparison methods on | ||||||
|  | `Version` instances and the other is using Constraints. There are some important | ||||||
|  | differences to notes between these two methods of comparison. | ||||||
|  |  | ||||||
|  | 1. When two versions are compared using functions such as `Compare`, `LessThan`, | ||||||
|  |    and others it will follow the specification and always include prereleases | ||||||
|  |    within the comparison. It will provide an answer valid with the comparison | ||||||
|  |    spec section at https://semver.org/#spec-item-11 | ||||||
|  | 2. When constraint checking is used for checks or validation it will follow a | ||||||
|  |    different set of rules that are common for ranges with tools like npm/js | ||||||
|  |    and Rust/Cargo. This includes considering prereleases to be invalid if the | ||||||
|  |    ranges does not include on. If you want to have it include pre-releases a | ||||||
|  |    simple solution is to include `-0` in your range. | ||||||
|  | 3. Constraint ranges can have some complex rules including the shorthard use of | ||||||
|  |    ~ and ^. For more details on those see the options below. | ||||||
|  |  | ||||||
|  | There are differences between the two methods or checking versions because the | ||||||
|  | comparison methods on `Version` follow the specification while comparison ranges | ||||||
|  | are not part of the specification. Different packages and tools have taken it | ||||||
|  | upon themselves to come up with range rules. This has resulted in differences. | ||||||
|  | For example, npm/js and Cargo/Rust follow similar patterns which PHP has a | ||||||
|  | different pattern for ^. The comparison features in this package follow the | ||||||
|  | npm/js and Cargo/Rust lead because applications using it have followed similar | ||||||
|  | patters with their versions. | ||||||
|  |  | ||||||
|  | Checking a version against version constraints is one of the most featureful | ||||||
|  | parts of the package. | ||||||
|  |  | ||||||
|  |     c, err := semver.NewConstraint(">= 1.2.3") | ||||||
|  |     if err != nil { | ||||||
|  |         // Handle constraint not being parsable. | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     v, err := semver.NewVersion("1.3") | ||||||
|  |     if err != nil { | ||||||
|  |         // Handle version not being parsable. | ||||||
|  |     } | ||||||
|  |     // Check if the version meets the constraints. The a variable will be true. | ||||||
|  |     a := c.Check(v) | ||||||
|  |  | ||||||
|  | Basic Comparisons | ||||||
|  |  | ||||||
|  | There are two elements to the comparisons. First, a comparison string is a list | ||||||
|  | of comma or space separated AND comparisons. These are then separated by || (OR) | ||||||
|  | comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a | ||||||
|  | comparison that's greater than or equal to 1.2 and less than 3.0.0 or is | ||||||
|  | greater than or equal to 4.2.3. This can also be written as | ||||||
|  | `">= 1.2, < 3.0.0 || >= 4.2.3"` | ||||||
|  |  | ||||||
|  | The basic comparisons are: | ||||||
|  |  | ||||||
|  |     * `=`: equal (aliased to no operator) | ||||||
|  |     * `!=`: not equal | ||||||
|  |     * `>`: greater than | ||||||
|  |     * `<`: less than | ||||||
|  |     * `>=`: greater than or equal to | ||||||
|  |     * `<=`: less than or equal to | ||||||
|  |  | ||||||
|  | Hyphen Range Comparisons | ||||||
|  |  | ||||||
|  | There are multiple methods to handle ranges and the first is hyphens ranges. | ||||||
|  | These look like: | ||||||
|  |  | ||||||
|  |     * `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5` | ||||||
|  |     * `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` | ||||||
|  |  | ||||||
|  | Wildcards In Comparisons | ||||||
|  |  | ||||||
|  | The `x`, `X`, and `*` characters can be used as a wildcard character. This works | ||||||
|  | for all comparison operators. When used on the `=` operator it falls | ||||||
|  | back to the tilde operation. For example, | ||||||
|  |  | ||||||
|  |     * `1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` | ||||||
|  |     * `>= 1.2.x` is equivalent to `>= 1.2.0` | ||||||
|  |     * `<= 2.x` is equivalent to `<= 3` | ||||||
|  |     * `*` is equivalent to `>= 0.0.0` | ||||||
|  |  | ||||||
|  | Tilde Range Comparisons (Patch) | ||||||
|  |  | ||||||
|  | The tilde (`~`) comparison operator is for patch level ranges when a minor | ||||||
|  | version is specified and major level changes when the minor number is missing. | ||||||
|  | For example, | ||||||
|  |  | ||||||
|  |     * `~1.2.3` is equivalent to `>= 1.2.3 < 1.3.0` | ||||||
|  |     * `~1` is equivalent to `>= 1, < 2` | ||||||
|  |     * `~2.3` is equivalent to `>= 2.3 < 2.4` | ||||||
|  |     * `~1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` | ||||||
|  |     * `~1.x` is equivalent to `>= 1 < 2` | ||||||
|  |  | ||||||
|  | Caret Range Comparisons (Major) | ||||||
|  |  | ||||||
|  | The caret (`^`) comparison operator is for major level changes once a stable | ||||||
|  | (1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts | ||||||
|  | as the API stability level. This is useful when comparisons of API versions as a | ||||||
|  | major change is API breaking. For example, | ||||||
|  |  | ||||||
|  |     * `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` | ||||||
|  |     * `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` | ||||||
|  |     * `^2.3` is equivalent to `>= 2.3, < 3` | ||||||
|  |     * `^2.x` is equivalent to `>= 2.0.0, < 3` | ||||||
|  |     * `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` | ||||||
|  |     * `^0.2` is equivalent to `>=0.2.0 <0.3.0` | ||||||
|  |     * `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` | ||||||
|  |     * `^0.0` is equivalent to `>=0.0.0 <0.1.0` | ||||||
|  |     * `^0` is equivalent to `>=0.0.0 <1.0.0` | ||||||
|  |  | ||||||
|  | Validation | ||||||
|  |  | ||||||
|  | In addition to testing a version against a constraint, a version can be validated | ||||||
|  | against a constraint. When validation fails a slice of errors containing why a | ||||||
|  | version didn't meet the constraint is returned. For example, | ||||||
|  |  | ||||||
|  |     c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") | ||||||
|  |     if err != nil { | ||||||
|  |         // Handle constraint not being parseable. | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     v, _ := semver.NewVersion("1.3") | ||||||
|  |     if err != nil { | ||||||
|  |         // Handle version not being parseable. | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Validate a version against a constraint. | ||||||
|  |     a, msgs := c.Validate(v) | ||||||
|  |     // a is false | ||||||
|  |     for _, m := range msgs { | ||||||
|  |         fmt.Println(m) | ||||||
|  |  | ||||||
|  |         // Loops over the errors which would read | ||||||
|  |         // "1.3 is greater than 1.2.3" | ||||||
|  |         // "1.3 is less than 1.4" | ||||||
|  |     } | ||||||
|  | */ | ||||||
|  | package semver | ||||||
							
								
								
									
										22
									
								
								vendor/github.com/Masterminds/semver/v3/fuzz.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/Masterminds/semver/v3/fuzz.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | // +build gofuzz | ||||||
|  |  | ||||||
|  | package semver | ||||||
|  |  | ||||||
|  | func Fuzz(data []byte) int { | ||||||
|  | 	d := string(data) | ||||||
|  |  | ||||||
|  | 	// Test NewVersion | ||||||
|  | 	_, _ = NewVersion(d) | ||||||
|  |  | ||||||
|  | 	// Test StrictNewVersion | ||||||
|  | 	_, _ = StrictNewVersion(d) | ||||||
|  |  | ||||||
|  | 	// Test NewConstraint | ||||||
|  | 	_, _ = NewConstraint(d) | ||||||
|  |  | ||||||
|  | 	// The return value should be 0 normally, 1 if the priority in future tests | ||||||
|  | 	// should be increased, and -1 if future tests should skip passing in that | ||||||
|  | 	// data. We do not have a reason to change priority so 0 is always returned. | ||||||
|  | 	// There are example tests that do this. | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
| @@ -2,6 +2,7 @@ package semver | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
|  | 	"database/sql/driver" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| @@ -13,13 +14,23 @@ import ( | |||||||
| // The compiled version of the regex created at init() is cached here so it | // The compiled version of the regex created at init() is cached here so it | ||||||
| // only needs to be created once. | // only needs to be created once. | ||||||
| var versionRegex *regexp.Regexp | var versionRegex *regexp.Regexp | ||||||
| var validPrereleaseRegex *regexp.Regexp |  | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
| 	// ErrInvalidSemVer is returned a version is found to be invalid when | 	// ErrInvalidSemVer is returned a version is found to be invalid when | ||||||
| 	// being parsed. | 	// being parsed. | ||||||
| 	ErrInvalidSemVer = errors.New("Invalid Semantic Version") | 	ErrInvalidSemVer = errors.New("Invalid Semantic Version") | ||||||
| 
 | 
 | ||||||
|  | 	// ErrEmptyString is returned when an empty string is passed in for parsing. | ||||||
|  | 	ErrEmptyString = errors.New("Version string empty") | ||||||
|  | 
 | ||||||
|  | 	// ErrInvalidCharacters is returned when invalid characters are found as | ||||||
|  | 	// part of a version | ||||||
|  | 	ErrInvalidCharacters = errors.New("Invalid characters in version") | ||||||
|  | 
 | ||||||
|  | 	// ErrSegmentStartsZero is returned when a version segment starts with 0. | ||||||
|  | 	// This is invalid in SemVer. | ||||||
|  | 	ErrSegmentStartsZero = errors.New("Version segment starts with 0") | ||||||
|  | 
 | ||||||
| 	// ErrInvalidMetadata is returned when the metadata is an invalid format | 	// ErrInvalidMetadata is returned when the metadata is an invalid format | ||||||
| 	ErrInvalidMetadata = errors.New("Invalid Metadata string") | 	ErrInvalidMetadata = errors.New("Invalid Metadata string") | ||||||
| 
 | 
 | ||||||
| @@ -27,30 +38,121 @@ var ( | |||||||
| 	ErrInvalidPrerelease = errors.New("Invalid Prerelease string") | 	ErrInvalidPrerelease = errors.New("Invalid Prerelease string") | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // SemVerRegex is the regular expression used to parse a semantic version. | // semVerRegex is the regular expression used to parse a semantic version. | ||||||
| const SemVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` + | const semVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` + | ||||||
| 	`(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + | 	`(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + | ||||||
| 	`(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` | 	`(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` | ||||||
| 
 | 
 | ||||||
| // ValidPrerelease is the regular expression which validates |  | ||||||
| // both prerelease and metadata values. |  | ||||||
| const ValidPrerelease string = `^([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*)$` |  | ||||||
| 
 |  | ||||||
| // Version represents a single semantic version. | // Version represents a single semantic version. | ||||||
| type Version struct { | type Version struct { | ||||||
| 	major, minor, patch int64 | 	major, minor, patch uint64 | ||||||
| 	pre                 string | 	pre                 string | ||||||
| 	metadata            string | 	metadata            string | ||||||
| 	original            string | 	original            string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	versionRegex = regexp.MustCompile("^" + SemVerRegex + "$") | 	versionRegex = regexp.MustCompile("^" + semVerRegex + "$") | ||||||
| 	validPrereleaseRegex = regexp.MustCompile(ValidPrerelease) | } | ||||||
|  | 
 | ||||||
|  | const num string = "0123456789" | ||||||
|  | const allowed string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" + num | ||||||
|  | 
 | ||||||
|  | // StrictNewVersion parses a given version and returns an instance of Version or | ||||||
|  | // an error if unable to parse the version. Only parses valid semantic versions. | ||||||
|  | // Performs checking that can find errors within the version. | ||||||
|  | // If you want to coerce a version, such as 1 or 1.2, and perse that as the 1.x | ||||||
|  | // releases of semver provided use the NewSemver() function. | ||||||
|  | func StrictNewVersion(v string) (*Version, error) { | ||||||
|  | 	// Parsing here does not use RegEx in order to increase performance and reduce | ||||||
|  | 	// allocations. | ||||||
|  | 
 | ||||||
|  | 	if len(v) == 0 { | ||||||
|  | 		return nil, ErrEmptyString | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Split the parts into [0]major, [1]minor, and [2]patch,prerelease,build | ||||||
|  | 	parts := strings.SplitN(v, ".", 3) | ||||||
|  | 	if len(parts) != 3 { | ||||||
|  | 		return nil, ErrInvalidSemVer | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	sv := &Version{ | ||||||
|  | 		original: v, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// check for prerelease or build metadata | ||||||
|  | 	var extra []string | ||||||
|  | 	if strings.ContainsAny(parts[2], "-+") { | ||||||
|  | 		// Start with the build metadata first as it needs to be on the right | ||||||
|  | 		extra = strings.SplitN(parts[2], "+", 2) | ||||||
|  | 		if len(extra) > 1 { | ||||||
|  | 			// build metadata found | ||||||
|  | 			sv.metadata = extra[1] | ||||||
|  | 			parts[2] = extra[0] | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		extra = strings.SplitN(parts[2], "-", 2) | ||||||
|  | 		if len(extra) > 1 { | ||||||
|  | 			// prerelease found | ||||||
|  | 			sv.pre = extra[1] | ||||||
|  | 			parts[2] = extra[0] | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Validate the number segments are valid. This includes only having positive | ||||||
|  | 	// numbers and no leading 0's. | ||||||
|  | 	for _, p := range parts { | ||||||
|  | 		if !containsOnly(p, num) { | ||||||
|  | 			return nil, ErrInvalidCharacters | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if len(p) > 1 && p[0] == '0' { | ||||||
|  | 			return nil, ErrSegmentStartsZero | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Extract the major, minor, and patch elements onto the returned Version | ||||||
|  | 	var err error | ||||||
|  | 	sv.major, err = strconv.ParseUint(parts[0], 10, 64) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	sv.minor, err = strconv.ParseUint(parts[1], 10, 64) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	sv.patch, err = strconv.ParseUint(parts[2], 10, 64) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// No prerelease or build metadata found so returning now as a fastpath. | ||||||
|  | 	if sv.pre == "" && sv.metadata == "" { | ||||||
|  | 		return sv, nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if sv.pre != "" { | ||||||
|  | 		if err = validatePrerelease(sv.pre); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if sv.metadata != "" { | ||||||
|  | 		if err = validateMetadata(sv.metadata); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return sv, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NewVersion parses a given version and returns an instance of Version or | // NewVersion parses a given version and returns an instance of Version or | ||||||
| // an error if unable to parse the version. | // an error if unable to parse the version. If the version is SemVer-ish it | ||||||
|  | // attempts to convert it to SemVer. If you want  to validate it was a strict | ||||||
|  | // semantic version at parse time see StrictNewVersion(). | ||||||
| func NewVersion(v string) (*Version, error) { | func NewVersion(v string) (*Version, error) { | ||||||
| 	m := versionRegex.FindStringSubmatch(v) | 	m := versionRegex.FindStringSubmatch(v) | ||||||
| 	if m == nil { | 	if m == nil { | ||||||
| @@ -63,33 +165,45 @@ func NewVersion(v string) (*Version, error) { | |||||||
| 		original: v, | 		original: v, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var temp int64 | 	var err error | ||||||
| 	temp, err := strconv.ParseInt(m[1], 10, 64) | 	sv.major, err = strconv.ParseUint(m[1], 10, 64) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, fmt.Errorf("Error parsing version segment: %s", err) | 		return nil, fmt.Errorf("Error parsing version segment: %s", err) | ||||||
| 	} | 	} | ||||||
| 	sv.major = temp |  | ||||||
| 
 | 
 | ||||||
| 	if m[2] != "" { | 	if m[2] != "" { | ||||||
| 		temp, err = strconv.ParseInt(strings.TrimPrefix(m[2], "."), 10, 64) | 		sv.minor, err = strconv.ParseUint(strings.TrimPrefix(m[2], "."), 10, 64) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, fmt.Errorf("Error parsing version segment: %s", err) | 			return nil, fmt.Errorf("Error parsing version segment: %s", err) | ||||||
| 		} | 		} | ||||||
| 		sv.minor = temp |  | ||||||
| 	} else { | 	} else { | ||||||
| 		sv.minor = 0 | 		sv.minor = 0 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if m[3] != "" { | 	if m[3] != "" { | ||||||
| 		temp, err = strconv.ParseInt(strings.TrimPrefix(m[3], "."), 10, 64) | 		sv.patch, err = strconv.ParseUint(strings.TrimPrefix(m[3], "."), 10, 64) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, fmt.Errorf("Error parsing version segment: %s", err) | 			return nil, fmt.Errorf("Error parsing version segment: %s", err) | ||||||
| 		} | 		} | ||||||
| 		sv.patch = temp |  | ||||||
| 	} else { | 	} else { | ||||||
| 		sv.patch = 0 | 		sv.patch = 0 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// Perform some basic due diligence on the extra parts to ensure they are | ||||||
|  | 	// valid. | ||||||
|  | 
 | ||||||
|  | 	if sv.pre != "" { | ||||||
|  | 		if err = validatePrerelease(sv.pre); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if sv.metadata != "" { | ||||||
|  | 		if err = validateMetadata(sv.metadata); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return sv, nil | 	return sv, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -107,7 +221,7 @@ func MustParse(v string) *Version { | |||||||
| // See the Original() method to retrieve the original value. Semantic Versions | // See the Original() method to retrieve the original value. Semantic Versions | ||||||
| // don't contain a leading v per the spec. Instead it's optional on | // don't contain a leading v per the spec. Instead it's optional on | ||||||
| // implementation. | // implementation. | ||||||
| func (v *Version) String() string { | func (v Version) String() string { | ||||||
| 	var buf bytes.Buffer | 	var buf bytes.Buffer | ||||||
| 
 | 
 | ||||||
| 	fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch) | 	fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch) | ||||||
| @@ -127,32 +241,32 @@ func (v *Version) Original() string { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Major returns the major version. | // Major returns the major version. | ||||||
| func (v *Version) Major() int64 { | func (v Version) Major() uint64 { | ||||||
| 	return v.major | 	return v.major | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Minor returns the minor version. | // Minor returns the minor version. | ||||||
| func (v *Version) Minor() int64 { | func (v Version) Minor() uint64 { | ||||||
| 	return v.minor | 	return v.minor | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Patch returns the patch version. | // Patch returns the patch version. | ||||||
| func (v *Version) Patch() int64 { | func (v Version) Patch() uint64 { | ||||||
| 	return v.patch | 	return v.patch | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Prerelease returns the pre-release version. | // Prerelease returns the pre-release version. | ||||||
| func (v *Version) Prerelease() string { | func (v Version) Prerelease() string { | ||||||
| 	return v.pre | 	return v.pre | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Metadata returns the metadata on the version. | // Metadata returns the metadata on the version. | ||||||
| func (v *Version) Metadata() string { | func (v Version) Metadata() string { | ||||||
| 	return v.metadata | 	return v.metadata | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // originalVPrefix returns the original 'v' prefix if any. | // originalVPrefix returns the original 'v' prefix if any. | ||||||
| func (v *Version) originalVPrefix() string { | func (v Version) originalVPrefix() string { | ||||||
| 
 | 
 | ||||||
| 	// Note, only lowercase v is supported as a prefix by the parser. | 	// Note, only lowercase v is supported as a prefix by the parser. | ||||||
| 	if v.original != "" && v.original[:1] == "v" { | 	if v.original != "" && v.original[:1] == "v" { | ||||||
| @@ -165,7 +279,7 @@ func (v *Version) originalVPrefix() string { | |||||||
| // If the current version does not have prerelease/metadata information, | // If the current version does not have prerelease/metadata information, | ||||||
| // it unsets metadata and prerelease values, increments patch number. | // it unsets metadata and prerelease values, increments patch number. | ||||||
| // If the current version has any of prerelease or metadata information, | // If the current version has any of prerelease or metadata information, | ||||||
| // it unsets both values and keeps curent patch value | // it unsets both values and keeps current patch value | ||||||
| func (v Version) IncPatch() Version { | func (v Version) IncPatch() Version { | ||||||
| 	vNext := v | 	vNext := v | ||||||
| 	// according to http://semver.org/#spec-item-9 | 	// according to http://semver.org/#spec-item-9 | ||||||
| @@ -217,11 +331,13 @@ func (v Version) IncMajor() Version { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SetPrerelease defines the prerelease value. | // SetPrerelease defines the prerelease value. | ||||||
| // Value must not include the required 'hypen' prefix. | // Value must not include the required 'hyphen' prefix. | ||||||
| func (v Version) SetPrerelease(prerelease string) (Version, error) { | func (v Version) SetPrerelease(prerelease string) (Version, error) { | ||||||
| 	vNext := v | 	vNext := v | ||||||
| 	if len(prerelease) > 0 && !validPrereleaseRegex.MatchString(prerelease) { | 	if len(prerelease) > 0 { | ||||||
| 		return vNext, ErrInvalidPrerelease | 		if err := validatePrerelease(prerelease); err != nil { | ||||||
|  | 			return vNext, err | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	vNext.pre = prerelease | 	vNext.pre = prerelease | ||||||
| 	vNext.original = v.originalVPrefix() + "" + vNext.String() | 	vNext.original = v.originalVPrefix() + "" + vNext.String() | ||||||
| @@ -232,8 +348,10 @@ func (v Version) SetPrerelease(prerelease string) (Version, error) { | |||||||
| // Value must not include the required 'plus' prefix. | // Value must not include the required 'plus' prefix. | ||||||
| func (v Version) SetMetadata(metadata string) (Version, error) { | func (v Version) SetMetadata(metadata string) (Version, error) { | ||||||
| 	vNext := v | 	vNext := v | ||||||
| 	if len(metadata) > 0 && !validPrereleaseRegex.MatchString(metadata) { | 	if len(metadata) > 0 { | ||||||
| 		return vNext, ErrInvalidMetadata | 		if err := validateMetadata(metadata); err != nil { | ||||||
|  | 			return vNext, err | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	vNext.metadata = metadata | 	vNext.metadata = metadata | ||||||
| 	vNext.original = v.originalVPrefix() + "" + vNext.String() | 	vNext.original = v.originalVPrefix() + "" + vNext.String() | ||||||
| @@ -261,7 +379,9 @@ func (v *Version) Equal(o *Version) bool { | |||||||
| // the version smaller, equal, or larger than the other version. | // the version smaller, equal, or larger than the other version. | ||||||
| // | // | ||||||
| // Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is | // Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is | ||||||
| // lower than the version without a prerelease. | // lower than the version without a prerelease. Compare always takes into account | ||||||
|  | // prereleases. If you want to work with ranges using typical range syntaxes that | ||||||
|  | // skip prereleases if the range is not looking for them use constraints. | ||||||
| func (v *Version) Compare(o *Version) int { | func (v *Version) Compare(o *Version) int { | ||||||
| 	// Compare the major, minor, and patch version for differences. If a | 	// Compare the major, minor, and patch version for differences. If a | ||||||
| 	// difference is found return the comparison. | 	// difference is found return the comparison. | ||||||
| @@ -308,16 +428,37 @@ func (v *Version) UnmarshalJSON(b []byte) error { | |||||||
| 	v.pre = temp.pre | 	v.pre = temp.pre | ||||||
| 	v.metadata = temp.metadata | 	v.metadata = temp.metadata | ||||||
| 	v.original = temp.original | 	v.original = temp.original | ||||||
| 	temp = nil |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // MarshalJSON implements JSON.Marshaler interface. | // MarshalJSON implements JSON.Marshaler interface. | ||||||
| func (v *Version) MarshalJSON() ([]byte, error) { | func (v Version) MarshalJSON() ([]byte, error) { | ||||||
| 	return json.Marshal(v.String()) | 	return json.Marshal(v.String()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func compareSegment(v, o int64) int { | // Scan implements the SQL.Scanner interface. | ||||||
|  | func (v *Version) Scan(value interface{}) error { | ||||||
|  | 	var s string | ||||||
|  | 	s, _ = value.(string) | ||||||
|  | 	temp, err := NewVersion(s) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	v.major = temp.major | ||||||
|  | 	v.minor = temp.minor | ||||||
|  | 	v.patch = temp.patch | ||||||
|  | 	v.pre = temp.pre | ||||||
|  | 	v.metadata = temp.metadata | ||||||
|  | 	v.original = temp.original | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Value implements the Driver.Valuer interface. | ||||||
|  | func (v Version) Value() (driver.Value, error) { | ||||||
|  | 	return v.String(), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func compareSegment(v, o uint64) int { | ||||||
| 	if v < o { | 	if v < o { | ||||||
| 		return -1 | 		return -1 | ||||||
| 	} | 	} | ||||||
| @@ -423,3 +564,43 @@ func comparePrePart(s, o string) int { | |||||||
| 	return -1 | 	return -1 | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // Like strings.ContainsAny but does an only instead of any. | ||||||
|  | func containsOnly(s string, comp string) bool { | ||||||
|  | 	return strings.IndexFunc(s, func(r rune) bool { | ||||||
|  | 		return !strings.ContainsRune(comp, r) | ||||||
|  | 	}) == -1 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // From the spec, "Identifiers MUST comprise only | ||||||
|  | // ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. | ||||||
|  | // Numeric identifiers MUST NOT include leading zeroes.". These segments can | ||||||
|  | // be dot separated. | ||||||
|  | func validatePrerelease(p string) error { | ||||||
|  | 	eparts := strings.Split(p, ".") | ||||||
|  | 	for _, p := range eparts { | ||||||
|  | 		if containsOnly(p, num) { | ||||||
|  | 			if len(p) > 1 && p[0] == '0' { | ||||||
|  | 				return ErrSegmentStartsZero | ||||||
|  | 			} | ||||||
|  | 		} else if !containsOnly(p, allowed) { | ||||||
|  | 			return ErrInvalidPrerelease | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // From the spec, "Build metadata MAY be denoted by | ||||||
|  | // appending a plus sign and a series of dot separated identifiers immediately | ||||||
|  | // following the patch or pre-release version. Identifiers MUST comprise only | ||||||
|  | // ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty." | ||||||
|  | func validateMetadata(m string) error { | ||||||
|  | 	eparts := strings.Split(m, ".") | ||||||
|  | 	for _, p := range eparts { | ||||||
|  | 		if !containsOnly(p, allowed) { | ||||||
|  | 			return ErrInvalidMetadata | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										10
									
								
								vendor/github.com/Masterminds/semver/version_fuzz.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/Masterminds/semver/version_fuzz.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,10 +0,0 @@ | |||||||
| // +build gofuzz |  | ||||||
|  |  | ||||||
| package semver |  | ||||||
|  |  | ||||||
| func Fuzz(data []byte) int { |  | ||||||
| 	if _, err := NewVersion(string(data)); err != nil { |  | ||||||
| 		return 0 |  | ||||||
| 	} |  | ||||||
| 	return 1 |  | ||||||
| } |  | ||||||
							
								
								
									
										26
									
								
								vendor/github.com/Masterminds/sprig/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/Masterminds/sprig/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,26 +0,0 @@ | |||||||
| language: go |  | ||||||
|  |  | ||||||
| go: |  | ||||||
|   - 1.9.x |  | ||||||
|   - 1.10.x |  | ||||||
|   - 1.11.x |  | ||||||
|   - 1.12.x |  | ||||||
|   - 1.13.x |  | ||||||
|   - tip |  | ||||||
|  |  | ||||||
| # Setting sudo access to false will let Travis CI use containers rather than |  | ||||||
| # VMs to run the tests. For more details see: |  | ||||||
| # - http://docs.travis-ci.com/user/workers/container-based-infrastructure/ |  | ||||||
| # - http://docs.travis-ci.com/user/workers/standard-infrastructure/ |  | ||||||
| sudo: false |  | ||||||
|  |  | ||||||
| script: |  | ||||||
|   - make setup test |  | ||||||
|  |  | ||||||
| notifications: |  | ||||||
|   webhooks: |  | ||||||
|     urls: |  | ||||||
|       - https://webhooks.gitter.im/e/06e3328629952dabe3e0 |  | ||||||
|     on_success: change  # options: [always|never|change] default: always |  | ||||||
|     on_failure: always  # options: [always|never|change] default: always |  | ||||||
|     on_start: never     # options: [always|never|change] default: always |  | ||||||
							
								
								
									
										13
									
								
								vendor/github.com/Masterminds/sprig/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/Masterminds/sprig/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,13 +0,0 @@ | |||||||
|  |  | ||||||
| HAS_GLIDE := $(shell command -v glide;) |  | ||||||
|  |  | ||||||
| .PHONY: test |  | ||||||
| test: |  | ||||||
| 	go test -v . |  | ||||||
|  |  | ||||||
| .PHONY: setup |  | ||||||
| setup: |  | ||||||
| ifndef HAS_GLIDE |  | ||||||
| 	go get -u github.com/Masterminds/glide |  | ||||||
| endif |  | ||||||
| 	glide install |  | ||||||
							
								
								
									
										26
									
								
								vendor/github.com/Masterminds/sprig/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/Masterminds/sprig/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,26 +0,0 @@ | |||||||
|  |  | ||||||
| version: build-{build}.{branch} |  | ||||||
|  |  | ||||||
| clone_folder: C:\gopath\src\github.com\Masterminds\sprig |  | ||||||
| shallow_clone: true |  | ||||||
|  |  | ||||||
| environment: |  | ||||||
|   GOPATH: C:\gopath |  | ||||||
|  |  | ||||||
| platform: |  | ||||||
|   - x64 |  | ||||||
|  |  | ||||||
| install: |  | ||||||
|   - go get -u github.com/Masterminds/glide |  | ||||||
|   - set PATH=%GOPATH%\bin;%PATH% |  | ||||||
|   - go version |  | ||||||
|   - go env |  | ||||||
|  |  | ||||||
| build_script: |  | ||||||
|   - glide install |  | ||||||
|   - go install ./... |  | ||||||
|  |  | ||||||
| test_script: |  | ||||||
|   - go test -v |  | ||||||
|  |  | ||||||
| deploy: off |  | ||||||
							
								
								
									
										19
									
								
								vendor/github.com/Masterminds/sprig/glide.yaml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/Masterminds/sprig/glide.yaml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,19 +0,0 @@ | |||||||
| package: github.com/Masterminds/sprig |  | ||||||
| import: |  | ||||||
| - package: github.com/Masterminds/goutils |  | ||||||
|   version: ^1.0.0 |  | ||||||
| - package: github.com/google/uuid |  | ||||||
|   version: ^1.0.0 |  | ||||||
| - package: golang.org/x/crypto |  | ||||||
|   subpackages: |  | ||||||
|   - scrypt |  | ||||||
| - package: github.com/Masterminds/semver |  | ||||||
|   version: ^v1.2.2 |  | ||||||
| - package: github.com/stretchr/testify |  | ||||||
|   version: ^v1.2.2 |  | ||||||
| - package: github.com/imdario/mergo |  | ||||||
|   version: ~0.3.7 |  | ||||||
| - package: github.com/huandu/xstrings |  | ||||||
|   version: ^1.2 |  | ||||||
| - package: github.com/mitchellh/copystructure |  | ||||||
|   version: ^1.0.0 |  | ||||||
							
								
								
									
										169
									
								
								vendor/github.com/Masterminds/sprig/numeric.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										169
									
								
								vendor/github.com/Masterminds/sprig/numeric.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,169 +0,0 @@ | |||||||
| package sprig |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"fmt" |  | ||||||
| 	"math" |  | ||||||
| 	"reflect" |  | ||||||
| 	"strconv" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // toFloat64 converts 64-bit floats |  | ||||||
| func toFloat64(v interface{}) float64 { |  | ||||||
| 	if str, ok := v.(string); ok { |  | ||||||
| 		iv, err := strconv.ParseFloat(str, 64) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0 |  | ||||||
| 		} |  | ||||||
| 		return iv |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	val := reflect.Indirect(reflect.ValueOf(v)) |  | ||||||
| 	switch val.Kind() { |  | ||||||
| 	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: |  | ||||||
| 		return float64(val.Int()) |  | ||||||
| 	case reflect.Uint8, reflect.Uint16, reflect.Uint32: |  | ||||||
| 		return float64(val.Uint()) |  | ||||||
| 	case reflect.Uint, reflect.Uint64: |  | ||||||
| 		return float64(val.Uint()) |  | ||||||
| 	case reflect.Float32, reflect.Float64: |  | ||||||
| 		return val.Float() |  | ||||||
| 	case reflect.Bool: |  | ||||||
| 		if val.Bool() == true { |  | ||||||
| 			return 1 |  | ||||||
| 		} |  | ||||||
| 		return 0 |  | ||||||
| 	default: |  | ||||||
| 		return 0 |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func toInt(v interface{}) int { |  | ||||||
| 	//It's not optimal. Bud I don't want duplicate toInt64 code. |  | ||||||
| 	return int(toInt64(v)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // toInt64 converts integer types to 64-bit integers |  | ||||||
| func toInt64(v interface{}) int64 { |  | ||||||
| 	if str, ok := v.(string); ok { |  | ||||||
| 		iv, err := strconv.ParseInt(str, 10, 64) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0 |  | ||||||
| 		} |  | ||||||
| 		return iv |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	val := reflect.Indirect(reflect.ValueOf(v)) |  | ||||||
| 	switch val.Kind() { |  | ||||||
| 	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: |  | ||||||
| 		return val.Int() |  | ||||||
| 	case reflect.Uint8, reflect.Uint16, reflect.Uint32: |  | ||||||
| 		return int64(val.Uint()) |  | ||||||
| 	case reflect.Uint, reflect.Uint64: |  | ||||||
| 		tv := val.Uint() |  | ||||||
| 		if tv <= math.MaxInt64 { |  | ||||||
| 			return int64(tv) |  | ||||||
| 		} |  | ||||||
| 		// TODO: What is the sensible thing to do here? |  | ||||||
| 		return math.MaxInt64 |  | ||||||
| 	case reflect.Float32, reflect.Float64: |  | ||||||
| 		return int64(val.Float()) |  | ||||||
| 	case reflect.Bool: |  | ||||||
| 		if val.Bool() == true { |  | ||||||
| 			return 1 |  | ||||||
| 		} |  | ||||||
| 		return 0 |  | ||||||
| 	default: |  | ||||||
| 		return 0 |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func max(a interface{}, i ...interface{}) int64 { |  | ||||||
| 	aa := toInt64(a) |  | ||||||
| 	for _, b := range i { |  | ||||||
| 		bb := toInt64(b) |  | ||||||
| 		if bb > aa { |  | ||||||
| 			aa = bb |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return aa |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func min(a interface{}, i ...interface{}) int64 { |  | ||||||
| 	aa := toInt64(a) |  | ||||||
| 	for _, b := range i { |  | ||||||
| 		bb := toInt64(b) |  | ||||||
| 		if bb < aa { |  | ||||||
| 			aa = bb |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return aa |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func until(count int) []int { |  | ||||||
| 	step := 1 |  | ||||||
| 	if count < 0 { |  | ||||||
| 		step = -1 |  | ||||||
| 	} |  | ||||||
| 	return untilStep(0, count, step) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func untilStep(start, stop, step int) []int { |  | ||||||
| 	v := []int{} |  | ||||||
|  |  | ||||||
| 	if stop < start { |  | ||||||
| 		if step >= 0 { |  | ||||||
| 			return v |  | ||||||
| 		} |  | ||||||
| 		for i := start; i > stop; i += step { |  | ||||||
| 			v = append(v, i) |  | ||||||
| 		} |  | ||||||
| 		return v |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if step <= 0 { |  | ||||||
| 		return v |  | ||||||
| 	} |  | ||||||
| 	for i := start; i < stop; i += step { |  | ||||||
| 		v = append(v, i) |  | ||||||
| 	} |  | ||||||
| 	return v |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func floor(a interface{}) float64 { |  | ||||||
| 	aa := toFloat64(a) |  | ||||||
| 	return math.Floor(aa) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func ceil(a interface{}) float64 { |  | ||||||
| 	aa := toFloat64(a) |  | ||||||
| 	return math.Ceil(aa) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func round(a interface{}, p int, r_opt ...float64) float64 { |  | ||||||
| 	roundOn := .5 |  | ||||||
| 	if len(r_opt) > 0 { |  | ||||||
| 		roundOn = r_opt[0] |  | ||||||
| 	} |  | ||||||
| 	val := toFloat64(a) |  | ||||||
| 	places := toFloat64(p) |  | ||||||
|  |  | ||||||
| 	var round float64 |  | ||||||
| 	pow := math.Pow(10, places) |  | ||||||
| 	digit := pow * val |  | ||||||
| 	_, div := math.Modf(digit) |  | ||||||
| 	if div >= roundOn { |  | ||||||
| 		round = math.Ceil(digit) |  | ||||||
| 	} else { |  | ||||||
| 		round = math.Floor(digit) |  | ||||||
| 	} |  | ||||||
| 	return round / pow |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // converts unix octal to decimal |  | ||||||
| func toDecimal(v interface{}) int64 { |  | ||||||
| 	result, err := strconv.ParseInt(fmt.Sprint(v), 8, 64) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0 |  | ||||||
| 	} |  | ||||||
| 	return result |  | ||||||
| } |  | ||||||
							
								
								
									
										35
									
								
								vendor/github.com/Masterminds/sprig/regex.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								vendor/github.com/Masterminds/sprig/regex.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,35 +0,0 @@ | |||||||
| package sprig |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"regexp" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func regexMatch(regex string, s string) bool { |  | ||||||
| 	match, _ := regexp.MatchString(regex, s) |  | ||||||
| 	return match |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func regexFindAll(regex string, s string, n int) []string { |  | ||||||
| 	r := regexp.MustCompile(regex) |  | ||||||
| 	return r.FindAllString(s, n) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func regexFind(regex string, s string) string { |  | ||||||
| 	r := regexp.MustCompile(regex) |  | ||||||
| 	return r.FindString(s) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func regexReplaceAll(regex string, s string, repl string) string { |  | ||||||
| 	r := regexp.MustCompile(regex) |  | ||||||
| 	return r.ReplaceAllString(s, repl) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func regexReplaceAllLiteral(regex string, s string, repl string) string { |  | ||||||
| 	r := regexp.MustCompile(regex) |  | ||||||
| 	return r.ReplaceAllLiteralString(s, repl) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func regexSplit(regex string, s string, n int) []string { |  | ||||||
| 	r := regexp.MustCompile(regex) |  | ||||||
| 	return r.Split(s, n) |  | ||||||
| } |  | ||||||
| @@ -1,5 +1,93 @@ | |||||||
| # Changelog | # Changelog | ||||||
| 
 | 
 | ||||||
|  | ## Release 3.2.1 (2021-02-04) | ||||||
|  | 
 | ||||||
|  | ### Changed  | ||||||
|  | 
 | ||||||
|  | - Upgraded `Masterminds/goutils` to `v1.1.1`. see the [Security Advisory](https://github.com/Masterminds/goutils/security/advisories/GHSA-xg2h-wx96-xgxr) | ||||||
|  | 
 | ||||||
|  | ## Release 3.2.0 (2020-12-14) | ||||||
|  | 
 | ||||||
|  | ### Added | ||||||
|  | 
 | ||||||
|  | - #211: Added randInt function (thanks @kochurovro) | ||||||
|  | - #223: Added fromJson and mustFromJson functions (thanks @mholt) | ||||||
|  | - #242: Added a bcrypt function (thanks @robbiet480) | ||||||
|  | - #253: Added randBytes function (thanks @MikaelSmith) | ||||||
|  | - #254: Added dig function for dicts (thanks @nyarly) | ||||||
|  | - #257: Added regexQuoteMeta for quoting regex metadata (thanks @rheaton) | ||||||
|  | - #261: Added filepath functions osBase, osDir, osExt, osClean, osIsAbs (thanks @zugl) | ||||||
|  | - #268: Added and and all functions for testing conditions (thanks @phuslu) | ||||||
|  | - #181: Added float64 arithmetic addf, add1f, subf, divf, mulf, maxf, and minf | ||||||
|  |   (thanks @andrewmostello) | ||||||
|  | - #265: Added chunk function to split array into smaller arrays (thanks @karelbilek) | ||||||
|  | - #270: Extend certificate functions to handle non-RSA keys + add support for | ||||||
|  |   ed25519 keys (thanks @misberner) | ||||||
|  | 
 | ||||||
|  | ### Changed | ||||||
|  | 
 | ||||||
|  | - Removed testing and support for Go 1.12. ed25519 support requires Go 1.13 or newer | ||||||
|  | - Using semver 3.1.1 and mergo 0.3.11 | ||||||
|  | 
 | ||||||
|  | ### Fixed | ||||||
|  | 
 | ||||||
|  | - #249: Fix htmlDateInZone example (thanks @spawnia) | ||||||
|  | 
 | ||||||
|  | NOTE: The dependency github.com/imdario/mergo reverted the breaking change in | ||||||
|  | 0.3.9 via 0.3.10 release. | ||||||
|  | 
 | ||||||
|  | ## Release 3.1.0 (2020-04-16) | ||||||
|  | 
 | ||||||
|  | NOTE: The dependency github.com/imdario/mergo made a behavior change in 0.3.9 | ||||||
|  | that impacts sprig functionality. Do not use sprig with a version newer than 0.3.8. | ||||||
|  | 
 | ||||||
|  | ### Added | ||||||
|  | 
 | ||||||
|  | - #225: Added support for generating htpasswd hash (thanks @rustycl0ck) | ||||||
|  | - #224: Added duration filter (thanks @frebib) | ||||||
|  | - #205: Added `seq` function (thanks @thadc23) | ||||||
|  | 
 | ||||||
|  | ### Changed | ||||||
|  | 
 | ||||||
|  | - #203: Unlambda functions with correct signature (thanks @muesli) | ||||||
|  | - #236: Updated the license formatting for GitHub display purposes | ||||||
|  | - #238: Updated package dependency versions. Note, mergo not updated to 0.3.9 | ||||||
|  |         as it causes a breaking change for sprig. That issue is tracked at | ||||||
|  |         https://github.com/imdario/mergo/issues/139 | ||||||
|  | 
 | ||||||
|  | ### Fixed | ||||||
|  | 
 | ||||||
|  | - #229: Fix `seq` example in docs (thanks @kalmant) | ||||||
|  | 
 | ||||||
|  | ## Release 3.0.2 (2019-12-13) | ||||||
|  | 
 | ||||||
|  | ### Fixed | ||||||
|  | 
 | ||||||
|  | - #220: Updating to semver v3.0.3 to fix issue with <= ranges | ||||||
|  | - #218: fix typo elyptical->elliptic in ecdsa key description (thanks @laverya) | ||||||
|  | 
 | ||||||
|  | ## Release 3.0.1 (2019-12-08) | ||||||
|  | 
 | ||||||
|  | ### Fixed | ||||||
|  | 
 | ||||||
|  | - #212: Updated semver fixing broken constraint checking with ^0.0 | ||||||
|  | 
 | ||||||
|  | ## Release 3.0.0 (2019-10-02) | ||||||
|  | 
 | ||||||
|  | ### Added | ||||||
|  | 
 | ||||||
|  | - #187: Added durationRound function (thanks @yjp20) | ||||||
|  | - #189: Added numerous template functions that return errors rather than panic (thanks @nrvnrvn) | ||||||
|  | - #193: Added toRawJson support (thanks @Dean-Coakley) | ||||||
|  | - #197: Added get support to dicts (thanks @Dean-Coakley) | ||||||
|  | 
 | ||||||
|  | ### Changed | ||||||
|  | 
 | ||||||
|  | - #186: Moving dependency management to Go modules | ||||||
|  | - #186: Updated semver to v3. This has changes in the way ^ is handled | ||||||
|  | - #194: Updated documentation on merging and how it copies. Added example using deepCopy | ||||||
|  | - #196: trunc now supports negative values (thanks @Dean-Coakley) | ||||||
|  | 
 | ||||||
| ## Release 2.22.0 (2019-10-02) | ## Release 2.22.0 (2019-10-02) | ||||||
| 
 | 
 | ||||||
| ### Added | ### Added | ||||||
| @@ -1,5 +1,4 @@ | |||||||
| Sprig | Copyright (C) 2013-2020 Masterminds | ||||||
| Copyright (C) 2013 Masterminds |  | ||||||
| 
 | 
 | ||||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
| of this software and associated documentation files (the "Software"), to deal | of this software and associated documentation files (the "Software"), to deal | ||||||
							
								
								
									
										9
									
								
								vendor/github.com/Masterminds/sprig/v3/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/Masterminds/sprig/v3/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | .PHONY: test | ||||||
|  | test: | ||||||
|  | 	@echo "==> Running tests" | ||||||
|  | 	GO111MODULE=on go test -v | ||||||
|  |  | ||||||
|  | .PHONY: test-cover | ||||||
|  | test-cover: | ||||||
|  | 	@echo "==> Running Tests with coverage" | ||||||
|  | 	GO111MODULE=on go test -cover . | ||||||
| @@ -1,6 +1,9 @@ | |||||||
| # Sprig: Template functions for Go templates | # Sprig: Template functions for Go templates | ||||||
|  | 
 | ||||||
|  | [](https://pkg.go.dev/github.com/Masterminds/sprig/v3) | ||||||
|  | [](https://goreportcard.com/report/github.com/Masterminds/sprig) | ||||||
| [](https://masterminds.github.io/stability/sustained.html) | [](https://masterminds.github.io/stability/sustained.html) | ||||||
| [](https://travis-ci.org/Masterminds/sprig) | [](https://github.com/Masterminds/sprig/actions) | ||||||
| 
 | 
 | ||||||
| The Go language comes with a [built-in template | The Go language comes with a [built-in template | ||||||
| language](http://golang.org/pkg/text/template/), but not | language](http://golang.org/pkg/text/template/), but not | ||||||
| @@ -11,6 +14,26 @@ It is inspired by the template functions found in | |||||||
| [Twig](http://twig.sensiolabs.org/documentation) and in various | [Twig](http://twig.sensiolabs.org/documentation) and in various | ||||||
| JavaScript libraries, such as [underscore.js](http://underscorejs.org/). | JavaScript libraries, such as [underscore.js](http://underscorejs.org/). | ||||||
| 
 | 
 | ||||||
|  | ## IMPORTANT NOTES | ||||||
|  | 
 | ||||||
|  | Sprig leverages [mergo](https://github.com/imdario/mergo) to handle merges. In | ||||||
|  | its v0.3.9 release there was a behavior change that impacts merging template | ||||||
|  | functions in sprig. It is currently recommended to use v0.3.8 of that package. | ||||||
|  | Using v0.3.9 will cause sprig tests to fail. The issue in mergo is tracked at | ||||||
|  | https://github.com/imdario/mergo/issues/139. | ||||||
|  | 
 | ||||||
|  | ## Package Versions | ||||||
|  | 
 | ||||||
|  | There are two active major versions of the `sprig` package. | ||||||
|  | 
 | ||||||
|  | * v3 is currently stable release series on the `master` branch. The Go API should | ||||||
|  |   remain compatible with v2, the current stable version. Behavior change behind | ||||||
|  |   some functions is the reason for the new major version. | ||||||
|  | * v2 is the previous stable release series. It has been more than three years since | ||||||
|  |   the initial release of v2. You can read the documentation and see the code | ||||||
|  |   on the [release-2](https://github.com/Masterminds/sprig/tree/release-2) branch. | ||||||
|  |   Bug fixes to this major version will continue for some time. | ||||||
|  | 
 | ||||||
| ## Usage | ## Usage | ||||||
| 
 | 
 | ||||||
| **Template developers**: Please use Sprig's [function documentation](http://masterminds.github.io/sprig/) for | **Template developers**: Please use Sprig's [function documentation](http://masterminds.github.io/sprig/) for | ||||||
| @@ -2,10 +2,12 @@ package sprig | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
|  | 	"crypto" | ||||||
| 	"crypto/aes" | 	"crypto/aes" | ||||||
| 	"crypto/cipher" | 	"crypto/cipher" | ||||||
| 	"crypto/dsa" | 	"crypto/dsa" | ||||||
| 	"crypto/ecdsa" | 	"crypto/ecdsa" | ||||||
|  | 	"crypto/ed25519" | ||||||
| 	"crypto/elliptic" | 	"crypto/elliptic" | ||||||
| 	"crypto/hmac" | 	"crypto/hmac" | ||||||
| 	"crypto/rand" | 	"crypto/rand" | ||||||
| @@ -21,13 +23,16 @@ import ( | |||||||
| 	"encoding/pem" | 	"encoding/pem" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" |  | ||||||
| 	"hash/adler32" | 	"hash/adler32" | ||||||
|  | 	"io" | ||||||
| 	"math/big" | 	"math/big" | ||||||
| 	"net" | 	"net" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
| 	"github.com/google/uuid" | 	"github.com/google/uuid" | ||||||
|  | 	bcrypt_lib "golang.org/x/crypto/bcrypt" | ||||||
| 	"golang.org/x/crypto/scrypt" | 	"golang.org/x/crypto/scrypt" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @@ -46,14 +51,38 @@ func adler32sum(input string) string { | |||||||
| 	return fmt.Sprintf("%d", hash) | 	return fmt.Sprintf("%d", hash) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // uuidv4 provides a safe and secure UUID v4 implementation | func bcrypt(input string) string { | ||||||
| func uuidv4() string { | 	hash, err := bcrypt_lib.GenerateFromPassword([]byte(input), bcrypt_lib.DefaultCost) | ||||||
| 	return fmt.Sprintf("%s", uuid.New()) | 	if err != nil { | ||||||
|  | 		return fmt.Sprintf("failed to encrypt string with bcrypt: %s", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return string(hash) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var master_password_seed = "com.lyndir.masterpassword" | func htpasswd(username string, password string) string { | ||||||
|  | 	if strings.Contains(username, ":") { | ||||||
|  | 		return fmt.Sprintf("invalid username: %s", username) | ||||||
|  | 	} | ||||||
|  | 	return fmt.Sprintf("%s:%s", username, bcrypt(password)) | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| var password_type_templates = map[string][][]byte{ | func randBytes(count int) (string, error) { | ||||||
|  | 	buf := make([]byte, count) | ||||||
|  | 	if _, err := rand.Read(buf); err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return base64.StdEncoding.EncodeToString(buf), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // uuidv4 provides a safe and secure UUID v4 implementation | ||||||
|  | func uuidv4() string { | ||||||
|  | 	return uuid.New().String() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var masterPasswordSeed = "com.lyndir.masterpassword" | ||||||
|  | 
 | ||||||
|  | var passwordTypeTemplates = map[string][][]byte{ | ||||||
| 	"maximum": {[]byte("anoxxxxxxxxxxxxxxxxx"), []byte("axxxxxxxxxxxxxxxxxno")}, | 	"maximum": {[]byte("anoxxxxxxxxxxxxxxxxx"), []byte("axxxxxxxxxxxxxxxxxno")}, | ||||||
| 	"long": {[]byte("CvcvnoCvcvCvcv"), []byte("CvcvCvcvnoCvcv"), []byte("CvcvCvcvCvcvno"), []byte("CvccnoCvcvCvcv"), []byte("CvccCvcvnoCvcv"), | 	"long": {[]byte("CvcvnoCvcvCvcv"), []byte("CvcvCvcvnoCvcv"), []byte("CvcvCvcvCvcvno"), []byte("CvccnoCvcvCvcv"), []byte("CvccCvcvnoCvcv"), | ||||||
| 		[]byte("CvccCvcvCvcvno"), []byte("CvcvnoCvccCvcv"), []byte("CvcvCvccnoCvcv"), []byte("CvcvCvccCvcvno"), []byte("CvcvnoCvcvCvcc"), | 		[]byte("CvccCvcvCvcvno"), []byte("CvcvnoCvccCvcv"), []byte("CvcvCvccnoCvcv"), []byte("CvcvCvccCvcvno"), []byte("CvcvnoCvcvCvcc"), | ||||||
| @@ -66,7 +95,7 @@ var password_type_templates = map[string][][]byte{ | |||||||
| 	"pin":    {[]byte("nnnn")}, | 	"pin":    {[]byte("nnnn")}, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var template_characters = map[byte]string{ | var templateCharacters = map[byte]string{ | ||||||
| 	'V': "AEIOU", | 	'V': "AEIOU", | ||||||
| 	'C': "BCDFGHJKLMNPQRSTVWXYZ", | 	'C': "BCDFGHJKLMNPQRSTVWXYZ", | ||||||
| 	'v': "aeiou", | 	'v': "aeiou", | ||||||
| @@ -78,14 +107,14 @@ var template_characters = map[byte]string{ | |||||||
| 	'x': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()", | 	'x': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()", | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func derivePassword(counter uint32, password_type, password, user, site string) string { | func derivePassword(counter uint32, passwordType, password, user, site string) string { | ||||||
| 	var templates = password_type_templates[password_type] | 	var templates = passwordTypeTemplates[passwordType] | ||||||
| 	if templates == nil { | 	if templates == nil { | ||||||
| 		return fmt.Sprintf("cannot find password template %s", password_type) | 		return fmt.Sprintf("cannot find password template %s", passwordType) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var buffer bytes.Buffer | 	var buffer bytes.Buffer | ||||||
| 	buffer.WriteString(master_password_seed) | 	buffer.WriteString(masterPasswordSeed) | ||||||
| 	binary.Write(&buffer, binary.BigEndian, uint32(len(user))) | 	binary.Write(&buffer, binary.BigEndian, uint32(len(user))) | ||||||
| 	buffer.WriteString(user) | 	buffer.WriteString(user) | ||||||
| 
 | 
 | ||||||
| @@ -95,7 +124,7 @@ func derivePassword(counter uint32, password_type, password, user, site string) | |||||||
| 		return fmt.Sprintf("failed to derive password: %s", err) | 		return fmt.Sprintf("failed to derive password: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	buffer.Truncate(len(master_password_seed)) | 	buffer.Truncate(len(masterPasswordSeed)) | ||||||
| 	binary.Write(&buffer, binary.BigEndian, uint32(len(site))) | 	binary.Write(&buffer, binary.BigEndian, uint32(len(site))) | ||||||
| 	buffer.WriteString(site) | 	buffer.WriteString(site) | ||||||
| 	binary.Write(&buffer, binary.BigEndian, counter) | 	binary.Write(&buffer, binary.BigEndian, counter) | ||||||
| @@ -107,9 +136,9 @@ func derivePassword(counter uint32, password_type, password, user, site string) | |||||||
| 
 | 
 | ||||||
| 	buffer.Truncate(0) | 	buffer.Truncate(0) | ||||||
| 	for i, element := range temp { | 	for i, element := range temp { | ||||||
| 		pass_chars := template_characters[element] | 		passChars := templateCharacters[element] | ||||||
| 		pass_char := pass_chars[int(seed[i+1])%len(pass_chars)] | 		passChar := passChars[int(seed[i+1])%len(passChars)] | ||||||
| 		buffer.WriteByte(pass_char) | 		buffer.WriteByte(passChar) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return buffer.String() | 	return buffer.String() | ||||||
| @@ -133,6 +162,8 @@ func generatePrivateKey(typ string) string { | |||||||
| 	case "ecdsa": | 	case "ecdsa": | ||||||
| 		// again, good enough for government work | 		// again, good enough for government work | ||||||
| 		priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) | 		priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) | ||||||
|  | 	case "ed25519": | ||||||
|  | 		_, priv, err = ed25519.GenerateKey(rand.Reader) | ||||||
| 	default: | 	default: | ||||||
| 		return "Unknown type " + typ | 		return "Unknown type " + typ | ||||||
| 	} | 	} | ||||||
| @@ -143,6 +174,8 @@ func generatePrivateKey(typ string) string { | |||||||
| 	return string(pem.EncodeToMemory(pemBlockForKey(priv))) | 	return string(pem.EncodeToMemory(pemBlockForKey(priv))) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // DSAKeyFormat stores the format for DSA keys. | ||||||
|  | // Used by pemBlockForKey | ||||||
| type DSAKeyFormat struct { | type DSAKeyFormat struct { | ||||||
| 	Version       int | 	Version       int | ||||||
| 	P, Q, G, Y, X *big.Int | 	P, Q, G, Y, X *big.Int | ||||||
| @@ -163,7 +196,73 @@ func pemBlockForKey(priv interface{}) *pem.Block { | |||||||
| 		b, _ := x509.MarshalECPrivateKey(k) | 		b, _ := x509.MarshalECPrivateKey(k) | ||||||
| 		return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b} | 		return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b} | ||||||
| 	default: | 	default: | ||||||
| 		return nil | 		// attempt PKCS#8 format for all other keys | ||||||
|  | 		b, err := x509.MarshalPKCS8PrivateKey(k) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 		return &pem.Block{Type: "PRIVATE KEY", Bytes: b} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func parsePrivateKeyPEM(pemBlock string) (crypto.PrivateKey, error) { | ||||||
|  | 	block, _ := pem.Decode([]byte(pemBlock)) | ||||||
|  | 	if block == nil { | ||||||
|  | 		return nil, errors.New("no PEM data in input") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if block.Type == "PRIVATE KEY" { | ||||||
|  | 		priv, err := x509.ParsePKCS8PrivateKey(block.Bytes) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf("decoding PEM as PKCS#8: %s", err) | ||||||
|  | 		} | ||||||
|  | 		return priv, nil | ||||||
|  | 	} else if !strings.HasSuffix(block.Type, " PRIVATE KEY") { | ||||||
|  | 		return nil, fmt.Errorf("no private key data in PEM block of type %s", block.Type) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	switch block.Type[:len(block.Type)-12] { // strip " PRIVATE KEY" | ||||||
|  | 	case "RSA": | ||||||
|  | 		priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf("parsing RSA private key from PEM: %s", err) | ||||||
|  | 		} | ||||||
|  | 		return priv, nil | ||||||
|  | 	case "EC": | ||||||
|  | 		priv, err := x509.ParseECPrivateKey(block.Bytes) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf("parsing EC private key from PEM: %s", err) | ||||||
|  | 		} | ||||||
|  | 		return priv, nil | ||||||
|  | 	case "DSA": | ||||||
|  | 		var k DSAKeyFormat | ||||||
|  | 		_, err := asn1.Unmarshal(block.Bytes, &k) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf("parsing DSA private key from PEM: %s", err) | ||||||
|  | 		} | ||||||
|  | 		priv := &dsa.PrivateKey{ | ||||||
|  | 			PublicKey: dsa.PublicKey{ | ||||||
|  | 				Parameters: dsa.Parameters{ | ||||||
|  | 					P: k.P, Q: k.Q, G: k.G, | ||||||
|  | 				}, | ||||||
|  | 				Y: k.Y, | ||||||
|  | 			}, | ||||||
|  | 			X: k.X, | ||||||
|  | 		} | ||||||
|  | 		return priv, nil | ||||||
|  | 	default: | ||||||
|  | 		return nil, fmt.Errorf("invalid private key type %s", block.Type) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func getPublicKey(priv crypto.PrivateKey) (crypto.PublicKey, error) { | ||||||
|  | 	switch k := priv.(type) { | ||||||
|  | 	case interface{ Public() crypto.PublicKey }: | ||||||
|  | 		return k.Public(), nil | ||||||
|  | 	case *dsa.PrivateKey: | ||||||
|  | 		return &k.PublicKey, nil | ||||||
|  | 	default: | ||||||
|  | 		return nil, fmt.Errorf("unable to get public key for type %T", priv) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -197,14 +296,10 @@ func buildCustomCertificate(b64cert string, b64key string) (certificate, error) | |||||||
| 		) | 		) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	decodedKey, _ := pem.Decode(key) | 	_, err = parsePrivateKeyPEM(string(key)) | ||||||
| 	if decodedKey == nil { |  | ||||||
| 		return crt, errors.New("unable to decode key") |  | ||||||
| 	} |  | ||||||
| 	_, err = x509.ParsePKCS1PrivateKey(decodedKey.Bytes) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return crt, fmt.Errorf( | 		return crt, fmt.Errorf( | ||||||
| 			"error parsing prive key: decodedKey.Bytes: %s", | 			"error parsing private key: %s", | ||||||
| 			err, | 			err, | ||||||
| 		) | 		) | ||||||
| 	} | 	} | ||||||
| @@ -218,6 +313,31 @@ func buildCustomCertificate(b64cert string, b64key string) (certificate, error) | |||||||
| func generateCertificateAuthority( | func generateCertificateAuthority( | ||||||
| 	cn string, | 	cn string, | ||||||
| 	daysValid int, | 	daysValid int, | ||||||
|  | ) (certificate, error) { | ||||||
|  | 	priv, err := rsa.GenerateKey(rand.Reader, 2048) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return certificate{}, fmt.Errorf("error generating rsa key: %s", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return generateCertificateAuthorityWithKeyInternal(cn, daysValid, priv) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func generateCertificateAuthorityWithPEMKey( | ||||||
|  | 	cn string, | ||||||
|  | 	daysValid int, | ||||||
|  | 	privPEM string, | ||||||
|  | ) (certificate, error) { | ||||||
|  | 	priv, err := parsePrivateKeyPEM(privPEM) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return certificate{}, fmt.Errorf("parsing private key: %s", err) | ||||||
|  | 	} | ||||||
|  | 	return generateCertificateAuthorityWithKeyInternal(cn, daysValid, priv) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func generateCertificateAuthorityWithKeyInternal( | ||||||
|  | 	cn string, | ||||||
|  | 	daysValid int, | ||||||
|  | 	priv crypto.PrivateKey, | ||||||
| ) (certificate, error) { | ) (certificate, error) { | ||||||
| 	ca := certificate{} | 	ca := certificate{} | ||||||
| 
 | 
 | ||||||
| @@ -231,17 +351,9 @@ func generateCertificateAuthority( | |||||||
| 		x509.KeyUsageCertSign | 		x509.KeyUsageCertSign | ||||||
| 	template.IsCA = true | 	template.IsCA = true | ||||||
| 
 | 
 | ||||||
| 	priv, err := rsa.GenerateKey(rand.Reader, 2048) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return ca, fmt.Errorf("error generating rsa key: %s", err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ca.Cert, ca.Key, err = getCertAndKey(template, priv, template, priv) | 	ca.Cert, ca.Key, err = getCertAndKey(template, priv, template, priv) | ||||||
| 	if err != nil { |  | ||||||
| 		return ca, err |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	return ca, nil | 	return ca, err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func generateSelfSignedCertificate( | func generateSelfSignedCertificate( | ||||||
| @@ -249,6 +361,34 @@ func generateSelfSignedCertificate( | |||||||
| 	ips []interface{}, | 	ips []interface{}, | ||||||
| 	alternateDNS []interface{}, | 	alternateDNS []interface{}, | ||||||
| 	daysValid int, | 	daysValid int, | ||||||
|  | ) (certificate, error) { | ||||||
|  | 	priv, err := rsa.GenerateKey(rand.Reader, 2048) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return certificate{}, fmt.Errorf("error generating rsa key: %s", err) | ||||||
|  | 	} | ||||||
|  | 	return generateSelfSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, priv) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func generateSelfSignedCertificateWithPEMKey( | ||||||
|  | 	cn string, | ||||||
|  | 	ips []interface{}, | ||||||
|  | 	alternateDNS []interface{}, | ||||||
|  | 	daysValid int, | ||||||
|  | 	privPEM string, | ||||||
|  | ) (certificate, error) { | ||||||
|  | 	priv, err := parsePrivateKeyPEM(privPEM) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return certificate{}, fmt.Errorf("parsing private key: %s", err) | ||||||
|  | 	} | ||||||
|  | 	return generateSelfSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, priv) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func generateSelfSignedCertificateWithKeyInternal( | ||||||
|  | 	cn string, | ||||||
|  | 	ips []interface{}, | ||||||
|  | 	alternateDNS []interface{}, | ||||||
|  | 	daysValid int, | ||||||
|  | 	priv crypto.PrivateKey, | ||||||
| ) (certificate, error) { | ) (certificate, error) { | ||||||
| 	cert := certificate{} | 	cert := certificate{} | ||||||
| 
 | 
 | ||||||
| @@ -257,17 +397,9 @@ func generateSelfSignedCertificate( | |||||||
| 		return cert, err | 		return cert, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	priv, err := rsa.GenerateKey(rand.Reader, 2048) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return cert, fmt.Errorf("error generating rsa key: %s", err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	cert.Cert, cert.Key, err = getCertAndKey(template, priv, template, priv) | 	cert.Cert, cert.Key, err = getCertAndKey(template, priv, template, priv) | ||||||
| 	if err != nil { |  | ||||||
| 		return cert, err |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	return cert, nil | 	return cert, err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func generateSignedCertificate( | func generateSignedCertificate( | ||||||
| @@ -276,6 +408,36 @@ func generateSignedCertificate( | |||||||
| 	alternateDNS []interface{}, | 	alternateDNS []interface{}, | ||||||
| 	daysValid int, | 	daysValid int, | ||||||
| 	ca certificate, | 	ca certificate, | ||||||
|  | ) (certificate, error) { | ||||||
|  | 	priv, err := rsa.GenerateKey(rand.Reader, 2048) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return certificate{}, fmt.Errorf("error generating rsa key: %s", err) | ||||||
|  | 	} | ||||||
|  | 	return generateSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, ca, priv) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func generateSignedCertificateWithPEMKey( | ||||||
|  | 	cn string, | ||||||
|  | 	ips []interface{}, | ||||||
|  | 	alternateDNS []interface{}, | ||||||
|  | 	daysValid int, | ||||||
|  | 	ca certificate, | ||||||
|  | 	privPEM string, | ||||||
|  | ) (certificate, error) { | ||||||
|  | 	priv, err := parsePrivateKeyPEM(privPEM) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return certificate{}, fmt.Errorf("parsing private key: %s", err) | ||||||
|  | 	} | ||||||
|  | 	return generateSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, ca, priv) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func generateSignedCertificateWithKeyInternal( | ||||||
|  | 	cn string, | ||||||
|  | 	ips []interface{}, | ||||||
|  | 	alternateDNS []interface{}, | ||||||
|  | 	daysValid int, | ||||||
|  | 	ca certificate, | ||||||
|  | 	priv crypto.PrivateKey, | ||||||
| ) (certificate, error) { | ) (certificate, error) { | ||||||
| 	cert := certificate{} | 	cert := certificate{} | ||||||
| 
 | 
 | ||||||
| @@ -290,14 +452,10 @@ func generateSignedCertificate( | |||||||
| 			err, | 			err, | ||||||
| 		) | 		) | ||||||
| 	} | 	} | ||||||
| 	decodedSignerKey, _ := pem.Decode([]byte(ca.Key)) | 	signerKey, err := parsePrivateKeyPEM(ca.Key) | ||||||
| 	if decodedSignerKey == nil { |  | ||||||
| 		return cert, errors.New("unable to decode key") |  | ||||||
| 	} |  | ||||||
| 	signerKey, err := x509.ParsePKCS1PrivateKey(decodedSignerKey.Bytes) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return cert, fmt.Errorf( | 		return cert, fmt.Errorf( | ||||||
| 			"error parsing prive key: decodedSignerKey.Bytes: %s", | 			"error parsing private key: %s", | ||||||
| 			err, | 			err, | ||||||
| 		) | 		) | ||||||
| 	} | 	} | ||||||
| @@ -307,35 +465,31 @@ func generateSignedCertificate( | |||||||
| 		return cert, err | 		return cert, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	priv, err := rsa.GenerateKey(rand.Reader, 2048) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return cert, fmt.Errorf("error generating rsa key: %s", err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	cert.Cert, cert.Key, err = getCertAndKey( | 	cert.Cert, cert.Key, err = getCertAndKey( | ||||||
| 		template, | 		template, | ||||||
| 		priv, | 		priv, | ||||||
| 		signerCert, | 		signerCert, | ||||||
| 		signerKey, | 		signerKey, | ||||||
| 	) | 	) | ||||||
| 	if err != nil { |  | ||||||
| 		return cert, err |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	return cert, nil | 	return cert, err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func getCertAndKey( | func getCertAndKey( | ||||||
| 	template *x509.Certificate, | 	template *x509.Certificate, | ||||||
| 	signeeKey *rsa.PrivateKey, | 	signeeKey crypto.PrivateKey, | ||||||
| 	parent *x509.Certificate, | 	parent *x509.Certificate, | ||||||
| 	signingKey *rsa.PrivateKey, | 	signingKey crypto.PrivateKey, | ||||||
| ) (string, string, error) { | ) (string, string, error) { | ||||||
|  | 	signeePubKey, err := getPublicKey(signeeKey) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", "", fmt.Errorf("error retrieving public key from signee key: %s", err) | ||||||
|  | 	} | ||||||
| 	derBytes, err := x509.CreateCertificate( | 	derBytes, err := x509.CreateCertificate( | ||||||
| 		rand.Reader, | 		rand.Reader, | ||||||
| 		template, | 		template, | ||||||
| 		parent, | 		parent, | ||||||
| 		&signeeKey.PublicKey, | 		signeePubKey, | ||||||
| 		signingKey, | 		signingKey, | ||||||
| 	) | 	) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -353,15 +507,12 @@ func getCertAndKey( | |||||||
| 	keyBuffer := bytes.Buffer{} | 	keyBuffer := bytes.Buffer{} | ||||||
| 	if err := pem.Encode( | 	if err := pem.Encode( | ||||||
| 		&keyBuffer, | 		&keyBuffer, | ||||||
| 		&pem.Block{ | 		pemBlockForKey(signeeKey), | ||||||
| 			Type:  "RSA PRIVATE KEY", |  | ||||||
| 			Bytes: x509.MarshalPKCS1PrivateKey(signeeKey), |  | ||||||
| 		}, |  | ||||||
| 	); err != nil { | 	); err != nil { | ||||||
| 		return "", "", fmt.Errorf("error pem-encoding key: %s", err) | 		return "", "", fmt.Errorf("error pem-encoding key: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return string(certBuffer.Bytes()), string(keyBuffer.Bytes()), nil | 	return certBuffer.String(), keyBuffer.String(), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func getBaseCertTemplate( | func getBaseCertTemplate( | ||||||
| @@ -55,6 +55,14 @@ func dateModify(fmt string, date time.Time) time.Time { | |||||||
| 	return date.Add(d) | 	return date.Add(d) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func mustDateModify(fmt string, date time.Time) (time.Time, error) { | ||||||
|  | 	d, err := time.ParseDuration(fmt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return time.Time{}, err | ||||||
|  | 	} | ||||||
|  | 	return date.Add(d), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func dateAgo(date interface{}) string { | func dateAgo(date interface{}) string { | ||||||
| 	var t time.Time | 	var t time.Time | ||||||
| 
 | 
 | ||||||
| @@ -73,11 +81,72 @@ func dateAgo(date interface{}) string { | |||||||
| 	return duration.String() | 	return duration.String() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func duration(sec interface{}) string { | ||||||
|  | 	var n int64 | ||||||
|  | 	switch value := sec.(type) { | ||||||
|  | 	default: | ||||||
|  | 		n = 0 | ||||||
|  | 	case string: | ||||||
|  | 		n, _ = strconv.ParseInt(value, 10, 64) | ||||||
|  | 	case int64: | ||||||
|  | 		n = value | ||||||
|  | 	} | ||||||
|  | 	return (time.Duration(n) * time.Second).String() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func durationRound(duration interface{}) string { | ||||||
|  | 	var d time.Duration | ||||||
|  | 	switch duration := duration.(type) { | ||||||
|  | 	default: | ||||||
|  | 		d = 0 | ||||||
|  | 	case string: | ||||||
|  | 		d, _ = time.ParseDuration(duration) | ||||||
|  | 	case int64: | ||||||
|  | 		d = time.Duration(duration) | ||||||
|  | 	case time.Time: | ||||||
|  | 		d = time.Since(duration) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	u := uint64(d) | ||||||
|  | 	neg := d < 0 | ||||||
|  | 	if neg { | ||||||
|  | 		u = -u | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var ( | ||||||
|  | 		year   = uint64(time.Hour) * 24 * 365 | ||||||
|  | 		month  = uint64(time.Hour) * 24 * 30 | ||||||
|  | 		day    = uint64(time.Hour) * 24 | ||||||
|  | 		hour   = uint64(time.Hour) | ||||||
|  | 		minute = uint64(time.Minute) | ||||||
|  | 		second = uint64(time.Second) | ||||||
|  | 	) | ||||||
|  | 	switch { | ||||||
|  | 	case u > year: | ||||||
|  | 		return strconv.FormatUint(u/year, 10) + "y" | ||||||
|  | 	case u > month: | ||||||
|  | 		return strconv.FormatUint(u/month, 10) + "mo" | ||||||
|  | 	case u > day: | ||||||
|  | 		return strconv.FormatUint(u/day, 10) + "d" | ||||||
|  | 	case u > hour: | ||||||
|  | 		return strconv.FormatUint(u/hour, 10) + "h" | ||||||
|  | 	case u > minute: | ||||||
|  | 		return strconv.FormatUint(u/minute, 10) + "m" | ||||||
|  | 	case u > second: | ||||||
|  | 		return strconv.FormatUint(u/second, 10) + "s" | ||||||
|  | 	} | ||||||
|  | 	return "0s" | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func toDate(fmt, str string) time.Time { | func toDate(fmt, str string) time.Time { | ||||||
| 	t, _ := time.ParseInLocation(fmt, str, time.Local) | 	t, _ := time.ParseInLocation(fmt, str, time.Local) | ||||||
| 	return t | 	return t | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func mustToDate(fmt, str string) (time.Time, error) { | ||||||
|  | 	return time.ParseInLocation(fmt, str, time.Local) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func unixEpoch(date time.Time) string { | func unixEpoch(date time.Time) string { | ||||||
| 	return strconv.FormatInt(date.Unix(), 10) | 	return strconv.FormatInt(date.Unix(), 10) | ||||||
| } | } | ||||||
| @@ -1,10 +1,18 @@ | |||||||
| package sprig | package sprig | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"bytes" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
|  | 	"math/rand" | ||||||
| 	"reflect" | 	"reflect" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | func init() { | ||||||
|  | 	rand.Seed(time.Now().UnixNano()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // dfault checks whether `given` is set, and returns default if not set. | // dfault checks whether `given` is set, and returns default if not set. | ||||||
| // | // | ||||||
| // This returns `d` if `given` appears not to be set, and `given` otherwise. | // This returns `d` if `given` appears not to be set, and `given` otherwise. | ||||||
| @@ -37,7 +45,7 @@ func empty(given interface{}) bool { | |||||||
| 	case reflect.Array, reflect.Slice, reflect.Map, reflect.String: | 	case reflect.Array, reflect.Slice, reflect.Map, reflect.String: | ||||||
| 		return g.Len() == 0 | 		return g.Len() == 0 | ||||||
| 	case reflect.Bool: | 	case reflect.Bool: | ||||||
| 		return g.Bool() == false | 		return !g.Bool() | ||||||
| 	case reflect.Complex64, reflect.Complex128: | 	case reflect.Complex64, reflect.Complex128: | ||||||
| 		return g.Complex() == 0 | 		return g.Complex() == 0 | ||||||
| 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||||
| @@ -61,18 +69,90 @@ func coalesce(v ...interface{}) interface{} { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // all returns true if empty(x) is false for all values x in the list. | ||||||
|  | // If the list is empty, return true. | ||||||
|  | func all(v ...interface{}) bool { | ||||||
|  | 	for _, val := range v { | ||||||
|  | 		if empty(val) { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // any returns true if empty(x) is false for any x in the list. | ||||||
|  | // If the list is empty, return false. | ||||||
|  | func any(v ...interface{}) bool { | ||||||
|  | 	for _, val := range v { | ||||||
|  | 		if !empty(val) { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // fromJson decodes JSON into a structured value, ignoring errors. | ||||||
|  | func fromJson(v string) interface{} { | ||||||
|  | 	output, _ := mustFromJson(v) | ||||||
|  | 	return output | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // mustFromJson decodes JSON into a structured value, returning errors. | ||||||
|  | func mustFromJson(v string) (interface{}, error) { | ||||||
|  | 	var output interface{} | ||||||
|  | 	err := json.Unmarshal([]byte(v), &output) | ||||||
|  | 	return output, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // toJson encodes an item into a JSON string | // toJson encodes an item into a JSON string | ||||||
| func toJson(v interface{}) string { | func toJson(v interface{}) string { | ||||||
| 	output, _ := json.Marshal(v) | 	output, _ := json.Marshal(v) | ||||||
| 	return string(output) | 	return string(output) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func mustToJson(v interface{}) (string, error) { | ||||||
|  | 	output, err := json.Marshal(v) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return string(output), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // toPrettyJson encodes an item into a pretty (indented) JSON string | // toPrettyJson encodes an item into a pretty (indented) JSON string | ||||||
| func toPrettyJson(v interface{}) string { | func toPrettyJson(v interface{}) string { | ||||||
| 	output, _ := json.MarshalIndent(v, "", "  ") | 	output, _ := json.MarshalIndent(v, "", "  ") | ||||||
| 	return string(output) | 	return string(output) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func mustToPrettyJson(v interface{}) (string, error) { | ||||||
|  | 	output, err := json.MarshalIndent(v, "", "  ") | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return string(output), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // toRawJson encodes an item into a JSON string with no escaping of HTML characters. | ||||||
|  | func toRawJson(v interface{}) string { | ||||||
|  | 	output, err := mustToRawJson(v) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 	return string(output) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // mustToRawJson encodes an item into a JSON string with no escaping of HTML characters. | ||||||
|  | func mustToRawJson(v interface{}) (string, error) { | ||||||
|  | 	buf := new(bytes.Buffer) | ||||||
|  | 	enc := json.NewEncoder(buf) | ||||||
|  | 	enc.SetEscapeHTML(false) | ||||||
|  | 	err := enc.Encode(&v) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return strings.TrimSuffix(buf.String(), "\n"), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // ternary returns the first value if the last value is true, otherwise returns the second value. | // ternary returns the first value if the last value is true, otherwise returns the second value. | ||||||
| func ternary(vt interface{}, vf interface{}, v bool) interface{} { | func ternary(vt interface{}, vf interface{}, v bool) interface{} { | ||||||
| 	if v { | 	if v { | ||||||
| @@ -5,6 +5,13 @@ import ( | |||||||
| 	"github.com/mitchellh/copystructure" | 	"github.com/mitchellh/copystructure" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | func get(d map[string]interface{}, key string) interface{} { | ||||||
|  | 	if val, ok := d[key]; ok { | ||||||
|  | 		return val | ||||||
|  | 	} | ||||||
|  | 	return "" | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func set(d map[string]interface{}, key string, value interface{}) map[string]interface{} { | func set(d map[string]interface{}, key string, value interface{}) map[string]interface{} { | ||||||
| 	d[key] = value | 	d[key] = value | ||||||
| 	return d | 	return d | ||||||
| @@ -90,6 +97,15 @@ func merge(dst map[string]interface{}, srcs ...map[string]interface{}) interface | |||||||
| 	return dst | 	return dst | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func mustMerge(dst map[string]interface{}, srcs ...map[string]interface{}) (interface{}, error) { | ||||||
|  | 	for _, src := range srcs { | ||||||
|  | 		if err := mergo.Merge(&dst, src); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return dst, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func mergeOverwrite(dst map[string]interface{}, srcs ...map[string]interface{}) interface{} { | func mergeOverwrite(dst map[string]interface{}, srcs ...map[string]interface{}) interface{} { | ||||||
| 	for _, src := range srcs { | 	for _, src := range srcs { | ||||||
| 		if err := mergo.MergeWithOverwrite(&dst, src); err != nil { | 		if err := mergo.MergeWithOverwrite(&dst, src); err != nil { | ||||||
| @@ -100,6 +116,15 @@ func mergeOverwrite(dst map[string]interface{}, srcs ...map[string]interface{}) | |||||||
| 	return dst | 	return dst | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func mustMergeOverwrite(dst map[string]interface{}, srcs ...map[string]interface{}) (interface{}, error) { | ||||||
|  | 	for _, src := range srcs { | ||||||
|  | 		if err := mergo.MergeWithOverwrite(&dst, src); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return dst, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func values(dict map[string]interface{}) []interface{} { | func values(dict map[string]interface{}) []interface{} { | ||||||
| 	values := []interface{}{} | 	values := []interface{}{} | ||||||
| 	for _, value := range dict { | 	for _, value := range dict { | ||||||
| @@ -110,10 +135,40 @@ func values(dict map[string]interface{}) []interface{} { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func deepCopy(i interface{}) interface{} { | func deepCopy(i interface{}) interface{} { | ||||||
| 	c, err := copystructure.Copy(i) | 	c, err := mustDeepCopy(i) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		panic("deepCopy error: " + err.Error()) | 		panic("deepCopy error: " + err.Error()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return c | 	return c | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func mustDeepCopy(i interface{}) (interface{}, error) { | ||||||
|  | 	return copystructure.Copy(i) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func dig(ps ...interface{}) (interface{}, error) { | ||||||
|  | 	if len(ps) < 3 { | ||||||
|  | 		panic("dig needs at least three arguments") | ||||||
|  | 	} | ||||||
|  | 	dict := ps[len(ps)-1].(map[string]interface{}) | ||||||
|  | 	def := ps[len(ps)-2] | ||||||
|  | 	ks := make([]string, len(ps)-2) | ||||||
|  | 	for i := 0; i < len(ks); i++ { | ||||||
|  | 		ks[i] = ps[i].(string) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return digFromDict(dict, def, ks) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func digFromDict(dict map[string]interface{}, d interface{}, ks []string) (interface{}, error) { | ||||||
|  | 	k, ns := ks[0], ks[1:len(ks)] | ||||||
|  | 	step, has := dict[k] | ||||||
|  | 	if !has { | ||||||
|  | 		return d, nil | ||||||
|  | 	} | ||||||
|  | 	if len(ns) == 0 { | ||||||
|  | 		return step, nil | ||||||
|  | 	} | ||||||
|  | 	return digFromDict(step.(map[string]interface{}), d, ns) | ||||||
|  | } | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
| Sprig: Template functions for Go. | Package sprig provides template functions for Go. | ||||||
| 
 | 
 | ||||||
| This package contains a number of utility functions for working with data | This package contains a number of utility functions for working with data | ||||||
| inside of Go `html/template` and `text/template` files. | inside of Go `html/template` and `text/template` files. | ||||||
| @@ -3,8 +3,10 @@ package sprig | |||||||
| import ( | import ( | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"html/template" | 	"html/template" | ||||||
|  | 	"math/rand" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path" | 	"path" | ||||||
|  | 	"path/filepath" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| @@ -13,9 +15,10 @@ import ( | |||||||
| 
 | 
 | ||||||
| 	util "github.com/Masterminds/goutils" | 	util "github.com/Masterminds/goutils" | ||||||
| 	"github.com/huandu/xstrings" | 	"github.com/huandu/xstrings" | ||||||
|  | 	"github.com/shopspring/decimal" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Produce the function map. | // FuncMap produces the function map. | ||||||
| // | // | ||||||
| // Use this to pass the functions into the template engine: | // Use this to pass the functions into the template engine: | ||||||
| // | // | ||||||
| @@ -63,7 +66,7 @@ func GenericFuncMap() map[string]interface{} { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // These functions are not guaranteed to evaluate to the same result for given input, because they | // These functions are not guaranteed to evaluate to the same result for given input, because they | ||||||
| // refer to the environemnt or global state. | // refer to the environment or global state. | ||||||
| var nonhermeticFunctions = []string{ | var nonhermeticFunctions = []string{ | ||||||
| 	// Date functions | 	// Date functions | ||||||
| 	"date", | 	"date", | ||||||
| @@ -80,6 +83,7 @@ var nonhermeticFunctions = []string{ | |||||||
| 	"randAlpha", | 	"randAlpha", | ||||||
| 	"randAscii", | 	"randAscii", | ||||||
| 	"randNumeric", | 	"randNumeric", | ||||||
|  | 	"randBytes", | ||||||
| 	"uuidv4", | 	"uuidv4", | ||||||
| 
 | 
 | ||||||
| 	// OS | 	// OS | ||||||
| @@ -94,17 +98,22 @@ var genericMap = map[string]interface{}{ | |||||||
| 	"hello": func() string { return "Hello!" }, | 	"hello": func() string { return "Hello!" }, | ||||||
| 
 | 
 | ||||||
| 	// Date functions | 	// Date functions | ||||||
| 	"date":           date, | 	"ago":              dateAgo, | ||||||
| 	"date_in_zone":   dateInZone, | 	"date":             date, | ||||||
| 	"date_modify":    dateModify, | 	"date_in_zone":     dateInZone, | ||||||
| 	"now":            func() time.Time { return time.Now() }, | 	"date_modify":      dateModify, | ||||||
| 	"htmlDate":       htmlDate, | 	"dateInZone":       dateInZone, | ||||||
| 	"htmlDateInZone": htmlDateInZone, | 	"dateModify":       dateModify, | ||||||
| 	"dateInZone":     dateInZone, | 	"duration":         duration, | ||||||
| 	"dateModify":     dateModify, | 	"durationRound":    durationRound, | ||||||
| 	"ago":            dateAgo, | 	"htmlDate":         htmlDate, | ||||||
| 	"toDate":         toDate, | 	"htmlDateInZone":   htmlDateInZone, | ||||||
| 	"unixEpoch":      unixEpoch, | 	"must_date_modify": mustDateModify, | ||||||
|  | 	"mustDateModify":   mustDateModify, | ||||||
|  | 	"mustToDate":       mustToDate, | ||||||
|  | 	"now":              time.Now, | ||||||
|  | 	"toDate":           toDate, | ||||||
|  | 	"unixEpoch":        unixEpoch, | ||||||
| 
 | 
 | ||||||
| 	// Strings | 	// Strings | ||||||
| 	"abbrev":     abbrev, | 	"abbrev":     abbrev, | ||||||
| @@ -158,6 +167,7 @@ var genericMap = map[string]interface{}{ | |||||||
| 	"int64":     toInt64, | 	"int64":     toInt64, | ||||||
| 	"int":       toInt, | 	"int":       toInt, | ||||||
| 	"float64":   toFloat64, | 	"float64":   toFloat64, | ||||||
|  | 	"seq":       seq, | ||||||
| 	"toDecimal": toDecimal, | 	"toDecimal": toDecimal, | ||||||
| 
 | 
 | ||||||
| 	//"gt": func(a, b int) bool {return a > b}, | 	//"gt": func(a, b int) bool {return a > b}, | ||||||
| @@ -194,9 +204,28 @@ var genericMap = map[string]interface{}{ | |||||||
| 		} | 		} | ||||||
| 		return val | 		return val | ||||||
| 	}, | 	}, | ||||||
|  | 	"randInt": func(min, max int) int { return rand.Intn(max-min) + min }, | ||||||
|  | 	"add1f": func(i interface{}) float64 { | ||||||
|  | 		return execDecimalOp(i, []interface{}{1}, func(d1, d2 decimal.Decimal) decimal.Decimal { return d1.Add(d2) }) | ||||||
|  | 	}, | ||||||
|  | 	"addf": func(i ...interface{}) float64 { | ||||||
|  | 		a := interface{}(float64(0)) | ||||||
|  | 		return execDecimalOp(a, i, func(d1, d2 decimal.Decimal) decimal.Decimal { return d1.Add(d2) }) | ||||||
|  | 	}, | ||||||
|  | 	"subf": func(a interface{}, v ...interface{}) float64 { | ||||||
|  | 		return execDecimalOp(a, v, func(d1, d2 decimal.Decimal) decimal.Decimal { return d1.Sub(d2) }) | ||||||
|  | 	}, | ||||||
|  | 	"divf": func(a interface{}, v ...interface{}) float64 { | ||||||
|  | 		return execDecimalOp(a, v, func(d1, d2 decimal.Decimal) decimal.Decimal { return d1.Div(d2) }) | ||||||
|  | 	}, | ||||||
|  | 	"mulf": func(a interface{}, v ...interface{}) float64 { | ||||||
|  | 		return execDecimalOp(a, v, func(d1, d2 decimal.Decimal) decimal.Decimal { return d1.Mul(d2) }) | ||||||
|  | 	}, | ||||||
| 	"biggest": max, | 	"biggest": max, | ||||||
| 	"max":     max, | 	"max":     max, | ||||||
| 	"min":     min, | 	"min":     min, | ||||||
|  | 	"maxf":    maxf, | ||||||
|  | 	"minf":    minf, | ||||||
| 	"ceil":    ceil, | 	"ceil":    ceil, | ||||||
| 	"floor":   floor, | 	"floor":   floor, | ||||||
| 	"round":   round, | 	"round":   round, | ||||||
| @@ -207,14 +236,24 @@ var genericMap = map[string]interface{}{ | |||||||
| 	"sortAlpha": sortAlpha, | 	"sortAlpha": sortAlpha, | ||||||
| 
 | 
 | ||||||
| 	// Defaults | 	// Defaults | ||||||
| 	"default":      dfault, | 	"default":          dfault, | ||||||
| 	"empty":        empty, | 	"empty":            empty, | ||||||
| 	"coalesce":     coalesce, | 	"coalesce":         coalesce, | ||||||
| 	"compact":      compact, | 	"all":              all, | ||||||
| 	"deepCopy":     deepCopy, | 	"any":              any, | ||||||
| 	"toJson":       toJson, | 	"compact":          compact, | ||||||
| 	"toPrettyJson": toPrettyJson, | 	"mustCompact":      mustCompact, | ||||||
| 	"ternary":      ternary, | 	"fromJson":         fromJson, | ||||||
|  | 	"toJson":           toJson, | ||||||
|  | 	"toPrettyJson":     toPrettyJson, | ||||||
|  | 	"toRawJson":        toRawJson, | ||||||
|  | 	"mustFromJson":     mustFromJson, | ||||||
|  | 	"mustToJson":       mustToJson, | ||||||
|  | 	"mustToPrettyJson": mustToPrettyJson, | ||||||
|  | 	"mustToRawJson":    mustToRawJson, | ||||||
|  | 	"ternary":          ternary, | ||||||
|  | 	"deepCopy":         deepCopy, | ||||||
|  | 	"mustDeepCopy":     mustDeepCopy, | ||||||
| 
 | 
 | ||||||
| 	// Reflection | 	// Reflection | ||||||
| 	"typeOf":     typeOf, | 	"typeOf":     typeOf, | ||||||
| @@ -225,19 +264,26 @@ var genericMap = map[string]interface{}{ | |||||||
| 	"deepEqual":  reflect.DeepEqual, | 	"deepEqual":  reflect.DeepEqual, | ||||||
| 
 | 
 | ||||||
| 	// OS: | 	// OS: | ||||||
| 	"env":       func(s string) string { return os.Getenv(s) }, | 	"env":       os.Getenv, | ||||||
| 	"expandenv": func(s string) string { return os.ExpandEnv(s) }, | 	"expandenv": os.ExpandEnv, | ||||||
| 
 | 
 | ||||||
| 	// Network: | 	// Network: | ||||||
| 	"getHostByName": getHostByName, | 	"getHostByName": getHostByName, | ||||||
| 
 | 
 | ||||||
| 	// File Paths: | 	// Paths: | ||||||
| 	"base":  path.Base, | 	"base":  path.Base, | ||||||
| 	"dir":   path.Dir, | 	"dir":   path.Dir, | ||||||
| 	"clean": path.Clean, | 	"clean": path.Clean, | ||||||
| 	"ext":   path.Ext, | 	"ext":   path.Ext, | ||||||
| 	"isAbs": path.IsAbs, | 	"isAbs": path.IsAbs, | ||||||
| 
 | 
 | ||||||
|  | 	// Filepaths: | ||||||
|  | 	"osBase":  filepath.Base, | ||||||
|  | 	"osClean": filepath.Clean, | ||||||
|  | 	"osDir":   filepath.Dir, | ||||||
|  | 	"osExt":   filepath.Ext, | ||||||
|  | 	"osIsAbs": filepath.IsAbs, | ||||||
|  | 
 | ||||||
| 	// Encoding: | 	// Encoding: | ||||||
| 	"b64enc": base64encode, | 	"b64enc": base64encode, | ||||||
| 	"b64dec": base64decode, | 	"b64dec": base64decode, | ||||||
| @@ -245,42 +291,65 @@ var genericMap = map[string]interface{}{ | |||||||
| 	"b32dec": base32decode, | 	"b32dec": base32decode, | ||||||
| 
 | 
 | ||||||
| 	// Data Structures: | 	// Data Structures: | ||||||
| 	"tuple":          list, // FIXME: with the addition of append/prepend these are no longer immutable. | 	"tuple":              list, // FIXME: with the addition of append/prepend these are no longer immutable. | ||||||
| 	"list":           list, | 	"list":               list, | ||||||
| 	"dict":           dict, | 	"dict":               dict, | ||||||
| 	"set":            set, | 	"get":                get, | ||||||
| 	"unset":          unset, | 	"set":                set, | ||||||
| 	"hasKey":         hasKey, | 	"unset":              unset, | ||||||
| 	"pluck":          pluck, | 	"hasKey":             hasKey, | ||||||
| 	"keys":           keys, | 	"pluck":              pluck, | ||||||
| 	"pick":           pick, | 	"keys":               keys, | ||||||
| 	"omit":           omit, | 	"pick":               pick, | ||||||
| 	"merge":          merge, | 	"omit":               omit, | ||||||
| 	"mergeOverwrite": mergeOverwrite, | 	"merge":              merge, | ||||||
| 	"values":         values, | 	"mergeOverwrite":     mergeOverwrite, | ||||||
|  | 	"mustMerge":          mustMerge, | ||||||
|  | 	"mustMergeOverwrite": mustMergeOverwrite, | ||||||
|  | 	"values":             values, | ||||||
| 
 | 
 | ||||||
| 	"append": push, "push": push, | 	"append": push, "push": push, | ||||||
| 	"prepend": prepend, | 	"mustAppend": mustPush, "mustPush": mustPush, | ||||||
| 	"first":   first, | 	"prepend":     prepend, | ||||||
| 	"rest":    rest, | 	"mustPrepend": mustPrepend, | ||||||
| 	"last":    last, | 	"first":       first, | ||||||
| 	"initial": initial, | 	"mustFirst":   mustFirst, | ||||||
| 	"reverse": reverse, | 	"rest":        rest, | ||||||
| 	"uniq":    uniq, | 	"mustRest":    mustRest, | ||||||
| 	"without": without, | 	"last":        last, | ||||||
| 	"has":     has, | 	"mustLast":    mustLast, | ||||||
| 	"slice":   slice, | 	"initial":     initial, | ||||||
| 	"concat":  concat, | 	"mustInitial": mustInitial, | ||||||
|  | 	"reverse":     reverse, | ||||||
|  | 	"mustReverse": mustReverse, | ||||||
|  | 	"uniq":        uniq, | ||||||
|  | 	"mustUniq":    mustUniq, | ||||||
|  | 	"without":     without, | ||||||
|  | 	"mustWithout": mustWithout, | ||||||
|  | 	"has":         has, | ||||||
|  | 	"mustHas":     mustHas, | ||||||
|  | 	"slice":       slice, | ||||||
|  | 	"mustSlice":   mustSlice, | ||||||
|  | 	"concat":      concat, | ||||||
|  | 	"dig":         dig, | ||||||
|  | 	"chunk":       chunk, | ||||||
|  | 	"mustChunk":   mustChunk, | ||||||
| 
 | 
 | ||||||
| 	// Crypto: | 	// Crypto: | ||||||
|  | 	"bcrypt":            bcrypt, | ||||||
|  | 	"htpasswd":          htpasswd, | ||||||
| 	"genPrivateKey":     generatePrivateKey, | 	"genPrivateKey":     generatePrivateKey, | ||||||
| 	"derivePassword":    derivePassword, | 	"derivePassword":    derivePassword, | ||||||
| 	"buildCustomCert":   buildCustomCertificate, | 	"buildCustomCert":   buildCustomCertificate, | ||||||
| 	"genCA":             generateCertificateAuthority, | 	"genCA":             generateCertificateAuthority, | ||||||
|  | 	"genCAWithKey":      generateCertificateAuthorityWithPEMKey, | ||||||
| 	"genSelfSignedCert": generateSelfSignedCertificate, | 	"genSelfSignedCert": generateSelfSignedCertificate, | ||||||
|  | 	"genSelfSignedCertWithKey": generateSelfSignedCertificateWithPEMKey, | ||||||
| 	"genSignedCert":     generateSignedCertificate, | 	"genSignedCert":     generateSignedCertificate, | ||||||
|  | 	"genSignedCertWithKey": generateSignedCertificateWithPEMKey, | ||||||
| 	"encryptAES":        encryptAES, | 	"encryptAES":        encryptAES, | ||||||
| 	"decryptAES":        decryptAES, | 	"decryptAES":        decryptAES, | ||||||
|  | 	"randBytes":         randBytes, | ||||||
| 
 | 
 | ||||||
| 	// UUIDs: | 	// UUIDs: | ||||||
| 	"uuidv4": uuidv4, | 	"uuidv4": uuidv4, | ||||||
| @@ -293,12 +362,19 @@ var genericMap = map[string]interface{}{ | |||||||
| 	"fail": func(msg string) (string, error) { return "", errors.New(msg) }, | 	"fail": func(msg string) (string, error) { return "", errors.New(msg) }, | ||||||
| 
 | 
 | ||||||
| 	// Regex | 	// Regex | ||||||
| 	"regexMatch":             regexMatch, | 	"regexMatch":                 regexMatch, | ||||||
| 	"regexFindAll":           regexFindAll, | 	"mustRegexMatch":             mustRegexMatch, | ||||||
| 	"regexFind":              regexFind, | 	"regexFindAll":               regexFindAll, | ||||||
| 	"regexReplaceAll":        regexReplaceAll, | 	"mustRegexFindAll":           mustRegexFindAll, | ||||||
| 	"regexReplaceAllLiteral": regexReplaceAllLiteral, | 	"regexFind":                  regexFind, | ||||||
| 	"regexSplit":             regexSplit, | 	"mustRegexFind":              mustRegexFind, | ||||||
|  | 	"regexReplaceAll":            regexReplaceAll, | ||||||
|  | 	"mustRegexReplaceAll":        mustRegexReplaceAll, | ||||||
|  | 	"regexReplaceAllLiteral":     regexReplaceAllLiteral, | ||||||
|  | 	"mustRegexReplaceAllLiteral": mustRegexReplaceAllLiteral, | ||||||
|  | 	"regexSplit":                 regexSplit, | ||||||
|  | 	"mustRegexSplit":             mustRegexSplit, | ||||||
|  | 	"regexQuoteMeta":             regexQuoteMeta, | ||||||
| 
 | 
 | ||||||
| 	// URLs: | 	// URLs: | ||||||
| 	"urlParse": urlParse, | 	"urlParse": urlParse, | ||||||
							
								
								
									
										215
									
								
								vendor/github.com/Masterminds/sprig/list.go → vendor/github.com/Masterminds/sprig/v3/list.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										215
									
								
								vendor/github.com/Masterminds/sprig/list.go → vendor/github.com/Masterminds/sprig/v3/list.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -2,6 +2,7 @@ package sprig | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"math" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"sort" | 	"sort" | ||||||
| ) | ) | ||||||
| @@ -15,6 +16,15 @@ func list(v ...interface{}) []interface{} { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func push(list interface{}, v interface{}) []interface{} { | func push(list interface{}, v interface{}) []interface{} { | ||||||
|  | 	l, err := mustPush(list, v) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func mustPush(list interface{}, v interface{}) ([]interface{}, error) { | ||||||
| 	tp := reflect.TypeOf(list).Kind() | 	tp := reflect.TypeOf(list).Kind() | ||||||
| 	switch tp { | 	switch tp { | ||||||
| 	case reflect.Slice, reflect.Array: | 	case reflect.Slice, reflect.Array: | ||||||
| @@ -26,14 +36,23 @@ func push(list interface{}, v interface{}) []interface{} { | |||||||
| 			nl[i] = l2.Index(i).Interface() | 			nl[i] = l2.Index(i).Interface() | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return append(nl, v) | 		return append(nl, v), nil | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		panic(fmt.Sprintf("Cannot push on type %s", tp)) | 		return nil, fmt.Errorf("Cannot push on type %s", tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func prepend(list interface{}, v interface{}) []interface{} { | func prepend(list interface{}, v interface{}) []interface{} { | ||||||
|  | 	l, err := mustPrepend(list, v) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func mustPrepend(list interface{}, v interface{}) ([]interface{}, error) { | ||||||
| 	//return append([]interface{}{v}, list...) | 	//return append([]interface{}{v}, list...) | ||||||
| 
 | 
 | ||||||
| 	tp := reflect.TypeOf(list).Kind() | 	tp := reflect.TypeOf(list).Kind() | ||||||
| @@ -47,14 +66,67 @@ func prepend(list interface{}, v interface{}) []interface{} { | |||||||
| 			nl[i] = l2.Index(i).Interface() | 			nl[i] = l2.Index(i).Interface() | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return append([]interface{}{v}, nl...) | 		return append([]interface{}{v}, nl...), nil | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		panic(fmt.Sprintf("Cannot prepend on type %s", tp)) | 		return nil, fmt.Errorf("Cannot prepend on type %s", tp) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func chunk(size int, list interface{}) [][]interface{} { | ||||||
|  | 	l, err := mustChunk(size, list) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func mustChunk(size int, list interface{}) ([][]interface{}, error) { | ||||||
|  | 	tp := reflect.TypeOf(list).Kind() | ||||||
|  | 	switch tp { | ||||||
|  | 	case reflect.Slice, reflect.Array: | ||||||
|  | 		l2 := reflect.ValueOf(list) | ||||||
|  | 
 | ||||||
|  | 		l := l2.Len() | ||||||
|  | 
 | ||||||
|  | 		cs := int(math.Floor(float64(l-1)/float64(size)) + 1) | ||||||
|  | 		nl := make([][]interface{}, cs) | ||||||
|  | 
 | ||||||
|  | 		for i := 0; i < cs; i++ { | ||||||
|  | 			clen := size | ||||||
|  | 			if i == cs-1 { | ||||||
|  | 				clen = int(math.Floor(math.Mod(float64(l), float64(size)))) | ||||||
|  | 				if clen == 0 { | ||||||
|  | 					clen = size | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			nl[i] = make([]interface{}, clen) | ||||||
|  | 
 | ||||||
|  | 			for j := 0; j < clen; j++ { | ||||||
|  | 				ix := i*size + j | ||||||
|  | 				nl[i][j] = l2.Index(ix).Interface() | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return nl, nil | ||||||
|  | 
 | ||||||
|  | 	default: | ||||||
|  | 		return nil, fmt.Errorf("Cannot chunk type %s", tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func last(list interface{}) interface{} { | func last(list interface{}) interface{} { | ||||||
|  | 	l, err := mustLast(list) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func mustLast(list interface{}) (interface{}, error) { | ||||||
| 	tp := reflect.TypeOf(list).Kind() | 	tp := reflect.TypeOf(list).Kind() | ||||||
| 	switch tp { | 	switch tp { | ||||||
| 	case reflect.Slice, reflect.Array: | 	case reflect.Slice, reflect.Array: | ||||||
| @@ -62,16 +134,25 @@ func last(list interface{}) interface{} { | |||||||
| 
 | 
 | ||||||
| 		l := l2.Len() | 		l := l2.Len() | ||||||
| 		if l == 0 { | 		if l == 0 { | ||||||
| 			return nil | 			return nil, nil | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return l2.Index(l - 1).Interface() | 		return l2.Index(l - 1).Interface(), nil | ||||||
| 	default: | 	default: | ||||||
| 		panic(fmt.Sprintf("Cannot find last on type %s", tp)) | 		return nil, fmt.Errorf("Cannot find last on type %s", tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func first(list interface{}) interface{} { | func first(list interface{}) interface{} { | ||||||
|  | 	l, err := mustFirst(list) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func mustFirst(list interface{}) (interface{}, error) { | ||||||
| 	tp := reflect.TypeOf(list).Kind() | 	tp := reflect.TypeOf(list).Kind() | ||||||
| 	switch tp { | 	switch tp { | ||||||
| 	case reflect.Slice, reflect.Array: | 	case reflect.Slice, reflect.Array: | ||||||
| @@ -79,16 +160,25 @@ func first(list interface{}) interface{} { | |||||||
| 
 | 
 | ||||||
| 		l := l2.Len() | 		l := l2.Len() | ||||||
| 		if l == 0 { | 		if l == 0 { | ||||||
| 			return nil | 			return nil, nil | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return l2.Index(0).Interface() | 		return l2.Index(0).Interface(), nil | ||||||
| 	default: | 	default: | ||||||
| 		panic(fmt.Sprintf("Cannot find first on type %s", tp)) | 		return nil, fmt.Errorf("Cannot find first on type %s", tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func rest(list interface{}) []interface{} { | func rest(list interface{}) []interface{} { | ||||||
|  | 	l, err := mustRest(list) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func mustRest(list interface{}) ([]interface{}, error) { | ||||||
| 	tp := reflect.TypeOf(list).Kind() | 	tp := reflect.TypeOf(list).Kind() | ||||||
| 	switch tp { | 	switch tp { | ||||||
| 	case reflect.Slice, reflect.Array: | 	case reflect.Slice, reflect.Array: | ||||||
| @@ -96,7 +186,7 @@ func rest(list interface{}) []interface{} { | |||||||
| 
 | 
 | ||||||
| 		l := l2.Len() | 		l := l2.Len() | ||||||
| 		if l == 0 { | 		if l == 0 { | ||||||
| 			return nil | 			return nil, nil | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		nl := make([]interface{}, l-1) | 		nl := make([]interface{}, l-1) | ||||||
| @@ -104,13 +194,22 @@ func rest(list interface{}) []interface{} { | |||||||
| 			nl[i-1] = l2.Index(i).Interface() | 			nl[i-1] = l2.Index(i).Interface() | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return nl | 		return nl, nil | ||||||
| 	default: | 	default: | ||||||
| 		panic(fmt.Sprintf("Cannot find rest on type %s", tp)) | 		return nil, fmt.Errorf("Cannot find rest on type %s", tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func initial(list interface{}) []interface{} { | func initial(list interface{}) []interface{} { | ||||||
|  | 	l, err := mustInitial(list) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func mustInitial(list interface{}) ([]interface{}, error) { | ||||||
| 	tp := reflect.TypeOf(list).Kind() | 	tp := reflect.TypeOf(list).Kind() | ||||||
| 	switch tp { | 	switch tp { | ||||||
| 	case reflect.Slice, reflect.Array: | 	case reflect.Slice, reflect.Array: | ||||||
| @@ -118,7 +217,7 @@ func initial(list interface{}) []interface{} { | |||||||
| 
 | 
 | ||||||
| 		l := l2.Len() | 		l := l2.Len() | ||||||
| 		if l == 0 { | 		if l == 0 { | ||||||
| 			return nil | 			return nil, nil | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		nl := make([]interface{}, l-1) | 		nl := make([]interface{}, l-1) | ||||||
| @@ -126,9 +225,9 @@ func initial(list interface{}) []interface{} { | |||||||
| 			nl[i] = l2.Index(i).Interface() | 			nl[i] = l2.Index(i).Interface() | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return nl | 		return nl, nil | ||||||
| 	default: | 	default: | ||||||
| 		panic(fmt.Sprintf("Cannot find initial on type %s", tp)) | 		return nil, fmt.Errorf("Cannot find initial on type %s", tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -145,6 +244,15 @@ func sortAlpha(list interface{}) []string { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func reverse(v interface{}) []interface{} { | func reverse(v interface{}) []interface{} { | ||||||
|  | 	l, err := mustReverse(v) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func mustReverse(v interface{}) ([]interface{}, error) { | ||||||
| 	tp := reflect.TypeOf(v).Kind() | 	tp := reflect.TypeOf(v).Kind() | ||||||
| 	switch tp { | 	switch tp { | ||||||
| 	case reflect.Slice, reflect.Array: | 	case reflect.Slice, reflect.Array: | ||||||
| @@ -157,13 +265,22 @@ func reverse(v interface{}) []interface{} { | |||||||
| 			nl[l-i-1] = l2.Index(i).Interface() | 			nl[l-i-1] = l2.Index(i).Interface() | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return nl | 		return nl, nil | ||||||
| 	default: | 	default: | ||||||
| 		panic(fmt.Sprintf("Cannot find reverse on type %s", tp)) | 		return nil, fmt.Errorf("Cannot find reverse on type %s", tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func compact(list interface{}) []interface{} { | func compact(list interface{}) []interface{} { | ||||||
|  | 	l, err := mustCompact(list) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func mustCompact(list interface{}) ([]interface{}, error) { | ||||||
| 	tp := reflect.TypeOf(list).Kind() | 	tp := reflect.TypeOf(list).Kind() | ||||||
| 	switch tp { | 	switch tp { | ||||||
| 	case reflect.Slice, reflect.Array: | 	case reflect.Slice, reflect.Array: | ||||||
| @@ -179,13 +296,22 @@ func compact(list interface{}) []interface{} { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return nl | 		return nl, nil | ||||||
| 	default: | 	default: | ||||||
| 		panic(fmt.Sprintf("Cannot compact on type %s", tp)) | 		return nil, fmt.Errorf("Cannot compact on type %s", tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func uniq(list interface{}) []interface{} { | func uniq(list interface{}) []interface{} { | ||||||
|  | 	l, err := mustUniq(list) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func mustUniq(list interface{}) ([]interface{}, error) { | ||||||
| 	tp := reflect.TypeOf(list).Kind() | 	tp := reflect.TypeOf(list).Kind() | ||||||
| 	switch tp { | 	switch tp { | ||||||
| 	case reflect.Slice, reflect.Array: | 	case reflect.Slice, reflect.Array: | ||||||
| @@ -201,9 +327,9 @@ func uniq(list interface{}) []interface{} { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return dest | 		return dest, nil | ||||||
| 	default: | 	default: | ||||||
| 		panic(fmt.Sprintf("Cannot find uniq on type %s", tp)) | 		return nil, fmt.Errorf("Cannot find uniq on type %s", tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -217,6 +343,15 @@ func inList(haystack []interface{}, needle interface{}) bool { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func without(list interface{}, omit ...interface{}) []interface{} { | func without(list interface{}, omit ...interface{}) []interface{} { | ||||||
|  | 	l, err := mustWithout(list, omit...) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func mustWithout(list interface{}, omit ...interface{}) ([]interface{}, error) { | ||||||
| 	tp := reflect.TypeOf(list).Kind() | 	tp := reflect.TypeOf(list).Kind() | ||||||
| 	switch tp { | 	switch tp { | ||||||
| 	case reflect.Slice, reflect.Array: | 	case reflect.Slice, reflect.Array: | ||||||
| @@ -232,15 +367,24 @@ func without(list interface{}, omit ...interface{}) []interface{} { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return res | 		return res, nil | ||||||
| 	default: | 	default: | ||||||
| 		panic(fmt.Sprintf("Cannot find without on type %s", tp)) | 		return nil, fmt.Errorf("Cannot find without on type %s", tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func has(needle interface{}, haystack interface{}) bool { | func has(needle interface{}, haystack interface{}) bool { | ||||||
|  | 	l, err := mustHas(needle, haystack) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func mustHas(needle interface{}, haystack interface{}) (bool, error) { | ||||||
| 	if haystack == nil { | 	if haystack == nil { | ||||||
| 		return false | 		return false, nil | ||||||
| 	} | 	} | ||||||
| 	tp := reflect.TypeOf(haystack).Kind() | 	tp := reflect.TypeOf(haystack).Kind() | ||||||
| 	switch tp { | 	switch tp { | ||||||
| @@ -251,13 +395,13 @@ func has(needle interface{}, haystack interface{}) bool { | |||||||
| 		for i := 0; i < l; i++ { | 		for i := 0; i < l; i++ { | ||||||
| 			item = l2.Index(i).Interface() | 			item = l2.Index(i).Interface() | ||||||
| 			if reflect.DeepEqual(needle, item) { | 			if reflect.DeepEqual(needle, item) { | ||||||
| 				return true | 				return true, nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return false | 		return false, nil | ||||||
| 	default: | 	default: | ||||||
| 		panic(fmt.Sprintf("Cannot find has on type %s", tp)) | 		return false, fmt.Errorf("Cannot find has on type %s", tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -267,6 +411,15 @@ func has(needle interface{}, haystack interface{}) bool { | |||||||
| // slice $list 3 5 -> list[3:5] | // slice $list 3 5 -> list[3:5] | ||||||
| // slice $list 3   -> list[3:5] = list[3:] | // slice $list 3   -> list[3:5] = list[3:] | ||||||
| func slice(list interface{}, indices ...interface{}) interface{} { | func slice(list interface{}, indices ...interface{}) interface{} { | ||||||
|  | 	l, err := mustSlice(list, indices...) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func mustSlice(list interface{}, indices ...interface{}) (interface{}, error) { | ||||||
| 	tp := reflect.TypeOf(list).Kind() | 	tp := reflect.TypeOf(list).Kind() | ||||||
| 	switch tp { | 	switch tp { | ||||||
| 	case reflect.Slice, reflect.Array: | 	case reflect.Slice, reflect.Array: | ||||||
| @@ -274,7 +427,7 @@ func slice(list interface{}, indices ...interface{}) interface{} { | |||||||
| 
 | 
 | ||||||
| 		l := l2.Len() | 		l := l2.Len() | ||||||
| 		if l == 0 { | 		if l == 0 { | ||||||
| 			return nil | 			return nil, nil | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		var start, end int | 		var start, end int | ||||||
| @@ -287,9 +440,9 @@ func slice(list interface{}, indices ...interface{}) interface{} { | |||||||
| 			end = toInt(indices[1]) | 			end = toInt(indices[1]) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return l2.Slice(start, end).Interface() | 		return l2.Slice(start, end).Interface(), nil | ||||||
| 	default: | 	default: | ||||||
| 		panic(fmt.Sprintf("list should be type of slice or array but %s", tp)) | 		return nil, fmt.Errorf("list should be type of slice or array but %s", tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -7,6 +7,6 @@ import ( | |||||||
| 
 | 
 | ||||||
| func getHostByName(name string) string { | func getHostByName(name string) string { | ||||||
| 	addrs, _ := net.LookupHost(name) | 	addrs, _ := net.LookupHost(name) | ||||||
| 	//TODO: add error handing when release v3 cames out | 	//TODO: add error handing when release v3 comes out | ||||||
| 	return addrs[rand.Intn(len(addrs))] | 	return addrs[rand.Intn(len(addrs))] | ||||||
| } | } | ||||||
							
								
								
									
										186
									
								
								vendor/github.com/Masterminds/sprig/v3/numeric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								vendor/github.com/Masterminds/sprig/v3/numeric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,186 @@ | |||||||
|  | package sprig | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"math" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
|  | 	"github.com/spf13/cast" | ||||||
|  | 	"github.com/shopspring/decimal" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // toFloat64 converts 64-bit floats | ||||||
|  | func toFloat64(v interface{}) float64 { | ||||||
|  | 	return cast.ToFloat64(v) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func toInt(v interface{}) int { | ||||||
|  | 	return cast.ToInt(v) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // toInt64 converts integer types to 64-bit integers | ||||||
|  | func toInt64(v interface{}) int64 { | ||||||
|  | 	return cast.ToInt64(v) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func max(a interface{}, i ...interface{}) int64 { | ||||||
|  | 	aa := toInt64(a) | ||||||
|  | 	for _, b := range i { | ||||||
|  | 		bb := toInt64(b) | ||||||
|  | 		if bb > aa { | ||||||
|  | 			aa = bb | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return aa | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func maxf(a interface{}, i ...interface{}) float64 { | ||||||
|  | 	aa := toFloat64(a) | ||||||
|  | 	for _, b := range i { | ||||||
|  | 		bb := toFloat64(b) | ||||||
|  | 		aa = math.Max(aa, bb) | ||||||
|  | 	} | ||||||
|  | 	return aa | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func min(a interface{}, i ...interface{}) int64 { | ||||||
|  | 	aa := toInt64(a) | ||||||
|  | 	for _, b := range i { | ||||||
|  | 		bb := toInt64(b) | ||||||
|  | 		if bb < aa { | ||||||
|  | 			aa = bb | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return aa | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func minf(a interface{}, i ...interface{}) float64 { | ||||||
|  | 	aa := toFloat64(a) | ||||||
|  | 	for _, b := range i { | ||||||
|  | 		bb := toFloat64(b) | ||||||
|  | 		aa = math.Min(aa, bb) | ||||||
|  | 	} | ||||||
|  | 	return aa | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func until(count int) []int { | ||||||
|  | 	step := 1 | ||||||
|  | 	if count < 0 { | ||||||
|  | 		step = -1 | ||||||
|  | 	} | ||||||
|  | 	return untilStep(0, count, step) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func untilStep(start, stop, step int) []int { | ||||||
|  | 	v := []int{} | ||||||
|  |  | ||||||
|  | 	if stop < start { | ||||||
|  | 		if step >= 0 { | ||||||
|  | 			return v | ||||||
|  | 		} | ||||||
|  | 		for i := start; i > stop; i += step { | ||||||
|  | 			v = append(v, i) | ||||||
|  | 		} | ||||||
|  | 		return v | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if step <= 0 { | ||||||
|  | 		return v | ||||||
|  | 	} | ||||||
|  | 	for i := start; i < stop; i += step { | ||||||
|  | 		v = append(v, i) | ||||||
|  | 	} | ||||||
|  | 	return v | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func floor(a interface{}) float64 { | ||||||
|  | 	aa := toFloat64(a) | ||||||
|  | 	return math.Floor(aa) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func ceil(a interface{}) float64 { | ||||||
|  | 	aa := toFloat64(a) | ||||||
|  | 	return math.Ceil(aa) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func round(a interface{}, p int, rOpt ...float64) float64 { | ||||||
|  | 	roundOn := .5 | ||||||
|  | 	if len(rOpt) > 0 { | ||||||
|  | 		roundOn = rOpt[0] | ||||||
|  | 	} | ||||||
|  | 	val := toFloat64(a) | ||||||
|  | 	places := toFloat64(p) | ||||||
|  |  | ||||||
|  | 	var round float64 | ||||||
|  | 	pow := math.Pow(10, places) | ||||||
|  | 	digit := pow * val | ||||||
|  | 	_, div := math.Modf(digit) | ||||||
|  | 	if div >= roundOn { | ||||||
|  | 		round = math.Ceil(digit) | ||||||
|  | 	} else { | ||||||
|  | 		round = math.Floor(digit) | ||||||
|  | 	} | ||||||
|  | 	return round / pow | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // converts unix octal to decimal | ||||||
|  | func toDecimal(v interface{}) int64 { | ||||||
|  | 	result, err := strconv.ParseInt(fmt.Sprint(v), 8, 64) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  | 	return result | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func seq(params ...int) string { | ||||||
|  | 	increment := 1 | ||||||
|  | 	switch len(params) { | ||||||
|  | 	case 0: | ||||||
|  | 		return "" | ||||||
|  | 	case 1: | ||||||
|  | 		start := 1 | ||||||
|  | 		end := params[0] | ||||||
|  | 		if end < start { | ||||||
|  | 			increment = -1 | ||||||
|  | 		} | ||||||
|  | 		return intArrayToString(untilStep(start, end+increment, increment), " ") | ||||||
|  | 	case 3: | ||||||
|  | 		start := params[0] | ||||||
|  | 		end := params[2] | ||||||
|  | 		step := params[1] | ||||||
|  | 		if end < start { | ||||||
|  | 			increment = -1 | ||||||
|  | 			if step > 0 { | ||||||
|  | 				return "" | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return intArrayToString(untilStep(start, end+increment, step), " ") | ||||||
|  | 	case 2: | ||||||
|  | 		start := params[0] | ||||||
|  | 		end := params[1] | ||||||
|  | 		step := 1 | ||||||
|  | 		if end < start { | ||||||
|  | 			step = -1 | ||||||
|  | 		} | ||||||
|  | 		return intArrayToString(untilStep(start, end+step, step), " ") | ||||||
|  | 	default: | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func intArrayToString(slice []int, delimeter string) string { | ||||||
|  | 	return strings.Trim(strings.Join(strings.Fields(fmt.Sprint(slice)), delimeter), "[]") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // performs a float and subsequent decimal.Decimal conversion on inputs, | ||||||
|  | // and iterates through a and b executing the mathmetical operation f | ||||||
|  | func execDecimalOp(a interface{}, b []interface{}, f func(d1, d2 decimal.Decimal) decimal.Decimal) float64 { | ||||||
|  | 	prt := decimal.NewFromFloat(toFloat64(a)) | ||||||
|  | 	for _, x := range b { | ||||||
|  | 		dx := decimal.NewFromFloat(toFloat64(x)) | ||||||
|  | 		prt = f(prt, dx) | ||||||
|  | 	} | ||||||
|  | 	rslt, _ := prt.Float64() | ||||||
|  | 	return rslt | ||||||
|  | } | ||||||
							
								
								
									
										83
									
								
								vendor/github.com/Masterminds/sprig/v3/regex.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								vendor/github.com/Masterminds/sprig/v3/regex.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | |||||||
|  | package sprig | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"regexp" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func regexMatch(regex string, s string) bool { | ||||||
|  | 	match, _ := regexp.MatchString(regex, s) | ||||||
|  | 	return match | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func mustRegexMatch(regex string, s string) (bool, error) { | ||||||
|  | 	return regexp.MatchString(regex, s) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func regexFindAll(regex string, s string, n int) []string { | ||||||
|  | 	r := regexp.MustCompile(regex) | ||||||
|  | 	return r.FindAllString(s, n) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func mustRegexFindAll(regex string, s string, n int) ([]string, error) { | ||||||
|  | 	r, err := regexp.Compile(regex) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return []string{}, err | ||||||
|  | 	} | ||||||
|  | 	return r.FindAllString(s, n), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func regexFind(regex string, s string) string { | ||||||
|  | 	r := regexp.MustCompile(regex) | ||||||
|  | 	return r.FindString(s) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func mustRegexFind(regex string, s string) (string, error) { | ||||||
|  | 	r, err := regexp.Compile(regex) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return r.FindString(s), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func regexReplaceAll(regex string, s string, repl string) string { | ||||||
|  | 	r := regexp.MustCompile(regex) | ||||||
|  | 	return r.ReplaceAllString(s, repl) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func mustRegexReplaceAll(regex string, s string, repl string) (string, error) { | ||||||
|  | 	r, err := regexp.Compile(regex) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return r.ReplaceAllString(s, repl), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func regexReplaceAllLiteral(regex string, s string, repl string) string { | ||||||
|  | 	r := regexp.MustCompile(regex) | ||||||
|  | 	return r.ReplaceAllLiteralString(s, repl) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func mustRegexReplaceAllLiteral(regex string, s string, repl string) (string, error) { | ||||||
|  | 	r, err := regexp.Compile(regex) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return r.ReplaceAllLiteralString(s, repl), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func regexSplit(regex string, s string, n int) []string { | ||||||
|  | 	r := regexp.MustCompile(regex) | ||||||
|  | 	return r.Split(s, n) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func mustRegexSplit(regex string, s string, n int) ([]string, error) { | ||||||
|  | 	r, err := regexp.Compile(regex) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return []string{}, err | ||||||
|  | 	} | ||||||
|  | 	return r.Split(s, n), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func regexQuoteMeta(s string) string { | ||||||
|  | 	return regexp.QuoteMeta(s) | ||||||
|  | } | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| package sprig | package sprig | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	sv2 "github.com/Masterminds/semver" | 	sv2 "github.com/Masterminds/semver/v3" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func semverCompare(constraint, version string) (bool, error) { | func semverCompare(constraint, version string) (bool, error) { | ||||||
| @@ -154,9 +154,9 @@ func strslice(v interface{}) []string { | |||||||
| 		default: | 		default: | ||||||
| 			if v == nil { | 			if v == nil { | ||||||
| 				return []string{} | 				return []string{} | ||||||
| 			} else { |  | ||||||
| 				return []string{strval(v)} |  | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
|  | 			return []string{strval(v)} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -187,10 +187,13 @@ func strval(v interface{}) string { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func trunc(c int, s string) string { | func trunc(c int, s string) string { | ||||||
| 	if len(s) <= c { | 	if c < 0 && len(s)+c > 0 { | ||||||
| 		return s | 		return s[len(s)+c:] | ||||||
| 	} | 	} | ||||||
| 	return s[0:c] | 	if c >= 0 && len(s) > c { | ||||||
|  | 		return s[:c] | ||||||
|  | 	} | ||||||
|  | 	return s | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func join(sep string, v interface{}) string { | func join(sep string, v interface{}) string { | ||||||
| @@ -7,7 +7,8 @@ import ( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func dictGetOrEmpty(dict map[string]interface{}, key string) string { | func dictGetOrEmpty(dict map[string]interface{}, key string) string { | ||||||
| 	value, ok := dict[key]; if !ok { | 	value, ok := dict[key] | ||||||
|  | 	if !ok { | ||||||
| 		return "" | 		return "" | ||||||
| 	} | 	} | ||||||
| 	tp := reflect.TypeOf(value).Kind() | 	tp := reflect.TypeOf(value).Kind() | ||||||
| @@ -20,19 +21,19 @@ func dictGetOrEmpty(dict map[string]interface{}, key string) string { | |||||||
| // parses given URL to return dict object | // parses given URL to return dict object | ||||||
| func urlParse(v string) map[string]interface{} { | func urlParse(v string) map[string]interface{} { | ||||||
| 	dict := map[string]interface{}{} | 	dict := map[string]interface{}{} | ||||||
| 	parsedUrl, err := url.Parse(v) | 	parsedURL, err := url.Parse(v) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		panic(fmt.Sprintf("unable to parse url: %s", err)) | 		panic(fmt.Sprintf("unable to parse url: %s", err)) | ||||||
| 	} | 	} | ||||||
| 	dict["scheme"]    = parsedUrl.Scheme | 	dict["scheme"] = parsedURL.Scheme | ||||||
| 	dict["host"]      = parsedUrl.Host | 	dict["host"] = parsedURL.Host | ||||||
| 	dict["hostname"]  = parsedUrl.Hostname() | 	dict["hostname"] = parsedURL.Hostname() | ||||||
| 	dict["path"]      = parsedUrl.Path | 	dict["path"] = parsedURL.Path | ||||||
| 	dict["query"]     = parsedUrl.RawQuery | 	dict["query"] = parsedURL.RawQuery | ||||||
| 	dict["opaque"]    = parsedUrl.Opaque | 	dict["opaque"] = parsedURL.Opaque | ||||||
| 	dict["fragment"]  = parsedUrl.Fragment | 	dict["fragment"] = parsedURL.Fragment | ||||||
| 	if parsedUrl.User != nil { | 	if parsedURL.User != nil { | ||||||
| 		dict["userinfo"]  = parsedUrl.User.String() | 		dict["userinfo"] = parsedURL.User.String() | ||||||
| 	} else { | 	} else { | ||||||
| 		dict["userinfo"] = "" | 		dict["userinfo"] = "" | ||||||
| 	} | 	} | ||||||
| @@ -42,25 +43,24 @@ func urlParse(v string) map[string]interface{} { | |||||||
| 
 | 
 | ||||||
| // join given dict to URL string | // join given dict to URL string | ||||||
| func urlJoin(d map[string]interface{}) string { | func urlJoin(d map[string]interface{}) string { | ||||||
| 	resUrl := url.URL{ | 	resURL := url.URL{ | ||||||
| 		Scheme:   dictGetOrEmpty(d, "scheme"), | 		Scheme:   dictGetOrEmpty(d, "scheme"), | ||||||
| 		Host:     dictGetOrEmpty(d, "host"), | 		Host:     dictGetOrEmpty(d, "host"), | ||||||
| 		Path:     dictGetOrEmpty(d, "path"), | 		Path:     dictGetOrEmpty(d, "path"), | ||||||
| 		RawQuery: dictGetOrEmpty(d, "query"), | 		RawQuery: dictGetOrEmpty(d, "query"), | ||||||
| 		Opaque:   dictGetOrEmpty(d, "opaque"), | 		Opaque:   dictGetOrEmpty(d, "opaque"), | ||||||
| 		Fragment: dictGetOrEmpty(d, "fragment"), | 		Fragment: dictGetOrEmpty(d, "fragment"), | ||||||
| 
 |  | ||||||
| 	} | 	} | ||||||
| 	userinfo := dictGetOrEmpty(d, "userinfo") | 	userinfo := dictGetOrEmpty(d, "userinfo") | ||||||
| 	var user *url.Userinfo = nil | 	var user *url.Userinfo | ||||||
| 	if userinfo != "" { | 	if userinfo != "" { | ||||||
| 		tempUrl, err := url.Parse(fmt.Sprintf("proto://%s@host", userinfo)) | 		tempURL, err := url.Parse(fmt.Sprintf("proto://%s@host", userinfo)) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			panic(fmt.Sprintf("unable to parse userinfo in dict: %s", err)) | 			panic(fmt.Sprintf("unable to parse userinfo in dict: %s", err)) | ||||||
| 		} | 		} | ||||||
| 		user = tempUrl.User | 		user = tempURL.User | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	resUrl.User = user | 	resURL.User = user | ||||||
| 	return resUrl.String() | 	return resURL.String() | ||||||
| } | } | ||||||
							
								
								
									
										15
									
								
								vendor/github.com/davecgh/go-spew/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/davecgh/go-spew/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,15 +0,0 @@ | |||||||
| ISC License |  | ||||||
|  |  | ||||||
| Copyright (c) 2012-2016 Dave Collins <dave@davec.name> |  | ||||||
|  |  | ||||||
| Permission to use, copy, modify, and/or distribute this software for any |  | ||||||
| purpose with or without fee is hereby granted, provided that the above |  | ||||||
| copyright notice and this permission notice appear in all copies. |  | ||||||
|  |  | ||||||
| THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |  | ||||||
| WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |  | ||||||
| MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |  | ||||||
| ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |  | ||||||
| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |  | ||||||
| ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |  | ||||||
| OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |  | ||||||
							
								
								
									
										145
									
								
								vendor/github.com/davecgh/go-spew/spew/bypass.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										145
									
								
								vendor/github.com/davecgh/go-spew/spew/bypass.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,145 +0,0 @@ | |||||||
| // Copyright (c) 2015-2016 Dave Collins <dave@davec.name> |  | ||||||
| // |  | ||||||
| // Permission to use, copy, modify, and distribute this software for any |  | ||||||
| // purpose with or without fee is hereby granted, provided that the above |  | ||||||
| // copyright notice and this permission notice appear in all copies. |  | ||||||
| // |  | ||||||
| // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |  | ||||||
| // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |  | ||||||
| // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |  | ||||||
| // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |  | ||||||
| // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |  | ||||||
| // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |  | ||||||
| // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |  | ||||||
|  |  | ||||||
| // NOTE: Due to the following build constraints, this file will only be compiled |  | ||||||
| // when the code is not running on Google App Engine, compiled by GopherJS, and |  | ||||||
| // "-tags safe" is not added to the go build command line.  The "disableunsafe" |  | ||||||
| // tag is deprecated and thus should not be used. |  | ||||||
| // Go versions prior to 1.4 are disabled because they use a different layout |  | ||||||
| // for interfaces which make the implementation of unsafeReflectValue more complex. |  | ||||||
| // +build !js,!appengine,!safe,!disableunsafe,go1.4 |  | ||||||
|  |  | ||||||
| package spew |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"reflect" |  | ||||||
| 	"unsafe" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	// UnsafeDisabled is a build-time constant which specifies whether or |  | ||||||
| 	// not access to the unsafe package is available. |  | ||||||
| 	UnsafeDisabled = false |  | ||||||
|  |  | ||||||
| 	// ptrSize is the size of a pointer on the current arch. |  | ||||||
| 	ptrSize = unsafe.Sizeof((*byte)(nil)) |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type flag uintptr |  | ||||||
|  |  | ||||||
| var ( |  | ||||||
| 	// flagRO indicates whether the value field of a reflect.Value |  | ||||||
| 	// is read-only. |  | ||||||
| 	flagRO flag |  | ||||||
|  |  | ||||||
| 	// flagAddr indicates whether the address of the reflect.Value's |  | ||||||
| 	// value may be taken. |  | ||||||
| 	flagAddr flag |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // flagKindMask holds the bits that make up the kind |  | ||||||
| // part of the flags field. In all the supported versions, |  | ||||||
| // it is in the lower 5 bits. |  | ||||||
| const flagKindMask = flag(0x1f) |  | ||||||
|  |  | ||||||
| // Different versions of Go have used different |  | ||||||
| // bit layouts for the flags type. This table |  | ||||||
| // records the known combinations. |  | ||||||
| var okFlags = []struct { |  | ||||||
| 	ro, addr flag |  | ||||||
| }{{ |  | ||||||
| 	// From Go 1.4 to 1.5 |  | ||||||
| 	ro:   1 << 5, |  | ||||||
| 	addr: 1 << 7, |  | ||||||
| }, { |  | ||||||
| 	// Up to Go tip. |  | ||||||
| 	ro:   1<<5 | 1<<6, |  | ||||||
| 	addr: 1 << 8, |  | ||||||
| }} |  | ||||||
|  |  | ||||||
| var flagValOffset = func() uintptr { |  | ||||||
| 	field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") |  | ||||||
| 	if !ok { |  | ||||||
| 		panic("reflect.Value has no flag field") |  | ||||||
| 	} |  | ||||||
| 	return field.Offset |  | ||||||
| }() |  | ||||||
|  |  | ||||||
| // flagField returns a pointer to the flag field of a reflect.Value. |  | ||||||
| func flagField(v *reflect.Value) *flag { |  | ||||||
| 	return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // unsafeReflectValue converts the passed reflect.Value into a one that bypasses |  | ||||||
| // the typical safety restrictions preventing access to unaddressable and |  | ||||||
| // unexported data.  It works by digging the raw pointer to the underlying |  | ||||||
| // value out of the protected value and generating a new unprotected (unsafe) |  | ||||||
| // reflect.Value to it. |  | ||||||
| // |  | ||||||
| // This allows us to check for implementations of the Stringer and error |  | ||||||
| // interfaces to be used for pretty printing ordinarily unaddressable and |  | ||||||
| // inaccessible values such as unexported struct fields. |  | ||||||
| func unsafeReflectValue(v reflect.Value) reflect.Value { |  | ||||||
| 	if !v.IsValid() || (v.CanInterface() && v.CanAddr()) { |  | ||||||
| 		return v |  | ||||||
| 	} |  | ||||||
| 	flagFieldPtr := flagField(&v) |  | ||||||
| 	*flagFieldPtr &^= flagRO |  | ||||||
| 	*flagFieldPtr |= flagAddr |  | ||||||
| 	return v |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Sanity checks against future reflect package changes |  | ||||||
| // to the type or semantics of the Value.flag field. |  | ||||||
| func init() { |  | ||||||
| 	field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") |  | ||||||
| 	if !ok { |  | ||||||
| 		panic("reflect.Value has no flag field") |  | ||||||
| 	} |  | ||||||
| 	if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() { |  | ||||||
| 		panic("reflect.Value flag field has changed kind") |  | ||||||
| 	} |  | ||||||
| 	type t0 int |  | ||||||
| 	var t struct { |  | ||||||
| 		A t0 |  | ||||||
| 		// t0 will have flagEmbedRO set. |  | ||||||
| 		t0 |  | ||||||
| 		// a will have flagStickyRO set |  | ||||||
| 		a t0 |  | ||||||
| 	} |  | ||||||
| 	vA := reflect.ValueOf(t).FieldByName("A") |  | ||||||
| 	va := reflect.ValueOf(t).FieldByName("a") |  | ||||||
| 	vt0 := reflect.ValueOf(t).FieldByName("t0") |  | ||||||
|  |  | ||||||
| 	// Infer flagRO from the difference between the flags |  | ||||||
| 	// for the (otherwise identical) fields in t. |  | ||||||
| 	flagPublic := *flagField(&vA) |  | ||||||
| 	flagWithRO := *flagField(&va) | *flagField(&vt0) |  | ||||||
| 	flagRO = flagPublic ^ flagWithRO |  | ||||||
|  |  | ||||||
| 	// Infer flagAddr from the difference between a value |  | ||||||
| 	// taken from a pointer and not. |  | ||||||
| 	vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A") |  | ||||||
| 	flagNoPtr := *flagField(&vA) |  | ||||||
| 	flagPtr := *flagField(&vPtrA) |  | ||||||
| 	flagAddr = flagNoPtr ^ flagPtr |  | ||||||
|  |  | ||||||
| 	// Check that the inferred flags tally with one of the known versions. |  | ||||||
| 	for _, f := range okFlags { |  | ||||||
| 		if flagRO == f.ro && flagAddr == f.addr { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	panic("reflect.Value read-only flag has changed semantics") |  | ||||||
| } |  | ||||||
							
								
								
									
										38
									
								
								vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,38 +0,0 @@ | |||||||
| // Copyright (c) 2015-2016 Dave Collins <dave@davec.name> |  | ||||||
| // |  | ||||||
| // Permission to use, copy, modify, and distribute this software for any |  | ||||||
| // purpose with or without fee is hereby granted, provided that the above |  | ||||||
| // copyright notice and this permission notice appear in all copies. |  | ||||||
| // |  | ||||||
| // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |  | ||||||
| // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |  | ||||||
| // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |  | ||||||
| // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |  | ||||||
| // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |  | ||||||
| // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |  | ||||||
| // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |  | ||||||
|  |  | ||||||
| // NOTE: Due to the following build constraints, this file will only be compiled |  | ||||||
| // when the code is running on Google App Engine, compiled by GopherJS, or |  | ||||||
| // "-tags safe" is added to the go build command line.  The "disableunsafe" |  | ||||||
| // tag is deprecated and thus should not be used. |  | ||||||
| // +build js appengine safe disableunsafe !go1.4 |  | ||||||
|  |  | ||||||
| package spew |  | ||||||
|  |  | ||||||
| import "reflect" |  | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	// UnsafeDisabled is a build-time constant which specifies whether or |  | ||||||
| 	// not access to the unsafe package is available. |  | ||||||
| 	UnsafeDisabled = true |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // unsafeReflectValue typically converts the passed reflect.Value into a one |  | ||||||
| // that bypasses the typical safety restrictions preventing access to |  | ||||||
| // unaddressable and unexported data.  However, doing this relies on access to |  | ||||||
| // the unsafe package.  This is a stub version which simply returns the passed |  | ||||||
| // reflect.Value when the unsafe package is not available. |  | ||||||
| func unsafeReflectValue(v reflect.Value) reflect.Value { |  | ||||||
| 	return v |  | ||||||
| } |  | ||||||
							
								
								
									
										341
									
								
								vendor/github.com/davecgh/go-spew/spew/common.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										341
									
								
								vendor/github.com/davecgh/go-spew/spew/common.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,341 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright (c) 2013-2016 Dave Collins <dave@davec.name> |  | ||||||
|  * |  | ||||||
|  * Permission to use, copy, modify, and distribute this software for any |  | ||||||
|  * purpose with or without fee is hereby granted, provided that the above |  | ||||||
|  * copyright notice and this permission notice appear in all copies. |  | ||||||
|  * |  | ||||||
|  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |  | ||||||
|  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |  | ||||||
|  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |  | ||||||
|  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |  | ||||||
|  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |  | ||||||
|  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |  | ||||||
|  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| package spew |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"reflect" |  | ||||||
| 	"sort" |  | ||||||
| 	"strconv" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // Some constants in the form of bytes to avoid string overhead.  This mirrors |  | ||||||
| // the technique used in the fmt package. |  | ||||||
| var ( |  | ||||||
| 	panicBytes            = []byte("(PANIC=") |  | ||||||
| 	plusBytes             = []byte("+") |  | ||||||
| 	iBytes                = []byte("i") |  | ||||||
| 	trueBytes             = []byte("true") |  | ||||||
| 	falseBytes            = []byte("false") |  | ||||||
| 	interfaceBytes        = []byte("(interface {})") |  | ||||||
| 	commaNewlineBytes     = []byte(",\n") |  | ||||||
| 	newlineBytes          = []byte("\n") |  | ||||||
| 	openBraceBytes        = []byte("{") |  | ||||||
| 	openBraceNewlineBytes = []byte("{\n") |  | ||||||
| 	closeBraceBytes       = []byte("}") |  | ||||||
| 	asteriskBytes         = []byte("*") |  | ||||||
| 	colonBytes            = []byte(":") |  | ||||||
| 	colonSpaceBytes       = []byte(": ") |  | ||||||
| 	openParenBytes        = []byte("(") |  | ||||||
| 	closeParenBytes       = []byte(")") |  | ||||||
| 	spaceBytes            = []byte(" ") |  | ||||||
| 	pointerChainBytes     = []byte("->") |  | ||||||
| 	nilAngleBytes         = []byte("<nil>") |  | ||||||
| 	maxNewlineBytes       = []byte("<max depth reached>\n") |  | ||||||
| 	maxShortBytes         = []byte("<max>") |  | ||||||
| 	circularBytes         = []byte("<already shown>") |  | ||||||
| 	circularShortBytes    = []byte("<shown>") |  | ||||||
| 	invalidAngleBytes     = []byte("<invalid>") |  | ||||||
| 	openBracketBytes      = []byte("[") |  | ||||||
| 	closeBracketBytes     = []byte("]") |  | ||||||
| 	percentBytes          = []byte("%") |  | ||||||
| 	precisionBytes        = []byte(".") |  | ||||||
| 	openAngleBytes        = []byte("<") |  | ||||||
| 	closeAngleBytes       = []byte(">") |  | ||||||
| 	openMapBytes          = []byte("map[") |  | ||||||
| 	closeMapBytes         = []byte("]") |  | ||||||
| 	lenEqualsBytes        = []byte("len=") |  | ||||||
| 	capEqualsBytes        = []byte("cap=") |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // hexDigits is used to map a decimal value to a hex digit. |  | ||||||
| var hexDigits = "0123456789abcdef" |  | ||||||
|  |  | ||||||
| // catchPanic handles any panics that might occur during the handleMethods |  | ||||||
| // calls. |  | ||||||
| func catchPanic(w io.Writer, v reflect.Value) { |  | ||||||
| 	if err := recover(); err != nil { |  | ||||||
| 		w.Write(panicBytes) |  | ||||||
| 		fmt.Fprintf(w, "%v", err) |  | ||||||
| 		w.Write(closeParenBytes) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // handleMethods attempts to call the Error and String methods on the underlying |  | ||||||
| // type the passed reflect.Value represents and outputes the result to Writer w. |  | ||||||
| // |  | ||||||
| // It handles panics in any called methods by catching and displaying the error |  | ||||||
| // as the formatted value. |  | ||||||
| func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) { |  | ||||||
| 	// We need an interface to check if the type implements the error or |  | ||||||
| 	// Stringer interface.  However, the reflect package won't give us an |  | ||||||
| 	// interface on certain things like unexported struct fields in order |  | ||||||
| 	// to enforce visibility rules.  We use unsafe, when it's available, |  | ||||||
| 	// to bypass these restrictions since this package does not mutate the |  | ||||||
| 	// values. |  | ||||||
| 	if !v.CanInterface() { |  | ||||||
| 		if UnsafeDisabled { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		v = unsafeReflectValue(v) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Choose whether or not to do error and Stringer interface lookups against |  | ||||||
| 	// the base type or a pointer to the base type depending on settings. |  | ||||||
| 	// Technically calling one of these methods with a pointer receiver can |  | ||||||
| 	// mutate the value, however, types which choose to satisify an error or |  | ||||||
| 	// Stringer interface with a pointer receiver should not be mutating their |  | ||||||
| 	// state inside these interface methods. |  | ||||||
| 	if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() { |  | ||||||
| 		v = unsafeReflectValue(v) |  | ||||||
| 	} |  | ||||||
| 	if v.CanAddr() { |  | ||||||
| 		v = v.Addr() |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Is it an error or Stringer? |  | ||||||
| 	switch iface := v.Interface().(type) { |  | ||||||
| 	case error: |  | ||||||
| 		defer catchPanic(w, v) |  | ||||||
| 		if cs.ContinueOnMethod { |  | ||||||
| 			w.Write(openParenBytes) |  | ||||||
| 			w.Write([]byte(iface.Error())) |  | ||||||
| 			w.Write(closeParenBytes) |  | ||||||
| 			w.Write(spaceBytes) |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		w.Write([]byte(iface.Error())) |  | ||||||
| 		return true |  | ||||||
|  |  | ||||||
| 	case fmt.Stringer: |  | ||||||
| 		defer catchPanic(w, v) |  | ||||||
| 		if cs.ContinueOnMethod { |  | ||||||
| 			w.Write(openParenBytes) |  | ||||||
| 			w.Write([]byte(iface.String())) |  | ||||||
| 			w.Write(closeParenBytes) |  | ||||||
| 			w.Write(spaceBytes) |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 		w.Write([]byte(iface.String())) |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // printBool outputs a boolean value as true or false to Writer w. |  | ||||||
| func printBool(w io.Writer, val bool) { |  | ||||||
| 	if val { |  | ||||||
| 		w.Write(trueBytes) |  | ||||||
| 	} else { |  | ||||||
| 		w.Write(falseBytes) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // printInt outputs a signed integer value to Writer w. |  | ||||||
| func printInt(w io.Writer, val int64, base int) { |  | ||||||
| 	w.Write([]byte(strconv.FormatInt(val, base))) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // printUint outputs an unsigned integer value to Writer w. |  | ||||||
| func printUint(w io.Writer, val uint64, base int) { |  | ||||||
| 	w.Write([]byte(strconv.FormatUint(val, base))) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // printFloat outputs a floating point value using the specified precision, |  | ||||||
| // which is expected to be 32 or 64bit, to Writer w. |  | ||||||
| func printFloat(w io.Writer, val float64, precision int) { |  | ||||||
| 	w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision))) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // printComplex outputs a complex value using the specified float precision |  | ||||||
| // for the real and imaginary parts to Writer w. |  | ||||||
| func printComplex(w io.Writer, c complex128, floatPrecision int) { |  | ||||||
| 	r := real(c) |  | ||||||
| 	w.Write(openParenBytes) |  | ||||||
| 	w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision))) |  | ||||||
| 	i := imag(c) |  | ||||||
| 	if i >= 0 { |  | ||||||
| 		w.Write(plusBytes) |  | ||||||
| 	} |  | ||||||
| 	w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision))) |  | ||||||
| 	w.Write(iBytes) |  | ||||||
| 	w.Write(closeParenBytes) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x' |  | ||||||
| // prefix to Writer w. |  | ||||||
| func printHexPtr(w io.Writer, p uintptr) { |  | ||||||
| 	// Null pointer. |  | ||||||
| 	num := uint64(p) |  | ||||||
| 	if num == 0 { |  | ||||||
| 		w.Write(nilAngleBytes) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix |  | ||||||
| 	buf := make([]byte, 18) |  | ||||||
|  |  | ||||||
| 	// It's simpler to construct the hex string right to left. |  | ||||||
| 	base := uint64(16) |  | ||||||
| 	i := len(buf) - 1 |  | ||||||
| 	for num >= base { |  | ||||||
| 		buf[i] = hexDigits[num%base] |  | ||||||
| 		num /= base |  | ||||||
| 		i-- |  | ||||||
| 	} |  | ||||||
| 	buf[i] = hexDigits[num] |  | ||||||
|  |  | ||||||
| 	// Add '0x' prefix. |  | ||||||
| 	i-- |  | ||||||
| 	buf[i] = 'x' |  | ||||||
| 	i-- |  | ||||||
| 	buf[i] = '0' |  | ||||||
|  |  | ||||||
| 	// Strip unused leading bytes. |  | ||||||
| 	buf = buf[i:] |  | ||||||
| 	w.Write(buf) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // valuesSorter implements sort.Interface to allow a slice of reflect.Value |  | ||||||
| // elements to be sorted. |  | ||||||
| type valuesSorter struct { |  | ||||||
| 	values  []reflect.Value |  | ||||||
| 	strings []string // either nil or same len and values |  | ||||||
| 	cs      *ConfigState |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // newValuesSorter initializes a valuesSorter instance, which holds a set of |  | ||||||
| // surrogate keys on which the data should be sorted.  It uses flags in |  | ||||||
| // ConfigState to decide if and how to populate those surrogate keys. |  | ||||||
| func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface { |  | ||||||
| 	vs := &valuesSorter{values: values, cs: cs} |  | ||||||
| 	if canSortSimply(vs.values[0].Kind()) { |  | ||||||
| 		return vs |  | ||||||
| 	} |  | ||||||
| 	if !cs.DisableMethods { |  | ||||||
| 		vs.strings = make([]string, len(values)) |  | ||||||
| 		for i := range vs.values { |  | ||||||
| 			b := bytes.Buffer{} |  | ||||||
| 			if !handleMethods(cs, &b, vs.values[i]) { |  | ||||||
| 				vs.strings = nil |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 			vs.strings[i] = b.String() |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if vs.strings == nil && cs.SpewKeys { |  | ||||||
| 		vs.strings = make([]string, len(values)) |  | ||||||
| 		for i := range vs.values { |  | ||||||
| 			vs.strings[i] = Sprintf("%#v", vs.values[i].Interface()) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return vs |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // canSortSimply tests whether a reflect.Kind is a primitive that can be sorted |  | ||||||
| // directly, or whether it should be considered for sorting by surrogate keys |  | ||||||
| // (if the ConfigState allows it). |  | ||||||
| func canSortSimply(kind reflect.Kind) bool { |  | ||||||
| 	// This switch parallels valueSortLess, except for the default case. |  | ||||||
| 	switch kind { |  | ||||||
| 	case reflect.Bool: |  | ||||||
| 		return true |  | ||||||
| 	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: |  | ||||||
| 		return true |  | ||||||
| 	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: |  | ||||||
| 		return true |  | ||||||
| 	case reflect.Float32, reflect.Float64: |  | ||||||
| 		return true |  | ||||||
| 	case reflect.String: |  | ||||||
| 		return true |  | ||||||
| 	case reflect.Uintptr: |  | ||||||
| 		return true |  | ||||||
| 	case reflect.Array: |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Len returns the number of values in the slice.  It is part of the |  | ||||||
| // sort.Interface implementation. |  | ||||||
| func (s *valuesSorter) Len() int { |  | ||||||
| 	return len(s.values) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Swap swaps the values at the passed indices.  It is part of the |  | ||||||
| // sort.Interface implementation. |  | ||||||
| func (s *valuesSorter) Swap(i, j int) { |  | ||||||
| 	s.values[i], s.values[j] = s.values[j], s.values[i] |  | ||||||
| 	if s.strings != nil { |  | ||||||
| 		s.strings[i], s.strings[j] = s.strings[j], s.strings[i] |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // valueSortLess returns whether the first value should sort before the second |  | ||||||
| // value.  It is used by valueSorter.Less as part of the sort.Interface |  | ||||||
| // implementation. |  | ||||||
| func valueSortLess(a, b reflect.Value) bool { |  | ||||||
| 	switch a.Kind() { |  | ||||||
| 	case reflect.Bool: |  | ||||||
| 		return !a.Bool() && b.Bool() |  | ||||||
| 	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: |  | ||||||
| 		return a.Int() < b.Int() |  | ||||||
| 	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: |  | ||||||
| 		return a.Uint() < b.Uint() |  | ||||||
| 	case reflect.Float32, reflect.Float64: |  | ||||||
| 		return a.Float() < b.Float() |  | ||||||
| 	case reflect.String: |  | ||||||
| 		return a.String() < b.String() |  | ||||||
| 	case reflect.Uintptr: |  | ||||||
| 		return a.Uint() < b.Uint() |  | ||||||
| 	case reflect.Array: |  | ||||||
| 		// Compare the contents of both arrays. |  | ||||||
| 		l := a.Len() |  | ||||||
| 		for i := 0; i < l; i++ { |  | ||||||
| 			av := a.Index(i) |  | ||||||
| 			bv := b.Index(i) |  | ||||||
| 			if av.Interface() == bv.Interface() { |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 			return valueSortLess(av, bv) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return a.String() < b.String() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Less returns whether the value at index i should sort before the |  | ||||||
| // value at index j.  It is part of the sort.Interface implementation. |  | ||||||
| func (s *valuesSorter) Less(i, j int) bool { |  | ||||||
| 	if s.strings == nil { |  | ||||||
| 		return valueSortLess(s.values[i], s.values[j]) |  | ||||||
| 	} |  | ||||||
| 	return s.strings[i] < s.strings[j] |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // sortValues is a sort function that handles both native types and any type that |  | ||||||
| // can be converted to error or Stringer.  Other inputs are sorted according to |  | ||||||
| // their Value.String() value to ensure display stability. |  | ||||||
| func sortValues(values []reflect.Value, cs *ConfigState) { |  | ||||||
| 	if len(values) == 0 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	sort.Sort(newValuesSorter(values, cs)) |  | ||||||
| } |  | ||||||
							
								
								
									
										306
									
								
								vendor/github.com/davecgh/go-spew/spew/config.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										306
									
								
								vendor/github.com/davecgh/go-spew/spew/config.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,306 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright (c) 2013-2016 Dave Collins <dave@davec.name> |  | ||||||
|  * |  | ||||||
|  * Permission to use, copy, modify, and distribute this software for any |  | ||||||
|  * purpose with or without fee is hereby granted, provided that the above |  | ||||||
|  * copyright notice and this permission notice appear in all copies. |  | ||||||
|  * |  | ||||||
|  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |  | ||||||
|  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |  | ||||||
|  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |  | ||||||
|  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |  | ||||||
|  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |  | ||||||
|  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |  | ||||||
|  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| package spew |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"os" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // ConfigState houses the configuration options used by spew to format and |  | ||||||
| // display values.  There is a global instance, Config, that is used to control |  | ||||||
| // all top-level Formatter and Dump functionality.  Each ConfigState instance |  | ||||||
| // provides methods equivalent to the top-level functions. |  | ||||||
| // |  | ||||||
| // The zero value for ConfigState provides no indentation.  You would typically |  | ||||||
| // want to set it to a space or a tab. |  | ||||||
| // |  | ||||||
| // Alternatively, you can use NewDefaultConfig to get a ConfigState instance |  | ||||||
| // with default settings.  See the documentation of NewDefaultConfig for default |  | ||||||
| // values. |  | ||||||
| type ConfigState struct { |  | ||||||
| 	// Indent specifies the string to use for each indentation level.  The |  | ||||||
| 	// global config instance that all top-level functions use set this to a |  | ||||||
| 	// single space by default.  If you would like more indentation, you might |  | ||||||
| 	// set this to a tab with "\t" or perhaps two spaces with "  ". |  | ||||||
| 	Indent string |  | ||||||
|  |  | ||||||
| 	// MaxDepth controls the maximum number of levels to descend into nested |  | ||||||
| 	// data structures.  The default, 0, means there is no limit. |  | ||||||
| 	// |  | ||||||
| 	// NOTE: Circular data structures are properly detected, so it is not |  | ||||||
| 	// necessary to set this value unless you specifically want to limit deeply |  | ||||||
| 	// nested data structures. |  | ||||||
| 	MaxDepth int |  | ||||||
|  |  | ||||||
| 	// DisableMethods specifies whether or not error and Stringer interfaces are |  | ||||||
| 	// invoked for types that implement them. |  | ||||||
| 	DisableMethods bool |  | ||||||
|  |  | ||||||
| 	// DisablePointerMethods specifies whether or not to check for and invoke |  | ||||||
| 	// error and Stringer interfaces on types which only accept a pointer |  | ||||||
| 	// receiver when the current type is not a pointer. |  | ||||||
| 	// |  | ||||||
| 	// NOTE: This might be an unsafe action since calling one of these methods |  | ||||||
| 	// with a pointer receiver could technically mutate the value, however, |  | ||||||
| 	// in practice, types which choose to satisify an error or Stringer |  | ||||||
| 	// interface with a pointer receiver should not be mutating their state |  | ||||||
| 	// inside these interface methods.  As a result, this option relies on |  | ||||||
| 	// access to the unsafe package, so it will not have any effect when |  | ||||||
| 	// running in environments without access to the unsafe package such as |  | ||||||
| 	// Google App Engine or with the "safe" build tag specified. |  | ||||||
| 	DisablePointerMethods bool |  | ||||||
|  |  | ||||||
| 	// DisablePointerAddresses specifies whether to disable the printing of |  | ||||||
| 	// pointer addresses. This is useful when diffing data structures in tests. |  | ||||||
| 	DisablePointerAddresses bool |  | ||||||
|  |  | ||||||
| 	// DisableCapacities specifies whether to disable the printing of capacities |  | ||||||
| 	// for arrays, slices, maps and channels. This is useful when diffing |  | ||||||
| 	// data structures in tests. |  | ||||||
| 	DisableCapacities bool |  | ||||||
|  |  | ||||||
| 	// ContinueOnMethod specifies whether or not recursion should continue once |  | ||||||
| 	// a custom error or Stringer interface is invoked.  The default, false, |  | ||||||
| 	// means it will print the results of invoking the custom error or Stringer |  | ||||||
| 	// interface and return immediately instead of continuing to recurse into |  | ||||||
| 	// the internals of the data type. |  | ||||||
| 	// |  | ||||||
| 	// NOTE: This flag does not have any effect if method invocation is disabled |  | ||||||
| 	// via the DisableMethods or DisablePointerMethods options. |  | ||||||
| 	ContinueOnMethod bool |  | ||||||
|  |  | ||||||
| 	// SortKeys specifies map keys should be sorted before being printed. Use |  | ||||||
| 	// this to have a more deterministic, diffable output.  Note that only |  | ||||||
| 	// native types (bool, int, uint, floats, uintptr and string) and types |  | ||||||
| 	// that support the error or Stringer interfaces (if methods are |  | ||||||
| 	// enabled) are supported, with other types sorted according to the |  | ||||||
| 	// reflect.Value.String() output which guarantees display stability. |  | ||||||
| 	SortKeys bool |  | ||||||
|  |  | ||||||
| 	// SpewKeys specifies that, as a last resort attempt, map keys should |  | ||||||
| 	// be spewed to strings and sorted by those strings.  This is only |  | ||||||
| 	// considered if SortKeys is true. |  | ||||||
| 	SpewKeys bool |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Config is the active configuration of the top-level functions. |  | ||||||
| // The configuration can be changed by modifying the contents of spew.Config. |  | ||||||
| var Config = ConfigState{Indent: " "} |  | ||||||
|  |  | ||||||
| // Errorf is a wrapper for fmt.Errorf that treats each argument as if it were |  | ||||||
| // passed with a Formatter interface returned by c.NewFormatter.  It returns |  | ||||||
| // the formatted string as a value that satisfies error.  See NewFormatter |  | ||||||
| // for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b)) |  | ||||||
| func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) { |  | ||||||
| 	return fmt.Errorf(format, c.convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Fprint is a wrapper for fmt.Fprint that treats each argument as if it were |  | ||||||
| // passed with a Formatter interface returned by c.NewFormatter.  It returns |  | ||||||
| // the number of bytes written and any write error encountered.  See |  | ||||||
| // NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b)) |  | ||||||
| func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) { |  | ||||||
| 	return fmt.Fprint(w, c.convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were |  | ||||||
| // passed with a Formatter interface returned by c.NewFormatter.  It returns |  | ||||||
| // the number of bytes written and any write error encountered.  See |  | ||||||
| // NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b)) |  | ||||||
| func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { |  | ||||||
| 	return fmt.Fprintf(w, format, c.convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it |  | ||||||
| // passed with a Formatter interface returned by c.NewFormatter.  See |  | ||||||
| // NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b)) |  | ||||||
| func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { |  | ||||||
| 	return fmt.Fprintln(w, c.convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Print is a wrapper for fmt.Print that treats each argument as if it were |  | ||||||
| // passed with a Formatter interface returned by c.NewFormatter.  It returns |  | ||||||
| // the number of bytes written and any write error encountered.  See |  | ||||||
| // NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Print(c.NewFormatter(a), c.NewFormatter(b)) |  | ||||||
| func (c *ConfigState) Print(a ...interface{}) (n int, err error) { |  | ||||||
| 	return fmt.Print(c.convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Printf is a wrapper for fmt.Printf that treats each argument as if it were |  | ||||||
| // passed with a Formatter interface returned by c.NewFormatter.  It returns |  | ||||||
| // the number of bytes written and any write error encountered.  See |  | ||||||
| // NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b)) |  | ||||||
| func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) { |  | ||||||
| 	return fmt.Printf(format, c.convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Println is a wrapper for fmt.Println that treats each argument as if it were |  | ||||||
| // passed with a Formatter interface returned by c.NewFormatter.  It returns |  | ||||||
| // the number of bytes written and any write error encountered.  See |  | ||||||
| // NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Println(c.NewFormatter(a), c.NewFormatter(b)) |  | ||||||
| func (c *ConfigState) Println(a ...interface{}) (n int, err error) { |  | ||||||
| 	return fmt.Println(c.convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Sprint is a wrapper for fmt.Sprint that treats each argument as if it were |  | ||||||
| // passed with a Formatter interface returned by c.NewFormatter.  It returns |  | ||||||
| // the resulting string.  See NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b)) |  | ||||||
| func (c *ConfigState) Sprint(a ...interface{}) string { |  | ||||||
| 	return fmt.Sprint(c.convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were |  | ||||||
| // passed with a Formatter interface returned by c.NewFormatter.  It returns |  | ||||||
| // the resulting string.  See NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b)) |  | ||||||
| func (c *ConfigState) Sprintf(format string, a ...interface{}) string { |  | ||||||
| 	return fmt.Sprintf(format, c.convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it |  | ||||||
| // were passed with a Formatter interface returned by c.NewFormatter.  It |  | ||||||
| // returns the resulting string.  See NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b)) |  | ||||||
| func (c *ConfigState) Sprintln(a ...interface{}) string { |  | ||||||
| 	return fmt.Sprintln(c.convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* |  | ||||||
| NewFormatter returns a custom formatter that satisfies the fmt.Formatter |  | ||||||
| interface.  As a result, it integrates cleanly with standard fmt package |  | ||||||
| printing functions.  The formatter is useful for inline printing of smaller data |  | ||||||
| types similar to the standard %v format specifier. |  | ||||||
|  |  | ||||||
| The custom formatter only responds to the %v (most compact), %+v (adds pointer |  | ||||||
| addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb |  | ||||||
| combinations.  Any other verbs such as %x and %q will be sent to the the |  | ||||||
| standard fmt package for formatting.  In addition, the custom formatter ignores |  | ||||||
| the width and precision arguments (however they will still work on the format |  | ||||||
| specifiers not handled by the custom formatter). |  | ||||||
|  |  | ||||||
| Typically this function shouldn't be called directly.  It is much easier to make |  | ||||||
| use of the custom formatter by calling one of the convenience functions such as |  | ||||||
| c.Printf, c.Println, or c.Printf. |  | ||||||
| */ |  | ||||||
| func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter { |  | ||||||
| 	return newFormatter(c, v) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Fdump formats and displays the passed arguments to io.Writer w.  It formats |  | ||||||
| // exactly the same as Dump. |  | ||||||
| func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) { |  | ||||||
| 	fdump(c, w, a...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* |  | ||||||
| Dump displays the passed parameters to standard out with newlines, customizable |  | ||||||
| indentation, and additional debug information such as complete types and all |  | ||||||
| pointer addresses used to indirect to the final value.  It provides the |  | ||||||
| following features over the built-in printing facilities provided by the fmt |  | ||||||
| package: |  | ||||||
|  |  | ||||||
| 	* Pointers are dereferenced and followed |  | ||||||
| 	* Circular data structures are detected and handled properly |  | ||||||
| 	* Custom Stringer/error interfaces are optionally invoked, including |  | ||||||
| 	  on unexported types |  | ||||||
| 	* Custom types which only implement the Stringer/error interfaces via |  | ||||||
| 	  a pointer receiver are optionally invoked when passing non-pointer |  | ||||||
| 	  variables |  | ||||||
| 	* Byte arrays and slices are dumped like the hexdump -C command which |  | ||||||
| 	  includes offsets, byte values in hex, and ASCII output |  | ||||||
|  |  | ||||||
| The configuration options are controlled by modifying the public members |  | ||||||
| of c.  See ConfigState for options documentation. |  | ||||||
|  |  | ||||||
| See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to |  | ||||||
| get the formatted result as a string. |  | ||||||
| */ |  | ||||||
| func (c *ConfigState) Dump(a ...interface{}) { |  | ||||||
| 	fdump(c, os.Stdout, a...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Sdump returns a string with the passed arguments formatted exactly the same |  | ||||||
| // as Dump. |  | ||||||
| func (c *ConfigState) Sdump(a ...interface{}) string { |  | ||||||
| 	var buf bytes.Buffer |  | ||||||
| 	fdump(c, &buf, a...) |  | ||||||
| 	return buf.String() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // convertArgs accepts a slice of arguments and returns a slice of the same |  | ||||||
| // length with each argument converted to a spew Formatter interface using |  | ||||||
| // the ConfigState associated with s. |  | ||||||
| func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) { |  | ||||||
| 	formatters = make([]interface{}, len(args)) |  | ||||||
| 	for index, arg := range args { |  | ||||||
| 		formatters[index] = newFormatter(c, arg) |  | ||||||
| 	} |  | ||||||
| 	return formatters |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // NewDefaultConfig returns a ConfigState with the following default settings. |  | ||||||
| // |  | ||||||
| // 	Indent: " " |  | ||||||
| // 	MaxDepth: 0 |  | ||||||
| // 	DisableMethods: false |  | ||||||
| // 	DisablePointerMethods: false |  | ||||||
| // 	ContinueOnMethod: false |  | ||||||
| // 	SortKeys: false |  | ||||||
| func NewDefaultConfig() *ConfigState { |  | ||||||
| 	return &ConfigState{Indent: " "} |  | ||||||
| } |  | ||||||
							
								
								
									
										211
									
								
								vendor/github.com/davecgh/go-spew/spew/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										211
									
								
								vendor/github.com/davecgh/go-spew/spew/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,211 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright (c) 2013-2016 Dave Collins <dave@davec.name> |  | ||||||
|  * |  | ||||||
|  * Permission to use, copy, modify, and distribute this software for any |  | ||||||
|  * purpose with or without fee is hereby granted, provided that the above |  | ||||||
|  * copyright notice and this permission notice appear in all copies. |  | ||||||
|  * |  | ||||||
|  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |  | ||||||
|  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |  | ||||||
|  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |  | ||||||
|  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |  | ||||||
|  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |  | ||||||
|  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |  | ||||||
|  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| /* |  | ||||||
| Package spew implements a deep pretty printer for Go data structures to aid in |  | ||||||
| debugging. |  | ||||||
|  |  | ||||||
| A quick overview of the additional features spew provides over the built-in |  | ||||||
| printing facilities for Go data types are as follows: |  | ||||||
|  |  | ||||||
| 	* Pointers are dereferenced and followed |  | ||||||
| 	* Circular data structures are detected and handled properly |  | ||||||
| 	* Custom Stringer/error interfaces are optionally invoked, including |  | ||||||
| 	  on unexported types |  | ||||||
| 	* Custom types which only implement the Stringer/error interfaces via |  | ||||||
| 	  a pointer receiver are optionally invoked when passing non-pointer |  | ||||||
| 	  variables |  | ||||||
| 	* Byte arrays and slices are dumped like the hexdump -C command which |  | ||||||
| 	  includes offsets, byte values in hex, and ASCII output (only when using |  | ||||||
| 	  Dump style) |  | ||||||
|  |  | ||||||
| There are two different approaches spew allows for dumping Go data structures: |  | ||||||
|  |  | ||||||
| 	* Dump style which prints with newlines, customizable indentation, |  | ||||||
| 	  and additional debug information such as types and all pointer addresses |  | ||||||
| 	  used to indirect to the final value |  | ||||||
| 	* A custom Formatter interface that integrates cleanly with the standard fmt |  | ||||||
| 	  package and replaces %v, %+v, %#v, and %#+v to provide inline printing |  | ||||||
| 	  similar to the default %v while providing the additional functionality |  | ||||||
| 	  outlined above and passing unsupported format verbs such as %x and %q |  | ||||||
| 	  along to fmt |  | ||||||
|  |  | ||||||
| Quick Start |  | ||||||
|  |  | ||||||
| This section demonstrates how to quickly get started with spew.  See the |  | ||||||
| sections below for further details on formatting and configuration options. |  | ||||||
|  |  | ||||||
| To dump a variable with full newlines, indentation, type, and pointer |  | ||||||
| information use Dump, Fdump, or Sdump: |  | ||||||
| 	spew.Dump(myVar1, myVar2, ...) |  | ||||||
| 	spew.Fdump(someWriter, myVar1, myVar2, ...) |  | ||||||
| 	str := spew.Sdump(myVar1, myVar2, ...) |  | ||||||
|  |  | ||||||
| Alternatively, if you would prefer to use format strings with a compacted inline |  | ||||||
| printing style, use the convenience wrappers Printf, Fprintf, etc with |  | ||||||
| %v (most compact), %+v (adds pointer addresses), %#v (adds types), or |  | ||||||
| %#+v (adds types and pointer addresses): |  | ||||||
| 	spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) |  | ||||||
| 	spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) |  | ||||||
| 	spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) |  | ||||||
| 	spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) |  | ||||||
|  |  | ||||||
| Configuration Options |  | ||||||
|  |  | ||||||
| Configuration of spew is handled by fields in the ConfigState type.  For |  | ||||||
| convenience, all of the top-level functions use a global state available |  | ||||||
| via the spew.Config global. |  | ||||||
|  |  | ||||||
| It is also possible to create a ConfigState instance that provides methods |  | ||||||
| equivalent to the top-level functions.  This allows concurrent configuration |  | ||||||
| options.  See the ConfigState documentation for more details. |  | ||||||
|  |  | ||||||
| The following configuration options are available: |  | ||||||
| 	* Indent |  | ||||||
| 		String to use for each indentation level for Dump functions. |  | ||||||
| 		It is a single space by default.  A popular alternative is "\t". |  | ||||||
|  |  | ||||||
| 	* MaxDepth |  | ||||||
| 		Maximum number of levels to descend into nested data structures. |  | ||||||
| 		There is no limit by default. |  | ||||||
|  |  | ||||||
| 	* DisableMethods |  | ||||||
| 		Disables invocation of error and Stringer interface methods. |  | ||||||
| 		Method invocation is enabled by default. |  | ||||||
|  |  | ||||||
| 	* DisablePointerMethods |  | ||||||
| 		Disables invocation of error and Stringer interface methods on types |  | ||||||
| 		which only accept pointer receivers from non-pointer variables. |  | ||||||
| 		Pointer method invocation is enabled by default. |  | ||||||
|  |  | ||||||
| 	* DisablePointerAddresses |  | ||||||
| 		DisablePointerAddresses specifies whether to disable the printing of |  | ||||||
| 		pointer addresses. This is useful when diffing data structures in tests. |  | ||||||
|  |  | ||||||
| 	* DisableCapacities |  | ||||||
| 		DisableCapacities specifies whether to disable the printing of |  | ||||||
| 		capacities for arrays, slices, maps and channels. This is useful when |  | ||||||
| 		diffing data structures in tests. |  | ||||||
|  |  | ||||||
| 	* ContinueOnMethod |  | ||||||
| 		Enables recursion into types after invoking error and Stringer interface |  | ||||||
| 		methods. Recursion after method invocation is disabled by default. |  | ||||||
|  |  | ||||||
| 	* SortKeys |  | ||||||
| 		Specifies map keys should be sorted before being printed. Use |  | ||||||
| 		this to have a more deterministic, diffable output.  Note that |  | ||||||
| 		only native types (bool, int, uint, floats, uintptr and string) |  | ||||||
| 		and types which implement error or Stringer interfaces are |  | ||||||
| 		supported with other types sorted according to the |  | ||||||
| 		reflect.Value.String() output which guarantees display |  | ||||||
| 		stability.  Natural map order is used by default. |  | ||||||
|  |  | ||||||
| 	* SpewKeys |  | ||||||
| 		Specifies that, as a last resort attempt, map keys should be |  | ||||||
| 		spewed to strings and sorted by those strings.  This is only |  | ||||||
| 		considered if SortKeys is true. |  | ||||||
|  |  | ||||||
| Dump Usage |  | ||||||
|  |  | ||||||
| Simply call spew.Dump with a list of variables you want to dump: |  | ||||||
|  |  | ||||||
| 	spew.Dump(myVar1, myVar2, ...) |  | ||||||
|  |  | ||||||
| You may also call spew.Fdump if you would prefer to output to an arbitrary |  | ||||||
| io.Writer.  For example, to dump to standard error: |  | ||||||
|  |  | ||||||
| 	spew.Fdump(os.Stderr, myVar1, myVar2, ...) |  | ||||||
|  |  | ||||||
| A third option is to call spew.Sdump to get the formatted output as a string: |  | ||||||
|  |  | ||||||
| 	str := spew.Sdump(myVar1, myVar2, ...) |  | ||||||
|  |  | ||||||
| Sample Dump Output |  | ||||||
|  |  | ||||||
| See the Dump example for details on the setup of the types and variables being |  | ||||||
| shown here. |  | ||||||
|  |  | ||||||
| 	(main.Foo) { |  | ||||||
| 	 unexportedField: (*main.Bar)(0xf84002e210)({ |  | ||||||
| 	  flag: (main.Flag) flagTwo, |  | ||||||
| 	  data: (uintptr) <nil> |  | ||||||
| 	 }), |  | ||||||
| 	 ExportedField: (map[interface {}]interface {}) (len=1) { |  | ||||||
| 	  (string) (len=3) "one": (bool) true |  | ||||||
| 	 } |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C |  | ||||||
| command as shown. |  | ||||||
| 	([]uint8) (len=32 cap=32) { |  | ||||||
| 	 00000000  11 12 13 14 15 16 17 18  19 1a 1b 1c 1d 1e 1f 20  |............... | |  | ||||||
| 	 00000010  21 22 23 24 25 26 27 28  29 2a 2b 2c 2d 2e 2f 30  |!"#$%&'()*+,-./0| |  | ||||||
| 	 00000020  31 32                                             |12| |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| Custom Formatter |  | ||||||
|  |  | ||||||
| Spew provides a custom formatter that implements the fmt.Formatter interface |  | ||||||
| so that it integrates cleanly with standard fmt package printing functions. The |  | ||||||
| formatter is useful for inline printing of smaller data types similar to the |  | ||||||
| standard %v format specifier. |  | ||||||
|  |  | ||||||
| The custom formatter only responds to the %v (most compact), %+v (adds pointer |  | ||||||
| addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb |  | ||||||
| combinations.  Any other verbs such as %x and %q will be sent to the the |  | ||||||
| standard fmt package for formatting.  In addition, the custom formatter ignores |  | ||||||
| the width and precision arguments (however they will still work on the format |  | ||||||
| specifiers not handled by the custom formatter). |  | ||||||
|  |  | ||||||
| Custom Formatter Usage |  | ||||||
|  |  | ||||||
| The simplest way to make use of the spew custom formatter is to call one of the |  | ||||||
| convenience functions such as spew.Printf, spew.Println, or spew.Printf.  The |  | ||||||
| functions have syntax you are most likely already familiar with: |  | ||||||
|  |  | ||||||
| 	spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) |  | ||||||
| 	spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) |  | ||||||
| 	spew.Println(myVar, myVar2) |  | ||||||
| 	spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) |  | ||||||
| 	spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) |  | ||||||
|  |  | ||||||
| See the Index for the full list convenience functions. |  | ||||||
|  |  | ||||||
| Sample Formatter Output |  | ||||||
|  |  | ||||||
| Double pointer to a uint8: |  | ||||||
| 	  %v: <**>5 |  | ||||||
| 	 %+v: <**>(0xf8400420d0->0xf8400420c8)5 |  | ||||||
| 	 %#v: (**uint8)5 |  | ||||||
| 	%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 |  | ||||||
|  |  | ||||||
| Pointer to circular struct with a uint8 field and a pointer to itself: |  | ||||||
| 	  %v: <*>{1 <*><shown>} |  | ||||||
| 	 %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>} |  | ||||||
| 	 %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>} |  | ||||||
| 	%#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)<shown>} |  | ||||||
|  |  | ||||||
| See the Printf example for details on the setup of variables being shown |  | ||||||
| here. |  | ||||||
|  |  | ||||||
| Errors |  | ||||||
|  |  | ||||||
| Since it is possible for custom Stringer/error interfaces to panic, spew |  | ||||||
| detects them and handles them internally by printing the panic information |  | ||||||
| inline with the output.  Since spew is intended to provide deep pretty printing |  | ||||||
| capabilities on structures, it intentionally does not return any errors. |  | ||||||
| */ |  | ||||||
| package spew |  | ||||||
							
								
								
									
										509
									
								
								vendor/github.com/davecgh/go-spew/spew/dump.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										509
									
								
								vendor/github.com/davecgh/go-spew/spew/dump.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,509 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright (c) 2013-2016 Dave Collins <dave@davec.name> |  | ||||||
|  * |  | ||||||
|  * Permission to use, copy, modify, and distribute this software for any |  | ||||||
|  * purpose with or without fee is hereby granted, provided that the above |  | ||||||
|  * copyright notice and this permission notice appear in all copies. |  | ||||||
|  * |  | ||||||
|  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |  | ||||||
|  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |  | ||||||
|  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |  | ||||||
|  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |  | ||||||
|  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |  | ||||||
|  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |  | ||||||
|  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| package spew |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"encoding/hex" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"os" |  | ||||||
| 	"reflect" |  | ||||||
| 	"regexp" |  | ||||||
| 	"strconv" |  | ||||||
| 	"strings" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| var ( |  | ||||||
| 	// uint8Type is a reflect.Type representing a uint8.  It is used to |  | ||||||
| 	// convert cgo types to uint8 slices for hexdumping. |  | ||||||
| 	uint8Type = reflect.TypeOf(uint8(0)) |  | ||||||
|  |  | ||||||
| 	// cCharRE is a regular expression that matches a cgo char. |  | ||||||
| 	// It is used to detect character arrays to hexdump them. |  | ||||||
| 	cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`) |  | ||||||
|  |  | ||||||
| 	// cUnsignedCharRE is a regular expression that matches a cgo unsigned |  | ||||||
| 	// char.  It is used to detect unsigned character arrays to hexdump |  | ||||||
| 	// them. |  | ||||||
| 	cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`) |  | ||||||
|  |  | ||||||
| 	// cUint8tCharRE is a regular expression that matches a cgo uint8_t. |  | ||||||
| 	// It is used to detect uint8_t arrays to hexdump them. |  | ||||||
| 	cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`) |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // dumpState contains information about the state of a dump operation. |  | ||||||
| type dumpState struct { |  | ||||||
| 	w                io.Writer |  | ||||||
| 	depth            int |  | ||||||
| 	pointers         map[uintptr]int |  | ||||||
| 	ignoreNextType   bool |  | ||||||
| 	ignoreNextIndent bool |  | ||||||
| 	cs               *ConfigState |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // indent performs indentation according to the depth level and cs.Indent |  | ||||||
| // option. |  | ||||||
| func (d *dumpState) indent() { |  | ||||||
| 	if d.ignoreNextIndent { |  | ||||||
| 		d.ignoreNextIndent = false |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // unpackValue returns values inside of non-nil interfaces when possible. |  | ||||||
| // This is useful for data types like structs, arrays, slices, and maps which |  | ||||||
| // can contain varying types packed inside an interface. |  | ||||||
| func (d *dumpState) unpackValue(v reflect.Value) reflect.Value { |  | ||||||
| 	if v.Kind() == reflect.Interface && !v.IsNil() { |  | ||||||
| 		v = v.Elem() |  | ||||||
| 	} |  | ||||||
| 	return v |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // dumpPtr handles formatting of pointers by indirecting them as necessary. |  | ||||||
| func (d *dumpState) dumpPtr(v reflect.Value) { |  | ||||||
| 	// Remove pointers at or below the current depth from map used to detect |  | ||||||
| 	// circular refs. |  | ||||||
| 	for k, depth := range d.pointers { |  | ||||||
| 		if depth >= d.depth { |  | ||||||
| 			delete(d.pointers, k) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Keep list of all dereferenced pointers to show later. |  | ||||||
| 	pointerChain := make([]uintptr, 0) |  | ||||||
|  |  | ||||||
| 	// Figure out how many levels of indirection there are by dereferencing |  | ||||||
| 	// pointers and unpacking interfaces down the chain while detecting circular |  | ||||||
| 	// references. |  | ||||||
| 	nilFound := false |  | ||||||
| 	cycleFound := false |  | ||||||
| 	indirects := 0 |  | ||||||
| 	ve := v |  | ||||||
| 	for ve.Kind() == reflect.Ptr { |  | ||||||
| 		if ve.IsNil() { |  | ||||||
| 			nilFound = true |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		indirects++ |  | ||||||
| 		addr := ve.Pointer() |  | ||||||
| 		pointerChain = append(pointerChain, addr) |  | ||||||
| 		if pd, ok := d.pointers[addr]; ok && pd < d.depth { |  | ||||||
| 			cycleFound = true |  | ||||||
| 			indirects-- |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		d.pointers[addr] = d.depth |  | ||||||
|  |  | ||||||
| 		ve = ve.Elem() |  | ||||||
| 		if ve.Kind() == reflect.Interface { |  | ||||||
| 			if ve.IsNil() { |  | ||||||
| 				nilFound = true |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 			ve = ve.Elem() |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Display type information. |  | ||||||
| 	d.w.Write(openParenBytes) |  | ||||||
| 	d.w.Write(bytes.Repeat(asteriskBytes, indirects)) |  | ||||||
| 	d.w.Write([]byte(ve.Type().String())) |  | ||||||
| 	d.w.Write(closeParenBytes) |  | ||||||
|  |  | ||||||
| 	// Display pointer information. |  | ||||||
| 	if !d.cs.DisablePointerAddresses && len(pointerChain) > 0 { |  | ||||||
| 		d.w.Write(openParenBytes) |  | ||||||
| 		for i, addr := range pointerChain { |  | ||||||
| 			if i > 0 { |  | ||||||
| 				d.w.Write(pointerChainBytes) |  | ||||||
| 			} |  | ||||||
| 			printHexPtr(d.w, addr) |  | ||||||
| 		} |  | ||||||
| 		d.w.Write(closeParenBytes) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Display dereferenced value. |  | ||||||
| 	d.w.Write(openParenBytes) |  | ||||||
| 	switch { |  | ||||||
| 	case nilFound: |  | ||||||
| 		d.w.Write(nilAngleBytes) |  | ||||||
|  |  | ||||||
| 	case cycleFound: |  | ||||||
| 		d.w.Write(circularBytes) |  | ||||||
|  |  | ||||||
| 	default: |  | ||||||
| 		d.ignoreNextType = true |  | ||||||
| 		d.dump(ve) |  | ||||||
| 	} |  | ||||||
| 	d.w.Write(closeParenBytes) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // dumpSlice handles formatting of arrays and slices.  Byte (uint8 under |  | ||||||
| // reflection) arrays and slices are dumped in hexdump -C fashion. |  | ||||||
| func (d *dumpState) dumpSlice(v reflect.Value) { |  | ||||||
| 	// Determine whether this type should be hex dumped or not.  Also, |  | ||||||
| 	// for types which should be hexdumped, try to use the underlying data |  | ||||||
| 	// first, then fall back to trying to convert them to a uint8 slice. |  | ||||||
| 	var buf []uint8 |  | ||||||
| 	doConvert := false |  | ||||||
| 	doHexDump := false |  | ||||||
| 	numEntries := v.Len() |  | ||||||
| 	if numEntries > 0 { |  | ||||||
| 		vt := v.Index(0).Type() |  | ||||||
| 		vts := vt.String() |  | ||||||
| 		switch { |  | ||||||
| 		// C types that need to be converted. |  | ||||||
| 		case cCharRE.MatchString(vts): |  | ||||||
| 			fallthrough |  | ||||||
| 		case cUnsignedCharRE.MatchString(vts): |  | ||||||
| 			fallthrough |  | ||||||
| 		case cUint8tCharRE.MatchString(vts): |  | ||||||
| 			doConvert = true |  | ||||||
|  |  | ||||||
| 		// Try to use existing uint8 slices and fall back to converting |  | ||||||
| 		// and copying if that fails. |  | ||||||
| 		case vt.Kind() == reflect.Uint8: |  | ||||||
| 			// We need an addressable interface to convert the type |  | ||||||
| 			// to a byte slice.  However, the reflect package won't |  | ||||||
| 			// give us an interface on certain things like |  | ||||||
| 			// unexported struct fields in order to enforce |  | ||||||
| 			// visibility rules.  We use unsafe, when available, to |  | ||||||
| 			// bypass these restrictions since this package does not |  | ||||||
| 			// mutate the values. |  | ||||||
| 			vs := v |  | ||||||
| 			if !vs.CanInterface() || !vs.CanAddr() { |  | ||||||
| 				vs = unsafeReflectValue(vs) |  | ||||||
| 			} |  | ||||||
| 			if !UnsafeDisabled { |  | ||||||
| 				vs = vs.Slice(0, numEntries) |  | ||||||
|  |  | ||||||
| 				// Use the existing uint8 slice if it can be |  | ||||||
| 				// type asserted. |  | ||||||
| 				iface := vs.Interface() |  | ||||||
| 				if slice, ok := iface.([]uint8); ok { |  | ||||||
| 					buf = slice |  | ||||||
| 					doHexDump = true |  | ||||||
| 					break |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			// The underlying data needs to be converted if it can't |  | ||||||
| 			// be type asserted to a uint8 slice. |  | ||||||
| 			doConvert = true |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// Copy and convert the underlying type if needed. |  | ||||||
| 		if doConvert && vt.ConvertibleTo(uint8Type) { |  | ||||||
| 			// Convert and copy each element into a uint8 byte |  | ||||||
| 			// slice. |  | ||||||
| 			buf = make([]uint8, numEntries) |  | ||||||
| 			for i := 0; i < numEntries; i++ { |  | ||||||
| 				vv := v.Index(i) |  | ||||||
| 				buf[i] = uint8(vv.Convert(uint8Type).Uint()) |  | ||||||
| 			} |  | ||||||
| 			doHexDump = true |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Hexdump the entire slice as needed. |  | ||||||
| 	if doHexDump { |  | ||||||
| 		indent := strings.Repeat(d.cs.Indent, d.depth) |  | ||||||
| 		str := indent + hex.Dump(buf) |  | ||||||
| 		str = strings.Replace(str, "\n", "\n"+indent, -1) |  | ||||||
| 		str = strings.TrimRight(str, d.cs.Indent) |  | ||||||
| 		d.w.Write([]byte(str)) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Recursively call dump for each item. |  | ||||||
| 	for i := 0; i < numEntries; i++ { |  | ||||||
| 		d.dump(d.unpackValue(v.Index(i))) |  | ||||||
| 		if i < (numEntries - 1) { |  | ||||||
| 			d.w.Write(commaNewlineBytes) |  | ||||||
| 		} else { |  | ||||||
| 			d.w.Write(newlineBytes) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // dump is the main workhorse for dumping a value.  It uses the passed reflect |  | ||||||
| // value to figure out what kind of object we are dealing with and formats it |  | ||||||
| // appropriately.  It is a recursive function, however circular data structures |  | ||||||
| // are detected and handled properly. |  | ||||||
| func (d *dumpState) dump(v reflect.Value) { |  | ||||||
| 	// Handle invalid reflect values immediately. |  | ||||||
| 	kind := v.Kind() |  | ||||||
| 	if kind == reflect.Invalid { |  | ||||||
| 		d.w.Write(invalidAngleBytes) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Handle pointers specially. |  | ||||||
| 	if kind == reflect.Ptr { |  | ||||||
| 		d.indent() |  | ||||||
| 		d.dumpPtr(v) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Print type information unless already handled elsewhere. |  | ||||||
| 	if !d.ignoreNextType { |  | ||||||
| 		d.indent() |  | ||||||
| 		d.w.Write(openParenBytes) |  | ||||||
| 		d.w.Write([]byte(v.Type().String())) |  | ||||||
| 		d.w.Write(closeParenBytes) |  | ||||||
| 		d.w.Write(spaceBytes) |  | ||||||
| 	} |  | ||||||
| 	d.ignoreNextType = false |  | ||||||
|  |  | ||||||
| 	// Display length and capacity if the built-in len and cap functions |  | ||||||
| 	// work with the value's kind and the len/cap itself is non-zero. |  | ||||||
| 	valueLen, valueCap := 0, 0 |  | ||||||
| 	switch v.Kind() { |  | ||||||
| 	case reflect.Array, reflect.Slice, reflect.Chan: |  | ||||||
| 		valueLen, valueCap = v.Len(), v.Cap() |  | ||||||
| 	case reflect.Map, reflect.String: |  | ||||||
| 		valueLen = v.Len() |  | ||||||
| 	} |  | ||||||
| 	if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 { |  | ||||||
| 		d.w.Write(openParenBytes) |  | ||||||
| 		if valueLen != 0 { |  | ||||||
| 			d.w.Write(lenEqualsBytes) |  | ||||||
| 			printInt(d.w, int64(valueLen), 10) |  | ||||||
| 		} |  | ||||||
| 		if !d.cs.DisableCapacities && valueCap != 0 { |  | ||||||
| 			if valueLen != 0 { |  | ||||||
| 				d.w.Write(spaceBytes) |  | ||||||
| 			} |  | ||||||
| 			d.w.Write(capEqualsBytes) |  | ||||||
| 			printInt(d.w, int64(valueCap), 10) |  | ||||||
| 		} |  | ||||||
| 		d.w.Write(closeParenBytes) |  | ||||||
| 		d.w.Write(spaceBytes) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Call Stringer/error interfaces if they exist and the handle methods flag |  | ||||||
| 	// is enabled |  | ||||||
| 	if !d.cs.DisableMethods { |  | ||||||
| 		if (kind != reflect.Invalid) && (kind != reflect.Interface) { |  | ||||||
| 			if handled := handleMethods(d.cs, d.w, v); handled { |  | ||||||
| 				return |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	switch kind { |  | ||||||
| 	case reflect.Invalid: |  | ||||||
| 		// Do nothing.  We should never get here since invalid has already |  | ||||||
| 		// been handled above. |  | ||||||
|  |  | ||||||
| 	case reflect.Bool: |  | ||||||
| 		printBool(d.w, v.Bool()) |  | ||||||
|  |  | ||||||
| 	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: |  | ||||||
| 		printInt(d.w, v.Int(), 10) |  | ||||||
|  |  | ||||||
| 	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: |  | ||||||
| 		printUint(d.w, v.Uint(), 10) |  | ||||||
|  |  | ||||||
| 	case reflect.Float32: |  | ||||||
| 		printFloat(d.w, v.Float(), 32) |  | ||||||
|  |  | ||||||
| 	case reflect.Float64: |  | ||||||
| 		printFloat(d.w, v.Float(), 64) |  | ||||||
|  |  | ||||||
| 	case reflect.Complex64: |  | ||||||
| 		printComplex(d.w, v.Complex(), 32) |  | ||||||
|  |  | ||||||
| 	case reflect.Complex128: |  | ||||||
| 		printComplex(d.w, v.Complex(), 64) |  | ||||||
|  |  | ||||||
| 	case reflect.Slice: |  | ||||||
| 		if v.IsNil() { |  | ||||||
| 			d.w.Write(nilAngleBytes) |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		fallthrough |  | ||||||
|  |  | ||||||
| 	case reflect.Array: |  | ||||||
| 		d.w.Write(openBraceNewlineBytes) |  | ||||||
| 		d.depth++ |  | ||||||
| 		if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { |  | ||||||
| 			d.indent() |  | ||||||
| 			d.w.Write(maxNewlineBytes) |  | ||||||
| 		} else { |  | ||||||
| 			d.dumpSlice(v) |  | ||||||
| 		} |  | ||||||
| 		d.depth-- |  | ||||||
| 		d.indent() |  | ||||||
| 		d.w.Write(closeBraceBytes) |  | ||||||
|  |  | ||||||
| 	case reflect.String: |  | ||||||
| 		d.w.Write([]byte(strconv.Quote(v.String()))) |  | ||||||
|  |  | ||||||
| 	case reflect.Interface: |  | ||||||
| 		// The only time we should get here is for nil interfaces due to |  | ||||||
| 		// unpackValue calls. |  | ||||||
| 		if v.IsNil() { |  | ||||||
| 			d.w.Write(nilAngleBytes) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 	case reflect.Ptr: |  | ||||||
| 		// Do nothing.  We should never get here since pointers have already |  | ||||||
| 		// been handled above. |  | ||||||
|  |  | ||||||
| 	case reflect.Map: |  | ||||||
| 		// nil maps should be indicated as different than empty maps |  | ||||||
| 		if v.IsNil() { |  | ||||||
| 			d.w.Write(nilAngleBytes) |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		d.w.Write(openBraceNewlineBytes) |  | ||||||
| 		d.depth++ |  | ||||||
| 		if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { |  | ||||||
| 			d.indent() |  | ||||||
| 			d.w.Write(maxNewlineBytes) |  | ||||||
| 		} else { |  | ||||||
| 			numEntries := v.Len() |  | ||||||
| 			keys := v.MapKeys() |  | ||||||
| 			if d.cs.SortKeys { |  | ||||||
| 				sortValues(keys, d.cs) |  | ||||||
| 			} |  | ||||||
| 			for i, key := range keys { |  | ||||||
| 				d.dump(d.unpackValue(key)) |  | ||||||
| 				d.w.Write(colonSpaceBytes) |  | ||||||
| 				d.ignoreNextIndent = true |  | ||||||
| 				d.dump(d.unpackValue(v.MapIndex(key))) |  | ||||||
| 				if i < (numEntries - 1) { |  | ||||||
| 					d.w.Write(commaNewlineBytes) |  | ||||||
| 				} else { |  | ||||||
| 					d.w.Write(newlineBytes) |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		d.depth-- |  | ||||||
| 		d.indent() |  | ||||||
| 		d.w.Write(closeBraceBytes) |  | ||||||
|  |  | ||||||
| 	case reflect.Struct: |  | ||||||
| 		d.w.Write(openBraceNewlineBytes) |  | ||||||
| 		d.depth++ |  | ||||||
| 		if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { |  | ||||||
| 			d.indent() |  | ||||||
| 			d.w.Write(maxNewlineBytes) |  | ||||||
| 		} else { |  | ||||||
| 			vt := v.Type() |  | ||||||
| 			numFields := v.NumField() |  | ||||||
| 			for i := 0; i < numFields; i++ { |  | ||||||
| 				d.indent() |  | ||||||
| 				vtf := vt.Field(i) |  | ||||||
| 				d.w.Write([]byte(vtf.Name)) |  | ||||||
| 				d.w.Write(colonSpaceBytes) |  | ||||||
| 				d.ignoreNextIndent = true |  | ||||||
| 				d.dump(d.unpackValue(v.Field(i))) |  | ||||||
| 				if i < (numFields - 1) { |  | ||||||
| 					d.w.Write(commaNewlineBytes) |  | ||||||
| 				} else { |  | ||||||
| 					d.w.Write(newlineBytes) |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		d.depth-- |  | ||||||
| 		d.indent() |  | ||||||
| 		d.w.Write(closeBraceBytes) |  | ||||||
|  |  | ||||||
| 	case reflect.Uintptr: |  | ||||||
| 		printHexPtr(d.w, uintptr(v.Uint())) |  | ||||||
|  |  | ||||||
| 	case reflect.UnsafePointer, reflect.Chan, reflect.Func: |  | ||||||
| 		printHexPtr(d.w, v.Pointer()) |  | ||||||
|  |  | ||||||
| 	// There were not any other types at the time this code was written, but |  | ||||||
| 	// fall back to letting the default fmt package handle it in case any new |  | ||||||
| 	// types are added. |  | ||||||
| 	default: |  | ||||||
| 		if v.CanInterface() { |  | ||||||
| 			fmt.Fprintf(d.w, "%v", v.Interface()) |  | ||||||
| 		} else { |  | ||||||
| 			fmt.Fprintf(d.w, "%v", v.String()) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // fdump is a helper function to consolidate the logic from the various public |  | ||||||
| // methods which take varying writers and config states. |  | ||||||
| func fdump(cs *ConfigState, w io.Writer, a ...interface{}) { |  | ||||||
| 	for _, arg := range a { |  | ||||||
| 		if arg == nil { |  | ||||||
| 			w.Write(interfaceBytes) |  | ||||||
| 			w.Write(spaceBytes) |  | ||||||
| 			w.Write(nilAngleBytes) |  | ||||||
| 			w.Write(newlineBytes) |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		d := dumpState{w: w, cs: cs} |  | ||||||
| 		d.pointers = make(map[uintptr]int) |  | ||||||
| 		d.dump(reflect.ValueOf(arg)) |  | ||||||
| 		d.w.Write(newlineBytes) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Fdump formats and displays the passed arguments to io.Writer w.  It formats |  | ||||||
| // exactly the same as Dump. |  | ||||||
| func Fdump(w io.Writer, a ...interface{}) { |  | ||||||
| 	fdump(&Config, w, a...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Sdump returns a string with the passed arguments formatted exactly the same |  | ||||||
| // as Dump. |  | ||||||
| func Sdump(a ...interface{}) string { |  | ||||||
| 	var buf bytes.Buffer |  | ||||||
| 	fdump(&Config, &buf, a...) |  | ||||||
| 	return buf.String() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* |  | ||||||
| Dump displays the passed parameters to standard out with newlines, customizable |  | ||||||
| indentation, and additional debug information such as complete types and all |  | ||||||
| pointer addresses used to indirect to the final value.  It provides the |  | ||||||
| following features over the built-in printing facilities provided by the fmt |  | ||||||
| package: |  | ||||||
|  |  | ||||||
| 	* Pointers are dereferenced and followed |  | ||||||
| 	* Circular data structures are detected and handled properly |  | ||||||
| 	* Custom Stringer/error interfaces are optionally invoked, including |  | ||||||
| 	  on unexported types |  | ||||||
| 	* Custom types which only implement the Stringer/error interfaces via |  | ||||||
| 	  a pointer receiver are optionally invoked when passing non-pointer |  | ||||||
| 	  variables |  | ||||||
| 	* Byte arrays and slices are dumped like the hexdump -C command which |  | ||||||
| 	  includes offsets, byte values in hex, and ASCII output |  | ||||||
|  |  | ||||||
| The configuration options are controlled by an exported package global, |  | ||||||
| spew.Config.  See ConfigState for options documentation. |  | ||||||
|  |  | ||||||
| See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to |  | ||||||
| get the formatted result as a string. |  | ||||||
| */ |  | ||||||
| func Dump(a ...interface{}) { |  | ||||||
| 	fdump(&Config, os.Stdout, a...) |  | ||||||
| } |  | ||||||
							
								
								
									
										419
									
								
								vendor/github.com/davecgh/go-spew/spew/format.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										419
									
								
								vendor/github.com/davecgh/go-spew/spew/format.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,419 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright (c) 2013-2016 Dave Collins <dave@davec.name> |  | ||||||
|  * |  | ||||||
|  * Permission to use, copy, modify, and distribute this software for any |  | ||||||
|  * purpose with or without fee is hereby granted, provided that the above |  | ||||||
|  * copyright notice and this permission notice appear in all copies. |  | ||||||
|  * |  | ||||||
|  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |  | ||||||
|  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |  | ||||||
|  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |  | ||||||
|  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |  | ||||||
|  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |  | ||||||
|  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |  | ||||||
|  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| package spew |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"fmt" |  | ||||||
| 	"reflect" |  | ||||||
| 	"strconv" |  | ||||||
| 	"strings" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // supportedFlags is a list of all the character flags supported by fmt package. |  | ||||||
| const supportedFlags = "0-+# " |  | ||||||
|  |  | ||||||
| // formatState implements the fmt.Formatter interface and contains information |  | ||||||
| // about the state of a formatting operation.  The NewFormatter function can |  | ||||||
| // be used to get a new Formatter which can be used directly as arguments |  | ||||||
| // in standard fmt package printing calls. |  | ||||||
| type formatState struct { |  | ||||||
| 	value          interface{} |  | ||||||
| 	fs             fmt.State |  | ||||||
| 	depth          int |  | ||||||
| 	pointers       map[uintptr]int |  | ||||||
| 	ignoreNextType bool |  | ||||||
| 	cs             *ConfigState |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // buildDefaultFormat recreates the original format string without precision |  | ||||||
| // and width information to pass in to fmt.Sprintf in the case of an |  | ||||||
| // unrecognized type.  Unless new types are added to the language, this |  | ||||||
| // function won't ever be called. |  | ||||||
| func (f *formatState) buildDefaultFormat() (format string) { |  | ||||||
| 	buf := bytes.NewBuffer(percentBytes) |  | ||||||
|  |  | ||||||
| 	for _, flag := range supportedFlags { |  | ||||||
| 		if f.fs.Flag(int(flag)) { |  | ||||||
| 			buf.WriteRune(flag) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	buf.WriteRune('v') |  | ||||||
|  |  | ||||||
| 	format = buf.String() |  | ||||||
| 	return format |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // constructOrigFormat recreates the original format string including precision |  | ||||||
| // and width information to pass along to the standard fmt package.  This allows |  | ||||||
| // automatic deferral of all format strings this package doesn't support. |  | ||||||
| func (f *formatState) constructOrigFormat(verb rune) (format string) { |  | ||||||
| 	buf := bytes.NewBuffer(percentBytes) |  | ||||||
|  |  | ||||||
| 	for _, flag := range supportedFlags { |  | ||||||
| 		if f.fs.Flag(int(flag)) { |  | ||||||
| 			buf.WriteRune(flag) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if width, ok := f.fs.Width(); ok { |  | ||||||
| 		buf.WriteString(strconv.Itoa(width)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if precision, ok := f.fs.Precision(); ok { |  | ||||||
| 		buf.Write(precisionBytes) |  | ||||||
| 		buf.WriteString(strconv.Itoa(precision)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	buf.WriteRune(verb) |  | ||||||
|  |  | ||||||
| 	format = buf.String() |  | ||||||
| 	return format |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // unpackValue returns values inside of non-nil interfaces when possible and |  | ||||||
| // ensures that types for values which have been unpacked from an interface |  | ||||||
| // are displayed when the show types flag is also set. |  | ||||||
| // This is useful for data types like structs, arrays, slices, and maps which |  | ||||||
| // can contain varying types packed inside an interface. |  | ||||||
| func (f *formatState) unpackValue(v reflect.Value) reflect.Value { |  | ||||||
| 	if v.Kind() == reflect.Interface { |  | ||||||
| 		f.ignoreNextType = false |  | ||||||
| 		if !v.IsNil() { |  | ||||||
| 			v = v.Elem() |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return v |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // formatPtr handles formatting of pointers by indirecting them as necessary. |  | ||||||
| func (f *formatState) formatPtr(v reflect.Value) { |  | ||||||
| 	// Display nil if top level pointer is nil. |  | ||||||
| 	showTypes := f.fs.Flag('#') |  | ||||||
| 	if v.IsNil() && (!showTypes || f.ignoreNextType) { |  | ||||||
| 		f.fs.Write(nilAngleBytes) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Remove pointers at or below the current depth from map used to detect |  | ||||||
| 	// circular refs. |  | ||||||
| 	for k, depth := range f.pointers { |  | ||||||
| 		if depth >= f.depth { |  | ||||||
| 			delete(f.pointers, k) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Keep list of all dereferenced pointers to possibly show later. |  | ||||||
| 	pointerChain := make([]uintptr, 0) |  | ||||||
|  |  | ||||||
| 	// Figure out how many levels of indirection there are by derferencing |  | ||||||
| 	// pointers and unpacking interfaces down the chain while detecting circular |  | ||||||
| 	// references. |  | ||||||
| 	nilFound := false |  | ||||||
| 	cycleFound := false |  | ||||||
| 	indirects := 0 |  | ||||||
| 	ve := v |  | ||||||
| 	for ve.Kind() == reflect.Ptr { |  | ||||||
| 		if ve.IsNil() { |  | ||||||
| 			nilFound = true |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		indirects++ |  | ||||||
| 		addr := ve.Pointer() |  | ||||||
| 		pointerChain = append(pointerChain, addr) |  | ||||||
| 		if pd, ok := f.pointers[addr]; ok && pd < f.depth { |  | ||||||
| 			cycleFound = true |  | ||||||
| 			indirects-- |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		f.pointers[addr] = f.depth |  | ||||||
|  |  | ||||||
| 		ve = ve.Elem() |  | ||||||
| 		if ve.Kind() == reflect.Interface { |  | ||||||
| 			if ve.IsNil() { |  | ||||||
| 				nilFound = true |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 			ve = ve.Elem() |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Display type or indirection level depending on flags. |  | ||||||
| 	if showTypes && !f.ignoreNextType { |  | ||||||
| 		f.fs.Write(openParenBytes) |  | ||||||
| 		f.fs.Write(bytes.Repeat(asteriskBytes, indirects)) |  | ||||||
| 		f.fs.Write([]byte(ve.Type().String())) |  | ||||||
| 		f.fs.Write(closeParenBytes) |  | ||||||
| 	} else { |  | ||||||
| 		if nilFound || cycleFound { |  | ||||||
| 			indirects += strings.Count(ve.Type().String(), "*") |  | ||||||
| 		} |  | ||||||
| 		f.fs.Write(openAngleBytes) |  | ||||||
| 		f.fs.Write([]byte(strings.Repeat("*", indirects))) |  | ||||||
| 		f.fs.Write(closeAngleBytes) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Display pointer information depending on flags. |  | ||||||
| 	if f.fs.Flag('+') && (len(pointerChain) > 0) { |  | ||||||
| 		f.fs.Write(openParenBytes) |  | ||||||
| 		for i, addr := range pointerChain { |  | ||||||
| 			if i > 0 { |  | ||||||
| 				f.fs.Write(pointerChainBytes) |  | ||||||
| 			} |  | ||||||
| 			printHexPtr(f.fs, addr) |  | ||||||
| 		} |  | ||||||
| 		f.fs.Write(closeParenBytes) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Display dereferenced value. |  | ||||||
| 	switch { |  | ||||||
| 	case nilFound: |  | ||||||
| 		f.fs.Write(nilAngleBytes) |  | ||||||
|  |  | ||||||
| 	case cycleFound: |  | ||||||
| 		f.fs.Write(circularShortBytes) |  | ||||||
|  |  | ||||||
| 	default: |  | ||||||
| 		f.ignoreNextType = true |  | ||||||
| 		f.format(ve) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // format is the main workhorse for providing the Formatter interface.  It |  | ||||||
| // uses the passed reflect value to figure out what kind of object we are |  | ||||||
| // dealing with and formats it appropriately.  It is a recursive function, |  | ||||||
| // however circular data structures are detected and handled properly. |  | ||||||
| func (f *formatState) format(v reflect.Value) { |  | ||||||
| 	// Handle invalid reflect values immediately. |  | ||||||
| 	kind := v.Kind() |  | ||||||
| 	if kind == reflect.Invalid { |  | ||||||
| 		f.fs.Write(invalidAngleBytes) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Handle pointers specially. |  | ||||||
| 	if kind == reflect.Ptr { |  | ||||||
| 		f.formatPtr(v) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Print type information unless already handled elsewhere. |  | ||||||
| 	if !f.ignoreNextType && f.fs.Flag('#') { |  | ||||||
| 		f.fs.Write(openParenBytes) |  | ||||||
| 		f.fs.Write([]byte(v.Type().String())) |  | ||||||
| 		f.fs.Write(closeParenBytes) |  | ||||||
| 	} |  | ||||||
| 	f.ignoreNextType = false |  | ||||||
|  |  | ||||||
| 	// Call Stringer/error interfaces if they exist and the handle methods |  | ||||||
| 	// flag is enabled. |  | ||||||
| 	if !f.cs.DisableMethods { |  | ||||||
| 		if (kind != reflect.Invalid) && (kind != reflect.Interface) { |  | ||||||
| 			if handled := handleMethods(f.cs, f.fs, v); handled { |  | ||||||
| 				return |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	switch kind { |  | ||||||
| 	case reflect.Invalid: |  | ||||||
| 		// Do nothing.  We should never get here since invalid has already |  | ||||||
| 		// been handled above. |  | ||||||
|  |  | ||||||
| 	case reflect.Bool: |  | ||||||
| 		printBool(f.fs, v.Bool()) |  | ||||||
|  |  | ||||||
| 	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: |  | ||||||
| 		printInt(f.fs, v.Int(), 10) |  | ||||||
|  |  | ||||||
| 	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: |  | ||||||
| 		printUint(f.fs, v.Uint(), 10) |  | ||||||
|  |  | ||||||
| 	case reflect.Float32: |  | ||||||
| 		printFloat(f.fs, v.Float(), 32) |  | ||||||
|  |  | ||||||
| 	case reflect.Float64: |  | ||||||
| 		printFloat(f.fs, v.Float(), 64) |  | ||||||
|  |  | ||||||
| 	case reflect.Complex64: |  | ||||||
| 		printComplex(f.fs, v.Complex(), 32) |  | ||||||
|  |  | ||||||
| 	case reflect.Complex128: |  | ||||||
| 		printComplex(f.fs, v.Complex(), 64) |  | ||||||
|  |  | ||||||
| 	case reflect.Slice: |  | ||||||
| 		if v.IsNil() { |  | ||||||
| 			f.fs.Write(nilAngleBytes) |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		fallthrough |  | ||||||
|  |  | ||||||
| 	case reflect.Array: |  | ||||||
| 		f.fs.Write(openBracketBytes) |  | ||||||
| 		f.depth++ |  | ||||||
| 		if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { |  | ||||||
| 			f.fs.Write(maxShortBytes) |  | ||||||
| 		} else { |  | ||||||
| 			numEntries := v.Len() |  | ||||||
| 			for i := 0; i < numEntries; i++ { |  | ||||||
| 				if i > 0 { |  | ||||||
| 					f.fs.Write(spaceBytes) |  | ||||||
| 				} |  | ||||||
| 				f.ignoreNextType = true |  | ||||||
| 				f.format(f.unpackValue(v.Index(i))) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		f.depth-- |  | ||||||
| 		f.fs.Write(closeBracketBytes) |  | ||||||
|  |  | ||||||
| 	case reflect.String: |  | ||||||
| 		f.fs.Write([]byte(v.String())) |  | ||||||
|  |  | ||||||
| 	case reflect.Interface: |  | ||||||
| 		// The only time we should get here is for nil interfaces due to |  | ||||||
| 		// unpackValue calls. |  | ||||||
| 		if v.IsNil() { |  | ||||||
| 			f.fs.Write(nilAngleBytes) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 	case reflect.Ptr: |  | ||||||
| 		// Do nothing.  We should never get here since pointers have already |  | ||||||
| 		// been handled above. |  | ||||||
|  |  | ||||||
| 	case reflect.Map: |  | ||||||
| 		// nil maps should be indicated as different than empty maps |  | ||||||
| 		if v.IsNil() { |  | ||||||
| 			f.fs.Write(nilAngleBytes) |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		f.fs.Write(openMapBytes) |  | ||||||
| 		f.depth++ |  | ||||||
| 		if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { |  | ||||||
| 			f.fs.Write(maxShortBytes) |  | ||||||
| 		} else { |  | ||||||
| 			keys := v.MapKeys() |  | ||||||
| 			if f.cs.SortKeys { |  | ||||||
| 				sortValues(keys, f.cs) |  | ||||||
| 			} |  | ||||||
| 			for i, key := range keys { |  | ||||||
| 				if i > 0 { |  | ||||||
| 					f.fs.Write(spaceBytes) |  | ||||||
| 				} |  | ||||||
| 				f.ignoreNextType = true |  | ||||||
| 				f.format(f.unpackValue(key)) |  | ||||||
| 				f.fs.Write(colonBytes) |  | ||||||
| 				f.ignoreNextType = true |  | ||||||
| 				f.format(f.unpackValue(v.MapIndex(key))) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		f.depth-- |  | ||||||
| 		f.fs.Write(closeMapBytes) |  | ||||||
|  |  | ||||||
| 	case reflect.Struct: |  | ||||||
| 		numFields := v.NumField() |  | ||||||
| 		f.fs.Write(openBraceBytes) |  | ||||||
| 		f.depth++ |  | ||||||
| 		if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { |  | ||||||
| 			f.fs.Write(maxShortBytes) |  | ||||||
| 		} else { |  | ||||||
| 			vt := v.Type() |  | ||||||
| 			for i := 0; i < numFields; i++ { |  | ||||||
| 				if i > 0 { |  | ||||||
| 					f.fs.Write(spaceBytes) |  | ||||||
| 				} |  | ||||||
| 				vtf := vt.Field(i) |  | ||||||
| 				if f.fs.Flag('+') || f.fs.Flag('#') { |  | ||||||
| 					f.fs.Write([]byte(vtf.Name)) |  | ||||||
| 					f.fs.Write(colonBytes) |  | ||||||
| 				} |  | ||||||
| 				f.format(f.unpackValue(v.Field(i))) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		f.depth-- |  | ||||||
| 		f.fs.Write(closeBraceBytes) |  | ||||||
|  |  | ||||||
| 	case reflect.Uintptr: |  | ||||||
| 		printHexPtr(f.fs, uintptr(v.Uint())) |  | ||||||
|  |  | ||||||
| 	case reflect.UnsafePointer, reflect.Chan, reflect.Func: |  | ||||||
| 		printHexPtr(f.fs, v.Pointer()) |  | ||||||
|  |  | ||||||
| 	// There were not any other types at the time this code was written, but |  | ||||||
| 	// fall back to letting the default fmt package handle it if any get added. |  | ||||||
| 	default: |  | ||||||
| 		format := f.buildDefaultFormat() |  | ||||||
| 		if v.CanInterface() { |  | ||||||
| 			fmt.Fprintf(f.fs, format, v.Interface()) |  | ||||||
| 		} else { |  | ||||||
| 			fmt.Fprintf(f.fs, format, v.String()) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Format satisfies the fmt.Formatter interface. See NewFormatter for usage |  | ||||||
| // details. |  | ||||||
| func (f *formatState) Format(fs fmt.State, verb rune) { |  | ||||||
| 	f.fs = fs |  | ||||||
|  |  | ||||||
| 	// Use standard formatting for verbs that are not v. |  | ||||||
| 	if verb != 'v' { |  | ||||||
| 		format := f.constructOrigFormat(verb) |  | ||||||
| 		fmt.Fprintf(fs, format, f.value) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if f.value == nil { |  | ||||||
| 		if fs.Flag('#') { |  | ||||||
| 			fs.Write(interfaceBytes) |  | ||||||
| 		} |  | ||||||
| 		fs.Write(nilAngleBytes) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	f.format(reflect.ValueOf(f.value)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // newFormatter is a helper function to consolidate the logic from the various |  | ||||||
| // public methods which take varying config states. |  | ||||||
| func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter { |  | ||||||
| 	fs := &formatState{value: v, cs: cs} |  | ||||||
| 	fs.pointers = make(map[uintptr]int) |  | ||||||
| 	return fs |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* |  | ||||||
| NewFormatter returns a custom formatter that satisfies the fmt.Formatter |  | ||||||
| interface.  As a result, it integrates cleanly with standard fmt package |  | ||||||
| printing functions.  The formatter is useful for inline printing of smaller data |  | ||||||
| types similar to the standard %v format specifier. |  | ||||||
|  |  | ||||||
| The custom formatter only responds to the %v (most compact), %+v (adds pointer |  | ||||||
| addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb |  | ||||||
| combinations.  Any other verbs such as %x and %q will be sent to the the |  | ||||||
| standard fmt package for formatting.  In addition, the custom formatter ignores |  | ||||||
| the width and precision arguments (however they will still work on the format |  | ||||||
| specifiers not handled by the custom formatter). |  | ||||||
|  |  | ||||||
| Typically this function shouldn't be called directly.  It is much easier to make |  | ||||||
| use of the custom formatter by calling one of the convenience functions such as |  | ||||||
| Printf, Println, or Fprintf. |  | ||||||
| */ |  | ||||||
| func NewFormatter(v interface{}) fmt.Formatter { |  | ||||||
| 	return newFormatter(&Config, v) |  | ||||||
| } |  | ||||||
							
								
								
									
										148
									
								
								vendor/github.com/davecgh/go-spew/spew/spew.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										148
									
								
								vendor/github.com/davecgh/go-spew/spew/spew.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,148 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright (c) 2013-2016 Dave Collins <dave@davec.name> |  | ||||||
|  * |  | ||||||
|  * Permission to use, copy, modify, and distribute this software for any |  | ||||||
|  * purpose with or without fee is hereby granted, provided that the above |  | ||||||
|  * copyright notice and this permission notice appear in all copies. |  | ||||||
|  * |  | ||||||
|  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |  | ||||||
|  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |  | ||||||
|  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |  | ||||||
|  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |  | ||||||
|  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |  | ||||||
|  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |  | ||||||
|  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| package spew |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // Errorf is a wrapper for fmt.Errorf that treats each argument as if it were |  | ||||||
| // passed with a default Formatter interface returned by NewFormatter.  It |  | ||||||
| // returns the formatted string as a value that satisfies error.  See |  | ||||||
| // NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b)) |  | ||||||
| func Errorf(format string, a ...interface{}) (err error) { |  | ||||||
| 	return fmt.Errorf(format, convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Fprint is a wrapper for fmt.Fprint that treats each argument as if it were |  | ||||||
| // passed with a default Formatter interface returned by NewFormatter.  It |  | ||||||
| // returns the number of bytes written and any write error encountered.  See |  | ||||||
| // NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b)) |  | ||||||
| func Fprint(w io.Writer, a ...interface{}) (n int, err error) { |  | ||||||
| 	return fmt.Fprint(w, convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were |  | ||||||
| // passed with a default Formatter interface returned by NewFormatter.  It |  | ||||||
| // returns the number of bytes written and any write error encountered.  See |  | ||||||
| // NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b)) |  | ||||||
| func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { |  | ||||||
| 	return fmt.Fprintf(w, format, convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it |  | ||||||
| // passed with a default Formatter interface returned by NewFormatter.  See |  | ||||||
| // NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b)) |  | ||||||
| func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { |  | ||||||
| 	return fmt.Fprintln(w, convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Print is a wrapper for fmt.Print that treats each argument as if it were |  | ||||||
| // passed with a default Formatter interface returned by NewFormatter.  It |  | ||||||
| // returns the number of bytes written and any write error encountered.  See |  | ||||||
| // NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b)) |  | ||||||
| func Print(a ...interface{}) (n int, err error) { |  | ||||||
| 	return fmt.Print(convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Printf is a wrapper for fmt.Printf that treats each argument as if it were |  | ||||||
| // passed with a default Formatter interface returned by NewFormatter.  It |  | ||||||
| // returns the number of bytes written and any write error encountered.  See |  | ||||||
| // NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b)) |  | ||||||
| func Printf(format string, a ...interface{}) (n int, err error) { |  | ||||||
| 	return fmt.Printf(format, convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Println is a wrapper for fmt.Println that treats each argument as if it were |  | ||||||
| // passed with a default Formatter interface returned by NewFormatter.  It |  | ||||||
| // returns the number of bytes written and any write error encountered.  See |  | ||||||
| // NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b)) |  | ||||||
| func Println(a ...interface{}) (n int, err error) { |  | ||||||
| 	return fmt.Println(convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Sprint is a wrapper for fmt.Sprint that treats each argument as if it were |  | ||||||
| // passed with a default Formatter interface returned by NewFormatter.  It |  | ||||||
| // returns the resulting string.  See NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b)) |  | ||||||
| func Sprint(a ...interface{}) string { |  | ||||||
| 	return fmt.Sprint(convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were |  | ||||||
| // passed with a default Formatter interface returned by NewFormatter.  It |  | ||||||
| // returns the resulting string.  See NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b)) |  | ||||||
| func Sprintf(format string, a ...interface{}) string { |  | ||||||
| 	return fmt.Sprintf(format, convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it |  | ||||||
| // were passed with a default Formatter interface returned by NewFormatter.  It |  | ||||||
| // returns the resulting string.  See NewFormatter for formatting details. |  | ||||||
| // |  | ||||||
| // This function is shorthand for the following syntax: |  | ||||||
| // |  | ||||||
| //	fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b)) |  | ||||||
| func Sprintln(a ...interface{}) string { |  | ||||||
| 	return fmt.Sprintln(convertArgs(a)...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // convertArgs accepts a slice of arguments and returns a slice of the same |  | ||||||
| // length with each argument converted to a default spew Formatter interface. |  | ||||||
| func convertArgs(args []interface{}) (formatters []interface{}) { |  | ||||||
| 	formatters = make([]interface{}, len(args)) |  | ||||||
| 	for index, arg := range args { |  | ||||||
| 		formatters[index] = NewFormatter(arg) |  | ||||||
| 	} |  | ||||||
| 	return formatters |  | ||||||
| } |  | ||||||
							
								
								
									
										64
									
								
								vendor/github.com/google/go-cmp/cmp/compare.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/google/go-cmp/cmp/compare.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -13,21 +13,21 @@ | |||||||
| // | // | ||||||
| // The primary features of cmp are: | // The primary features of cmp are: | ||||||
| // | // | ||||||
| // • When the default behavior of equality does not suit the needs of the test, | //   - When the default behavior of equality does not suit the test's needs, | ||||||
| // custom equality functions can override the equality operation. | //     custom equality functions can override the equality operation. | ||||||
| // For example, an equality function may report floats as equal so long as they | //     For example, an equality function may report floats as equal so long as | ||||||
| // are within some tolerance of each other. | //     they are within some tolerance of each other. | ||||||
| // | // | ||||||
| // • Types that have an Equal method may use that method to determine equality. | //   - Types with an Equal method may use that method to determine equality. | ||||||
| // This allows package authors to determine the equality operation for the types | //     This allows package authors to determine the equality operation | ||||||
| // that they define. | //     for the types that they define. | ||||||
| // | // | ||||||
| // • If no custom equality functions are used and no Equal method is defined, | //   - If no custom equality functions are used and no Equal method is defined, | ||||||
| // equality is determined by recursively comparing the primitive kinds on both | //     equality is determined by recursively comparing the primitive kinds on | ||||||
| // values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, unexported | //     both values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, | ||||||
| // fields are not compared by default; they result in panics unless suppressed | //     unexported fields are not compared by default; they result in panics | ||||||
| // by using an Ignore option (see cmpopts.IgnoreUnexported) or explicitly | //     unless suppressed by using an Ignore option (see cmpopts.IgnoreUnexported) | ||||||
| // compared using the Exporter option. | //     or explicitly compared using the Exporter option. | ||||||
| package cmp | package cmp | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| @@ -45,25 +45,25 @@ import ( | |||||||
| // Equal reports whether x and y are equal by recursively applying the | // Equal reports whether x and y are equal by recursively applying the | ||||||
| // following rules in the given order to x and y and all of their sub-values: | // following rules in the given order to x and y and all of their sub-values: | ||||||
| // | // | ||||||
| // • Let S be the set of all Ignore, Transformer, and Comparer options that | //   - Let S be the set of all Ignore, Transformer, and Comparer options that | ||||||
| // remain after applying all path filters, value filters, and type filters. | //     remain after applying all path filters, value filters, and type filters. | ||||||
| // If at least one Ignore exists in S, then the comparison is ignored. | //     If at least one Ignore exists in S, then the comparison is ignored. | ||||||
| // If the number of Transformer and Comparer options in S is greater than one, | //     If the number of Transformer and Comparer options in S is non-zero, | ||||||
| // then Equal panics because it is ambiguous which option to use. | //     then Equal panics because it is ambiguous which option to use. | ||||||
| // If S contains a single Transformer, then use that to transform the current | //     If S contains a single Transformer, then use that to transform | ||||||
| // values and recursively call Equal on the output values. | //     the current values and recursively call Equal on the output values. | ||||||
| // If S contains a single Comparer, then use that to compare the current values. | //     If S contains a single Comparer, then use that to compare the current values. | ||||||
| // Otherwise, evaluation proceeds to the next rule. | //     Otherwise, evaluation proceeds to the next rule. | ||||||
| // | // | ||||||
| // • If the values have an Equal method of the form "(T) Equal(T) bool" or | //   - If the values have an Equal method of the form "(T) Equal(T) bool" or | ||||||
| // "(T) Equal(I) bool" where T is assignable to I, then use the result of | //     "(T) Equal(I) bool" where T is assignable to I, then use the result of | ||||||
| // x.Equal(y) even if x or y is nil. Otherwise, no such method exists and | //     x.Equal(y) even if x or y is nil. Otherwise, no such method exists and | ||||||
| // evaluation proceeds to the next rule. | //     evaluation proceeds to the next rule. | ||||||
| // | // | ||||||
| // • Lastly, try to compare x and y based on their basic kinds. | //   - Lastly, try to compare x and y based on their basic kinds. | ||||||
| // Simple kinds like booleans, integers, floats, complex numbers, strings, and | //     Simple kinds like booleans, integers, floats, complex numbers, strings, | ||||||
| // channels are compared using the equivalent of the == operator in Go. | //     and channels are compared using the equivalent of the == operator in Go. | ||||||
| // Functions are only equal if they are both nil, otherwise they are unequal. | //     Functions are only equal if they are both nil, otherwise they are unequal. | ||||||
| // | // | ||||||
| // Structs are equal if recursively calling Equal on all fields report equal. | // Structs are equal if recursively calling Equal on all fields report equal. | ||||||
| // If a struct contains unexported fields, Equal panics unless an Ignore option | // If a struct contains unexported fields, Equal panics unless an Ignore option | ||||||
| @@ -144,7 +144,7 @@ func rootStep(x, y interface{}) PathStep { | |||||||
| 	// so that they have the same parent type. | 	// so that they have the same parent type. | ||||||
| 	var t reflect.Type | 	var t reflect.Type | ||||||
| 	if !vx.IsValid() || !vy.IsValid() || vx.Type() != vy.Type() { | 	if !vx.IsValid() || !vy.IsValid() || vx.Type() != vy.Type() { | ||||||
| 		t = reflect.TypeOf((*interface{})(nil)).Elem() | 		t = anyType | ||||||
| 		if vx.IsValid() { | 		if vx.IsValid() { | ||||||
| 			vvx := reflect.New(t).Elem() | 			vvx := reflect.New(t).Elem() | ||||||
| 			vvx.Set(vx) | 			vvx.Set(vx) | ||||||
| @@ -639,7 +639,9 @@ type dynChecker struct{ curr, next int } | |||||||
| // Next increments the state and reports whether a check should be performed. | // Next increments the state and reports whether a check should be performed. | ||||||
| // | // | ||||||
| // Checks occur every Nth function call, where N is a triangular number: | // Checks occur every Nth function call, where N is a triangular number: | ||||||
|  | // | ||||||
| //	0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 ... | //	0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 ... | ||||||
|  | // | ||||||
| // See https://en.wikipedia.org/wiki/Triangular_number | // See https://en.wikipedia.org/wiki/Triangular_number | ||||||
| // | // | ||||||
| // This sequence ensures that the cost of checks drops significantly as | // This sequence ensures that the cost of checks drops significantly as | ||||||
|   | |||||||
							
								
								
									
										44
									
								
								vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										44
									
								
								vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -127,9 +127,9 @@ var randBool = rand.New(rand.NewSource(time.Now().Unix())).Intn(2) == 0 | |||||||
| // This function returns an edit-script, which is a sequence of operations | // This function returns an edit-script, which is a sequence of operations | ||||||
| // needed to convert one list into the other. The following invariants for | // needed to convert one list into the other. The following invariants for | ||||||
| // the edit-script are maintained: | // the edit-script are maintained: | ||||||
| //	• eq == (es.Dist()==0) | //   - eq == (es.Dist()==0) | ||||||
| //	• nx == es.LenX() | //   - nx == es.LenX() | ||||||
| //	• ny == es.LenY() | //   - ny == es.LenY() | ||||||
| // | // | ||||||
| // This algorithm is not guaranteed to be an optimal solution (i.e., one that | // This algorithm is not guaranteed to be an optimal solution (i.e., one that | ||||||
| // produces an edit-script with a minimal Levenshtein distance). This algorithm | // produces an edit-script with a minimal Levenshtein distance). This algorithm | ||||||
| @@ -169,12 +169,13 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) { | |||||||
| 	// A diagonal edge is equivalent to a matching symbol between both X and Y. | 	// A diagonal edge is equivalent to a matching symbol between both X and Y. | ||||||
|  |  | ||||||
| 	// Invariants: | 	// Invariants: | ||||||
| 	//	• 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx | 	//   - 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx | ||||||
| 	//	• 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny | 	//   - 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny | ||||||
| 	// | 	// | ||||||
| 	// In general: | 	// In general: | ||||||
| 	//	• fwdFrontier.X < revFrontier.X | 	//   - fwdFrontier.X < revFrontier.X | ||||||
| 	//	• fwdFrontier.Y < revFrontier.Y | 	//   - fwdFrontier.Y < revFrontier.Y | ||||||
|  | 	// | ||||||
| 	// Unless, it is time for the algorithm to terminate. | 	// Unless, it is time for the algorithm to terminate. | ||||||
| 	fwdPath := path{+1, point{0, 0}, make(EditScript, 0, (nx+ny)/2)} | 	fwdPath := path{+1, point{0, 0}, make(EditScript, 0, (nx+ny)/2)} | ||||||
| 	revPath := path{-1, point{nx, ny}, make(EditScript, 0)} | 	revPath := path{-1, point{nx, ny}, make(EditScript, 0)} | ||||||
| @@ -195,19 +196,21 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) { | |||||||
| 	// computing sub-optimal edit-scripts between two lists. | 	// computing sub-optimal edit-scripts between two lists. | ||||||
| 	// | 	// | ||||||
| 	// The algorithm is approximately as follows: | 	// The algorithm is approximately as follows: | ||||||
| 	//	• Searching for differences switches back-and-forth between | 	//   - Searching for differences switches back-and-forth between | ||||||
| 	//	a search that starts at the beginning (the top-left corner), and | 	//     a search that starts at the beginning (the top-left corner), and | ||||||
| 	//	a search that starts at the end (the bottom-right corner). The goal of | 	//     a search that starts at the end (the bottom-right corner). | ||||||
| 	//	the search is connect with the search from the opposite corner. | 	//     The goal of the search is connect with the search | ||||||
| 	//	• As we search, we build a path in a greedy manner, where the first | 	//     from the opposite corner. | ||||||
| 	//	match seen is added to the path (this is sub-optimal, but provides a | 	//   - As we search, we build a path in a greedy manner, | ||||||
| 	//	decent result in practice). When matches are found, we try the next pair | 	//     where the first match seen is added to the path (this is sub-optimal, | ||||||
| 	//	of symbols in the lists and follow all matches as far as possible. | 	//     but provides a decent result in practice). When matches are found, | ||||||
| 	//	• When searching for matches, we search along a diagonal going through | 	//     we try the next pair of symbols in the lists and follow all matches | ||||||
| 	//	through the "frontier" point. If no matches are found, we advance the | 	//     as far as possible. | ||||||
| 	//	frontier towards the opposite corner. | 	//   - When searching for matches, we search along a diagonal going through | ||||||
| 	//	• This algorithm terminates when either the X coordinates or the | 	//     through the "frontier" point. If no matches are found, | ||||||
| 	//	Y coordinates of the forward and reverse frontier points ever intersect. | 	//     we advance the frontier towards the opposite corner. | ||||||
|  | 	//   - This algorithm terminates when either the X coordinates or the | ||||||
|  | 	//     Y coordinates of the forward and reverse frontier points ever intersect. | ||||||
|  |  | ||||||
| 	// This algorithm is correct even if searching only in the forward direction | 	// This algorithm is correct even if searching only in the forward direction | ||||||
| 	// or in the reverse direction. We do both because it is commonly observed | 	// or in the reverse direction. We do both because it is commonly observed | ||||||
| @@ -389,6 +392,7 @@ type point struct{ X, Y int } | |||||||
| func (p *point) add(dx, dy int) { p.X += dx; p.Y += dy } | func (p *point) add(dx, dy int) { p.X += dx; p.Y += dy } | ||||||
|  |  | ||||||
| // zigzag maps a consecutive sequence of integers to a zig-zag sequence. | // zigzag maps a consecutive sequence of integers to a zig-zag sequence. | ||||||
|  | // | ||||||
| //	[0 1 2 3 4 5 ...] => [0 -1 +1 -2 +2 ...] | //	[0 1 2 3 4 5 ...] => [0 -1 +1 -2 +2 ...] | ||||||
| func zigzag(x int) int { | func zigzag(x int) int { | ||||||
| 	if x&1 != 0 { | 	if x&1 != 0 { | ||||||
|   | |||||||
							
								
								
									
										48
									
								
								vendor/github.com/google/go-cmp/cmp/internal/value/zero.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										48
									
								
								vendor/github.com/google/go-cmp/cmp/internal/value/zero.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,48 +0,0 @@ | |||||||
| // Copyright 2017, The Go Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package value |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"math" |  | ||||||
| 	"reflect" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // IsZero reports whether v is the zero value. |  | ||||||
| // This does not rely on Interface and so can be used on unexported fields. |  | ||||||
| func IsZero(v reflect.Value) bool { |  | ||||||
| 	switch v.Kind() { |  | ||||||
| 	case reflect.Bool: |  | ||||||
| 		return v.Bool() == false |  | ||||||
| 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: |  | ||||||
| 		return v.Int() == 0 |  | ||||||
| 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: |  | ||||||
| 		return v.Uint() == 0 |  | ||||||
| 	case reflect.Float32, reflect.Float64: |  | ||||||
| 		return math.Float64bits(v.Float()) == 0 |  | ||||||
| 	case reflect.Complex64, reflect.Complex128: |  | ||||||
| 		return math.Float64bits(real(v.Complex())) == 0 && math.Float64bits(imag(v.Complex())) == 0 |  | ||||||
| 	case reflect.String: |  | ||||||
| 		return v.String() == "" |  | ||||||
| 	case reflect.UnsafePointer: |  | ||||||
| 		return v.Pointer() == 0 |  | ||||||
| 	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: |  | ||||||
| 		return v.IsNil() |  | ||||||
| 	case reflect.Array: |  | ||||||
| 		for i := 0; i < v.Len(); i++ { |  | ||||||
| 			if !IsZero(v.Index(i)) { |  | ||||||
| 				return false |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return true |  | ||||||
| 	case reflect.Struct: |  | ||||||
| 		for i := 0; i < v.NumField(); i++ { |  | ||||||
| 			if !IsZero(v.Field(i)) { |  | ||||||
| 				return false |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
							
								
								
									
										10
									
								
								vendor/github.com/google/go-cmp/cmp/options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/google/go-cmp/cmp/options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -33,6 +33,7 @@ type Option interface { | |||||||
| } | } | ||||||
|  |  | ||||||
| // applicableOption represents the following types: | // applicableOption represents the following types: | ||||||
|  | // | ||||||
| //	Fundamental: ignore | validator | *comparer | *transformer | //	Fundamental: ignore | validator | *comparer | *transformer | ||||||
| //	Grouping:    Options | //	Grouping:    Options | ||||||
| type applicableOption interface { | type applicableOption interface { | ||||||
| @@ -43,6 +44,7 @@ type applicableOption interface { | |||||||
| } | } | ||||||
|  |  | ||||||
| // coreOption represents the following types: | // coreOption represents the following types: | ||||||
|  | // | ||||||
| //	Fundamental: ignore | validator | *comparer | *transformer | //	Fundamental: ignore | validator | *comparer | *transformer | ||||||
| //	Filters:     *pathFilter | *valuesFilter | //	Filters:     *pathFilter | *valuesFilter | ||||||
| type coreOption interface { | type coreOption interface { | ||||||
| @@ -336,9 +338,9 @@ func (tr transformer) String() string { | |||||||
| // both implement T. | // both implement T. | ||||||
| // | // | ||||||
| // The equality function must be: | // The equality function must be: | ||||||
| //	• Symmetric: equal(x, y) == equal(y, x) | //   - Symmetric: equal(x, y) == equal(y, x) | ||||||
| //	• Deterministic: equal(x, y) == equal(x, y) | //   - Deterministic: equal(x, y) == equal(x, y) | ||||||
| //	• Pure: equal(x, y) does not modify x or y | //   - Pure: equal(x, y) does not modify x or y | ||||||
| func Comparer(f interface{}) Option { | func Comparer(f interface{}) Option { | ||||||
| 	v := reflect.ValueOf(f) | 	v := reflect.ValueOf(f) | ||||||
| 	if !function.IsType(v.Type(), function.Equal) || v.IsNil() { | 	if !function.IsType(v.Type(), function.Equal) || v.IsNil() { | ||||||
| @@ -430,7 +432,7 @@ func AllowUnexported(types ...interface{}) Option { | |||||||
| } | } | ||||||
|  |  | ||||||
| // Result represents the comparison result for a single node and | // Result represents the comparison result for a single node and | ||||||
| // is provided by cmp when calling Result (see Reporter). | // is provided by cmp when calling Report (see Reporter). | ||||||
| type Result struct { | type Result struct { | ||||||
| 	_     [0]func() // Make Result incomparable | 	_     [0]func() // Make Result incomparable | ||||||
| 	flags resultFlags | 	flags resultFlags | ||||||
|   | |||||||
							
								
								
									
										20
									
								
								vendor/github.com/google/go-cmp/cmp/path.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/google/go-cmp/cmp/path.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -41,13 +41,13 @@ type PathStep interface { | |||||||
| 	// The type of each valid value is guaranteed to be identical to Type. | 	// The type of each valid value is guaranteed to be identical to Type. | ||||||
| 	// | 	// | ||||||
| 	// In some cases, one or both may be invalid or have restrictions: | 	// In some cases, one or both may be invalid or have restrictions: | ||||||
| 	//	• For StructField, both are not interface-able if the current field | 	//   - For StructField, both are not interface-able if the current field | ||||||
| 	//	is unexported and the struct type is not explicitly permitted by | 	//     is unexported and the struct type is not explicitly permitted by | ||||||
| 	//	an Exporter to traverse unexported fields. | 	//     an Exporter to traverse unexported fields. | ||||||
| 	//	• For SliceIndex, one may be invalid if an element is missing from | 	//   - For SliceIndex, one may be invalid if an element is missing from | ||||||
| 	//	either the x or y slice. | 	//     either the x or y slice. | ||||||
| 	//	• For MapIndex, one may be invalid if an entry is missing from | 	//   - For MapIndex, one may be invalid if an entry is missing from | ||||||
| 	//	either the x or y map. | 	//     either the x or y map. | ||||||
| 	// | 	// | ||||||
| 	// The provided values must not be mutated. | 	// The provided values must not be mutated. | ||||||
| 	Values() (vx, vy reflect.Value) | 	Values() (vx, vy reflect.Value) | ||||||
| @@ -94,6 +94,7 @@ func (pa Path) Index(i int) PathStep { | |||||||
| // The simplified path only contains struct field accesses. | // The simplified path only contains struct field accesses. | ||||||
| // | // | ||||||
| // For example: | // For example: | ||||||
|  | // | ||||||
| //	MyMap.MySlices.MyField | //	MyMap.MySlices.MyField | ||||||
| func (pa Path) String() string { | func (pa Path) String() string { | ||||||
| 	var ss []string | 	var ss []string | ||||||
| @@ -108,6 +109,7 @@ func (pa Path) String() string { | |||||||
| // GoString returns the path to a specific node using Go syntax. | // GoString returns the path to a specific node using Go syntax. | ||||||
| // | // | ||||||
| // For example: | // For example: | ||||||
|  | // | ||||||
| //	(*root.MyMap["key"].(*mypkg.MyStruct).MySlices)[2][3].MyField | //	(*root.MyMap["key"].(*mypkg.MyStruct).MySlices)[2][3].MyField | ||||||
| func (pa Path) GoString() string { | func (pa Path) GoString() string { | ||||||
| 	var ssPre, ssPost []string | 	var ssPre, ssPost []string | ||||||
| @@ -159,7 +161,7 @@ func (ps pathStep) String() string { | |||||||
| 	if ps.typ == nil { | 	if ps.typ == nil { | ||||||
| 		return "<nil>" | 		return "<nil>" | ||||||
| 	} | 	} | ||||||
| 	s := ps.typ.String() | 	s := value.TypeString(ps.typ, false) | ||||||
| 	if s == "" || strings.ContainsAny(s, "{}\n") { | 	if s == "" || strings.ContainsAny(s, "{}\n") { | ||||||
| 		return "root" // Type too simple or complex to print | 		return "root" // Type too simple or complex to print | ||||||
| 	} | 	} | ||||||
| @@ -282,7 +284,7 @@ type typeAssertion struct { | |||||||
|  |  | ||||||
| func (ta TypeAssertion) Type() reflect.Type             { return ta.typ } | func (ta TypeAssertion) Type() reflect.Type             { return ta.typ } | ||||||
| func (ta TypeAssertion) Values() (vx, vy reflect.Value) { return ta.vx, ta.vy } | func (ta TypeAssertion) Values() (vx, vy reflect.Value) { return ta.vx, ta.vy } | ||||||
| func (ta TypeAssertion) String() string                 { return fmt.Sprintf(".(%v)", ta.typ) } | func (ta TypeAssertion) String() string                 { return fmt.Sprintf(".(%v)", value.TypeString(ta.typ, false)) } | ||||||
|  |  | ||||||
| // Transform is a transformation from the parent type to the current type. | // Transform is a transformation from the parent type to the current type. | ||||||
| type Transform struct{ *transform } | type Transform struct{ *transform } | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								vendor/github.com/google/go-cmp/cmp/report_compare.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/google/go-cmp/cmp/report_compare.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -7,8 +7,6 @@ package cmp | |||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"reflect" | 	"reflect" | ||||||
|  |  | ||||||
| 	"github.com/google/go-cmp/cmp/internal/value" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // numContextRecords is the number of surrounding equal records to print. | // numContextRecords is the number of surrounding equal records to print. | ||||||
| @@ -117,7 +115,7 @@ func (opts formatOptions) FormatDiff(v *valueNode, ptrs *pointerReferences) (out | |||||||
|  |  | ||||||
| 	// For leaf nodes, format the value based on the reflect.Values alone. | 	// For leaf nodes, format the value based on the reflect.Values alone. | ||||||
| 	// As a special case, treat equal []byte as a leaf nodes. | 	// As a special case, treat equal []byte as a leaf nodes. | ||||||
| 	isBytes := v.Type.Kind() == reflect.Slice && v.Type.Elem() == reflect.TypeOf(byte(0)) | 	isBytes := v.Type.Kind() == reflect.Slice && v.Type.Elem() == byteType | ||||||
| 	isEqualBytes := isBytes && v.NumDiff+v.NumIgnored+v.NumTransformed == 0 | 	isEqualBytes := isBytes && v.NumDiff+v.NumIgnored+v.NumTransformed == 0 | ||||||
| 	if v.MaxDepth == 0 || isEqualBytes { | 	if v.MaxDepth == 0 || isEqualBytes { | ||||||
| 		switch opts.DiffMode { | 		switch opts.DiffMode { | ||||||
| @@ -248,11 +246,11 @@ func (opts formatOptions) formatDiffList(recs []reportRecord, k reflect.Kind, pt | |||||||
| 				var isZero bool | 				var isZero bool | ||||||
| 				switch opts.DiffMode { | 				switch opts.DiffMode { | ||||||
| 				case diffIdentical: | 				case diffIdentical: | ||||||
| 					isZero = value.IsZero(r.Value.ValueX) || value.IsZero(r.Value.ValueY) | 					isZero = r.Value.ValueX.IsZero() || r.Value.ValueY.IsZero() | ||||||
| 				case diffRemoved: | 				case diffRemoved: | ||||||
| 					isZero = value.IsZero(r.Value.ValueX) | 					isZero = r.Value.ValueX.IsZero() | ||||||
| 				case diffInserted: | 				case diffInserted: | ||||||
| 					isZero = value.IsZero(r.Value.ValueY) | 					isZero = r.Value.ValueY.IsZero() | ||||||
| 				} | 				} | ||||||
| 				if isZero { | 				if isZero { | ||||||
| 					continue | 					continue | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								vendor/github.com/google/go-cmp/cmp/report_reflect.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/google/go-cmp/cmp/report_reflect.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -16,6 +16,13 @@ import ( | |||||||
| 	"github.com/google/go-cmp/cmp/internal/value" | 	"github.com/google/go-cmp/cmp/internal/value" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	anyType    = reflect.TypeOf((*interface{})(nil)).Elem() | ||||||
|  | 	stringType = reflect.TypeOf((*string)(nil)).Elem() | ||||||
|  | 	bytesType  = reflect.TypeOf((*[]byte)(nil)).Elem() | ||||||
|  | 	byteType   = reflect.TypeOf((*byte)(nil)).Elem() | ||||||
|  | ) | ||||||
|  |  | ||||||
| type formatValueOptions struct { | type formatValueOptions struct { | ||||||
| 	// AvoidStringer controls whether to avoid calling custom stringer | 	// AvoidStringer controls whether to avoid calling custom stringer | ||||||
| 	// methods like error.Error or fmt.Stringer.String. | 	// methods like error.Error or fmt.Stringer.String. | ||||||
| @@ -184,7 +191,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind, | |||||||
| 		} | 		} | ||||||
| 		for i := 0; i < v.NumField(); i++ { | 		for i := 0; i < v.NumField(); i++ { | ||||||
| 			vv := v.Field(i) | 			vv := v.Field(i) | ||||||
| 			if value.IsZero(vv) { | 			if vv.IsZero() { | ||||||
| 				continue // Elide fields with zero values | 				continue // Elide fields with zero values | ||||||
| 			} | 			} | ||||||
| 			if len(list) == maxLen { | 			if len(list) == maxLen { | ||||||
| @@ -205,7 +212,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind, | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Check whether this is a []byte of text data. | 		// Check whether this is a []byte of text data. | ||||||
| 		if t.Elem() == reflect.TypeOf(byte(0)) { | 		if t.Elem() == byteType { | ||||||
| 			b := v.Bytes() | 			b := v.Bytes() | ||||||
| 			isPrintSpace := func(r rune) bool { return unicode.IsPrint(r) || unicode.IsSpace(r) } | 			isPrintSpace := func(r rune) bool { return unicode.IsPrint(r) || unicode.IsSpace(r) } | ||||||
| 			if len(b) > 0 && utf8.Valid(b) && len(bytes.TrimFunc(b, isPrintSpace)) == 0 { | 			if len(b) > 0 && utf8.Valid(b) && len(bytes.TrimFunc(b, isPrintSpace)) == 0 { | ||||||
|   | |||||||
							
								
								
									
										25
									
								
								vendor/github.com/google/go-cmp/cmp/report_slices.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								vendor/github.com/google/go-cmp/cmp/report_slices.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -104,7 +104,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { | |||||||
| 	case t.Kind() == reflect.String: | 	case t.Kind() == reflect.String: | ||||||
| 		sx, sy = vx.String(), vy.String() | 		sx, sy = vx.String(), vy.String() | ||||||
| 		isString = true | 		isString = true | ||||||
| 	case t.Kind() == reflect.Slice && t.Elem() == reflect.TypeOf(byte(0)): | 	case t.Kind() == reflect.Slice && t.Elem() == byteType: | ||||||
| 		sx, sy = string(vx.Bytes()), string(vy.Bytes()) | 		sx, sy = string(vx.Bytes()), string(vy.Bytes()) | ||||||
| 		isString = true | 		isString = true | ||||||
| 	case t.Kind() == reflect.Array: | 	case t.Kind() == reflect.Array: | ||||||
| @@ -147,7 +147,10 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { | |||||||
| 			}) | 			}) | ||||||
| 			efficiencyLines := float64(esLines.Dist()) / float64(len(esLines)) | 			efficiencyLines := float64(esLines.Dist()) / float64(len(esLines)) | ||||||
| 			efficiencyBytes := float64(esBytes.Dist()) / float64(len(esBytes)) | 			efficiencyBytes := float64(esBytes.Dist()) / float64(len(esBytes)) | ||||||
| 			isPureLinedText = efficiencyLines < 4*efficiencyBytes | 			quotedLength := len(strconv.Quote(sx + sy)) | ||||||
|  | 			unquotedLength := len(sx) + len(sy) | ||||||
|  | 			escapeExpansionRatio := float64(quotedLength) / float64(unquotedLength) | ||||||
|  | 			isPureLinedText = efficiencyLines < 4*efficiencyBytes || escapeExpansionRatio > 1.1 | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -171,12 +174,13 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { | |||||||
| 		// differences in a string literal. This format is more readable, | 		// differences in a string literal. This format is more readable, | ||||||
| 		// but has edge-cases where differences are visually indistinguishable. | 		// but has edge-cases where differences are visually indistinguishable. | ||||||
| 		// This format is avoided under the following conditions: | 		// This format is avoided under the following conditions: | ||||||
| 		//	• A line starts with `"""` | 		//   - A line starts with `"""` | ||||||
| 		//	• A line starts with "..." | 		//   - A line starts with "..." | ||||||
| 		//	• A line contains non-printable characters | 		//   - A line contains non-printable characters | ||||||
| 		//	• Adjacent different lines differ only by whitespace | 		//   - Adjacent different lines differ only by whitespace | ||||||
| 		// | 		// | ||||||
| 		// For example: | 		// For example: | ||||||
|  | 		// | ||||||
| 		//		""" | 		//		""" | ||||||
| 		//		... // 3 identical lines | 		//		... // 3 identical lines | ||||||
| 		//		foo | 		//		foo | ||||||
| @@ -231,7 +235,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { | |||||||
| 			var out textNode = &textWrap{Prefix: "(", Value: list2, Suffix: ")"} | 			var out textNode = &textWrap{Prefix: "(", Value: list2, Suffix: ")"} | ||||||
| 			switch t.Kind() { | 			switch t.Kind() { | ||||||
| 			case reflect.String: | 			case reflect.String: | ||||||
| 				if t != reflect.TypeOf(string("")) { | 				if t != stringType { | ||||||
| 					out = opts.FormatType(t, out) | 					out = opts.FormatType(t, out) | ||||||
| 				} | 				} | ||||||
| 			case reflect.Slice: | 			case reflect.Slice: | ||||||
| @@ -326,12 +330,12 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { | |||||||
| 	switch t.Kind() { | 	switch t.Kind() { | ||||||
| 	case reflect.String: | 	case reflect.String: | ||||||
| 		out = &textWrap{Prefix: "strings.Join(", Value: out, Suffix: fmt.Sprintf(", %q)", delim)} | 		out = &textWrap{Prefix: "strings.Join(", Value: out, Suffix: fmt.Sprintf(", %q)", delim)} | ||||||
| 		if t != reflect.TypeOf(string("")) { | 		if t != stringType { | ||||||
| 			out = opts.FormatType(t, out) | 			out = opts.FormatType(t, out) | ||||||
| 		} | 		} | ||||||
| 	case reflect.Slice: | 	case reflect.Slice: | ||||||
| 		out = &textWrap{Prefix: "bytes.Join(", Value: out, Suffix: fmt.Sprintf(", %q)", delim)} | 		out = &textWrap{Prefix: "bytes.Join(", Value: out, Suffix: fmt.Sprintf(", %q)", delim)} | ||||||
| 		if t != reflect.TypeOf([]byte(nil)) { | 		if t != bytesType { | ||||||
| 			out = opts.FormatType(t, out) | 			out = opts.FormatType(t, out) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -446,7 +450,6 @@ func (opts formatOptions) formatDiffSlice( | |||||||
| //		{NumIdentical: 3}, | //		{NumIdentical: 3}, | ||||||
| //		{NumInserted: 1}, | //		{NumInserted: 1}, | ||||||
| //	] | //	] | ||||||
| // |  | ||||||
| func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) { | func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) { | ||||||
| 	var prevMode byte | 	var prevMode byte | ||||||
| 	lastStats := func(mode byte) *diffStats { | 	lastStats := func(mode byte) *diffStats { | ||||||
| @@ -503,7 +506,6 @@ func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) | |||||||
| //		{NumIdentical: 8, NumRemoved: 12, NumInserted: 3}, | //		{NumIdentical: 8, NumRemoved: 12, NumInserted: 3}, | ||||||
| //		{NumIdentical: 63}, | //		{NumIdentical: 63}, | ||||||
| //	] | //	] | ||||||
| // |  | ||||||
| func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStats { | func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStats { | ||||||
| 	groups, groupsOrig := groups[:0], groups | 	groups, groupsOrig := groups[:0], groups | ||||||
| 	for i, ds := range groupsOrig { | 	for i, ds := range groupsOrig { | ||||||
| @@ -548,7 +550,6 @@ func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStat | |||||||
| //		{NumRemoved: 9}, | //		{NumRemoved: 9}, | ||||||
| //		{NumIdentical: 64}, // incremented by 10 | //		{NumIdentical: 64}, // incremented by 10 | ||||||
| //	] | //	] | ||||||
| // |  | ||||||
| func cleanupSurroundingIdentical(groups []diffStats, eq func(i, j int) bool) []diffStats { | func cleanupSurroundingIdentical(groups []diffStats, eq func(i, j int) bool) []diffStats { | ||||||
| 	var ix, iy int // indexes into sequence x and y | 	var ix, iy int // indexes into sequence x and y | ||||||
| 	for i, ds := range groups { | 	for i, ds := range groups { | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/google/go-cmp/cmp/report_text.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/google/go-cmp/cmp/report_text.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -393,6 +393,7 @@ func (s diffStats) Append(ds diffStats) diffStats { | |||||||
| // String prints a humanly-readable summary of coalesced records. | // String prints a humanly-readable summary of coalesced records. | ||||||
| // | // | ||||||
| // Example: | // Example: | ||||||
|  | // | ||||||
| //	diffStats{Name: "Field", NumIgnored: 5}.String() => "5 ignored fields" | //	diffStats{Name: "Field", NumIgnored: 5}.String() => "5 ignored fields" | ||||||
| func (s diffStats) String() string { | func (s diffStats) String() string { | ||||||
| 	var ss []string | 	var ss []string | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								vendor/github.com/google/uuid/hash.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/google/uuid/hash.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -26,8 +26,8 @@ var ( | |||||||
| // NewMD5 and NewSHA1. | // NewMD5 and NewSHA1. | ||||||
| func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { | func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { | ||||||
| 	h.Reset() | 	h.Reset() | ||||||
| 	h.Write(space[:]) | 	h.Write(space[:]) //nolint:errcheck | ||||||
| 	h.Write(data) | 	h.Write(data)     //nolint:errcheck | ||||||
| 	s := h.Sum(nil) | 	s := h.Sum(nil) | ||||||
| 	var uuid UUID | 	var uuid UUID | ||||||
| 	copy(uuid[:], s) | 	copy(uuid[:], s) | ||||||
|   | |||||||
							
								
								
									
										118
									
								
								vendor/github.com/google/uuid/null.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								vendor/github.com/google/uuid/null.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | |||||||
|  | // Copyright 2021 Google Inc.  All rights reserved. | ||||||
|  | // Use of this source code is governed by a BSD-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package uuid | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"database/sql/driver" | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var jsonNull = []byte("null") | ||||||
|  |  | ||||||
|  | // NullUUID represents a UUID that may be null. | ||||||
|  | // NullUUID implements the SQL driver.Scanner interface so | ||||||
|  | // it can be used as a scan destination: | ||||||
|  | // | ||||||
|  | //  var u uuid.NullUUID | ||||||
|  | //  err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&u) | ||||||
|  | //  ... | ||||||
|  | //  if u.Valid { | ||||||
|  | //     // use u.UUID | ||||||
|  | //  } else { | ||||||
|  | //     // NULL value | ||||||
|  | //  } | ||||||
|  | // | ||||||
|  | type NullUUID struct { | ||||||
|  | 	UUID  UUID | ||||||
|  | 	Valid bool // Valid is true if UUID is not NULL | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Scan implements the SQL driver.Scanner interface. | ||||||
|  | func (nu *NullUUID) Scan(value interface{}) error { | ||||||
|  | 	if value == nil { | ||||||
|  | 		nu.UUID, nu.Valid = Nil, false | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err := nu.UUID.Scan(value) | ||||||
|  | 	if err != nil { | ||||||
|  | 		nu.Valid = false | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	nu.Valid = true | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Value implements the driver Valuer interface. | ||||||
|  | func (nu NullUUID) Value() (driver.Value, error) { | ||||||
|  | 	if !nu.Valid { | ||||||
|  | 		return nil, nil | ||||||
|  | 	} | ||||||
|  | 	// Delegate to UUID Value function | ||||||
|  | 	return nu.UUID.Value() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // MarshalBinary implements encoding.BinaryMarshaler. | ||||||
|  | func (nu NullUUID) MarshalBinary() ([]byte, error) { | ||||||
|  | 	if nu.Valid { | ||||||
|  | 		return nu.UUID[:], nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return []byte(nil), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // UnmarshalBinary implements encoding.BinaryUnmarshaler. | ||||||
|  | func (nu *NullUUID) UnmarshalBinary(data []byte) error { | ||||||
|  | 	if len(data) != 16 { | ||||||
|  | 		return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) | ||||||
|  | 	} | ||||||
|  | 	copy(nu.UUID[:], data) | ||||||
|  | 	nu.Valid = true | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // MarshalText implements encoding.TextMarshaler. | ||||||
|  | func (nu NullUUID) MarshalText() ([]byte, error) { | ||||||
|  | 	if nu.Valid { | ||||||
|  | 		return nu.UUID.MarshalText() | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return jsonNull, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // UnmarshalText implements encoding.TextUnmarshaler. | ||||||
|  | func (nu *NullUUID) UnmarshalText(data []byte) error { | ||||||
|  | 	id, err := ParseBytes(data) | ||||||
|  | 	if err != nil { | ||||||
|  | 		nu.Valid = false | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	nu.UUID = id | ||||||
|  | 	nu.Valid = true | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // MarshalJSON implements json.Marshaler. | ||||||
|  | func (nu NullUUID) MarshalJSON() ([]byte, error) { | ||||||
|  | 	if nu.Valid { | ||||||
|  | 		return json.Marshal(nu.UUID) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return jsonNull, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // UnmarshalJSON implements json.Unmarshaler. | ||||||
|  | func (nu *NullUUID) UnmarshalJSON(data []byte) error { | ||||||
|  | 	if bytes.Equal(data, jsonNull) { | ||||||
|  | 		*nu = NullUUID{} | ||||||
|  | 		return nil // valid null UUID | ||||||
|  | 	} | ||||||
|  | 	err := json.Unmarshal(data, &nu.UUID) | ||||||
|  | 	nu.Valid = err == nil | ||||||
|  | 	return err | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								vendor/github.com/google/uuid/sql.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/google/uuid/sql.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -9,7 +9,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Scan implements sql.Scanner so UUIDs can be read from databases transparently | // Scan implements sql.Scanner so UUIDs can be read from databases transparently. | ||||||
| // Currently, database types that map to string and []byte are supported. Please | // Currently, database types that map to string and []byte are supported. Please | ||||||
| // consult database-specific driver documentation for matching types. | // consult database-specific driver documentation for matching types. | ||||||
| func (uuid *UUID) Scan(src interface{}) error { | func (uuid *UUID) Scan(src interface{}) error { | ||||||
|   | |||||||
							
								
								
									
										55
									
								
								vendor/github.com/google/uuid/uuid.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										55
									
								
								vendor/github.com/google/uuid/uuid.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -12,6 +12,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
| 	"strings" | 	"strings" | ||||||
|  | 	"sync" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC | // A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC | ||||||
| @@ -33,7 +34,27 @@ const ( | |||||||
| 	Future                    // Reserved for future definition. | 	Future                    // Reserved for future definition. | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var rander = rand.Reader // random function | const randPoolSize = 16 * 16 | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	rander      = rand.Reader // random function | ||||||
|  | 	poolEnabled = false | ||||||
|  | 	poolMu      sync.Mutex | ||||||
|  | 	poolPos     = randPoolSize     // protected with poolMu | ||||||
|  | 	pool        [randPoolSize]byte // protected with poolMu | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type invalidLengthError struct{ len int } | ||||||
|  |  | ||||||
|  | func (err invalidLengthError) Error() string { | ||||||
|  | 	return fmt.Sprintf("invalid UUID length: %d", err.len) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IsInvalidLengthError is matcher function for custom error invalidLengthError | ||||||
|  | func IsInvalidLengthError(err error) bool { | ||||||
|  | 	_, ok := err.(invalidLengthError) | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  |  | ||||||
| // Parse decodes s into a UUID or returns an error.  Both the standard UUID | // Parse decodes s into a UUID or returns an error.  Both the standard UUID | ||||||
| // forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and | // forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and | ||||||
| @@ -68,7 +89,7 @@ func Parse(s string) (UUID, error) { | |||||||
| 		} | 		} | ||||||
| 		return uuid, nil | 		return uuid, nil | ||||||
| 	default: | 	default: | ||||||
| 		return uuid, fmt.Errorf("invalid UUID length: %d", len(s)) | 		return uuid, invalidLengthError{len(s)} | ||||||
| 	} | 	} | ||||||
| 	// s is now at least 36 bytes long | 	// s is now at least 36 bytes long | ||||||
| 	// it must be of the form  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | 	// it must be of the form  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | ||||||
| @@ -112,7 +133,7 @@ func ParseBytes(b []byte) (UUID, error) { | |||||||
| 		} | 		} | ||||||
| 		return uuid, nil | 		return uuid, nil | ||||||
| 	default: | 	default: | ||||||
| 		return uuid, fmt.Errorf("invalid UUID length: %d", len(b)) | 		return uuid, invalidLengthError{len(b)} | ||||||
| 	} | 	} | ||||||
| 	// s is now at least 36 bytes long | 	// s is now at least 36 bytes long | ||||||
| 	// it must be of the form  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | 	// it must be of the form  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | ||||||
| @@ -243,3 +264,31 @@ func SetRand(r io.Reader) { | |||||||
| 	} | 	} | ||||||
| 	rander = r | 	rander = r | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // EnableRandPool enables internal randomness pool used for Random | ||||||
|  | // (Version 4) UUID generation. The pool contains random bytes read from | ||||||
|  | // the random number generator on demand in batches. Enabling the pool | ||||||
|  | // may improve the UUID generation throughput significantly. | ||||||
|  | // | ||||||
|  | // Since the pool is stored on the Go heap, this feature may be a bad fit | ||||||
|  | // for security sensitive applications. | ||||||
|  | // | ||||||
|  | // Both EnableRandPool and DisableRandPool are not thread-safe and should | ||||||
|  | // only be called when there is no possibility that New or any other | ||||||
|  | // UUID Version 4 generation function will be called concurrently. | ||||||
|  | func EnableRandPool() { | ||||||
|  | 	poolEnabled = true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // DisableRandPool disables the randomness pool if it was previously | ||||||
|  | // enabled with EnableRandPool. | ||||||
|  | // | ||||||
|  | // Both EnableRandPool and DisableRandPool are not thread-safe and should | ||||||
|  | // only be called when there is no possibility that New or any other | ||||||
|  | // UUID Version 4 generation function will be called concurrently. | ||||||
|  | func DisableRandPool() { | ||||||
|  | 	poolEnabled = false | ||||||
|  | 	defer poolMu.Unlock() | ||||||
|  | 	poolMu.Lock() | ||||||
|  | 	poolPos = randPoolSize | ||||||
|  | } | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user