Compare commits
	
		
			83 Commits
		
	
	
		
			v0.7.0
			...
			340bcd48fe
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 340bcd48fe | ||
|  | 2d7147442b | ||
|  | ed32470b17 | ||
| 483bda1033 | |||
|  | 48f5c3ee3c | ||
|  | c707cba22e | ||
|  | 5b14a5d789 | ||
|  | 707443c6d2 | ||
|  | 04160fa7a3 | ||
|  | c1ba34b248 | ||
|  | 0d09d97866 | ||
|  | b3f93373d0 | ||
|  | 58498b616b | ||
|  | 4e94047737 | ||
|  | 425434baa8 | ||
|  | 7f04ccd8f8 | ||
|  | e8584b0270 | ||
|  | 910ccdb092 | ||
|  | b2403e2569 | ||
|  | 98867f2830 | ||
|  | 948b20a6d2 | ||
|  | 83a0cbf14c | ||
|  | 71caf4430b | ||
|  | 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 | ||
| e7ad54b0a4 | |||
| 3f67ba1895 | |||
| 0f441b26d1 | |||
| f9d35d01c6 | |||
| c183098b7d | |||
| e4ff32cc94 | |||
| c4757ce109 | |||
| 8e2fc7264b | |||
| aa7856ea7b | |||
| 8b25a1519e | |||
| cfa43451d8 | |||
| cf2fc0f54f | |||
| bc6261d444 | |||
| e1266ebf64 | 
							
								
								
									
										19
									
								
								.drone.yml
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								.drone.yml
									
									
									
									
									
								
							| @@ -15,13 +15,25 @@ steps: | |||||||
|       - push |       - push | ||||||
|       - pull_request |       - pull_request | ||||||
|       - tag |       - tag | ||||||
|   - name: build |   - name: build-dev | ||||||
|     image: goreleaser/goreleaser |     image: golang:1.18.3-alpine3.16 | ||||||
|     commands: |     commands: | ||||||
|       - goreleaser build --snapshot |       - "apk add --update --no-cache make" | ||||||
|  |       - "make build" | ||||||
|     when: |     when: | ||||||
|       event: |       event: | ||||||
|       - push |       - push | ||||||
|  |     resources: | ||||||
|  |       limits: | ||||||
|  |         cpu: 1000 | ||||||
|  |         memory: 1024MiB | ||||||
|  |   - name: build | ||||||
|  |     image: goreleaser/goreleaser | ||||||
|  |     commands: | ||||||
|  |       - curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin v0.64.0 | ||||||
|  |       - goreleaser build --snapshot | ||||||
|  |     when: | ||||||
|  |       event: | ||||||
|       - pull_request |       - pull_request | ||||||
|     resources: |     resources: | ||||||
|       limits: |       limits: | ||||||
| @@ -48,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 | ||||||
|   | |||||||
							
								
								
									
										28
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | --- | ||||||
|  | name: Bug report | ||||||
|  | about: Create a report to improve the provider | ||||||
|  | title: '' | ||||||
|  | labels: 'bug' | ||||||
|  | assignees: '' | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | **Describe the bug** | ||||||
|  | A clear and concise description of what the bug is. | ||||||
|  |  | ||||||
|  | **To Reproduce** | ||||||
|  | Steps to reproduce the behavior: | ||||||
|  |  | ||||||
|  | **Expected behavior** | ||||||
|  | A clear and concise description of what you expected to happen. | ||||||
|  |  | ||||||
|  | **Log Output** | ||||||
|  | If applicable, add logs to help explain your problem. | ||||||
|  |  | ||||||
|  | **Additional Data** | ||||||
|  | Important for reproducability. | ||||||
|  |  | ||||||
|  | - Terraform Version | ||||||
|  |  | ||||||
|  | - Operating System | ||||||
|  |  | ||||||
|  | - Provider Version | ||||||
							
								
								
									
										20
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | --- | ||||||
|  | name: Feature request | ||||||
|  | about: Suggest an idea for this provider | ||||||
|  | title: '' | ||||||
|  | labels: 'enhancement' | ||||||
|  | assignees: '' | ||||||
|  |  | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | **Is your feature request related to a problem? Please describe.** | ||||||
|  | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] | ||||||
|  |  | ||||||
|  | **Describe the solution you'd like** | ||||||
|  | A clear and concise description of what you want to happen. | ||||||
|  |  | ||||||
|  | **Describe alternatives you've considered** | ||||||
|  | A clear and concise description of any alternative solutions or features you've considered. | ||||||
|  |  | ||||||
|  | **Additional context** | ||||||
|  | Add any other context or screenshots about the feature request here. | ||||||
							
								
								
									
										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" | ||||||
							
								
								
									
										34
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -18,31 +18,29 @@ 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: hashicorp/ghaction-import-gpg@v2.1.0 |         uses: crazy-max/ghaction-import-gpg@v5.3.0 | ||||||
|         env: |         with: | ||||||
|           # These secrets will need to be configured for the repository: |           gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} | ||||||
|           GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} |           passphrase: ${{ secrets.PASSPHRASE }} | ||||||
|           PASSPHRASE: ${{ secrets.PASSPHRASE }} |       - name: setup-syft | ||||||
|       - |         run: | | ||||||
|         name: Run GoReleaser |           curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | \ | ||||||
|         uses: goreleaser/goreleaser-action@v3.0.0 |           sh -s -- -b /usr/local/bin v0.64.0 | ||||||
|  |       - name: Run GoReleaser | ||||||
|  |         uses: goreleaser/goreleaser-action@v4.3.0 | ||||||
|         with: |         with: | ||||||
|           version: latest |           version: latest | ||||||
|           args: release --rm-dist |           args: release --clean | ||||||
|         env: |         env: | ||||||
|           GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} |           GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} | ||||||
|           # GitHub sets this automatically |           # GitHub sets this automatically | ||||||
|   | |||||||
| @@ -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: | ||||||
|   | |||||||
							
								
								
									
										128
									
								
								CODE_OF_CONDUCT.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								CODE_OF_CONDUCT.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | |||||||
|  | # Contributor Covenant Code of Conduct | ||||||
|  |  | ||||||
|  | ## Our Pledge | ||||||
|  |  | ||||||
|  | We as members, contributors, and leaders pledge to make participation in our | ||||||
|  | community a harassment-free experience for everyone, regardless of age, body | ||||||
|  | size, visible or invisible disability, ethnicity, sex characteristics, gender | ||||||
|  | identity and expression, level of experience, education, socio-economic status, | ||||||
|  | nationality, personal appearance, race, religion, or sexual identity | ||||||
|  | and orientation. | ||||||
|  |  | ||||||
|  | We pledge to act and interact in ways that contribute to an open, welcoming, | ||||||
|  | diverse, inclusive, and healthy community. | ||||||
|  |  | ||||||
|  | ## Our Standards | ||||||
|  |  | ||||||
|  | Examples of behavior that contributes to a positive environment for our | ||||||
|  | community include: | ||||||
|  |  | ||||||
|  | * Demonstrating empathy and kindness toward other people | ||||||
|  | * Being respectful of differing opinions, viewpoints, and experiences | ||||||
|  | * Giving and gracefully accepting constructive feedback | ||||||
|  | * Accepting responsibility and apologizing to those affected by our mistakes, | ||||||
|  |   and learning from the experience | ||||||
|  | * Focusing on what is best not just for us as individuals, but for the | ||||||
|  |   overall community | ||||||
|  |  | ||||||
|  | Examples of unacceptable behavior include: | ||||||
|  |  | ||||||
|  | * The use of sexualized language or imagery, and sexual attention or | ||||||
|  |   advances of any kind | ||||||
|  | * Trolling, insulting or derogatory comments, and personal or political attacks | ||||||
|  | * Public or private harassment | ||||||
|  | * Publishing others' private information, such as a physical or email | ||||||
|  |   address, without their explicit permission | ||||||
|  | * Other conduct which could reasonably be considered inappropriate in a | ||||||
|  |   professional setting | ||||||
|  |  | ||||||
|  | ## Enforcement Responsibilities | ||||||
|  |  | ||||||
|  | Community leaders are responsible for clarifying and enforcing our standards of | ||||||
|  | acceptable behavior and will take appropriate and fair corrective action in | ||||||
|  | response to any behavior that they deem inappropriate, threatening, offensive, | ||||||
|  | or harmful. | ||||||
|  |  | ||||||
|  | Community leaders have the right and responsibility to remove, edit, or reject | ||||||
|  | comments, commits, code, wiki edits, issues, and other contributions that are | ||||||
|  | not aligned to this Code of Conduct, and will communicate reasons for moderation | ||||||
|  | decisions when appropriate. | ||||||
|  |  | ||||||
|  | ## Scope | ||||||
|  |  | ||||||
|  | This Code of Conduct applies within all community spaces, and also applies when | ||||||
|  | an individual is officially representing the community in public spaces. | ||||||
|  | Examples of representing our community include using an official e-mail address, | ||||||
|  | posting via an official social media account, or acting as an appointed | ||||||
|  | representative at an online or offline event. | ||||||
|  |  | ||||||
|  | ## Enforcement | ||||||
|  |  | ||||||
|  | Instances of abusive, harassing, or otherwise unacceptable behavior may be | ||||||
|  | reported to the community leaders responsible for enforcement at | ||||||
|  | `lerentis at uploadfilter24 dot eu`. | ||||||
|  | All complaints will be reviewed and investigated promptly and fairly. | ||||||
|  |  | ||||||
|  | All community leaders are obligated to respect the privacy and security of the | ||||||
|  | reporter of any incident. | ||||||
|  |  | ||||||
|  | ## Enforcement Guidelines | ||||||
|  |  | ||||||
|  | Community leaders will follow these Community Impact Guidelines in determining | ||||||
|  | the consequences for any action they deem in violation of this Code of Conduct: | ||||||
|  |  | ||||||
|  | ### 1. Correction | ||||||
|  |  | ||||||
|  | **Community Impact**: Use of inappropriate language or other behavior deemed | ||||||
|  | unprofessional or unwelcome in the community. | ||||||
|  |  | ||||||
|  | **Consequence**: A private, written warning from community leaders, providing | ||||||
|  | clarity around the nature of the violation and an explanation of why the | ||||||
|  | behavior was inappropriate. A public apology may be requested. | ||||||
|  |  | ||||||
|  | ### 2. Warning | ||||||
|  |  | ||||||
|  | **Community Impact**: A violation through a single incident or series | ||||||
|  | of actions. | ||||||
|  |  | ||||||
|  | **Consequence**: A warning with consequences for continued behavior. No | ||||||
|  | interaction with the people involved, including unsolicited interaction with | ||||||
|  | those enforcing the Code of Conduct, for a specified period of time. This | ||||||
|  | includes avoiding interactions in community spaces as well as external channels | ||||||
|  | like social media. Violating these terms may lead to a temporary or | ||||||
|  | permanent ban. | ||||||
|  |  | ||||||
|  | ### 3. Temporary Ban | ||||||
|  |  | ||||||
|  | **Community Impact**: A serious violation of community standards, including | ||||||
|  | sustained inappropriate behavior. | ||||||
|  |  | ||||||
|  | **Consequence**: A temporary ban from any sort of interaction or public | ||||||
|  | communication with the community for a specified period of time. No public or | ||||||
|  | private interaction with the people involved, including unsolicited interaction | ||||||
|  | with those enforcing the Code of Conduct, is allowed during this period. | ||||||
|  | Violating these terms may lead to a permanent ban. | ||||||
|  |  | ||||||
|  | ### 4. Permanent Ban | ||||||
|  |  | ||||||
|  | **Community Impact**: Demonstrating a pattern of violation of community | ||||||
|  | standards, including sustained inappropriate behavior,  harassment of an | ||||||
|  | individual, or aggression toward or disparagement of classes of individuals. | ||||||
|  |  | ||||||
|  | **Consequence**: A permanent ban from any sort of public interaction within | ||||||
|  | the community. | ||||||
|  |  | ||||||
|  | ## Attribution | ||||||
|  |  | ||||||
|  | This Code of Conduct is adapted from the [Contributor Covenant][homepage], | ||||||
|  | version 2.0, available at | ||||||
|  | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. | ||||||
|  |  | ||||||
|  | Community Impact Guidelines were inspired by [Mozilla's code of conduct | ||||||
|  | enforcement ladder](https://github.com/mozilla/diversity). | ||||||
|  |  | ||||||
|  | [homepage]: https://www.contributor-covenant.org | ||||||
|  |  | ||||||
|  | For answers to common questions about this code of conduct, see the FAQ at | ||||||
|  | https://www.contributor-covenant.org/faq. Translations are available at | ||||||
|  | https://www.contributor-covenant.org/translations. | ||||||
							
								
								
									
										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.7.0 | VERSION = 0.15.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.7.0" |       version = "0.15.0" | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ terraform { | |||||||
|   required_providers { |   required_providers { | ||||||
|     gitea = { |     gitea = { | ||||||
|       source = "Lerentis/gitea" |       source = "Lerentis/gitea" | ||||||
|       version = "0.3.0" |       version = "0.15.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. | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										55
									
								
								docs/resources/git_hook.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								docs/resources/git_hook.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | |||||||
|  | --- | ||||||
|  | # generated by https://github.com/hashicorp/terraform-plugin-docs | ||||||
|  | page_title: "gitea_git_hook Resource - terraform-provider-gitea" | ||||||
|  | subcategory: "" | ||||||
|  | description: |- | ||||||
|  |   gitea_git_hook manages git hooks on a repository. | ||||||
|  |   import is currently not supported | ||||||
|  |   WARNING: using this resource requires to enable server side hookswhich are known to cause security issues https://github.com/go-gitea/gitea/pull/13058! | ||||||
|  |   if you want to procede, you need to enable server side hooks as stated here https://docs.gitea.io/en-us/config-cheat-sheet/#security-security | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | # gitea_git_hook (Resource) | ||||||
|  |  | ||||||
|  | `gitea_git_hook` manages git hooks on a repository. | ||||||
|  | import is currently not supported | ||||||
|  |  | ||||||
|  | WARNING: using this resource requires to enable server side hookswhich are known to cause [security issues](https://github.com/go-gitea/gitea/pull/13058)! | ||||||
|  |  | ||||||
|  | if you want to procede, you need to enable server side hooks as stated [here](https://docs.gitea.io/en-us/config-cheat-sheet/#security-security) | ||||||
|  |  | ||||||
|  | ## Example Usage | ||||||
|  |  | ||||||
|  | ```terraform | ||||||
|  | resource "gitea_org" "test_org" { | ||||||
|  |   name = "test-org" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_repository" "org_repo" { | ||||||
|  |   username = gitea_org.test_org.name | ||||||
|  |   name     = "org-test-repo" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_git_hook" "org_repo_post_receive" { | ||||||
|  |   name    = "post-receive" | ||||||
|  |   user    = gitea_org.test_org.name | ||||||
|  |   repo    = gitea_repository.org_repo.name | ||||||
|  |   content = file("${path.module}/post-receive.sh") | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | <!-- schema generated by tfplugindocs --> | ||||||
|  | ## Schema | ||||||
|  |  | ||||||
|  | ### Required | ||||||
|  |  | ||||||
|  | - `content` (String) Content of the git hook | ||||||
|  | - `name` (String) Name of the git hook to configure | ||||||
|  | - `repo` (String) The repository that this hook belongs too. | ||||||
|  | - `user` (String) The user (or organisation) owning the repo this hook belongs too | ||||||
|  |  | ||||||
|  | ### Read-Only | ||||||
|  |  | ||||||
|  | - `id` (String) The ID of this resource. | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -20,6 +20,10 @@ Handling [gitea oauth application](https://docs.gitea.io/en-us/oauth2-provider/) | |||||||
| - `name` (String) OAuth Application name | - `name` (String) OAuth Application name | ||||||
| - `redirect_uris` (Set of String) Accepted redirect URIs | - `redirect_uris` (Set of String) Accepted redirect URIs | ||||||
|  |  | ||||||
|  | ### Optional | ||||||
|  |  | ||||||
|  | - `confidential_client` (Boolean) If set to false, it will be a public client (PKCE will be required) | ||||||
|  |  | ||||||
| ### Read-Only | ### Read-Only | ||||||
|  |  | ||||||
| - `client_id` (String) OAuth2 Application client id | - `client_id` (String) OAuth2 Application client id | ||||||
|   | |||||||
| @@ -46,5 +46,6 @@ resource "gitea_repository" "org_repo" { | |||||||
|  |  | ||||||
| - `avatar_url` (String) | - `avatar_url` (String) | ||||||
| - `id` (String) The ID of this resource. | - `id` (String) The ID of this resource. | ||||||
|  | - `repos` (List of String) List of all Repositories that are part of this organisation | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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 | ||||||
|  |  | ||||||
| @@ -39,6 +41,16 @@ resource "gitea_repository" "mirror" { | |||||||
|   migration_service            = "gitea" |   migration_service            = "gitea" | ||||||
|   migration_service_auth_token = var.gitea_mirror_token |   migration_service_auth_token = var.gitea_mirror_token | ||||||
| } | } | ||||||
|  |  | ||||||
|  | resource "gitea_repository" "clone" { | ||||||
|  |   username                     = "lerentis" | ||||||
|  |   name                         = "terraform-provider-gitea-clone" | ||||||
|  |   description                  = "Clone of Terraform Provider" | ||||||
|  |   mirror                       = false | ||||||
|  |   migration_clone_address      = "https://git.uploadfilter24.eu/lerentis/terraform-provider-gitea.git" | ||||||
|  |   migration_service            = "gitea" | ||||||
|  |   migration_service_auth_token = var.gitea_clone_token | ||||||
|  | } | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| <!-- schema generated by tfplugindocs --> | <!-- schema generated by tfplugindocs --> | ||||||
| @@ -72,7 +84,8 @@ Need to exist in the gitea instance | |||||||
| Need to exist in the gitea instance | Need to exist in the gitea instance | ||||||
| - `license` (String) The license under which the source code of this repository should be. | - `license` (String) The license under which the source code of this repository should be. | ||||||
| Need to exist in the gitea instance | Need to exist in the gitea instance | ||||||
| - `migration_clone_addresse` (String) | - `migration_clone_address` (String) | ||||||
|  | - `migration_clone_addresse` (String) DEPRECATED in favor of `migration_clone_address` | ||||||
| - `migration_issue_labels` (Boolean) | - `migration_issue_labels` (Boolean) | ||||||
| - `migration_lfs` (Boolean) | - `migration_lfs` (Boolean) | ||||||
| - `migration_lfs_endpoint` (String) | - `migration_lfs_endpoint` (String) | ||||||
| @@ -91,11 +104,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 | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -12,13 +12,14 @@ resource "gitea_repository" "mirror" { | |||||||
|   name                         = "terraform-provider-gitea-mirror" |   name                         = "terraform-provider-gitea-mirror" | ||||||
|   description                  = "Mirror of Terraform Provider" |   description                  = "Mirror of Terraform Provider" | ||||||
|   mirror                       = true |   mirror                       = true | ||||||
|   migration_clone_addresse     = "https://git.uploadfilter24.eu/lerentis/terraform-provider-gitea.git" |   migration_clone_address      = "https://git.uploadfilter24.eu/lerentis/terraform-provider-gitea.git" | ||||||
|   migration_service            = "gitea" |   migration_service            = "gitea" | ||||||
|   migration_service_auth_token = var.gitea_mirror_token |   migration_service_auth_token = var.gitea_mirror_token | ||||||
| } | } | ||||||
|  |  | ||||||
| resource "gitea_org" "test_org" { | resource "gitea_org" "test_org" { | ||||||
|   name        = "test-org" |   name        = "test-org" | ||||||
|  |   description = "test description" | ||||||
| } | } | ||||||
|  |  | ||||||
| resource "gitea_repository" "org_repo" { | resource "gitea_repository" "org_repo" { | ||||||
| @@ -55,3 +56,82 @@ resource "gitea_team" "test_team" { | |||||||
|   permission   = "write" |   permission   = "write" | ||||||
|   members      = [gitea_user.test.username] |   members      = [gitea_user.test.username] | ||||||
| } | } | ||||||
|  |  | ||||||
|  | resource "gitea_team" "admin_team" { | ||||||
|  |   name         = "Admins" | ||||||
|  |   organisation = gitea_org.test_org.name | ||||||
|  |   description  = "Admins of Test Org" | ||||||
|  |   permission   = "admin" | ||||||
|  |   members      = [data.gitea_user.me.username] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_git_hook" "org_repo_pre_receive" { | ||||||
|  |   name    = "pre-receive" | ||||||
|  |   user    = gitea_org.test_org.name | ||||||
|  |   repo    = gitea_repository.org_repo.name | ||||||
|  |   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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | data "gitea_repo" "org_repos" { | ||||||
|  |   name = each.key | ||||||
|  |   username = gitea_org.org1.name | ||||||
|  |   for_each = { | ||||||
|  |     for repo in resource.gitea_org.org1.repos : repo => repo | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | output "repos" { | ||||||
|  |   value = data.gitea_repo.org_repos["repo1-in-org1"].clone_url | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								examples/pre-receive.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								examples/pre-receive.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | while read oldrev newrev refname | ||||||
|  | do | ||||||
|  |     branch=$(git rev-parse --symbolic --abbrev-ref $refname) | ||||||
|  |     if [ "master" = "$branch" ]; then | ||||||
|  |         echo "wrong branch" | ||||||
|  |         exit 1 | ||||||
|  |     fi | ||||||
|  | done | ||||||
| @@ -2,12 +2,14 @@ terraform { | |||||||
|   required_providers { |   required_providers { | ||||||
|     gitea = { |     gitea = { | ||||||
|       source = "terraform.local/lerentis/gitea" |       source = "terraform.local/lerentis/gitea" | ||||||
|       version = "0.7.0" |       version = "0.15.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.3.0" |       version = "0.15.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 | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								examples/resources/gitea_git_hook/post-receive.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								examples/resources/gitea_git_hook/post-receive.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | while read oldrev newrev refname | ||||||
|  | do | ||||||
|  |     branch=$(git rev-parse --symbolic --abbrev-ref $refname) | ||||||
|  |     if [ "master" = "$branch" ]; then | ||||||
|  |         # Do something | ||||||
|  |     fi | ||||||
|  | done | ||||||
							
								
								
									
										15
									
								
								examples/resources/gitea_git_hook/resource.tf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								examples/resources/gitea_git_hook/resource.tf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | resource "gitea_org" "test_org" { | ||||||
|  |   name = "test-org" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_repository" "org_repo" { | ||||||
|  |   username = gitea_org.test_org.name | ||||||
|  |   name     = "org-test-repo" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | resource "gitea_git_hook" "org_repo_post_receive" { | ||||||
|  |   name    = "post-receive" | ||||||
|  |   user    = gitea_org.test_org.name | ||||||
|  |   repo    = gitea_repository.org_repo.name | ||||||
|  |   content = file("${path.module}/post-receive.sh") | ||||||
|  | } | ||||||
| @@ -16,3 +16,13 @@ resource "gitea_repository" "mirror" { | |||||||
|   migration_service            = "gitea" |   migration_service            = "gitea" | ||||||
|   migration_service_auth_token = var.gitea_mirror_token |   migration_service_auth_token = var.gitea_mirror_token | ||||||
| } | } | ||||||
|  |  | ||||||
|  | resource "gitea_repository" "clone" { | ||||||
|  |   username                     = "lerentis" | ||||||
|  |   name                         = "terraform-provider-gitea-clone" | ||||||
|  |   description                  = "Clone of Terraform Provider" | ||||||
|  |   mirror                       = false | ||||||
|  |   migration_clone_address      = "https://git.uploadfilter24.eu/lerentis/terraform-provider-gitea.git" | ||||||
|  |   migration_service            = "gitea" | ||||||
|  |   migration_service_auth_token = var.gitea_clone_token | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										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,9 +6,10 @@ 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/helper/logging" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Config is per-provider, specifies where to connect to gitea | // Config is per-provider, specifies where to connect to gitea | ||||||
| @@ -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 | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"code.gitea.io/sdk/gitea" | 	"code.gitea.io/sdk/gitea" | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func dataSourceGiteaOrg() *schema.Resource { | func dataSourceGiteaOrg() *schema.Resource { | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"code.gitea.io/sdk/gitea" | 	"code.gitea.io/sdk/gitea" | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func dataSourceGiteaRepo() *schema.Resource { | func dataSourceGiteaRepo() *schema.Resource { | ||||||
| @@ -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") | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"code.gitea.io/sdk/gitea" | 	"code.gitea.io/sdk/gitea" | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func dataSourceGiteaUser() *schema.Resource { | func dataSourceGiteaUser() *schema.Resource { | ||||||
|   | |||||||
| @@ -4,8 +4,8 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/helper/resource" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/terraform" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestAccDataSourceGiteaUser_basic(t *testing.T) { | func TestAccDataSourceGiteaUser_basic(t *testing.T) { | ||||||
|   | |||||||
| @@ -4,12 +4,11 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/terraform" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Provider returns a terraform.ResourceProvider. | // Provider returns a terraform.ResourceProvider. | ||||||
| func Provider() terraform.ResourceProvider { | func Provider() *schema.Provider { | ||||||
|  |  | ||||||
| 	// The actual provider | 	// The actual provider | ||||||
| 	return &schema.Provider{ | 	return &schema.Provider{ | ||||||
| @@ -79,8 +78,12 @@ func Provider() terraform.ResourceProvider { | |||||||
| 			"gitea_user":           resourceGiteaUser(), | 			"gitea_user":           resourceGiteaUser(), | ||||||
| 			"gitea_oauth2_app":     resourceGiteaOauthApp(), | 			"gitea_oauth2_app":     resourceGiteaOauthApp(), | ||||||
| 			"gitea_repository":     resourceGiteaRepository(), | 			"gitea_repository":     resourceGiteaRepository(), | ||||||
|  | 			"gitea_fork":           resourceGiteaFork(), | ||||||
| 			"gitea_public_key":     resourceGiteaPublicKey(), | 			"gitea_public_key":     resourceGiteaPublicKey(), | ||||||
| 			"gitea_team":           resourceGiteaTeam(), | 			"gitea_team":           resourceGiteaTeam(), | ||||||
|  | 			"gitea_git_hook":       resourceGiteaGitHook(), | ||||||
|  | 			"gitea_token":          resourceGiteaToken(), | ||||||
|  | 			"gitea_repository_key": resourceGiteaRepositoryKey(), | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		ConfigureFunc: providerConfigure, | 		ConfigureFunc: providerConfigure, | ||||||
|   | |||||||
| @@ -4,30 +4,28 @@ import ( | |||||||
| 	"os" | 	"os" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/terraform" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var testAccProviders map[string]terraform.ResourceProvider | var testAccProviders map[string]*schema.Provider | ||||||
| var testAccProvider *schema.Provider | var testAccProvider *schema.Provider | ||||||
|  |  | ||||||
| func init() { | func init() { | ||||||
| 	testAccProvider = Provider().(*schema.Provider) | 	testAccProvider = Provider() | ||||||
| 	testAccProviders = map[string]terraform.ResourceProvider{ | 	testAccProviders = map[string]*schema.Provider{ | ||||||
| 		"gitea": testAccProvider, | 		"gitea": testAccProvider, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestProvider(t *testing.T) { | func TestProvider(t *testing.T) { | ||||||
| 	if err := Provider().(*schema.Provider).InternalValidate(); err != nil { | 	if err := Provider().InternalValidate(); err != nil { | ||||||
| 		t.Fatalf("err: %s", err) | 		t.Fatalf("err: %s", err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestProvider_impl(t *testing.T) { | func TestProvider_impl(t *testing.T) { | ||||||
| 	var _ terraform.ResourceProvider = Provider() | 	var _ *schema.Provider = Provider() | ||||||
| } | } | ||||||
|  |  | ||||||
| func testAccPreCheck(t *testing.T) { | func testAccPreCheck(t *testing.T) { | ||||||
| 	if v := os.Getenv("GITEA_TOKEN"); v == "" { | 	if v := os.Getenv("GITEA_TOKEN"); v == "" { | ||||||
| 		t.Fatal("GITEA_TOKEN must be set for acceptance tests") | 		t.Fatal("GITEA_TOKEN must be set for acceptance tests") | ||||||
|   | |||||||
							
								
								
									
										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", | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										120
									
								
								gitea/resource_gitea_git_hook.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								gitea/resource_gitea_git_hook.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | |||||||
|  | package gitea | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/sdk/gitea" | ||||||
|  | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	GitHookUser    string = "user" | ||||||
|  | 	GitHookRepo    string = "repo" | ||||||
|  | 	GitHookName    string = "name" | ||||||
|  | 	GitHookContent string = "content" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func resourceGitHookRead(d *schema.ResourceData, meta interface{}) (err error) { | ||||||
|  | 	client := meta.(*gitea.Client) | ||||||
|  |  | ||||||
|  | 	user := d.Get(GitHookUser).(string) | ||||||
|  | 	repo := d.Get(GitHookRepo).(string) | ||||||
|  | 	name := d.Get(GitHookName).(string) | ||||||
|  |  | ||||||
|  | 	gitHook, _, err := client.GetRepoGitHook(user, repo, name) | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err = setGitHookResourceData(user, repo, gitHook, d) | ||||||
|  |  | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func resourceGitHookUpdate(d *schema.ResourceData, meta interface{}) (err error) { | ||||||
|  | 	client := meta.(*gitea.Client) | ||||||
|  |  | ||||||
|  | 	user := d.Get(GitHookUser).(string) | ||||||
|  | 	repo := d.Get(GitHookRepo).(string) | ||||||
|  | 	name := d.Get(GitHookName).(string) | ||||||
|  |  | ||||||
|  | 	opts := gitea.EditGitHookOption{ | ||||||
|  | 		Content: d.Get(GitHookContent).(string), | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	_, err = client.EditRepoGitHook(user, repo, name, opts) | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Get gitHook ourselves, EditRepoGitHook does not return it | ||||||
|  | 	gitHook, _, err := client.GetRepoGitHook(user, repo, name) | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err = setGitHookResourceData(user, repo, gitHook, d) | ||||||
|  |  | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func resourceGitHookDelete(d *schema.ResourceData, meta interface{}) (err error) { | ||||||
|  | 	client := meta.(*gitea.Client) | ||||||
|  |  | ||||||
|  | 	user := d.Get(GitHookUser).(string) | ||||||
|  | 	repo := d.Get(GitHookRepo).(string) | ||||||
|  | 	name := d.Get(GitHookName).(string) | ||||||
|  |  | ||||||
|  | 	_, err = client.DeleteRepoGitHook(user, repo, name) | ||||||
|  |  | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func setGitHookResourceData(user string, repo string, gitHook *gitea.GitHook, d *schema.ResourceData) (err error) { | ||||||
|  | 	d.SetId(fmt.Sprintf("%s/%s/%s", user, repo, gitHook.Name)) | ||||||
|  | 	d.Set(GitHookUser, user) | ||||||
|  | 	d.Set(GitHookRepo, repo) | ||||||
|  | 	d.Set(GitHookName, gitHook.Name) | ||||||
|  | 	d.Set(GitHookContent, gitHook.Content) | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func resourceGiteaGitHook() *schema.Resource { | ||||||
|  | 	return &schema.Resource{ | ||||||
|  | 		Read:   resourceGitHookRead, | ||||||
|  | 		Create: resourceGitHookUpdate, // All hooks already exist, just empty and disabled | ||||||
|  | 		Update: resourceGitHookUpdate, | ||||||
|  | 		Delete: resourceGitHookDelete, | ||||||
|  | 		Schema: map[string]*schema.Schema{ | ||||||
|  | 			"name": { | ||||||
|  | 				Type:        schema.TypeString, | ||||||
|  | 				Required:    true, | ||||||
|  | 				Description: "Name of the git hook to configure", | ||||||
|  | 			}, | ||||||
|  | 			"repo": { | ||||||
|  | 				Type:        schema.TypeString, | ||||||
|  | 				Required:    true, | ||||||
|  | 				Description: "The repository that this hook belongs too.", | ||||||
|  | 			}, | ||||||
|  | 			"user": { | ||||||
|  | 				Type:        schema.TypeString, | ||||||
|  | 				Required:    true, | ||||||
|  | 				Description: "The user (or organisation) owning the repo this hook belongs too", | ||||||
|  | 			}, | ||||||
|  | 			"content": { | ||||||
|  | 				Type:        schema.TypeString, | ||||||
|  | 				Required:    true, | ||||||
|  | 				Description: "Content of the git hook", | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		Description: "`gitea_git_hook` manages git hooks on a repository.\n" + | ||||||
|  | 			"import is currently not supported\n\n" + | ||||||
|  | 			"WARNING: using this resource requires to enable server side hooks" + | ||||||
|  | 			"which are known to cause [security issues](https://github.com/go-gitea/gitea/pull/13058)!\n\n" + | ||||||
|  | 			"if you want to procede, you need to enable server side hooks as stated" + | ||||||
|  | 			" [here](https://docs.gitea.io/en-us/config-cheat-sheet/#security-security)", | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -4,11 +4,12 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"code.gitea.io/sdk/gitea" | 	"code.gitea.io/sdk/gitea" | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| 	oauth2KeyName               string = "name" | 	oauth2KeyName               string = "name" | ||||||
|  | 	oauth2KeyConfidentialClient string = "confidential_client" | ||||||
| 	oauth2KeyRedirectURIs       string = "redirect_uris" | 	oauth2KeyRedirectURIs       string = "redirect_uris" | ||||||
| 	oauth2KeyClientId           string = "client_id" | 	oauth2KeyClientId           string = "client_id" | ||||||
| 	oauth2KeyClientSecret       string = "client_secret" | 	oauth2KeyClientSecret       string = "client_secret" | ||||||
| @@ -37,6 +38,12 @@ func resourceGiteaOauthApp() *schema.Resource { | |||||||
| 				}, | 				}, | ||||||
| 				Description: "Accepted redirect URIs", | 				Description: "Accepted redirect URIs", | ||||||
| 			}, | 			}, | ||||||
|  | 			oauth2KeyConfidentialClient: { | ||||||
|  | 				Type:        schema.TypeBool, | ||||||
|  | 				Optional:    true, | ||||||
|  | 				Default:     false, | ||||||
|  | 				Description: "If set to false, it will be a public client (PKCE will be required)", | ||||||
|  | 			}, | ||||||
| 			oauth2KeyClientId: { | 			oauth2KeyClientId: { | ||||||
| 				Type:        schema.TypeString, | 				Type:        schema.TypeString, | ||||||
| 				Computed:    true, | 				Computed:    true, | ||||||
| @@ -89,8 +96,15 @@ func resourceOauth2AppUpcreate(d *schema.ResourceData, meta interface{}) (err er | |||||||
| 		return fmt.Errorf("attribute %s must be set and must be a string", oauth2KeyName) | 		return fmt.Errorf("attribute %s must be set and must be a string", oauth2KeyName) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	confidentialClient, confidentialClientOk := d.Get(oauth2KeyConfidentialClient).(bool) | ||||||
|  |  | ||||||
|  | 	if !confidentialClientOk { | ||||||
|  | 		return fmt.Errorf("attribute %s must be set and must be a bool", oauth2KeyConfidentialClient) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	opts := gitea.CreateOauth2Option{ | 	opts := gitea.CreateOauth2Option{ | ||||||
| 		Name:               name, | 		Name:               name, | ||||||
|  | 		ConfidentialClient: confidentialClient, | ||||||
| 		RedirectURIs:       redirectURIs, | 		RedirectURIs:       redirectURIs, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -99,7 +113,7 @@ func resourceOauth2AppUpcreate(d *schema.ResourceData, meta interface{}) (err er | |||||||
| 	if d.IsNewResource() { | 	if d.IsNewResource() { | ||||||
| 		oauth2, _, err = client.CreateOauth2(opts) | 		oauth2, _, err = client.CreateOauth2(opts) | ||||||
| 	} else { | 	} else { | ||||||
| 		oauth2, err := searchOauth2AppByClientId(client, d.Id()) | 		oauth2, err = searchOauth2AppByClientId(client, d.Id()) | ||||||
|  |  | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| @@ -177,6 +191,7 @@ func setOAuth2ResourceData(app *gitea.Oauth2, d *schema.ResourceData) (err error | |||||||
|  |  | ||||||
| 	for k, v := range map[string]interface{}{ | 	for k, v := range map[string]interface{}{ | ||||||
| 		oauth2KeyName:               app.Name, | 		oauth2KeyName:               app.Name, | ||||||
|  | 		oauth2KeyConfidentialClient: app.ConfidentialClient, | ||||||
| 		oauth2KeyRedirectURIs:       schema.NewSet(schema.HashString, CollapseStringList(app.RedirectURIs)), | 		oauth2KeyRedirectURIs:       schema.NewSet(schema.HashString, CollapseStringList(app.RedirectURIs)), | ||||||
| 		oauth2KeyClientId:           app.ClientID, | 		oauth2KeyClientId:           app.ClientID, | ||||||
| 	} { | 	} { | ||||||
|   | |||||||
| @@ -2,9 +2,10 @@ package gitea | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  |  | ||||||
| 	"code.gitea.io/sdk/gitea" | 	"code.gitea.io/sdk/gitea" | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| @@ -15,26 +16,81 @@ const ( | |||||||
| 	orgLocation               string = "location" | 	orgLocation               string = "location" | ||||||
| 	orgVisibility             string = "visibility" | 	orgVisibility             string = "visibility" | ||||||
| 	RepoAdminChangeTeamAccess string = "repo_admin_change_team_access" | 	RepoAdminChangeTeamAccess string = "repo_admin_change_team_access" | ||||||
|  | 	orgRepos                  string = "org_repos" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | // might come in handy if we want to stick to numeric IDs | ||||||
|  | func searchOrgByClientId(c *gitea.Client, id int64) (res *gitea.Organization, err error) { | ||||||
|  |  | ||||||
|  | 	page := 1 | ||||||
|  |  | ||||||
|  | 	for { | ||||||
|  | 		orgs, _, err := c.AdminListOrgs(gitea.AdminListOrgsOptions{ | ||||||
|  | 			ListOptions: gitea.ListOptions{ | ||||||
|  | 				Page:     page, | ||||||
|  | 				PageSize: 50, | ||||||
|  | 			}, | ||||||
|  | 		}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if len(orgs) == 0 { | ||||||
|  | 			return nil, fmt.Errorf("Organisation with ID %d could not be found", id) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		for _, org := range orgs { | ||||||
|  | 			if org.ID == id { | ||||||
|  | 				return org, nil | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		page += 1 | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func getAllOrgRepos(c *gitea.Client, orgName string) (repos []string, err error) { | ||||||
|  | 	page := 1 | ||||||
|  |  | ||||||
|  | 	for { | ||||||
|  | 		repoBuffer, _, err := c.ListOrgRepos(orgName, gitea.ListOrgReposOptions{ | ||||||
|  | 			ListOptions: gitea.ListOptions{ | ||||||
|  | 				Page:     page, | ||||||
|  | 				PageSize: 50, | ||||||
|  | 			}, | ||||||
|  | 		}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if len(repoBuffer) == 0 { | ||||||
|  | 			return repos, nil | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		for _, repo := range repoBuffer { | ||||||
|  | 			repos = append(repos, repo.Name) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		page += 1 | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func resourceOrgRead(d *schema.ResourceData, meta interface{}) (err error) { | func resourceOrgRead(d *schema.ResourceData, meta interface{}) (err error) { | ||||||
| 	client := meta.(*gitea.Client) | 	client := meta.(*gitea.Client) | ||||||
|  |  | ||||||
| 	var org *gitea.Organization | 	var org *gitea.Organization | ||||||
| 	var resp *gitea.Response |  | ||||||
|  |  | ||||||
| 	org, resp, err = client.GetOrg(d.Get(orgName).(string)) | 	id, err := strconv.ParseInt(d.Id(), 10, 64) | ||||||
|  |  | ||||||
|  | 	org, err = searchOrgByClientId(client, id) | ||||||
|  |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if resp.StatusCode == 404 { |  | ||||||
| 		d.SetId("") | 		d.SetId("") | ||||||
| 		return nil | 		return nil | ||||||
| 		} else { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err = setOrgResourceData(org, d) | 	repos, _ := getAllOrgRepos(client, org.UserName) | ||||||
|  | 	err = setOrgResourceData(org, d, &repos) | ||||||
|  |  | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| @@ -57,7 +113,8 @@ func resourceOrgCreate(d *schema.ResourceData, meta interface{}) (err error) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err = setOrgResourceData(org, d) | 	repos, _ := getAllOrgRepos(client, org.UserName) | ||||||
|  | 	err = setOrgResourceData(org, d, &repos) | ||||||
|  |  | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| @@ -90,7 +147,8 @@ func resourceOrgUpdate(d *schema.ResourceData, meta interface{}) (err error) { | |||||||
|  |  | ||||||
| 	org, resp, err = client.GetOrg(d.Get(orgName).(string)) | 	org, resp, err = client.GetOrg(d.Get(orgName).(string)) | ||||||
|  |  | ||||||
| 	err = setOrgResourceData(org, d) | 	repos, _ := getAllOrgRepos(client, org.UserName) | ||||||
|  | 	err = setOrgResourceData(org, d, &repos) | ||||||
|  |  | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| @@ -113,7 +171,7 @@ func resourceOrgDelete(d *schema.ResourceData, meta interface{}) (err error) { | |||||||
| 	return | 	return | ||||||
| } | } | ||||||
|  |  | ||||||
| func setOrgResourceData(org *gitea.Organization, d *schema.ResourceData) (err error) { | func setOrgResourceData(org *gitea.Organization, d *schema.ResourceData, repos *[]string) (err error) { | ||||||
| 	d.SetId(fmt.Sprintf("%d", org.ID)) | 	d.SetId(fmt.Sprintf("%d", org.ID)) | ||||||
| 	d.Set("name", org.UserName) | 	d.Set("name", org.UserName) | ||||||
| 	d.Set("full_name", org.FullName) | 	d.Set("full_name", org.FullName) | ||||||
| @@ -122,6 +180,7 @@ func setOrgResourceData(org *gitea.Organization, d *schema.ResourceData) (err er | |||||||
| 	d.Set("website", org.Website) | 	d.Set("website", org.Website) | ||||||
| 	d.Set("location", org.Location) | 	d.Set("location", org.Location) | ||||||
| 	d.Set("visibility", org.Visibility) | 	d.Set("visibility", org.Visibility) | ||||||
|  | 	d.Set("repos", repos) | ||||||
|  |  | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| @@ -133,7 +192,7 @@ func resourceGiteaOrg() *schema.Resource { | |||||||
| 		Update: resourceOrgUpdate, | 		Update: resourceOrgUpdate, | ||||||
| 		Delete: resourceOrgDelete, | 		Delete: resourceOrgDelete, | ||||||
| 		Importer: &schema.ResourceImporter{ | 		Importer: &schema.ResourceImporter{ | ||||||
| 			State: schema.ImportStatePassthrough, | 			StateContext: schema.ImportStatePassthroughContext, | ||||||
| 		}, | 		}, | ||||||
| 		Schema: map[string]*schema.Schema{ | 		Schema: map[string]*schema.Schema{ | ||||||
| 			"name": { | 			"name": { | ||||||
| @@ -183,6 +242,13 @@ func resourceGiteaOrg() *schema.Resource { | |||||||
| 				Default:     "public", | 				Default:     "public", | ||||||
| 				Description: "Flag is this organisation should be publicly visible or not.", | 				Description: "Flag is this organisation should be publicly visible or not.", | ||||||
| 			}, | 			}, | ||||||
|  | 			"repos": { | ||||||
|  | 				Type:        schema.TypeList, | ||||||
|  | 				Required:    false, | ||||||
|  | 				Computed:    true, | ||||||
|  | 				Description: "List of all Repositories that are part of this organisation", | ||||||
|  | 				Elem:        &schema.Schema{Type: schema.TypeString}, | ||||||
|  | 			}, | ||||||
| 		}, | 		}, | ||||||
| 		Description: "`gitea_org` manages a gitea organisation.\n\n" + | 		Description: "`gitea_org` manages a gitea organisation.\n\n" + | ||||||
| 			"Organisations are a way to group repositories and abstract permission management in a gitea instance.", | 			"Organisations are a way to group repositories and abstract permission management in a gitea instance.", | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ import ( | |||||||
| 	"strconv" | 	"strconv" | ||||||
|  |  | ||||||
| 	"code.gitea.io/sdk/gitea" | 	"code.gitea.io/sdk/gitea" | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
|   | |||||||
| @@ -1,11 +1,15 @@ | |||||||
| 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-sdk/helper/schema" | 	"github.com/hashicorp/terraform-plugin-log/tflog" | ||||||
|  | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| @@ -34,7 +38,8 @@ const ( | |||||||
| 	repoAllowManualMerge         string = "allow_manual_merge" | 	repoAllowManualMerge         string = "allow_manual_merge" | ||||||
| 	repoAutodetectManualMerge    string = "autodetect_manual_merge" | 	repoAutodetectManualMerge    string = "autodetect_manual_merge" | ||||||
| 	repoMirror                   string = "mirror" | 	repoMirror                   string = "mirror" | ||||||
| 	migrationCloneAddress        string = "migration_clone_addresse" | 	migrationCloneAddresse       string = "migration_clone_addresse" | ||||||
|  | 	migrationCloneAddress        string = "migration_clone_address" | ||||||
| 	migrationService             string = "migration_service" | 	migrationService             string = "migration_service" | ||||||
| 	migrationServiceAuthName     string = "migration_service_auth_username" | 	migrationServiceAuthName     string = "migration_service_auth_username" | ||||||
| 	migrationServiceAuthPassword string = "migration_service_auth_password" | 	migrationServiceAuthPassword string = "migration_service_auth_password" | ||||||
| @@ -47,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) | ||||||
|  |  | ||||||
| @@ -78,21 +111,39 @@ 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 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (d.Get(repoMirror)).(bool) { | 	var cloneAddr string | ||||||
|  | 	if d.Get(migrationCloneAddresse).(string) != "" { | ||||||
|  | 		cloneAddr = d.Get(migrationCloneAddresse).(string) | ||||||
|  | 	} else { | ||||||
|  | 		cloneAddr = d.Get(migrationCloneAddress).(string) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if cloneAddr != "" { | ||||||
|  |  | ||||||
| 		opts := gitea.MigrateRepoOption{ | 		opts := gitea.MigrateRepoOption{ | ||||||
| 			RepoName:       d.Get(repoName).(string), | 			RepoName:       d.Get(repoName).(string), | ||||||
| 			RepoOwner:      d.Get(repoOwner).(string), | 			RepoOwner:      d.Get(repoOwner).(string), | ||||||
| 			CloneAddr:      d.Get(migrationCloneAddress).(string), | 			CloneAddr:      cloneAddr, | ||||||
| 			Service:        gitea.GitServiceType(d.Get(migrationService).(string)), | 			Service:        gitea.GitServiceType(d.Get(migrationService).(string)), | ||||||
| 			Mirror:         d.Get(repoMirror).(bool), | 			Mirror:         d.Get(repoMirror).(bool), | ||||||
| 			Private:        d.Get(repoPrivateFlag).(bool), | 			Private:        d.Get(repoPrivateFlag).(bool), | ||||||
| @@ -137,13 +188,17 @@ 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 { | ||||||
|  | 			if hasAdmin { | ||||||
|  | 				repo, _, err = client.AdminCreateRepo(d.Get(repoOwner).(string), opts) | ||||||
| 			} else { | 			} else { | ||||||
| 				repo, _, err = client.CreateRepo(opts) | 				repo, _, err = client.CreateRepo(opts) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err = setRepoResourceData(repo, d) | 	err = setRepoResourceData(repo, d) | ||||||
| @@ -223,6 +278,7 @@ func respurceRepoDelete(d *schema.ResourceData, meta interface{}) (err error) { | |||||||
|  |  | ||||||
| func setRepoResourceData(repo *gitea.Repository, d *schema.ResourceData) (err error) { | func setRepoResourceData(repo *gitea.Repository, d *schema.ResourceData) (err error) { | ||||||
| 	d.SetId(fmt.Sprintf("%d", repo.ID)) | 	d.SetId(fmt.Sprintf("%d", repo.ID)) | ||||||
|  | 	d.Set("username", repo.Owner.UserName) | ||||||
| 	d.Set("name", repo.Name) | 	d.Set("name", repo.Name) | ||||||
| 	d.Set("description", repo.Description) | 	d.Set("description", repo.Description) | ||||||
| 	d.Set("full_name", repo.FullName) | 	d.Set("full_name", repo.FullName) | ||||||
| @@ -239,8 +295,8 @@ func setRepoResourceData(repo *gitea.Repository, d *schema.ResourceData) (err er | |||||||
| 	d.Set("watchers", repo.Watchers) | 	d.Set("watchers", repo.Watchers) | ||||||
| 	d.Set("open_issue_count", repo.OpenIssues) | 	d.Set("open_issue_count", repo.OpenIssues) | ||||||
| 	d.Set("default_branch", repo.DefaultBranch) | 	d.Set("default_branch", repo.DefaultBranch) | ||||||
| 	d.Set("created", repo.Created) | 	d.Set("created", repo.Created.String()) | ||||||
| 	d.Set("updated", repo.Updated) | 	d.Set("updated", repo.Updated.String()) | ||||||
| 	d.Set("permission_admin", repo.Permissions.Admin) | 	d.Set("permission_admin", repo.Permissions.Admin) | ||||||
| 	d.Set("permission_push", repo.Permissions.Push) | 	d.Set("permission_push", repo.Permissions.Push) | ||||||
| 	d.Set("permission_pull", repo.Permissions.Pull) | 	d.Set("permission_pull", repo.Permissions.Pull) | ||||||
| @@ -255,7 +311,7 @@ func resourceGiteaRepository() *schema.Resource { | |||||||
| 		Update: resourceRepoUpdate, | 		Update: resourceRepoUpdate, | ||||||
| 		Delete: respurceRepoDelete, | 		Delete: respurceRepoDelete, | ||||||
| 		Importer: &schema.ResourceImporter{ | 		Importer: &schema.ResourceImporter{ | ||||||
| 			State: schema.ImportStatePassthrough, | 			StateContext: schema.ImportStatePassthroughContext, | ||||||
| 		}, | 		}, | ||||||
| 		Schema: map[string]*schema.Schema{ | 		Schema: map[string]*schema.Schema{ | ||||||
| 			"username": { | 			"username": { | ||||||
| @@ -449,6 +505,13 @@ func resourceGiteaRepository() *schema.Resource { | |||||||
| 				Required:    false, | 				Required:    false, | ||||||
| 				Optional:    true, | 				Optional:    true, | ||||||
| 				ForceNew:    true, | 				ForceNew:    true, | ||||||
|  | 				Description: "DEPRECATED in favor of `migration_clone_address`", | ||||||
|  | 			}, | ||||||
|  | 			"migration_clone_address": { | ||||||
|  | 				Type:     schema.TypeString, | ||||||
|  | 				Required: false, | ||||||
|  | 				Optional: true, | ||||||
|  | 				ForceNew: true, | ||||||
| 			}, | 			}, | ||||||
| 			"migration_service": { | 			"migration_service": { | ||||||
| 				Type:        schema.TypeString, | 				Type:        schema.TypeString, | ||||||
| @@ -513,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,12 +1,13 @@ | |||||||
| package gitea | package gitea | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"code.gitea.io/sdk/gitea" | 	"code.gitea.io/sdk/gitea" | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| @@ -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) { | ||||||
| @@ -39,7 +41,7 @@ func resourceTeamRead(d *schema.ResourceData, meta interface{}) (err error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err = setTeamResourceData(team, d) | 	err = setTeamResourceData(team, d, meta) | ||||||
|  |  | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| @@ -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,7 +105,14 @@ func resourceTeamCreate(d *schema.ResourceData, meta interface{}) (err error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err = setTeamResourceData(team, d) | 	if !includeAllRepos { | ||||||
|  | 		err = setTeamRepositories(team, d, meta, false) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err = setTeamResourceData(team, d, meta) | ||||||
|  |  | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| @@ -181,9 +192,16 @@ 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, meta) | ||||||
|  |  | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| @@ -208,7 +226,13 @@ func resourceTeamDelete(d *schema.ResourceData, meta interface{}) (err error) { | |||||||
| 	return | 	return | ||||||
| } | } | ||||||
|  |  | ||||||
| func setTeamResourceData(team *gitea.Team, d *schema.ResourceData) (err error) { | func setTeamResourceData(team *gitea.Team, d *schema.ResourceData, meta interface{}) (err error) { | ||||||
|  | 	client := meta.(*gitea.Client) | ||||||
|  | 	if err := client.CheckServerVersionConstraint(">= 1.19.4"); err != nil { | ||||||
|  | 		d.Set(TeamOrg, d.Get(TeamOrg).(string)) | ||||||
|  | 	} else { | ||||||
|  | 		d.Set(TeamOrg, team.Organization.UserName) | ||||||
|  | 	} | ||||||
| 	d.SetId(fmt.Sprintf("%d", team.ID)) | 	d.SetId(fmt.Sprintf("%d", team.ID)) | ||||||
| 	d.Set(TeamCreateRepoFlag, team.CanCreateOrgRepo) | 	d.Set(TeamCreateRepoFlag, team.CanCreateOrgRepo) | ||||||
| 	d.Set(TeamDescription, team.Description) | 	d.Set(TeamDescription, team.Description) | ||||||
| @@ -216,8 +240,8 @@ func setTeamResourceData(team *gitea.Team, d *schema.ResourceData) (err error) { | |||||||
| 	d.Set(TeamPermissions, string(team.Permission)) | 	d.Set(TeamPermissions, string(team.Permission)) | ||||||
| 	d.Set(TeamIncludeAllReposFlag, team.IncludesAllRepositories) | 	d.Set(TeamIncludeAllReposFlag, team.IncludesAllRepositories) | ||||||
| 	d.Set(TeamUnits, d.Get(TeamUnits).(string)) | 	d.Set(TeamUnits, d.Get(TeamUnits).(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 | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -228,7 +252,7 @@ func resourceGiteaTeam() *schema.Resource { | |||||||
| 		Update: resourceTeamUpdate, | 		Update: resourceTeamUpdate, | ||||||
| 		Delete: resourceTeamDelete, | 		Delete: resourceTeamDelete, | ||||||
| 		Importer: &schema.ResourceImporter{ | 		Importer: &schema.ResourceImporter{ | ||||||
| 			State: schema.ImportStatePassthrough, | 			StateContext: schema.ImportStatePassthroughContext, | ||||||
| 		}, | 		}, | ||||||
| 		Schema: map[string]*schema.Schema{ | 		Schema: map[string]*schema.Schema{ | ||||||
| 			"name": { | 			"name": { | ||||||
| @@ -290,7 +314,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!", | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -5,7 +5,7 @@ import ( | |||||||
| 	"strconv" | 	"strconv" | ||||||
|  |  | ||||||
| 	"code.gitea.io/sdk/gitea" | 	"code.gitea.io/sdk/gitea" | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
|   | |||||||
							
								
								
									
										106
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								go.mod
									
									
									
									
									
								
							| @@ -4,80 +4,70 @@ 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.16.0 | ||||||
| 	github.com/hashicorp/terraform-plugin-sdk v1.13.0 | 	github.com/hashicorp/terraform-plugin-log v0.9.0 | ||||||
|  | 	github.com/hashicorp/terraform-plugin-sdk/v2 v2.27.0 | ||||||
| ) | ) | ||||||
|  |  | ||||||
| require ( | require ( | ||||||
| 	cloud.google.com/go v0.45.1 // indirect | 	github.com/Masterminds/goutils v1.1.1 // indirect | ||||||
| 	github.com/Masterminds/goutils v1.1.0 // indirect | 	github.com/Masterminds/semver/v3 v3.1.1 // indirect | ||||||
| 	github.com/Masterminds/semver v1.5.0 // indirect | 	github.com/Masterminds/sprig/v3 v3.2.2 // indirect | ||||||
| 	github.com/Masterminds/sprig v2.22.0+incompatible // indirect | 	github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect | ||||||
| 	github.com/agext/levenshtein v1.2.2 // indirect | 	github.com/agext/levenshtein v1.2.2 // indirect | ||||||
| 	github.com/apparentlymart/go-cidr v1.0.1 // indirect |  | ||||||
| 	github.com/apparentlymart/go-textseg v1.0.0 // 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 v1.0.0 // indirect | 	github.com/armon/go-radix v1.0.0 // indirect | ||||||
| 	github.com/aws/aws-sdk-go v1.25.3 // indirect |  | ||||||
| 	github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // 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/cloudflare/circl v1.3.3 // indirect | ||||||
| 	github.com/fatih/color v1.7.0 // indirect | 	github.com/fatih/color v1.13.0 // indirect | ||||||
| 	github.com/golang/protobuf v1.3.4 // indirect | 	github.com/golang/protobuf v1.5.3 // indirect | ||||||
| 	github.com/google/go-cmp v0.5.7 // 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/googleapis/gax-go/v2 v2.0.5 // indirect | 	github.com/hashicorp/errwrap v1.1.0 // indirect | ||||||
| 	github.com/hashicorp/errwrap v1.0.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-getter v1.4.0 // indirect | 	github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect | ||||||
| 	github.com/hashicorp/go-hclog v0.9.2 // indirect | 	github.com/hashicorp/go-hclog v1.5.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.0.1 // indirect | 	github.com/hashicorp/go-plugin v1.4.10 // indirect | ||||||
| 	github.com/hashicorp/go-safetemp v1.0.0 // indirect | 	github.com/hashicorp/go-uuid v1.0.3 // indirect | ||||||
| 	github.com/hashicorp/go-uuid v1.0.1 // indirect | 	github.com/hashicorp/go-version v1.6.0 // indirect | ||||||
| 	github.com/hashicorp/go-version v1.4.0 // indirect | 	github.com/hashicorp/hc-install v0.5.2 // indirect | ||||||
| 	github.com/hashicorp/golang-lru v0.5.1 // indirect | 	github.com/hashicorp/hcl/v2 v2.17.0 // indirect | ||||||
| 	github.com/hashicorp/hc-install v0.3.1 // indirect |  | ||||||
| 	github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f // indirect |  | ||||||
| 	github.com/hashicorp/hcl/v2 v2.0.0 // indirect |  | ||||||
| 	github.com/hashicorp/logutils v1.0.0 // indirect | 	github.com/hashicorp/logutils v1.0.0 // indirect | ||||||
| 	github.com/hashicorp/terraform-config-inspect v0.0.0-20191115094559-17f92b0546e8 // indirect | 	github.com/hashicorp/terraform-exec v0.18.1 // indirect | ||||||
| 	github.com/hashicorp/terraform-exec v0.16.0 // indirect | 	github.com/hashicorp/terraform-json v0.17.1 // indirect | ||||||
| 	github.com/hashicorp/terraform-json v0.13.0 // indirect | 	github.com/hashicorp/terraform-plugin-go v0.16.0 // indirect | ||||||
| 	github.com/hashicorp/terraform-plugin-test v1.3.0 // indirect | 	github.com/hashicorp/terraform-registry-address v0.2.1 // indirect | ||||||
| 	github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596 // indirect | 	github.com/hashicorp/terraform-svchost v0.1.1 // 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/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect | 	github.com/mattn/go-colorable v0.1.13 // indirect | ||||||
| 	github.com/mattn/go-colorable v0.1.12 // indirect | 	github.com/mattn/go-isatty v0.0.16 // indirect | ||||||
| 	github.com/mattn/go-isatty v0.0.14 // indirect | 	github.com/mitchellh/cli v1.1.5 // indirect | ||||||
| 	github.com/mitchellh/cli v1.1.2 // indirect |  | ||||||
| 	github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect |  | ||||||
| 	github.com/mitchellh/copystructure v1.2.0 // indirect | 	github.com/mitchellh/copystructure v1.2.0 // indirect | ||||||
| 	github.com/mitchellh/go-homedir v1.1.0 // indirect | 	github.com/mitchellh/go-testing-interface v1.14.1 // indirect | ||||||
| 	github.com/mitchellh/go-testing-interface v1.0.0 // indirect |  | ||||||
| 	github.com/mitchellh/go-wordwrap v1.0.0 // indirect | 	github.com/mitchellh/go-wordwrap v1.0.0 // indirect | ||||||
| 	github.com/mitchellh/mapstructure v1.1.2 // 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.2.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/spf13/afero v1.2.2 // indirect | 	github.com/shopspring/decimal v1.3.1 // indirect | ||||||
| 	github.com/ulikunitz/xz v0.5.5 // indirect | 	github.com/spf13/cast v1.5.0 // indirect | ||||||
| 	github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect | 	github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect | ||||||
| 	github.com/vmihailenco/tagparser v0.1.1 // indirect | 	github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect | ||||||
| 	github.com/zclconf/go-cty v1.10.0 // indirect | 	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect | ||||||
| 	github.com/zclconf/go-cty-yaml v1.0.1 // indirect | 	github.com/zclconf/go-cty v1.13.2 // indirect | ||||||
| 	go.opencensus.io v0.22.0 // indirect | 	golang.org/x/crypto v0.10.0 // indirect | ||||||
| 	golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect | 	golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect | ||||||
| 	golang.org/x/net v0.0.0-20210326060303-6b1517762897 // indirect | 	golang.org/x/mod v0.11.0 // indirect | ||||||
| 	golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect | 	golang.org/x/net v0.11.0 // indirect | ||||||
| 	golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect | 	golang.org/x/sys v0.9.0 // indirect | ||||||
| 	golang.org/x/text v0.3.5 // indirect | 	golang.org/x/text v0.11.0 // indirect | ||||||
| 	google.golang.org/api v0.9.0 // indirect | 	google.golang.org/appengine v1.6.7 // indirect | ||||||
| 	google.golang.org/appengine v1.6.5 // indirect | 	google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect | ||||||
| 	google.golang.org/genproto v0.0.0-20200310143817-43be25429f5a // indirect | 	google.golang.org/grpc v1.56.0 // indirect | ||||||
| 	google.golang.org/grpc v1.27.1 // indirect | 	google.golang.org/protobuf v1.30.0 // indirect | ||||||
| ) | ) | ||||||
|   | |||||||
							
								
								
									
										457
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										457
									
								
								go.sum
									
									
									
									
									
								
							| @@ -1,429 +1,244 @@ | |||||||
| cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= |  | ||||||
| cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= |  | ||||||
| cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= |  | ||||||
| cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= |  | ||||||
| cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= |  | ||||||
| cloud.google.com/go v0.45.1 h1:lRi0CHyU+ytlvylOlFKKq0af6JncuyoRh1J+QJBqQx0= |  | ||||||
| cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= |  | ||||||
| cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= |  | ||||||
| cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= |  | ||||||
| code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= | code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= | ||||||
| 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/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= | ||||||
| github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= | github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= | ||||||
| github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= | github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= | ||||||
| github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= | github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= | ||||||
| github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= | github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= | ||||||
| github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= | github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= | ||||||
| github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= | github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= | ||||||
| github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= | github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= | ||||||
| github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= | github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= | ||||||
| github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= | github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= | ||||||
| github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= | github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= | ||||||
| github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= |  | ||||||
| github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= |  | ||||||
| github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= |  | ||||||
| github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= |  | ||||||
| github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= |  | ||||||
| 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/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= | github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= | ||||||
| github.com/andybalholm/crlf v0.0.0-20171020200849-670099aa064f/go.mod h1:k8feO4+kXDxro6ErPXBRTJ/ro2mf0SsFG8s7doP9kJE= |  | ||||||
| github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= |  | ||||||
| github.com/apparentlymart/go-cidr v1.0.1 h1:NmIwLZ/KdsjIUlhf+/Np40atNXm/+lZ5txfTJ/SpF+U= |  | ||||||
| github.com/apparentlymart/go-cidr v1.0.1/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= |  | ||||||
| github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= |  | ||||||
| github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I= |  | ||||||
| github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= |  | ||||||
| github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= |  | ||||||
| github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= |  | ||||||
| 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/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 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= | ||||||
| github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= | 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/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= |  | ||||||
| github.com/aws/aws-sdk-go v1.25.3 h1:uM16hIw9BotjZKMZlX05SN2EFtaWfi/NonPKIARiBLQ= |  | ||||||
| github.com/aws/aws-sdk-go v1.25.3/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= |  | ||||||
| github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= |  | ||||||
| github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= |  | ||||||
| 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/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= | ||||||
| github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= | github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= | ||||||
| github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= | github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= | ||||||
| github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= | github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= | ||||||
| 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.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= | ||||||
| github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= |  | ||||||
| github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= |  | ||||||
| github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= |  | ||||||
| github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= |  | ||||||
| github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= | ||||||
| github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= | github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= | ||||||
| github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= | github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= | ||||||
|  | github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= | ||||||
| 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/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= | ||||||
| github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= | github.com/go-git/go-git/v5 v5.6.1 h1:q4ZRqQl4pR/ZJHc1L5CFjGA1a10u76aV1iC+nh+bHsk= | ||||||
| github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= |  | ||||||
| github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= |  | ||||||
| github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= |  | ||||||
| github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= |  | ||||||
| github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= |  | ||||||
| github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= | github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= | ||||||
| github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= |  | ||||||
| github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= |  | ||||||
| github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= |  | ||||||
| github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= |  | ||||||
| github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= |  | ||||||
| github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= |  | ||||||
| github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= |  | ||||||
| github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | github.com/golang/protobuf v1.1.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.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= | ||||||
| github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= | ||||||
| github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk= | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= | ||||||
| github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= |  | ||||||
| github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= |  | ||||||
| github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= |  | ||||||
| github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= |  | ||||||
| github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= |  | ||||||
| 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.5.6/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.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= | ||||||
| github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | ||||||
| github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= |  | ||||||
| github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= |  | ||||||
| github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= |  | ||||||
| github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= |  | ||||||
| github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | 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/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= | ||||||
| github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||||||
| github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= |  | ||||||
| github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= |  | ||||||
| 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= | ||||||
| github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= |  | ||||||
| github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= | github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= | ||||||
| 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-getter v1.4.0 h1:ENHNi8494porjD0ZhIrjlAHnveSFhY7hvOJrV/fsKkw= | github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= | ||||||
| github.com/hashicorp/go-getter v1.4.0/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY= | github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= | ||||||
| github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= | github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= | ||||||
| github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= | github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= | ||||||
| github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= |  | ||||||
| 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.0.1 h1:4OtAfUGbnKC6yS48p0CtMX2oFYtzFZVv6rok3cRWgnE= | github.com/hashicorp/go-plugin v1.4.10 h1:xUbmA4jC6Dq163/fWcp8P3JuHilrHHMLNRxzGQJ9hNk= | ||||||
| github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= | github.com/hashicorp/go-plugin v1.4.10/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= | ||||||
| github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= |  | ||||||
| github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= |  | ||||||
| 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.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= | github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= | ||||||
| github.com/hashicorp/go-uuid v1.0.1/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.1.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.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= | ||||||
| github.com/hashicorp/go-version v1.4.0 h1:aAQzgqIrRKRa7w75CKpbBxYsmUoPjzVm1W59ca1L0J4= | github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | ||||||
| github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | github.com/hashicorp/hc-install v0.5.2 h1:SfwMFnEXVVirpwkDuSF5kymUOhrUxrTq3udEseZdOD0= | ||||||
| github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | github.com/hashicorp/hc-install v0.5.2/go.mod h1:9QISwe6newMWIfEiXpzuu1k9HAGtQYgnSH8H9T8wmoI= | ||||||
| github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= | github.com/hashicorp/hcl/v2 v2.17.0 h1:z1XvSUyXd1HP10U4lrLg5e0JMVz6CPaJvAgxM0KNZVY= | ||||||
| github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | github.com/hashicorp/hcl/v2 v2.17.0/go.mod h1:gJyW2PTShkJqQBKpAmPO3yxMxIuoXkOF2TpqXzrQyx4= | ||||||
| github.com/hashicorp/hc-install v0.3.1 h1:VIjllE6KyAI1A244G8kTaHXy+TL5/XYzvrtFi8po/Yk= |  | ||||||
| github.com/hashicorp/hc-install v0.3.1/go.mod h1:3LCdWcCDS1gaHC9mhHCGbkYfoY6vdsKohGjugbZdZak= |  | ||||||
| github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+DbLISwf2B8WXEolNRA8BGCwI9jws= |  | ||||||
| github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= |  | ||||||
| github.com/hashicorp/hcl/v2 v2.0.0 h1:efQznTz+ydmQXq3BOnRa3AXzvCeTq1P4dKj/z5GLlY8= |  | ||||||
| github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90= |  | ||||||
| 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-config-inspect v0.0.0-20191115094559-17f92b0546e8 h1:+RyjwU+Gnd/aTJBPZVDNm903eXVjjqhbaR4Ypx3xYyY= | github.com/hashicorp/terraform-exec v0.18.1 h1:LAbfDvNQU1l0NOQlTuudjczVhHj061fNX5H8XZxHlH4= | ||||||
| github.com/hashicorp/terraform-config-inspect v0.0.0-20191115094559-17f92b0546e8/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A= | github.com/hashicorp/terraform-exec v0.18.1/go.mod h1:58wg4IeuAJ6LVsLUeD2DWZZoc/bYi6dzhLHzxM41980= | ||||||
| github.com/hashicorp/terraform-exec v0.16.0 h1:XUh9pJPcbfZsuhReVvmRarQTaiiCnYogFCCjOvEYuug= | github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQHgyRwf3RkyA= | ||||||
| github.com/hashicorp/terraform-exec v0.16.0/go.mod h1:wB5JHmjxZ/YVNZuv9npAXKmz5pGyxy8PSi0GRR0+YjA= | github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o= | ||||||
| github.com/hashicorp/terraform-json v0.4.0/go.mod h1:eAbqb4w0pSlRmdvl8fOyHAi/+8jnkVYN28gJkSJrLhU= | github.com/hashicorp/terraform-plugin-docs v0.16.0 h1:UmxFr3AScl6Wged84jndJIfFccGyBZn52KtMNsS12dI= | ||||||
| github.com/hashicorp/terraform-json v0.13.0 h1:Li9L+lKD1FO5RVFRM1mMMIBDoUHslOniyEi5CM+FWGY= | github.com/hashicorp/terraform-plugin-docs v0.16.0/go.mod h1:M3ZrlKBJAbPMtNOPwHicGi1c+hZUh7/g0ifT/z7TVfA= | ||||||
| github.com/hashicorp/terraform-json v0.13.0/go.mod h1:y5OdLBCT+rxbwnpxZs9kGL7R9ExU76+cpdY8zHwoazk= | github.com/hashicorp/terraform-plugin-go v0.16.0 h1:DSOQ0rz5FUiVO4NUzMs8ln9gsPgHMTsfns7Nk+6gPuE= | ||||||
| github.com/hashicorp/terraform-plugin-docs v0.7.0 h1:7XKAOYHAxghe7q4/vx468X43X9GikdQ2dxtmcu2gQv0= | github.com/hashicorp/terraform-plugin-go v0.16.0/go.mod h1:4sn8bFuDbt+2+Yztt35IbOrvZc0zyEi87gJzsTgCES8= | ||||||
| github.com/hashicorp/terraform-plugin-docs v0.7.0/go.mod h1:57CICKfW7/KbW4lPhKOledyT6vu1LeAOzuvWXsVaxUE= | github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= | ||||||
| github.com/hashicorp/terraform-plugin-sdk v1.13.0 h1:8v2/ZNiI12OHxEn8pzJ3noCHyRc0biKbKj+iFv5ZWKw= | github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= | ||||||
| github.com/hashicorp/terraform-plugin-sdk v1.13.0/go.mod h1:HiWIPD/T9HixIhQUwaSoDQxo4BLFdmiBi/Qz5gjB8Q0= | github.com/hashicorp/terraform-plugin-sdk/v2 v2.27.0 h1:I8efBnjuDrgPjNF1MEypHy48VgcTIUY4X6rOFunrR3Y= | ||||||
| github.com/hashicorp/terraform-plugin-test v1.3.0 h1:hU5LoxrOn9qvOo+LTKN6mSav2J+dAMprbdxJPEQvp4U= | github.com/hashicorp/terraform-plugin-sdk/v2 v2.27.0/go.mod h1:cUEP4ly/nxlHy5HzD6YRrHydtlheGvGRJDhiWqqVik4= | ||||||
| github.com/hashicorp/terraform-plugin-test v1.3.0/go.mod h1:QIJHYz8j+xJtdtLrFTlzQVC0ocr3rf/OjIpgZLK56Hs= | github.com/hashicorp/terraform-registry-address v0.2.1 h1:QuTf6oJ1+WSflJw6WYOHhLgwUiQ0FrROpHPYFtwTYWM= | ||||||
| github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596 h1:hjyO2JsNZUKT1ym+FAdlBEkGPevazYsmVgIMw7dVELg= | github.com/hashicorp/terraform-registry-address v0.2.1/go.mod h1:BSE9fIFzp0qWsJUUyGquo4ldV9k2n+psif6NYkBRS3Y= | ||||||
| github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg= | github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= | ||||||
| github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= | github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= | ||||||
| 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.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= | ||||||
| github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= | 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/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= | ||||||
| github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= | github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= | ||||||
| github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= |  | ||||||
| github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= |  | ||||||
| github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= |  | ||||||
| github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= |  | ||||||
| github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= |  | ||||||
| github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= |  | ||||||
| github.com/keybase/go-crypto v0.0.0-20161004153544-93f5b35093ba/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M= |  | ||||||
| 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.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= | ||||||
| github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= |  | ||||||
| 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= | ||||||
| github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= |  | ||||||
| github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= |  | ||||||
| github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= | github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= | ||||||
| github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= |  | ||||||
| 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.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= | 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.4/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.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= |  | ||||||
| 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/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= | github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= | ||||||
| github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= | ||||||
| github.com/mitchellh/cli v1.1.2 h1:PvH+lL2B7IQ101xQL63Of8yFS2y+aDlsFcsqNc+u/Kw= | github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng= | ||||||
| github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= | github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= | ||||||
| github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= |  | ||||||
| github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= |  | ||||||
| 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= | ||||||
| github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= | github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= | ||||||
| github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= | github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= | ||||||
| github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= |  | ||||||
| github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= |  | ||||||
| github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= |  | ||||||
| github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= |  | ||||||
| github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= |  | ||||||
| github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= | github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= | ||||||
| github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= | github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= | ||||||
| github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= | github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= | ||||||
| github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= | github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= | ||||||
| github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= | github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= | ||||||
| github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= |  | ||||||
| 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/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/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= | github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= | ||||||
| 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/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/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= | github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= | ||||||
| github.com/posener/complete v1.2.1 h1:LrvDIY//XNo65Lq84G/akBuMGlawHvGBABv8f/ZN6DI= | github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= | ||||||
| github.com/posener/complete v1.2.1/go.mod h1:6gapUrK/U1TAN7ciCoNRIdVC5sbdBTUh1DKN0g6uH7E= | 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/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.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= |  | ||||||
| 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/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= | github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= | ||||||
| github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= | github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= | ||||||
| github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= | github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= | ||||||
| github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= | github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0= | ||||||
| github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= | ||||||
| github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | 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/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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||||
| github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= | github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= | ||||||
| github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= | ||||||
| github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok= |  | ||||||
| github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= |  | ||||||
| github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= | github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= | ||||||
| github.com/vmihailenco/msgpack v4.0.1+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= | github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= | ||||||
| github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U= | github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= | ||||||
| github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= | github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= | ||||||
| github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= | github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= | ||||||
| github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= | github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= | ||||||
| github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= | github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= | ||||||
| github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= | github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= | ||||||
| github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||||
| github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= | github.com/zclconf/go-cty v1.13.2 h1:4GvrUxe/QUDYuJKAav4EYqdM47/kZa672LwmXFmEKT0= | ||||||
| github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= | github.com/zclconf/go-cty v1.13.2/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= | ||||||
| github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= |  | ||||||
| github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= |  | ||||||
| github.com/zclconf/go-cty v1.9.1/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= |  | ||||||
| github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0= |  | ||||||
| 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= |  | ||||||
| github.com/zclconf/go-cty-yaml v1.0.1 h1:up11wlgAaDvlAGENcFDnZgkn0qUJurso7k6EpURKNF8= |  | ||||||
| github.com/zclconf/go-cty-yaml v1.0.1/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0= |  | ||||||
| go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= |  | ||||||
| go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= |  | ||||||
| go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= |  | ||||||
| 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-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= |  | ||||||
| golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= |  | ||||||
| golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= |  | ||||||
| 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-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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | ||||||
| golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= | golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= | ||||||
| golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI= | golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= | ||||||
| golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= | ||||||
| golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= | ||||||
| golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= |  | ||||||
| golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= |  | ||||||
| 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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= |  | ||||||
| golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= |  | ||||||
| golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= |  | ||||||
| golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= |  | ||||||
| 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/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= | ||||||
| golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= | ||||||
| golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |  | ||||||
| golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |  | ||||||
| golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |  | ||||||
| golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= |  | ||||||
| golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||||
| golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= |  | ||||||
| golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= |  | ||||||
| golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= | ||||||
| golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/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-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 h1:KrsHThm5nFk34YtATK1LsThyGhGbGe1olrte/HInHvs= | golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= | ||||||
| golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= | golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= | ||||||
| golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= |  | ||||||
| golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= |  | ||||||
| golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= |  | ||||||
| golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/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-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |  | ||||||
| golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/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/sys v0.0.0-20180823144017-11551d06cbcc/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-20190129075346-302c3dd5f1cc/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= | ||||||
| golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |  | ||||||
| golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |  | ||||||
| golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |  | ||||||
| golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |  | ||||||
| golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |  | ||||||
| golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |  | ||||||
| golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/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-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-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 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo= |  | ||||||
| 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-20211007075335-d3039528d8ac/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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
|  | golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= | ||||||
|  | golang.org/x/sys v0.9.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/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.1-0.20180807135948-17ff2d5776d2/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 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= | golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= | ||||||
| golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= | ||||||
| golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= |  | ||||||
| golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= |  | ||||||
| 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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= |  | ||||||
| golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= |  | ||||||
| golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= |  | ||||||
| golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= |  | ||||||
| golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= |  | ||||||
| golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= |  | ||||||
| golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= |  | ||||||
| golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= |  | ||||||
| golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= |  | ||||||
| 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/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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= |  | ||||||
| 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= | ||||||
| google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= |  | ||||||
| google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= |  | ||||||
| google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= |  | ||||||
| google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= |  | ||||||
| google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= |  | ||||||
| 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.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= | ||||||
| google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= | google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= | ||||||
| google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= | google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= | ||||||
| google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= | google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= | ||||||
| google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= | google.golang.org/grpc v1.56.0 h1:+y7Bs8rtMd07LeXmL3NxcTLn7mUkbKZqEpPhMNkwJEE= | ||||||
| google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= | google.golang.org/grpc v1.56.0/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= | ||||||
| google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= | ||||||
| google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= | ||||||
| google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= | google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= | ||||||
| google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= | google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | ||||||
| google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= |  | ||||||
| google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= |  | ||||||
| google.golang.org/genproto v0.0.0-20200310143817-43be25429f5a h1:lRlI5zu6AFy3iU/F8YWyNrAmn/tPCnhiTxfwhWb76eU= |  | ||||||
| google.golang.org/genproto v0.0.0-20200310143817-43be25429f5a/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= |  | ||||||
| google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= |  | ||||||
| google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= |  | ||||||
| google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= |  | ||||||
| google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= |  | ||||||
| google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= |  | ||||||
| google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= |  | ||||||
| google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk= |  | ||||||
| google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= |  | ||||||
| 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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= | ||||||
| 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-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |  | ||||||
| gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= |  | ||||||
| gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= |  | ||||||
| gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= |  | ||||||
| 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/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.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 h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= |  | ||||||
| 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= | ||||||
| honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||||
| honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||||||
| honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||||
| honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= |  | ||||||
| rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								main.go
									
									
									
									
									
								
							| @@ -2,7 +2,7 @@ package main // import "src.techknowlogick.com/terraform-provider-gitea" | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"git.uploadfilter24.eu/terraform-provider-gitea/gitea" | 	"git.uploadfilter24.eu/terraform-provider-gitea/gitea" | ||||||
| 	"github.com/hashicorp/terraform-plugin-sdk/plugin" | 	"github.com/hashicorp/terraform-plugin-sdk/v2/plugin" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var Version = "development" | var Version = "development" | ||||||
|   | |||||||
| @@ -6,11 +6,12 @@ networks: | |||||||
|  |  | ||||||
| services: | services: | ||||||
|   server: |   server: | ||||||
|     image: gitea/gitea:1.16.8 |     image: gitea/gitea:1.19.3 | ||||||
|     container_name: gitea |     container_name: gitea | ||||||
|     environment: |     environment: | ||||||
|       - USER_UID=1000 |       - USER_UID=1000 | ||||||
|       - USER_GID=1000 |       - USER_GID=1000 | ||||||
|  |       - DISABLE_GIT_HOOKS=false | ||||||
|     restart: always |     restart: always | ||||||
|     networks: |     networks: | ||||||
|       - gitea |       - gitea | ||||||
|   | |||||||
							
								
								
									
										202
									
								
								vendor/cloud.google.com/go/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										202
									
								
								vendor/cloud.google.com/go/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,202 +0,0 @@ | |||||||
|  |  | ||||||
|                                  Apache License |  | ||||||
|                            Version 2.0, January 2004 |  | ||||||
|                         http://www.apache.org/licenses/ |  | ||||||
|  |  | ||||||
|    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |  | ||||||
|  |  | ||||||
|    1. Definitions. |  | ||||||
|  |  | ||||||
|       "License" shall mean the terms and conditions for use, reproduction, |  | ||||||
|       and distribution as defined by Sections 1 through 9 of this document. |  | ||||||
|  |  | ||||||
|       "Licensor" shall mean the copyright owner or entity authorized by |  | ||||||
|       the copyright owner that is granting the License. |  | ||||||
|  |  | ||||||
|       "Legal Entity" shall mean the union of the acting entity and all |  | ||||||
|       other entities that control, are controlled by, or are under common |  | ||||||
|       control with that entity. For the purposes of this definition, |  | ||||||
|       "control" means (i) the power, direct or indirect, to cause the |  | ||||||
|       direction or management of such entity, whether by contract or |  | ||||||
|       otherwise, or (ii) ownership of fifty percent (50%) or more of the |  | ||||||
|       outstanding shares, or (iii) beneficial ownership of such entity. |  | ||||||
|  |  | ||||||
|       "You" (or "Your") shall mean an individual or Legal Entity |  | ||||||
|       exercising permissions granted by this License. |  | ||||||
|  |  | ||||||
|       "Source" form shall mean the preferred form for making modifications, |  | ||||||
|       including but not limited to software source code, documentation |  | ||||||
|       source, and configuration files. |  | ||||||
|  |  | ||||||
|       "Object" form shall mean any form resulting from mechanical |  | ||||||
|       transformation or translation of a Source form, including but |  | ||||||
|       not limited to compiled object code, generated documentation, |  | ||||||
|       and conversions to other media types. |  | ||||||
|  |  | ||||||
|       "Work" shall mean the work of authorship, whether in Source or |  | ||||||
|       Object form, made available under the License, as indicated by a |  | ||||||
|       copyright notice that is included in or attached to the work |  | ||||||
|       (an example is provided in the Appendix below). |  | ||||||
|  |  | ||||||
|       "Derivative Works" shall mean any work, whether in Source or Object |  | ||||||
|       form, that is based on (or derived from) the Work and for which the |  | ||||||
|       editorial revisions, annotations, elaborations, or other modifications |  | ||||||
|       represent, as a whole, an original work of authorship. For the purposes |  | ||||||
|       of this License, Derivative Works shall not include works that remain |  | ||||||
|       separable from, or merely link (or bind by name) to the interfaces of, |  | ||||||
|       the Work and Derivative Works thereof. |  | ||||||
|  |  | ||||||
|       "Contribution" shall mean any work of authorship, including |  | ||||||
|       the original version of the Work and any modifications or additions |  | ||||||
|       to that Work or Derivative Works thereof, that is intentionally |  | ||||||
|       submitted to Licensor for inclusion in the Work by the copyright owner |  | ||||||
|       or by an individual or Legal Entity authorized to submit on behalf of |  | ||||||
|       the copyright owner. For the purposes of this definition, "submitted" |  | ||||||
|       means any form of electronic, verbal, or written communication sent |  | ||||||
|       to the Licensor or its representatives, including but not limited to |  | ||||||
|       communication on electronic mailing lists, source code control systems, |  | ||||||
|       and issue tracking systems that are managed by, or on behalf of, the |  | ||||||
|       Licensor for the purpose of discussing and improving the Work, but |  | ||||||
|       excluding communication that is conspicuously marked or otherwise |  | ||||||
|       designated in writing by the copyright owner as "Not a Contribution." |  | ||||||
|  |  | ||||||
|       "Contributor" shall mean Licensor and any individual or Legal Entity |  | ||||||
|       on behalf of whom a Contribution has been received by Licensor and |  | ||||||
|       subsequently incorporated within the Work. |  | ||||||
|  |  | ||||||
|    2. Grant of Copyright License. Subject to the terms and conditions of |  | ||||||
|       this License, each Contributor hereby grants to You a perpetual, |  | ||||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable |  | ||||||
|       copyright license to reproduce, prepare Derivative Works of, |  | ||||||
|       publicly display, publicly perform, sublicense, and distribute the |  | ||||||
|       Work and such Derivative Works in Source or Object form. |  | ||||||
|  |  | ||||||
|    3. Grant of Patent License. Subject to the terms and conditions of |  | ||||||
|       this License, each Contributor hereby grants to You a perpetual, |  | ||||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable |  | ||||||
|       (except as stated in this section) patent license to make, have made, |  | ||||||
|       use, offer to sell, sell, import, and otherwise transfer the Work, |  | ||||||
|       where such license applies only to those patent claims licensable |  | ||||||
|       by such Contributor that are necessarily infringed by their |  | ||||||
|       Contribution(s) alone or by combination of their Contribution(s) |  | ||||||
|       with the Work to which such Contribution(s) was submitted. If You |  | ||||||
|       institute patent litigation against any entity (including a |  | ||||||
|       cross-claim or counterclaim in a lawsuit) alleging that the Work |  | ||||||
|       or a Contribution incorporated within the Work constitutes direct |  | ||||||
|       or contributory patent infringement, then any patent licenses |  | ||||||
|       granted to You under this License for that Work shall terminate |  | ||||||
|       as of the date such litigation is filed. |  | ||||||
|  |  | ||||||
|    4. Redistribution. You may reproduce and distribute copies of the |  | ||||||
|       Work or Derivative Works thereof in any medium, with or without |  | ||||||
|       modifications, and in Source or Object form, provided that You |  | ||||||
|       meet the following conditions: |  | ||||||
|  |  | ||||||
|       (a) You must give any other recipients of the Work or |  | ||||||
|           Derivative Works a copy of this License; and |  | ||||||
|  |  | ||||||
|       (b) You must cause any modified files to carry prominent notices |  | ||||||
|           stating that You changed the files; and |  | ||||||
|  |  | ||||||
|       (c) You must retain, in the Source form of any Derivative Works |  | ||||||
|           that You distribute, all copyright, patent, trademark, and |  | ||||||
|           attribution notices from the Source form of the Work, |  | ||||||
|           excluding those notices that do not pertain to any part of |  | ||||||
|           the Derivative Works; and |  | ||||||
|  |  | ||||||
|       (d) If the Work includes a "NOTICE" text file as part of its |  | ||||||
|           distribution, then any Derivative Works that You distribute must |  | ||||||
|           include a readable copy of the attribution notices contained |  | ||||||
|           within such NOTICE file, excluding those notices that do not |  | ||||||
|           pertain to any part of the Derivative Works, in at least one |  | ||||||
|           of the following places: within a NOTICE text file distributed |  | ||||||
|           as part of the Derivative Works; within the Source form or |  | ||||||
|           documentation, if provided along with the Derivative Works; or, |  | ||||||
|           within a display generated by the Derivative Works, if and |  | ||||||
|           wherever such third-party notices normally appear. The contents |  | ||||||
|           of the NOTICE file are for informational purposes only and |  | ||||||
|           do not modify the License. You may add Your own attribution |  | ||||||
|           notices within Derivative Works that You distribute, alongside |  | ||||||
|           or as an addendum to the NOTICE text from the Work, provided |  | ||||||
|           that such additional attribution notices cannot be construed |  | ||||||
|           as modifying the License. |  | ||||||
|  |  | ||||||
|       You may add Your own copyright statement to Your modifications and |  | ||||||
|       may provide additional or different license terms and conditions |  | ||||||
|       for use, reproduction, or distribution of Your modifications, or |  | ||||||
|       for any such Derivative Works as a whole, provided Your use, |  | ||||||
|       reproduction, and distribution of the Work otherwise complies with |  | ||||||
|       the conditions stated in this License. |  | ||||||
|  |  | ||||||
|    5. Submission of Contributions. Unless You explicitly state otherwise, |  | ||||||
|       any Contribution intentionally submitted for inclusion in the Work |  | ||||||
|       by You to the Licensor shall be under the terms and conditions of |  | ||||||
|       this License, without any additional terms or conditions. |  | ||||||
|       Notwithstanding the above, nothing herein shall supersede or modify |  | ||||||
|       the terms of any separate license agreement you may have executed |  | ||||||
|       with Licensor regarding such Contributions. |  | ||||||
|  |  | ||||||
|    6. Trademarks. This License does not grant permission to use the trade |  | ||||||
|       names, trademarks, service marks, or product names of the Licensor, |  | ||||||
|       except as required for reasonable and customary use in describing the |  | ||||||
|       origin of the Work and reproducing the content of the NOTICE file. |  | ||||||
|  |  | ||||||
|    7. Disclaimer of Warranty. Unless required by applicable law or |  | ||||||
|       agreed to in writing, Licensor provides the Work (and each |  | ||||||
|       Contributor provides its Contributions) on an "AS IS" BASIS, |  | ||||||
|       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |  | ||||||
|       implied, including, without limitation, any warranties or conditions |  | ||||||
|       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |  | ||||||
|       PARTICULAR PURPOSE. You are solely responsible for determining the |  | ||||||
|       appropriateness of using or redistributing the Work and assume any |  | ||||||
|       risks associated with Your exercise of permissions under this License. |  | ||||||
|  |  | ||||||
|    8. Limitation of Liability. In no event and under no legal theory, |  | ||||||
|       whether in tort (including negligence), contract, or otherwise, |  | ||||||
|       unless required by applicable law (such as deliberate and grossly |  | ||||||
|       negligent acts) or agreed to in writing, shall any Contributor be |  | ||||||
|       liable to You for damages, including any direct, indirect, special, |  | ||||||
|       incidental, or consequential damages of any character arising as a |  | ||||||
|       result of this License or out of the use or inability to use the |  | ||||||
|       Work (including but not limited to damages for loss of goodwill, |  | ||||||
|       work stoppage, computer failure or malfunction, or any and all |  | ||||||
|       other commercial damages or losses), even if such Contributor |  | ||||||
|       has been advised of the possibility of such damages. |  | ||||||
|  |  | ||||||
|    9. Accepting Warranty or Additional Liability. While redistributing |  | ||||||
|       the Work or Derivative Works thereof, You may choose to offer, |  | ||||||
|       and charge a fee for, acceptance of support, warranty, indemnity, |  | ||||||
|       or other liability obligations and/or rights consistent with this |  | ||||||
|       License. However, in accepting such obligations, You may act only |  | ||||||
|       on Your own behalf and on Your sole responsibility, not on behalf |  | ||||||
|       of any other Contributor, and only if You agree to indemnify, |  | ||||||
|       defend, and hold each Contributor harmless for any liability |  | ||||||
|       incurred by, or claims asserted against, such Contributor by reason |  | ||||||
|       of your accepting any such warranty or additional liability. |  | ||||||
|  |  | ||||||
|    END OF TERMS AND CONDITIONS |  | ||||||
|  |  | ||||||
|    APPENDIX: How to apply the Apache License to your work. |  | ||||||
|  |  | ||||||
|       To apply the Apache License to your work, attach the following |  | ||||||
|       boilerplate notice, with the fields enclosed by brackets "[]" |  | ||||||
|       replaced with your own identifying information. (Don't include |  | ||||||
|       the brackets!)  The text should be enclosed in the appropriate |  | ||||||
|       comment syntax for the file format. We also recommend that a |  | ||||||
|       file or class name and description of purpose be included on the |  | ||||||
|       same "printed page" as the copyright notice for easier |  | ||||||
|       identification within third-party archives. |  | ||||||
|  |  | ||||||
|    Copyright [yyyy] [name of copyright owner] |  | ||||||
|  |  | ||||||
|    Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|    you may not use this file except in compliance with the License. |  | ||||||
|    You may obtain a copy of the License at |  | ||||||
|  |  | ||||||
|        http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  |  | ||||||
|    Unless required by applicable law or agreed to in writing, software |  | ||||||
|    distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|    See the License for the specific language governing permissions and |  | ||||||
|    limitations under the License. |  | ||||||
							
								
								
									
										526
									
								
								vendor/cloud.google.com/go/compute/metadata/metadata.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										526
									
								
								vendor/cloud.google.com/go/compute/metadata/metadata.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,526 +0,0 @@ | |||||||
| // Copyright 2014 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| // Package metadata provides access to Google Compute Engine (GCE) |  | ||||||
| // metadata and API service accounts. |  | ||||||
| // |  | ||||||
| // This package is a wrapper around the GCE metadata service, |  | ||||||
| // as documented at https://developers.google.com/compute/docs/metadata. |  | ||||||
| package metadata // import "cloud.google.com/go/compute/metadata" |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"encoding/json" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io/ioutil" |  | ||||||
| 	"net" |  | ||||||
| 	"net/http" |  | ||||||
| 	"net/url" |  | ||||||
| 	"os" |  | ||||||
| 	"runtime" |  | ||||||
| 	"strings" |  | ||||||
| 	"sync" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	// metadataIP is the documented metadata server IP address. |  | ||||||
| 	metadataIP = "169.254.169.254" |  | ||||||
|  |  | ||||||
| 	// metadataHostEnv is the environment variable specifying the |  | ||||||
| 	// GCE metadata hostname.  If empty, the default value of |  | ||||||
| 	// metadataIP ("169.254.169.254") is used instead. |  | ||||||
| 	// This is variable name is not defined by any spec, as far as |  | ||||||
| 	// I know; it was made up for the Go package. |  | ||||||
| 	metadataHostEnv = "GCE_METADATA_HOST" |  | ||||||
|  |  | ||||||
| 	userAgent = "gcloud-golang/0.1" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type cachedValue struct { |  | ||||||
| 	k    string |  | ||||||
| 	trim bool |  | ||||||
| 	mu   sync.Mutex |  | ||||||
| 	v    string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var ( |  | ||||||
| 	projID  = &cachedValue{k: "project/project-id", trim: true} |  | ||||||
| 	projNum = &cachedValue{k: "project/numeric-project-id", trim: true} |  | ||||||
| 	instID  = &cachedValue{k: "instance/id", trim: true} |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| var ( |  | ||||||
| 	defaultClient = &Client{hc: &http.Client{ |  | ||||||
| 		Transport: &http.Transport{ |  | ||||||
| 			Dial: (&net.Dialer{ |  | ||||||
| 				Timeout:   2 * time.Second, |  | ||||||
| 				KeepAlive: 30 * time.Second, |  | ||||||
| 			}).Dial, |  | ||||||
| 			ResponseHeaderTimeout: 2 * time.Second, |  | ||||||
| 		}, |  | ||||||
| 	}} |  | ||||||
| 	subscribeClient = &Client{hc: &http.Client{ |  | ||||||
| 		Transport: &http.Transport{ |  | ||||||
| 			Dial: (&net.Dialer{ |  | ||||||
| 				Timeout:   2 * time.Second, |  | ||||||
| 				KeepAlive: 30 * time.Second, |  | ||||||
| 			}).Dial, |  | ||||||
| 		}, |  | ||||||
| 	}} |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // NotDefinedError is returned when requested metadata is not defined. |  | ||||||
| // |  | ||||||
| // The underlying string is the suffix after "/computeMetadata/v1/". |  | ||||||
| // |  | ||||||
| // This error is not returned if the value is defined to be the empty |  | ||||||
| // string. |  | ||||||
| type NotDefinedError string |  | ||||||
|  |  | ||||||
| func (suffix NotDefinedError) Error() string { |  | ||||||
| 	return fmt.Sprintf("metadata: GCE metadata %q not defined", string(suffix)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *cachedValue) get(cl *Client) (v string, err error) { |  | ||||||
| 	defer c.mu.Unlock() |  | ||||||
| 	c.mu.Lock() |  | ||||||
| 	if c.v != "" { |  | ||||||
| 		return c.v, nil |  | ||||||
| 	} |  | ||||||
| 	if c.trim { |  | ||||||
| 		v, err = cl.getTrimmed(c.k) |  | ||||||
| 	} else { |  | ||||||
| 		v, err = cl.Get(c.k) |  | ||||||
| 	} |  | ||||||
| 	if err == nil { |  | ||||||
| 		c.v = v |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var ( |  | ||||||
| 	onGCEOnce sync.Once |  | ||||||
| 	onGCE     bool |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // OnGCE reports whether this process is running on Google Compute Engine. |  | ||||||
| func OnGCE() bool { |  | ||||||
| 	onGCEOnce.Do(initOnGCE) |  | ||||||
| 	return onGCE |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func initOnGCE() { |  | ||||||
| 	onGCE = testOnGCE() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func testOnGCE() bool { |  | ||||||
| 	// The user explicitly said they're on GCE, so trust them. |  | ||||||
| 	if os.Getenv(metadataHostEnv) != "" { |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ctx, cancel := context.WithCancel(context.Background()) |  | ||||||
| 	defer cancel() |  | ||||||
|  |  | ||||||
| 	resc := make(chan bool, 2) |  | ||||||
|  |  | ||||||
| 	// Try two strategies in parallel. |  | ||||||
| 	// See https://github.com/googleapis/google-cloud-go/issues/194 |  | ||||||
| 	go func() { |  | ||||||
| 		req, _ := http.NewRequest("GET", "http://"+metadataIP, nil) |  | ||||||
| 		req.Header.Set("User-Agent", userAgent) |  | ||||||
| 		res, err := defaultClient.hc.Do(req.WithContext(ctx)) |  | ||||||
| 		if err != nil { |  | ||||||
| 			resc <- false |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		defer res.Body.Close() |  | ||||||
| 		resc <- res.Header.Get("Metadata-Flavor") == "Google" |  | ||||||
| 	}() |  | ||||||
|  |  | ||||||
| 	go func() { |  | ||||||
| 		addrs, err := net.LookupHost("metadata.google.internal") |  | ||||||
| 		if err != nil || len(addrs) == 0 { |  | ||||||
| 			resc <- false |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		resc <- strsContains(addrs, metadataIP) |  | ||||||
| 	}() |  | ||||||
|  |  | ||||||
| 	tryHarder := systemInfoSuggestsGCE() |  | ||||||
| 	if tryHarder { |  | ||||||
| 		res := <-resc |  | ||||||
| 		if res { |  | ||||||
| 			// The first strategy succeeded, so let's use it. |  | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 		// Wait for either the DNS or metadata server probe to |  | ||||||
| 		// contradict the other one and say we are running on |  | ||||||
| 		// GCE. Give it a lot of time to do so, since the system |  | ||||||
| 		// info already suggests we're running on a GCE BIOS. |  | ||||||
| 		timer := time.NewTimer(5 * time.Second) |  | ||||||
| 		defer timer.Stop() |  | ||||||
| 		select { |  | ||||||
| 		case res = <-resc: |  | ||||||
| 			return res |  | ||||||
| 		case <-timer.C: |  | ||||||
| 			// Too slow. Who knows what this system is. |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// There's no hint from the system info that we're running on |  | ||||||
| 	// GCE, so use the first probe's result as truth, whether it's |  | ||||||
| 	// true or false. The goal here is to optimize for speed for |  | ||||||
| 	// users who are NOT running on GCE. We can't assume that |  | ||||||
| 	// either a DNS lookup or an HTTP request to a blackholed IP |  | ||||||
| 	// address is fast. Worst case this should return when the |  | ||||||
| 	// metaClient's Transport.ResponseHeaderTimeout or |  | ||||||
| 	// Transport.Dial.Timeout fires (in two seconds). |  | ||||||
| 	return <-resc |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // systemInfoSuggestsGCE reports whether the local system (without |  | ||||||
| // doing network requests) suggests that we're running on GCE. If this |  | ||||||
| // returns true, testOnGCE tries a bit harder to reach its metadata |  | ||||||
| // server. |  | ||||||
| func systemInfoSuggestsGCE() bool { |  | ||||||
| 	if runtime.GOOS != "linux" { |  | ||||||
| 		// We don't have any non-Linux clues available, at least yet. |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	slurp, _ := ioutil.ReadFile("/sys/class/dmi/id/product_name") |  | ||||||
| 	name := strings.TrimSpace(string(slurp)) |  | ||||||
| 	return name == "Google" || name == "Google Compute Engine" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Subscribe calls Client.Subscribe on a client designed for subscribing (one with no |  | ||||||
| // ResponseHeaderTimeout). |  | ||||||
| func Subscribe(suffix string, fn func(v string, ok bool) error) error { |  | ||||||
| 	return subscribeClient.Subscribe(suffix, fn) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Get calls Client.Get on the default client. |  | ||||||
| func Get(suffix string) (string, error) { return defaultClient.Get(suffix) } |  | ||||||
|  |  | ||||||
| // ProjectID returns the current instance's project ID string. |  | ||||||
| func ProjectID() (string, error) { return defaultClient.ProjectID() } |  | ||||||
|  |  | ||||||
| // NumericProjectID returns the current instance's numeric project ID. |  | ||||||
| func NumericProjectID() (string, error) { return defaultClient.NumericProjectID() } |  | ||||||
|  |  | ||||||
| // InternalIP returns the instance's primary internal IP address. |  | ||||||
| func InternalIP() (string, error) { return defaultClient.InternalIP() } |  | ||||||
|  |  | ||||||
| // ExternalIP returns the instance's primary external (public) IP address. |  | ||||||
| func ExternalIP() (string, error) { return defaultClient.ExternalIP() } |  | ||||||
|  |  | ||||||
| // Email calls Client.Email on the default client. |  | ||||||
| func Email(serviceAccount string) (string, error) { return defaultClient.Email(serviceAccount) } |  | ||||||
|  |  | ||||||
| // Hostname returns the instance's hostname. This will be of the form |  | ||||||
| // "<instanceID>.c.<projID>.internal". |  | ||||||
| func Hostname() (string, error) { return defaultClient.Hostname() } |  | ||||||
|  |  | ||||||
| // InstanceTags returns the list of user-defined instance tags, |  | ||||||
| // assigned when initially creating a GCE instance. |  | ||||||
| func InstanceTags() ([]string, error) { return defaultClient.InstanceTags() } |  | ||||||
|  |  | ||||||
| // InstanceID returns the current VM's numeric instance ID. |  | ||||||
| func InstanceID() (string, error) { return defaultClient.InstanceID() } |  | ||||||
|  |  | ||||||
| // InstanceName returns the current VM's instance ID string. |  | ||||||
| func InstanceName() (string, error) { return defaultClient.InstanceName() } |  | ||||||
|  |  | ||||||
| // Zone returns the current VM's zone, such as "us-central1-b". |  | ||||||
| func Zone() (string, error) { return defaultClient.Zone() } |  | ||||||
|  |  | ||||||
| // InstanceAttributes calls Client.InstanceAttributes on the default client. |  | ||||||
| func InstanceAttributes() ([]string, error) { return defaultClient.InstanceAttributes() } |  | ||||||
|  |  | ||||||
| // ProjectAttributes calls Client.ProjectAttributes on the default client. |  | ||||||
| func ProjectAttributes() ([]string, error) { return defaultClient.ProjectAttributes() } |  | ||||||
|  |  | ||||||
| // InstanceAttributeValue calls Client.InstanceAttributeValue on the default client. |  | ||||||
| func InstanceAttributeValue(attr string) (string, error) { |  | ||||||
| 	return defaultClient.InstanceAttributeValue(attr) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ProjectAttributeValue calls Client.ProjectAttributeValue on the default client. |  | ||||||
| func ProjectAttributeValue(attr string) (string, error) { |  | ||||||
| 	return defaultClient.ProjectAttributeValue(attr) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Scopes calls Client.Scopes on the default client. |  | ||||||
| func Scopes(serviceAccount string) ([]string, error) { return defaultClient.Scopes(serviceAccount) } |  | ||||||
|  |  | ||||||
| func strsContains(ss []string, s string) bool { |  | ||||||
| 	for _, v := range ss { |  | ||||||
| 		if v == s { |  | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // A Client provides metadata. |  | ||||||
| type Client struct { |  | ||||||
| 	hc *http.Client |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // NewClient returns a Client that can be used to fetch metadata. All HTTP requests |  | ||||||
| // will use the given http.Client instead of the default client. |  | ||||||
| func NewClient(c *http.Client) *Client { |  | ||||||
| 	return &Client{hc: c} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // getETag returns a value from the metadata service as well as the associated ETag. |  | ||||||
| // This func is otherwise equivalent to Get. |  | ||||||
| func (c *Client) getETag(suffix string) (value, etag string, err error) { |  | ||||||
| 	// Using a fixed IP makes it very difficult to spoof the metadata service in |  | ||||||
| 	// a container, which is an important use-case for local testing of cloud |  | ||||||
| 	// deployments. To enable spoofing of the metadata service, the environment |  | ||||||
| 	// variable GCE_METADATA_HOST is first inspected to decide where metadata |  | ||||||
| 	// requests shall go. |  | ||||||
| 	host := os.Getenv(metadataHostEnv) |  | ||||||
| 	if host == "" { |  | ||||||
| 		// Using 169.254.169.254 instead of "metadata" here because Go |  | ||||||
| 		// binaries built with the "netgo" tag and without cgo won't |  | ||||||
| 		// know the search suffix for "metadata" is |  | ||||||
| 		// ".google.internal", and this IP address is documented as |  | ||||||
| 		// being stable anyway. |  | ||||||
| 		host = metadataIP |  | ||||||
| 	} |  | ||||||
| 	u := "http://" + host + "/computeMetadata/v1/" + suffix |  | ||||||
| 	req, _ := http.NewRequest("GET", u, nil) |  | ||||||
| 	req.Header.Set("Metadata-Flavor", "Google") |  | ||||||
| 	req.Header.Set("User-Agent", userAgent) |  | ||||||
| 	res, err := c.hc.Do(req) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return "", "", err |  | ||||||
| 	} |  | ||||||
| 	defer res.Body.Close() |  | ||||||
| 	if res.StatusCode == http.StatusNotFound { |  | ||||||
| 		return "", "", NotDefinedError(suffix) |  | ||||||
| 	} |  | ||||||
| 	all, err := ioutil.ReadAll(res.Body) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return "", "", err |  | ||||||
| 	} |  | ||||||
| 	if res.StatusCode != 200 { |  | ||||||
| 		return "", "", &Error{Code: res.StatusCode, Message: string(all)} |  | ||||||
| 	} |  | ||||||
| 	return string(all), res.Header.Get("Etag"), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Get returns a value from the metadata service. |  | ||||||
| // The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". |  | ||||||
| // |  | ||||||
| // If the GCE_METADATA_HOST environment variable is not defined, a default of |  | ||||||
| // 169.254.169.254 will be used instead. |  | ||||||
| // |  | ||||||
| // If the requested metadata is not defined, the returned error will |  | ||||||
| // be of type NotDefinedError. |  | ||||||
| func (c *Client) Get(suffix string) (string, error) { |  | ||||||
| 	val, _, err := c.getETag(suffix) |  | ||||||
| 	return val, err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Client) getTrimmed(suffix string) (s string, err error) { |  | ||||||
| 	s, err = c.Get(suffix) |  | ||||||
| 	s = strings.TrimSpace(s) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Client) lines(suffix string) ([]string, error) { |  | ||||||
| 	j, err := c.Get(suffix) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	s := strings.Split(strings.TrimSpace(j), "\n") |  | ||||||
| 	for i := range s { |  | ||||||
| 		s[i] = strings.TrimSpace(s[i]) |  | ||||||
| 	} |  | ||||||
| 	return s, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ProjectID returns the current instance's project ID string. |  | ||||||
| func (c *Client) ProjectID() (string, error) { return projID.get(c) } |  | ||||||
|  |  | ||||||
| // NumericProjectID returns the current instance's numeric project ID. |  | ||||||
| func (c *Client) NumericProjectID() (string, error) { return projNum.get(c) } |  | ||||||
|  |  | ||||||
| // InstanceID returns the current VM's numeric instance ID. |  | ||||||
| func (c *Client) InstanceID() (string, error) { return instID.get(c) } |  | ||||||
|  |  | ||||||
| // InternalIP returns the instance's primary internal IP address. |  | ||||||
| func (c *Client) InternalIP() (string, error) { |  | ||||||
| 	return c.getTrimmed("instance/network-interfaces/0/ip") |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Email returns the email address associated with the service account. |  | ||||||
| // The account may be empty or the string "default" to use the instance's |  | ||||||
| // main account. |  | ||||||
| func (c *Client) Email(serviceAccount string) (string, error) { |  | ||||||
| 	if serviceAccount == "" { |  | ||||||
| 		serviceAccount = "default" |  | ||||||
| 	} |  | ||||||
| 	return c.getTrimmed("instance/service-accounts/" + serviceAccount + "/email") |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ExternalIP returns the instance's primary external (public) IP address. |  | ||||||
| func (c *Client) ExternalIP() (string, error) { |  | ||||||
| 	return c.getTrimmed("instance/network-interfaces/0/access-configs/0/external-ip") |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Hostname returns the instance's hostname. This will be of the form |  | ||||||
| // "<instanceID>.c.<projID>.internal". |  | ||||||
| func (c *Client) Hostname() (string, error) { |  | ||||||
| 	return c.getTrimmed("instance/hostname") |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // InstanceTags returns the list of user-defined instance tags, |  | ||||||
| // assigned when initially creating a GCE instance. |  | ||||||
| func (c *Client) InstanceTags() ([]string, error) { |  | ||||||
| 	var s []string |  | ||||||
| 	j, err := c.Get("instance/tags") |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return s, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // InstanceName returns the current VM's instance ID string. |  | ||||||
| func (c *Client) InstanceName() (string, error) { |  | ||||||
| 	host, err := c.Hostname() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return "", err |  | ||||||
| 	} |  | ||||||
| 	return strings.Split(host, ".")[0], nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Zone returns the current VM's zone, such as "us-central1-b". |  | ||||||
| func (c *Client) Zone() (string, error) { |  | ||||||
| 	zone, err := c.getTrimmed("instance/zone") |  | ||||||
| 	// zone is of the form "projects/<projNum>/zones/<zoneName>". |  | ||||||
| 	if err != nil { |  | ||||||
| 		return "", err |  | ||||||
| 	} |  | ||||||
| 	return zone[strings.LastIndex(zone, "/")+1:], nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // InstanceAttributes returns the list of user-defined attributes, |  | ||||||
| // assigned when initially creating a GCE VM instance. The value of an |  | ||||||
| // attribute can be obtained with InstanceAttributeValue. |  | ||||||
| func (c *Client) InstanceAttributes() ([]string, error) { return c.lines("instance/attributes/") } |  | ||||||
|  |  | ||||||
| // ProjectAttributes returns the list of user-defined attributes |  | ||||||
| // applying to the project as a whole, not just this VM.  The value of |  | ||||||
| // an attribute can be obtained with ProjectAttributeValue. |  | ||||||
| func (c *Client) ProjectAttributes() ([]string, error) { return c.lines("project/attributes/") } |  | ||||||
|  |  | ||||||
| // InstanceAttributeValue returns the value of the provided VM |  | ||||||
| // instance attribute. |  | ||||||
| // |  | ||||||
| // If the requested attribute is not defined, the returned error will |  | ||||||
| // be of type NotDefinedError. |  | ||||||
| // |  | ||||||
| // InstanceAttributeValue may return ("", nil) if the attribute was |  | ||||||
| // defined to be the empty string. |  | ||||||
| func (c *Client) InstanceAttributeValue(attr string) (string, error) { |  | ||||||
| 	return c.Get("instance/attributes/" + attr) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ProjectAttributeValue returns the value of the provided |  | ||||||
| // project attribute. |  | ||||||
| // |  | ||||||
| // If the requested attribute is not defined, the returned error will |  | ||||||
| // be of type NotDefinedError. |  | ||||||
| // |  | ||||||
| // ProjectAttributeValue may return ("", nil) if the attribute was |  | ||||||
| // defined to be the empty string. |  | ||||||
| func (c *Client) ProjectAttributeValue(attr string) (string, error) { |  | ||||||
| 	return c.Get("project/attributes/" + attr) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Scopes returns the service account scopes for the given account. |  | ||||||
| // The account may be empty or the string "default" to use the instance's |  | ||||||
| // main account. |  | ||||||
| func (c *Client) Scopes(serviceAccount string) ([]string, error) { |  | ||||||
| 	if serviceAccount == "" { |  | ||||||
| 		serviceAccount = "default" |  | ||||||
| 	} |  | ||||||
| 	return c.lines("instance/service-accounts/" + serviceAccount + "/scopes") |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Subscribe subscribes to a value from the metadata service. |  | ||||||
| // The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". |  | ||||||
| // The suffix may contain query parameters. |  | ||||||
| // |  | ||||||
| // Subscribe calls fn with the latest metadata value indicated by the provided |  | ||||||
| // suffix. If the metadata value is deleted, fn is called with the empty string |  | ||||||
| // and ok false. Subscribe blocks until fn returns a non-nil error or the value |  | ||||||
| // is deleted. Subscribe returns the error value returned from the last call to |  | ||||||
| // fn, which may be nil when ok == false. |  | ||||||
| func (c *Client) Subscribe(suffix string, fn func(v string, ok bool) error) error { |  | ||||||
| 	const failedSubscribeSleep = time.Second * 5 |  | ||||||
|  |  | ||||||
| 	// First check to see if the metadata value exists at all. |  | ||||||
| 	val, lastETag, err := c.getETag(suffix) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err := fn(val, true); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ok := true |  | ||||||
| 	if strings.ContainsRune(suffix, '?') { |  | ||||||
| 		suffix += "&wait_for_change=true&last_etag=" |  | ||||||
| 	} else { |  | ||||||
| 		suffix += "?wait_for_change=true&last_etag=" |  | ||||||
| 	} |  | ||||||
| 	for { |  | ||||||
| 		val, etag, err := c.getETag(suffix + url.QueryEscape(lastETag)) |  | ||||||
| 		if err != nil { |  | ||||||
| 			if _, deleted := err.(NotDefinedError); !deleted { |  | ||||||
| 				time.Sleep(failedSubscribeSleep) |  | ||||||
| 				continue // Retry on other errors. |  | ||||||
| 			} |  | ||||||
| 			ok = false |  | ||||||
| 		} |  | ||||||
| 		lastETag = etag |  | ||||||
|  |  | ||||||
| 		if err := fn(val, ok); err != nil || !ok { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Error contains an error response from the server. |  | ||||||
| type Error struct { |  | ||||||
| 	// Code is the HTTP response status code. |  | ||||||
| 	Code int |  | ||||||
| 	// Message is the server response message. |  | ||||||
| 	Message string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (e *Error) Error() string { |  | ||||||
| 	return fmt.Sprintf("compute: Received %d `%s`", e.Code, e.Message) |  | ||||||
| } |  | ||||||
							
								
								
									
										315
									
								
								vendor/cloud.google.com/go/iam/iam.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										315
									
								
								vendor/cloud.google.com/go/iam/iam.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,315 +0,0 @@ | |||||||
| // Copyright 2016 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| // Package iam supports the resource-specific operations of Google Cloud |  | ||||||
| // IAM (Identity and Access Management) for the Google Cloud Libraries. |  | ||||||
| // See https://cloud.google.com/iam for more about IAM. |  | ||||||
| // |  | ||||||
| // Users of the Google Cloud Libraries will typically not use this package |  | ||||||
| // directly. Instead they will begin with some resource that supports IAM, like |  | ||||||
| // a pubsub topic, and call its IAM method to get a Handle for that resource. |  | ||||||
| package iam |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"fmt" |  | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	gax "github.com/googleapis/gax-go/v2" |  | ||||||
| 	pb "google.golang.org/genproto/googleapis/iam/v1" |  | ||||||
| 	"google.golang.org/grpc" |  | ||||||
| 	"google.golang.org/grpc/codes" |  | ||||||
| 	"google.golang.org/grpc/metadata" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // client abstracts the IAMPolicy API to allow multiple implementations. |  | ||||||
| type client interface { |  | ||||||
| 	Get(ctx context.Context, resource string) (*pb.Policy, error) |  | ||||||
| 	Set(ctx context.Context, resource string, p *pb.Policy) error |  | ||||||
| 	Test(ctx context.Context, resource string, perms []string) ([]string, error) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // grpcClient implements client for the standard gRPC-based IAMPolicy service. |  | ||||||
| type grpcClient struct { |  | ||||||
| 	c pb.IAMPolicyClient |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var withRetry = gax.WithRetry(func() gax.Retryer { |  | ||||||
| 	return gax.OnCodes([]codes.Code{ |  | ||||||
| 		codes.DeadlineExceeded, |  | ||||||
| 		codes.Unavailable, |  | ||||||
| 	}, gax.Backoff{ |  | ||||||
| 		Initial:    100 * time.Millisecond, |  | ||||||
| 		Max:        60 * time.Second, |  | ||||||
| 		Multiplier: 1.3, |  | ||||||
| 	}) |  | ||||||
| }) |  | ||||||
|  |  | ||||||
| func (g *grpcClient) Get(ctx context.Context, resource string) (*pb.Policy, error) { |  | ||||||
| 	var proto *pb.Policy |  | ||||||
| 	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", resource)) |  | ||||||
| 	ctx = insertMetadata(ctx, md) |  | ||||||
|  |  | ||||||
| 	err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { |  | ||||||
| 		var err error |  | ||||||
| 		proto, err = g.c.GetIamPolicy(ctx, &pb.GetIamPolicyRequest{Resource: resource}) |  | ||||||
| 		return err |  | ||||||
| 	}, withRetry) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return proto, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (g *grpcClient) Set(ctx context.Context, resource string, p *pb.Policy) error { |  | ||||||
| 	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", resource)) |  | ||||||
| 	ctx = insertMetadata(ctx, md) |  | ||||||
|  |  | ||||||
| 	return gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { |  | ||||||
| 		_, err := g.c.SetIamPolicy(ctx, &pb.SetIamPolicyRequest{ |  | ||||||
| 			Resource: resource, |  | ||||||
| 			Policy:   p, |  | ||||||
| 		}) |  | ||||||
| 		return err |  | ||||||
| 	}, withRetry) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (g *grpcClient) Test(ctx context.Context, resource string, perms []string) ([]string, error) { |  | ||||||
| 	var res *pb.TestIamPermissionsResponse |  | ||||||
| 	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", resource)) |  | ||||||
| 	ctx = insertMetadata(ctx, md) |  | ||||||
|  |  | ||||||
| 	err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { |  | ||||||
| 		var err error |  | ||||||
| 		res, err = g.c.TestIamPermissions(ctx, &pb.TestIamPermissionsRequest{ |  | ||||||
| 			Resource:    resource, |  | ||||||
| 			Permissions: perms, |  | ||||||
| 		}) |  | ||||||
| 		return err |  | ||||||
| 	}, withRetry) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return res.Permissions, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // A Handle provides IAM operations for a resource. |  | ||||||
| type Handle struct { |  | ||||||
| 	c        client |  | ||||||
| 	resource string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // InternalNewHandle is for use by the Google Cloud Libraries only. |  | ||||||
| // |  | ||||||
| // InternalNewHandle returns a Handle for resource. |  | ||||||
| // The conn parameter refers to a server that must support the IAMPolicy service. |  | ||||||
| func InternalNewHandle(conn *grpc.ClientConn, resource string) *Handle { |  | ||||||
| 	return InternalNewHandleGRPCClient(pb.NewIAMPolicyClient(conn), resource) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // InternalNewHandleGRPCClient is for use by the Google Cloud Libraries only. |  | ||||||
| // |  | ||||||
| // InternalNewHandleClient returns a Handle for resource using the given |  | ||||||
| // grpc service that implements IAM as a mixin |  | ||||||
| func InternalNewHandleGRPCClient(c pb.IAMPolicyClient, resource string) *Handle { |  | ||||||
| 	return InternalNewHandleClient(&grpcClient{c: c}, resource) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // InternalNewHandleClient is for use by the Google Cloud Libraries only. |  | ||||||
| // |  | ||||||
| // InternalNewHandleClient returns a Handle for resource using the given |  | ||||||
| // client implementation. |  | ||||||
| func InternalNewHandleClient(c client, resource string) *Handle { |  | ||||||
| 	return &Handle{ |  | ||||||
| 		c:        c, |  | ||||||
| 		resource: resource, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Policy retrieves the IAM policy for the resource. |  | ||||||
| func (h *Handle) Policy(ctx context.Context) (*Policy, error) { |  | ||||||
| 	proto, err := h.c.Get(ctx, h.resource) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return &Policy{InternalProto: proto}, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // SetPolicy replaces the resource's current policy with the supplied Policy. |  | ||||||
| // |  | ||||||
| // If policy was created from a prior call to Get, then the modification will |  | ||||||
| // only succeed if the policy has not changed since the Get. |  | ||||||
| func (h *Handle) SetPolicy(ctx context.Context, policy *Policy) error { |  | ||||||
| 	return h.c.Set(ctx, h.resource, policy.InternalProto) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // TestPermissions returns the subset of permissions that the caller has on the resource. |  | ||||||
| func (h *Handle) TestPermissions(ctx context.Context, permissions []string) ([]string, error) { |  | ||||||
| 	return h.c.Test(ctx, h.resource, permissions) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // A RoleName is a name representing a collection of permissions. |  | ||||||
| type RoleName string |  | ||||||
|  |  | ||||||
| // Common role names. |  | ||||||
| const ( |  | ||||||
| 	Owner  RoleName = "roles/owner" |  | ||||||
| 	Editor RoleName = "roles/editor" |  | ||||||
| 	Viewer RoleName = "roles/viewer" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	// AllUsers is a special member that denotes all users, even unauthenticated ones. |  | ||||||
| 	AllUsers = "allUsers" |  | ||||||
|  |  | ||||||
| 	// AllAuthenticatedUsers is a special member that denotes all authenticated users. |  | ||||||
| 	AllAuthenticatedUsers = "allAuthenticatedUsers" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // A Policy is a list of Bindings representing roles |  | ||||||
| // granted to members. |  | ||||||
| // |  | ||||||
| // The zero Policy is a valid policy with no bindings. |  | ||||||
| type Policy struct { |  | ||||||
| 	// TODO(jba): when type aliases are available, put Policy into an internal package |  | ||||||
| 	// and provide an exported alias here. |  | ||||||
|  |  | ||||||
| 	// This field is exported for use by the Google Cloud Libraries only. |  | ||||||
| 	// It may become unexported in a future release. |  | ||||||
| 	InternalProto *pb.Policy |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Members returns the list of members with the supplied role. |  | ||||||
| // The return value should not be modified. Use Add and Remove |  | ||||||
| // to modify the members of a role. |  | ||||||
| func (p *Policy) Members(r RoleName) []string { |  | ||||||
| 	b := p.binding(r) |  | ||||||
| 	if b == nil { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	return b.Members |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // HasRole reports whether member has role r. |  | ||||||
| func (p *Policy) HasRole(member string, r RoleName) bool { |  | ||||||
| 	return memberIndex(member, p.binding(r)) >= 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Add adds member member to role r if it is not already present. |  | ||||||
| // A new binding is created if there is no binding for the role. |  | ||||||
| func (p *Policy) Add(member string, r RoleName) { |  | ||||||
| 	b := p.binding(r) |  | ||||||
| 	if b == nil { |  | ||||||
| 		if p.InternalProto == nil { |  | ||||||
| 			p.InternalProto = &pb.Policy{} |  | ||||||
| 		} |  | ||||||
| 		p.InternalProto.Bindings = append(p.InternalProto.Bindings, &pb.Binding{ |  | ||||||
| 			Role:    string(r), |  | ||||||
| 			Members: []string{member}, |  | ||||||
| 		}) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if memberIndex(member, b) < 0 { |  | ||||||
| 		b.Members = append(b.Members, member) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Remove removes member from role r if it is present. |  | ||||||
| func (p *Policy) Remove(member string, r RoleName) { |  | ||||||
| 	bi := p.bindingIndex(r) |  | ||||||
| 	if bi < 0 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	bindings := p.InternalProto.Bindings |  | ||||||
| 	b := bindings[bi] |  | ||||||
| 	mi := memberIndex(member, b) |  | ||||||
| 	if mi < 0 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	// Order doesn't matter for bindings or members, so to remove, move the last item |  | ||||||
| 	// into the removed spot and shrink the slice. |  | ||||||
| 	if len(b.Members) == 1 { |  | ||||||
| 		// Remove binding. |  | ||||||
| 		last := len(bindings) - 1 |  | ||||||
| 		bindings[bi] = bindings[last] |  | ||||||
| 		bindings[last] = nil |  | ||||||
| 		p.InternalProto.Bindings = bindings[:last] |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	// Remove member. |  | ||||||
| 	// TODO(jba): worry about multiple copies of m? |  | ||||||
| 	last := len(b.Members) - 1 |  | ||||||
| 	b.Members[mi] = b.Members[last] |  | ||||||
| 	b.Members[last] = "" |  | ||||||
| 	b.Members = b.Members[:last] |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Roles returns the names of all the roles that appear in the Policy. |  | ||||||
| func (p *Policy) Roles() []RoleName { |  | ||||||
| 	if p.InternalProto == nil { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	var rns []RoleName |  | ||||||
| 	for _, b := range p.InternalProto.Bindings { |  | ||||||
| 		rns = append(rns, RoleName(b.Role)) |  | ||||||
| 	} |  | ||||||
| 	return rns |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // binding returns the Binding for the suppied role, or nil if there isn't one. |  | ||||||
| func (p *Policy) binding(r RoleName) *pb.Binding { |  | ||||||
| 	i := p.bindingIndex(r) |  | ||||||
| 	if i < 0 { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	return p.InternalProto.Bindings[i] |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *Policy) bindingIndex(r RoleName) int { |  | ||||||
| 	if p.InternalProto == nil { |  | ||||||
| 		return -1 |  | ||||||
| 	} |  | ||||||
| 	for i, b := range p.InternalProto.Bindings { |  | ||||||
| 		if b.Role == string(r) { |  | ||||||
| 			return i |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return -1 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // memberIndex returns the index of m in b's Members, or -1 if not found. |  | ||||||
| func memberIndex(m string, b *pb.Binding) int { |  | ||||||
| 	if b == nil { |  | ||||||
| 		return -1 |  | ||||||
| 	} |  | ||||||
| 	for i, mm := range b.Members { |  | ||||||
| 		if mm == m { |  | ||||||
| 			return i |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return -1 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // insertMetadata inserts metadata into the given context |  | ||||||
| func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { |  | ||||||
| 	out, _ := metadata.FromOutgoingContext(ctx) |  | ||||||
| 	out = out.Copy() |  | ||||||
| 	for _, md := range mds { |  | ||||||
| 		for k, v := range md { |  | ||||||
| 			out[k] = append(out[k], v...) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return metadata.NewOutgoingContext(ctx, out) |  | ||||||
| } |  | ||||||
							
								
								
									
										54
									
								
								vendor/cloud.google.com/go/internal/annotate.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								vendor/cloud.google.com/go/internal/annotate.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,54 +0,0 @@ | |||||||
| // Copyright 2017 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| package internal |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"fmt" |  | ||||||
|  |  | ||||||
| 	"google.golang.org/api/googleapi" |  | ||||||
| 	"google.golang.org/grpc/status" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // Annotate prepends msg to the error message in err, attempting |  | ||||||
| // to preserve other information in err, like an error code. |  | ||||||
| // |  | ||||||
| // Annotate panics if err is nil. |  | ||||||
| // |  | ||||||
| // Annotate knows about these error types: |  | ||||||
| // - "google.golang.org/grpc/status".Status |  | ||||||
| // - "google.golang.org/api/googleapi".Error |  | ||||||
| // If the error is not one of these types, Annotate behaves |  | ||||||
| // like |  | ||||||
| //   fmt.Errorf("%s: %v", msg, err) |  | ||||||
| func Annotate(err error, msg string) error { |  | ||||||
| 	if err == nil { |  | ||||||
| 		panic("Annotate called with nil") |  | ||||||
| 	} |  | ||||||
| 	if s, ok := status.FromError(err); ok { |  | ||||||
| 		p := s.Proto() |  | ||||||
| 		p.Message = msg + ": " + p.Message |  | ||||||
| 		return status.ErrorProto(p) |  | ||||||
| 	} |  | ||||||
| 	if g, ok := err.(*googleapi.Error); ok { |  | ||||||
| 		g.Message = msg + ": " + g.Message |  | ||||||
| 		return g |  | ||||||
| 	} |  | ||||||
| 	return fmt.Errorf("%s: %v", msg, err) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Annotatef uses format and args to format a string, then calls Annotate. |  | ||||||
| func Annotatef(err error, format string, args ...interface{}) error { |  | ||||||
| 	return Annotate(err, fmt.Sprintf(format, args...)) |  | ||||||
| } |  | ||||||
							
								
								
									
										108
									
								
								vendor/cloud.google.com/go/internal/optional/optional.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										108
									
								
								vendor/cloud.google.com/go/internal/optional/optional.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,108 +0,0 @@ | |||||||
| // Copyright 2016 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| // Package optional provides versions of primitive types that can |  | ||||||
| // be nil. These are useful in methods that update some of an API object's |  | ||||||
| // fields. |  | ||||||
| package optional |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"fmt" |  | ||||||
| 	"strings" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type ( |  | ||||||
| 	// Bool is either a bool or nil. |  | ||||||
| 	Bool interface{} |  | ||||||
|  |  | ||||||
| 	// String is either a string or nil. |  | ||||||
| 	String interface{} |  | ||||||
|  |  | ||||||
| 	// Int is either an int or nil. |  | ||||||
| 	Int interface{} |  | ||||||
|  |  | ||||||
| 	// Uint is either a uint or nil. |  | ||||||
| 	Uint interface{} |  | ||||||
|  |  | ||||||
| 	// Float64 is either a float64 or nil. |  | ||||||
| 	Float64 interface{} |  | ||||||
|  |  | ||||||
| 	// Duration is either a time.Duration or nil. |  | ||||||
| 	Duration interface{} |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // ToBool returns its argument as a bool. |  | ||||||
| // It panics if its argument is nil or not a bool. |  | ||||||
| func ToBool(v Bool) bool { |  | ||||||
| 	x, ok := v.(bool) |  | ||||||
| 	if !ok { |  | ||||||
| 		doPanic("Bool", v) |  | ||||||
| 	} |  | ||||||
| 	return x |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ToString returns its argument as a string. |  | ||||||
| // It panics if its argument is nil or not a string. |  | ||||||
| func ToString(v String) string { |  | ||||||
| 	x, ok := v.(string) |  | ||||||
| 	if !ok { |  | ||||||
| 		doPanic("String", v) |  | ||||||
| 	} |  | ||||||
| 	return x |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ToInt returns its argument as an int. |  | ||||||
| // It panics if its argument is nil or not an int. |  | ||||||
| func ToInt(v Int) int { |  | ||||||
| 	x, ok := v.(int) |  | ||||||
| 	if !ok { |  | ||||||
| 		doPanic("Int", v) |  | ||||||
| 	} |  | ||||||
| 	return x |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ToUint returns its argument as a uint. |  | ||||||
| // It panics if its argument is nil or not a uint. |  | ||||||
| func ToUint(v Uint) uint { |  | ||||||
| 	x, ok := v.(uint) |  | ||||||
| 	if !ok { |  | ||||||
| 		doPanic("Uint", v) |  | ||||||
| 	} |  | ||||||
| 	return x |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ToFloat64 returns its argument as a float64. |  | ||||||
| // It panics if its argument is nil or not a float64. |  | ||||||
| func ToFloat64(v Float64) float64 { |  | ||||||
| 	x, ok := v.(float64) |  | ||||||
| 	if !ok { |  | ||||||
| 		doPanic("Float64", v) |  | ||||||
| 	} |  | ||||||
| 	return x |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ToDuration returns its argument as a time.Duration. |  | ||||||
| // It panics if its argument is nil or not a time.Duration. |  | ||||||
| func ToDuration(v Duration) time.Duration { |  | ||||||
| 	x, ok := v.(time.Duration) |  | ||||||
| 	if !ok { |  | ||||||
| 		doPanic("Duration", v) |  | ||||||
| 	} |  | ||||||
| 	return x |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func doPanic(capType string, v interface{}) { |  | ||||||
| 	panic(fmt.Sprintf("optional.%s value should be %s, got %T", capType, strings.ToLower(capType), v)) |  | ||||||
| } |  | ||||||
							
								
								
									
										54
									
								
								vendor/cloud.google.com/go/internal/retry.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								vendor/cloud.google.com/go/internal/retry.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,54 +0,0 @@ | |||||||
| // Copyright 2016 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| package internal |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	gax "github.com/googleapis/gax-go/v2" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // Retry calls the supplied function f repeatedly according to the provided |  | ||||||
| // backoff parameters. It returns when one of the following occurs: |  | ||||||
| // When f's first return value is true, Retry immediately returns with f's second |  | ||||||
| // return value. |  | ||||||
| // When the provided context is done, Retry returns with an error that |  | ||||||
| // includes both ctx.Error() and the last error returned by f. |  | ||||||
| func Retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error)) error { |  | ||||||
| 	return retry(ctx, bo, f, gax.Sleep) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error), |  | ||||||
| 	sleep func(context.Context, time.Duration) error) error { |  | ||||||
| 	var lastErr error |  | ||||||
| 	for { |  | ||||||
| 		stop, err := f() |  | ||||||
| 		if stop { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		// Remember the last "real" error from f. |  | ||||||
| 		if err != nil && err != context.Canceled && err != context.DeadlineExceeded { |  | ||||||
| 			lastErr = err |  | ||||||
| 		} |  | ||||||
| 		p := bo.Pause() |  | ||||||
| 		if cerr := sleep(ctx, p); cerr != nil { |  | ||||||
| 			if lastErr != nil { |  | ||||||
| 				return Annotatef(lastErr, "retry failed with %v; last error", cerr) |  | ||||||
| 			} |  | ||||||
| 			return cerr |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
							
								
								
									
										109
									
								
								vendor/cloud.google.com/go/internal/trace/trace.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										109
									
								
								vendor/cloud.google.com/go/internal/trace/trace.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,109 +0,0 @@ | |||||||
| // Copyright 2018 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| package trace |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"fmt" |  | ||||||
|  |  | ||||||
| 	"go.opencensus.io/trace" |  | ||||||
| 	"google.golang.org/api/googleapi" |  | ||||||
| 	"google.golang.org/genproto/googleapis/rpc/code" |  | ||||||
| 	"google.golang.org/grpc/status" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // StartSpan adds a span to the trace with the given name. |  | ||||||
| func StartSpan(ctx context.Context, name string) context.Context { |  | ||||||
| 	ctx, _ = trace.StartSpan(ctx, name) |  | ||||||
| 	return ctx |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // EndSpan ends a span with the given error. |  | ||||||
| func EndSpan(ctx context.Context, err error) { |  | ||||||
| 	span := trace.FromContext(ctx) |  | ||||||
| 	if err != nil { |  | ||||||
| 		span.SetStatus(toStatus(err)) |  | ||||||
| 	} |  | ||||||
| 	span.End() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // toStatus interrogates an error and converts it to an appropriate |  | ||||||
| // OpenCensus status. |  | ||||||
| func toStatus(err error) trace.Status { |  | ||||||
| 	if err2, ok := err.(*googleapi.Error); ok { |  | ||||||
| 		return trace.Status{Code: httpStatusCodeToOCCode(err2.Code), Message: err2.Message} |  | ||||||
| 	} else if s, ok := status.FromError(err); ok { |  | ||||||
| 		return trace.Status{Code: int32(s.Code()), Message: s.Message()} |  | ||||||
| 	} else { |  | ||||||
| 		return trace.Status{Code: int32(code.Code_UNKNOWN), Message: err.Error()} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // TODO(deklerk): switch to using OpenCensus function when it becomes available. |  | ||||||
| // Reference: https://github.com/googleapis/googleapis/blob/26b634d2724ac5dd30ae0b0cbfb01f07f2e4050e/google/rpc/code.proto |  | ||||||
| func httpStatusCodeToOCCode(httpStatusCode int) int32 { |  | ||||||
| 	switch httpStatusCode { |  | ||||||
| 	case 200: |  | ||||||
| 		return int32(code.Code_OK) |  | ||||||
| 	case 499: |  | ||||||
| 		return int32(code.Code_CANCELLED) |  | ||||||
| 	case 500: |  | ||||||
| 		return int32(code.Code_UNKNOWN) // Could also be Code_INTERNAL, Code_DATA_LOSS |  | ||||||
| 	case 400: |  | ||||||
| 		return int32(code.Code_INVALID_ARGUMENT) // Could also be Code_OUT_OF_RANGE |  | ||||||
| 	case 504: |  | ||||||
| 		return int32(code.Code_DEADLINE_EXCEEDED) |  | ||||||
| 	case 404: |  | ||||||
| 		return int32(code.Code_NOT_FOUND) |  | ||||||
| 	case 409: |  | ||||||
| 		return int32(code.Code_ALREADY_EXISTS) // Could also be Code_ABORTED |  | ||||||
| 	case 403: |  | ||||||
| 		return int32(code.Code_PERMISSION_DENIED) |  | ||||||
| 	case 401: |  | ||||||
| 		return int32(code.Code_UNAUTHENTICATED) |  | ||||||
| 	case 429: |  | ||||||
| 		return int32(code.Code_RESOURCE_EXHAUSTED) |  | ||||||
| 	case 501: |  | ||||||
| 		return int32(code.Code_UNIMPLEMENTED) |  | ||||||
| 	case 503: |  | ||||||
| 		return int32(code.Code_UNAVAILABLE) |  | ||||||
| 	default: |  | ||||||
| 		return int32(code.Code_UNKNOWN) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // TODO: (odeke-em): perhaps just pass around spans due to the cost |  | ||||||
| // incurred from using trace.FromContext(ctx) yet we could avoid |  | ||||||
| // throwing away the work done by ctx, span := trace.StartSpan. |  | ||||||
| func TracePrintf(ctx context.Context, attrMap map[string]interface{}, format string, args ...interface{}) { |  | ||||||
| 	var attrs []trace.Attribute |  | ||||||
| 	for k, v := range attrMap { |  | ||||||
| 		var a trace.Attribute |  | ||||||
| 		switch v := v.(type) { |  | ||||||
| 		case string: |  | ||||||
| 			a = trace.StringAttribute(k, v) |  | ||||||
| 		case bool: |  | ||||||
| 			a = trace.BoolAttribute(k, v) |  | ||||||
| 		case int: |  | ||||||
| 			a = trace.Int64Attribute(k, int64(v)) |  | ||||||
| 		case int64: |  | ||||||
| 			a = trace.Int64Attribute(k, v) |  | ||||||
| 		default: |  | ||||||
| 			a = trace.StringAttribute(k, fmt.Sprintf("%#v", v)) |  | ||||||
| 		} |  | ||||||
| 		attrs = append(attrs, a) |  | ||||||
| 	} |  | ||||||
| 	trace.FromContext(ctx).Annotatef(attrs, format, args...) |  | ||||||
| } |  | ||||||
							
								
								
									
										19
									
								
								vendor/cloud.google.com/go/internal/version/update_version.sh
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/cloud.google.com/go/internal/version/update_version.sh
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,19 +0,0 @@ | |||||||
| #!/bin/bash |  | ||||||
| # Copyright 2019 Google LLC |  | ||||||
| # |  | ||||||
| # Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| # you may not use this file except in compliance with the License. |  | ||||||
| # You may obtain a copy of the License at |  | ||||||
| # |  | ||||||
| #      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| # |  | ||||||
| # Unless required by applicable law or agreed to in writing, software |  | ||||||
| # distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| # See the License for the specific language governing permissions and |  | ||||||
| # limitations under the License. |  | ||||||
|  |  | ||||||
| today=$(date +%Y%m%d) |  | ||||||
|  |  | ||||||
| sed -i -r -e 's/const Repo = "([0-9]{8})"/const Repo = "'$today'"/' $GOFILE |  | ||||||
|  |  | ||||||
							
								
								
									
										71
									
								
								vendor/cloud.google.com/go/internal/version/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										71
									
								
								vendor/cloud.google.com/go/internal/version/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,71 +0,0 @@ | |||||||
| // Copyright 2016 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| //go:generate ./update_version.sh |  | ||||||
|  |  | ||||||
| // Package version contains version information for Google Cloud Client |  | ||||||
| // Libraries for Go, as reported in request headers. |  | ||||||
| package version |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"runtime" |  | ||||||
| 	"strings" |  | ||||||
| 	"unicode" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // Repo is the current version of the client libraries in this |  | ||||||
| // repo. It should be a date in YYYYMMDD format. |  | ||||||
| const Repo = "20190802" |  | ||||||
|  |  | ||||||
| // Go returns the Go runtime version. The returned string |  | ||||||
| // has no whitespace. |  | ||||||
| func Go() string { |  | ||||||
| 	return goVersion |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var goVersion = goVer(runtime.Version()) |  | ||||||
|  |  | ||||||
| const develPrefix = "devel +" |  | ||||||
|  |  | ||||||
| func goVer(s string) string { |  | ||||||
| 	if strings.HasPrefix(s, develPrefix) { |  | ||||||
| 		s = s[len(develPrefix):] |  | ||||||
| 		if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { |  | ||||||
| 			s = s[:p] |  | ||||||
| 		} |  | ||||||
| 		return s |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if strings.HasPrefix(s, "go1") { |  | ||||||
| 		s = s[2:] |  | ||||||
| 		var prerelease string |  | ||||||
| 		if p := strings.IndexFunc(s, notSemverRune); p >= 0 { |  | ||||||
| 			s, prerelease = s[:p], s[p:] |  | ||||||
| 		} |  | ||||||
| 		if strings.HasSuffix(s, ".") { |  | ||||||
| 			s += "0" |  | ||||||
| 		} else if strings.Count(s, ".") < 2 { |  | ||||||
| 			s += ".0" |  | ||||||
| 		} |  | ||||||
| 		if prerelease != "" { |  | ||||||
| 			s += "-" + prerelease |  | ||||||
| 		} |  | ||||||
| 		return s |  | ||||||
| 	} |  | ||||||
| 	return "" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func notSemverRune(r rune) bool { |  | ||||||
| 	return !strings.ContainsRune("0123456789.", r) |  | ||||||
| } |  | ||||||
							
								
								
									
										32
									
								
								vendor/cloud.google.com/go/storage/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/cloud.google.com/go/storage/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,32 +0,0 @@ | |||||||
| ## Cloud Storage [](https://godoc.org/cloud.google.com/go/storage) |  | ||||||
|  |  | ||||||
| - [About Cloud Storage](https://cloud.google.com/storage/) |  | ||||||
| - [API documentation](https://cloud.google.com/storage/docs) |  | ||||||
| - [Go client documentation](https://godoc.org/cloud.google.com/go/storage) |  | ||||||
| - [Complete sample programs](https://github.com/GoogleCloudPlatform/golang-samples/tree/master/storage) |  | ||||||
|  |  | ||||||
| ### Example Usage |  | ||||||
|  |  | ||||||
| First create a `storage.Client` to use throughout your application: |  | ||||||
|  |  | ||||||
| [snip]:# (storage-1) |  | ||||||
| ```go |  | ||||||
| client, err := storage.NewClient(ctx) |  | ||||||
| if err != nil { |  | ||||||
| 	log.Fatal(err) |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| [snip]:# (storage-2) |  | ||||||
| ```go |  | ||||||
| // Read the object1 from bucket. |  | ||||||
| rc, err := client.Bucket("bucket").Object("object1").NewReader(ctx) |  | ||||||
| if err != nil { |  | ||||||
| 	log.Fatal(err) |  | ||||||
| } |  | ||||||
| defer rc.Close() |  | ||||||
| body, err := ioutil.ReadAll(rc) |  | ||||||
| if err != nil { |  | ||||||
| 	log.Fatal(err) |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
							
								
								
									
										335
									
								
								vendor/cloud.google.com/go/storage/acl.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										335
									
								
								vendor/cloud.google.com/go/storage/acl.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,335 +0,0 @@ | |||||||
| // Copyright 2014 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| package storage |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"net/http" |  | ||||||
| 	"reflect" |  | ||||||
|  |  | ||||||
| 	"cloud.google.com/go/internal/trace" |  | ||||||
| 	"google.golang.org/api/googleapi" |  | ||||||
| 	raw "google.golang.org/api/storage/v1" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // ACLRole is the level of access to grant. |  | ||||||
| type ACLRole string |  | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	RoleOwner  ACLRole = "OWNER" |  | ||||||
| 	RoleReader ACLRole = "READER" |  | ||||||
| 	RoleWriter ACLRole = "WRITER" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // ACLEntity refers to a user or group. |  | ||||||
| // They are sometimes referred to as grantees. |  | ||||||
| // |  | ||||||
| // It could be in the form of: |  | ||||||
| // "user-<userId>", "user-<email>", "group-<groupId>", "group-<email>", |  | ||||||
| // "domain-<domain>" and "project-team-<projectId>". |  | ||||||
| // |  | ||||||
| // Or one of the predefined constants: AllUsers, AllAuthenticatedUsers. |  | ||||||
| type ACLEntity string |  | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	AllUsers              ACLEntity = "allUsers" |  | ||||||
| 	AllAuthenticatedUsers ACLEntity = "allAuthenticatedUsers" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // ACLRule represents a grant for a role to an entity (user, group or team) for a |  | ||||||
| // Google Cloud Storage object or bucket. |  | ||||||
| type ACLRule struct { |  | ||||||
| 	Entity      ACLEntity |  | ||||||
| 	EntityID    string |  | ||||||
| 	Role        ACLRole |  | ||||||
| 	Domain      string |  | ||||||
| 	Email       string |  | ||||||
| 	ProjectTeam *ProjectTeam |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ProjectTeam is the project team associated with the entity, if any. |  | ||||||
| type ProjectTeam struct { |  | ||||||
| 	ProjectNumber string |  | ||||||
| 	Team          string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ACLHandle provides operations on an access control list for a Google Cloud Storage bucket or object. |  | ||||||
| type ACLHandle struct { |  | ||||||
| 	c           *Client |  | ||||||
| 	bucket      string |  | ||||||
| 	object      string |  | ||||||
| 	isDefault   bool |  | ||||||
| 	userProject string // for requester-pays buckets |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Delete permanently deletes the ACL entry for the given entity. |  | ||||||
| func (a *ACLHandle) Delete(ctx context.Context, entity ACLEntity) (err error) { |  | ||||||
| 	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.Delete") |  | ||||||
| 	defer func() { trace.EndSpan(ctx, err) }() |  | ||||||
|  |  | ||||||
| 	if a.object != "" { |  | ||||||
| 		return a.objectDelete(ctx, entity) |  | ||||||
| 	} |  | ||||||
| 	if a.isDefault { |  | ||||||
| 		return a.bucketDefaultDelete(ctx, entity) |  | ||||||
| 	} |  | ||||||
| 	return a.bucketDelete(ctx, entity) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Set sets the role for the given entity. |  | ||||||
| func (a *ACLHandle) Set(ctx context.Context, entity ACLEntity, role ACLRole) (err error) { |  | ||||||
| 	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.Set") |  | ||||||
| 	defer func() { trace.EndSpan(ctx, err) }() |  | ||||||
|  |  | ||||||
| 	if a.object != "" { |  | ||||||
| 		return a.objectSet(ctx, entity, role, false) |  | ||||||
| 	} |  | ||||||
| 	if a.isDefault { |  | ||||||
| 		return a.objectSet(ctx, entity, role, true) |  | ||||||
| 	} |  | ||||||
| 	return a.bucketSet(ctx, entity, role) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // List retrieves ACL entries. |  | ||||||
| func (a *ACLHandle) List(ctx context.Context) (rules []ACLRule, err error) { |  | ||||||
| 	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.List") |  | ||||||
| 	defer func() { trace.EndSpan(ctx, err) }() |  | ||||||
|  |  | ||||||
| 	if a.object != "" { |  | ||||||
| 		return a.objectList(ctx) |  | ||||||
| 	} |  | ||||||
| 	if a.isDefault { |  | ||||||
| 		return a.bucketDefaultList(ctx) |  | ||||||
| 	} |  | ||||||
| 	return a.bucketList(ctx) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (a *ACLHandle) bucketDefaultList(ctx context.Context) ([]ACLRule, error) { |  | ||||||
| 	var acls *raw.ObjectAccessControls |  | ||||||
| 	var err error |  | ||||||
| 	err = runWithRetry(ctx, func() error { |  | ||||||
| 		req := a.c.raw.DefaultObjectAccessControls.List(a.bucket) |  | ||||||
| 		a.configureCall(ctx, req) |  | ||||||
| 		acls, err = req.Do() |  | ||||||
| 		return err |  | ||||||
| 	}) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return toObjectACLRules(acls.Items), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (a *ACLHandle) bucketDefaultDelete(ctx context.Context, entity ACLEntity) error { |  | ||||||
| 	return runWithRetry(ctx, func() error { |  | ||||||
| 		req := a.c.raw.DefaultObjectAccessControls.Delete(a.bucket, string(entity)) |  | ||||||
| 		a.configureCall(ctx, req) |  | ||||||
| 		return req.Do() |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (a *ACLHandle) bucketList(ctx context.Context) ([]ACLRule, error) { |  | ||||||
| 	var acls *raw.BucketAccessControls |  | ||||||
| 	var err error |  | ||||||
| 	err = runWithRetry(ctx, func() error { |  | ||||||
| 		req := a.c.raw.BucketAccessControls.List(a.bucket) |  | ||||||
| 		a.configureCall(ctx, req) |  | ||||||
| 		acls, err = req.Do() |  | ||||||
| 		return err |  | ||||||
| 	}) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return toBucketACLRules(acls.Items), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (a *ACLHandle) bucketSet(ctx context.Context, entity ACLEntity, role ACLRole) error { |  | ||||||
| 	acl := &raw.BucketAccessControl{ |  | ||||||
| 		Bucket: a.bucket, |  | ||||||
| 		Entity: string(entity), |  | ||||||
| 		Role:   string(role), |  | ||||||
| 	} |  | ||||||
| 	err := runWithRetry(ctx, func() error { |  | ||||||
| 		req := a.c.raw.BucketAccessControls.Update(a.bucket, string(entity), acl) |  | ||||||
| 		a.configureCall(ctx, req) |  | ||||||
| 		_, err := req.Do() |  | ||||||
| 		return err |  | ||||||
| 	}) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (a *ACLHandle) bucketDelete(ctx context.Context, entity ACLEntity) error { |  | ||||||
| 	return runWithRetry(ctx, func() error { |  | ||||||
| 		req := a.c.raw.BucketAccessControls.Delete(a.bucket, string(entity)) |  | ||||||
| 		a.configureCall(ctx, req) |  | ||||||
| 		return req.Do() |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (a *ACLHandle) objectList(ctx context.Context) ([]ACLRule, error) { |  | ||||||
| 	var acls *raw.ObjectAccessControls |  | ||||||
| 	var err error |  | ||||||
| 	err = runWithRetry(ctx, func() error { |  | ||||||
| 		req := a.c.raw.ObjectAccessControls.List(a.bucket, a.object) |  | ||||||
| 		a.configureCall(ctx, req) |  | ||||||
| 		acls, err = req.Do() |  | ||||||
| 		return err |  | ||||||
| 	}) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return toObjectACLRules(acls.Items), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (a *ACLHandle) objectSet(ctx context.Context, entity ACLEntity, role ACLRole, isBucketDefault bool) error { |  | ||||||
| 	type setRequest interface { |  | ||||||
| 		Do(opts ...googleapi.CallOption) (*raw.ObjectAccessControl, error) |  | ||||||
| 		Header() http.Header |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	acl := &raw.ObjectAccessControl{ |  | ||||||
| 		Bucket: a.bucket, |  | ||||||
| 		Entity: string(entity), |  | ||||||
| 		Role:   string(role), |  | ||||||
| 	} |  | ||||||
| 	var req setRequest |  | ||||||
| 	if isBucketDefault { |  | ||||||
| 		req = a.c.raw.DefaultObjectAccessControls.Update(a.bucket, string(entity), acl) |  | ||||||
| 	} else { |  | ||||||
| 		req = a.c.raw.ObjectAccessControls.Update(a.bucket, a.object, string(entity), acl) |  | ||||||
| 	} |  | ||||||
| 	a.configureCall(ctx, req) |  | ||||||
| 	return runWithRetry(ctx, func() error { |  | ||||||
| 		_, err := req.Do() |  | ||||||
| 		return err |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (a *ACLHandle) objectDelete(ctx context.Context, entity ACLEntity) error { |  | ||||||
| 	return runWithRetry(ctx, func() error { |  | ||||||
| 		req := a.c.raw.ObjectAccessControls.Delete(a.bucket, a.object, string(entity)) |  | ||||||
| 		a.configureCall(ctx, req) |  | ||||||
| 		return req.Do() |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (a *ACLHandle) configureCall(ctx context.Context, call interface{ Header() http.Header }) { |  | ||||||
| 	vc := reflect.ValueOf(call) |  | ||||||
| 	vc.MethodByName("Context").Call([]reflect.Value{reflect.ValueOf(ctx)}) |  | ||||||
| 	if a.userProject != "" { |  | ||||||
| 		vc.MethodByName("UserProject").Call([]reflect.Value{reflect.ValueOf(a.userProject)}) |  | ||||||
| 	} |  | ||||||
| 	setClientHeader(call.Header()) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func toObjectACLRules(items []*raw.ObjectAccessControl) []ACLRule { |  | ||||||
| 	var rs []ACLRule |  | ||||||
| 	for _, item := range items { |  | ||||||
| 		rs = append(rs, toObjectACLRule(item)) |  | ||||||
| 	} |  | ||||||
| 	return rs |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func toBucketACLRules(items []*raw.BucketAccessControl) []ACLRule { |  | ||||||
| 	var rs []ACLRule |  | ||||||
| 	for _, item := range items { |  | ||||||
| 		rs = append(rs, toBucketACLRule(item)) |  | ||||||
| 	} |  | ||||||
| 	return rs |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func toObjectACLRule(a *raw.ObjectAccessControl) ACLRule { |  | ||||||
| 	return ACLRule{ |  | ||||||
| 		Entity:      ACLEntity(a.Entity), |  | ||||||
| 		EntityID:    a.EntityId, |  | ||||||
| 		Role:        ACLRole(a.Role), |  | ||||||
| 		Domain:      a.Domain, |  | ||||||
| 		Email:       a.Email, |  | ||||||
| 		ProjectTeam: toObjectProjectTeam(a.ProjectTeam), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func toBucketACLRule(a *raw.BucketAccessControl) ACLRule { |  | ||||||
| 	return ACLRule{ |  | ||||||
| 		Entity:      ACLEntity(a.Entity), |  | ||||||
| 		EntityID:    a.EntityId, |  | ||||||
| 		Role:        ACLRole(a.Role), |  | ||||||
| 		Domain:      a.Domain, |  | ||||||
| 		Email:       a.Email, |  | ||||||
| 		ProjectTeam: toBucketProjectTeam(a.ProjectTeam), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func toRawObjectACL(rules []ACLRule) []*raw.ObjectAccessControl { |  | ||||||
| 	if len(rules) == 0 { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	r := make([]*raw.ObjectAccessControl, 0, len(rules)) |  | ||||||
| 	for _, rule := range rules { |  | ||||||
| 		r = append(r, rule.toRawObjectAccessControl("")) // bucket name unnecessary |  | ||||||
| 	} |  | ||||||
| 	return r |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func toRawBucketACL(rules []ACLRule) []*raw.BucketAccessControl { |  | ||||||
| 	if len(rules) == 0 { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	r := make([]*raw.BucketAccessControl, 0, len(rules)) |  | ||||||
| 	for _, rule := range rules { |  | ||||||
| 		r = append(r, rule.toRawBucketAccessControl("")) // bucket name unnecessary |  | ||||||
| 	} |  | ||||||
| 	return r |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r ACLRule) toRawBucketAccessControl(bucket string) *raw.BucketAccessControl { |  | ||||||
| 	return &raw.BucketAccessControl{ |  | ||||||
| 		Bucket: bucket, |  | ||||||
| 		Entity: string(r.Entity), |  | ||||||
| 		Role:   string(r.Role), |  | ||||||
| 		// The other fields are not settable. |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r ACLRule) toRawObjectAccessControl(bucket string) *raw.ObjectAccessControl { |  | ||||||
| 	return &raw.ObjectAccessControl{ |  | ||||||
| 		Bucket: bucket, |  | ||||||
| 		Entity: string(r.Entity), |  | ||||||
| 		Role:   string(r.Role), |  | ||||||
| 		// The other fields are not settable. |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func toBucketProjectTeam(p *raw.BucketAccessControlProjectTeam) *ProjectTeam { |  | ||||||
| 	if p == nil { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	return &ProjectTeam{ |  | ||||||
| 		ProjectNumber: p.ProjectNumber, |  | ||||||
| 		Team:          p.Team, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func toObjectProjectTeam(p *raw.ObjectAccessControlProjectTeam) *ProjectTeam { |  | ||||||
| 	if p == nil { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	return &ProjectTeam{ |  | ||||||
| 		ProjectNumber: p.ProjectNumber, |  | ||||||
| 		Team:          p.Team, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
							
								
								
									
										1195
									
								
								vendor/cloud.google.com/go/storage/bucket.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1195
									
								
								vendor/cloud.google.com/go/storage/bucket.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										228
									
								
								vendor/cloud.google.com/go/storage/copy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										228
									
								
								vendor/cloud.google.com/go/storage/copy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,228 +0,0 @@ | |||||||
| // Copyright 2016 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| package storage |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
|  |  | ||||||
| 	"cloud.google.com/go/internal/trace" |  | ||||||
| 	raw "google.golang.org/api/storage/v1" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // CopierFrom creates a Copier that can copy src to dst. |  | ||||||
| // You can immediately call Run on the returned Copier, or |  | ||||||
| // you can configure it first. |  | ||||||
| // |  | ||||||
| // For Requester Pays buckets, the user project of dst is billed, unless it is empty, |  | ||||||
| // in which case the user project of src is billed. |  | ||||||
| func (dst *ObjectHandle) CopierFrom(src *ObjectHandle) *Copier { |  | ||||||
| 	return &Copier{dst: dst, src: src} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // A Copier copies a source object to a destination. |  | ||||||
| type Copier struct { |  | ||||||
| 	// ObjectAttrs are optional attributes to set on the destination object. |  | ||||||
| 	// Any attributes must be initialized before any calls on the Copier. Nil |  | ||||||
| 	// or zero-valued attributes are ignored. |  | ||||||
| 	ObjectAttrs |  | ||||||
|  |  | ||||||
| 	// RewriteToken can be set before calling Run to resume a copy |  | ||||||
| 	// operation. After Run returns a non-nil error, RewriteToken will |  | ||||||
| 	// have been updated to contain the value needed to resume the copy. |  | ||||||
| 	RewriteToken string |  | ||||||
|  |  | ||||||
| 	// ProgressFunc can be used to monitor the progress of a multi-RPC copy |  | ||||||
| 	// operation. If ProgressFunc is not nil and copying requires multiple |  | ||||||
| 	// calls to the underlying service (see |  | ||||||
| 	// https://cloud.google.com/storage/docs/json_api/v1/objects/rewrite), then |  | ||||||
| 	// ProgressFunc will be invoked after each call with the number of bytes of |  | ||||||
| 	// content copied so far and the total size in bytes of the source object. |  | ||||||
| 	// |  | ||||||
| 	// ProgressFunc is intended to make upload progress available to the |  | ||||||
| 	// application. For example, the implementation of ProgressFunc may update |  | ||||||
| 	// a progress bar in the application's UI, or log the result of |  | ||||||
| 	// float64(copiedBytes)/float64(totalBytes). |  | ||||||
| 	// |  | ||||||
| 	// ProgressFunc should return quickly without blocking. |  | ||||||
| 	ProgressFunc func(copiedBytes, totalBytes uint64) |  | ||||||
|  |  | ||||||
| 	// The Cloud KMS key, in the form projects/P/locations/L/keyRings/R/cryptoKeys/K, |  | ||||||
| 	// that will be used to encrypt the object. Overrides the object's KMSKeyName, if |  | ||||||
| 	// any. |  | ||||||
| 	// |  | ||||||
| 	// Providing both a DestinationKMSKeyName and a customer-supplied encryption key |  | ||||||
| 	// (via ObjectHandle.Key) on the destination object will result in an error when |  | ||||||
| 	// Run is called. |  | ||||||
| 	DestinationKMSKeyName string |  | ||||||
|  |  | ||||||
| 	dst, src *ObjectHandle |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Run performs the copy. |  | ||||||
| func (c *Copier) Run(ctx context.Context) (attrs *ObjectAttrs, err error) { |  | ||||||
| 	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Copier.Run") |  | ||||||
| 	defer func() { trace.EndSpan(ctx, err) }() |  | ||||||
|  |  | ||||||
| 	if err := c.src.validate(); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	if err := c.dst.validate(); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	if c.DestinationKMSKeyName != "" && c.dst.encryptionKey != nil { |  | ||||||
| 		return nil, errors.New("storage: cannot use DestinationKMSKeyName with a customer-supplied encryption key") |  | ||||||
| 	} |  | ||||||
| 	// Convert destination attributes to raw form, omitting the bucket. |  | ||||||
| 	// If the bucket is included but name or content-type aren't, the service |  | ||||||
| 	// returns a 400 with "Required" as the only message. Omitting the bucket |  | ||||||
| 	// does not cause any problems. |  | ||||||
| 	rawObject := c.ObjectAttrs.toRawObject("") |  | ||||||
| 	for { |  | ||||||
| 		res, err := c.callRewrite(ctx, rawObject) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		if c.ProgressFunc != nil { |  | ||||||
| 			c.ProgressFunc(uint64(res.TotalBytesRewritten), uint64(res.ObjectSize)) |  | ||||||
| 		} |  | ||||||
| 		if res.Done { // Finished successfully. |  | ||||||
| 			return newObject(res.Resource), nil |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Copier) callRewrite(ctx context.Context, rawObj *raw.Object) (*raw.RewriteResponse, error) { |  | ||||||
| 	call := c.dst.c.raw.Objects.Rewrite(c.src.bucket, c.src.object, c.dst.bucket, c.dst.object, rawObj) |  | ||||||
|  |  | ||||||
| 	call.Context(ctx).Projection("full") |  | ||||||
| 	if c.RewriteToken != "" { |  | ||||||
| 		call.RewriteToken(c.RewriteToken) |  | ||||||
| 	} |  | ||||||
| 	if c.DestinationKMSKeyName != "" { |  | ||||||
| 		call.DestinationKmsKeyName(c.DestinationKMSKeyName) |  | ||||||
| 	} |  | ||||||
| 	if c.PredefinedACL != "" { |  | ||||||
| 		call.DestinationPredefinedAcl(c.PredefinedACL) |  | ||||||
| 	} |  | ||||||
| 	if err := applyConds("Copy destination", c.dst.gen, c.dst.conds, call); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	if c.dst.userProject != "" { |  | ||||||
| 		call.UserProject(c.dst.userProject) |  | ||||||
| 	} else if c.src.userProject != "" { |  | ||||||
| 		call.UserProject(c.src.userProject) |  | ||||||
| 	} |  | ||||||
| 	if err := applySourceConds(c.src.gen, c.src.conds, call); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	if err := setEncryptionHeaders(call.Header(), c.dst.encryptionKey, false); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	if err := setEncryptionHeaders(call.Header(), c.src.encryptionKey, true); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	var res *raw.RewriteResponse |  | ||||||
| 	var err error |  | ||||||
| 	setClientHeader(call.Header()) |  | ||||||
| 	err = runWithRetry(ctx, func() error { res, err = call.Do(); return err }) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	c.RewriteToken = res.RewriteToken |  | ||||||
| 	return res, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ComposerFrom creates a Composer that can compose srcs into dst. |  | ||||||
| // You can immediately call Run on the returned Composer, or you can |  | ||||||
| // configure it first. |  | ||||||
| // |  | ||||||
| // The encryption key for the destination object will be used to decrypt all |  | ||||||
| // source objects and encrypt the destination object. It is an error |  | ||||||
| // to specify an encryption key for any of the source objects. |  | ||||||
| func (dst *ObjectHandle) ComposerFrom(srcs ...*ObjectHandle) *Composer { |  | ||||||
| 	return &Composer{dst: dst, srcs: srcs} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // A Composer composes source objects into a destination object. |  | ||||||
| // |  | ||||||
| // For Requester Pays buckets, the user project of dst is billed. |  | ||||||
| type Composer struct { |  | ||||||
| 	// ObjectAttrs are optional attributes to set on the destination object. |  | ||||||
| 	// Any attributes must be initialized before any calls on the Composer. Nil |  | ||||||
| 	// or zero-valued attributes are ignored. |  | ||||||
| 	ObjectAttrs |  | ||||||
|  |  | ||||||
| 	dst  *ObjectHandle |  | ||||||
| 	srcs []*ObjectHandle |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Run performs the compose operation. |  | ||||||
| func (c *Composer) Run(ctx context.Context) (attrs *ObjectAttrs, err error) { |  | ||||||
| 	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Composer.Run") |  | ||||||
| 	defer func() { trace.EndSpan(ctx, err) }() |  | ||||||
|  |  | ||||||
| 	if err := c.dst.validate(); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	if len(c.srcs) == 0 { |  | ||||||
| 		return nil, errors.New("storage: at least one source object must be specified") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	req := &raw.ComposeRequest{} |  | ||||||
| 	// Compose requires a non-empty Destination, so we always set it, |  | ||||||
| 	// even if the caller-provided ObjectAttrs is the zero value. |  | ||||||
| 	req.Destination = c.ObjectAttrs.toRawObject(c.dst.bucket) |  | ||||||
| 	for _, src := range c.srcs { |  | ||||||
| 		if err := src.validate(); err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		if src.bucket != c.dst.bucket { |  | ||||||
| 			return nil, fmt.Errorf("storage: all source objects must be in bucket %q, found %q", c.dst.bucket, src.bucket) |  | ||||||
| 		} |  | ||||||
| 		if src.encryptionKey != nil { |  | ||||||
| 			return nil, fmt.Errorf("storage: compose source %s.%s must not have encryption key", src.bucket, src.object) |  | ||||||
| 		} |  | ||||||
| 		srcObj := &raw.ComposeRequestSourceObjects{ |  | ||||||
| 			Name: src.object, |  | ||||||
| 		} |  | ||||||
| 		if err := applyConds("ComposeFrom source", src.gen, src.conds, composeSourceObj{srcObj}); err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		req.SourceObjects = append(req.SourceObjects, srcObj) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	call := c.dst.c.raw.Objects.Compose(c.dst.bucket, c.dst.object, req).Context(ctx) |  | ||||||
| 	if err := applyConds("ComposeFrom destination", c.dst.gen, c.dst.conds, call); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	if c.dst.userProject != "" { |  | ||||||
| 		call.UserProject(c.dst.userProject) |  | ||||||
| 	} |  | ||||||
| 	if c.PredefinedACL != "" { |  | ||||||
| 		call.DestinationPredefinedAcl(c.PredefinedACL) |  | ||||||
| 	} |  | ||||||
| 	if err := setEncryptionHeaders(call.Header(), c.dst.encryptionKey, false); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	var obj *raw.Object |  | ||||||
| 	setClientHeader(call.Header()) |  | ||||||
| 	err = runWithRetry(ctx, func() error { obj, err = call.Do(); return err }) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return newObject(obj), nil |  | ||||||
| } |  | ||||||
							
								
								
									
										176
									
								
								vendor/cloud.google.com/go/storage/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										176
									
								
								vendor/cloud.google.com/go/storage/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,176 +0,0 @@ | |||||||
| // Copyright 2016 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| /* |  | ||||||
| Package storage provides an easy way to work with Google Cloud Storage. |  | ||||||
| Google Cloud Storage stores data in named objects, which are grouped into buckets. |  | ||||||
|  |  | ||||||
| More information about Google Cloud Storage is available at |  | ||||||
| https://cloud.google.com/storage/docs. |  | ||||||
|  |  | ||||||
| See https://godoc.org/cloud.google.com/go for authentication, timeouts, |  | ||||||
| connection pooling and similar aspects of this package. |  | ||||||
|  |  | ||||||
| All of the methods of this package use exponential backoff to retry calls that fail |  | ||||||
| with certain errors, as described in |  | ||||||
| https://cloud.google.com/storage/docs/exponential-backoff. Retrying continues |  | ||||||
| indefinitely unless the controlling context is canceled or the client is closed. See |  | ||||||
| context.WithTimeout and context.WithCancel. |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Creating a Client |  | ||||||
|  |  | ||||||
| To start working with this package, create a client: |  | ||||||
|  |  | ||||||
|     ctx := context.Background() |  | ||||||
|     client, err := storage.NewClient(ctx) |  | ||||||
|     if err != nil { |  | ||||||
|         // TODO: Handle error. |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| The client will use your default application credentials. |  | ||||||
|  |  | ||||||
| If you only wish to access public data, you can create |  | ||||||
| an unauthenticated client with |  | ||||||
|  |  | ||||||
|     client, err := storage.NewClient(ctx, option.WithoutAuthentication()) |  | ||||||
|  |  | ||||||
| Buckets |  | ||||||
|  |  | ||||||
| A Google Cloud Storage bucket is a collection of objects. To work with a |  | ||||||
| bucket, make a bucket handle: |  | ||||||
|  |  | ||||||
|     bkt := client.Bucket(bucketName) |  | ||||||
|  |  | ||||||
| A handle is a reference to a bucket. You can have a handle even if the |  | ||||||
| bucket doesn't exist yet. To create a bucket in Google Cloud Storage, |  | ||||||
| call Create on the handle: |  | ||||||
|  |  | ||||||
|     if err := bkt.Create(ctx, projectID, nil); err != nil { |  | ||||||
|         // TODO: Handle error. |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| Note that although buckets are associated with projects, bucket names are |  | ||||||
| global across all projects. |  | ||||||
|  |  | ||||||
| Each bucket has associated metadata, represented in this package by |  | ||||||
| BucketAttrs. The third argument to BucketHandle.Create allows you to set |  | ||||||
| the initial BucketAttrs of a bucket. To retrieve a bucket's attributes, use |  | ||||||
| Attrs: |  | ||||||
|  |  | ||||||
|     attrs, err := bkt.Attrs(ctx) |  | ||||||
|     if err != nil { |  | ||||||
|         // TODO: Handle error. |  | ||||||
|     } |  | ||||||
|     fmt.Printf("bucket %s, created at %s, is located in %s with storage class %s\n", |  | ||||||
|         attrs.Name, attrs.Created, attrs.Location, attrs.StorageClass) |  | ||||||
|  |  | ||||||
| Objects |  | ||||||
|  |  | ||||||
| An object holds arbitrary data as a sequence of bytes, like a file. You |  | ||||||
| refer to objects using a handle, just as with buckets, but unlike buckets |  | ||||||
| you don't explicitly create an object. Instead, the first time you write |  | ||||||
| to an object it will be created. You can use the standard Go io.Reader |  | ||||||
| and io.Writer interfaces to read and write object data: |  | ||||||
|  |  | ||||||
|     obj := bkt.Object("data") |  | ||||||
|     // Write something to obj. |  | ||||||
|     // w implements io.Writer. |  | ||||||
|     w := obj.NewWriter(ctx) |  | ||||||
|     // Write some text to obj. This will either create the object or overwrite whatever is there already. |  | ||||||
|     if _, err := fmt.Fprintf(w, "This object contains text.\n"); err != nil { |  | ||||||
|         // TODO: Handle error. |  | ||||||
|     } |  | ||||||
|     // Close, just like writing a file. |  | ||||||
|     if err := w.Close(); err != nil { |  | ||||||
|         // TODO: Handle error. |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Read it back. |  | ||||||
|     r, err := obj.NewReader(ctx) |  | ||||||
|     if err != nil { |  | ||||||
|         // TODO: Handle error. |  | ||||||
|     } |  | ||||||
|     defer r.Close() |  | ||||||
|     if _, err := io.Copy(os.Stdout, r); err != nil { |  | ||||||
|         // TODO: Handle error. |  | ||||||
|     } |  | ||||||
|     // Prints "This object contains text." |  | ||||||
|  |  | ||||||
| Objects also have attributes, which you can fetch with Attrs: |  | ||||||
|  |  | ||||||
|     objAttrs, err := obj.Attrs(ctx) |  | ||||||
|     if err != nil { |  | ||||||
|         // TODO: Handle error. |  | ||||||
|     } |  | ||||||
|     fmt.Printf("object %s has size %d and can be read using %s\n", |  | ||||||
|         objAttrs.Name, objAttrs.Size, objAttrs.MediaLink) |  | ||||||
|  |  | ||||||
| ACLs |  | ||||||
|  |  | ||||||
| Both objects and buckets have ACLs (Access Control Lists). An ACL is a list of |  | ||||||
| ACLRules, each of which specifies the role of a user, group or project. ACLs |  | ||||||
| are suitable for fine-grained control, but you may prefer using IAM to control |  | ||||||
| access at the project level (see |  | ||||||
| https://cloud.google.com/storage/docs/access-control/iam). |  | ||||||
|  |  | ||||||
| To list the ACLs of a bucket or object, obtain an ACLHandle and call its List method: |  | ||||||
|  |  | ||||||
|     acls, err := obj.ACL().List(ctx) |  | ||||||
|     if err != nil { |  | ||||||
|         // TODO: Handle error. |  | ||||||
|     } |  | ||||||
|     for _, rule := range acls { |  | ||||||
|         fmt.Printf("%s has role %s\n", rule.Entity, rule.Role) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| You can also set and delete ACLs. |  | ||||||
|  |  | ||||||
| Conditions |  | ||||||
|  |  | ||||||
| Every object has a generation and a metageneration. The generation changes |  | ||||||
| whenever the content changes, and the metageneration changes whenever the |  | ||||||
| metadata changes. Conditions let you check these values before an operation; |  | ||||||
| the operation only executes if the conditions match. You can use conditions to |  | ||||||
| prevent race conditions in read-modify-write operations. |  | ||||||
|  |  | ||||||
| For example, say you've read an object's metadata into objAttrs. Now |  | ||||||
| you want to write to that object, but only if its contents haven't changed |  | ||||||
| since you read it. Here is how to express that: |  | ||||||
|  |  | ||||||
|     w = obj.If(storage.Conditions{GenerationMatch: objAttrs.Generation}).NewWriter(ctx) |  | ||||||
|     // Proceed with writing as above. |  | ||||||
|  |  | ||||||
| Signed URLs |  | ||||||
|  |  | ||||||
| You can obtain a URL that lets anyone read or write an object for a limited time. |  | ||||||
| You don't need to create a client to do this. See the documentation of |  | ||||||
| SignedURL for details. |  | ||||||
|  |  | ||||||
|     url, err := storage.SignedURL(bucketName, "shared-object", opts) |  | ||||||
|     if err != nil { |  | ||||||
|         // TODO: Handle error. |  | ||||||
|     } |  | ||||||
|     fmt.Println(url) |  | ||||||
|  |  | ||||||
| Errors |  | ||||||
|  |  | ||||||
| Errors returned by this client are often of the type [`googleapi.Error`](https://godoc.org/google.golang.org/api/googleapi#Error). |  | ||||||
| These errors can be introspected for more information by type asserting to the richer `googleapi.Error` type. For example: |  | ||||||
|  |  | ||||||
| 	if e, ok := err.(*googleapi.Error); ok { |  | ||||||
| 		  if e.Code == 409 { ... } |  | ||||||
| 	} |  | ||||||
| */ |  | ||||||
| package storage // import "cloud.google.com/go/storage" |  | ||||||
							
								
								
									
										32
									
								
								vendor/cloud.google.com/go/storage/go110.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/cloud.google.com/go/storage/go110.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,32 +0,0 @@ | |||||||
| // Copyright 2017 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| // +build go1.10 |  | ||||||
|  |  | ||||||
| package storage |  | ||||||
|  |  | ||||||
| import "google.golang.org/api/googleapi" |  | ||||||
|  |  | ||||||
| func shouldRetry(err error) bool { |  | ||||||
| 	switch e := err.(type) { |  | ||||||
| 	case *googleapi.Error: |  | ||||||
| 		// Retry on 429 and 5xx, according to |  | ||||||
| 		// https://cloud.google.com/storage/docs/exponential-backoff. |  | ||||||
| 		return e.Code == 429 || (e.Code >= 500 && e.Code < 600) |  | ||||||
| 	case interface{ Temporary() bool }: |  | ||||||
| 		return e.Temporary() |  | ||||||
| 	default: |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
							
								
								
									
										330
									
								
								vendor/cloud.google.com/go/storage/hmac.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										330
									
								
								vendor/cloud.google.com/go/storage/hmac.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,330 +0,0 @@ | |||||||
| // Copyright 2019 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| package storage |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"google.golang.org/api/iterator" |  | ||||||
| 	raw "google.golang.org/api/storage/v1" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // HMACState is the state of the HMAC key. |  | ||||||
| type HMACState string |  | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	// Active is the status for an active key that can be used to sign |  | ||||||
| 	// requests. |  | ||||||
| 	Active HMACState = "ACTIVE" |  | ||||||
|  |  | ||||||
| 	// Inactive is the status for an inactive key thus requests signed by |  | ||||||
| 	// this key will be denied. |  | ||||||
| 	Inactive HMACState = "INACTIVE" |  | ||||||
|  |  | ||||||
| 	// Deleted is the status for a key that is deleted. |  | ||||||
| 	// Once in this state the key cannot key cannot be recovered |  | ||||||
| 	// and does not count towards key limits. Deleted keys will be cleaned |  | ||||||
| 	// up later. |  | ||||||
| 	Deleted HMACState = "DELETED" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // HMACKey is the representation of a Google Cloud Storage HMAC key. |  | ||||||
| // |  | ||||||
| // HMAC keys are used to authenticate signed access to objects. To enable HMAC key |  | ||||||
| // authentication, please visit https://cloud.google.com/storage/docs/migrating. |  | ||||||
| // |  | ||||||
| // This type is EXPERIMENTAL and subject to change or removal without notice. |  | ||||||
| type HMACKey struct { |  | ||||||
| 	// The HMAC's secret key. |  | ||||||
| 	Secret string |  | ||||||
|  |  | ||||||
| 	// AccessID is the ID of the HMAC key. |  | ||||||
| 	AccessID string |  | ||||||
|  |  | ||||||
| 	// Etag is the HTTP/1.1 Entity tag. |  | ||||||
| 	Etag string |  | ||||||
|  |  | ||||||
| 	// ID is the ID of the HMAC key, including the ProjectID and AccessID. |  | ||||||
| 	ID string |  | ||||||
|  |  | ||||||
| 	// ProjectID is the ID of the project that owns the |  | ||||||
| 	// service account to which the key authenticates. |  | ||||||
| 	ProjectID string |  | ||||||
|  |  | ||||||
| 	// ServiceAccountEmail is the email address |  | ||||||
| 	// of the key's associated service account. |  | ||||||
| 	ServiceAccountEmail string |  | ||||||
|  |  | ||||||
| 	// CreatedTime is the creation time of the HMAC key. |  | ||||||
| 	CreatedTime time.Time |  | ||||||
|  |  | ||||||
| 	// UpdatedTime is the last modification time of the HMAC key metadata. |  | ||||||
| 	UpdatedTime time.Time |  | ||||||
|  |  | ||||||
| 	// State is the state of the HMAC key. |  | ||||||
| 	// It can be one of StateActive, StateInactive or StateDeleted. |  | ||||||
| 	State HMACState |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // HMACKeyHandle helps provide access and management for HMAC keys. |  | ||||||
| // |  | ||||||
| // This type is EXPERIMENTAL and subject to change or removal without notice. |  | ||||||
| type HMACKeyHandle struct { |  | ||||||
| 	projectID string |  | ||||||
| 	accessID  string |  | ||||||
|  |  | ||||||
| 	raw *raw.ProjectsHmacKeysService |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // HMACKeyHandle creates a handle that will be used for HMACKey operations. |  | ||||||
| // |  | ||||||
| // This method is EXPERIMENTAL and subject to change or removal without notice. |  | ||||||
| func (c *Client) HMACKeyHandle(projectID, accessID string) *HMACKeyHandle { |  | ||||||
| 	return &HMACKeyHandle{ |  | ||||||
| 		projectID: projectID, |  | ||||||
| 		accessID:  accessID, |  | ||||||
| 		raw:       raw.NewProjectsHmacKeysService(c.raw), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Get invokes an RPC to retrieve the HMAC key referenced by the |  | ||||||
| // HMACKeyHandle's accessID. |  | ||||||
| // |  | ||||||
| // This method is EXPERIMENTAL and subject to change or removal without notice. |  | ||||||
| func (hkh *HMACKeyHandle) Get(ctx context.Context) (*HMACKey, error) { |  | ||||||
| 	call := hkh.raw.Get(hkh.projectID, hkh.accessID) |  | ||||||
| 	setClientHeader(call.Header()) |  | ||||||
|  |  | ||||||
| 	var metadata *raw.HmacKeyMetadata |  | ||||||
| 	var err error |  | ||||||
| 	err = runWithRetry(ctx, func() error { |  | ||||||
| 		metadata, err = call.Context(ctx).Do() |  | ||||||
| 		return err |  | ||||||
| 	}) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	hkPb := &raw.HmacKey{ |  | ||||||
| 		Metadata: metadata, |  | ||||||
| 	} |  | ||||||
| 	return pbHmacKeyToHMACKey(hkPb, false) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Delete invokes an RPC to delete the key referenced by accessID, on Google Cloud Storage. |  | ||||||
| // Only inactive HMAC keys can be deleted. |  | ||||||
| // After deletion, a key cannot be used to authenticate requests. |  | ||||||
| // |  | ||||||
| // This method is EXPERIMENTAL and subject to change or removal without notice. |  | ||||||
| func (hkh *HMACKeyHandle) Delete(ctx context.Context) error { |  | ||||||
| 	delCall := hkh.raw.Delete(hkh.projectID, hkh.accessID) |  | ||||||
| 	setClientHeader(delCall.Header()) |  | ||||||
|  |  | ||||||
| 	return runWithRetry(ctx, func() error { |  | ||||||
| 		return delCall.Context(ctx).Do() |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func pbHmacKeyToHMACKey(pb *raw.HmacKey, updatedTimeCanBeNil bool) (*HMACKey, error) { |  | ||||||
| 	pbmd := pb.Metadata |  | ||||||
| 	if pbmd == nil { |  | ||||||
| 		return nil, errors.New("field Metadata cannot be nil") |  | ||||||
| 	} |  | ||||||
| 	createdTime, err := time.Parse(time.RFC3339, pbmd.TimeCreated) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, fmt.Errorf("field CreatedTime: %v", err) |  | ||||||
| 	} |  | ||||||
| 	updatedTime, err := time.Parse(time.RFC3339, pbmd.Updated) |  | ||||||
| 	if err != nil && !updatedTimeCanBeNil { |  | ||||||
| 		return nil, fmt.Errorf("field UpdatedTime: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	hmk := &HMACKey{ |  | ||||||
| 		AccessID:    pbmd.AccessId, |  | ||||||
| 		Secret:      pb.Secret, |  | ||||||
| 		Etag:        pbmd.Etag, |  | ||||||
| 		ID:          pbmd.Id, |  | ||||||
| 		State:       HMACState(pbmd.State), |  | ||||||
| 		ProjectID:   pbmd.ProjectId, |  | ||||||
| 		CreatedTime: createdTime, |  | ||||||
| 		UpdatedTime: updatedTime, |  | ||||||
|  |  | ||||||
| 		ServiceAccountEmail: pbmd.ServiceAccountEmail, |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return hmk, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // CreateHMACKey invokes an RPC for Google Cloud Storage to create a new HMACKey. |  | ||||||
| // |  | ||||||
| // This method is EXPERIMENTAL and subject to change or removal without notice. |  | ||||||
| func (c *Client) CreateHMACKey(ctx context.Context, projectID, serviceAccountEmail string) (*HMACKey, error) { |  | ||||||
| 	if projectID == "" { |  | ||||||
| 		return nil, errors.New("storage: expecting a non-blank projectID") |  | ||||||
| 	} |  | ||||||
| 	if serviceAccountEmail == "" { |  | ||||||
| 		return nil, errors.New("storage: expecting a non-blank service account email") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	svc := raw.NewProjectsHmacKeysService(c.raw) |  | ||||||
| 	call := svc.Create(projectID, serviceAccountEmail) |  | ||||||
| 	setClientHeader(call.Header()) |  | ||||||
|  |  | ||||||
| 	var hkPb *raw.HmacKey |  | ||||||
| 	var err error |  | ||||||
| 	err = runWithRetry(ctx, func() error { |  | ||||||
| 		hkPb, err = call.Context(ctx).Do() |  | ||||||
| 		return err |  | ||||||
| 	}) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return pbHmacKeyToHMACKey(hkPb, true) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // HMACKeyAttrsToUpdate defines the attributes of an HMACKey that will be updated. |  | ||||||
| // |  | ||||||
| // This type is EXPERIMENTAL and subject to change or removal without notice. |  | ||||||
| type HMACKeyAttrsToUpdate struct { |  | ||||||
| 	// State is required and must be either StateActive or StateInactive. |  | ||||||
| 	State HMACState |  | ||||||
|  |  | ||||||
| 	// Etag is an optional field and it is the HTTP/1.1 Entity tag. |  | ||||||
| 	Etag string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Update mutates the HMACKey referred to by accessID. |  | ||||||
| // |  | ||||||
| // This method is EXPERIMENTAL and subject to change or removal without notice. |  | ||||||
| func (h *HMACKeyHandle) Update(ctx context.Context, au HMACKeyAttrsToUpdate) (*HMACKey, error) { |  | ||||||
| 	if au.State != Active && au.State != Inactive { |  | ||||||
| 		return nil, fmt.Errorf("storage: invalid state %q for update, must be either %q or %q", au.State, Active, Inactive) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	call := h.raw.Update(h.projectID, h.accessID, &raw.HmacKeyMetadata{ |  | ||||||
| 		Etag:  au.Etag, |  | ||||||
| 		State: string(au.State), |  | ||||||
| 	}) |  | ||||||
| 	setClientHeader(call.Header()) |  | ||||||
|  |  | ||||||
| 	var metadata *raw.HmacKeyMetadata |  | ||||||
| 	var err error |  | ||||||
| 	err = runWithRetry(ctx, func() error { |  | ||||||
| 		metadata, err = call.Context(ctx).Do() |  | ||||||
| 		return err |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	hkPb := &raw.HmacKey{ |  | ||||||
| 		Metadata: metadata, |  | ||||||
| 	} |  | ||||||
| 	return pbHmacKeyToHMACKey(hkPb, false) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // An HMACKeysIterator is an iterator over HMACKeys. |  | ||||||
| // |  | ||||||
| // This type is EXPERIMENTAL and subject to change or removal without notice. |  | ||||||
| type HMACKeysIterator struct { |  | ||||||
| 	ctx       context.Context |  | ||||||
| 	raw       *raw.ProjectsHmacKeysService |  | ||||||
| 	projectID string |  | ||||||
| 	hmacKeys  []*HMACKey |  | ||||||
| 	pageInfo  *iterator.PageInfo |  | ||||||
| 	nextFunc  func() error |  | ||||||
| 	index     int |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ListHMACKeys returns an iterator for listing HMACKeys. |  | ||||||
| // |  | ||||||
| // This method is EXPERIMENTAL and subject to change or removal without notice. |  | ||||||
| func (c *Client) ListHMACKeys(ctx context.Context, projectID string) *HMACKeysIterator { |  | ||||||
| 	it := &HMACKeysIterator{ |  | ||||||
| 		ctx:       ctx, |  | ||||||
| 		raw:       raw.NewProjectsHmacKeysService(c.raw), |  | ||||||
| 		projectID: projectID, |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	it.pageInfo, it.nextFunc = iterator.NewPageInfo( |  | ||||||
| 		it.fetch, |  | ||||||
| 		func() int { return len(it.hmacKeys) - it.index }, |  | ||||||
| 		func() interface{} { |  | ||||||
| 			prev := it.hmacKeys |  | ||||||
| 			it.hmacKeys = it.hmacKeys[:0] |  | ||||||
| 			it.index = 0 |  | ||||||
| 			return prev |  | ||||||
| 		}) |  | ||||||
| 	return it |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Next returns the next result. Its second return value is iterator.Done if |  | ||||||
| // there are no more results. Once Next returns iterator.Done, all subsequent |  | ||||||
| // calls will return iterator.Done. |  | ||||||
| // |  | ||||||
| // This method is EXPERIMENTAL and subject to change or removal without notice. |  | ||||||
| func (it *HMACKeysIterator) Next() (*HMACKey, error) { |  | ||||||
| 	if err := it.nextFunc(); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	key := it.hmacKeys[it.index] |  | ||||||
| 	it.index++ |  | ||||||
|  |  | ||||||
| 	return key, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. |  | ||||||
| // |  | ||||||
| // This method is EXPERIMENTAL and subject to change or removal without notice. |  | ||||||
| func (it *HMACKeysIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } |  | ||||||
|  |  | ||||||
| func (it *HMACKeysIterator) fetch(pageSize int, pageToken string) (token string, err error) { |  | ||||||
| 	call := it.raw.List(it.projectID) |  | ||||||
| 	setClientHeader(call.Header()) |  | ||||||
| 	call = call.PageToken(pageToken) |  | ||||||
| 	// By default we'll also show deleted keys and then |  | ||||||
| 	// let users filter on their own. |  | ||||||
| 	call = call.ShowDeletedKeys(true) |  | ||||||
| 	if pageSize > 0 { |  | ||||||
| 		call = call.MaxResults(int64(pageSize)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ctx := it.ctx |  | ||||||
| 	var resp *raw.HmacKeysMetadata |  | ||||||
| 	err = runWithRetry(it.ctx, func() error { |  | ||||||
| 		resp, err = call.Context(ctx).Do() |  | ||||||
| 		return err |  | ||||||
| 	}) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return "", err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for _, metadata := range resp.Items { |  | ||||||
| 		hkPb := &raw.HmacKey{ |  | ||||||
| 			Metadata: metadata, |  | ||||||
| 		} |  | ||||||
| 		hkey, err := pbHmacKeyToHMACKey(hkPb, true) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return "", err |  | ||||||
| 		} |  | ||||||
| 		it.hmacKeys = append(it.hmacKeys, hkey) |  | ||||||
| 	} |  | ||||||
| 	return resp.NextPageToken, nil |  | ||||||
| } |  | ||||||
							
								
								
									
										130
									
								
								vendor/cloud.google.com/go/storage/iam.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										130
									
								
								vendor/cloud.google.com/go/storage/iam.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,130 +0,0 @@ | |||||||
| // Copyright 2017 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| package storage |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
|  |  | ||||||
| 	"cloud.google.com/go/iam" |  | ||||||
| 	"cloud.google.com/go/internal/trace" |  | ||||||
| 	raw "google.golang.org/api/storage/v1" |  | ||||||
| 	iampb "google.golang.org/genproto/googleapis/iam/v1" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // IAM provides access to IAM access control for the bucket. |  | ||||||
| func (b *BucketHandle) IAM() *iam.Handle { |  | ||||||
| 	return iam.InternalNewHandleClient(&iamClient{ |  | ||||||
| 		raw:         b.c.raw, |  | ||||||
| 		userProject: b.userProject, |  | ||||||
| 	}, b.name) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // iamClient implements the iam.client interface. |  | ||||||
| type iamClient struct { |  | ||||||
| 	raw         *raw.Service |  | ||||||
| 	userProject string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *iamClient) Get(ctx context.Context, resource string) (p *iampb.Policy, err error) { |  | ||||||
| 	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.IAM.Get") |  | ||||||
| 	defer func() { trace.EndSpan(ctx, err) }() |  | ||||||
|  |  | ||||||
| 	call := c.raw.Buckets.GetIamPolicy(resource) |  | ||||||
| 	setClientHeader(call.Header()) |  | ||||||
| 	if c.userProject != "" { |  | ||||||
| 		call.UserProject(c.userProject) |  | ||||||
| 	} |  | ||||||
| 	var rp *raw.Policy |  | ||||||
| 	err = runWithRetry(ctx, func() error { |  | ||||||
| 		rp, err = call.Context(ctx).Do() |  | ||||||
| 		return err |  | ||||||
| 	}) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return iamFromStoragePolicy(rp), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *iamClient) Set(ctx context.Context, resource string, p *iampb.Policy) (err error) { |  | ||||||
| 	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.IAM.Set") |  | ||||||
| 	defer func() { trace.EndSpan(ctx, err) }() |  | ||||||
|  |  | ||||||
| 	rp := iamToStoragePolicy(p) |  | ||||||
| 	call := c.raw.Buckets.SetIamPolicy(resource, rp) |  | ||||||
| 	setClientHeader(call.Header()) |  | ||||||
| 	if c.userProject != "" { |  | ||||||
| 		call.UserProject(c.userProject) |  | ||||||
| 	} |  | ||||||
| 	return runWithRetry(ctx, func() error { |  | ||||||
| 		_, err := call.Context(ctx).Do() |  | ||||||
| 		return err |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *iamClient) Test(ctx context.Context, resource string, perms []string) (permissions []string, err error) { |  | ||||||
| 	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.IAM.Test") |  | ||||||
| 	defer func() { trace.EndSpan(ctx, err) }() |  | ||||||
|  |  | ||||||
| 	call := c.raw.Buckets.TestIamPermissions(resource, perms) |  | ||||||
| 	setClientHeader(call.Header()) |  | ||||||
| 	if c.userProject != "" { |  | ||||||
| 		call.UserProject(c.userProject) |  | ||||||
| 	} |  | ||||||
| 	var res *raw.TestIamPermissionsResponse |  | ||||||
| 	err = runWithRetry(ctx, func() error { |  | ||||||
| 		res, err = call.Context(ctx).Do() |  | ||||||
| 		return err |  | ||||||
| 	}) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return res.Permissions, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func iamToStoragePolicy(ip *iampb.Policy) *raw.Policy { |  | ||||||
| 	return &raw.Policy{ |  | ||||||
| 		Bindings: iamToStorageBindings(ip.Bindings), |  | ||||||
| 		Etag:     string(ip.Etag), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func iamToStorageBindings(ibs []*iampb.Binding) []*raw.PolicyBindings { |  | ||||||
| 	var rbs []*raw.PolicyBindings |  | ||||||
| 	for _, ib := range ibs { |  | ||||||
| 		rbs = append(rbs, &raw.PolicyBindings{ |  | ||||||
| 			Role:    ib.Role, |  | ||||||
| 			Members: ib.Members, |  | ||||||
| 		}) |  | ||||||
| 	} |  | ||||||
| 	return rbs |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func iamFromStoragePolicy(rp *raw.Policy) *iampb.Policy { |  | ||||||
| 	return &iampb.Policy{ |  | ||||||
| 		Bindings: iamFromStorageBindings(rp.Bindings), |  | ||||||
| 		Etag:     []byte(rp.Etag), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func iamFromStorageBindings(rbs []*raw.PolicyBindings) []*iampb.Binding { |  | ||||||
| 	var ibs []*iampb.Binding |  | ||||||
| 	for _, rb := range rbs { |  | ||||||
| 		ibs = append(ibs, &iampb.Binding{ |  | ||||||
| 			Role:    rb.Role, |  | ||||||
| 			Members: rb.Members, |  | ||||||
| 		}) |  | ||||||
| 	} |  | ||||||
| 	return ibs |  | ||||||
| } |  | ||||||
							
								
								
									
										37
									
								
								vendor/cloud.google.com/go/storage/invoke.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								vendor/cloud.google.com/go/storage/invoke.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,37 +0,0 @@ | |||||||
| // Copyright 2014 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| package storage |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
|  |  | ||||||
| 	"cloud.google.com/go/internal" |  | ||||||
| 	gax "github.com/googleapis/gax-go/v2" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // runWithRetry calls the function until it returns nil or a non-retryable error, or |  | ||||||
| // the context is done. |  | ||||||
| func runWithRetry(ctx context.Context, call func() error) error { |  | ||||||
| 	return internal.Retry(ctx, gax.Backoff{}, func() (stop bool, err error) { |  | ||||||
| 		err = call() |  | ||||||
| 		if err == nil { |  | ||||||
| 			return true, nil |  | ||||||
| 		} |  | ||||||
| 		if shouldRetry(err) { |  | ||||||
| 			return false, nil |  | ||||||
| 		} |  | ||||||
| 		return true, err |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
							
								
								
									
										42
									
								
								vendor/cloud.google.com/go/storage/not_go110.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								vendor/cloud.google.com/go/storage/not_go110.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,42 +0,0 @@ | |||||||
| // Copyright 2017 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| // +build !go1.10 |  | ||||||
|  |  | ||||||
| package storage |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"net/url" |  | ||||||
| 	"strings" |  | ||||||
|  |  | ||||||
| 	"google.golang.org/api/googleapi" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func shouldRetry(err error) bool { |  | ||||||
| 	switch e := err.(type) { |  | ||||||
| 	case *googleapi.Error: |  | ||||||
| 		// Retry on 429 and 5xx, according to |  | ||||||
| 		// https://cloud.google.com/storage/docs/exponential-backoff. |  | ||||||
| 		return e.Code == 429 || (e.Code >= 500 && e.Code < 600) |  | ||||||
| 	case *url.Error: |  | ||||||
| 		// Retry on REFUSED_STREAM. |  | ||||||
| 		// Unfortunately the error type is unexported, so we resort to string |  | ||||||
| 		// matching. |  | ||||||
| 		return strings.Contains(e.Error(), "REFUSED_STREAM") |  | ||||||
| 	case interface{ Temporary() bool }: |  | ||||||
| 		return e.Temporary() |  | ||||||
| 	default: |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
							
								
								
									
										188
									
								
								vendor/cloud.google.com/go/storage/notifications.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										188
									
								
								vendor/cloud.google.com/go/storage/notifications.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,188 +0,0 @@ | |||||||
| // Copyright 2017 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| package storage |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"regexp" |  | ||||||
|  |  | ||||||
| 	"cloud.google.com/go/internal/trace" |  | ||||||
| 	raw "google.golang.org/api/storage/v1" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // A Notification describes how to send Cloud PubSub messages when certain |  | ||||||
| // events occur in a bucket. |  | ||||||
| type Notification struct { |  | ||||||
| 	//The ID of the notification. |  | ||||||
| 	ID string |  | ||||||
|  |  | ||||||
| 	// The ID of the topic to which this subscription publishes. |  | ||||||
| 	TopicID string |  | ||||||
|  |  | ||||||
| 	// The ID of the project to which the topic belongs. |  | ||||||
| 	TopicProjectID string |  | ||||||
|  |  | ||||||
| 	// Only send notifications about listed event types. If empty, send notifications |  | ||||||
| 	// for all event types. |  | ||||||
| 	// See https://cloud.google.com/storage/docs/pubsub-notifications#events. |  | ||||||
| 	EventTypes []string |  | ||||||
|  |  | ||||||
| 	// If present, only apply this notification configuration to object names that |  | ||||||
| 	// begin with this prefix. |  | ||||||
| 	ObjectNamePrefix string |  | ||||||
|  |  | ||||||
| 	// An optional list of additional attributes to attach to each Cloud PubSub |  | ||||||
| 	// message published for this notification subscription. |  | ||||||
| 	CustomAttributes map[string]string |  | ||||||
|  |  | ||||||
| 	// The contents of the message payload. |  | ||||||
| 	// See https://cloud.google.com/storage/docs/pubsub-notifications#payload. |  | ||||||
| 	PayloadFormat string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Values for Notification.PayloadFormat. |  | ||||||
| const ( |  | ||||||
| 	// Send no payload with notification messages. |  | ||||||
| 	NoPayload = "NONE" |  | ||||||
|  |  | ||||||
| 	// Send object metadata as JSON with notification messages. |  | ||||||
| 	JSONPayload = "JSON_API_V1" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // Values for Notification.EventTypes. |  | ||||||
| const ( |  | ||||||
| 	// Event that occurs when an object is successfully created. |  | ||||||
| 	ObjectFinalizeEvent = "OBJECT_FINALIZE" |  | ||||||
|  |  | ||||||
| 	// Event that occurs when the metadata of an existing object changes. |  | ||||||
| 	ObjectMetadataUpdateEvent = "OBJECT_METADATA_UPDATE" |  | ||||||
|  |  | ||||||
| 	// Event that occurs when an object is permanently deleted. |  | ||||||
| 	ObjectDeleteEvent = "OBJECT_DELETE" |  | ||||||
|  |  | ||||||
| 	// Event that occurs when the live version of an object becomes an |  | ||||||
| 	// archived version. |  | ||||||
| 	ObjectArchiveEvent = "OBJECT_ARCHIVE" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func toNotification(rn *raw.Notification) *Notification { |  | ||||||
| 	n := &Notification{ |  | ||||||
| 		ID:               rn.Id, |  | ||||||
| 		EventTypes:       rn.EventTypes, |  | ||||||
| 		ObjectNamePrefix: rn.ObjectNamePrefix, |  | ||||||
| 		CustomAttributes: rn.CustomAttributes, |  | ||||||
| 		PayloadFormat:    rn.PayloadFormat, |  | ||||||
| 	} |  | ||||||
| 	n.TopicProjectID, n.TopicID = parseNotificationTopic(rn.Topic) |  | ||||||
| 	return n |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var topicRE = regexp.MustCompile("^//pubsub.googleapis.com/projects/([^/]+)/topics/([^/]+)") |  | ||||||
|  |  | ||||||
| // parseNotificationTopic extracts the project and topic IDs from from the full |  | ||||||
| // resource name returned by the service. If the name is malformed, it returns |  | ||||||
| // "?" for both IDs. |  | ||||||
| func parseNotificationTopic(nt string) (projectID, topicID string) { |  | ||||||
| 	matches := topicRE.FindStringSubmatch(nt) |  | ||||||
| 	if matches == nil { |  | ||||||
| 		return "?", "?" |  | ||||||
| 	} |  | ||||||
| 	return matches[1], matches[2] |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func toRawNotification(n *Notification) *raw.Notification { |  | ||||||
| 	return &raw.Notification{ |  | ||||||
| 		Id: n.ID, |  | ||||||
| 		Topic: fmt.Sprintf("//pubsub.googleapis.com/projects/%s/topics/%s", |  | ||||||
| 			n.TopicProjectID, n.TopicID), |  | ||||||
| 		EventTypes:       n.EventTypes, |  | ||||||
| 		ObjectNamePrefix: n.ObjectNamePrefix, |  | ||||||
| 		CustomAttributes: n.CustomAttributes, |  | ||||||
| 		PayloadFormat:    string(n.PayloadFormat), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AddNotification adds a notification to b. You must set n's TopicProjectID, TopicID |  | ||||||
| // and PayloadFormat, and must not set its ID. The other fields are all optional. The |  | ||||||
| // returned Notification's ID can be used to refer to it. |  | ||||||
| func (b *BucketHandle) AddNotification(ctx context.Context, n *Notification) (ret *Notification, err error) { |  | ||||||
| 	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.AddNotification") |  | ||||||
| 	defer func() { trace.EndSpan(ctx, err) }() |  | ||||||
|  |  | ||||||
| 	if n.ID != "" { |  | ||||||
| 		return nil, errors.New("storage: AddNotification: ID must not be set") |  | ||||||
| 	} |  | ||||||
| 	if n.TopicProjectID == "" { |  | ||||||
| 		return nil, errors.New("storage: AddNotification: missing TopicProjectID") |  | ||||||
| 	} |  | ||||||
| 	if n.TopicID == "" { |  | ||||||
| 		return nil, errors.New("storage: AddNotification: missing TopicID") |  | ||||||
| 	} |  | ||||||
| 	call := b.c.raw.Notifications.Insert(b.name, toRawNotification(n)) |  | ||||||
| 	setClientHeader(call.Header()) |  | ||||||
| 	if b.userProject != "" { |  | ||||||
| 		call.UserProject(b.userProject) |  | ||||||
| 	} |  | ||||||
| 	rn, err := call.Context(ctx).Do() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return toNotification(rn), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Notifications returns all the Notifications configured for this bucket, as a map |  | ||||||
| // indexed by notification ID. |  | ||||||
| func (b *BucketHandle) Notifications(ctx context.Context) (n map[string]*Notification, err error) { |  | ||||||
| 	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.Notifications") |  | ||||||
| 	defer func() { trace.EndSpan(ctx, err) }() |  | ||||||
|  |  | ||||||
| 	call := b.c.raw.Notifications.List(b.name) |  | ||||||
| 	setClientHeader(call.Header()) |  | ||||||
| 	if b.userProject != "" { |  | ||||||
| 		call.UserProject(b.userProject) |  | ||||||
| 	} |  | ||||||
| 	var res *raw.Notifications |  | ||||||
| 	err = runWithRetry(ctx, func() error { |  | ||||||
| 		res, err = call.Context(ctx).Do() |  | ||||||
| 		return err |  | ||||||
| 	}) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return notificationsToMap(res.Items), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func notificationsToMap(rns []*raw.Notification) map[string]*Notification { |  | ||||||
| 	m := map[string]*Notification{} |  | ||||||
| 	for _, rn := range rns { |  | ||||||
| 		m[rn.Id] = toNotification(rn) |  | ||||||
| 	} |  | ||||||
| 	return m |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // DeleteNotification deletes the notification with the given ID. |  | ||||||
| func (b *BucketHandle) DeleteNotification(ctx context.Context, id string) (err error) { |  | ||||||
| 	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.DeleteNotification") |  | ||||||
| 	defer func() { trace.EndSpan(ctx, err) }() |  | ||||||
|  |  | ||||||
| 	call := b.c.raw.Notifications.Delete(b.name, id) |  | ||||||
| 	setClientHeader(call.Header()) |  | ||||||
| 	if b.userProject != "" { |  | ||||||
| 		call.UserProject(b.userProject) |  | ||||||
| 	} |  | ||||||
| 	return call.Context(ctx).Do() |  | ||||||
| } |  | ||||||
							
								
								
									
										403
									
								
								vendor/cloud.google.com/go/storage/reader.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										403
									
								
								vendor/cloud.google.com/go/storage/reader.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,403 +0,0 @@ | |||||||
| // Copyright 2016 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| package storage |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"hash/crc32" |  | ||||||
| 	"io" |  | ||||||
| 	"io/ioutil" |  | ||||||
| 	"net/http" |  | ||||||
| 	"net/url" |  | ||||||
| 	"reflect" |  | ||||||
| 	"strconv" |  | ||||||
| 	"strings" |  | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"cloud.google.com/go/internal/trace" |  | ||||||
| 	"google.golang.org/api/googleapi" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| var crc32cTable = crc32.MakeTable(crc32.Castagnoli) |  | ||||||
|  |  | ||||||
| // ReaderObjectAttrs are attributes about the object being read. These are populated |  | ||||||
| // during the New call. This struct only holds a subset of object attributes: to |  | ||||||
| // get the full set of attributes, use ObjectHandle.Attrs. |  | ||||||
| // |  | ||||||
| // Each field is read-only. |  | ||||||
| type ReaderObjectAttrs struct { |  | ||||||
| 	// Size is the length of the object's content. |  | ||||||
| 	Size int64 |  | ||||||
|  |  | ||||||
| 	// StartOffset is the byte offset within the object |  | ||||||
| 	// from which reading begins. |  | ||||||
| 	// This value is only non-zero for range requests. |  | ||||||
| 	StartOffset int64 |  | ||||||
|  |  | ||||||
| 	// ContentType is the MIME type of the object's content. |  | ||||||
| 	ContentType string |  | ||||||
|  |  | ||||||
| 	// ContentEncoding is the encoding of the object's content. |  | ||||||
| 	ContentEncoding string |  | ||||||
|  |  | ||||||
| 	// CacheControl specifies whether and for how long browser and Internet |  | ||||||
| 	// caches are allowed to cache your objects. |  | ||||||
| 	CacheControl string |  | ||||||
|  |  | ||||||
| 	// LastModified is the time that the object was last modified. |  | ||||||
| 	LastModified time.Time |  | ||||||
|  |  | ||||||
| 	// Generation is the generation number of the object's content. |  | ||||||
| 	Generation int64 |  | ||||||
|  |  | ||||||
| 	// Metageneration is the version of the metadata for this object at |  | ||||||
| 	// this generation. This field is used for preconditions and for |  | ||||||
| 	// detecting changes in metadata. A metageneration number is only |  | ||||||
| 	// meaningful in the context of a particular generation of a |  | ||||||
| 	// particular object. |  | ||||||
| 	Metageneration int64 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // NewReader creates a new Reader to read the contents of the |  | ||||||
| // object. |  | ||||||
| // ErrObjectNotExist will be returned if the object is not found. |  | ||||||
| // |  | ||||||
| // The caller must call Close on the returned Reader when done reading. |  | ||||||
| func (o *ObjectHandle) NewReader(ctx context.Context) (*Reader, error) { |  | ||||||
| 	return o.NewRangeReader(ctx, 0, -1) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // NewRangeReader reads part of an object, reading at most length bytes |  | ||||||
| // starting at the given offset. If length is negative, the object is read |  | ||||||
| // until the end. If offset is negative, the object is read abs(offset) bytes |  | ||||||
| // from the end, and length must also be negative to indicate all remaining |  | ||||||
| // bytes will be read. |  | ||||||
| func (o *ObjectHandle) NewRangeReader(ctx context.Context, offset, length int64) (r *Reader, err error) { |  | ||||||
| 	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Object.NewRangeReader") |  | ||||||
| 	defer func() { trace.EndSpan(ctx, err) }() |  | ||||||
|  |  | ||||||
| 	if err := o.validate(); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	if offset < 0 && length >= 0 { |  | ||||||
| 		return nil, fmt.Errorf("storage: invalid offset %d < 0 requires negative length", offset) |  | ||||||
| 	} |  | ||||||
| 	if o.conds != nil { |  | ||||||
| 		if err := o.conds.validate("NewRangeReader"); err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	u := &url.URL{ |  | ||||||
| 		Scheme: o.c.scheme, |  | ||||||
| 		Host:   o.c.readHost, |  | ||||||
| 		Path:   fmt.Sprintf("/%s/%s", o.bucket, o.object), |  | ||||||
| 	} |  | ||||||
| 	verb := "GET" |  | ||||||
| 	if length == 0 { |  | ||||||
| 		verb = "HEAD" |  | ||||||
| 	} |  | ||||||
| 	req, err := http.NewRequest(verb, u.String(), nil) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	req = req.WithContext(ctx) |  | ||||||
| 	if o.userProject != "" { |  | ||||||
| 		req.Header.Set("X-Goog-User-Project", o.userProject) |  | ||||||
| 	} |  | ||||||
| 	if o.readCompressed { |  | ||||||
| 		req.Header.Set("Accept-Encoding", "gzip") |  | ||||||
| 	} |  | ||||||
| 	if err := setEncryptionHeaders(req.Header, o.encryptionKey, false); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	gen := o.gen |  | ||||||
|  |  | ||||||
| 	// Define a function that initiates a Read with offset and length, assuming we |  | ||||||
| 	// have already read seen bytes. |  | ||||||
| 	reopen := func(seen int64) (*http.Response, error) { |  | ||||||
| 		start := offset + seen |  | ||||||
| 		if length < 0 && start < 0 { |  | ||||||
| 			req.Header.Set("Range", fmt.Sprintf("bytes=%d", start)) |  | ||||||
| 		} else if length < 0 && start > 0 { |  | ||||||
| 			req.Header.Set("Range", fmt.Sprintf("bytes=%d-", start)) |  | ||||||
| 		} else if length > 0 { |  | ||||||
| 			// The end character isn't affected by how many bytes we've seen. |  | ||||||
| 			req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", start, offset+length-1)) |  | ||||||
| 		} |  | ||||||
| 		// We wait to assign conditions here because the generation number can change in between reopen() runs. |  | ||||||
| 		req.URL.RawQuery = conditionsQuery(gen, o.conds) |  | ||||||
| 		var res *http.Response |  | ||||||
| 		err = runWithRetry(ctx, func() error { |  | ||||||
| 			res, err = o.c.hc.Do(req) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 			if res.StatusCode == http.StatusNotFound { |  | ||||||
| 				res.Body.Close() |  | ||||||
| 				return ErrObjectNotExist |  | ||||||
| 			} |  | ||||||
| 			if res.StatusCode < 200 || res.StatusCode > 299 { |  | ||||||
| 				body, _ := ioutil.ReadAll(res.Body) |  | ||||||
| 				res.Body.Close() |  | ||||||
| 				return &googleapi.Error{ |  | ||||||
| 					Code:   res.StatusCode, |  | ||||||
| 					Header: res.Header, |  | ||||||
| 					Body:   string(body), |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			if start > 0 && length != 0 && res.StatusCode != http.StatusPartialContent { |  | ||||||
| 				res.Body.Close() |  | ||||||
| 				return errors.New("storage: partial request not satisfied") |  | ||||||
| 			} |  | ||||||
| 			// If a generation hasn't been specified, and this is the first response we get, let's record the |  | ||||||
| 			// generation. In future requests we'll use this generation as a precondition to avoid data races. |  | ||||||
| 			if gen < 0 && res.Header.Get("X-Goog-Generation") != "" { |  | ||||||
| 				gen64, err := strconv.ParseInt(res.Header.Get("X-Goog-Generation"), 10, 64) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return err |  | ||||||
| 				} |  | ||||||
| 				gen = gen64 |  | ||||||
| 			} |  | ||||||
| 			return nil |  | ||||||
| 		}) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		return res, nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	res, err := reopen(0) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	var ( |  | ||||||
| 		size        int64 // total size of object, even if a range was requested. |  | ||||||
| 		checkCRC    bool |  | ||||||
| 		crc         uint32 |  | ||||||
| 		startOffset int64 // non-zero if range request. |  | ||||||
| 	) |  | ||||||
| 	if res.StatusCode == http.StatusPartialContent { |  | ||||||
| 		cr := strings.TrimSpace(res.Header.Get("Content-Range")) |  | ||||||
| 		if !strings.HasPrefix(cr, "bytes ") || !strings.Contains(cr, "/") { |  | ||||||
| 			return nil, fmt.Errorf("storage: invalid Content-Range %q", cr) |  | ||||||
| 		} |  | ||||||
| 		size, err = strconv.ParseInt(cr[strings.LastIndex(cr, "/")+1:], 10, 64) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, fmt.Errorf("storage: invalid Content-Range %q", cr) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		dashIndex := strings.Index(cr, "-") |  | ||||||
| 		if dashIndex >= 0 { |  | ||||||
| 			startOffset, err = strconv.ParseInt(cr[len("bytes="):dashIndex], 10, 64) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return nil, fmt.Errorf("storage: invalid Content-Range %q: %v", cr, err) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		size = res.ContentLength |  | ||||||
| 		// Check the CRC iff all of the following hold: |  | ||||||
| 		// - We asked for content (length != 0). |  | ||||||
| 		// - We got all the content (status != PartialContent). |  | ||||||
| 		// - The server sent a CRC header. |  | ||||||
| 		// - The Go http stack did not uncompress the file. |  | ||||||
| 		// - We were not served compressed data that was uncompressed on download. |  | ||||||
| 		// The problem with the last two cases is that the CRC will not match -- GCS |  | ||||||
| 		// computes it on the compressed contents, but we compute it on the |  | ||||||
| 		// uncompressed contents. |  | ||||||
| 		if length != 0 && !res.Uncompressed && !uncompressedByServer(res) { |  | ||||||
| 			crc, checkCRC = parseCRC32c(res) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	remain := res.ContentLength |  | ||||||
| 	body := res.Body |  | ||||||
| 	if length == 0 { |  | ||||||
| 		remain = 0 |  | ||||||
| 		body.Close() |  | ||||||
| 		body = emptyBody |  | ||||||
| 	} |  | ||||||
| 	var metaGen int64 |  | ||||||
| 	if res.Header.Get("X-Goog-Generation") != "" { |  | ||||||
| 		metaGen, err = strconv.ParseInt(res.Header.Get("X-Goog-Metageneration"), 10, 64) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	var lm time.Time |  | ||||||
| 	if res.Header.Get("Last-Modified") != "" { |  | ||||||
| 		lm, err = http.ParseTime(res.Header.Get("Last-Modified")) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	attrs := ReaderObjectAttrs{ |  | ||||||
| 		Size:            size, |  | ||||||
| 		ContentType:     res.Header.Get("Content-Type"), |  | ||||||
| 		ContentEncoding: res.Header.Get("Content-Encoding"), |  | ||||||
| 		CacheControl:    res.Header.Get("Cache-Control"), |  | ||||||
| 		LastModified:    lm, |  | ||||||
| 		StartOffset:     startOffset, |  | ||||||
| 		Generation:      gen, |  | ||||||
| 		Metageneration:  metaGen, |  | ||||||
| 	} |  | ||||||
| 	return &Reader{ |  | ||||||
| 		Attrs:    attrs, |  | ||||||
| 		body:     body, |  | ||||||
| 		size:     size, |  | ||||||
| 		remain:   remain, |  | ||||||
| 		wantCRC:  crc, |  | ||||||
| 		checkCRC: checkCRC, |  | ||||||
| 		reopen:   reopen, |  | ||||||
| 	}, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func uncompressedByServer(res *http.Response) bool { |  | ||||||
| 	// If the data is stored as gzip but is not encoded as gzip, then it |  | ||||||
| 	// was uncompressed by the server. |  | ||||||
| 	return res.Header.Get("X-Goog-Stored-Content-Encoding") == "gzip" && |  | ||||||
| 		res.Header.Get("Content-Encoding") != "gzip" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func parseCRC32c(res *http.Response) (uint32, bool) { |  | ||||||
| 	const prefix = "crc32c=" |  | ||||||
| 	for _, spec := range res.Header["X-Goog-Hash"] { |  | ||||||
| 		if strings.HasPrefix(spec, prefix) { |  | ||||||
| 			c, err := decodeUint32(spec[len(prefix):]) |  | ||||||
| 			if err == nil { |  | ||||||
| 				return c, true |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return 0, false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var emptyBody = ioutil.NopCloser(strings.NewReader("")) |  | ||||||
|  |  | ||||||
| // Reader reads a Cloud Storage object. |  | ||||||
| // It implements io.Reader. |  | ||||||
| // |  | ||||||
| // Typically, a Reader computes the CRC of the downloaded content and compares it to |  | ||||||
| // the stored CRC, returning an error from Read if there is a mismatch. This integrity check |  | ||||||
| // is skipped if transcoding occurs. See https://cloud.google.com/storage/docs/transcoding. |  | ||||||
| type Reader struct { |  | ||||||
| 	Attrs              ReaderObjectAttrs |  | ||||||
| 	body               io.ReadCloser |  | ||||||
| 	seen, remain, size int64 |  | ||||||
| 	checkCRC           bool   // should we check the CRC? |  | ||||||
| 	wantCRC            uint32 // the CRC32c value the server sent in the header |  | ||||||
| 	gotCRC             uint32 // running crc |  | ||||||
| 	reopen             func(seen int64) (*http.Response, error) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Close closes the Reader. It must be called when done reading. |  | ||||||
| func (r *Reader) Close() error { |  | ||||||
| 	return r.body.Close() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *Reader) Read(p []byte) (int, error) { |  | ||||||
| 	n, err := r.readWithRetry(p) |  | ||||||
| 	if r.remain != -1 { |  | ||||||
| 		r.remain -= int64(n) |  | ||||||
| 	} |  | ||||||
| 	if r.checkCRC { |  | ||||||
| 		r.gotCRC = crc32.Update(r.gotCRC, crc32cTable, p[:n]) |  | ||||||
| 		// Check CRC here. It would be natural to check it in Close, but |  | ||||||
| 		// everybody defers Close on the assumption that it doesn't return |  | ||||||
| 		// anything worth looking at. |  | ||||||
| 		if err == io.EOF { |  | ||||||
| 			if r.gotCRC != r.wantCRC { |  | ||||||
| 				return n, fmt.Errorf("storage: bad CRC on read: got %d, want %d", |  | ||||||
| 					r.gotCRC, r.wantCRC) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return n, err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *Reader) readWithRetry(p []byte) (int, error) { |  | ||||||
| 	n := 0 |  | ||||||
| 	for len(p[n:]) > 0 { |  | ||||||
| 		m, err := r.body.Read(p[n:]) |  | ||||||
| 		n += m |  | ||||||
| 		r.seen += int64(m) |  | ||||||
| 		if !shouldRetryRead(err) { |  | ||||||
| 			return n, err |  | ||||||
| 		} |  | ||||||
| 		// Read failed, but we will try again. Send a ranged read request that takes |  | ||||||
| 		// into account the number of bytes we've already seen. |  | ||||||
| 		res, err := r.reopen(r.seen) |  | ||||||
| 		if err != nil { |  | ||||||
| 			// reopen already retries |  | ||||||
| 			return n, err |  | ||||||
| 		} |  | ||||||
| 		r.body.Close() |  | ||||||
| 		r.body = res.Body |  | ||||||
| 	} |  | ||||||
| 	return n, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func shouldRetryRead(err error) bool { |  | ||||||
| 	if err == nil { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	return strings.HasSuffix(err.Error(), "INTERNAL_ERROR") && strings.Contains(reflect.TypeOf(err).String(), "http2") |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Size returns the size of the object in bytes. |  | ||||||
| // The returned value is always the same and is not affected by |  | ||||||
| // calls to Read or Close. |  | ||||||
| // |  | ||||||
| // Deprecated: use Reader.Attrs.Size. |  | ||||||
| func (r *Reader) Size() int64 { |  | ||||||
| 	return r.Attrs.Size |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Remain returns the number of bytes left to read, or -1 if unknown. |  | ||||||
| func (r *Reader) Remain() int64 { |  | ||||||
| 	return r.remain |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ContentType returns the content type of the object. |  | ||||||
| // |  | ||||||
| // Deprecated: use Reader.Attrs.ContentType. |  | ||||||
| func (r *Reader) ContentType() string { |  | ||||||
| 	return r.Attrs.ContentType |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ContentEncoding returns the content encoding of the object. |  | ||||||
| // |  | ||||||
| // Deprecated: use Reader.Attrs.ContentEncoding. |  | ||||||
| func (r *Reader) ContentEncoding() string { |  | ||||||
| 	return r.Attrs.ContentEncoding |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // CacheControl returns the cache control of the object. |  | ||||||
| // |  | ||||||
| // Deprecated: use Reader.Attrs.CacheControl. |  | ||||||
| func (r *Reader) CacheControl() string { |  | ||||||
| 	return r.Attrs.CacheControl |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // LastModified returns the value of the Last-Modified header. |  | ||||||
| // |  | ||||||
| // Deprecated: use Reader.Attrs.LastModified. |  | ||||||
| func (r *Reader) LastModified() (time.Time, error) { |  | ||||||
| 	return r.Attrs.LastModified, nil |  | ||||||
| } |  | ||||||
							
								
								
									
										1369
									
								
								vendor/cloud.google.com/go/storage/storage.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1369
									
								
								vendor/cloud.google.com/go/storage/storage.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										30067
									
								
								vendor/cloud.google.com/go/storage/storage.replay
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										30067
									
								
								vendor/cloud.google.com/go/storage/storage.replay
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										260
									
								
								vendor/cloud.google.com/go/storage/writer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										260
									
								
								vendor/cloud.google.com/go/storage/writer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,260 +0,0 @@ | |||||||
| // Copyright 2014 Google LLC |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //      http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| package storage |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"encoding/base64" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"sync" |  | ||||||
| 	"unicode/utf8" |  | ||||||
|  |  | ||||||
| 	"google.golang.org/api/googleapi" |  | ||||||
| 	raw "google.golang.org/api/storage/v1" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // A Writer writes a Cloud Storage object. |  | ||||||
| type Writer struct { |  | ||||||
| 	// ObjectAttrs are optional attributes to set on the object. Any attributes |  | ||||||
| 	// must be initialized before the first Write call. Nil or zero-valued |  | ||||||
| 	// attributes are ignored. |  | ||||||
| 	ObjectAttrs |  | ||||||
|  |  | ||||||
| 	// SendCRC specifies whether to transmit a CRC32C field. It should be set |  | ||||||
| 	// to true in addition to setting the Writer's CRC32C field, because zero |  | ||||||
| 	// is a valid CRC and normally a zero would not be transmitted. |  | ||||||
| 	// If a CRC32C is sent, and the data written does not match the checksum, |  | ||||||
| 	// the write will be rejected. |  | ||||||
| 	SendCRC32C bool |  | ||||||
|  |  | ||||||
| 	// ChunkSize controls the maximum number of bytes of the object that the |  | ||||||
| 	// Writer will attempt to send to the server in a single request. Objects |  | ||||||
| 	// smaller than the size will be sent in a single request, while larger |  | ||||||
| 	// objects will be split over multiple requests. The size will be rounded up |  | ||||||
| 	// to the nearest multiple of 256K. If zero, chunking will be disabled and |  | ||||||
| 	// the object will be uploaded in a single request. |  | ||||||
| 	// |  | ||||||
| 	// ChunkSize will default to a reasonable value. If you perform many concurrent |  | ||||||
| 	// writes of small objects, you may wish set ChunkSize to a value that matches |  | ||||||
| 	// your objects' sizes to avoid consuming large amounts of memory. |  | ||||||
| 	// |  | ||||||
| 	// ChunkSize must be set before the first Write call. |  | ||||||
| 	ChunkSize int |  | ||||||
|  |  | ||||||
| 	// ProgressFunc can be used to monitor the progress of a large write. |  | ||||||
| 	// operation. If ProgressFunc is not nil and writing requires multiple |  | ||||||
| 	// calls to the underlying service (see |  | ||||||
| 	// https://cloud.google.com/storage/docs/json_api/v1/how-tos/resumable-upload), |  | ||||||
| 	// then ProgressFunc will be invoked after each call with the number of bytes of |  | ||||||
| 	// content copied so far. |  | ||||||
| 	// |  | ||||||
| 	// ProgressFunc should return quickly without blocking. |  | ||||||
| 	ProgressFunc func(int64) |  | ||||||
|  |  | ||||||
| 	ctx context.Context |  | ||||||
| 	o   *ObjectHandle |  | ||||||
|  |  | ||||||
| 	opened bool |  | ||||||
| 	pw     *io.PipeWriter |  | ||||||
|  |  | ||||||
| 	donec chan struct{} // closed after err and obj are set. |  | ||||||
| 	obj   *ObjectAttrs |  | ||||||
|  |  | ||||||
| 	mu  sync.Mutex |  | ||||||
| 	err error |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (w *Writer) open() error { |  | ||||||
| 	attrs := w.ObjectAttrs |  | ||||||
| 	// Check the developer didn't change the object Name (this is unfortunate, but |  | ||||||
| 	// we don't want to store an object under the wrong name). |  | ||||||
| 	if attrs.Name != w.o.object { |  | ||||||
| 		return fmt.Errorf("storage: Writer.Name %q does not match object name %q", attrs.Name, w.o.object) |  | ||||||
| 	} |  | ||||||
| 	if !utf8.ValidString(attrs.Name) { |  | ||||||
| 		return fmt.Errorf("storage: object name %q is not valid UTF-8", attrs.Name) |  | ||||||
| 	} |  | ||||||
| 	if attrs.KMSKeyName != "" && w.o.encryptionKey != nil { |  | ||||||
| 		return errors.New("storage: cannot use KMSKeyName with a customer-supplied encryption key") |  | ||||||
| 	} |  | ||||||
| 	pr, pw := io.Pipe() |  | ||||||
| 	w.pw = pw |  | ||||||
| 	w.opened = true |  | ||||||
|  |  | ||||||
| 	go w.monitorCancel() |  | ||||||
|  |  | ||||||
| 	if w.ChunkSize < 0 { |  | ||||||
| 		return errors.New("storage: Writer.ChunkSize must be non-negative") |  | ||||||
| 	} |  | ||||||
| 	mediaOpts := []googleapi.MediaOption{ |  | ||||||
| 		googleapi.ChunkSize(w.ChunkSize), |  | ||||||
| 	} |  | ||||||
| 	if c := attrs.ContentType; c != "" { |  | ||||||
| 		mediaOpts = append(mediaOpts, googleapi.ContentType(c)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	go func() { |  | ||||||
| 		defer close(w.donec) |  | ||||||
|  |  | ||||||
| 		rawObj := attrs.toRawObject(w.o.bucket) |  | ||||||
| 		if w.SendCRC32C { |  | ||||||
| 			rawObj.Crc32c = encodeUint32(attrs.CRC32C) |  | ||||||
| 		} |  | ||||||
| 		if w.MD5 != nil { |  | ||||||
| 			rawObj.Md5Hash = base64.StdEncoding.EncodeToString(w.MD5) |  | ||||||
| 		} |  | ||||||
| 		if w.o.c.envHost != "" { |  | ||||||
| 			w.o.c.raw.BasePath = fmt.Sprintf("%s://%s", w.o.c.scheme, w.o.c.envHost) |  | ||||||
| 		} |  | ||||||
| 		call := w.o.c.raw.Objects.Insert(w.o.bucket, rawObj). |  | ||||||
| 			Media(pr, mediaOpts...). |  | ||||||
| 			Projection("full"). |  | ||||||
| 			Context(w.ctx) |  | ||||||
|  |  | ||||||
| 		if w.ProgressFunc != nil { |  | ||||||
| 			call.ProgressUpdater(func(n, _ int64) { w.ProgressFunc(n) }) |  | ||||||
| 		} |  | ||||||
| 		if attrs.KMSKeyName != "" { |  | ||||||
| 			call.KmsKeyName(attrs.KMSKeyName) |  | ||||||
| 		} |  | ||||||
| 		if attrs.PredefinedACL != "" { |  | ||||||
| 			call.PredefinedAcl(attrs.PredefinedACL) |  | ||||||
| 		} |  | ||||||
| 		if err := setEncryptionHeaders(call.Header(), w.o.encryptionKey, false); err != nil { |  | ||||||
| 			w.mu.Lock() |  | ||||||
| 			w.err = err |  | ||||||
| 			w.mu.Unlock() |  | ||||||
| 			pr.CloseWithError(err) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		var resp *raw.Object |  | ||||||
| 		err := applyConds("NewWriter", w.o.gen, w.o.conds, call) |  | ||||||
| 		if err == nil { |  | ||||||
| 			if w.o.userProject != "" { |  | ||||||
| 				call.UserProject(w.o.userProject) |  | ||||||
| 			} |  | ||||||
| 			setClientHeader(call.Header()) |  | ||||||
|  |  | ||||||
| 			// The internals that perform call.Do automatically retry |  | ||||||
| 			// uploading chunks, hence no need to add retries here. |  | ||||||
| 			// See issue https://github.com/googleapis/google-cloud-go/issues/1507. |  | ||||||
| 			// |  | ||||||
| 			// However, since this whole call's internals involve making the initial |  | ||||||
| 			// resumable upload session, the first HTTP request is not retried. |  | ||||||
| 			// TODO: Follow-up with google.golang.org/gensupport to solve |  | ||||||
| 			// https://github.com/googleapis/google-api-go-client/issues/392. |  | ||||||
| 			resp, err = call.Do() |  | ||||||
| 		} |  | ||||||
| 		if err != nil { |  | ||||||
| 			w.mu.Lock() |  | ||||||
| 			w.err = err |  | ||||||
| 			w.mu.Unlock() |  | ||||||
| 			pr.CloseWithError(err) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		w.obj = newObject(resp) |  | ||||||
| 	}() |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Write appends to w. It implements the io.Writer interface. |  | ||||||
| // |  | ||||||
| // Since writes happen asynchronously, Write may return a nil |  | ||||||
| // error even though the write failed (or will fail). Always |  | ||||||
| // use the error returned from Writer.Close to determine if |  | ||||||
| // the upload was successful. |  | ||||||
| func (w *Writer) Write(p []byte) (n int, err error) { |  | ||||||
| 	w.mu.Lock() |  | ||||||
| 	werr := w.err |  | ||||||
| 	w.mu.Unlock() |  | ||||||
| 	if werr != nil { |  | ||||||
| 		return 0, werr |  | ||||||
| 	} |  | ||||||
| 	if !w.opened { |  | ||||||
| 		if err := w.open(); err != nil { |  | ||||||
| 			return 0, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	n, err = w.pw.Write(p) |  | ||||||
| 	if err != nil { |  | ||||||
| 		w.mu.Lock() |  | ||||||
| 		werr := w.err |  | ||||||
| 		w.mu.Unlock() |  | ||||||
| 		// Preserve existing functionality that when context is canceled, Write will return |  | ||||||
| 		// context.Canceled instead of "io: read/write on closed pipe". This hides the |  | ||||||
| 		// pipe implementation detail from users and makes Write seem as though it's an RPC. |  | ||||||
| 		if werr == context.Canceled || werr == context.DeadlineExceeded { |  | ||||||
| 			return n, werr |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return n, err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Close completes the write operation and flushes any buffered data. |  | ||||||
| // If Close doesn't return an error, metadata about the written object |  | ||||||
| // can be retrieved by calling Attrs. |  | ||||||
| func (w *Writer) Close() error { |  | ||||||
| 	if !w.opened { |  | ||||||
| 		if err := w.open(); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Closing either the read or write causes the entire pipe to close. |  | ||||||
| 	if err := w.pw.Close(); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	<-w.donec |  | ||||||
| 	w.mu.Lock() |  | ||||||
| 	defer w.mu.Unlock() |  | ||||||
| 	return w.err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // monitorCancel is intended to be used as a background goroutine. It monitors the |  | ||||||
| // context, and when it observes that the context has been canceled, it manually |  | ||||||
| // closes things that do not take a context. |  | ||||||
| func (w *Writer) monitorCancel() { |  | ||||||
| 	select { |  | ||||||
| 	case <-w.ctx.Done(): |  | ||||||
| 		w.mu.Lock() |  | ||||||
| 		werr := w.ctx.Err() |  | ||||||
| 		w.err = werr |  | ||||||
| 		w.mu.Unlock() |  | ||||||
|  |  | ||||||
| 		// Closing either the read or write causes the entire pipe to close. |  | ||||||
| 		w.CloseWithError(werr) |  | ||||||
| 	case <-w.donec: |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // CloseWithError aborts the write operation with the provided error. |  | ||||||
| // CloseWithError always returns nil. |  | ||||||
| // |  | ||||||
| // Deprecated: cancel the context passed to NewWriter instead. |  | ||||||
| func (w *Writer) CloseWithError(err error) error { |  | ||||||
| 	if !w.opened { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	return w.pw.CloseWithError(err) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Attrs returns metadata about a successfully-written object. |  | ||||||
| // It's only valid to call it after Close returns nil. |  | ||||||
| func (w *Writer) Attrs() *ObjectAttrs { |  | ||||||
| 	return w.obj |  | ||||||
| } |  | ||||||
							
								
								
									
										2
									
								
								vendor/code.gitea.io/sdk/gitea/oauth2.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/code.gitea.io/sdk/gitea/oauth2.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -18,6 +18,7 @@ type Oauth2 struct { | |||||||
| 	ClientID           string    `json:"client_id"` | 	ClientID           string    `json:"client_id"` | ||||||
| 	ClientSecret       string    `json:"client_secret"` | 	ClientSecret       string    `json:"client_secret"` | ||||||
| 	RedirectURIs       []string  `json:"redirect_uris"` | 	RedirectURIs       []string  `json:"redirect_uris"` | ||||||
|  | 	ConfidentialClient bool      `json:"confidential_client"` | ||||||
| 	Created            time.Time `json:"created"` | 	Created            time.Time `json:"created"` | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -29,6 +30,7 @@ type ListOauth2Option struct { | |||||||
| // CreateOauth2Option required options for creating an Application | // CreateOauth2Option required options for creating an Application | ||||||
| type CreateOauth2Option struct { | type CreateOauth2Option struct { | ||||||
| 	Name               string   `json:"name"` | 	Name               string   `json:"name"` | ||||||
|  | 	ConfidentialClient bool     `json:"confidential_client"` | ||||||
| 	RedirectURIs       []string `json:"redirect_uris"` | 	RedirectURIs       []string `json:"redirect_uris"` | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										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 | ||||||
|  | } | ||||||
							
								
								
									
										606
									
								
								vendor/github.com/Masterminds/semver/v3/version.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										606
									
								
								vendor/github.com/Masterminds/semver/v3/version.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,606 @@ | |||||||
|  | package semver | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"database/sql/driver" | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"regexp" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // The compiled version of the regex created at init() is cached here so it | ||||||
|  | // only needs to be created once. | ||||||
|  | var versionRegex *regexp.Regexp | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	// ErrInvalidSemVer is returned a version is found to be invalid when | ||||||
|  | 	// being parsed. | ||||||
|  | 	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 = errors.New("Invalid Metadata string") | ||||||
|  |  | ||||||
|  | 	// ErrInvalidPrerelease is returned when the pre-release is an invalid format | ||||||
|  | 	ErrInvalidPrerelease = errors.New("Invalid Prerelease string") | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // semVerRegex is the regular expression used to parse a semantic version. | ||||||
|  | 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\-]+)*))?` | ||||||
|  |  | ||||||
|  | // Version represents a single semantic version. | ||||||
|  | type Version struct { | ||||||
|  | 	major, minor, patch uint64 | ||||||
|  | 	pre                 string | ||||||
|  | 	metadata            string | ||||||
|  | 	original            string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func init() { | ||||||
|  | 	versionRegex = regexp.MustCompile("^" + semVerRegex + "$") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  | // 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) { | ||||||
|  | 	m := versionRegex.FindStringSubmatch(v) | ||||||
|  | 	if m == nil { | ||||||
|  | 		return nil, ErrInvalidSemVer | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	sv := &Version{ | ||||||
|  | 		metadata: m[8], | ||||||
|  | 		pre:      m[5], | ||||||
|  | 		original: v, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var err error | ||||||
|  | 	sv.major, err = strconv.ParseUint(m[1], 10, 64) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("Error parsing version segment: %s", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if m[2] != "" { | ||||||
|  | 		sv.minor, err = strconv.ParseUint(strings.TrimPrefix(m[2], "."), 10, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf("Error parsing version segment: %s", err) | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		sv.minor = 0 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if m[3] != "" { | ||||||
|  | 		sv.patch, err = strconv.ParseUint(strings.TrimPrefix(m[3], "."), 10, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf("Error parsing version segment: %s", err) | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // MustParse parses a given version and panics on error. | ||||||
|  | func MustParse(v string) *Version { | ||||||
|  | 	sv, err := NewVersion(v) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 	return sv | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String converts a Version object to a string. | ||||||
|  | // Note, if the original version contained a leading v this version will not. | ||||||
|  | // 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 | ||||||
|  | // implementation. | ||||||
|  | func (v Version) String() string { | ||||||
|  | 	var buf bytes.Buffer | ||||||
|  |  | ||||||
|  | 	fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch) | ||||||
|  | 	if v.pre != "" { | ||||||
|  | 		fmt.Fprintf(&buf, "-%s", v.pre) | ||||||
|  | 	} | ||||||
|  | 	if v.metadata != "" { | ||||||
|  | 		fmt.Fprintf(&buf, "+%s", v.metadata) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return buf.String() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Original returns the original value passed in to be parsed. | ||||||
|  | func (v *Version) Original() string { | ||||||
|  | 	return v.original | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Major returns the major version. | ||||||
|  | func (v Version) Major() uint64 { | ||||||
|  | 	return v.major | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Minor returns the minor version. | ||||||
|  | func (v Version) Minor() uint64 { | ||||||
|  | 	return v.minor | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Patch returns the patch version. | ||||||
|  | func (v Version) Patch() uint64 { | ||||||
|  | 	return v.patch | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Prerelease returns the pre-release version. | ||||||
|  | func (v Version) Prerelease() string { | ||||||
|  | 	return v.pre | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Metadata returns the metadata on the version. | ||||||
|  | func (v Version) Metadata() string { | ||||||
|  | 	return v.metadata | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // originalVPrefix returns the original 'v' prefix if any. | ||||||
|  | func (v Version) originalVPrefix() string { | ||||||
|  |  | ||||||
|  | 	// Note, only lowercase v is supported as a prefix by the parser. | ||||||
|  | 	if v.original != "" && v.original[:1] == "v" { | ||||||
|  | 		return v.original[:1] | ||||||
|  | 	} | ||||||
|  | 	return "" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IncPatch produces the next patch version. | ||||||
|  | // If the current version does not have prerelease/metadata information, | ||||||
|  | // it unsets metadata and prerelease values, increments patch number. | ||||||
|  | // If the current version has any of prerelease or metadata information, | ||||||
|  | // it unsets both values and keeps current patch value | ||||||
|  | func (v Version) IncPatch() Version { | ||||||
|  | 	vNext := v | ||||||
|  | 	// according to http://semver.org/#spec-item-9 | ||||||
|  | 	// Pre-release versions have a lower precedence than the associated normal version. | ||||||
|  | 	// according to http://semver.org/#spec-item-10 | ||||||
|  | 	// Build metadata SHOULD be ignored when determining version precedence. | ||||||
|  | 	if v.pre != "" { | ||||||
|  | 		vNext.metadata = "" | ||||||
|  | 		vNext.pre = "" | ||||||
|  | 	} else { | ||||||
|  | 		vNext.metadata = "" | ||||||
|  | 		vNext.pre = "" | ||||||
|  | 		vNext.patch = v.patch + 1 | ||||||
|  | 	} | ||||||
|  | 	vNext.original = v.originalVPrefix() + "" + vNext.String() | ||||||
|  | 	return vNext | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IncMinor produces the next minor version. | ||||||
|  | // Sets patch to 0. | ||||||
|  | // Increments minor number. | ||||||
|  | // Unsets metadata. | ||||||
|  | // Unsets prerelease status. | ||||||
|  | func (v Version) IncMinor() Version { | ||||||
|  | 	vNext := v | ||||||
|  | 	vNext.metadata = "" | ||||||
|  | 	vNext.pre = "" | ||||||
|  | 	vNext.patch = 0 | ||||||
|  | 	vNext.minor = v.minor + 1 | ||||||
|  | 	vNext.original = v.originalVPrefix() + "" + vNext.String() | ||||||
|  | 	return vNext | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IncMajor produces the next major version. | ||||||
|  | // Sets patch to 0. | ||||||
|  | // Sets minor to 0. | ||||||
|  | // Increments major number. | ||||||
|  | // Unsets metadata. | ||||||
|  | // Unsets prerelease status. | ||||||
|  | func (v Version) IncMajor() Version { | ||||||
|  | 	vNext := v | ||||||
|  | 	vNext.metadata = "" | ||||||
|  | 	vNext.pre = "" | ||||||
|  | 	vNext.patch = 0 | ||||||
|  | 	vNext.minor = 0 | ||||||
|  | 	vNext.major = v.major + 1 | ||||||
|  | 	vNext.original = v.originalVPrefix() + "" + vNext.String() | ||||||
|  | 	return vNext | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetPrerelease defines the prerelease value. | ||||||
|  | // Value must not include the required 'hyphen' prefix. | ||||||
|  | func (v Version) SetPrerelease(prerelease string) (Version, error) { | ||||||
|  | 	vNext := v | ||||||
|  | 	if len(prerelease) > 0 { | ||||||
|  | 		if err := validatePrerelease(prerelease); err != nil { | ||||||
|  | 			return vNext, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	vNext.pre = prerelease | ||||||
|  | 	vNext.original = v.originalVPrefix() + "" + vNext.String() | ||||||
|  | 	return vNext, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetMetadata defines metadata value. | ||||||
|  | // Value must not include the required 'plus' prefix. | ||||||
|  | func (v Version) SetMetadata(metadata string) (Version, error) { | ||||||
|  | 	vNext := v | ||||||
|  | 	if len(metadata) > 0 { | ||||||
|  | 		if err := validateMetadata(metadata); err != nil { | ||||||
|  | 			return vNext, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	vNext.metadata = metadata | ||||||
|  | 	vNext.original = v.originalVPrefix() + "" + vNext.String() | ||||||
|  | 	return vNext, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // LessThan tests if one version is less than another one. | ||||||
|  | func (v *Version) LessThan(o *Version) bool { | ||||||
|  | 	return v.Compare(o) < 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GreaterThan tests if one version is greater than another one. | ||||||
|  | func (v *Version) GreaterThan(o *Version) bool { | ||||||
|  | 	return v.Compare(o) > 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Equal tests if two versions are equal to each other. | ||||||
|  | // Note, versions can be equal with different metadata since metadata | ||||||
|  | // is not considered part of the comparable version. | ||||||
|  | func (v *Version) Equal(o *Version) bool { | ||||||
|  | 	return v.Compare(o) == 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Compare compares this version to another one. It returns -1, 0, or 1 if | ||||||
|  | // the version smaller, equal, or larger than the other version. | ||||||
|  | // | ||||||
|  | // Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is | ||||||
|  | // 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 { | ||||||
|  | 	// Compare the major, minor, and patch version for differences. If a | ||||||
|  | 	// difference is found return the comparison. | ||||||
|  | 	if d := compareSegment(v.Major(), o.Major()); d != 0 { | ||||||
|  | 		return d | ||||||
|  | 	} | ||||||
|  | 	if d := compareSegment(v.Minor(), o.Minor()); d != 0 { | ||||||
|  | 		return d | ||||||
|  | 	} | ||||||
|  | 	if d := compareSegment(v.Patch(), o.Patch()); d != 0 { | ||||||
|  | 		return d | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// At this point the major, minor, and patch versions are the same. | ||||||
|  | 	ps := v.pre | ||||||
|  | 	po := o.Prerelease() | ||||||
|  |  | ||||||
|  | 	if ps == "" && po == "" { | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  | 	if ps == "" { | ||||||
|  | 		return 1 | ||||||
|  | 	} | ||||||
|  | 	if po == "" { | ||||||
|  | 		return -1 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return comparePrerelease(ps, po) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // UnmarshalJSON implements JSON.Unmarshaler interface. | ||||||
|  | func (v *Version) UnmarshalJSON(b []byte) error { | ||||||
|  | 	var s string | ||||||
|  | 	if err := json.Unmarshal(b, &s); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // MarshalJSON implements JSON.Marshaler interface. | ||||||
|  | func (v Version) MarshalJSON() ([]byte, error) { | ||||||
|  | 	return json.Marshal(v.String()) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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 { | ||||||
|  | 		return -1 | ||||||
|  | 	} | ||||||
|  | 	if v > o { | ||||||
|  | 		return 1 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func comparePrerelease(v, o string) int { | ||||||
|  |  | ||||||
|  | 	// split the prelease versions by their part. The separator, per the spec, | ||||||
|  | 	// is a . | ||||||
|  | 	sparts := strings.Split(v, ".") | ||||||
|  | 	oparts := strings.Split(o, ".") | ||||||
|  |  | ||||||
|  | 	// Find the longer length of the parts to know how many loop iterations to | ||||||
|  | 	// go through. | ||||||
|  | 	slen := len(sparts) | ||||||
|  | 	olen := len(oparts) | ||||||
|  |  | ||||||
|  | 	l := slen | ||||||
|  | 	if olen > slen { | ||||||
|  | 		l = olen | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Iterate over each part of the prereleases to compare the differences. | ||||||
|  | 	for i := 0; i < l; i++ { | ||||||
|  | 		// Since the lentgh of the parts can be different we need to create | ||||||
|  | 		// a placeholder. This is to avoid out of bounds issues. | ||||||
|  | 		stemp := "" | ||||||
|  | 		if i < slen { | ||||||
|  | 			stemp = sparts[i] | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		otemp := "" | ||||||
|  | 		if i < olen { | ||||||
|  | 			otemp = oparts[i] | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		d := comparePrePart(stemp, otemp) | ||||||
|  | 		if d != 0 { | ||||||
|  | 			return d | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Reaching here means two versions are of equal value but have different | ||||||
|  | 	// metadata (the part following a +). They are not identical in string form | ||||||
|  | 	// but the version comparison finds them to be equal. | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func comparePrePart(s, o string) int { | ||||||
|  | 	// Fastpath if they are equal | ||||||
|  | 	if s == o { | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// When s or o are empty we can use the other in an attempt to determine | ||||||
|  | 	// the response. | ||||||
|  | 	if s == "" { | ||||||
|  | 		if o != "" { | ||||||
|  | 			return -1 | ||||||
|  | 		} | ||||||
|  | 		return 1 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o == "" { | ||||||
|  | 		if s != "" { | ||||||
|  | 			return 1 | ||||||
|  | 		} | ||||||
|  | 		return -1 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// When comparing strings "99" is greater than "103". To handle | ||||||
|  | 	// cases like this we need to detect numbers and compare them. According | ||||||
|  | 	// to the semver spec, numbers are always positive. If there is a - at the | ||||||
|  | 	// start like -99 this is to be evaluated as an alphanum. numbers always | ||||||
|  | 	// have precedence over alphanum. Parsing as Uints because negative numbers | ||||||
|  | 	// are ignored. | ||||||
|  |  | ||||||
|  | 	oi, n1 := strconv.ParseUint(o, 10, 64) | ||||||
|  | 	si, n2 := strconv.ParseUint(s, 10, 64) | ||||||
|  |  | ||||||
|  | 	// The case where both are strings compare the strings | ||||||
|  | 	if n1 != nil && n2 != nil { | ||||||
|  | 		if s > o { | ||||||
|  | 			return 1 | ||||||
|  | 		} | ||||||
|  | 		return -1 | ||||||
|  | 	} else if n1 != nil { | ||||||
|  | 		// o is a string and s is a number | ||||||
|  | 		return -1 | ||||||
|  | 	} else if n2 != nil { | ||||||
|  | 		// s is a string and o is a number | ||||||
|  | 		return 1 | ||||||
|  | 	} | ||||||
|  | 	// Both are numbers | ||||||
|  | 	if si > oi { | ||||||
|  | 		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 | ||||||
|  | } | ||||||
							
								
								
									
										425
									
								
								vendor/github.com/Masterminds/semver/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										425
									
								
								vendor/github.com/Masterminds/semver/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,425 +0,0 @@ | |||||||
| package semver |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"encoding/json" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"regexp" |  | ||||||
| 	"strconv" |  | ||||||
| 	"strings" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // The compiled version of the regex created at init() is cached here so it |  | ||||||
| // only needs to be created once. |  | ||||||
| var versionRegex *regexp.Regexp |  | ||||||
| var validPrereleaseRegex *regexp.Regexp |  | ||||||
|  |  | ||||||
| var ( |  | ||||||
| 	// ErrInvalidSemVer is returned a version is found to be invalid when |  | ||||||
| 	// being parsed. |  | ||||||
| 	ErrInvalidSemVer = errors.New("Invalid Semantic Version") |  | ||||||
|  |  | ||||||
| 	// ErrInvalidMetadata is returned when the metadata is an invalid format |  | ||||||
| 	ErrInvalidMetadata = errors.New("Invalid Metadata string") |  | ||||||
|  |  | ||||||
| 	// ErrInvalidPrerelease is returned when the pre-release is an invalid format |  | ||||||
| 	ErrInvalidPrerelease = errors.New("Invalid Prerelease string") |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // SemVerRegex is the regular expression used to parse a semantic version. |  | ||||||
| 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\-]+)*))?` |  | ||||||
|  |  | ||||||
| // 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. |  | ||||||
| type Version struct { |  | ||||||
| 	major, minor, patch int64 |  | ||||||
| 	pre                 string |  | ||||||
| 	metadata            string |  | ||||||
| 	original            string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func init() { |  | ||||||
| 	versionRegex = regexp.MustCompile("^" + SemVerRegex + "$") |  | ||||||
| 	validPrereleaseRegex = regexp.MustCompile(ValidPrerelease) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // NewVersion parses a given version and returns an instance of Version or |  | ||||||
| // an error if unable to parse the version. |  | ||||||
| func NewVersion(v string) (*Version, error) { |  | ||||||
| 	m := versionRegex.FindStringSubmatch(v) |  | ||||||
| 	if m == nil { |  | ||||||
| 		return nil, ErrInvalidSemVer |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	sv := &Version{ |  | ||||||
| 		metadata: m[8], |  | ||||||
| 		pre:      m[5], |  | ||||||
| 		original: v, |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	var temp int64 |  | ||||||
| 	temp, err := strconv.ParseInt(m[1], 10, 64) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, fmt.Errorf("Error parsing version segment: %s", err) |  | ||||||
| 	} |  | ||||||
| 	sv.major = temp |  | ||||||
|  |  | ||||||
| 	if m[2] != "" { |  | ||||||
| 		temp, err = strconv.ParseInt(strings.TrimPrefix(m[2], "."), 10, 64) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, fmt.Errorf("Error parsing version segment: %s", err) |  | ||||||
| 		} |  | ||||||
| 		sv.minor = temp |  | ||||||
| 	} else { |  | ||||||
| 		sv.minor = 0 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if m[3] != "" { |  | ||||||
| 		temp, err = strconv.ParseInt(strings.TrimPrefix(m[3], "."), 10, 64) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, fmt.Errorf("Error parsing version segment: %s", err) |  | ||||||
| 		} |  | ||||||
| 		sv.patch = temp |  | ||||||
| 	} else { |  | ||||||
| 		sv.patch = 0 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return sv, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // MustParse parses a given version and panics on error. |  | ||||||
| func MustParse(v string) *Version { |  | ||||||
| 	sv, err := NewVersion(v) |  | ||||||
| 	if err != nil { |  | ||||||
| 		panic(err) |  | ||||||
| 	} |  | ||||||
| 	return sv |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String converts a Version object to a string. |  | ||||||
| // Note, if the original version contained a leading v this version will not. |  | ||||||
| // 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 |  | ||||||
| // implementation. |  | ||||||
| func (v *Version) String() string { |  | ||||||
| 	var buf bytes.Buffer |  | ||||||
|  |  | ||||||
| 	fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch) |  | ||||||
| 	if v.pre != "" { |  | ||||||
| 		fmt.Fprintf(&buf, "-%s", v.pre) |  | ||||||
| 	} |  | ||||||
| 	if v.metadata != "" { |  | ||||||
| 		fmt.Fprintf(&buf, "+%s", v.metadata) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return buf.String() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Original returns the original value passed in to be parsed. |  | ||||||
| func (v *Version) Original() string { |  | ||||||
| 	return v.original |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Major returns the major version. |  | ||||||
| func (v *Version) Major() int64 { |  | ||||||
| 	return v.major |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Minor returns the minor version. |  | ||||||
| func (v *Version) Minor() int64 { |  | ||||||
| 	return v.minor |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Patch returns the patch version. |  | ||||||
| func (v *Version) Patch() int64 { |  | ||||||
| 	return v.patch |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Prerelease returns the pre-release version. |  | ||||||
| func (v *Version) Prerelease() string { |  | ||||||
| 	return v.pre |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Metadata returns the metadata on the version. |  | ||||||
| func (v *Version) Metadata() string { |  | ||||||
| 	return v.metadata |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // originalVPrefix returns the original 'v' prefix if any. |  | ||||||
| func (v *Version) originalVPrefix() string { |  | ||||||
|  |  | ||||||
| 	// Note, only lowercase v is supported as a prefix by the parser. |  | ||||||
| 	if v.original != "" && v.original[:1] == "v" { |  | ||||||
| 		return v.original[:1] |  | ||||||
| 	} |  | ||||||
| 	return "" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IncPatch produces the next patch version. |  | ||||||
| // If the current version does not have prerelease/metadata information, |  | ||||||
| // it unsets metadata and prerelease values, increments patch number. |  | ||||||
| // If the current version has any of prerelease or metadata information, |  | ||||||
| // it unsets both values and keeps curent patch value |  | ||||||
| func (v Version) IncPatch() Version { |  | ||||||
| 	vNext := v |  | ||||||
| 	// according to http://semver.org/#spec-item-9 |  | ||||||
| 	// Pre-release versions have a lower precedence than the associated normal version. |  | ||||||
| 	// according to http://semver.org/#spec-item-10 |  | ||||||
| 	// Build metadata SHOULD be ignored when determining version precedence. |  | ||||||
| 	if v.pre != "" { |  | ||||||
| 		vNext.metadata = "" |  | ||||||
| 		vNext.pre = "" |  | ||||||
| 	} else { |  | ||||||
| 		vNext.metadata = "" |  | ||||||
| 		vNext.pre = "" |  | ||||||
| 		vNext.patch = v.patch + 1 |  | ||||||
| 	} |  | ||||||
| 	vNext.original = v.originalVPrefix() + "" + vNext.String() |  | ||||||
| 	return vNext |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IncMinor produces the next minor version. |  | ||||||
| // Sets patch to 0. |  | ||||||
| // Increments minor number. |  | ||||||
| // Unsets metadata. |  | ||||||
| // Unsets prerelease status. |  | ||||||
| func (v Version) IncMinor() Version { |  | ||||||
| 	vNext := v |  | ||||||
| 	vNext.metadata = "" |  | ||||||
| 	vNext.pre = "" |  | ||||||
| 	vNext.patch = 0 |  | ||||||
| 	vNext.minor = v.minor + 1 |  | ||||||
| 	vNext.original = v.originalVPrefix() + "" + vNext.String() |  | ||||||
| 	return vNext |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IncMajor produces the next major version. |  | ||||||
| // Sets patch to 0. |  | ||||||
| // Sets minor to 0. |  | ||||||
| // Increments major number. |  | ||||||
| // Unsets metadata. |  | ||||||
| // Unsets prerelease status. |  | ||||||
| func (v Version) IncMajor() Version { |  | ||||||
| 	vNext := v |  | ||||||
| 	vNext.metadata = "" |  | ||||||
| 	vNext.pre = "" |  | ||||||
| 	vNext.patch = 0 |  | ||||||
| 	vNext.minor = 0 |  | ||||||
| 	vNext.major = v.major + 1 |  | ||||||
| 	vNext.original = v.originalVPrefix() + "" + vNext.String() |  | ||||||
| 	return vNext |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // SetPrerelease defines the prerelease value. |  | ||||||
| // Value must not include the required 'hypen' prefix. |  | ||||||
| func (v Version) SetPrerelease(prerelease string) (Version, error) { |  | ||||||
| 	vNext := v |  | ||||||
| 	if len(prerelease) > 0 && !validPrereleaseRegex.MatchString(prerelease) { |  | ||||||
| 		return vNext, ErrInvalidPrerelease |  | ||||||
| 	} |  | ||||||
| 	vNext.pre = prerelease |  | ||||||
| 	vNext.original = v.originalVPrefix() + "" + vNext.String() |  | ||||||
| 	return vNext, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // SetMetadata defines metadata value. |  | ||||||
| // Value must not include the required 'plus' prefix. |  | ||||||
| func (v Version) SetMetadata(metadata string) (Version, error) { |  | ||||||
| 	vNext := v |  | ||||||
| 	if len(metadata) > 0 && !validPrereleaseRegex.MatchString(metadata) { |  | ||||||
| 		return vNext, ErrInvalidMetadata |  | ||||||
| 	} |  | ||||||
| 	vNext.metadata = metadata |  | ||||||
| 	vNext.original = v.originalVPrefix() + "" + vNext.String() |  | ||||||
| 	return vNext, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // LessThan tests if one version is less than another one. |  | ||||||
| func (v *Version) LessThan(o *Version) bool { |  | ||||||
| 	return v.Compare(o) < 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GreaterThan tests if one version is greater than another one. |  | ||||||
| func (v *Version) GreaterThan(o *Version) bool { |  | ||||||
| 	return v.Compare(o) > 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Equal tests if two versions are equal to each other. |  | ||||||
| // Note, versions can be equal with different metadata since metadata |  | ||||||
| // is not considered part of the comparable version. |  | ||||||
| func (v *Version) Equal(o *Version) bool { |  | ||||||
| 	return v.Compare(o) == 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Compare compares this version to another one. It returns -1, 0, or 1 if |  | ||||||
| // the version smaller, equal, or larger than the other version. |  | ||||||
| // |  | ||||||
| // Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is |  | ||||||
| // lower than the version without a prerelease. |  | ||||||
| func (v *Version) Compare(o *Version) int { |  | ||||||
| 	// Compare the major, minor, and patch version for differences. If a |  | ||||||
| 	// difference is found return the comparison. |  | ||||||
| 	if d := compareSegment(v.Major(), o.Major()); d != 0 { |  | ||||||
| 		return d |  | ||||||
| 	} |  | ||||||
| 	if d := compareSegment(v.Minor(), o.Minor()); d != 0 { |  | ||||||
| 		return d |  | ||||||
| 	} |  | ||||||
| 	if d := compareSegment(v.Patch(), o.Patch()); d != 0 { |  | ||||||
| 		return d |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// At this point the major, minor, and patch versions are the same. |  | ||||||
| 	ps := v.pre |  | ||||||
| 	po := o.Prerelease() |  | ||||||
|  |  | ||||||
| 	if ps == "" && po == "" { |  | ||||||
| 		return 0 |  | ||||||
| 	} |  | ||||||
| 	if ps == "" { |  | ||||||
| 		return 1 |  | ||||||
| 	} |  | ||||||
| 	if po == "" { |  | ||||||
| 		return -1 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return comparePrerelease(ps, po) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // UnmarshalJSON implements JSON.Unmarshaler interface. |  | ||||||
| func (v *Version) UnmarshalJSON(b []byte) error { |  | ||||||
| 	var s string |  | ||||||
| 	if err := json.Unmarshal(b, &s); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	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 |  | ||||||
| 	temp = nil |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // MarshalJSON implements JSON.Marshaler interface. |  | ||||||
| func (v *Version) MarshalJSON() ([]byte, error) { |  | ||||||
| 	return json.Marshal(v.String()) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func compareSegment(v, o int64) int { |  | ||||||
| 	if v < o { |  | ||||||
| 		return -1 |  | ||||||
| 	} |  | ||||||
| 	if v > o { |  | ||||||
| 		return 1 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func comparePrerelease(v, o string) int { |  | ||||||
|  |  | ||||||
| 	// split the prelease versions by their part. The separator, per the spec, |  | ||||||
| 	// is a . |  | ||||||
| 	sparts := strings.Split(v, ".") |  | ||||||
| 	oparts := strings.Split(o, ".") |  | ||||||
|  |  | ||||||
| 	// Find the longer length of the parts to know how many loop iterations to |  | ||||||
| 	// go through. |  | ||||||
| 	slen := len(sparts) |  | ||||||
| 	olen := len(oparts) |  | ||||||
|  |  | ||||||
| 	l := slen |  | ||||||
| 	if olen > slen { |  | ||||||
| 		l = olen |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Iterate over each part of the prereleases to compare the differences. |  | ||||||
| 	for i := 0; i < l; i++ { |  | ||||||
| 		// Since the lentgh of the parts can be different we need to create |  | ||||||
| 		// a placeholder. This is to avoid out of bounds issues. |  | ||||||
| 		stemp := "" |  | ||||||
| 		if i < slen { |  | ||||||
| 			stemp = sparts[i] |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		otemp := "" |  | ||||||
| 		if i < olen { |  | ||||||
| 			otemp = oparts[i] |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		d := comparePrePart(stemp, otemp) |  | ||||||
| 		if d != 0 { |  | ||||||
| 			return d |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Reaching here means two versions are of equal value but have different |  | ||||||
| 	// metadata (the part following a +). They are not identical in string form |  | ||||||
| 	// but the version comparison finds them to be equal. |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func comparePrePart(s, o string) int { |  | ||||||
| 	// Fastpath if they are equal |  | ||||||
| 	if s == o { |  | ||||||
| 		return 0 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// When s or o are empty we can use the other in an attempt to determine |  | ||||||
| 	// the response. |  | ||||||
| 	if s == "" { |  | ||||||
| 		if o != "" { |  | ||||||
| 			return -1 |  | ||||||
| 		} |  | ||||||
| 		return 1 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if o == "" { |  | ||||||
| 		if s != "" { |  | ||||||
| 			return 1 |  | ||||||
| 		} |  | ||||||
| 		return -1 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// When comparing strings "99" is greater than "103". To handle |  | ||||||
| 	// cases like this we need to detect numbers and compare them. According |  | ||||||
| 	// to the semver spec, numbers are always positive. If there is a - at the |  | ||||||
| 	// start like -99 this is to be evaluated as an alphanum. numbers always |  | ||||||
| 	// have precedence over alphanum. Parsing as Uints because negative numbers |  | ||||||
| 	// are ignored. |  | ||||||
|  |  | ||||||
| 	oi, n1 := strconv.ParseUint(o, 10, 64) |  | ||||||
| 	si, n2 := strconv.ParseUint(s, 10, 64) |  | ||||||
|  |  | ||||||
| 	// The case where both are strings compare the strings |  | ||||||
| 	if n1 != nil && n2 != nil { |  | ||||||
| 		if s > o { |  | ||||||
| 			return 1 |  | ||||||
| 		} |  | ||||||
| 		return -1 |  | ||||||
| 	} else if n1 != nil { |  | ||||||
| 		// o is a string and s is a number |  | ||||||
| 		return -1 |  | ||||||
| 	} else if n2 != nil { |  | ||||||
| 		// s is a string and o is a number |  | ||||||
| 		return 1 |  | ||||||
| 	} |  | ||||||
| 	// Both are numbers |  | ||||||
| 	if si > oi { |  | ||||||
| 		return 1 |  | ||||||
| 	} |  | ||||||
| 	return -1 |  | ||||||
|  |  | ||||||
| } |  | ||||||
							
								
								
									
										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 |  | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user