Compare commits
64 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
601cc245ef | ||
|
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 |
@ -30,6 +30,7 @@ steps:
|
||||
- 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:
|
||||
@ -59,6 +60,7 @@ steps:
|
||||
GPG_PRIVATE_KEY_BASE64:
|
||||
from_secret: GPG_PRIVATE_KEY_BASE64
|
||||
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
|
||||
- gpg-agent --daemon --default-cache-ttl 7200
|
||||
- echo $GPG_PRIVATE_KEY_BASE64 | base64 -d | gpg --import --batch --no-tty
|
||||
|
15
.github/dependabot.yml
vendored
Normal file
15
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "gomod"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
27
.github/workflows/release.yml
vendored
27
.github/workflows/release.yml
vendored
@ -18,30 +18,29 @@ jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Unshallow
|
||||
- name: Unshallow
|
||||
run: git fetch --prune --unshallow
|
||||
-
|
||||
name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: 1.18
|
||||
-
|
||||
name: Import GPG key
|
||||
- name: Import GPG key
|
||||
id: import_gpg
|
||||
uses: crazy-max/ghaction-import-gpg@v5.0.0
|
||||
uses: crazy-max/ghaction-import-gpg@v5.3.0
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
passphrase: ${{ secrets.PASSPHRASE }}
|
||||
-
|
||||
name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v3.0.0
|
||||
- name: setup-syft
|
||||
run: |
|
||||
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | \
|
||||
sh -s -- -b /usr/local/bin v0.64.0
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v4.3.0
|
||||
with:
|
||||
version: latest
|
||||
args: release --rm-dist
|
||||
args: release --clean
|
||||
env:
|
||||
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
|
||||
# GitHub sets this automatically
|
||||
|
@ -41,6 +41,8 @@ checksum:
|
||||
name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
|
||||
name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS'
|
||||
algorithm: sha256
|
||||
sboms:
|
||||
- artifacts: archive
|
||||
signs:
|
||||
- artifacts: checksum
|
||||
args:
|
||||
|
10
Makefile
10
Makefile
@ -1,9 +1,11 @@
|
||||
TEST?=./gitea
|
||||
GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor)
|
||||
ARCH?=$$(uname -m)
|
||||
KERNEL?=$$(uname -s | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
GOFMT ?= gofmt -s
|
||||
|
||||
VERSION = 0.9.0
|
||||
VERSION = 0.16.0
|
||||
|
||||
test: fmt-check
|
||||
go test -i $(TEST) || exit 1
|
||||
@ -34,8 +36,8 @@ build:
|
||||
go build -ldflags="-X 'main.Version=${VERSION}'" -o terraform-provider-gitea_${VERSION}
|
||||
install: build
|
||||
@echo installing to
|
||||
@echo ~/.terraform.d/plugins/terraform.local/lerentis/gitea/${VERSION}/linux_amd64/terraform-provider-gitea_${VERSION}
|
||||
@mkdir -p ~/.terraform.d/plugins/terraform.local/lerentis/gitea/${VERSION}/linux_amd64
|
||||
@mv terraform-provider-gitea_${VERSION} ~/.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}/${KERNEL}_${ARCH}
|
||||
@mv terraform-provider-gitea_${VERSION} ~/.terraform.d/plugins/terraform.local/lerentis/gitea/${VERSION}/${KERNEL}_${ARCH}/terraform-provider-gitea_${VERSION}
|
||||
doc:
|
||||
tfplugindocs
|
||||
|
@ -17,7 +17,7 @@ terraform {
|
||||
required_providers {
|
||||
gitea = {
|
||||
source = "Lerentis/gitea"
|
||||
version = "0.9.0"
|
||||
version = "0.16.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ terraform {
|
||||
required_providers {
|
||||
gitea = {
|
||||
source = "Lerentis/gitea"
|
||||
version = "0.9.0"
|
||||
version = "0.16.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,10 @@ Handling [gitea oauth application](https://docs.gitea.io/en-us/oauth2-provider/)
|
||||
- `name` (String) OAuth Application name
|
||||
- `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
|
||||
|
||||
- `client_id` (String) OAuth2 Application client id
|
||||
|
@ -46,5 +46,6 @@ resource "gitea_repository" "org_repo" {
|
||||
|
||||
- `avatar_url` (String)
|
||||
- `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.).
|
||||
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_.
|
||||
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)
|
||||
@ -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.
|
||||
|
||||
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
|
||||
|
||||
@ -39,6 +41,16 @@ resource "gitea_repository" "mirror" {
|
||||
migration_service = "gitea"
|
||||
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 -->
|
||||
@ -92,11 +104,14 @@ Need to exist in the gitea instance
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `clone_url` (String)
|
||||
- `created` (String)
|
||||
- `html_url` (String)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `permission_admin` (Boolean)
|
||||
- `permission_pull` (Boolean)
|
||||
- `permission_push` (Boolean)
|
||||
- `ssh_url` (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"
|
||||
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 -->
|
||||
@ -52,6 +72,7 @@ resource "gitea_team" "test_team" {
|
||||
- `members` (List of String) List of Users that should be part of this team
|
||||
- `permission` (String) Permissions associated with this Team
|
||||
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.
|
||||
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
|
||||
|
||||
|
@ -94,4 +94,44 @@ 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
|
||||
}
|
||||
|
@ -2,12 +2,14 @@ terraform {
|
||||
required_providers {
|
||||
gitea = {
|
||||
source = "terraform.local/lerentis/gitea"
|
||||
version = "0.9.0"
|
||||
version = "0.16.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "gitea" {
|
||||
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 {
|
||||
gitea = {
|
||||
source = "Lerentis/gitea"
|
||||
version = "0.9.0"
|
||||
version = "0.16.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,3 +16,13 @@ resource "gitea_repository" "mirror" {
|
||||
migration_service = "gitea"
|
||||
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"
|
||||
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
|
||||
}
|
@ -8,4 +8,8 @@ variable "gitea_token" {
|
||||
|
||||
variable "gitea_mirror_token" {
|
||||
|
||||
}
|
||||
|
||||
variable "gitea_password" {
|
||||
|
||||
}
|
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging"
|
||||
@ -28,8 +29,7 @@ func (c *Config) Client() (interface{}, error) {
|
||||
return nil, fmt.Errorf("either a token or a username needs to be used")
|
||||
}
|
||||
// Configure TLS/SSL
|
||||
tlsConfig := &tls.Config{}
|
||||
|
||||
var tlsConfig tls.Config
|
||||
// If a CACertFile has been specified, use that for cert validation
|
||||
if 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 c.Insecure {
|
||||
tlsConfig.InsecureSkipVerify = true
|
||||
}
|
||||
tlsConfig.InsecureSkipVerify = c.Insecure
|
||||
|
||||
t := http.DefaultTransport.(*http.Transport).Clone()
|
||||
t.TLSClientConfig = tlsConfig
|
||||
t.TLSClientConfig = &tlsConfig
|
||||
t.MaxIdleConnsPerHost = 100
|
||||
t.TLSHandshakeTimeout = 10 * time.Second
|
||||
|
||||
httpClient := &http.Client{
|
||||
Transport: logging.NewTransport("Gitea", t),
|
||||
@ -60,16 +59,23 @@ func (c *Config) Client() (interface{}, error) {
|
||||
}
|
||||
|
||||
var client *gitea.Client
|
||||
var err error
|
||||
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 != "" {
|
||||
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.
|
||||
_, _, err := client.GetMyUserInfo()
|
||||
_, _, err = client.GetMyUserInfo()
|
||||
|
||||
return client, err
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ func dataSourceGiteaRepoRead(d *schema.ResourceData, meta interface{}) error {
|
||||
}
|
||||
username := strings.ToLower(usernameData.(string))
|
||||
|
||||
nameData, nameOk := d.GetOk("username")
|
||||
nameData, nameOk := d.GetOk("name")
|
||||
if !nameOk {
|
||||
return fmt.Errorf("name of repo must be passed")
|
||||
}
|
||||
|
@ -75,13 +75,15 @@ func Provider() *schema.Provider {
|
||||
"gitea_org": resourceGiteaOrg(),
|
||||
// "gitea_team": resourceGiteaTeam(),
|
||||
// "gitea_repo": resourceGiteaRepo(),
|
||||
"gitea_user": resourceGiteaUser(),
|
||||
"gitea_oauth2_app": resourceGiteaOauthApp(),
|
||||
"gitea_repository": resourceGiteaRepository(),
|
||||
"gitea_fork": resourceGiteaFork(),
|
||||
"gitea_public_key": resourceGiteaPublicKey(),
|
||||
"gitea_team": resourceGiteaTeam(),
|
||||
"gitea_git_hook": resourceGiteaGitHook(),
|
||||
"gitea_user": resourceGiteaUser(),
|
||||
"gitea_oauth2_app": resourceGiteaOauthApp(),
|
||||
"gitea_repository": resourceGiteaRepository(),
|
||||
"gitea_fork": resourceGiteaFork(),
|
||||
"gitea_public_key": resourceGiteaPublicKey(),
|
||||
"gitea_team": resourceGiteaTeam(),
|
||||
"gitea_git_hook": resourceGiteaGitHook(),
|
||||
"gitea_token": resourceGiteaToken(),
|
||||
"gitea_repository_key": resourceGiteaRepositoryKey(),
|
||||
},
|
||||
|
||||
ConfigureFunc: providerConfigure,
|
||||
|
@ -8,10 +8,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
oauth2KeyName string = "name"
|
||||
oauth2KeyRedirectURIs string = "redirect_uris"
|
||||
oauth2KeyClientId string = "client_id"
|
||||
oauth2KeyClientSecret string = "client_secret"
|
||||
oauth2KeyName string = "name"
|
||||
oauth2KeyConfidentialClient string = "confidential_client"
|
||||
oauth2KeyRedirectURIs string = "redirect_uris"
|
||||
oauth2KeyClientId string = "client_id"
|
||||
oauth2KeyClientSecret string = "client_secret"
|
||||
)
|
||||
|
||||
func resourceGiteaOauthApp() *schema.Resource {
|
||||
@ -37,6 +38,12 @@ func resourceGiteaOauthApp() *schema.Resource {
|
||||
},
|
||||
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: {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
@ -89,9 +96,16 @@ func resourceOauth2AppUpcreate(d *schema.ResourceData, meta interface{}) (err er
|
||||
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{
|
||||
Name: name,
|
||||
RedirectURIs: redirectURIs,
|
||||
Name: name,
|
||||
ConfidentialClient: confidentialClient,
|
||||
RedirectURIs: redirectURIs,
|
||||
}
|
||||
|
||||
var oauth2 *gitea.Oauth2
|
||||
@ -99,7 +113,7 @@ func resourceOauth2AppUpcreate(d *schema.ResourceData, meta interface{}) (err er
|
||||
if d.IsNewResource() {
|
||||
oauth2, _, err = client.CreateOauth2(opts)
|
||||
} else {
|
||||
oauth2, err := searchOauth2AppByClientId(client, d.Id())
|
||||
oauth2, err = searchOauth2AppByClientId(client, d.Id())
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@ -176,9 +190,10 @@ func setOAuth2ResourceData(app *gitea.Oauth2, d *schema.ResourceData) (err error
|
||||
d.SetId(app.ClientID)
|
||||
|
||||
for k, v := range map[string]interface{}{
|
||||
oauth2KeyName: app.Name,
|
||||
oauth2KeyRedirectURIs: schema.NewSet(schema.HashString, CollapseStringList(app.RedirectURIs)),
|
||||
oauth2KeyClientId: app.ClientID,
|
||||
oauth2KeyName: app.Name,
|
||||
oauth2KeyConfidentialClient: app.ConfidentialClient,
|
||||
oauth2KeyRedirectURIs: schema.NewSet(schema.HashString, CollapseStringList(app.RedirectURIs)),
|
||||
oauth2KeyClientId: app.ClientID,
|
||||
} {
|
||||
err = d.Set(k, v)
|
||||
if err != nil {
|
||||
|
@ -16,6 +16,7 @@ const (
|
||||
orgLocation string = "location"
|
||||
orgVisibility string = "visibility"
|
||||
RepoAdminChangeTeamAccess string = "repo_admin_change_team_access"
|
||||
orgRepos string = "org_repos"
|
||||
)
|
||||
|
||||
// might come in handy if we want to stick to numeric IDs
|
||||
@ -48,6 +49,32 @@ func searchOrgByClientId(c *gitea.Client, id int64) (res *gitea.Organization, er
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
client := meta.(*gitea.Client)
|
||||
|
||||
@ -58,10 +85,12 @@ func resourceOrgRead(d *schema.ResourceData, meta interface{}) (err error) {
|
||||
org, err = searchOrgByClientId(client, id)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
err = setOrgResourceData(org, d)
|
||||
repos, _ := getAllOrgRepos(client, org.UserName)
|
||||
err = setOrgResourceData(org, d, &repos)
|
||||
|
||||
return
|
||||
}
|
||||
@ -84,7 +113,8 @@ func resourceOrgCreate(d *schema.ResourceData, meta interface{}) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
err = setOrgResourceData(org, d)
|
||||
repos, _ := getAllOrgRepos(client, org.UserName)
|
||||
err = setOrgResourceData(org, d, &repos)
|
||||
|
||||
return
|
||||
}
|
||||
@ -117,7 +147,8 @@ func resourceOrgUpdate(d *schema.ResourceData, meta interface{}) (err error) {
|
||||
|
||||
org, resp, err = client.GetOrg(d.Get(orgName).(string))
|
||||
|
||||
err = setOrgResourceData(org, d)
|
||||
repos, _ := getAllOrgRepos(client, org.UserName)
|
||||
err = setOrgResourceData(org, d, &repos)
|
||||
|
||||
return
|
||||
}
|
||||
@ -140,7 +171,7 @@ func resourceOrgDelete(d *schema.ResourceData, meta interface{}) (err error) {
|
||||
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.Set("name", org.UserName)
|
||||
d.Set("full_name", org.FullName)
|
||||
@ -149,6 +180,7 @@ func setOrgResourceData(org *gitea.Organization, d *schema.ResourceData) (err er
|
||||
d.Set("website", org.Website)
|
||||
d.Set("location", org.Location)
|
||||
d.Set("visibility", org.Visibility)
|
||||
d.Set("repos", repos)
|
||||
|
||||
return
|
||||
}
|
||||
@ -210,6 +242,13 @@ func resourceGiteaOrg() *schema.Resource {
|
||||
Default: "public",
|
||||
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" +
|
||||
"Organisations are a way to group repositories and abstract permission management in a gitea instance.",
|
||||
|
@ -1,10 +1,14 @@
|
||||
package gitea
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
@ -48,6 +52,34 @@ const (
|
||||
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) {
|
||||
client := meta.(*gitea.Client)
|
||||
|
||||
@ -79,24 +111,34 @@ func resourceRepoCreate(d *schema.ResourceData, meta interface{}) (err error) {
|
||||
|
||||
var repo *gitea.Repository
|
||||
var resp *gitea.Response
|
||||
var orgRepo bool
|
||||
var orgRepo, hasAdmin bool
|
||||
|
||||
_, resp, err = client.GetOrg(d.Get(repoOwner).(string))
|
||||
|
||||
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
|
||||
} else {
|
||||
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)
|
||||
}
|
||||
|
||||
var cloneAddr string
|
||||
if d.Get(migrationCloneAddresse).(string) != "" {
|
||||
cloneAddr = d.Get(migrationCloneAddresse).(string)
|
||||
} else {
|
||||
cloneAddr = d.Get(migrationCloneAddress).(string)
|
||||
}
|
||||
if cloneAddr != "" {
|
||||
|
||||
opts := gitea.MigrateRepoOption{
|
||||
RepoName: d.Get(repoName).(string),
|
||||
@ -147,12 +189,16 @@ func resourceRepoCreate(d *schema.ResourceData, meta interface{}) (err error) {
|
||||
if orgRepo {
|
||||
repo, _, err = client.CreateOrgRepo(d.Get(repoOwner).(string), opts)
|
||||
} else {
|
||||
repo, _, err = client.CreateRepo(opts)
|
||||
if hasAdmin {
|
||||
repo, _, err = client.AdminCreateRepo(d.Get(repoOwner).(string), opts)
|
||||
} else {
|
||||
repo, _, err = client.CreateRepo(opts)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
err = setRepoResourceData(repo, d)
|
||||
@ -530,11 +576,25 @@ func resourceGiteaRepository() *schema.Resource {
|
||||
Optional: true,
|
||||
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" +
|
||||
"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 " +
|
||||
"and create the repository under the organisation scope.\n\n" +
|
||||
"Repository migrations have some properties that are not available to regular repositories. These are all prefixed with `migration_`.",
|
||||
"Repository migrations have some properties that are not available to regular repositories. These are all prefixed with `migration_`.\n" +
|
||||
"Codeberg.org does currently not allow mirrors to be created. See FAQ Section of CodeBerg for more information: " +
|
||||
"https://docs.codeberg.org/getting-started/faq/#why-am-i-not-allowed-to-set-up-an-automatic-mirror",
|
||||
}
|
||||
}
|
||||
|
169
gitea/resource_gitea_repository_key.go
Normal file
169
gitea/resource_gitea_repository_key.go
Normal file
@ -0,0 +1,169 @@
|
||||
package gitea
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
const (
|
||||
deployKeyRepoId string = "repository"
|
||||
deployKeyName string = "title"
|
||||
deployKeyKey string = "key"
|
||||
deployKeyReadOnly string = "read_only"
|
||||
)
|
||||
|
||||
func resourceRepoKeyIdParts(d *schema.ResourceData) (bool, int64, int64, error) {
|
||||
parts := strings.Split(d.Id(), "/")
|
||||
if len(parts) != 2 {
|
||||
return false, 0, 0, nil
|
||||
}
|
||||
|
||||
repoId, err := strconv.ParseInt(parts[0], 10, 64)
|
||||
if err != nil {
|
||||
return false, 0, 0, err
|
||||
}
|
||||
keyId, err := strconv.ParseInt(parts[1], 10, 64)
|
||||
if err != nil {
|
||||
return false, 0, 0, err
|
||||
}
|
||||
return true, repoId, keyId, err
|
||||
}
|
||||
|
||||
func resourceRepoKeyRead(d *schema.ResourceData, meta interface{}) (err error) {
|
||||
client := meta.(*gitea.Client)
|
||||
|
||||
hasId, repoId, keyId, err := resourceRepoKeyIdParts(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !hasId {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
repo, resp, err := client.GetRepoByID(repoId)
|
||||
if err != nil {
|
||||
if resp.StatusCode == 404 {
|
||||
d.SetId("")
|
||||
return nil
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
key, resp, err := client.GetDeployKey(repo.Owner.UserName, repo.Name, keyId)
|
||||
if err != nil {
|
||||
if resp.StatusCode == 404 {
|
||||
d.SetId("")
|
||||
return nil
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = setRepoKeyResourceData(key, repoId, d)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func resourceRepoKeyCreate(d *schema.ResourceData, meta interface{}) (err error) {
|
||||
client := meta.(*gitea.Client)
|
||||
|
||||
repo, _, err := client.GetRepoByID(int64(d.Get(deployKeyRepoId).(int)))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dk, _, err := client.CreateDeployKey(repo.Owner.UserName, repo.Name, gitea.CreateKeyOption{
|
||||
Title: d.Get(deployKeyName).(string),
|
||||
ReadOnly: d.Get(deployKeyReadOnly).(bool),
|
||||
Key: d.Get(deployKeyKey).(string),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
setRepoKeyResourceData(dk, repo.ID, d)
|
||||
return nil
|
||||
}
|
||||
|
||||
func respurceRepoKeyDelete(d *schema.ResourceData, meta interface{}) (err error) {
|
||||
client := meta.(*gitea.Client)
|
||||
|
||||
hasId, repoId, keyId, err := resourceRepoKeyIdParts(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !hasId {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
repo, resp, err := client.GetRepoByID(repoId)
|
||||
if err != nil {
|
||||
if resp.StatusCode == 404 {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
client.DeleteDeployKey(repo.Owner.UserName, repo.Name, keyId)
|
||||
return nil
|
||||
}
|
||||
|
||||
func setRepoKeyResourceData(dk *gitea.DeployKey, repoId int64, d *schema.ResourceData) (err error) {
|
||||
d.SetId(fmt.Sprintf("%d/%d", repoId, dk.ID))
|
||||
d.Set(deployKeyRepoId, repoId)
|
||||
d.Set(deployKeyReadOnly, dk.ReadOnly)
|
||||
d.Set(deployKeyKey, dk.Key)
|
||||
d.Set(deployKeyName, dk.Title)
|
||||
return
|
||||
}
|
||||
|
||||
func resourceGiteaRepositoryKey() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Read: resourceRepoKeyRead,
|
||||
Create: resourceRepoKeyCreate,
|
||||
Delete: respurceRepoKeyDelete,
|
||||
Importer: &schema.ResourceImporter{
|
||||
StateContext: schema.ImportStatePassthroughContext,
|
||||
},
|
||||
Schema: map[string]*schema.Schema{
|
||||
deployKeyRepoId: {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Description: "The ID of the repository where the deploy key belongs to",
|
||||
},
|
||||
deployKeyKey: {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Description: "Armored SSH key to add",
|
||||
},
|
||||
deployKeyReadOnly: {
|
||||
Type: schema.TypeBool,
|
||||
Required: false,
|
||||
Optional: true,
|
||||
Default: true,
|
||||
ForceNew: true,
|
||||
Description: "Whether this key has read or read/write access",
|
||||
},
|
||||
deployKeyName: {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Description: "Name of the deploy key",
|
||||
},
|
||||
},
|
||||
Description: "`gitea_repository_key` manages a deploy key for a single gitea_repository.\n\n" +
|
||||
"Every key needs a unique name and unique key, i.e. no key can be added twice to the same repo",
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package gitea
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -18,6 +19,7 @@ const (
|
||||
TeamIncludeAllReposFlag string = "include_all_repositories"
|
||||
TeamUnits string = "units"
|
||||
TeamMembers string = "members"
|
||||
TeamRepositories string = "repositories"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
@ -75,12 +77,14 @@ func resourceTeamCreate(d *schema.ResourceData, meta interface{}) (err error) {
|
||||
units = append(units, gitea.RepoUnitProjects)
|
||||
}
|
||||
|
||||
includeAllRepos := d.Get(TeamIncludeAllReposFlag).(bool)
|
||||
|
||||
opts := gitea.CreateTeamOption{
|
||||
Name: d.Get(TeamName).(string),
|
||||
Description: d.Get(TeamDescription).(string),
|
||||
Permission: gitea.AccessMode(d.Get(TeamPermissions).(string)),
|
||||
CanCreateOrgRepo: d.Get(TeamCreateRepoFlag).(bool),
|
||||
IncludesAllRepositories: d.Get(TeamIncludeAllReposFlag).(bool),
|
||||
IncludesAllRepositories: includeAllRepos,
|
||||
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
|
||||
}
|
||||
@ -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)
|
||||
|
||||
err = setTeamResourceData(team, d)
|
||||
err = setTeamResourceData(team, d, meta)
|
||||
|
||||
return
|
||||
}
|
||||
@ -208,7 +226,13 @@ func resourceTeamDelete(d *schema.ResourceData, meta interface{}) (err error) {
|
||||
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.Set(TeamCreateRepoFlag, team.CanCreateOrgRepo)
|
||||
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(TeamIncludeAllReposFlag, team.IncludesAllRepositories)
|
||||
d.Set(TeamUnits, d.Get(TeamUnits).(string))
|
||||
d.Set(TeamOrg, d.Get(TeamOrg).(string))
|
||||
d.Set(TeamMembers, d.Get(TeamMembers))
|
||||
d.Set(TeamRepositories, d.Get(TeamRepositories))
|
||||
return
|
||||
}
|
||||
|
||||
@ -228,7 +252,7 @@ func resourceGiteaTeam() *schema.Resource {
|
||||
Update: resourceTeamUpdate,
|
||||
Delete: resourceTeamDelete,
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
StateContext: schema.ImportStatePassthroughContext,
|
||||
},
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
@ -290,7 +314,75 @@ func resourceGiteaTeam() *schema.Resource {
|
||||
Computed: true,
|
||||
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.",
|
||||
}
|
||||
}
|
||||
|
||||
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!",
|
||||
}
|
||||
}
|
79
go.mod
79
go.mod
@ -4,65 +4,70 @@ go 1.18
|
||||
|
||||
require (
|
||||
code.gitea.io/sdk/gitea v0.15.1
|
||||
github.com/hashicorp/terraform-plugin-docs v0.7.0
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0
|
||||
github.com/hashicorp/terraform-plugin-docs v0.16.0
|
||||
github.com/hashicorp/terraform-plugin-log v0.9.0
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.27.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Masterminds/goutils v1.1.0 // indirect
|
||||
github.com/Masterminds/semver v1.5.0 // indirect
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect
|
||||
github.com/agext/levenshtein v1.2.2 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 // indirect
|
||||
github.com/armon/go-radix v1.0.0 // indirect
|
||||
github.com/bgentry/speakeasy v0.1.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/cloudflare/circl v1.3.3 // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/go-cmp v0.5.8 // indirect
|
||||
github.com/google/uuid v1.1.2 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect
|
||||
github.com/hashicorp/go-hclog v1.2.1 // indirect
|
||||
github.com/hashicorp/go-hclog v1.5.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-plugin v1.4.4 // indirect
|
||||
github.com/hashicorp/go-plugin v1.4.10 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/hashicorp/hc-install v0.4.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.13.0 // indirect
|
||||
github.com/hashicorp/hc-install v0.5.2 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.17.0 // indirect
|
||||
github.com/hashicorp/logutils v1.0.0 // indirect
|
||||
github.com/hashicorp/terraform-exec v0.17.2 // indirect
|
||||
github.com/hashicorp/terraform-json v0.14.0 // indirect
|
||||
github.com/hashicorp/terraform-plugin-go v0.12.0 // indirect
|
||||
github.com/hashicorp/terraform-plugin-log v0.7.0 // indirect
|
||||
github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c // indirect
|
||||
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 // indirect
|
||||
github.com/hashicorp/terraform-exec v0.18.1 // indirect
|
||||
github.com/hashicorp/terraform-json v0.17.1 // indirect
|
||||
github.com/hashicorp/terraform-plugin-go v0.16.0 // indirect
|
||||
github.com/hashicorp/terraform-registry-address v0.2.1 // indirect
|
||||
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
|
||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect
|
||||
github.com/huandu/xstrings v1.3.2 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mitchellh/cli v1.1.2 // indirect
|
||||
github.com/imdario/mergo v0.3.13 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mitchellh/cli v1.1.5 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/oklog/run v1.0.0 // indirect
|
||||
github.com/posener/complete v1.1.1 // indirect
|
||||
github.com/posener/complete v1.2.3 // indirect
|
||||
github.com/russross/blackfriday v1.6.0 // indirect
|
||||
github.com/shopspring/decimal v1.3.1 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
|
||||
github.com/vmihailenco/tagparser v0.1.1 // indirect
|
||||
github.com/zclconf/go-cty v1.10.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 // indirect
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
google.golang.org/appengine v1.6.6 // indirect
|
||||
google.golang.org/genproto v0.0.0-20200711021454-869866162049 // indirect
|
||||
google.golang.org/grpc v1.48.0 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/zclconf/go-cty v1.13.2 // indirect
|
||||
golang.org/x/crypto v0.10.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect
|
||||
golang.org/x/mod v0.11.0 // indirect
|
||||
golang.org/x/net v0.11.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/text v0.11.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
||||
google.golang.org/grpc v1.56.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
)
|
||||
|
346
go.sum
346
go.sum
@ -1,189 +1,133 @@
|
||||
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=
|
||||
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/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=
|
||||
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
|
||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
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/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
|
||||
github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
|
||||
github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
|
||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
|
||||
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
|
||||
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/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I=
|
||||
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
|
||||
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
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/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
|
||||
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/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
|
||||
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
|
||||
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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
|
||||
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
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/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||
github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
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-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
|
||||
github.com/go-git/go-git/v5 v5.6.1 h1:q4ZRqQl4pR/ZJHc1L5CFjGA1a10u76aV1iC+nh+bHsk=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
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/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.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
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/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.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/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=
|
||||
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/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI=
|
||||
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs=
|
||||
github.com/hashicorp/go-hclog v1.2.1 h1:YQsLlGDJgwhXFpucSPyVbCBviQtjlHv3jLTlp8YmtEw=
|
||||
github.com/hashicorp/go-hclog v1.2.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
|
||||
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-plugin v1.4.4 h1:NVdrSdFRt3SkZtNckJ6tog7gbpRrcbOjQi/rgF7JYWQ=
|
||||
github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
|
||||
github.com/hashicorp/go-plugin v1.4.10 h1:xUbmA4jC6Dq163/fWcp8P3JuHilrHHMLNRxzGQJ9hNk=
|
||||
github.com/hashicorp/go-plugin v1.4.10/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
||||
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/hc-install v0.4.0 h1:cZkRFr1WVa0Ty6x5fTvL1TuO1flul231rWkGH92oYYk=
|
||||
github.com/hashicorp/hc-install v0.4.0/go.mod h1:5d155H8EC5ewegao9A4PUTMNPZaq+TbOzkJJZ4vrXeI=
|
||||
github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc=
|
||||
github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0=
|
||||
github.com/hashicorp/hc-install v0.5.2 h1:SfwMFnEXVVirpwkDuSF5kymUOhrUxrTq3udEseZdOD0=
|
||||
github.com/hashicorp/hc-install v0.5.2/go.mod h1:9QISwe6newMWIfEiXpzuu1k9HAGtQYgnSH8H9T8wmoI=
|
||||
github.com/hashicorp/hcl/v2 v2.17.0 h1:z1XvSUyXd1HP10U4lrLg5e0JMVz6CPaJvAgxM0KNZVY=
|
||||
github.com/hashicorp/hcl/v2 v2.17.0/go.mod h1:gJyW2PTShkJqQBKpAmPO3yxMxIuoXkOF2TpqXzrQyx4=
|
||||
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/terraform-exec v0.17.2 h1:EU7i3Fh7vDUI9nNRdMATCEfnm9axzTnad8zszYZ73Go=
|
||||
github.com/hashicorp/terraform-exec v0.17.2/go.mod h1:tuIbsL2l4MlwwIZx9HPM+LOV9vVyEfBYu2GsO1uH3/8=
|
||||
github.com/hashicorp/terraform-json v0.14.0 h1:sh9iZ1Y8IFJLx+xQiKHGud6/TSUCM0N8e17dKDpqV7s=
|
||||
github.com/hashicorp/terraform-json v0.14.0/go.mod h1:5A9HIWPkk4e5aeeXIBbkcOvaZbIYnAIkEyqP2pNSckM=
|
||||
github.com/hashicorp/terraform-plugin-docs v0.7.0 h1:7XKAOYHAxghe7q4/vx468X43X9GikdQ2dxtmcu2gQv0=
|
||||
github.com/hashicorp/terraform-plugin-docs v0.7.0/go.mod h1:57CICKfW7/KbW4lPhKOledyT6vu1LeAOzuvWXsVaxUE=
|
||||
github.com/hashicorp/terraform-plugin-go v0.12.0 h1:6wW9mT1dSs0Xq4LR6HXj1heQ5ovr5GxXNJwkErZzpJw=
|
||||
github.com/hashicorp/terraform-plugin-go v0.12.0/go.mod h1:kwhmaWHNDvT1B3QiSJdAtrB/D4RaKSY/v3r2BuoWK4M=
|
||||
github.com/hashicorp/terraform-plugin-log v0.7.0 h1:SDxJUyT8TwN4l5b5/VkiTIaQgY6R+Y2BQ0sRZftGKQs=
|
||||
github.com/hashicorp/terraform-plugin-log v0.7.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4=
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 h1:+KxZULPsbjpAVoP0WNj/8aVW6EqpcX5JcUcQ5wl7Da4=
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0/go.mod h1:DwGJG3KNxIPluVk6hexvDfYR/MS/eKGpiztJoT3Bbbw=
|
||||
github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c h1:D8aRO6+mTqHfLsK/BC3j5OAoogv1WLRWzY1AaTo3rBg=
|
||||
github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c/go.mod h1:Wn3Na71knbXc1G8Lh+yu/dQWWJeFQEpDeJMtWMtlmNI=
|
||||
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 h1:HKLsbzeOsfXmKNpr3GiT18XAblV0BjCbzL8KQAMZGa0=
|
||||
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg=
|
||||
github.com/hashicorp/terraform-exec v0.18.1 h1:LAbfDvNQU1l0NOQlTuudjczVhHj061fNX5H8XZxHlH4=
|
||||
github.com/hashicorp/terraform-exec v0.18.1/go.mod h1:58wg4IeuAJ6LVsLUeD2DWZZoc/bYi6dzhLHzxM41980=
|
||||
github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQHgyRwf3RkyA=
|
||||
github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o=
|
||||
github.com/hashicorp/terraform-plugin-docs v0.16.0 h1:UmxFr3AScl6Wged84jndJIfFccGyBZn52KtMNsS12dI=
|
||||
github.com/hashicorp/terraform-plugin-docs v0.16.0/go.mod h1:M3ZrlKBJAbPMtNOPwHicGi1c+hZUh7/g0ifT/z7TVfA=
|
||||
github.com/hashicorp/terraform-plugin-go v0.16.0 h1:DSOQ0rz5FUiVO4NUzMs8ln9gsPgHMTsfns7Nk+6gPuE=
|
||||
github.com/hashicorp/terraform-plugin-go v0.16.0/go.mod h1:4sn8bFuDbt+2+Yztt35IbOrvZc0zyEi87gJzsTgCES8=
|
||||
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
|
||||
github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.27.0 h1:I8efBnjuDrgPjNF1MEypHy48VgcTIUY4X6rOFunrR3Y=
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.27.0/go.mod h1:cUEP4ly/nxlHy5HzD6YRrHydtlheGvGRJDhiWqqVik4=
|
||||
github.com/hashicorp/terraform-registry-address v0.2.1 h1:QuTf6oJ1+WSflJw6WYOHhLgwUiQ0FrROpHPYFtwTYWM=
|
||||
github.com/hashicorp/terraform-registry-address v0.2.1/go.mod h1:BSE9fIFzp0qWsJUUyGquo4ldV9k2n+psif6NYkBRS3Y=
|
||||
github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
|
||||
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/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/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.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
|
||||
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
|
||||
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/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
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.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/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.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.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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mitchellh/cli v1.1.2 h1:PvH+lL2B7IQ101xQL63Of8yFS2y+aDlsFcsqNc+u/Kw=
|
||||
github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng=
|
||||
github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
|
||||
@ -193,180 +137,108 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||
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/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758=
|
||||
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
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/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
|
||||
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/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=
|
||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||
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/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
|
||||
github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
|
||||
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
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.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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
|
||||
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
||||
github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY=
|
||||
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
||||
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
||||
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||
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/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
|
||||
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
|
||||
github.com/zclconf/go-cty v1.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=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
github.com/zclconf/go-cty v1.13.2 h1:4GvrUxe/QUDYuJKAav4EYqdM47/kZa672LwmXFmEKT0=
|
||||
github.com/zclconf/go-cty v1.13.2/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 h1:O8uGbHCqlTp2P6QJSLmCojM4mN6UemYv8K+dCnmHmu0=
|
||||
golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
|
||||
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
|
||||
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME=
|
||||
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
|
||||
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/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-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/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
|
||||
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/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-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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
|
||||
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
|
||||
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-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/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60=
|
||||
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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
|
||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
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-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
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.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200711021454-869866162049 h1:YFTFpQhgvrLrmxtiIncJxFXeCyq84ixuKWVCaCAi9Oc=
|
||||
google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=
|
||||
google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
|
||||
google.golang.org/grpc v1.56.0 h1:+y7Bs8rtMd07LeXmL3NxcTLn7mUkbKZqEpPhMNkwJEE=
|
||||
google.golang.org/grpc v1.56.0/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 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-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/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.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
@ -6,7 +6,7 @@ networks:
|
||||
|
||||
services:
|
||||
server:
|
||||
image: gitea/gitea:1.17.1
|
||||
image: gitea/gitea:1.19.3
|
||||
container_name: gitea
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
|
18
vendor/code.gitea.io/sdk/gitea/oauth2.go
generated
vendored
18
vendor/code.gitea.io/sdk/gitea/oauth2.go
generated
vendored
@ -13,12 +13,13 @@ import (
|
||||
|
||||
// Oauth2 represents an Oauth2 Application
|
||||
type Oauth2 struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
ClientID string `json:"client_id"`
|
||||
ClientSecret string `json:"client_secret"`
|
||||
RedirectURIs []string `json:"redirect_uris"`
|
||||
Created time.Time `json:"created"`
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
ClientID string `json:"client_id"`
|
||||
ClientSecret string `json:"client_secret"`
|
||||
RedirectURIs []string `json:"redirect_uris"`
|
||||
ConfidentialClient bool `json:"confidential_client"`
|
||||
Created time.Time `json:"created"`
|
||||
}
|
||||
|
||||
// ListOauth2Option for listing Oauth2 Applications
|
||||
@ -28,8 +29,9 @@ type ListOauth2Option struct {
|
||||
|
||||
// CreateOauth2Option required options for creating an Application
|
||||
type CreateOauth2Option struct {
|
||||
Name string `json:"name"`
|
||||
RedirectURIs []string `json:"redirect_uris"`
|
||||
Name string `json:"name"`
|
||||
ConfidentialClient bool `json:"confidential_client"`
|
||||
RedirectURIs []string `json:"redirect_uris"`
|
||||
}
|
||||
|
||||
// CreateOauth2 create an Oauth2 Application and returns a completed Oauth2 object.
|
||||
|
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"
|
||||
"math"
|
||||
"math/big"
|
||||
"regexp"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
@ -99,27 +98,7 @@ Returns:
|
||||
error - an error stemming from an invalid parameter within underlying function, CryptoRandom(...)
|
||||
*/
|
||||
func CryptoRandomAlphaNumeric(count int) (string, error) {
|
||||
if count == 0 {
|
||||
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
|
||||
|
||||
return CryptoRandom(count, 0, 0, true, true)
|
||||
}
|
||||
|
||||
/*
|
||||
@ -204,7 +183,7 @@ func CryptoRandom(count int, start int, end int, letters bool, numbers bool, cha
|
||||
if chars == nil {
|
||||
ch = rune(getCryptoRandomInt(gap) + int64(start))
|
||||
} else {
|
||||
ch = chars[getCryptoRandomInt(gap) + int64(start)]
|
||||
ch = chars[getCryptoRandomInt(gap)+int64(start)]
|
||||
}
|
||||
|
||||
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"
|
||||
"math"
|
||||
"math/rand"
|
||||
"regexp"
|
||||
"time"
|
||||
"unicode"
|
||||
)
|
||||
@ -75,12 +74,10 @@ func RandomNumeric(count int) (string, error) {
|
||||
|
||||
/*
|
||||
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:
|
||||
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:
|
||||
string - the random string
|
||||
@ -102,24 +99,7 @@ Returns:
|
||||
error - an error stemming from an invalid parameter within underlying function, RandomSeed(...)
|
||||
*/
|
||||
func RandomAlphaNumeric(count int) (string, error) {
|
||||
RandomString, err := 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
|
||||
|
||||
return Random(count, 0, 0, true, true)
|
||||
}
|
||||
|
||||
/*
|
||||
|
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 {
|
||||
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
|
||||
|
||||
[![Stability:
|
||||
Active](https://masterminds.github.io/stability/active.svg)](https://masterminds.github.io/stability/active.html)
|
||||
[![Build Status](https://travis-ci.org/Masterminds/semver.svg)](https://travis-ci.org/Masterminds/semver) [![Build status](https://ci.appveyor.com/api/projects/status/jfk66lib7hb985k8/branch/master?svg=true&passingText=windows%20build%20passing&failingText=windows%20build%20failing)](https://ci.appveyor.com/project/mattfarina/semver/branch/master) [![GoDoc](https://godoc.org/github.com/Masterminds/semver?status.svg)](https://godoc.org/github.com/Masterminds/semver) [![Go Report Card](https://goreportcard.com/badge/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
|
||||
|
||||
[![Stability:
|
||||
Active](https://masterminds.github.io/stability/active.svg)](https://masterminds.github.io/stability/active.html)
|
||||
[![](https://github.com/Masterminds/semver/workflows/Tests/badge.svg)](https://github.com/Masterminds/semver/actions)
|
||||
[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/Masterminds/semver/v3)
|
||||
[![Go Report Card](https://goreportcard.com/badge/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.
|
||||
|
||||
## Package Versions
|
||||
|
||||
There are three major versions fo the `semver` package.
|
||||
|
||||
* 3.x.x is the new stable and active version. This version is focused on constraint
|
||||
compatibility for range handling in other tools from other languages. It has
|
||||
a similar API to the v1 releases. The development of this version is on the master
|
||||
branch. The documentation for this version is below.
|
||||
* 2.x was developed primarily for [dep](https://github.com/golang/dep). There are
|
||||
no tagged releases and the development was performed by [@sdboyer](https://github.com/sdboyer).
|
||||
There are API breaking changes from v1. This version lives on the [2.x branch](https://github.com/Masterminds/semver/tree/2.x).
|
||||
* 1.x.x is the most widely used version with numerous tagged releases. This is the
|
||||
previous stable and is still maintained for bug fixes. The development, to fix
|
||||
bugs, occurs on the release-1 branch. You can read the documentation [here](https://github.com/Masterminds/semver/blob/release-1/README.md).
|
||||
|
||||
## Parsing Semantic Versions
|
||||
|
||||
There are two functions that can parse semantic versions. The `StrictNewVersion`
|
||||
function only parses valid version 2 semantic versions as outlined in the
|
||||
specification. The `NewVersion` function attempts to coerce a version into a
|
||||
semantic version and parse it. For example, if there is a leading v or a version
|
||||
listed without all 3 parts (e.g. `v1.2`) it will attempt to coerce it into a valid
|
||||
semantic version (e.g., 1.2.0). In both cases a `Version` object is returned
|
||||
that can be sorted, compared, and used in constraints.
|
||||
|
||||
When parsing a version an error is returned if there is an issue parsing the
|
||||
version. For example,
|
||||
|
||||
v, err := semver.NewVersion("1.2.3-beta.1+build345")
|
||||
|
||||
The version object has methods to get the parts of the version, compare it to
|
||||
other versions, convert the version back into a string, and get the original
|
||||
string. Getting the original string is useful if the semantic version was coerced
|
||||
into a valid form.
|
||||
|
||||
## Sorting Semantic Versions
|
||||
|
||||
A set of versions can be sorted using the `sort` package from the standard library.
|
||||
For example,
|
||||
|
||||
```go
|
||||
raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
|
||||
vs := make([]*semver.Version, len(raw))
|
||||
for i, r := range raw {
|
||||
v, err := semver.NewVersion(r)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
vs[i] = v
|
||||
}
|
||||
|
||||
sort.Sort(semver.Collection(vs))
|
||||
```
|
||||
|
||||
## Checking Version Constraints
|
||||
|
||||
There are two methods for comparing versions. One uses comparison methods on
|
||||
`Version` instances and the other uses `Constraints`. There are some important
|
||||
differences to notes between these two methods of comparison.
|
||||
|
||||
1. When two versions are compared using functions such as `Compare`, `LessThan`,
|
||||
and others it will follow the specification and always include prereleases
|
||||
within the comparison. It will provide an answer that is valid with the
|
||||
comparison section of the spec at https://semver.org/#spec-item-11
|
||||
2. When constraint checking is used for checks or validation it will follow a
|
||||
different set of rules that are common for ranges with tools like npm/js
|
||||
and Rust/Cargo. This includes considering prereleases to be invalid if the
|
||||
ranges does not include one. If you want to have it include pre-releases a
|
||||
simple solution is to include `-0` in your range.
|
||||
3. Constraint ranges can have some complex rules including the shorthand use of
|
||||
~ and ^. For more details on those see the options below.
|
||||
|
||||
There are differences between the two methods or checking versions because the
|
||||
comparison methods on `Version` follow the specification while comparison ranges
|
||||
are not part of the specification. Different packages and tools have taken it
|
||||
upon themselves to come up with range rules. This has resulted in differences.
|
||||
For example, npm/js and Cargo/Rust follow similar patterns while PHP has a
|
||||
different pattern for ^. The comparison features in this package follow the
|
||||
npm/js and Cargo/Rust lead because applications using it have followed similar
|
||||
patters with their versions.
|
||||
|
||||
Checking a version against version constraints is one of the most featureful
|
||||
parts of the package.
|
||||
|
||||
```go
|
||||
c, err := semver.NewConstraint(">= 1.2.3")
|
||||
if err != nil {
|
||||
// Handle constraint not being parsable.
|
||||
}
|
||||
|
||||
v, err := semver.NewVersion("1.3")
|
||||
if err != nil {
|
||||
// Handle version not being parsable.
|
||||
}
|
||||
// Check if the version meets the constraints. The a variable will be true.
|
||||
a := c.Check(v)
|
||||
```
|
||||
|
||||
### Basic Comparisons
|
||||
|
||||
There are two elements to the comparisons. First, a comparison string is a list
|
||||
of space or comma separated AND comparisons. These are then separated by || (OR)
|
||||
comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a
|
||||
comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
|
||||
greater than or equal to 4.2.3.
|
||||
|
||||
The basic comparisons are:
|
||||
|
||||
* `=`: equal (aliased to no operator)
|
||||
* `!=`: not equal
|
||||
* `>`: greater than
|
||||
* `<`: less than
|
||||
* `>=`: greater than or equal to
|
||||
* `<=`: less than or equal to
|
||||
|
||||
### Working With Prerelease Versions
|
||||
|
||||
Pre-releases, for those not familiar with them, are used for software releases
|
||||
prior to stable or generally available releases. Examples of prereleases include
|
||||
development, alpha, beta, and release candidate releases. A prerelease may be
|
||||
a version such as `1.2.3-beta.1` while the stable release would be `1.2.3`. In the
|
||||
order of precedence, prereleases come before their associated releases. In this
|
||||
example `1.2.3-beta.1 < 1.2.3`.
|
||||
|
||||
According to the Semantic Version specification prereleases may not be
|
||||
API compliant with their release counterpart. It says,
|
||||
|
||||
> A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version.
|
||||
|
||||
SemVer comparisons using constraints without a prerelease comparator will skip
|
||||
prerelease versions. For example, `>=1.2.3` will skip prereleases when looking
|
||||
at a list of releases while `>=1.2.3-0` will evaluate and find prereleases.
|
||||
|
||||
The reason for the `0` as a pre-release version in the example comparison is
|
||||
because pre-releases can only contain ASCII alphanumerics and hyphens (along with
|
||||
`.` separators), per the spec. Sorting happens in ASCII sort order, again per the
|
||||
spec. The lowest character is a `0` in ASCII sort order
|
||||
(see an [ASCII Table](http://www.asciitable.com/))
|
||||
|
||||
Understanding ASCII sort ordering is important because A-Z comes before a-z. That
|
||||
means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case
|
||||
sensitivity doesn't apply here. This is due to ASCII sort ordering which is what
|
||||
the spec specifies.
|
||||
|
||||
### Hyphen Range Comparisons
|
||||
|
||||
There are multiple methods to handle ranges and the first is hyphens ranges.
|
||||
These look like:
|
||||
|
||||
* `1.2 - 1.4.5` which is equivalent to `>= 1.2 <= 1.4.5`
|
||||
* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5`
|
||||
|
||||
### Wildcards In Comparisons
|
||||
|
||||
The `x`, `X`, and `*` characters can be used as a wildcard character. This works
|
||||
for all comparison operators. When used on the `=` operator it falls
|
||||
back to the patch level comparison (see tilde below). For example,
|
||||
|
||||
* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
|
||||
* `>= 1.2.x` is equivalent to `>= 1.2.0`
|
||||
* `<= 2.x` is equivalent to `< 3`
|
||||
* `*` is equivalent to `>= 0.0.0`
|
||||
|
||||
### Tilde Range Comparisons (Patch)
|
||||
|
||||
The tilde (`~`) comparison operator is for patch level ranges when a minor
|
||||
version is specified and major level changes when the minor number is missing.
|
||||
For example,
|
||||
|
||||
* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0`
|
||||
* `~1` is equivalent to `>= 1, < 2`
|
||||
* `~2.3` is equivalent to `>= 2.3, < 2.4`
|
||||
* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
|
||||
* `~1.x` is equivalent to `>= 1, < 2`
|
||||
|
||||
### Caret Range Comparisons (Major)
|
||||
|
||||
The caret (`^`) comparison operator is for major level changes once a stable
|
||||
(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts
|
||||
as the API stability level. This is useful when comparisons of API versions as a
|
||||
major change is API breaking. For example,
|
||||
|
||||
* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
|
||||
* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
|
||||
* `^2.3` is equivalent to `>= 2.3, < 3`
|
||||
* `^2.x` is equivalent to `>= 2.0.0, < 3`
|
||||
* `^0.2.3` is equivalent to `>=0.2.3 <0.3.0`
|
||||
* `^0.2` is equivalent to `>=0.2.0 <0.3.0`
|
||||
* `^0.0.3` is equivalent to `>=0.0.3 <0.0.4`
|
||||
* `^0.0` is equivalent to `>=0.0.0 <0.1.0`
|
||||
* `^0` is equivalent to `>=0.0.0 <1.0.0`
|
||||
|
||||
## Validation
|
||||
|
||||
In addition to testing a version against a constraint, a version can be validated
|
||||
against a constraint. When validation fails a slice of errors containing why a
|
||||
version didn't meet the constraint is returned. For example,
|
||||
|
||||
```go
|
||||
c, err := semver.NewConstraint("<= 1.2.3, >= 1.4")
|
||||
if err != nil {
|
||||
// Handle constraint not being parseable.
|
||||
}
|
||||
|
||||
v, err := semver.NewVersion("1.3")
|
||||
if err != nil {
|
||||
// Handle version not being parseable.
|
||||
}
|
||||
|
||||
// Validate a version against a constraint.
|
||||
a, msgs := c.Validate(v)
|
||||
// a is false
|
||||
for _, m := range msgs {
|
||||
fmt.Println(m)
|
||||
|
||||
// Loops over the errors which would read
|
||||
// "1.3 is greater than 1.2.3"
|
||||
// "1.3 is less than 1.4"
|
||||
}
|
||||
```
|
||||
|
||||
## Contribute
|
||||
|
||||
If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues)
|
||||
or [create a pull request](https://github.com/Masterminds/semver/pulls).
|
568
vendor/github.com/Masterminds/semver/v3/constraints.go
generated
vendored
Normal file
568
vendor/github.com/Masterminds/semver/v3/constraints.go
generated
vendored
Normal file
@ -0,0 +1,568 @@
|
||||
package semver
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Constraints is one or more constraint that a semantic version can be
|
||||
// checked against.
|
||||
type Constraints struct {
|
||||
constraints [][]*constraint
|
||||
}
|
||||
|
||||
// NewConstraint returns a Constraints instance that a Version instance can
|
||||
// be checked against. If there is a parse error it will be returned.
|
||||
func NewConstraint(c string) (*Constraints, error) {
|
||||
|
||||
// Rewrite - ranges into a comparison operation.
|
||||
c = rewriteRange(c)
|
||||
|
||||
ors := strings.Split(c, "||")
|
||||
or := make([][]*constraint, len(ors))
|
||||
for k, v := range ors {
|
||||
|
||||
// TODO: Find a way to validate and fetch all the constraints in a simpler form
|
||||
|
||||
// Validate the segment
|
||||
if !validConstraintRegex.MatchString(v) {
|
||||
return nil, fmt.Errorf("improper constraint: %s", v)
|
||||
}
|
||||
|
||||
cs := findConstraintRegex.FindAllString(v, -1)
|
||||
if cs == nil {
|
||||
cs = append(cs, v)
|
||||
}
|
||||
result := make([]*constraint, len(cs))
|
||||
for i, s := range cs {
|
||||
pc, err := parseConstraint(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result[i] = pc
|
||||
}
|
||||
or[k] = result
|
||||
}
|
||||
|
||||
o := &Constraints{constraints: or}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// Check tests if a version satisfies the constraints.
|
||||
func (cs Constraints) Check(v *Version) bool {
|
||||
// TODO(mattfarina): For v4 of this library consolidate the Check and Validate
|
||||
// functions as the underlying functions make that possible now.
|
||||
// loop over the ORs and check the inner ANDs
|
||||
for _, o := range cs.constraints {
|
||||
joy := true
|
||||
for _, c := range o {
|
||||
if check, _ := c.check(v); !check {
|
||||
joy = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if joy {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Validate checks if a version satisfies a constraint. If not a slice of
|
||||
// reasons for the failure are returned in addition to a bool.
|
||||
func (cs Constraints) Validate(v *Version) (bool, []error) {
|
||||
// loop over the ORs and check the inner ANDs
|
||||
var e []error
|
||||
|
||||
// Capture the prerelease message only once. When it happens the first time
|
||||
// this var is marked
|
||||
var prerelesase bool
|
||||
for _, o := range cs.constraints {
|
||||
joy := true
|
||||
for _, c := range o {
|
||||
// Before running the check handle the case there the version is
|
||||
// a prerelease and the check is not searching for prereleases.
|
||||
if c.con.pre == "" && v.pre != "" {
|
||||
if !prerelesase {
|
||||
em := fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
e = append(e, em)
|
||||
prerelesase = true
|
||||
}
|
||||
joy = false
|
||||
|
||||
} else {
|
||||
|
||||
if _, err := c.check(v); err != nil {
|
||||
e = append(e, err)
|
||||
joy = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if joy {
|
||||
return true, []error{}
|
||||
}
|
||||
}
|
||||
|
||||
return false, e
|
||||
}
|
||||
|
||||
func (cs Constraints) String() string {
|
||||
buf := make([]string, len(cs.constraints))
|
||||
var tmp bytes.Buffer
|
||||
|
||||
for k, v := range cs.constraints {
|
||||
tmp.Reset()
|
||||
vlen := len(v)
|
||||
for kk, c := range v {
|
||||
tmp.WriteString(c.string())
|
||||
|
||||
// Space separate the AND conditions
|
||||
if vlen > 1 && kk < vlen-1 {
|
||||
tmp.WriteString(" ")
|
||||
}
|
||||
}
|
||||
buf[k] = tmp.String()
|
||||
}
|
||||
|
||||
return strings.Join(buf, " || ")
|
||||
}
|
||||
|
||||
var constraintOps map[string]cfunc
|
||||
var constraintRegex *regexp.Regexp
|
||||
var constraintRangeRegex *regexp.Regexp
|
||||
|
||||
// Used to find individual constraints within a multi-constraint string
|
||||
var findConstraintRegex *regexp.Regexp
|
||||
|
||||
// Used to validate an segment of ANDs is valid
|
||||
var validConstraintRegex *regexp.Regexp
|
||||
|
||||
const cvRegex string = `v?([0-9|x|X|\*]+)(\.[0-9|x|X|\*]+)?(\.[0-9|x|X|\*]+)?` +
|
||||
`(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +
|
||||
`(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?`
|
||||
|
||||
func init() {
|
||||
constraintOps = map[string]cfunc{
|
||||
"": constraintTildeOrEqual,
|
||||
"=": constraintTildeOrEqual,
|
||||
"!=": constraintNotEqual,
|
||||
">": constraintGreaterThan,
|
||||
"<": constraintLessThan,
|
||||
">=": constraintGreaterThanEqual,
|
||||
"=>": constraintGreaterThanEqual,
|
||||
"<=": constraintLessThanEqual,
|
||||
"=<": constraintLessThanEqual,
|
||||
"~": constraintTilde,
|
||||
"~>": constraintTilde,
|
||||
"^": constraintCaret,
|
||||
}
|
||||
|
||||
ops := `=||!=|>|<|>=|=>|<=|=<|~|~>|\^`
|
||||
|
||||
constraintRegex = regexp.MustCompile(fmt.Sprintf(
|
||||
`^\s*(%s)\s*(%s)\s*$`,
|
||||
ops,
|
||||
cvRegex))
|
||||
|
||||
constraintRangeRegex = regexp.MustCompile(fmt.Sprintf(
|
||||
`\s*(%s)\s+-\s+(%s)\s*`,
|
||||
cvRegex, cvRegex))
|
||||
|
||||
findConstraintRegex = regexp.MustCompile(fmt.Sprintf(
|
||||
`(%s)\s*(%s)`,
|
||||
ops,
|
||||
cvRegex))
|
||||
|
||||
validConstraintRegex = regexp.MustCompile(fmt.Sprintf(
|
||||
`^(\s*(%s)\s*(%s)\s*\,?)+$`,
|
||||
ops,
|
||||
cvRegex))
|
||||
}
|
||||
|
||||
// An individual constraint
|
||||
type constraint struct {
|
||||
// The version used in the constraint check. For example, if a constraint
|
||||
// is '<= 2.0.0' the con a version instance representing 2.0.0.
|
||||
con *Version
|
||||
|
||||
// The original parsed version (e.g., 4.x from != 4.x)
|
||||
orig string
|
||||
|
||||
// The original operator for the constraint
|
||||
origfunc string
|
||||
|
||||
// When an x is used as part of the version (e.g., 1.x)
|
||||
minorDirty bool
|
||||
dirty bool
|
||||
patchDirty bool
|
||||
}
|
||||
|
||||
// Check if a version meets the constraint
|
||||
func (c *constraint) check(v *Version) (bool, error) {
|
||||
return constraintOps[c.origfunc](v, c)
|
||||
}
|
||||
|
||||
// String prints an individual constraint into a string
|
||||
func (c *constraint) string() string {
|
||||
return c.origfunc + c.orig
|
||||
}
|
||||
|
||||
type cfunc func(v *Version, c *constraint) (bool, error)
|
||||
|
||||
func parseConstraint(c string) (*constraint, error) {
|
||||
if len(c) > 0 {
|
||||
m := constraintRegex.FindStringSubmatch(c)
|
||||
if m == nil {
|
||||
return nil, fmt.Errorf("improper constraint: %s", c)
|
||||
}
|
||||
|
||||
cs := &constraint{
|
||||
orig: m[2],
|
||||
origfunc: m[1],
|
||||
}
|
||||
|
||||
ver := m[2]
|
||||
minorDirty := false
|
||||
patchDirty := false
|
||||
dirty := false
|
||||
if isX(m[3]) || m[3] == "" {
|
||||
ver = "0.0.0"
|
||||
dirty = true
|
||||
} else if isX(strings.TrimPrefix(m[4], ".")) || m[4] == "" {
|
||||
minorDirty = true
|
||||
dirty = true
|
||||
ver = fmt.Sprintf("%s.0.0%s", m[3], m[6])
|
||||
} else if isX(strings.TrimPrefix(m[5], ".")) || m[5] == "" {
|
||||
dirty = true
|
||||
patchDirty = true
|
||||
ver = fmt.Sprintf("%s%s.0%s", m[3], m[4], m[6])
|
||||
}
|
||||
|
||||
con, err := NewVersion(ver)
|
||||
if err != nil {
|
||||
|
||||
// The constraintRegex should catch any regex parsing errors. So,
|
||||
// we should never get here.
|
||||
return nil, errors.New("constraint Parser Error")
|
||||
}
|
||||
|
||||
cs.con = con
|
||||
cs.minorDirty = minorDirty
|
||||
cs.patchDirty = patchDirty
|
||||
cs.dirty = dirty
|
||||
|
||||
return cs, nil
|
||||
}
|
||||
|
||||
// The rest is the special case where an empty string was passed in which
|
||||
// is equivalent to * or >=0.0.0
|
||||
con, err := StrictNewVersion("0.0.0")
|
||||
if err != nil {
|
||||
|
||||
// The constraintRegex should catch any regex parsing errors. So,
|
||||
// we should never get here.
|
||||
return nil, errors.New("constraint Parser Error")
|
||||
}
|
||||
|
||||
cs := &constraint{
|
||||
con: con,
|
||||
orig: c,
|
||||
origfunc: "",
|
||||
minorDirty: false,
|
||||
patchDirty: false,
|
||||
dirty: true,
|
||||
}
|
||||
return cs, nil
|
||||
}
|
||||
|
||||
// Constraint functions
|
||||
func constraintNotEqual(v *Version, c *constraint) (bool, error) {
|
||||
if c.dirty {
|
||||
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
if c.con.Major() != v.Major() {
|
||||
return true, nil
|
||||
}
|
||||
if c.con.Minor() != v.Minor() && !c.minorDirty {
|
||||
return true, nil
|
||||
} else if c.minorDirty {
|
||||
return false, fmt.Errorf("%s is equal to %s", v, c.orig)
|
||||
} else if c.con.Patch() != v.Patch() && !c.patchDirty {
|
||||
return true, nil
|
||||
} else if c.patchDirty {
|
||||
// Need to handle prereleases if present
|
||||
if v.Prerelease() != "" || c.con.Prerelease() != "" {
|
||||
eq := comparePrerelease(v.Prerelease(), c.con.Prerelease()) != 0
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s is equal to %s", v, c.orig)
|
||||
}
|
||||
return false, fmt.Errorf("%s is equal to %s", v, c.orig)
|
||||
}
|
||||
}
|
||||
|
||||
eq := v.Equal(c.con)
|
||||
if eq {
|
||||
return false, fmt.Errorf("%s is equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func constraintGreaterThan(v *Version, c *constraint) (bool, error) {
|
||||
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
var eq bool
|
||||
|
||||
if !c.dirty {
|
||||
eq = v.Compare(c.con) == 1
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
if v.Major() > c.con.Major() {
|
||||
return true, nil
|
||||
} else if v.Major() < c.con.Major() {
|
||||
return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
|
||||
} else if c.minorDirty {
|
||||
// This is a range case such as >11. When the version is something like
|
||||
// 11.1.0 is it not > 11. For that we would need 12 or higher
|
||||
return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
|
||||
} else if c.patchDirty {
|
||||
// This is for ranges such as >11.1. A version of 11.1.1 is not greater
|
||||
// which one of 11.2.1 is greater
|
||||
eq = v.Minor() > c.con.Minor()
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
// If we have gotten here we are not comparing pre-preleases and can use the
|
||||
// Compare function to accomplish that.
|
||||
eq = v.Compare(c.con) == 1
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
func constraintLessThan(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
eq := v.Compare(c.con) < 0
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s is greater than or equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
func constraintGreaterThanEqual(v *Version, c *constraint) (bool, error) {
|
||||
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
eq := v.Compare(c.con) >= 0
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s is less than %s", v, c.orig)
|
||||
}
|
||||
|
||||
func constraintLessThanEqual(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
var eq bool
|
||||
|
||||
if !c.dirty {
|
||||
eq = v.Compare(c.con) <= 0
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s is greater than %s", v, c.orig)
|
||||
}
|
||||
|
||||
if v.Major() > c.con.Major() {
|
||||
return false, fmt.Errorf("%s is greater than %s", v, c.orig)
|
||||
} else if v.Major() == c.con.Major() && v.Minor() > c.con.Minor() && !c.minorDirty {
|
||||
return false, fmt.Errorf("%s is greater than %s", v, c.orig)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// ~*, ~>* --> >= 0.0.0 (any)
|
||||
// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0, <3.0.0
|
||||
// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0, <2.1.0
|
||||
// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0
|
||||
// ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0
|
||||
// ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0
|
||||
func constraintTilde(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
if v.LessThan(c.con) {
|
||||
return false, fmt.Errorf("%s is less than %s", v, c.orig)
|
||||
}
|
||||
|
||||
// ~0.0.0 is a special case where all constraints are accepted. It's
|
||||
// equivalent to >= 0.0.0.
|
||||
if c.con.Major() == 0 && c.con.Minor() == 0 && c.con.Patch() == 0 &&
|
||||
!c.minorDirty && !c.patchDirty {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if v.Major() != c.con.Major() {
|
||||
return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig)
|
||||
}
|
||||
|
||||
if v.Minor() != c.con.Minor() && !c.minorDirty {
|
||||
return false, fmt.Errorf("%s does not have same major and minor version as %s", v, c.orig)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// When there is a .x (dirty) status it automatically opts in to ~. Otherwise
|
||||
// it's a straight =
|
||||
func constraintTildeOrEqual(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
if c.dirty {
|
||||
return constraintTilde(v, c)
|
||||
}
|
||||
|
||||
eq := v.Equal(c.con)
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, fmt.Errorf("%s is not equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
// ^* --> (any)
|
||||
// ^1.2.3 --> >=1.2.3 <2.0.0
|
||||
// ^1.2 --> >=1.2.0 <2.0.0
|
||||
// ^1 --> >=1.0.0 <2.0.0
|
||||
// ^0.2.3 --> >=0.2.3 <0.3.0
|
||||
// ^0.2 --> >=0.2.0 <0.3.0
|
||||
// ^0.0.3 --> >=0.0.3 <0.0.4
|
||||
// ^0.0 --> >=0.0.0 <0.1.0
|
||||
// ^0 --> >=0.0.0 <1.0.0
|
||||
func constraintCaret(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
// This less than handles prereleases
|
||||
if v.LessThan(c.con) {
|
||||
return false, fmt.Errorf("%s is less than %s", v, c.orig)
|
||||
}
|
||||
|
||||
var eq bool
|
||||
|
||||
// ^ when the major > 0 is >=x.y.z < x+1
|
||||
if c.con.Major() > 0 || c.minorDirty {
|
||||
|
||||
// ^ has to be within a major range for > 0. Everything less than was
|
||||
// filtered out with the LessThan call above. This filters out those
|
||||
// that greater but not within the same major range.
|
||||
eq = v.Major() == c.con.Major()
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig)
|
||||
}
|
||||
|
||||
// ^ when the major is 0 and minor > 0 is >=0.y.z < 0.y+1
|
||||
if c.con.Major() == 0 && v.Major() > 0 {
|
||||
return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig)
|
||||
}
|
||||
// If the con Minor is > 0 it is not dirty
|
||||
if c.con.Minor() > 0 || c.patchDirty {
|
||||
eq = v.Minor() == c.con.Minor()
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s does not have same minor version as %s. Expected minor versions to match when constraint major version is 0", v, c.orig)
|
||||
}
|
||||
|
||||
// At this point the major is 0 and the minor is 0 and not dirty. The patch
|
||||
// is not dirty so we need to check if they are equal. If they are not equal
|
||||
eq = c.con.Patch() == v.Patch()
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s does not equal %s. Expect version and constraint to equal when major and minor versions are 0", v, c.orig)
|
||||
}
|
||||
|
||||
func isX(x string) bool {
|
||||
switch x {
|
||||
case "x", "*", "X":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func rewriteRange(i string) string {
|
||||
m := constraintRangeRegex.FindAllStringSubmatch(i, -1)
|
||||
if m == nil {
|
||||
return i
|
||||
}
|
||||
o := i
|
||||
for _, v := range m {
|
||||
t := fmt.Sprintf(">= %s, <= %s", v[1], v[11])
|
||||
o = strings.Replace(o, v[0], t, 1)
|
||||
}
|
||||
|
||||
return o
|
||||
}
|
184
vendor/github.com/Masterminds/semver/v3/doc.go
generated
vendored
Normal file
184
vendor/github.com/Masterminds/semver/v3/doc.go
generated
vendored
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
Package semver provides the ability to work with Semantic Versions (http://semver.org) in Go.
|
||||
|
||||
Specifically it provides the ability to:
|
||||
|
||||
* Parse semantic versions
|
||||
* Sort semantic versions
|
||||
* Check if a semantic version fits within a set of constraints
|
||||
* Optionally work with a `v` prefix
|
||||
|
||||
Parsing Semantic Versions
|
||||
|
||||
There are two functions that can parse semantic versions. The `StrictNewVersion`
|
||||
function only parses valid version 2 semantic versions as outlined in the
|
||||
specification. The `NewVersion` function attempts to coerce a version into a
|
||||
semantic version and parse it. For example, if there is a leading v or a version
|
||||
listed without all 3 parts (e.g. 1.2) it will attempt to coerce it into a valid
|
||||
semantic version (e.g., 1.2.0). In both cases a `Version` object is returned
|
||||
that can be sorted, compared, and used in constraints.
|
||||
|
||||
When parsing a version an optional error can be returned if there is an issue
|
||||
parsing the version. For example,
|
||||
|
||||
v, err := semver.NewVersion("1.2.3-beta.1+b345")
|
||||
|
||||
The version object has methods to get the parts of the version, compare it to
|
||||
other versions, convert the version back into a string, and get the original
|
||||
string. For more details please see the documentation
|
||||
at https://godoc.org/github.com/Masterminds/semver.
|
||||
|
||||
Sorting Semantic Versions
|
||||
|
||||
A set of versions can be sorted using the `sort` package from the standard library.
|
||||
For example,
|
||||
|
||||
raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
|
||||
vs := make([]*semver.Version, len(raw))
|
||||
for i, r := range raw {
|
||||
v, err := semver.NewVersion(r)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
vs[i] = v
|
||||
}
|
||||
|
||||
sort.Sort(semver.Collection(vs))
|
||||
|
||||
Checking Version Constraints and Comparing Versions
|
||||
|
||||
There are two methods for comparing versions. One uses comparison methods on
|
||||
`Version` instances and the other is using Constraints. There are some important
|
||||
differences to notes between these two methods of comparison.
|
||||
|
||||
1. When two versions are compared using functions such as `Compare`, `LessThan`,
|
||||
and others it will follow the specification and always include prereleases
|
||||
within the comparison. It will provide an answer valid with the comparison
|
||||
spec section at https://semver.org/#spec-item-11
|
||||
2. When constraint checking is used for checks or validation it will follow a
|
||||
different set of rules that are common for ranges with tools like npm/js
|
||||
and Rust/Cargo. This includes considering prereleases to be invalid if the
|
||||
ranges does not include on. If you want to have it include pre-releases a
|
||||
simple solution is to include `-0` in your range.
|
||||
3. Constraint ranges can have some complex rules including the shorthard use of
|
||||
~ and ^. For more details on those see the options below.
|
||||
|
||||
There are differences between the two methods or checking versions because the
|
||||
comparison methods on `Version` follow the specification while comparison ranges
|
||||
are not part of the specification. Different packages and tools have taken it
|
||||
upon themselves to come up with range rules. This has resulted in differences.
|
||||
For example, npm/js and Cargo/Rust follow similar patterns which PHP has a
|
||||
different pattern for ^. The comparison features in this package follow the
|
||||
npm/js and Cargo/Rust lead because applications using it have followed similar
|
||||
patters with their versions.
|
||||
|
||||
Checking a version against version constraints is one of the most featureful
|
||||
parts of the package.
|
||||
|
||||
c, err := semver.NewConstraint(">= 1.2.3")
|
||||
if err != nil {
|
||||
// Handle constraint not being parsable.
|
||||
}
|
||||
|
||||
v, err := semver.NewVersion("1.3")
|
||||
if err != nil {
|
||||
// Handle version not being parsable.
|
||||
}
|
||||
// Check if the version meets the constraints. The a variable will be true.
|
||||
a := c.Check(v)
|
||||
|
||||
Basic Comparisons
|
||||
|
||||
There are two elements to the comparisons. First, a comparison string is a list
|
||||
of comma or space separated AND comparisons. These are then separated by || (OR)
|
||||
comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a
|
||||
comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
|
||||
greater than or equal to 4.2.3. This can also be written as
|
||||
`">= 1.2, < 3.0.0 || >= 4.2.3"`
|
||||
|
||||
The basic comparisons are:
|
||||
|
||||
* `=`: equal (aliased to no operator)
|
||||
* `!=`: not equal
|
||||
* `>`: greater than
|
||||
* `<`: less than
|
||||
* `>=`: greater than or equal to
|
||||
* `<=`: less than or equal to
|
||||
|
||||
Hyphen Range Comparisons
|
||||
|
||||
There are multiple methods to handle ranges and the first is hyphens ranges.
|
||||
These look like:
|
||||
|
||||
* `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5`
|
||||
* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5`
|
||||
|
||||
Wildcards In Comparisons
|
||||
|
||||
The `x`, `X`, and `*` characters can be used as a wildcard character. This works
|
||||
for all comparison operators. When used on the `=` operator it falls
|
||||
back to the tilde operation. For example,
|
||||
|
||||
* `1.2.x` is equivalent to `>= 1.2.0 < 1.3.0`
|
||||
* `>= 1.2.x` is equivalent to `>= 1.2.0`
|
||||
* `<= 2.x` is equivalent to `<= 3`
|
||||
* `*` is equivalent to `>= 0.0.0`
|
||||
|
||||
Tilde Range Comparisons (Patch)
|
||||
|
||||
The tilde (`~`) comparison operator is for patch level ranges when a minor
|
||||
version is specified and major level changes when the minor number is missing.
|
||||
For example,
|
||||
|
||||
* `~1.2.3` is equivalent to `>= 1.2.3 < 1.3.0`
|
||||
* `~1` is equivalent to `>= 1, < 2`
|
||||
* `~2.3` is equivalent to `>= 2.3 < 2.4`
|
||||
* `~1.2.x` is equivalent to `>= 1.2.0 < 1.3.0`
|
||||
* `~1.x` is equivalent to `>= 1 < 2`
|
||||
|
||||
Caret Range Comparisons (Major)
|
||||
|
||||
The caret (`^`) comparison operator is for major level changes once a stable
|
||||
(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts
|
||||
as the API stability level. This is useful when comparisons of API versions as a
|
||||
major change is API breaking. For example,
|
||||
|
||||
* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
|
||||
* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
|
||||
* `^2.3` is equivalent to `>= 2.3, < 3`
|
||||
* `^2.x` is equivalent to `>= 2.0.0, < 3`
|
||||
* `^0.2.3` is equivalent to `>=0.2.3 <0.3.0`
|
||||
* `^0.2` is equivalent to `>=0.2.0 <0.3.0`
|
||||
* `^0.0.3` is equivalent to `>=0.0.3 <0.0.4`
|
||||
* `^0.0` is equivalent to `>=0.0.0 <0.1.0`
|
||||
* `^0` is equivalent to `>=0.0.0 <1.0.0`
|
||||
|
||||
Validation
|
||||
|
||||
In addition to testing a version against a constraint, a version can be validated
|
||||
against a constraint. When validation fails a slice of errors containing why a
|
||||
version didn't meet the constraint is returned. For example,
|
||||
|
||||
c, err := semver.NewConstraint("<= 1.2.3, >= 1.4")
|
||||
if err != nil {
|
||||
// Handle constraint not being parseable.
|
||||
}
|
||||
|
||||
v, _ := semver.NewVersion("1.3")
|
||||
if err != nil {
|
||||
// Handle version not being parseable.
|
||||
}
|
||||
|
||||
// Validate a version against a constraint.
|
||||
a, msgs := c.Validate(v)
|
||||
// a is false
|
||||
for _, m := range msgs {
|
||||
fmt.Println(m)
|
||||
|
||||
// Loops over the errors which would read
|
||||
// "1.3 is greater than 1.2.3"
|
||||
// "1.3 is less than 1.4"
|
||||
}
|
||||
*/
|
||||
package semver
|
22
vendor/github.com/Masterminds/semver/v3/fuzz.go
generated
vendored
Normal file
22
vendor/github.com/Masterminds/semver/v3/fuzz.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
// +build gofuzz
|
||||
|
||||
package semver
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
d := string(data)
|
||||
|
||||
// Test NewVersion
|
||||
_, _ = NewVersion(d)
|
||||
|
||||
// Test StrictNewVersion
|
||||
_, _ = StrictNewVersion(d)
|
||||
|
||||
// Test NewConstraint
|
||||
_, _ = NewConstraint(d)
|
||||
|
||||
// The return value should be 0 normally, 1 if the priority in future tests
|
||||
// should be increased, and -1 if future tests should skip passing in that
|
||||
// data. We do not have a reason to change priority so 0 is always returned.
|
||||
// There are example tests that do this.
|
||||
return 0
|
||||
}
|
@ -2,6 +2,7 @@ package semver
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -13,13 +14,23 @@ import (
|
||||
// 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")
|
||||
|
||||
// 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")
|
||||
|
||||
@ -27,30 +38,121 @@ var (
|
||||
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]+)?` +
|
||||
// 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
|
||||
major, minor, patch uint64
|
||||
pre string
|
||||
metadata string
|
||||
original string
|
||||
}
|
||||
|
||||
func init() {
|
||||
versionRegex = regexp.MustCompile("^" + SemVerRegex + "$")
|
||||
validPrereleaseRegex = regexp.MustCompile(ValidPrerelease)
|
||||
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.
|
||||
// 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 {
|
||||
@ -63,33 +165,45 @@ func NewVersion(v string) (*Version, error) {
|
||||
original: v,
|
||||
}
|
||||
|
||||
var temp int64
|
||||
temp, err := strconv.ParseInt(m[1], 10, 64)
|
||||
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)
|
||||
}
|
||||
sv.major = temp
|
||||
|
||||
if m[2] != "" {
|
||||
temp, err = strconv.ParseInt(strings.TrimPrefix(m[2], "."), 10, 64)
|
||||
sv.minor, err = strconv.ParseUint(strings.TrimPrefix(m[2], "."), 10, 64)
|
||||
if err != nil {
|
||||
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)
|
||||
sv.patch, err = strconv.ParseUint(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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
@ -107,7 +221,7 @@ func MustParse(v string) *Version {
|
||||
// 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 {
|
||||
func (v Version) String() string {
|
||||
var buf bytes.Buffer
|
||||
|
||||
fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch)
|
||||
@ -127,32 +241,32 @@ func (v *Version) Original() string {
|
||||
}
|
||||
|
||||
// Major returns the major version.
|
||||
func (v *Version) Major() int64 {
|
||||
func (v Version) Major() uint64 {
|
||||
return v.major
|
||||
}
|
||||
|
||||
// Minor returns the minor version.
|
||||
func (v *Version) Minor() int64 {
|
||||
func (v Version) Minor() uint64 {
|
||||
return v.minor
|
||||
}
|
||||
|
||||
// Patch returns the patch version.
|
||||
func (v *Version) Patch() int64 {
|
||||
func (v Version) Patch() uint64 {
|
||||
return v.patch
|
||||
}
|
||||
|
||||
// Prerelease returns the pre-release version.
|
||||
func (v *Version) Prerelease() string {
|
||||
func (v Version) Prerelease() string {
|
||||
return v.pre
|
||||
}
|
||||
|
||||
// Metadata returns the metadata on the version.
|
||||
func (v *Version) Metadata() string {
|
||||
func (v Version) Metadata() string {
|
||||
return v.metadata
|
||||
}
|
||||
|
||||
// originalVPrefix returns the original 'v' prefix if any.
|
||||
func (v *Version) originalVPrefix() string {
|
||||
func (v Version) originalVPrefix() string {
|
||||
|
||||
// Note, only lowercase v is supported as a prefix by the parser.
|
||||
if v.original != "" && v.original[:1] == "v" {
|
||||
@ -165,7 +279,7 @@ func (v *Version) originalVPrefix() string {
|
||||
// If the current version does not have prerelease/metadata information,
|
||||
// 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
|
||||
// it unsets both values and keeps current patch value
|
||||
func (v Version) IncPatch() Version {
|
||||
vNext := v
|
||||
// according to http://semver.org/#spec-item-9
|
||||
@ -217,11 +331,13 @@ func (v Version) IncMajor() Version {
|
||||
}
|
||||
|
||||
// SetPrerelease defines the prerelease value.
|
||||
// Value must not include the required 'hypen' prefix.
|
||||
// Value must not include the required 'hyphen' prefix.
|
||||
func (v Version) SetPrerelease(prerelease string) (Version, error) {
|
||||
vNext := v
|
||||
if len(prerelease) > 0 && !validPrereleaseRegex.MatchString(prerelease) {
|
||||
return vNext, ErrInvalidPrerelease
|
||||
if len(prerelease) > 0 {
|
||||
if err := validatePrerelease(prerelease); err != nil {
|
||||
return vNext, err
|
||||
}
|
||||
}
|
||||
vNext.pre = prerelease
|
||||
vNext.original = v.originalVPrefix() + "" + vNext.String()
|
||||
@ -232,8 +348,10 @@ func (v Version) SetPrerelease(prerelease string) (Version, error) {
|
||||
// Value must not include the required 'plus' prefix.
|
||||
func (v Version) SetMetadata(metadata string) (Version, error) {
|
||||
vNext := v
|
||||
if len(metadata) > 0 && !validPrereleaseRegex.MatchString(metadata) {
|
||||
return vNext, ErrInvalidMetadata
|
||||
if len(metadata) > 0 {
|
||||
if err := validateMetadata(metadata); err != nil {
|
||||
return vNext, err
|
||||
}
|
||||
}
|
||||
vNext.metadata = metadata
|
||||
vNext.original = v.originalVPrefix() + "" + vNext.String()
|
||||
@ -261,7 +379,9 @@ func (v *Version) Equal(o *Version) bool {
|
||||
// the version smaller, equal, or larger than the other version.
|
||||
//
|
||||
// Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is
|
||||
// lower than the version without a prerelease.
|
||||
// lower than the version without a prerelease. Compare always takes into account
|
||||
// prereleases. If you want to work with ranges using typical range syntaxes that
|
||||
// skip prereleases if the range is not looking for them use constraints.
|
||||
func (v *Version) Compare(o *Version) int {
|
||||
// Compare the major, minor, and patch version for differences. If a
|
||||
// difference is found return the comparison.
|
||||
@ -308,16 +428,37 @@ func (v *Version) UnmarshalJSON(b []byte) error {
|
||||
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) {
|
||||
func (v Version) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v.String())
|
||||
}
|
||||
|
||||
func compareSegment(v, o int64) int {
|
||||
// Scan implements the SQL.Scanner interface.
|
||||
func (v *Version) Scan(value interface{}) error {
|
||||
var s string
|
||||
s, _ = value.(string)
|
||||
temp, err := NewVersion(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.major = temp.major
|
||||
v.minor = temp.minor
|
||||
v.patch = temp.patch
|
||||
v.pre = temp.pre
|
||||
v.metadata = temp.metadata
|
||||
v.original = temp.original
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value implements the Driver.Valuer interface.
|
||||
func (v Version) Value() (driver.Value, error) {
|
||||
return v.String(), nil
|
||||
}
|
||||
|
||||
func compareSegment(v, o uint64) int {
|
||||
if v < o {
|
||||
return -1
|
||||
}
|
||||
@ -423,3 +564,43 @@ func comparePrePart(s, o string) int {
|
||||
return -1
|
||||
|
||||
}
|
||||
|
||||
// Like strings.ContainsAny but does an only instead of any.
|
||||
func containsOnly(s string, comp string) bool {
|
||||
return strings.IndexFunc(s, func(r rune) bool {
|
||||
return !strings.ContainsRune(comp, r)
|
||||
}) == -1
|
||||
}
|
||||
|
||||
// From the spec, "Identifiers MUST comprise only
|
||||
// ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty.
|
||||
// Numeric identifiers MUST NOT include leading zeroes.". These segments can
|
||||
// be dot separated.
|
||||
func validatePrerelease(p string) error {
|
||||
eparts := strings.Split(p, ".")
|
||||
for _, p := range eparts {
|
||||
if containsOnly(p, num) {
|
||||
if len(p) > 1 && p[0] == '0' {
|
||||
return ErrSegmentStartsZero
|
||||
}
|
||||
} else if !containsOnly(p, allowed) {
|
||||
return ErrInvalidPrerelease
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// From the spec, "Build metadata MAY be denoted by
|
||||
// appending a plus sign and a series of dot separated identifiers immediately
|
||||
// following the patch or pre-release version. Identifiers MUST comprise only
|
||||
// ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty."
|
||||
func validateMetadata(m string) error {
|
||||
eparts := strings.Split(m, ".")
|
||||
for _, p := range eparts {
|
||||
if !containsOnly(p, allowed) {
|
||||
return ErrInvalidMetadata
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
10
vendor/github.com/Masterminds/semver/version_fuzz.go
generated
vendored
10
vendor/github.com/Masterminds/semver/version_fuzz.go
generated
vendored
@ -1,10 +0,0 @@
|
||||
// +build gofuzz
|
||||
|
||||
package semver
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
if _, err := NewVersion(string(data)); err != nil {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
26
vendor/github.com/Masterminds/sprig/.travis.yml
generated
vendored
26
vendor/github.com/Masterminds/sprig/.travis.yml
generated
vendored
@ -1,26 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
- 1.13.x
|
||||
- tip
|
||||
|
||||
# Setting sudo access to false will let Travis CI use containers rather than
|
||||
# VMs to run the tests. For more details see:
|
||||
# - http://docs.travis-ci.com/user/workers/container-based-infrastructure/
|
||||
# - http://docs.travis-ci.com/user/workers/standard-infrastructure/
|
||||
sudo: false
|
||||
|
||||
script:
|
||||
- make setup test
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/06e3328629952dabe3e0
|
||||
on_success: change # options: [always|never|change] default: always
|
||||
on_failure: always # options: [always|never|change] default: always
|
||||
on_start: never # options: [always|never|change] default: always
|
13
vendor/github.com/Masterminds/sprig/Makefile
generated
vendored
13
vendor/github.com/Masterminds/sprig/Makefile
generated
vendored
@ -1,13 +0,0 @@
|
||||
|
||||
HAS_GLIDE := $(shell command -v glide;)
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go test -v .
|
||||
|
||||
.PHONY: setup
|
||||
setup:
|
||||
ifndef HAS_GLIDE
|
||||
go get -u github.com/Masterminds/glide
|
||||
endif
|
||||
glide install
|
26
vendor/github.com/Masterminds/sprig/appveyor.yml
generated
vendored
26
vendor/github.com/Masterminds/sprig/appveyor.yml
generated
vendored
@ -1,26 +0,0 @@
|
||||
|
||||
version: build-{build}.{branch}
|
||||
|
||||
clone_folder: C:\gopath\src\github.com\Masterminds\sprig
|
||||
shallow_clone: true
|
||||
|
||||
environment:
|
||||
GOPATH: C:\gopath
|
||||
|
||||
platform:
|
||||
- x64
|
||||
|
||||
install:
|
||||
- go get -u github.com/Masterminds/glide
|
||||
- set PATH=%GOPATH%\bin;%PATH%
|
||||
- go version
|
||||
- go env
|
||||
|
||||
build_script:
|
||||
- glide install
|
||||
- go install ./...
|
||||
|
||||
test_script:
|
||||
- go test -v
|
||||
|
||||
deploy: off
|
19
vendor/github.com/Masterminds/sprig/glide.yaml
generated
vendored
19
vendor/github.com/Masterminds/sprig/glide.yaml
generated
vendored
@ -1,19 +0,0 @@
|
||||
package: github.com/Masterminds/sprig
|
||||
import:
|
||||
- package: github.com/Masterminds/goutils
|
||||
version: ^1.0.0
|
||||
- package: github.com/google/uuid
|
||||
version: ^1.0.0
|
||||
- package: golang.org/x/crypto
|
||||
subpackages:
|
||||
- scrypt
|
||||
- package: github.com/Masterminds/semver
|
||||
version: ^v1.2.2
|
||||
- package: github.com/stretchr/testify
|
||||
version: ^v1.2.2
|
||||
- package: github.com/imdario/mergo
|
||||
version: ~0.3.7
|
||||
- package: github.com/huandu/xstrings
|
||||
version: ^1.2
|
||||
- package: github.com/mitchellh/copystructure
|
||||
version: ^1.0.0
|
169
vendor/github.com/Masterminds/sprig/numeric.go
generated
vendored
169
vendor/github.com/Masterminds/sprig/numeric.go
generated
vendored
@ -1,169 +0,0 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// toFloat64 converts 64-bit floats
|
||||
func toFloat64(v interface{}) float64 {
|
||||
if str, ok := v.(string); ok {
|
||||
iv, err := strconv.ParseFloat(str, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return iv
|
||||
}
|
||||
|
||||
val := reflect.Indirect(reflect.ValueOf(v))
|
||||
switch val.Kind() {
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||
return float64(val.Int())
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32:
|
||||
return float64(val.Uint())
|
||||
case reflect.Uint, reflect.Uint64:
|
||||
return float64(val.Uint())
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return val.Float()
|
||||
case reflect.Bool:
|
||||
if val.Bool() == true {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func toInt(v interface{}) int {
|
||||
//It's not optimal. Bud I don't want duplicate toInt64 code.
|
||||
return int(toInt64(v))
|
||||
}
|
||||
|
||||
// toInt64 converts integer types to 64-bit integers
|
||||
func toInt64(v interface{}) int64 {
|
||||
if str, ok := v.(string); ok {
|
||||
iv, err := strconv.ParseInt(str, 10, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return iv
|
||||
}
|
||||
|
||||
val := reflect.Indirect(reflect.ValueOf(v))
|
||||
switch val.Kind() {
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||
return val.Int()
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32:
|
||||
return int64(val.Uint())
|
||||
case reflect.Uint, reflect.Uint64:
|
||||
tv := val.Uint()
|
||||
if tv <= math.MaxInt64 {
|
||||
return int64(tv)
|
||||
}
|
||||
// TODO: What is the sensible thing to do here?
|
||||
return math.MaxInt64
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return int64(val.Float())
|
||||
case reflect.Bool:
|
||||
if val.Bool() == true {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func max(a interface{}, i ...interface{}) int64 {
|
||||
aa := toInt64(a)
|
||||
for _, b := range i {
|
||||
bb := toInt64(b)
|
||||
if bb > aa {
|
||||
aa = bb
|
||||
}
|
||||
}
|
||||
return aa
|
||||
}
|
||||
|
||||
func min(a interface{}, i ...interface{}) int64 {
|
||||
aa := toInt64(a)
|
||||
for _, b := range i {
|
||||
bb := toInt64(b)
|
||||
if bb < aa {
|
||||
aa = bb
|
||||
}
|
||||
}
|
||||
return aa
|
||||
}
|
||||
|
||||
func until(count int) []int {
|
||||
step := 1
|
||||
if count < 0 {
|
||||
step = -1
|
||||
}
|
||||
return untilStep(0, count, step)
|
||||
}
|
||||
|
||||
func untilStep(start, stop, step int) []int {
|
||||
v := []int{}
|
||||
|
||||
if stop < start {
|
||||
if step >= 0 {
|
||||
return v
|
||||
}
|
||||
for i := start; i > stop; i += step {
|
||||
v = append(v, i)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
if step <= 0 {
|
||||
return v
|
||||
}
|
||||
for i := start; i < stop; i += step {
|
||||
v = append(v, i)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func floor(a interface{}) float64 {
|
||||
aa := toFloat64(a)
|
||||
return math.Floor(aa)
|
||||
}
|
||||
|
||||
func ceil(a interface{}) float64 {
|
||||
aa := toFloat64(a)
|
||||
return math.Ceil(aa)
|
||||
}
|
||||
|
||||
func round(a interface{}, p int, r_opt ...float64) float64 {
|
||||
roundOn := .5
|
||||
if len(r_opt) > 0 {
|
||||
roundOn = r_opt[0]
|
||||
}
|
||||
val := toFloat64(a)
|
||||
places := toFloat64(p)
|
||||
|
||||
var round float64
|
||||
pow := math.Pow(10, places)
|
||||
digit := pow * val
|
||||
_, div := math.Modf(digit)
|
||||
if div >= roundOn {
|
||||
round = math.Ceil(digit)
|
||||
} else {
|
||||
round = math.Floor(digit)
|
||||
}
|
||||
return round / pow
|
||||
}
|
||||
|
||||
// converts unix octal to decimal
|
||||
func toDecimal(v interface{}) int64 {
|
||||
result, err := strconv.ParseInt(fmt.Sprint(v), 8, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return result
|
||||
}
|
35
vendor/github.com/Masterminds/sprig/regex.go
generated
vendored
35
vendor/github.com/Masterminds/sprig/regex.go
generated
vendored
@ -1,35 +0,0 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func regexMatch(regex string, s string) bool {
|
||||
match, _ := regexp.MatchString(regex, s)
|
||||
return match
|
||||
}
|
||||
|
||||
func regexFindAll(regex string, s string, n int) []string {
|
||||
r := regexp.MustCompile(regex)
|
||||
return r.FindAllString(s, n)
|
||||
}
|
||||
|
||||
func regexFind(regex string, s string) string {
|
||||
r := regexp.MustCompile(regex)
|
||||
return r.FindString(s)
|
||||
}
|
||||
|
||||
func regexReplaceAll(regex string, s string, repl string) string {
|
||||
r := regexp.MustCompile(regex)
|
||||
return r.ReplaceAllString(s, repl)
|
||||
}
|
||||
|
||||
func regexReplaceAllLiteral(regex string, s string, repl string) string {
|
||||
r := regexp.MustCompile(regex)
|
||||
return r.ReplaceAllLiteralString(s, repl)
|
||||
}
|
||||
|
||||
func regexSplit(regex string, s string, n int) []string {
|
||||
r := regexp.MustCompile(regex)
|
||||
return r.Split(s, n)
|
||||
}
|
@ -1,5 +1,93 @@
|
||||
# Changelog
|
||||
|
||||
## Release 3.2.1 (2021-02-04)
|
||||
|
||||
### Changed
|
||||
|
||||
- Upgraded `Masterminds/goutils` to `v1.1.1`. see the [Security Advisory](https://github.com/Masterminds/goutils/security/advisories/GHSA-xg2h-wx96-xgxr)
|
||||
|
||||
## Release 3.2.0 (2020-12-14)
|
||||
|
||||
### Added
|
||||
|
||||
- #211: Added randInt function (thanks @kochurovro)
|
||||
- #223: Added fromJson and mustFromJson functions (thanks @mholt)
|
||||
- #242: Added a bcrypt function (thanks @robbiet480)
|
||||
- #253: Added randBytes function (thanks @MikaelSmith)
|
||||
- #254: Added dig function for dicts (thanks @nyarly)
|
||||
- #257: Added regexQuoteMeta for quoting regex metadata (thanks @rheaton)
|
||||
- #261: Added filepath functions osBase, osDir, osExt, osClean, osIsAbs (thanks @zugl)
|
||||
- #268: Added and and all functions for testing conditions (thanks @phuslu)
|
||||
- #181: Added float64 arithmetic addf, add1f, subf, divf, mulf, maxf, and minf
|
||||
(thanks @andrewmostello)
|
||||
- #265: Added chunk function to split array into smaller arrays (thanks @karelbilek)
|
||||
- #270: Extend certificate functions to handle non-RSA keys + add support for
|
||||
ed25519 keys (thanks @misberner)
|
||||
|
||||
### Changed
|
||||
|
||||
- Removed testing and support for Go 1.12. ed25519 support requires Go 1.13 or newer
|
||||
- Using semver 3.1.1 and mergo 0.3.11
|
||||
|
||||
### Fixed
|
||||
|
||||
- #249: Fix htmlDateInZone example (thanks @spawnia)
|
||||
|
||||
NOTE: The dependency github.com/imdario/mergo reverted the breaking change in
|
||||
0.3.9 via 0.3.10 release.
|
||||
|
||||
## Release 3.1.0 (2020-04-16)
|
||||
|
||||
NOTE: The dependency github.com/imdario/mergo made a behavior change in 0.3.9
|
||||
that impacts sprig functionality. Do not use sprig with a version newer than 0.3.8.
|
||||
|
||||
### Added
|
||||
|
||||
- #225: Added support for generating htpasswd hash (thanks @rustycl0ck)
|
||||
- #224: Added duration filter (thanks @frebib)
|
||||
- #205: Added `seq` function (thanks @thadc23)
|
||||
|
||||
### Changed
|
||||
|
||||
- #203: Unlambda functions with correct signature (thanks @muesli)
|
||||
- #236: Updated the license formatting for GitHub display purposes
|
||||
- #238: Updated package dependency versions. Note, mergo not updated to 0.3.9
|
||||
as it causes a breaking change for sprig. That issue is tracked at
|
||||
https://github.com/imdario/mergo/issues/139
|
||||
|
||||
### Fixed
|
||||
|
||||
- #229: Fix `seq` example in docs (thanks @kalmant)
|
||||
|
||||
## Release 3.0.2 (2019-12-13)
|
||||
|
||||
### Fixed
|
||||
|
||||
- #220: Updating to semver v3.0.3 to fix issue with <= ranges
|
||||
- #218: fix typo elyptical->elliptic in ecdsa key description (thanks @laverya)
|
||||
|
||||
## Release 3.0.1 (2019-12-08)
|
||||
|
||||
### Fixed
|
||||
|
||||
- #212: Updated semver fixing broken constraint checking with ^0.0
|
||||
|
||||
## Release 3.0.0 (2019-10-02)
|
||||
|
||||
### Added
|
||||
|
||||
- #187: Added durationRound function (thanks @yjp20)
|
||||
- #189: Added numerous template functions that return errors rather than panic (thanks @nrvnrvn)
|
||||
- #193: Added toRawJson support (thanks @Dean-Coakley)
|
||||
- #197: Added get support to dicts (thanks @Dean-Coakley)
|
||||
|
||||
### Changed
|
||||
|
||||
- #186: Moving dependency management to Go modules
|
||||
- #186: Updated semver to v3. This has changes in the way ^ is handled
|
||||
- #194: Updated documentation on merging and how it copies. Added example using deepCopy
|
||||
- #196: trunc now supports negative values (thanks @Dean-Coakley)
|
||||
|
||||
## Release 2.22.0 (2019-10-02)
|
||||
|
||||
### Added
|
@ -1,5 +1,4 @@
|
||||
Sprig
|
||||
Copyright (C) 2013 Masterminds
|
||||
Copyright (C) 2013-2020 Masterminds
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
9
vendor/github.com/Masterminds/sprig/v3/Makefile
generated
vendored
Normal file
9
vendor/github.com/Masterminds/sprig/v3/Makefile
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
.PHONY: test
|
||||
test:
|
||||
@echo "==> Running tests"
|
||||
GO111MODULE=on go test -v
|
||||
|
||||
.PHONY: test-cover
|
||||
test-cover:
|
||||
@echo "==> Running Tests with coverage"
|
||||
GO111MODULE=on go test -cover .
|
@ -1,6 +1,9 @@
|
||||
# Sprig: Template functions for Go templates
|
||||
|
||||
[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/Masterminds/sprig/v3)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/Masterminds/sprig)](https://goreportcard.com/report/github.com/Masterminds/sprig)
|
||||
[![Stability: Sustained](https://masterminds.github.io/stability/sustained.svg)](https://masterminds.github.io/stability/sustained.html)
|
||||
[![Build Status](https://travis-ci.org/Masterminds/sprig.svg?branch=master)](https://travis-ci.org/Masterminds/sprig)
|
||||
[![](https://github.com/Masterminds/sprig/workflows/Tests/badge.svg)](https://github.com/Masterminds/sprig/actions)
|
||||
|
||||
The Go language comes with a [built-in template
|
||||
language](http://golang.org/pkg/text/template/), but not
|
||||
@ -11,6 +14,26 @@ It is inspired by the template functions found in
|
||||
[Twig](http://twig.sensiolabs.org/documentation) and in various
|
||||
JavaScript libraries, such as [underscore.js](http://underscorejs.org/).
|
||||
|
||||
## IMPORTANT NOTES
|
||||
|
||||
Sprig leverages [mergo](https://github.com/imdario/mergo) to handle merges. In
|
||||
its v0.3.9 release there was a behavior change that impacts merging template
|
||||
functions in sprig. It is currently recommended to use v0.3.8 of that package.
|
||||
Using v0.3.9 will cause sprig tests to fail. The issue in mergo is tracked at
|
||||
https://github.com/imdario/mergo/issues/139.
|
||||
|
||||
## Package Versions
|
||||
|
||||
There are two active major versions of the `sprig` package.
|
||||
|
||||
* v3 is currently stable release series on the `master` branch. The Go API should
|
||||
remain compatible with v2, the current stable version. Behavior change behind
|
||||
some functions is the reason for the new major version.
|
||||
* v2 is the previous stable release series. It has been more than three years since
|
||||
the initial release of v2. You can read the documentation and see the code
|
||||
on the [release-2](https://github.com/Masterminds/sprig/tree/release-2) branch.
|
||||
Bug fixes to this major version will continue for some time.
|
||||
|
||||
## Usage
|
||||
|
||||
**Template developers**: Please use Sprig's [function documentation](http://masterminds.github.io/sprig/) for
|
@ -2,10 +2,12 @@ package sprig
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/elliptic"
|
||||
"crypto/hmac"
|
||||
"crypto/rand"
|
||||
@ -21,13 +23,16 @@ import (
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"hash/adler32"
|
||||
"io"
|
||||
"math/big"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
bcrypt_lib "golang.org/x/crypto/bcrypt"
|
||||
"golang.org/x/crypto/scrypt"
|
||||
)
|
||||
|
||||
@ -46,14 +51,38 @@ func adler32sum(input string) string {
|
||||
return fmt.Sprintf("%d", hash)
|
||||
}
|
||||
|
||||
// uuidv4 provides a safe and secure UUID v4 implementation
|
||||
func uuidv4() string {
|
||||
return fmt.Sprintf("%s", uuid.New())
|
||||
func bcrypt(input string) string {
|
||||
hash, err := bcrypt_lib.GenerateFromPassword([]byte(input), bcrypt_lib.DefaultCost)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("failed to encrypt string with bcrypt: %s", err)
|
||||
}
|
||||
|
||||
return string(hash)
|
||||
}
|
||||
|
||||
var master_password_seed = "com.lyndir.masterpassword"
|
||||
func htpasswd(username string, password string) string {
|
||||
if strings.Contains(username, ":") {
|
||||
return fmt.Sprintf("invalid username: %s", username)
|
||||
}
|
||||
return fmt.Sprintf("%s:%s", username, bcrypt(password))
|
||||
}
|
||||
|
||||
var password_type_templates = map[string][][]byte{
|
||||
func randBytes(count int) (string, error) {
|
||||
buf := make([]byte, count)
|
||||
if _, err := rand.Read(buf); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(buf), nil
|
||||
}
|
||||
|
||||
// uuidv4 provides a safe and secure UUID v4 implementation
|
||||
func uuidv4() string {
|
||||
return uuid.New().String()
|
||||
}
|
||||
|
||||
var masterPasswordSeed = "com.lyndir.masterpassword"
|
||||
|
||||
var passwordTypeTemplates = map[string][][]byte{
|
||||
"maximum": {[]byte("anoxxxxxxxxxxxxxxxxx"), []byte("axxxxxxxxxxxxxxxxxno")},
|
||||
"long": {[]byte("CvcvnoCvcvCvcv"), []byte("CvcvCvcvnoCvcv"), []byte("CvcvCvcvCvcvno"), []byte("CvccnoCvcvCvcv"), []byte("CvccCvcvnoCvcv"),
|
||||
[]byte("CvccCvcvCvcvno"), []byte("CvcvnoCvccCvcv"), []byte("CvcvCvccnoCvcv"), []byte("CvcvCvccCvcvno"), []byte("CvcvnoCvcvCvcc"),
|
||||
@ -66,7 +95,7 @@ var password_type_templates = map[string][][]byte{
|
||||
"pin": {[]byte("nnnn")},
|
||||
}
|
||||
|
||||
var template_characters = map[byte]string{
|
||||
var templateCharacters = map[byte]string{
|
||||
'V': "AEIOU",
|
||||
'C': "BCDFGHJKLMNPQRSTVWXYZ",
|
||||
'v': "aeiou",
|
||||
@ -78,14 +107,14 @@ var template_characters = map[byte]string{
|
||||
'x': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()",
|
||||
}
|
||||
|
||||
func derivePassword(counter uint32, password_type, password, user, site string) string {
|
||||
var templates = password_type_templates[password_type]
|
||||
func derivePassword(counter uint32, passwordType, password, user, site string) string {
|
||||
var templates = passwordTypeTemplates[passwordType]
|
||||
if templates == nil {
|
||||
return fmt.Sprintf("cannot find password template %s", password_type)
|
||||
return fmt.Sprintf("cannot find password template %s", passwordType)
|
||||
}
|
||||
|
||||
var buffer bytes.Buffer
|
||||
buffer.WriteString(master_password_seed)
|
||||
buffer.WriteString(masterPasswordSeed)
|
||||
binary.Write(&buffer, binary.BigEndian, uint32(len(user)))
|
||||
buffer.WriteString(user)
|
||||
|
||||
@ -95,7 +124,7 @@ func derivePassword(counter uint32, password_type, password, user, site string)
|
||||
return fmt.Sprintf("failed to derive password: %s", err)
|
||||
}
|
||||
|
||||
buffer.Truncate(len(master_password_seed))
|
||||
buffer.Truncate(len(masterPasswordSeed))
|
||||
binary.Write(&buffer, binary.BigEndian, uint32(len(site)))
|
||||
buffer.WriteString(site)
|
||||
binary.Write(&buffer, binary.BigEndian, counter)
|
||||
@ -107,9 +136,9 @@ func derivePassword(counter uint32, password_type, password, user, site string)
|
||||
|
||||
buffer.Truncate(0)
|
||||
for i, element := range temp {
|
||||
pass_chars := template_characters[element]
|
||||
pass_char := pass_chars[int(seed[i+1])%len(pass_chars)]
|
||||
buffer.WriteByte(pass_char)
|
||||
passChars := templateCharacters[element]
|
||||
passChar := passChars[int(seed[i+1])%len(passChars)]
|
||||
buffer.WriteByte(passChar)
|
||||
}
|
||||
|
||||
return buffer.String()
|
||||
@ -133,6 +162,8 @@ func generatePrivateKey(typ string) string {
|
||||
case "ecdsa":
|
||||
// again, good enough for government work
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
case "ed25519":
|
||||
_, priv, err = ed25519.GenerateKey(rand.Reader)
|
||||
default:
|
||||
return "Unknown type " + typ
|
||||
}
|
||||
@ -143,6 +174,8 @@ func generatePrivateKey(typ string) string {
|
||||
return string(pem.EncodeToMemory(pemBlockForKey(priv)))
|
||||
}
|
||||
|
||||
// DSAKeyFormat stores the format for DSA keys.
|
||||
// Used by pemBlockForKey
|
||||
type DSAKeyFormat struct {
|
||||
Version int
|
||||
P, Q, G, Y, X *big.Int
|
||||
@ -163,7 +196,73 @@ func pemBlockForKey(priv interface{}) *pem.Block {
|
||||
b, _ := x509.MarshalECPrivateKey(k)
|
||||
return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
|
||||
default:
|
||||
return nil
|
||||
// attempt PKCS#8 format for all other keys
|
||||
b, err := x509.MarshalPKCS8PrivateKey(k)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return &pem.Block{Type: "PRIVATE KEY", Bytes: b}
|
||||
}
|
||||
}
|
||||
|
||||
func parsePrivateKeyPEM(pemBlock string) (crypto.PrivateKey, error) {
|
||||
block, _ := pem.Decode([]byte(pemBlock))
|
||||
if block == nil {
|
||||
return nil, errors.New("no PEM data in input")
|
||||
}
|
||||
|
||||
if block.Type == "PRIVATE KEY" {
|
||||
priv, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding PEM as PKCS#8: %s", err)
|
||||
}
|
||||
return priv, nil
|
||||
} else if !strings.HasSuffix(block.Type, " PRIVATE KEY") {
|
||||
return nil, fmt.Errorf("no private key data in PEM block of type %s", block.Type)
|
||||
}
|
||||
|
||||
switch block.Type[:len(block.Type)-12] { // strip " PRIVATE KEY"
|
||||
case "RSA":
|
||||
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing RSA private key from PEM: %s", err)
|
||||
}
|
||||
return priv, nil
|
||||
case "EC":
|
||||
priv, err := x509.ParseECPrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing EC private key from PEM: %s", err)
|
||||
}
|
||||
return priv, nil
|
||||
case "DSA":
|
||||
var k DSAKeyFormat
|
||||
_, err := asn1.Unmarshal(block.Bytes, &k)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing DSA private key from PEM: %s", err)
|
||||
}
|
||||
priv := &dsa.PrivateKey{
|
||||
PublicKey: dsa.PublicKey{
|
||||
Parameters: dsa.Parameters{
|
||||
P: k.P, Q: k.Q, G: k.G,
|
||||
},
|
||||
Y: k.Y,
|
||||
},
|
||||
X: k.X,
|
||||
}
|
||||
return priv, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid private key type %s", block.Type)
|
||||
}
|
||||
}
|
||||
|
||||
func getPublicKey(priv crypto.PrivateKey) (crypto.PublicKey, error) {
|
||||
switch k := priv.(type) {
|
||||
case interface{ Public() crypto.PublicKey }:
|
||||
return k.Public(), nil
|
||||
case *dsa.PrivateKey:
|
||||
return &k.PublicKey, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unable to get public key for type %T", priv)
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,14 +296,10 @@ func buildCustomCertificate(b64cert string, b64key string) (certificate, error)
|
||||
)
|
||||
}
|
||||
|
||||
decodedKey, _ := pem.Decode(key)
|
||||
if decodedKey == nil {
|
||||
return crt, errors.New("unable to decode key")
|
||||
}
|
||||
_, err = x509.ParsePKCS1PrivateKey(decodedKey.Bytes)
|
||||
_, err = parsePrivateKeyPEM(string(key))
|
||||
if err != nil {
|
||||
return crt, fmt.Errorf(
|
||||
"error parsing prive key: decodedKey.Bytes: %s",
|
||||
"error parsing private key: %s",
|
||||
err,
|
||||
)
|
||||
}
|
||||
@ -218,6 +313,31 @@ func buildCustomCertificate(b64cert string, b64key string) (certificate, error)
|
||||
func generateCertificateAuthority(
|
||||
cn string,
|
||||
daysValid int,
|
||||
) (certificate, error) {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return certificate{}, fmt.Errorf("error generating rsa key: %s", err)
|
||||
}
|
||||
|
||||
return generateCertificateAuthorityWithKeyInternal(cn, daysValid, priv)
|
||||
}
|
||||
|
||||
func generateCertificateAuthorityWithPEMKey(
|
||||
cn string,
|
||||
daysValid int,
|
||||
privPEM string,
|
||||
) (certificate, error) {
|
||||
priv, err := parsePrivateKeyPEM(privPEM)
|
||||
if err != nil {
|
||||
return certificate{}, fmt.Errorf("parsing private key: %s", err)
|
||||
}
|
||||
return generateCertificateAuthorityWithKeyInternal(cn, daysValid, priv)
|
||||
}
|
||||
|
||||
func generateCertificateAuthorityWithKeyInternal(
|
||||
cn string,
|
||||
daysValid int,
|
||||
priv crypto.PrivateKey,
|
||||
) (certificate, error) {
|
||||
ca := certificate{}
|
||||
|
||||
@ -231,17 +351,9 @@ func generateCertificateAuthority(
|
||||
x509.KeyUsageCertSign
|
||||
template.IsCA = true
|
||||
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return ca, fmt.Errorf("error generating rsa key: %s", err)
|
||||
}
|
||||
|
||||
ca.Cert, ca.Key, err = getCertAndKey(template, priv, template, priv)
|
||||
if err != nil {
|
||||
return ca, err
|
||||
}
|
||||
|
||||
return ca, nil
|
||||
return ca, err
|
||||
}
|
||||
|
||||
func generateSelfSignedCertificate(
|
||||
@ -249,6 +361,34 @@ func generateSelfSignedCertificate(
|
||||
ips []interface{},
|
||||
alternateDNS []interface{},
|
||||
daysValid int,
|
||||
) (certificate, error) {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return certificate{}, fmt.Errorf("error generating rsa key: %s", err)
|
||||
}
|
||||
return generateSelfSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, priv)
|
||||
}
|
||||
|
||||
func generateSelfSignedCertificateWithPEMKey(
|
||||
cn string,
|
||||
ips []interface{},
|
||||
alternateDNS []interface{},
|
||||
daysValid int,
|
||||
privPEM string,
|
||||
) (certificate, error) {
|
||||
priv, err := parsePrivateKeyPEM(privPEM)
|
||||
if err != nil {
|
||||
return certificate{}, fmt.Errorf("parsing private key: %s", err)
|
||||
}
|
||||
return generateSelfSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, priv)
|
||||
}
|
||||
|
||||
func generateSelfSignedCertificateWithKeyInternal(
|
||||
cn string,
|
||||
ips []interface{},
|
||||
alternateDNS []interface{},
|
||||
daysValid int,
|
||||
priv crypto.PrivateKey,
|
||||
) (certificate, error) {
|
||||
cert := certificate{}
|
||||
|
||||
@ -257,17 +397,9 @@ func generateSelfSignedCertificate(
|
||||
return cert, err
|
||||
}
|
||||
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return cert, fmt.Errorf("error generating rsa key: %s", err)
|
||||
}
|
||||
|
||||
cert.Cert, cert.Key, err = getCertAndKey(template, priv, template, priv)
|
||||
if err != nil {
|
||||
return cert, err
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
return cert, err
|
||||
}
|
||||
|
||||
func generateSignedCertificate(
|
||||
@ -276,6 +408,36 @@ func generateSignedCertificate(
|
||||
alternateDNS []interface{},
|
||||
daysValid int,
|
||||
ca certificate,
|
||||
) (certificate, error) {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return certificate{}, fmt.Errorf("error generating rsa key: %s", err)
|
||||
}
|
||||
return generateSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, ca, priv)
|
||||
}
|
||||
|
||||
func generateSignedCertificateWithPEMKey(
|
||||
cn string,
|
||||
ips []interface{},
|
||||
alternateDNS []interface{},
|
||||
daysValid int,
|
||||
ca certificate,
|
||||
privPEM string,
|
||||
) (certificate, error) {
|
||||
priv, err := parsePrivateKeyPEM(privPEM)
|
||||
if err != nil {
|
||||
return certificate{}, fmt.Errorf("parsing private key: %s", err)
|
||||
}
|
||||
return generateSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, ca, priv)
|
||||
}
|
||||
|
||||
func generateSignedCertificateWithKeyInternal(
|
||||
cn string,
|
||||
ips []interface{},
|
||||
alternateDNS []interface{},
|
||||
daysValid int,
|
||||
ca certificate,
|
||||
priv crypto.PrivateKey,
|
||||
) (certificate, error) {
|
||||
cert := certificate{}
|
||||
|
||||
@ -290,14 +452,10 @@ func generateSignedCertificate(
|
||||
err,
|
||||
)
|
||||
}
|
||||
decodedSignerKey, _ := pem.Decode([]byte(ca.Key))
|
||||
if decodedSignerKey == nil {
|
||||
return cert, errors.New("unable to decode key")
|
||||
}
|
||||
signerKey, err := x509.ParsePKCS1PrivateKey(decodedSignerKey.Bytes)
|
||||
signerKey, err := parsePrivateKeyPEM(ca.Key)
|
||||
if err != nil {
|
||||
return cert, fmt.Errorf(
|
||||
"error parsing prive key: decodedSignerKey.Bytes: %s",
|
||||
"error parsing private key: %s",
|
||||
err,
|
||||
)
|
||||
}
|
||||
@ -307,35 +465,31 @@ func generateSignedCertificate(
|
||||
return cert, err
|
||||
}
|
||||
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return cert, fmt.Errorf("error generating rsa key: %s", err)
|
||||
}
|
||||
|
||||
cert.Cert, cert.Key, err = getCertAndKey(
|
||||
template,
|
||||
priv,
|
||||
signerCert,
|
||||
signerKey,
|
||||
)
|
||||
if err != nil {
|
||||
return cert, err
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
return cert, err
|
||||
}
|
||||
|
||||
func getCertAndKey(
|
||||
template *x509.Certificate,
|
||||
signeeKey *rsa.PrivateKey,
|
||||
signeeKey crypto.PrivateKey,
|
||||
parent *x509.Certificate,
|
||||
signingKey *rsa.PrivateKey,
|
||||
signingKey crypto.PrivateKey,
|
||||
) (string, string, error) {
|
||||
signeePubKey, err := getPublicKey(signeeKey)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("error retrieving public key from signee key: %s", err)
|
||||
}
|
||||
derBytes, err := x509.CreateCertificate(
|
||||
rand.Reader,
|
||||
template,
|
||||
parent,
|
||||
&signeeKey.PublicKey,
|
||||
signeePubKey,
|
||||
signingKey,
|
||||
)
|
||||
if err != nil {
|
||||
@ -353,15 +507,12 @@ func getCertAndKey(
|
||||
keyBuffer := bytes.Buffer{}
|
||||
if err := pem.Encode(
|
||||
&keyBuffer,
|
||||
&pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(signeeKey),
|
||||
},
|
||||
pemBlockForKey(signeeKey),
|
||||
); err != nil {
|
||||
return "", "", fmt.Errorf("error pem-encoding key: %s", err)
|
||||
}
|
||||
|
||||
return string(certBuffer.Bytes()), string(keyBuffer.Bytes()), nil
|
||||
return certBuffer.String(), keyBuffer.String(), nil
|
||||
}
|
||||
|
||||
func getBaseCertTemplate(
|
@ -55,6 +55,14 @@ func dateModify(fmt string, date time.Time) time.Time {
|
||||
return date.Add(d)
|
||||
}
|
||||
|
||||
func mustDateModify(fmt string, date time.Time) (time.Time, error) {
|
||||
d, err := time.ParseDuration(fmt)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
return date.Add(d), nil
|
||||
}
|
||||
|
||||
func dateAgo(date interface{}) string {
|
||||
var t time.Time
|
||||
|
||||
@ -73,11 +81,72 @@ func dateAgo(date interface{}) string {
|
||||
return duration.String()
|
||||
}
|
||||
|
||||
func duration(sec interface{}) string {
|
||||
var n int64
|
||||
switch value := sec.(type) {
|
||||
default:
|
||||
n = 0
|
||||
case string:
|
||||
n, _ = strconv.ParseInt(value, 10, 64)
|
||||
case int64:
|
||||
n = value
|
||||
}
|
||||
return (time.Duration(n) * time.Second).String()
|
||||
}
|
||||
|
||||
func durationRound(duration interface{}) string {
|
||||
var d time.Duration
|
||||
switch duration := duration.(type) {
|
||||
default:
|
||||
d = 0
|
||||
case string:
|
||||
d, _ = time.ParseDuration(duration)
|
||||
case int64:
|
||||
d = time.Duration(duration)
|
||||
case time.Time:
|
||||
d = time.Since(duration)
|
||||
}
|
||||
|
||||
u := uint64(d)
|
||||
neg := d < 0
|
||||
if neg {
|
||||
u = -u
|
||||
}
|
||||
|
||||
var (
|
||||
year = uint64(time.Hour) * 24 * 365
|
||||
month = uint64(time.Hour) * 24 * 30
|
||||
day = uint64(time.Hour) * 24
|
||||
hour = uint64(time.Hour)
|
||||
minute = uint64(time.Minute)
|
||||
second = uint64(time.Second)
|
||||
)
|
||||
switch {
|
||||
case u > year:
|
||||
return strconv.FormatUint(u/year, 10) + "y"
|
||||
case u > month:
|
||||
return strconv.FormatUint(u/month, 10) + "mo"
|
||||
case u > day:
|
||||
return strconv.FormatUint(u/day, 10) + "d"
|
||||
case u > hour:
|
||||
return strconv.FormatUint(u/hour, 10) + "h"
|
||||
case u > minute:
|
||||
return strconv.FormatUint(u/minute, 10) + "m"
|
||||
case u > second:
|
||||
return strconv.FormatUint(u/second, 10) + "s"
|
||||
}
|
||||
return "0s"
|
||||
}
|
||||
|
||||
func toDate(fmt, str string) time.Time {
|
||||
t, _ := time.ParseInLocation(fmt, str, time.Local)
|
||||
return t
|
||||
}
|
||||
|
||||
func mustToDate(fmt, str string) (time.Time, error) {
|
||||
return time.ParseInLocation(fmt, str, time.Local)
|
||||
}
|
||||
|
||||
func unixEpoch(date time.Time) string {
|
||||
return strconv.FormatInt(date.Unix(), 10)
|
||||
}
|
@ -1,10 +1,18 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
// dfault checks whether `given` is set, and returns default if not set.
|
||||
//
|
||||
// This returns `d` if `given` appears not to be set, and `given` otherwise.
|
||||
@ -37,7 +45,7 @@ func empty(given interface{}) bool {
|
||||
case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
|
||||
return g.Len() == 0
|
||||
case reflect.Bool:
|
||||
return g.Bool() == false
|
||||
return !g.Bool()
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
return g.Complex() == 0
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
@ -61,18 +69,90 @@ func coalesce(v ...interface{}) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// all returns true if empty(x) is false for all values x in the list.
|
||||
// If the list is empty, return true.
|
||||
func all(v ...interface{}) bool {
|
||||
for _, val := range v {
|
||||
if empty(val) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// any returns true if empty(x) is false for any x in the list.
|
||||
// If the list is empty, return false.
|
||||
func any(v ...interface{}) bool {
|
||||
for _, val := range v {
|
||||
if !empty(val) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// fromJson decodes JSON into a structured value, ignoring errors.
|
||||
func fromJson(v string) interface{} {
|
||||
output, _ := mustFromJson(v)
|
||||
return output
|
||||
}
|
||||
|
||||
// mustFromJson decodes JSON into a structured value, returning errors.
|
||||
func mustFromJson(v string) (interface{}, error) {
|
||||
var output interface{}
|
||||
err := json.Unmarshal([]byte(v), &output)
|
||||
return output, err
|
||||
}
|
||||
|
||||
// toJson encodes an item into a JSON string
|
||||
func toJson(v interface{}) string {
|
||||
output, _ := json.Marshal(v)
|
||||
return string(output)
|
||||
}
|
||||
|
||||
func mustToJson(v interface{}) (string, error) {
|
||||
output, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(output), nil
|
||||
}
|
||||
|
||||
// toPrettyJson encodes an item into a pretty (indented) JSON string
|
||||
func toPrettyJson(v interface{}) string {
|
||||
output, _ := json.MarshalIndent(v, "", " ")
|
||||
return string(output)
|
||||
}
|
||||
|
||||
func mustToPrettyJson(v interface{}) (string, error) {
|
||||
output, err := json.MarshalIndent(v, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(output), nil
|
||||
}
|
||||
|
||||
// toRawJson encodes an item into a JSON string with no escaping of HTML characters.
|
||||
func toRawJson(v interface{}) string {
|
||||
output, err := mustToRawJson(v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(output)
|
||||
}
|
||||
|
||||
// mustToRawJson encodes an item into a JSON string with no escaping of HTML characters.
|
||||
func mustToRawJson(v interface{}) (string, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
enc := json.NewEncoder(buf)
|
||||
enc.SetEscapeHTML(false)
|
||||
err := enc.Encode(&v)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.TrimSuffix(buf.String(), "\n"), nil
|
||||
}
|
||||
|
||||
// ternary returns the first value if the last value is true, otherwise returns the second value.
|
||||
func ternary(vt interface{}, vf interface{}, v bool) interface{} {
|
||||
if v {
|
@ -5,6 +5,13 @@ import (
|
||||
"github.com/mitchellh/copystructure"
|
||||
)
|
||||
|
||||
func get(d map[string]interface{}, key string) interface{} {
|
||||
if val, ok := d[key]; ok {
|
||||
return val
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func set(d map[string]interface{}, key string, value interface{}) map[string]interface{} {
|
||||
d[key] = value
|
||||
return d
|
||||
@ -90,6 +97,15 @@ func merge(dst map[string]interface{}, srcs ...map[string]interface{}) interface
|
||||
return dst
|
||||
}
|
||||
|
||||
func mustMerge(dst map[string]interface{}, srcs ...map[string]interface{}) (interface{}, error) {
|
||||
for _, src := range srcs {
|
||||
if err := mergo.Merge(&dst, src); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
func mergeOverwrite(dst map[string]interface{}, srcs ...map[string]interface{}) interface{} {
|
||||
for _, src := range srcs {
|
||||
if err := mergo.MergeWithOverwrite(&dst, src); err != nil {
|
||||
@ -100,6 +116,15 @@ func mergeOverwrite(dst map[string]interface{}, srcs ...map[string]interface{})
|
||||
return dst
|
||||
}
|
||||
|
||||
func mustMergeOverwrite(dst map[string]interface{}, srcs ...map[string]interface{}) (interface{}, error) {
|
||||
for _, src := range srcs {
|
||||
if err := mergo.MergeWithOverwrite(&dst, src); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
func values(dict map[string]interface{}) []interface{} {
|
||||
values := []interface{}{}
|
||||
for _, value := range dict {
|
||||
@ -110,10 +135,40 @@ func values(dict map[string]interface{}) []interface{} {
|
||||
}
|
||||
|
||||
func deepCopy(i interface{}) interface{} {
|
||||
c, err := copystructure.Copy(i)
|
||||
c, err := mustDeepCopy(i)
|
||||
if err != nil {
|
||||
panic("deepCopy error: " + err.Error())
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func mustDeepCopy(i interface{}) (interface{}, error) {
|
||||
return copystructure.Copy(i)
|
||||
}
|
||||
|
||||
func dig(ps ...interface{}) (interface{}, error) {
|
||||
if len(ps) < 3 {
|
||||
panic("dig needs at least three arguments")
|
||||
}
|
||||
dict := ps[len(ps)-1].(map[string]interface{})
|
||||
def := ps[len(ps)-2]
|
||||
ks := make([]string, len(ps)-2)
|
||||
for i := 0; i < len(ks); i++ {
|
||||
ks[i] = ps[i].(string)
|
||||
}
|
||||
|
||||
return digFromDict(dict, def, ks)
|
||||
}
|
||||
|
||||
func digFromDict(dict map[string]interface{}, d interface{}, ks []string) (interface{}, error) {
|
||||
k, ns := ks[0], ks[1:len(ks)]
|
||||
step, has := dict[k]
|
||||
if !has {
|
||||
return d, nil
|
||||
}
|
||||
if len(ns) == 0 {
|
||||
return step, nil
|
||||
}
|
||||
return digFromDict(step.(map[string]interface{}), d, ns)
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Sprig: Template functions for Go.
|
||||
Package sprig provides template functions for Go.
|
||||
|
||||
This package contains a number of utility functions for working with data
|
||||
inside of Go `html/template` and `text/template` files.
|
@ -3,8 +3,10 @@ package sprig
|
||||
import (
|
||||
"errors"
|
||||
"html/template"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -13,9 +15,10 @@ import (
|
||||
|
||||
util "github.com/Masterminds/goutils"
|
||||
"github.com/huandu/xstrings"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
// Produce the function map.
|
||||
// FuncMap produces the function map.
|
||||
//
|
||||
// Use this to pass the functions into the template engine:
|
||||
//
|
||||
@ -63,7 +66,7 @@ func GenericFuncMap() map[string]interface{} {
|
||||
}
|
||||
|
||||
// These functions are not guaranteed to evaluate to the same result for given input, because they
|
||||
// refer to the environemnt or global state.
|
||||
// refer to the environment or global state.
|
||||
var nonhermeticFunctions = []string{
|
||||
// Date functions
|
||||
"date",
|
||||
@ -80,6 +83,7 @@ var nonhermeticFunctions = []string{
|
||||
"randAlpha",
|
||||
"randAscii",
|
||||
"randNumeric",
|
||||
"randBytes",
|
||||
"uuidv4",
|
||||
|
||||
// OS
|
||||
@ -94,17 +98,22 @@ var genericMap = map[string]interface{}{
|
||||
"hello": func() string { return "Hello!" },
|
||||
|
||||
// Date functions
|
||||
"date": date,
|
||||
"date_in_zone": dateInZone,
|
||||
"date_modify": dateModify,
|
||||
"now": func() time.Time { return time.Now() },
|
||||
"htmlDate": htmlDate,
|
||||
"htmlDateInZone": htmlDateInZone,
|
||||
"dateInZone": dateInZone,
|
||||
"dateModify": dateModify,
|
||||
"ago": dateAgo,
|
||||
"toDate": toDate,
|
||||
"unixEpoch": unixEpoch,
|
||||
"ago": dateAgo,
|
||||
"date": date,
|
||||
"date_in_zone": dateInZone,
|
||||
"date_modify": dateModify,
|
||||
"dateInZone": dateInZone,
|
||||
"dateModify": dateModify,
|
||||
"duration": duration,
|
||||
"durationRound": durationRound,
|
||||
"htmlDate": htmlDate,
|
||||
"htmlDateInZone": htmlDateInZone,
|
||||
"must_date_modify": mustDateModify,
|
||||
"mustDateModify": mustDateModify,
|
||||
"mustToDate": mustToDate,
|
||||
"now": time.Now,
|
||||
"toDate": toDate,
|
||||
"unixEpoch": unixEpoch,
|
||||
|
||||
// Strings
|
||||
"abbrev": abbrev,
|
||||
@ -158,6 +167,7 @@ var genericMap = map[string]interface{}{
|
||||
"int64": toInt64,
|
||||
"int": toInt,
|
||||
"float64": toFloat64,
|
||||
"seq": seq,
|
||||
"toDecimal": toDecimal,
|
||||
|
||||
//"gt": func(a, b int) bool {return a > b},
|
||||
@ -194,9 +204,28 @@ var genericMap = map[string]interface{}{
|
||||
}
|
||||
return val
|
||||
},
|
||||
"randInt": func(min, max int) int { return rand.Intn(max-min) + min },
|
||||
"add1f": func(i interface{}) float64 {
|
||||
return execDecimalOp(i, []interface{}{1}, func(d1, d2 decimal.Decimal) decimal.Decimal { return d1.Add(d2) })
|
||||
},
|
||||
"addf": func(i ...interface{}) float64 {
|
||||
a := interface{}(float64(0))
|
||||
return execDecimalOp(a, i, func(d1, d2 decimal.Decimal) decimal.Decimal { return d1.Add(d2) })
|
||||
},
|
||||
"subf": func(a interface{}, v ...interface{}) float64 {
|
||||
return execDecimalOp(a, v, func(d1, d2 decimal.Decimal) decimal.Decimal { return d1.Sub(d2) })
|
||||
},
|
||||
"divf": func(a interface{}, v ...interface{}) float64 {
|
||||
return execDecimalOp(a, v, func(d1, d2 decimal.Decimal) decimal.Decimal { return d1.Div(d2) })
|
||||
},
|
||||
"mulf": func(a interface{}, v ...interface{}) float64 {
|
||||
return execDecimalOp(a, v, func(d1, d2 decimal.Decimal) decimal.Decimal { return d1.Mul(d2) })
|
||||
},
|
||||
"biggest": max,
|
||||
"max": max,
|
||||
"min": min,
|
||||
"maxf": maxf,
|
||||
"minf": minf,
|
||||
"ceil": ceil,
|
||||
"floor": floor,
|
||||
"round": round,
|
||||
@ -207,14 +236,24 @@ var genericMap = map[string]interface{}{
|
||||
"sortAlpha": sortAlpha,
|
||||
|
||||
// Defaults
|
||||
"default": dfault,
|
||||
"empty": empty,
|
||||
"coalesce": coalesce,
|
||||
"compact": compact,
|
||||
"deepCopy": deepCopy,
|
||||
"toJson": toJson,
|
||||
"toPrettyJson": toPrettyJson,
|
||||
"ternary": ternary,
|
||||
"default": dfault,
|
||||
"empty": empty,
|
||||
"coalesce": coalesce,
|
||||
"all": all,
|
||||
"any": any,
|
||||
"compact": compact,
|
||||
"mustCompact": mustCompact,
|
||||
"fromJson": fromJson,
|
||||
"toJson": toJson,
|
||||
"toPrettyJson": toPrettyJson,
|
||||
"toRawJson": toRawJson,
|
||||
"mustFromJson": mustFromJson,
|
||||
"mustToJson": mustToJson,
|
||||
"mustToPrettyJson": mustToPrettyJson,
|
||||
"mustToRawJson": mustToRawJson,
|
||||
"ternary": ternary,
|
||||
"deepCopy": deepCopy,
|
||||
"mustDeepCopy": mustDeepCopy,
|
||||
|
||||
// Reflection
|
||||
"typeOf": typeOf,
|
||||
@ -225,19 +264,26 @@ var genericMap = map[string]interface{}{
|
||||
"deepEqual": reflect.DeepEqual,
|
||||
|
||||
// OS:
|
||||
"env": func(s string) string { return os.Getenv(s) },
|
||||
"expandenv": func(s string) string { return os.ExpandEnv(s) },
|
||||
"env": os.Getenv,
|
||||
"expandenv": os.ExpandEnv,
|
||||
|
||||
// Network:
|
||||
"getHostByName": getHostByName,
|
||||
|
||||
// File Paths:
|
||||
// Paths:
|
||||
"base": path.Base,
|
||||
"dir": path.Dir,
|
||||
"clean": path.Clean,
|
||||
"ext": path.Ext,
|
||||
"isAbs": path.IsAbs,
|
||||
|
||||
// Filepaths:
|
||||
"osBase": filepath.Base,
|
||||
"osClean": filepath.Clean,
|
||||
"osDir": filepath.Dir,
|
||||
"osExt": filepath.Ext,
|
||||
"osIsAbs": filepath.IsAbs,
|
||||
|
||||
// Encoding:
|
||||
"b64enc": base64encode,
|
||||
"b64dec": base64decode,
|
||||
@ -245,42 +291,65 @@ var genericMap = map[string]interface{}{
|
||||
"b32dec": base32decode,
|
||||
|
||||
// Data Structures:
|
||||
"tuple": list, // FIXME: with the addition of append/prepend these are no longer immutable.
|
||||
"list": list,
|
||||
"dict": dict,
|
||||
"set": set,
|
||||
"unset": unset,
|
||||
"hasKey": hasKey,
|
||||
"pluck": pluck,
|
||||
"keys": keys,
|
||||
"pick": pick,
|
||||
"omit": omit,
|
||||
"merge": merge,
|
||||
"mergeOverwrite": mergeOverwrite,
|
||||
"values": values,
|
||||
"tuple": list, // FIXME: with the addition of append/prepend these are no longer immutable.
|
||||
"list": list,
|
||||
"dict": dict,
|
||||
"get": get,
|
||||
"set": set,
|
||||
"unset": unset,
|
||||
"hasKey": hasKey,
|
||||
"pluck": pluck,
|
||||
"keys": keys,
|
||||
"pick": pick,
|
||||
"omit": omit,
|
||||
"merge": merge,
|
||||
"mergeOverwrite": mergeOverwrite,
|
||||
"mustMerge": mustMerge,
|
||||
"mustMergeOverwrite": mustMergeOverwrite,
|
||||
"values": values,
|
||||
|
||||
"append": push, "push": push,
|
||||
"prepend": prepend,
|
||||
"first": first,
|
||||
"rest": rest,
|
||||
"last": last,
|
||||
"initial": initial,
|
||||
"reverse": reverse,
|
||||
"uniq": uniq,
|
||||
"without": without,
|
||||
"has": has,
|
||||
"slice": slice,
|
||||
"concat": concat,
|
||||
"mustAppend": mustPush, "mustPush": mustPush,
|
||||
"prepend": prepend,
|
||||
"mustPrepend": mustPrepend,
|
||||
"first": first,
|
||||
"mustFirst": mustFirst,
|
||||
"rest": rest,
|
||||
"mustRest": mustRest,
|
||||
"last": last,
|
||||
"mustLast": mustLast,
|
||||
"initial": initial,
|
||||
"mustInitial": mustInitial,
|
||||
"reverse": reverse,
|
||||
"mustReverse": mustReverse,
|
||||
"uniq": uniq,
|
||||
"mustUniq": mustUniq,
|
||||
"without": without,
|
||||
"mustWithout": mustWithout,
|
||||
"has": has,
|
||||
"mustHas": mustHas,
|
||||
"slice": slice,
|
||||
"mustSlice": mustSlice,
|
||||
"concat": concat,
|
||||
"dig": dig,
|
||||
"chunk": chunk,
|
||||
"mustChunk": mustChunk,
|
||||
|
||||
// Crypto:
|
||||
"bcrypt": bcrypt,
|
||||
"htpasswd": htpasswd,
|
||||
"genPrivateKey": generatePrivateKey,
|
||||
"derivePassword": derivePassword,
|
||||
"buildCustomCert": buildCustomCertificate,
|
||||
"genCA": generateCertificateAuthority,
|
||||
"genCAWithKey": generateCertificateAuthorityWithPEMKey,
|
||||
"genSelfSignedCert": generateSelfSignedCertificate,
|
||||
"genSelfSignedCertWithKey": generateSelfSignedCertificateWithPEMKey,
|
||||
"genSignedCert": generateSignedCertificate,
|
||||
"genSignedCertWithKey": generateSignedCertificateWithPEMKey,
|
||||
"encryptAES": encryptAES,
|
||||
"decryptAES": decryptAES,
|
||||
"randBytes": randBytes,
|
||||
|
||||
// UUIDs:
|
||||
"uuidv4": uuidv4,
|
||||
@ -293,12 +362,19 @@ var genericMap = map[string]interface{}{
|
||||
"fail": func(msg string) (string, error) { return "", errors.New(msg) },
|
||||
|
||||
// Regex
|
||||
"regexMatch": regexMatch,
|
||||
"regexFindAll": regexFindAll,
|
||||
"regexFind": regexFind,
|
||||
"regexReplaceAll": regexReplaceAll,
|
||||
"regexReplaceAllLiteral": regexReplaceAllLiteral,
|
||||
"regexSplit": regexSplit,
|
||||
"regexMatch": regexMatch,
|
||||
"mustRegexMatch": mustRegexMatch,
|
||||
"regexFindAll": regexFindAll,
|
||||
"mustRegexFindAll": mustRegexFindAll,
|
||||
"regexFind": regexFind,
|
||||
"mustRegexFind": mustRegexFind,
|
||||
"regexReplaceAll": regexReplaceAll,
|
||||
"mustRegexReplaceAll": mustRegexReplaceAll,
|
||||
"regexReplaceAllLiteral": regexReplaceAllLiteral,
|
||||
"mustRegexReplaceAllLiteral": mustRegexReplaceAllLiteral,
|
||||
"regexSplit": regexSplit,
|
||||
"mustRegexSplit": mustRegexSplit,
|
||||
"regexQuoteMeta": regexQuoteMeta,
|
||||
|
||||
// URLs:
|
||||
"urlParse": urlParse,
|
215
vendor/github.com/Masterminds/sprig/list.go → vendor/github.com/Masterminds/sprig/v3/list.go
generated
vendored
215
vendor/github.com/Masterminds/sprig/list.go → vendor/github.com/Masterminds/sprig/v3/list.go
generated
vendored
@ -2,6 +2,7 @@ package sprig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
@ -15,6 +16,15 @@ func list(v ...interface{}) []interface{} {
|
||||
}
|
||||
|
||||
func push(list interface{}, v interface{}) []interface{} {
|
||||
l, err := mustPush(list, v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func mustPush(list interface{}, v interface{}) ([]interface{}, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
@ -26,14 +36,23 @@ func push(list interface{}, v interface{}) []interface{} {
|
||||
nl[i] = l2.Index(i).Interface()
|
||||
}
|
||||
|
||||
return append(nl, v)
|
||||
return append(nl, v), nil
|
||||
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot push on type %s", tp))
|
||||
return nil, fmt.Errorf("Cannot push on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
func prepend(list interface{}, v interface{}) []interface{} {
|
||||
l, err := mustPrepend(list, v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func mustPrepend(list interface{}, v interface{}) ([]interface{}, error) {
|
||||
//return append([]interface{}{v}, list...)
|
||||
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
@ -47,14 +66,67 @@ func prepend(list interface{}, v interface{}) []interface{} {
|
||||
nl[i] = l2.Index(i).Interface()
|
||||
}
|
||||
|
||||
return append([]interface{}{v}, nl...)
|
||||
return append([]interface{}{v}, nl...), nil
|
||||
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot prepend on type %s", tp))
|
||||
return nil, fmt.Errorf("Cannot prepend on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
func chunk(size int, list interface{}) [][]interface{} {
|
||||
l, err := mustChunk(size, list)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func mustChunk(size int, list interface{}) ([][]interface{}, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
|
||||
cs := int(math.Floor(float64(l-1)/float64(size)) + 1)
|
||||
nl := make([][]interface{}, cs)
|
||||
|
||||
for i := 0; i < cs; i++ {
|
||||
clen := size
|
||||
if i == cs-1 {
|
||||
clen = int(math.Floor(math.Mod(float64(l), float64(size))))
|
||||
if clen == 0 {
|
||||
clen = size
|
||||
}
|
||||
}
|
||||
|
||||
nl[i] = make([]interface{}, clen)
|
||||
|
||||
for j := 0; j < clen; j++ {
|
||||
ix := i*size + j
|
||||
nl[i][j] = l2.Index(ix).Interface()
|
||||
}
|
||||
}
|
||||
|
||||
return nl, nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("Cannot chunk type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
func last(list interface{}) interface{} {
|
||||
l, err := mustLast(list)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func mustLast(list interface{}) (interface{}, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
@ -62,16 +134,25 @@ func last(list interface{}) interface{} {
|
||||
|
||||
l := l2.Len()
|
||||
if l == 0 {
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return l2.Index(l - 1).Interface()
|
||||
return l2.Index(l - 1).Interface(), nil
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find last on type %s", tp))
|
||||
return nil, fmt.Errorf("Cannot find last on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
func first(list interface{}) interface{} {
|
||||
l, err := mustFirst(list)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func mustFirst(list interface{}) (interface{}, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
@ -79,16 +160,25 @@ func first(list interface{}) interface{} {
|
||||
|
||||
l := l2.Len()
|
||||
if l == 0 {
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return l2.Index(0).Interface()
|
||||
return l2.Index(0).Interface(), nil
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find first on type %s", tp))
|
||||
return nil, fmt.Errorf("Cannot find first on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
func rest(list interface{}) []interface{} {
|
||||
l, err := mustRest(list)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func mustRest(list interface{}) ([]interface{}, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
@ -96,7 +186,7 @@ func rest(list interface{}) []interface{} {
|
||||
|
||||
l := l2.Len()
|
||||
if l == 0 {
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
nl := make([]interface{}, l-1)
|
||||
@ -104,13 +194,22 @@ func rest(list interface{}) []interface{} {
|
||||
nl[i-1] = l2.Index(i).Interface()
|
||||
}
|
||||
|
||||
return nl
|
||||
return nl, nil
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find rest on type %s", tp))
|
||||
return nil, fmt.Errorf("Cannot find rest on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
func initial(list interface{}) []interface{} {
|
||||
l, err := mustInitial(list)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func mustInitial(list interface{}) ([]interface{}, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
@ -118,7 +217,7 @@ func initial(list interface{}) []interface{} {
|
||||
|
||||
l := l2.Len()
|
||||
if l == 0 {
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
nl := make([]interface{}, l-1)
|
||||
@ -126,9 +225,9 @@ func initial(list interface{}) []interface{} {
|
||||
nl[i] = l2.Index(i).Interface()
|
||||
}
|
||||
|
||||
return nl
|
||||
return nl, nil
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find initial on type %s", tp))
|
||||
return nil, fmt.Errorf("Cannot find initial on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,6 +244,15 @@ func sortAlpha(list interface{}) []string {
|
||||
}
|
||||
|
||||
func reverse(v interface{}) []interface{} {
|
||||
l, err := mustReverse(v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func mustReverse(v interface{}) ([]interface{}, error) {
|
||||
tp := reflect.TypeOf(v).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
@ -157,13 +265,22 @@ func reverse(v interface{}) []interface{} {
|
||||
nl[l-i-1] = l2.Index(i).Interface()
|
||||
}
|
||||
|
||||
return nl
|
||||
return nl, nil
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find reverse on type %s", tp))
|
||||
return nil, fmt.Errorf("Cannot find reverse on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
func compact(list interface{}) []interface{} {
|
||||
l, err := mustCompact(list)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func mustCompact(list interface{}) ([]interface{}, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
@ -179,13 +296,22 @@ func compact(list interface{}) []interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
return nl
|
||||
return nl, nil
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot compact on type %s", tp))
|
||||
return nil, fmt.Errorf("Cannot compact on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
func uniq(list interface{}) []interface{} {
|
||||
l, err := mustUniq(list)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func mustUniq(list interface{}) ([]interface{}, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
@ -201,9 +327,9 @@ func uniq(list interface{}) []interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
return dest
|
||||
return dest, nil
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find uniq on type %s", tp))
|
||||
return nil, fmt.Errorf("Cannot find uniq on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,6 +343,15 @@ func inList(haystack []interface{}, needle interface{}) bool {
|
||||
}
|
||||
|
||||
func without(list interface{}, omit ...interface{}) []interface{} {
|
||||
l, err := mustWithout(list, omit...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func mustWithout(list interface{}, omit ...interface{}) ([]interface{}, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
@ -232,15 +367,24 @@ func without(list interface{}, omit ...interface{}) []interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
return res, nil
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find without on type %s", tp))
|
||||
return nil, fmt.Errorf("Cannot find without on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
func has(needle interface{}, haystack interface{}) bool {
|
||||
l, err := mustHas(needle, haystack)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func mustHas(needle interface{}, haystack interface{}) (bool, error) {
|
||||
if haystack == nil {
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
tp := reflect.TypeOf(haystack).Kind()
|
||||
switch tp {
|
||||
@ -251,13 +395,13 @@ func has(needle interface{}, haystack interface{}) bool {
|
||||
for i := 0; i < l; i++ {
|
||||
item = l2.Index(i).Interface()
|
||||
if reflect.DeepEqual(needle, item) {
|
||||
return true
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return false, nil
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find has on type %s", tp))
|
||||
return false, fmt.Errorf("Cannot find has on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,6 +411,15 @@ func has(needle interface{}, haystack interface{}) bool {
|
||||
// slice $list 3 5 -> list[3:5]
|
||||
// slice $list 3 -> list[3:5] = list[3:]
|
||||
func slice(list interface{}, indices ...interface{}) interface{} {
|
||||
l, err := mustSlice(list, indices...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func mustSlice(list interface{}, indices ...interface{}) (interface{}, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
@ -274,7 +427,7 @@ func slice(list interface{}, indices ...interface{}) interface{} {
|
||||
|
||||
l := l2.Len()
|
||||
if l == 0 {
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var start, end int
|
||||
@ -287,9 +440,9 @@ func slice(list interface{}, indices ...interface{}) interface{} {
|
||||
end = toInt(indices[1])
|
||||
}
|
||||
|
||||
return l2.Slice(start, end).Interface()
|
||||
return l2.Slice(start, end).Interface(), nil
|
||||
default:
|
||||
panic(fmt.Sprintf("list should be type of slice or array but %s", tp))
|
||||
return nil, fmt.Errorf("list should be type of slice or array but %s", tp)
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,6 @@ import (
|
||||
|
||||
func getHostByName(name string) string {
|
||||
addrs, _ := net.LookupHost(name)
|
||||
//TODO: add error handing when release v3 cames out
|
||||
//TODO: add error handing when release v3 comes out
|
||||
return addrs[rand.Intn(len(addrs))]
|
||||
}
|
186
vendor/github.com/Masterminds/sprig/v3/numeric.go
generated
vendored
Normal file
186
vendor/github.com/Masterminds/sprig/v3/numeric.go
generated
vendored
Normal file
@ -0,0 +1,186 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
// toFloat64 converts 64-bit floats
|
||||
func toFloat64(v interface{}) float64 {
|
||||
return cast.ToFloat64(v)
|
||||
}
|
||||
|
||||
func toInt(v interface{}) int {
|
||||
return cast.ToInt(v)
|
||||
}
|
||||
|
||||
// toInt64 converts integer types to 64-bit integers
|
||||
func toInt64(v interface{}) int64 {
|
||||
return cast.ToInt64(v)
|
||||
}
|
||||
|
||||
func max(a interface{}, i ...interface{}) int64 {
|
||||
aa := toInt64(a)
|
||||
for _, b := range i {
|
||||
bb := toInt64(b)
|
||||
if bb > aa {
|
||||
aa = bb
|
||||
}
|
||||
}
|
||||
return aa
|
||||
}
|
||||
|
||||
func maxf(a interface{}, i ...interface{}) float64 {
|
||||
aa := toFloat64(a)
|
||||
for _, b := range i {
|
||||
bb := toFloat64(b)
|
||||
aa = math.Max(aa, bb)
|
||||
}
|
||||
return aa
|
||||
}
|
||||
|
||||
func min(a interface{}, i ...interface{}) int64 {
|
||||
aa := toInt64(a)
|
||||
for _, b := range i {
|
||||
bb := toInt64(b)
|
||||
if bb < aa {
|
||||
aa = bb
|
||||
}
|
||||
}
|
||||
return aa
|
||||
}
|
||||
|
||||
func minf(a interface{}, i ...interface{}) float64 {
|
||||
aa := toFloat64(a)
|
||||
for _, b := range i {
|
||||
bb := toFloat64(b)
|
||||
aa = math.Min(aa, bb)
|
||||
}
|
||||
return aa
|
||||
}
|
||||
|
||||
func until(count int) []int {
|
||||
step := 1
|
||||
if count < 0 {
|
||||
step = -1
|
||||
}
|
||||
return untilStep(0, count, step)
|
||||
}
|
||||
|
||||
func untilStep(start, stop, step int) []int {
|
||||
v := []int{}
|
||||
|
||||
if stop < start {
|
||||
if step >= 0 {
|
||||
return v
|
||||
}
|
||||
for i := start; i > stop; i += step {
|
||||
v = append(v, i)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
if step <= 0 {
|
||||
return v
|
||||
}
|
||||
for i := start; i < stop; i += step {
|
||||
v = append(v, i)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func floor(a interface{}) float64 {
|
||||
aa := toFloat64(a)
|
||||
return math.Floor(aa)
|
||||
}
|
||||
|
||||
func ceil(a interface{}) float64 {
|
||||
aa := toFloat64(a)
|
||||
return math.Ceil(aa)
|
||||
}
|
||||
|
||||
func round(a interface{}, p int, rOpt ...float64) float64 {
|
||||
roundOn := .5
|
||||
if len(rOpt) > 0 {
|
||||
roundOn = rOpt[0]
|
||||
}
|
||||
val := toFloat64(a)
|
||||
places := toFloat64(p)
|
||||
|
||||
var round float64
|
||||
pow := math.Pow(10, places)
|
||||
digit := pow * val
|
||||
_, div := math.Modf(digit)
|
||||
if div >= roundOn {
|
||||
round = math.Ceil(digit)
|
||||
} else {
|
||||
round = math.Floor(digit)
|
||||
}
|
||||
return round / pow
|
||||
}
|
||||
|
||||
// converts unix octal to decimal
|
||||
func toDecimal(v interface{}) int64 {
|
||||
result, err := strconv.ParseInt(fmt.Sprint(v), 8, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func seq(params ...int) string {
|
||||
increment := 1
|
||||
switch len(params) {
|
||||
case 0:
|
||||
return ""
|
||||
case 1:
|
||||
start := 1
|
||||
end := params[0]
|
||||
if end < start {
|
||||
increment = -1
|
||||
}
|
||||
return intArrayToString(untilStep(start, end+increment, increment), " ")
|
||||
case 3:
|
||||
start := params[0]
|
||||
end := params[2]
|
||||
step := params[1]
|
||||
if end < start {
|
||||
increment = -1
|
||||
if step > 0 {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
return intArrayToString(untilStep(start, end+increment, step), " ")
|
||||
case 2:
|
||||
start := params[0]
|
||||
end := params[1]
|
||||
step := 1
|
||||
if end < start {
|
||||
step = -1
|
||||
}
|
||||
return intArrayToString(untilStep(start, end+step, step), " ")
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func intArrayToString(slice []int, delimeter string) string {
|
||||
return strings.Trim(strings.Join(strings.Fields(fmt.Sprint(slice)), delimeter), "[]")
|
||||
}
|
||||
|
||||
// performs a float and subsequent decimal.Decimal conversion on inputs,
|
||||
// and iterates through a and b executing the mathmetical operation f
|
||||
func execDecimalOp(a interface{}, b []interface{}, f func(d1, d2 decimal.Decimal) decimal.Decimal) float64 {
|
||||
prt := decimal.NewFromFloat(toFloat64(a))
|
||||
for _, x := range b {
|
||||
dx := decimal.NewFromFloat(toFloat64(x))
|
||||
prt = f(prt, dx)
|
||||
}
|
||||
rslt, _ := prt.Float64()
|
||||
return rslt
|
||||
}
|
83
vendor/github.com/Masterminds/sprig/v3/regex.go
generated
vendored
Normal file
83
vendor/github.com/Masterminds/sprig/v3/regex.go
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func regexMatch(regex string, s string) bool {
|
||||
match, _ := regexp.MatchString(regex, s)
|
||||
return match
|
||||
}
|
||||
|
||||
func mustRegexMatch(regex string, s string) (bool, error) {
|
||||
return regexp.MatchString(regex, s)
|
||||
}
|
||||
|
||||
func regexFindAll(regex string, s string, n int) []string {
|
||||
r := regexp.MustCompile(regex)
|
||||
return r.FindAllString(s, n)
|
||||
}
|
||||
|
||||
func mustRegexFindAll(regex string, s string, n int) ([]string, error) {
|
||||
r, err := regexp.Compile(regex)
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
return r.FindAllString(s, n), nil
|
||||
}
|
||||
|
||||
func regexFind(regex string, s string) string {
|
||||
r := regexp.MustCompile(regex)
|
||||
return r.FindString(s)
|
||||
}
|
||||
|
||||
func mustRegexFind(regex string, s string) (string, error) {
|
||||
r, err := regexp.Compile(regex)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return r.FindString(s), nil
|
||||
}
|
||||
|
||||
func regexReplaceAll(regex string, s string, repl string) string {
|
||||
r := regexp.MustCompile(regex)
|
||||
return r.ReplaceAllString(s, repl)
|
||||
}
|
||||
|
||||
func mustRegexReplaceAll(regex string, s string, repl string) (string, error) {
|
||||
r, err := regexp.Compile(regex)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return r.ReplaceAllString(s, repl), nil
|
||||
}
|
||||
|
||||
func regexReplaceAllLiteral(regex string, s string, repl string) string {
|
||||
r := regexp.MustCompile(regex)
|
||||
return r.ReplaceAllLiteralString(s, repl)
|
||||
}
|
||||
|
||||
func mustRegexReplaceAllLiteral(regex string, s string, repl string) (string, error) {
|
||||
r, err := regexp.Compile(regex)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return r.ReplaceAllLiteralString(s, repl), nil
|
||||
}
|
||||
|
||||
func regexSplit(regex string, s string, n int) []string {
|
||||
r := regexp.MustCompile(regex)
|
||||
return r.Split(s, n)
|
||||
}
|
||||
|
||||
func mustRegexSplit(regex string, s string, n int) ([]string, error) {
|
||||
r, err := regexp.Compile(regex)
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
return r.Split(s, n), nil
|
||||
}
|
||||
|
||||
func regexQuoteMeta(s string) string {
|
||||
return regexp.QuoteMeta(s)
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
sv2 "github.com/Masterminds/semver"
|
||||
sv2 "github.com/Masterminds/semver/v3"
|
||||
)
|
||||
|
||||
func semverCompare(constraint, version string) (bool, error) {
|
@ -154,9 +154,9 @@ func strslice(v interface{}) []string {
|
||||
default:
|
||||
if v == nil {
|
||||
return []string{}
|
||||
} else {
|
||||
return []string{strval(v)}
|
||||
}
|
||||
|
||||
return []string{strval(v)}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -187,10 +187,13 @@ func strval(v interface{}) string {
|
||||
}
|
||||
|
||||
func trunc(c int, s string) string {
|
||||
if len(s) <= c {
|
||||
return s
|
||||
if c < 0 && len(s)+c > 0 {
|
||||
return s[len(s)+c:]
|
||||
}
|
||||
return s[0:c]
|
||||
if c >= 0 && len(s) > c {
|
||||
return s[:c]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func join(sep string, v interface{}) string {
|
@ -7,7 +7,8 @@ import (
|
||||
)
|
||||
|
||||
func dictGetOrEmpty(dict map[string]interface{}, key string) string {
|
||||
value, ok := dict[key]; if !ok {
|
||||
value, ok := dict[key]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
tp := reflect.TypeOf(value).Kind()
|
||||
@ -20,19 +21,19 @@ func dictGetOrEmpty(dict map[string]interface{}, key string) string {
|
||||
// parses given URL to return dict object
|
||||
func urlParse(v string) map[string]interface{} {
|
||||
dict := map[string]interface{}{}
|
||||
parsedUrl, err := url.Parse(v)
|
||||
parsedURL, err := url.Parse(v)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("unable to parse url: %s", err))
|
||||
}
|
||||
dict["scheme"] = parsedUrl.Scheme
|
||||
dict["host"] = parsedUrl.Host
|
||||
dict["hostname"] = parsedUrl.Hostname()
|
||||
dict["path"] = parsedUrl.Path
|
||||
dict["query"] = parsedUrl.RawQuery
|
||||
dict["opaque"] = parsedUrl.Opaque
|
||||
dict["fragment"] = parsedUrl.Fragment
|
||||
if parsedUrl.User != nil {
|
||||
dict["userinfo"] = parsedUrl.User.String()
|
||||
dict["scheme"] = parsedURL.Scheme
|
||||
dict["host"] = parsedURL.Host
|
||||
dict["hostname"] = parsedURL.Hostname()
|
||||
dict["path"] = parsedURL.Path
|
||||
dict["query"] = parsedURL.RawQuery
|
||||
dict["opaque"] = parsedURL.Opaque
|
||||
dict["fragment"] = parsedURL.Fragment
|
||||
if parsedURL.User != nil {
|
||||
dict["userinfo"] = parsedURL.User.String()
|
||||
} else {
|
||||
dict["userinfo"] = ""
|
||||
}
|
||||
@ -42,25 +43,24 @@ func urlParse(v string) map[string]interface{} {
|
||||
|
||||
// join given dict to URL string
|
||||
func urlJoin(d map[string]interface{}) string {
|
||||
resUrl := url.URL{
|
||||
resURL := url.URL{
|
||||
Scheme: dictGetOrEmpty(d, "scheme"),
|
||||
Host: dictGetOrEmpty(d, "host"),
|
||||
Path: dictGetOrEmpty(d, "path"),
|
||||
RawQuery: dictGetOrEmpty(d, "query"),
|
||||
Opaque: dictGetOrEmpty(d, "opaque"),
|
||||
Fragment: dictGetOrEmpty(d, "fragment"),
|
||||
|
||||
}
|
||||
userinfo := dictGetOrEmpty(d, "userinfo")
|
||||
var user *url.Userinfo = nil
|
||||
var user *url.Userinfo
|
||||
if userinfo != "" {
|
||||
tempUrl, err := url.Parse(fmt.Sprintf("proto://%s@host", userinfo))
|
||||
tempURL, err := url.Parse(fmt.Sprintf("proto://%s@host", userinfo))
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("unable to parse userinfo in dict: %s", err))
|
||||
}
|
||||
user = tempUrl.User
|
||||
user = tempURL.User
|
||||
}
|
||||
|
||||
resUrl.User = user
|
||||
return resUrl.String()
|
||||
resURL.User = user
|
||||
return resURL.String()
|
||||
}
|
0
vendor/golang.org/x/crypto/AUTHORS → vendor/github.com/ProtonMail/go-crypto/AUTHORS
generated
vendored
0
vendor/golang.org/x/crypto/AUTHORS → vendor/github.com/ProtonMail/go-crypto/AUTHORS
generated
vendored
27
vendor/github.com/ProtonMail/go-crypto/LICENSE
generated
vendored
Normal file
27
vendor/github.com/ProtonMail/go-crypto/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
22
vendor/github.com/ProtonMail/go-crypto/PATENTS
generated
vendored
Normal file
22
vendor/github.com/ProtonMail/go-crypto/PATENTS
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
Additional IP Rights Grant (Patents)
|
||||
|
||||
"This implementation" means the copyrightable works distributed by
|
||||
Google as part of the Go project.
|
||||
|
||||
Google 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,
|
||||
transfer and otherwise run, modify and propagate the contents of this
|
||||
implementation of Go, where such license applies only to those patent
|
||||
claims, both currently owned or controlled by Google and acquired in
|
||||
the future, licensable by Google that are necessarily infringed by this
|
||||
implementation of Go. This grant does not include claims that would be
|
||||
infringed only as a consequence of further modification of this
|
||||
implementation. If you or your agent or exclusive licensee institute or
|
||||
order or agree to the institution of patent litigation against any
|
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that this implementation of Go or any code incorporated within this
|
||||
implementation of Go constitutes direct or contributory patent
|
||||
infringement, or inducement of patent infringement, then any patent
|
||||
rights granted to you under this License for this implementation of Go
|
||||
shall terminate as of the date such litigation is filed.
|
381
vendor/github.com/ProtonMail/go-crypto/bitcurves/bitcurve.go
generated
vendored
Normal file
381
vendor/github.com/ProtonMail/go-crypto/bitcurves/bitcurve.go
generated
vendored
Normal file
@ -0,0 +1,381 @@
|
||||
package bitcurves
|
||||
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Copyright 2011 ThePiachu. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package bitelliptic implements several Koblitz elliptic curves over prime
|
||||
// fields.
|
||||
|
||||
// This package operates, internally, on Jacobian coordinates. For a given
|
||||
// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1)
|
||||
// where x = x1/z1² and y = y1/z1³. The greatest speedups come when the whole
|
||||
// calculation can be performed within the transform (as in ScalarMult and
|
||||
// ScalarBaseMult). But even for Add and Double, it's faster to apply and
|
||||
// reverse the transform than to operate in affine coordinates.
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"io"
|
||||
"math/big"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// A BitCurve represents a Koblitz Curve with a=0.
|
||||
// See http://www.hyperelliptic.org/EFD/g1p/auto-shortw.html
|
||||
type BitCurve struct {
|
||||
Name string
|
||||
P *big.Int // the order of the underlying field
|
||||
N *big.Int // the order of the base point
|
||||
B *big.Int // the constant of the BitCurve equation
|
||||
Gx, Gy *big.Int // (x,y) of the base point
|
||||
BitSize int // the size of the underlying field
|
||||
}
|
||||
|
||||
// Params returns the parameters of the given BitCurve (see BitCurve struct)
|
||||
func (bitCurve *BitCurve) Params() (cp *elliptic.CurveParams) {
|
||||
cp = new(elliptic.CurveParams)
|
||||
cp.Name = bitCurve.Name
|
||||
cp.P = bitCurve.P
|
||||
cp.N = bitCurve.N
|
||||
cp.Gx = bitCurve.Gx
|
||||
cp.Gy = bitCurve.Gy
|
||||
cp.BitSize = bitCurve.BitSize
|
||||
return cp
|
||||
}
|
||||
|
||||
// IsOnCurve returns true if the given (x,y) lies on the BitCurve.
|
||||
func (bitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool {
|
||||
// y² = x³ + b
|
||||
y2 := new(big.Int).Mul(y, y) //y²
|
||||
y2.Mod(y2, bitCurve.P) //y²%P
|
||||
|
||||
x3 := new(big.Int).Mul(x, x) //x²
|
||||
x3.Mul(x3, x) //x³
|
||||
|
||||
x3.Add(x3, bitCurve.B) //x³+B
|
||||
x3.Mod(x3, bitCurve.P) //(x³+B)%P
|
||||
|
||||
return x3.Cmp(y2) == 0
|
||||
}
|
||||
|
||||
// affineFromJacobian reverses the Jacobian transform. See the comment at the
|
||||
// top of the file.
|
||||
func (bitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
|
||||
if z.Cmp(big.NewInt(0)) == 0 {
|
||||
panic("bitcurve: Can't convert to affine with Jacobian Z = 0")
|
||||
}
|
||||
// x = YZ^2 mod P
|
||||
zinv := new(big.Int).ModInverse(z, bitCurve.P)
|
||||
zinvsq := new(big.Int).Mul(zinv, zinv)
|
||||
|
||||
xOut = new(big.Int).Mul(x, zinvsq)
|
||||
xOut.Mod(xOut, bitCurve.P)
|
||||
// y = YZ^3 mod P
|
||||
zinvsq.Mul(zinvsq, zinv)
|
||||
yOut = new(big.Int).Mul(y, zinvsq)
|
||||
yOut.Mod(yOut, bitCurve.P)
|
||||
return xOut, yOut
|
||||
}
|
||||
|
||||
// Add returns the sum of (x1,y1) and (x2,y2)
|
||||
func (bitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
|
||||
z := new(big.Int).SetInt64(1)
|
||||
x, y, z := bitCurve.addJacobian(x1, y1, z, x2, y2, z)
|
||||
return bitCurve.affineFromJacobian(x, y, z)
|
||||
}
|
||||
|
||||
// addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and
|
||||
// (x2, y2, z2) and returns their sum, also in Jacobian form.
|
||||
func (bitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) {
|
||||
// See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
|
||||
z1z1 := new(big.Int).Mul(z1, z1)
|
||||
z1z1.Mod(z1z1, bitCurve.P)
|
||||
z2z2 := new(big.Int).Mul(z2, z2)
|
||||
z2z2.Mod(z2z2, bitCurve.P)
|
||||
|
||||
u1 := new(big.Int).Mul(x1, z2z2)
|
||||
u1.Mod(u1, bitCurve.P)
|
||||
u2 := new(big.Int).Mul(x2, z1z1)
|
||||
u2.Mod(u2, bitCurve.P)
|
||||
h := new(big.Int).Sub(u2, u1)
|
||||
if h.Sign() == -1 {
|
||||
h.Add(h, bitCurve.P)
|
||||
}
|
||||
i := new(big.Int).Lsh(h, 1)
|
||||
i.Mul(i, i)
|
||||
j := new(big.Int).Mul(h, i)
|
||||
|
||||
s1 := new(big.Int).Mul(y1, z2)
|
||||
s1.Mul(s1, z2z2)
|
||||
s1.Mod(s1, bitCurve.P)
|
||||
s2 := new(big.Int).Mul(y2, z1)
|
||||
s2.Mul(s2, z1z1)
|
||||
s2.Mod(s2, bitCurve.P)
|
||||
r := new(big.Int).Sub(s2, s1)
|
||||
if r.Sign() == -1 {
|
||||
r.Add(r, bitCurve.P)
|
||||
}
|
||||
r.Lsh(r, 1)
|
||||
v := new(big.Int).Mul(u1, i)
|
||||
|
||||
x3 := new(big.Int).Set(r)
|
||||
x3.Mul(x3, x3)
|
||||
x3.Sub(x3, j)
|
||||
x3.Sub(x3, v)
|
||||
x3.Sub(x3, v)
|
||||
x3.Mod(x3, bitCurve.P)
|
||||
|
||||
y3 := new(big.Int).Set(r)
|
||||
v.Sub(v, x3)
|
||||
y3.Mul(y3, v)
|
||||
s1.Mul(s1, j)
|
||||
s1.Lsh(s1, 1)
|
||||
y3.Sub(y3, s1)
|
||||
y3.Mod(y3, bitCurve.P)
|
||||
|
||||
z3 := new(big.Int).Add(z1, z2)
|
||||
z3.Mul(z3, z3)
|
||||
z3.Sub(z3, z1z1)
|
||||
if z3.Sign() == -1 {
|
||||
z3.Add(z3, bitCurve.P)
|
||||
}
|
||||
z3.Sub(z3, z2z2)
|
||||
if z3.Sign() == -1 {
|
||||
z3.Add(z3, bitCurve.P)
|
||||
}
|
||||
z3.Mul(z3, h)
|
||||
z3.Mod(z3, bitCurve.P)
|
||||
|
||||
return x3, y3, z3
|
||||
}
|
||||
|
||||
// Double returns 2*(x,y)
|
||||
func (bitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
|
||||
z1 := new(big.Int).SetInt64(1)
|
||||
return bitCurve.affineFromJacobian(bitCurve.doubleJacobian(x1, y1, z1))
|
||||
}
|
||||
|
||||
// doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and
|
||||
// returns its double, also in Jacobian form.
|
||||
func (bitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) {
|
||||
// See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
|
||||
|
||||
a := new(big.Int).Mul(x, x) //X1²
|
||||
b := new(big.Int).Mul(y, y) //Y1²
|
||||
c := new(big.Int).Mul(b, b) //B²
|
||||
|
||||
d := new(big.Int).Add(x, b) //X1+B
|
||||
d.Mul(d, d) //(X1+B)²
|
||||
d.Sub(d, a) //(X1+B)²-A
|
||||
d.Sub(d, c) //(X1+B)²-A-C
|
||||
d.Mul(d, big.NewInt(2)) //2*((X1+B)²-A-C)
|
||||
|
||||
e := new(big.Int).Mul(big.NewInt(3), a) //3*A
|
||||
f := new(big.Int).Mul(e, e) //E²
|
||||
|
||||
x3 := new(big.Int).Mul(big.NewInt(2), d) //2*D
|
||||
x3.Sub(f, x3) //F-2*D
|
||||
x3.Mod(x3, bitCurve.P)
|
||||
|
||||
y3 := new(big.Int).Sub(d, x3) //D-X3
|
||||
y3.Mul(e, y3) //E*(D-X3)
|
||||
y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) //E*(D-X3)-8*C
|
||||
y3.Mod(y3, bitCurve.P)
|
||||
|
||||
z3 := new(big.Int).Mul(y, z) //Y1*Z1
|
||||
z3.Mul(big.NewInt(2), z3) //3*Y1*Z1
|
||||
z3.Mod(z3, bitCurve.P)
|
||||
|
||||
return x3, y3, z3
|
||||
}
|
||||
|
||||
//TODO: double check if it is okay
|
||||
// ScalarMult returns k*(Bx,By) where k is a number in big-endian form.
|
||||
func (bitCurve *BitCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
|
||||
// We have a slight problem in that the identity of the group (the
|
||||
// point at infinity) cannot be represented in (x, y) form on a finite
|
||||
// machine. Thus the standard add/double algorithm has to be tweaked
|
||||
// slightly: our initial state is not the identity, but x, and we
|
||||
// ignore the first true bit in |k|. If we don't find any true bits in
|
||||
// |k|, then we return nil, nil, because we cannot return the identity
|
||||
// element.
|
||||
|
||||
Bz := new(big.Int).SetInt64(1)
|
||||
x := Bx
|
||||
y := By
|
||||
z := Bz
|
||||
|
||||
seenFirstTrue := false
|
||||
for _, byte := range k {
|
||||
for bitNum := 0; bitNum < 8; bitNum++ {
|
||||
if seenFirstTrue {
|
||||
x, y, z = bitCurve.doubleJacobian(x, y, z)
|
||||
}
|
||||
if byte&0x80 == 0x80 {
|
||||
if !seenFirstTrue {
|
||||
seenFirstTrue = true
|
||||
} else {
|
||||
x, y, z = bitCurve.addJacobian(Bx, By, Bz, x, y, z)
|
||||
}
|
||||
}
|
||||
byte <<= 1
|
||||
}
|
||||
}
|
||||
|
||||
if !seenFirstTrue {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return bitCurve.affineFromJacobian(x, y, z)
|
||||
}
|
||||
|
||||
// ScalarBaseMult returns k*G, where G is the base point of the group and k is
|
||||
// an integer in big-endian form.
|
||||
func (bitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
|
||||
return bitCurve.ScalarMult(bitCurve.Gx, bitCurve.Gy, k)
|
||||
}
|
||||
|
||||
var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f}
|
||||
|
||||
//TODO: double check if it is okay
|
||||
// GenerateKey returns a public/private key pair. The private key is generated
|
||||
// using the given reader, which must return random data.
|
||||
func (bitCurve *BitCurve) GenerateKey(rand io.Reader) (priv []byte, x, y *big.Int, err error) {
|
||||
byteLen := (bitCurve.BitSize + 7) >> 3
|
||||
priv = make([]byte, byteLen)
|
||||
|
||||
for x == nil {
|
||||
_, err = io.ReadFull(rand, priv)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// We have to mask off any excess bits in the case that the size of the
|
||||
// underlying field is not a whole number of bytes.
|
||||
priv[0] &= mask[bitCurve.BitSize%8]
|
||||
// This is because, in tests, rand will return all zeros and we don't
|
||||
// want to get the point at infinity and loop forever.
|
||||
priv[1] ^= 0x42
|
||||
x, y = bitCurve.ScalarBaseMult(priv)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Marshal converts a point into the form specified in section 4.3.6 of ANSI
|
||||
// X9.62.
|
||||
func (bitCurve *BitCurve) Marshal(x, y *big.Int) []byte {
|
||||
byteLen := (bitCurve.BitSize + 7) >> 3
|
||||
|
||||
ret := make([]byte, 1+2*byteLen)
|
||||
ret[0] = 4 // uncompressed point
|
||||
|
||||
xBytes := x.Bytes()
|
||||
copy(ret[1+byteLen-len(xBytes):], xBytes)
|
||||
yBytes := y.Bytes()
|
||||
copy(ret[1+2*byteLen-len(yBytes):], yBytes)
|
||||
return ret
|
||||
}
|
||||
|
||||
// Unmarshal converts a point, serialised by Marshal, into an x, y pair. On
|
||||
// error, x = nil.
|
||||
func (bitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) {
|
||||
byteLen := (bitCurve.BitSize + 7) >> 3
|
||||
if len(data) != 1+2*byteLen {
|
||||
return
|
||||
}
|
||||
if data[0] != 4 { // uncompressed form
|
||||
return
|
||||
}
|
||||
x = new(big.Int).SetBytes(data[1 : 1+byteLen])
|
||||
y = new(big.Int).SetBytes(data[1+byteLen:])
|
||||
return
|
||||
}
|
||||
|
||||
//curve parameters taken from:
|
||||
//http://www.secg.org/collateral/sec2_final.pdf
|
||||
|
||||
var initonce sync.Once
|
||||
var secp160k1 *BitCurve
|
||||
var secp192k1 *BitCurve
|
||||
var secp224k1 *BitCurve
|
||||
var secp256k1 *BitCurve
|
||||
|
||||
func initAll() {
|
||||
initS160()
|
||||
initS192()
|
||||
initS224()
|
||||
initS256()
|
||||
}
|
||||
|
||||
func initS160() {
|
||||
// See SEC 2 section 2.4.1
|
||||
secp160k1 = new(BitCurve)
|
||||
secp160k1.Name = "secp160k1"
|
||||
secp160k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", 16)
|
||||
secp160k1.N, _ = new(big.Int).SetString("0100000000000000000001B8FA16DFAB9ACA16B6B3", 16)
|
||||
secp160k1.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000007", 16)
|
||||
secp160k1.Gx, _ = new(big.Int).SetString("3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", 16)
|
||||
secp160k1.Gy, _ = new(big.Int).SetString("938CF935318FDCED6BC28286531733C3F03C4FEE", 16)
|
||||
secp160k1.BitSize = 160
|
||||
}
|
||||
|
||||
func initS192() {
|
||||
// See SEC 2 section 2.5.1
|
||||
secp192k1 = new(BitCurve)
|
||||
secp192k1.Name = "secp192k1"
|
||||
secp192k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", 16)
|
||||
secp192k1.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", 16)
|
||||
secp192k1.B, _ = new(big.Int).SetString("000000000000000000000000000000000000000000000003", 16)
|
||||
secp192k1.Gx, _ = new(big.Int).SetString("DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", 16)
|
||||
secp192k1.Gy, _ = new(big.Int).SetString("9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", 16)
|
||||
secp192k1.BitSize = 192
|
||||
}
|
||||
|
||||
func initS224() {
|
||||
// See SEC 2 section 2.6.1
|
||||
secp224k1 = new(BitCurve)
|
||||
secp224k1.Name = "secp224k1"
|
||||
secp224k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", 16)
|
||||
secp224k1.N, _ = new(big.Int).SetString("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", 16)
|
||||
secp224k1.B, _ = new(big.Int).SetString("00000000000000000000000000000000000000000000000000000005", 16)
|
||||
secp224k1.Gx, _ = new(big.Int).SetString("A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", 16)
|
||||
secp224k1.Gy, _ = new(big.Int).SetString("7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", 16)
|
||||
secp224k1.BitSize = 224
|
||||
}
|
||||
|
||||
func initS256() {
|
||||
// See SEC 2 section 2.7.1
|
||||
secp256k1 = new(BitCurve)
|
||||
secp256k1.Name = "secp256k1"
|
||||
secp256k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16)
|
||||
secp256k1.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16)
|
||||
secp256k1.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000000000000000000000000000007", 16)
|
||||
secp256k1.Gx, _ = new(big.Int).SetString("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16)
|
||||
secp256k1.Gy, _ = new(big.Int).SetString("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16)
|
||||
secp256k1.BitSize = 256
|
||||
}
|
||||
|
||||
// S160 returns a BitCurve which implements secp160k1 (see SEC 2 section 2.4.1)
|
||||
func S160() *BitCurve {
|
||||
initonce.Do(initAll)
|
||||
return secp160k1
|
||||
}
|
||||
|
||||
// S192 returns a BitCurve which implements secp192k1 (see SEC 2 section 2.5.1)
|
||||
func S192() *BitCurve {
|
||||
initonce.Do(initAll)
|
||||
return secp192k1
|
||||
}
|
||||
|
||||
// S224 returns a BitCurve which implements secp224k1 (see SEC 2 section 2.6.1)
|
||||
func S224() *BitCurve {
|
||||
initonce.Do(initAll)
|
||||
return secp224k1
|
||||
}
|
||||
|
||||
// S256 returns a BitCurve which implements bitcurves (see SEC 2 section 2.7.1)
|
||||
func S256() *BitCurve {
|
||||
initonce.Do(initAll)
|
||||
return secp256k1
|
||||
}
|
134
vendor/github.com/ProtonMail/go-crypto/brainpool/brainpool.go
generated
vendored
Normal file
134
vendor/github.com/ProtonMail/go-crypto/brainpool/brainpool.go
generated
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
// Package brainpool implements Brainpool elliptic curves.
|
||||
// Implementation of rcurves is from github.com/ebfe/brainpool
|
||||
// Note that these curves are implemented with naive, non-constant time operations
|
||||
// and are likely not suitable for environments where timing attacks are a concern.
|
||||
package brainpool
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"math/big"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
once sync.Once
|
||||
p256t1, p384t1, p512t1 *elliptic.CurveParams
|
||||
p256r1, p384r1, p512r1 *rcurve
|
||||
)
|
||||
|
||||
func initAll() {
|
||||
initP256t1()
|
||||
initP384t1()
|
||||
initP512t1()
|
||||
initP256r1()
|
||||
initP384r1()
|
||||
initP512r1()
|
||||
}
|
||||
|
||||
func initP256t1() {
|
||||
p256t1 = &elliptic.CurveParams{Name: "brainpoolP256t1"}
|
||||
p256t1.P, _ = new(big.Int).SetString("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", 16)
|
||||
p256t1.N, _ = new(big.Int).SetString("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16)
|
||||
p256t1.B, _ = new(big.Int).SetString("662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04", 16)
|
||||
p256t1.Gx, _ = new(big.Int).SetString("A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F4", 16)
|
||||
p256t1.Gy, _ = new(big.Int).SetString("2D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE", 16)
|
||||
p256t1.BitSize = 256
|
||||
}
|
||||
|
||||
func initP256r1() {
|
||||
twisted := p256t1
|
||||
params := &elliptic.CurveParams{
|
||||
Name: "brainpoolP256r1",
|
||||
P: twisted.P,
|
||||
N: twisted.N,
|
||||
BitSize: twisted.BitSize,
|
||||
}
|
||||
params.Gx, _ = new(big.Int).SetString("8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", 16)
|
||||
params.Gy, _ = new(big.Int).SetString("547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", 16)
|
||||
z, _ := new(big.Int).SetString("3E2D4BD9597B58639AE7AA669CAB9837CF5CF20A2C852D10F655668DFC150EF0", 16)
|
||||
p256r1 = newrcurve(twisted, params, z)
|
||||
}
|
||||
|
||||
func initP384t1() {
|
||||
p384t1 = &elliptic.CurveParams{Name: "brainpoolP384t1"}
|
||||
p384t1.P, _ = new(big.Int).SetString("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", 16)
|
||||
p384t1.N, _ = new(big.Int).SetString("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16)
|
||||
p384t1.B, _ = new(big.Int).SetString("7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE", 16)
|
||||
p384t1.Gx, _ = new(big.Int).SetString("18DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC", 16)
|
||||
p384t1.Gy, _ = new(big.Int).SetString("25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928", 16)
|
||||
p384t1.BitSize = 384
|
||||
}
|
||||
|
||||
func initP384r1() {
|
||||
twisted := p384t1
|
||||
params := &elliptic.CurveParams{
|
||||
Name: "brainpoolP384r1",
|
||||
P: twisted.P,
|
||||
N: twisted.N,
|
||||
BitSize: twisted.BitSize,
|
||||
}
|
||||
params.Gx, _ = new(big.Int).SetString("1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", 16)
|
||||
params.Gy, _ = new(big.Int).SetString("8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", 16)
|
||||
z, _ := new(big.Int).SetString("41DFE8DD399331F7166A66076734A89CD0D2BCDB7D068E44E1F378F41ECBAE97D2D63DBC87BCCDDCCC5DA39E8589291C", 16)
|
||||
p384r1 = newrcurve(twisted, params, z)
|
||||
}
|
||||
|
||||
func initP512t1() {
|
||||
p512t1 = &elliptic.CurveParams{Name: "brainpoolP512t1"}
|
||||
p512t1.P, _ = new(big.Int).SetString("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", 16)
|
||||
p512t1.N, _ = new(big.Int).SetString("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16)
|
||||
p512t1.B, _ = new(big.Int).SetString("7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E", 16)
|
||||
p512t1.Gx, _ = new(big.Int).SetString("640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA", 16)
|
||||
p512t1.Gy, _ = new(big.Int).SetString("5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332", 16)
|
||||
p512t1.BitSize = 512
|
||||
}
|
||||
|
||||
func initP512r1() {
|
||||
twisted := p512t1
|
||||
params := &elliptic.CurveParams{
|
||||
Name: "brainpoolP512r1",
|
||||
P: twisted.P,
|
||||
N: twisted.N,
|
||||
BitSize: twisted.BitSize,
|
||||
}
|
||||
params.Gx, _ = new(big.Int).SetString("81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", 16)
|
||||
params.Gy, _ = new(big.Int).SetString("7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", 16)
|
||||
z, _ := new(big.Int).SetString("12EE58E6764838B69782136F0F2D3BA06E27695716054092E60A80BEDB212B64E585D90BCE13761F85C3F1D2A64E3BE8FEA2220F01EBA5EEB0F35DBD29D922AB", 16)
|
||||
p512r1 = newrcurve(twisted, params, z)
|
||||
}
|
||||
|
||||
// P256t1 returns a Curve which implements Brainpool P256t1 (see RFC 5639, section 3.4)
|
||||
func P256t1() elliptic.Curve {
|
||||
once.Do(initAll)
|
||||
return p256t1
|
||||
}
|
||||
|
||||
// P256r1 returns a Curve which implements Brainpool P256r1 (see RFC 5639, section 3.4)
|
||||
func P256r1() elliptic.Curve {
|
||||
once.Do(initAll)
|
||||
return p256r1
|
||||
}
|
||||
|
||||
// P384t1 returns a Curve which implements Brainpool P384t1 (see RFC 5639, section 3.6)
|
||||
func P384t1() elliptic.Curve {
|
||||
once.Do(initAll)
|
||||
return p384t1
|
||||
}
|
||||
|
||||
// P384r1 returns a Curve which implements Brainpool P384r1 (see RFC 5639, section 3.6)
|
||||
func P384r1() elliptic.Curve {
|
||||
once.Do(initAll)
|
||||
return p384r1
|
||||
}
|
||||
|
||||
// P512t1 returns a Curve which implements Brainpool P512t1 (see RFC 5639, section 3.7)
|
||||
func P512t1() elliptic.Curve {
|
||||
once.Do(initAll)
|
||||
return p512t1
|
||||
}
|
||||
|
||||
// P512r1 returns a Curve which implements Brainpool P512r1 (see RFC 5639, section 3.7)
|
||||
func P512r1() elliptic.Curve {
|
||||
once.Do(initAll)
|
||||
return p512r1
|
||||
}
|
83
vendor/github.com/ProtonMail/go-crypto/brainpool/rcurve.go
generated
vendored
Normal file
83
vendor/github.com/ProtonMail/go-crypto/brainpool/rcurve.go
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
package brainpool
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
var _ elliptic.Curve = (*rcurve)(nil)
|
||||
|
||||
type rcurve struct {
|
||||
twisted elliptic.Curve
|
||||
params *elliptic.CurveParams
|
||||
z *big.Int
|
||||
zinv *big.Int
|
||||
z2 *big.Int
|
||||
z3 *big.Int
|
||||
zinv2 *big.Int
|
||||
zinv3 *big.Int
|
||||
}
|
||||
|
||||
var (
|
||||
two = big.NewInt(2)
|
||||
three = big.NewInt(3)
|
||||
)
|
||||
|
||||
func newrcurve(twisted elliptic.Curve, params *elliptic.CurveParams, z *big.Int) *rcurve {
|
||||
zinv := new(big.Int).ModInverse(z, params.P)
|
||||
return &rcurve{
|
||||
twisted: twisted,
|
||||
params: params,
|
||||
z: z,
|
||||
zinv: zinv,
|
||||
z2: new(big.Int).Exp(z, two, params.P),
|
||||
z3: new(big.Int).Exp(z, three, params.P),
|
||||
zinv2: new(big.Int).Exp(zinv, two, params.P),
|
||||
zinv3: new(big.Int).Exp(zinv, three, params.P),
|
||||
}
|
||||
}
|
||||
|
||||
func (curve *rcurve) toTwisted(x, y *big.Int) (*big.Int, *big.Int) {
|
||||
var tx, ty big.Int
|
||||
tx.Mul(x, curve.z2)
|
||||
tx.Mod(&tx, curve.params.P)
|
||||
ty.Mul(y, curve.z3)
|
||||
ty.Mod(&ty, curve.params.P)
|
||||
return &tx, &ty
|
||||
}
|
||||
|
||||
func (curve *rcurve) fromTwisted(tx, ty *big.Int) (*big.Int, *big.Int) {
|
||||
var x, y big.Int
|
||||
x.Mul(tx, curve.zinv2)
|
||||
x.Mod(&x, curve.params.P)
|
||||
y.Mul(ty, curve.zinv3)
|
||||
y.Mod(&y, curve.params.P)
|
||||
return &x, &y
|
||||
}
|
||||
|
||||
func (curve *rcurve) Params() *elliptic.CurveParams {
|
||||
return curve.params
|
||||
}
|
||||
|
||||
func (curve *rcurve) IsOnCurve(x, y *big.Int) bool {
|
||||
return curve.twisted.IsOnCurve(curve.toTwisted(x, y))
|
||||
}
|
||||
|
||||
func (curve *rcurve) Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int) {
|
||||
tx1, ty1 := curve.toTwisted(x1, y1)
|
||||
tx2, ty2 := curve.toTwisted(x2, y2)
|
||||
return curve.fromTwisted(curve.twisted.Add(tx1, ty1, tx2, ty2))
|
||||
}
|
||||
|
||||
func (curve *rcurve) Double(x1, y1 *big.Int) (x, y *big.Int) {
|
||||
return curve.fromTwisted(curve.twisted.Double(curve.toTwisted(x1, y1)))
|
||||
}
|
||||
|
||||
func (curve *rcurve) ScalarMult(x1, y1 *big.Int, scalar []byte) (x, y *big.Int) {
|
||||
tx1, ty1 := curve.toTwisted(x1, y1)
|
||||
return curve.fromTwisted(curve.twisted.ScalarMult(tx1, ty1, scalar))
|
||||
}
|
||||
|
||||
func (curve *rcurve) ScalarBaseMult(scalar []byte) (x, y *big.Int) {
|
||||
return curve.fromTwisted(curve.twisted.ScalarBaseMult(scalar))
|
||||
}
|
162
vendor/github.com/ProtonMail/go-crypto/eax/eax.go
generated
vendored
Normal file
162
vendor/github.com/ProtonMail/go-crypto/eax/eax.go
generated
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
// Copyright (C) 2019 ProtonTech AG
|
||||
|
||||
// Package eax provides an implementation of the EAX
|
||||
// (encrypt-authenticate-translate) mode of operation, as described in
|
||||
// Bellare, Rogaway, and Wagner "THE EAX MODE OF OPERATION: A TWO-PASS
|
||||
// AUTHENTICATED-ENCRYPTION SCHEME OPTIMIZED FOR SIMPLICITY AND EFFICIENCY."
|
||||
// In FSE'04, volume 3017 of LNCS, 2004
|
||||
package eax
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"github.com/ProtonMail/go-crypto/internal/byteutil"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultTagSize = 16
|
||||
defaultNonceSize = 16
|
||||
)
|
||||
|
||||
type eax struct {
|
||||
block cipher.Block // Only AES-{128, 192, 256} supported
|
||||
tagSize int // At least 12 bytes recommended
|
||||
nonceSize int
|
||||
}
|
||||
|
||||
func (e *eax) NonceSize() int {
|
||||
return e.nonceSize
|
||||
}
|
||||
|
||||
func (e *eax) Overhead() int {
|
||||
return e.tagSize
|
||||
}
|
||||
|
||||
// NewEAX returns an EAX instance with AES-{KEYLENGTH} and default nonce and
|
||||
// tag lengths. Supports {128, 192, 256}- bit key length.
|
||||
func NewEAX(block cipher.Block) (cipher.AEAD, error) {
|
||||
return NewEAXWithNonceAndTagSize(block, defaultNonceSize, defaultTagSize)
|
||||
}
|
||||
|
||||
// NewEAXWithNonceAndTagSize returns an EAX instance with AES-{keyLength} and
|
||||
// given nonce and tag lengths in bytes. Panics on zero nonceSize and
|
||||
// exceedingly long tags.
|
||||
//
|
||||
// It is recommended to use at least 12 bytes as tag length (see, for instance,
|
||||
// NIST SP 800-38D).
|
||||
//
|
||||
// Only to be used for compatibility with existing cryptosystems with
|
||||
// non-standard parameters. For all other cases, prefer NewEAX.
|
||||
func NewEAXWithNonceAndTagSize(
|
||||
block cipher.Block, nonceSize, tagSize int) (cipher.AEAD, error) {
|
||||
if nonceSize < 1 {
|
||||
return nil, eaxError("Cannot initialize EAX with nonceSize = 0")
|
||||
}
|
||||
if tagSize > block.BlockSize() {
|
||||
return nil, eaxError("Custom tag length exceeds blocksize")
|
||||
}
|
||||
return &eax{
|
||||
block: block,
|
||||
tagSize: tagSize,
|
||||
nonceSize: nonceSize,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (e *eax) Seal(dst, nonce, plaintext, adata []byte) []byte {
|
||||
if len(nonce) > e.nonceSize {
|
||||
panic("crypto/eax: Nonce too long for this instance")
|
||||
}
|
||||
ret, out := byteutil.SliceForAppend(dst, len(plaintext) + e.tagSize)
|
||||
omacNonce := e.omacT(0, nonce)
|
||||
omacAdata := e.omacT(1, adata)
|
||||
|
||||
// Encrypt message using CTR mode and omacNonce as IV
|
||||
ctr := cipher.NewCTR(e.block, omacNonce)
|
||||
ciphertextData := out[:len(plaintext)]
|
||||
ctr.XORKeyStream(ciphertextData, plaintext)
|
||||
|
||||
omacCiphertext := e.omacT(2, ciphertextData)
|
||||
|
||||
tag := out[len(plaintext):]
|
||||
for i := 0; i < e.tagSize; i++ {
|
||||
tag[i] = omacCiphertext[i] ^ omacNonce[i] ^ omacAdata[i]
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (e* eax) Open(dst, nonce, ciphertext, adata []byte) ([]byte, error) {
|
||||
if len(nonce) > e.nonceSize {
|
||||
panic("crypto/eax: Nonce too long for this instance")
|
||||
}
|
||||
if len(ciphertext) < e.tagSize {
|
||||
return nil, eaxError("Ciphertext shorter than tag length")
|
||||
}
|
||||
sep := len(ciphertext) - e.tagSize
|
||||
|
||||
// Compute tag
|
||||
omacNonce := e.omacT(0, nonce)
|
||||
omacAdata := e.omacT(1, adata)
|
||||
omacCiphertext := e.omacT(2, ciphertext[:sep])
|
||||
|
||||
tag := make([]byte, e.tagSize)
|
||||
for i := 0; i < e.tagSize; i++ {
|
||||
tag[i] = omacCiphertext[i] ^ omacNonce[i] ^ omacAdata[i]
|
||||
}
|
||||
|
||||
// Compare tags
|
||||
if subtle.ConstantTimeCompare(ciphertext[sep:], tag) != 1 {
|
||||
return nil, eaxError("Tag authentication failed")
|
||||
}
|
||||
|
||||
// Decrypt ciphertext
|
||||
ret, out := byteutil.SliceForAppend(dst, len(ciphertext))
|
||||
ctr := cipher.NewCTR(e.block, omacNonce)
|
||||
ctr.XORKeyStream(out, ciphertext[:sep])
|
||||
|
||||
return ret[:sep], nil
|
||||
}
|
||||
|
||||
// Tweakable OMAC - Calls OMAC_K([t]_n || plaintext)
|
||||
func (e *eax) omacT(t byte, plaintext []byte) []byte {
|
||||
blockSize := e.block.BlockSize()
|
||||
byteT := make([]byte, blockSize)
|
||||
byteT[blockSize-1] = t
|
||||
concat := append(byteT, plaintext...)
|
||||
return e.omac(concat)
|
||||
}
|
||||
|
||||
func (e *eax) omac(plaintext []byte) []byte {
|
||||
blockSize := e.block.BlockSize()
|
||||
// L ← E_K(0^n); B ← 2L; P ← 4L
|
||||
L := make([]byte, blockSize)
|
||||
e.block.Encrypt(L, L)
|
||||
B := byteutil.GfnDouble(L)
|
||||
P := byteutil.GfnDouble(B)
|
||||
|
||||
// CBC with IV = 0
|
||||
cbc := cipher.NewCBCEncrypter(e.block, make([]byte, blockSize))
|
||||
padded := e.pad(plaintext, B, P)
|
||||
cbcCiphertext := make([]byte, len(padded))
|
||||
cbc.CryptBlocks(cbcCiphertext, padded)
|
||||
|
||||
return cbcCiphertext[len(cbcCiphertext)-blockSize:]
|
||||
}
|
||||
|
||||
func (e *eax) pad(plaintext, B, P []byte) []byte {
|
||||
// if |M| in {n, 2n, 3n, ...}
|
||||
blockSize := e.block.BlockSize()
|
||||
if len(plaintext) != 0 && len(plaintext)%blockSize == 0 {
|
||||
return byteutil.RightXor(plaintext, B)
|
||||
}
|
||||
|
||||
// else return (M || 1 || 0^(n−1−(|M| % n))) xor→ P
|
||||
ending := make([]byte, blockSize-len(plaintext)%blockSize)
|
||||
ending[0] = 0x80
|
||||
padded := append(plaintext, ending...)
|
||||
return byteutil.RightXor(padded, P)
|
||||
}
|
||||
|
||||
func eaxError(err string) error {
|
||||
return errors.New("crypto/eax: " + err)
|
||||
}
|
58
vendor/github.com/ProtonMail/go-crypto/eax/eax_test_vectors.go
generated
vendored
Normal file
58
vendor/github.com/ProtonMail/go-crypto/eax/eax_test_vectors.go
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
package eax
|
||||
|
||||
// Test vectors from
|
||||
// https://web.cs.ucdavis.edu/~rogaway/papers/eax.pdf
|
||||
var testVectors = []struct {
|
||||
msg, key, nonce, header, ciphertext string
|
||||
}{
|
||||
{"",
|
||||
"233952DEE4D5ED5F9B9C6D6FF80FF478",
|
||||
"62EC67F9C3A4A407FCB2A8C49031A8B3",
|
||||
"6BFB914FD07EAE6B",
|
||||
"E037830E8389F27B025A2D6527E79D01"},
|
||||
{"F7FB",
|
||||
"91945D3F4DCBEE0BF45EF52255F095A4",
|
||||
"BECAF043B0A23D843194BA972C66DEBD",
|
||||
"FA3BFD4806EB53FA",
|
||||
"19DD5C4C9331049D0BDAB0277408F67967E5"},
|
||||
{"1A47CB4933",
|
||||
"01F74AD64077F2E704C0F60ADA3DD523",
|
||||
"70C3DB4F0D26368400A10ED05D2BFF5E",
|
||||
"234A3463C1264AC6",
|
||||
"D851D5BAE03A59F238A23E39199DC9266626C40F80"},
|
||||
{"481C9E39B1",
|
||||
"D07CF6CBB7F313BDDE66B727AFD3C5E8",
|
||||
"8408DFFF3C1A2B1292DC199E46B7D617",
|
||||
"33CCE2EABFF5A79D",
|
||||
"632A9D131AD4C168A4225D8E1FF755939974A7BEDE"},
|
||||
{"40D0C07DA5E4",
|
||||
"35B6D0580005BBC12B0587124557D2C2",
|
||||
"FDB6B06676EEDC5C61D74276E1F8E816",
|
||||
"AEB96EAEBE2970E9",
|
||||
"071DFE16C675CB0677E536F73AFE6A14B74EE49844DD"},
|
||||
{"4DE3B35C3FC039245BD1FB7D",
|
||||
"BD8E6E11475E60B268784C38C62FEB22",
|
||||
"6EAC5C93072D8E8513F750935E46DA1B",
|
||||
"D4482D1CA78DCE0F",
|
||||
"835BB4F15D743E350E728414ABB8644FD6CCB86947C5E10590210A4F"},
|
||||
{"8B0A79306C9CE7ED99DAE4F87F8DD61636",
|
||||
"7C77D6E813BED5AC98BAA417477A2E7D",
|
||||
"1A8C98DCD73D38393B2BF1569DEEFC19",
|
||||
"65D2017990D62528",
|
||||
"02083E3979DA014812F59F11D52630DA30137327D10649B0AA6E1C181DB617D7F2"},
|
||||
{"1BDA122BCE8A8DBAF1877D962B8592DD2D56",
|
||||
"5FFF20CAFAB119CA2FC73549E20F5B0D",
|
||||
"DDE59B97D722156D4D9AFF2BC7559826",
|
||||
"54B9F04E6A09189A",
|
||||
"2EC47B2C4954A489AFC7BA4897EDCDAE8CC33B60450599BD02C96382902AEF7F832A"},
|
||||
{"6CF36720872B8513F6EAB1A8A44438D5EF11",
|
||||
"A4A4782BCFFD3EC5E7EF6D8C34A56123",
|
||||
"B781FCF2F75FA5A8DE97A9CA48E522EC",
|
||||
"899A175897561D7E",
|
||||
"0DE18FD0FDD91E7AF19F1D8EE8733938B1E8E7F6D2231618102FDB7FE55FF1991700"},
|
||||
{"CA40D7446E545FFAED3BD12A740A659FFBBB3CEAB7",
|
||||
"8395FCF1E95BEBD697BD010BC766AAC3",
|
||||
"22E7ADD93CFC6393C57EC0B3C17D6B44",
|
||||
"126735FCC320D25A",
|
||||
"CB8920F87A6C75CFF39627B56E3ED197C552D295A7CFC46AFC253B4652B1AF3795B124AB6E"},
|
||||
}
|
131
vendor/github.com/ProtonMail/go-crypto/eax/random_vectors.go
generated
vendored
Normal file
131
vendor/github.com/ProtonMail/go-crypto/eax/random_vectors.go
generated
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
// These vectors include key length in {128, 192, 256}, tag size 128, and
|
||||
// random nonce, header, and plaintext lengths.
|
||||
|
||||
// This file was automatically generated.
|
||||
|
||||
package eax
|
||||
|
||||
var randomVectors = []struct {
|
||||
key, nonce, header, plaintext, ciphertext string
|
||||
}{
|
||||
{"DFDE093F36B0356E5A81F609786982E3",
|
||||
"1D8AC604419001816905BA72B14CED7E",
|
||||
"152A1517A998D7A24163FCDD146DE81AC347C8B97088F502093C1ABB8F6E33D9A219C34D7603A18B1F5ABE02E56661B7D7F67E81EC08C1302EF38D80A859486D450E94A4F26AD9E68EEBBC0C857A0FC5CF9E641D63D565A7E361BC8908F5A8DC8FD6",
|
||||
"1C8EAAB71077FE18B39730A3156ADE29C5EE824C7EE86ED2A253B775603FB237116E654F6FEC588DD27F523A0E01246FE73FE348491F2A8E9ABC6CA58D663F71CDBCF4AD798BE46C42AE6EE8B599DB44A1A48D7BBBBA0F7D2750181E1C5E66967F7D57CBD30AFBDA5727",
|
||||
"79E7E150934BBEBF7013F61C60462A14D8B15AF7A248AFB8A344EF021C1500E16666891D6E973D8BB56B71A371F12CA34660C4410C016982B20F547E3762A58B7BF4F20236CADCF559E2BE7D783B13723B2741FC7CDC8997D839E39A3DDD2BADB96743DD7049F1BDB0516A262869915B3F70498AFB7B191BF960"},
|
||||
{"F10619EF02E5D94D7550EB84ED364A21",
|
||||
"8DC0D4F2F745BBAE835CC5574B942D20",
|
||||
"FE561358F2E8DF7E1024FF1AE9A8D36EBD01352214505CB99D644777A8A1F6027FA2BDBFC529A9B91136D5F2416CFC5F0F4EC3A1AFD32BDDA23CA504C5A5CB451785FABF4DFE4CD50D817491991A60615B30286361C100A95D1712F2A45F8E374461F4CA2B",
|
||||
"D7B5A971FC219631D30EFC3664AE3127D9CF3097DAD9C24AC7905D15E8D9B25B026B31D68CAE00975CDB81EB1FD96FD5E1A12E2BB83FA25F1B1D91363457657FC03875C27F2946C5",
|
||||
"2F336ED42D3CC38FC61660C4CD60BA4BD438B05F5965D8B7B399D2E7167F5D34F792D318F94DB15D67463AC449E13D568CC09BFCE32A35EE3EE96A041927680AE329811811E27F2D1E8E657707AF99BA96D13A478D695D59"},
|
||||
{"429F514EFC64D98A698A9247274CFF45",
|
||||
"976AA5EB072F912D126ACEBC954FEC38",
|
||||
"A71D89DC5B6CEDBB7451A27C3C2CAE09126DB4C421",
|
||||
"5632FE62AB1DC549D54D3BC3FC868ACCEDEFD9ECF5E9F8",
|
||||
"848AE4306CA8C7F416F8707625B7F55881C0AB430353A5C967CDA2DA787F581A70E34DBEBB2385"},
|
||||
{"398138F309085F47F8457CDF53895A63",
|
||||
"F8A8A7F2D28E5FFF7BBC2F24353F7A36",
|
||||
"5D633C21BA7764B8855CAB586F3746E236AD486039C83C6B56EFA9C651D38A41D6B20DAEE3418BFEA44B8BD6",
|
||||
"A3BBAA91920AF5E10659818B1B3B300AC79BFC129C8329E75251F73A66D3AE0128EB91D5031E0A65C329DB7D1E9C0493E268",
|
||||
"D078097267606E5FB07CFB7E2B4B718172A82C6A4CEE65D549A4DFB9838003BD2FBF64A7A66988AC1A632FD88F9E9FBB57C5A78AD2E086EACBA3DB68511D81C2970A"},
|
||||
{"7A4151EBD3901B42CBA45DAFB2E931BA",
|
||||
"0FC88ACEE74DD538040321C330974EB8",
|
||||
"250464FB04733BAB934C59E6AD2D6AE8D662CBCFEFBE61E5A308D4211E58C4C25935B72C69107722E946BFCBF416796600542D76AEB73F2B25BF53BAF97BDEB36ED3A7A51C31E7F170EB897457E7C17571D1BA0A908954E9",
|
||||
"88C41F3EBEC23FAB8A362D969CAC810FAD4F7CA6A7F7D0D44F060F92E37E1183768DD4A8C733F71C96058D362A39876D183B86C103DE",
|
||||
"74A25B2182C51096D48A870D80F18E1CE15867778E34FCBA6BD7BFB3739FDCD42AD0F2D9F4EBA29085285C6048C15BCE5E5166F1F962D3337AA88E6062F05523029D0A7F0BF9"},
|
||||
{"BFB147E1CD5459424F8C0271FC0E0DC5",
|
||||
"EABCC126442BF373969EA3015988CC45",
|
||||
"4C0880E1D71AA2C7",
|
||||
"BE1B5EC78FBF73E7A6682B21BA7E0E5D2D1C7ABE",
|
||||
"5660D7C1380E2F306895B1402CB2D6C37876504276B414D120F4CF92FDDDBB293A238EA0"},
|
||||
{"595DD6F52D18BC2CA8EB4EDAA18D9FA3",
|
||||
"0F84B5D36CF4BC3B863313AF3B4D2E97",
|
||||
"30AE6CC5F99580F12A779D98BD379A60948020C0B6FBD5746B30BA3A15C6CD33DAF376C70A9F15B6C0EB410A93161F7958AE23",
|
||||
"8EF3687A1642B070970B0B91462229D1D76ABC154D18211F7152AA9FF368",
|
||||
"317C1DDB11417E5A9CC4DDE7FDFF6659A5AC4B31DE025212580A05CDAC6024D3E4AE7C2966E52B9129E9ECDBED86"},
|
||||
{"44E6F2DC8FDC778AD007137D11410F50",
|
||||
"270A237AD977F7187AA6C158A0BAB24F",
|
||||
"509B0F0EB12E2AA5C5BA2DE553C07FAF4CE0C9E926531AA709A3D6224FCB783ACCF1559E10B1123EBB7D52E8AB54E6B5352A9ED0D04124BF0E9D9BACFD7E32B817B2E625F5EE94A64EDE9E470DE7FE6886C19B294F9F828209FE257A78",
|
||||
"8B3D7815DF25618A5D0C55A601711881483878F113A12EC36CF64900549A3199555528559DC118F789788A55FAFD944E6E99A9CA3F72F238CD3F4D88223F7A745992B3FAED1848",
|
||||
"1CC00D79F7AD82FDA71B58D286E5F34D0CC4CEF30704E771CC1E50746BDF83E182B078DB27149A42BAE619DF0F85B0B1090AD55D3B4471B0D6F6ECCD09C8F876B30081F0E7537A9624F8AAF29DA85E324122EFB4D68A56"},
|
||||
{"BB7BC352A03044B4428D8DBB4B0701FDEC4649FD17B81452",
|
||||
"8B4BBE26CCD9859DCD84884159D6B0A4",
|
||||
"2212BEB0E78E0F044A86944CF33C8D5C80D9DBE1034BF3BCF73611835C7D3A52F5BD2D81B68FD681B68540A496EE5DA16FD8AC8824E60E1EC2042BE28FB0BFAD4E4B03596446BDD8C37D936D9B3D5295BE19F19CF5ACE1D33A46C952CE4DE5C12F92C1DD051E04AEED",
|
||||
"9037234CC44FFF828FABED3A7084AF40FA7ABFF8E0C0EFB57A1CC361E18FC4FAC1AB54F3ABFE9FF77263ACE16C3A",
|
||||
"A9391B805CCD956081E0B63D282BEA46E7025126F1C1631239C33E92AA6F92CD56E5A4C56F00FF9658E93D48AF4EF0EF81628E34AD4DB0CDAEDCD2A17EE7"},
|
||||
{"99C0AD703196D2F60A74E6B378B838B31F82EA861F06FC4E",
|
||||
"92745C018AA708ECFEB1667E9F3F1B01",
|
||||
"828C69F376C0C0EC651C67749C69577D589EE39E51404D80EBF70C8660A8F5FD375473F4A7C611D59CB546A605D67446CE2AA844135FCD78BB5FBC90222A00D42920BB1D7EEDFB0C4672554F583EF23184F89063CDECBE482367B5F9AF3ACBC3AF61392BD94CBCD9B64677",
|
||||
"A879214658FD0A5B0E09836639BF82E05EC7A5EF71D4701934BDA228435C68AC3D5CEB54997878B06A655EEACEFB1345C15867E7FE6C6423660C8B88DF128EBD6BCD85118DBAE16E9252FFB204324E5C8F38CA97759BDBF3CB0083",
|
||||
"51FE87996F194A2585E438B023B345439EA60D1AEBED4650CDAF48A4D4EEC4FC77DC71CC4B09D3BEEF8B7B7AF716CE2B4EFFB3AC9E6323C18AC35E0AA6E2BBBC8889490EB6226C896B0D105EAB42BFE7053CCF00ED66BA94C1BA09A792AA873F0C3B26C5C5F9A936E57B25"},
|
||||
{"7086816D00D648FB8304AA8C9E552E1B69A9955FB59B25D1",
|
||||
"0F45CF7F0BF31CCEB85D9DA10F4D749F",
|
||||
"93F27C60A417D9F0669E86ACC784FC8917B502DAF30A6338F11B30B94D74FEFE2F8BE1BBE2EAD10FAB7EED3C6F72B7C3ECEE1937C32ED4970A6404E139209C05",
|
||||
"877F046601F3CBE4FB1491943FA29487E738F94B99AF206262A1D6FF856C9AA0B8D4D08A54370C98F8E88FA3DCC2B14C1F76D71B2A4C7963AEE8AF960464C5BEC8357AD00DC8",
|
||||
"FE96906B895CE6A8E72BC72344E2C8BB3C63113D70EAFA26C299BAFE77A8A6568172EB447FB3E86648A0AF3512DEB1AAC0819F3EC553903BF28A9FB0F43411237A774BF9EE03E445D280FBB9CD12B9BAAB6EF5E52691"},
|
||||
{"062F65A896D5BF1401BADFF70E91B458E1F9BD4888CB2E4D",
|
||||
"5B11EA1D6008EBB41CF892FCA5B943D1",
|
||||
"BAF4FF5C8242",
|
||||
"A8870E091238355984EB2F7D61A865B9170F440BFF999A5993DD41A10F4440D21FF948DDA2BF663B2E03AC3324492DC5E40262ECC6A65C07672353BE23E7FB3A9D79FF6AA38D97960905A38DECC312CB6A59E5467ECF06C311CD43ADC0B543EDF34FE8BE611F176460D5627CA51F8F8D9FED71F55C",
|
||||
"B10E127A632172CF8AA7539B140D2C9C2590E6F28C3CB892FC498FCE56A34F732FBFF32E79C7B9747D9094E8635A0C084D6F0247F9768FB5FF83493799A9BEC6C39572120C40E9292C8C947AE8573462A9108C36D9D7112E6995AE5867E6C8BB387D1C5D4BEF524F391B9FD9F0A3B4BFA079E915BCD920185CFD38D114C558928BD7D47877"},
|
||||
{"38A8E45D6D705A11AF58AED5A1344896998EACF359F2E26A",
|
||||
"FD82B5B31804FF47D44199B533D0CF84",
|
||||
"DE454D4E62FE879F2050EE3E25853623D3E9AC52EEC1A1779A48CFAF5ECA0BFDE44749391866D1",
|
||||
"B804",
|
||||
"164BB965C05EBE0931A1A63293EDF9C38C27"},
|
||||
{"34C33C97C6D7A0850DA94D78A58DC61EC717CD7574833068",
|
||||
"343BE00DA9483F05C14F2E9EB8EA6AE8",
|
||||
"78312A43EFDE3CAE34A65796FF059A3FE15304EEA5CF1D9306949FE5BF3349D4977D4EBE76C040FE894C5949E4E4D6681153DA87FB9AC5062063CA2EA183566343362370944CE0362D25FC195E124FD60E8682E665D13F2229DDA3E4B2CB1DCA",
|
||||
"CC11BB284B1153578E4A5ED9D937B869DAF00F5B1960C23455CA9CC43F486A3BE0B66254F1041F04FDF459C8640465B6E1D2CF899A381451E8E7FCB50CF87823BE77E24B132BBEEDC72E53369B275E1D8F49ECE59F4F215230AC4FE133FC80E4F634EE80BA4682B62C86",
|
||||
"E7F703DC31A95E3A4919FF957836CB76C063D81702AEA4703E1C2BF30831E58C4609D626EC6810E12EAA5B930F049FF9EFC22C3E3F1EBD4A1FB285CB02A1AC5AD46B425199FC0A85670A5C4E3DAA9636C8F64C199F42F18AAC8EA7457FD377F322DD7752D7D01B946C8F0A97E6113F0D50106F319AFD291AAACE"},
|
||||
{"C6ECF7F053573E403E61B83052A343D93CBCC179D1E835BE",
|
||||
"E280E13D7367042E3AA09A80111B6184",
|
||||
"21486C9D7A9647",
|
||||
"5F2639AFA6F17931853791CD8C92382BBB677FD72D0AB1A080D0E49BFAA21810E963E4FACD422E92F65CBFAD5884A60CD94740DF31AF02F95AA57DA0C4401B0ED906",
|
||||
"5C51DB20755302070C45F52E50128A67C8B2E4ED0EACB7E29998CCE2E8C289DD5655913EC1A51CC3AABE5CDC2402B2BE7D6D4BF6945F266FBD70BA9F37109067157AE7530678B45F64475D4EBFCB5FFF46A5"},
|
||||
{"5EC6CF7401BC57B18EF154E8C38ACCA8959E57D2F3975FF5",
|
||||
"656B41CB3F9CF8C08BAD7EBFC80BD225",
|
||||
"6B817C2906E2AF425861A7EF59BA5801F143EE2A139EE72697CDE168B4",
|
||||
"2C0E1DDC9B1E5389BA63845B18B1F8A1DB062037151BCC56EF7C21C0BB4DAE366636BBA975685D7CC5A94AFBE89C769016388C56FB7B57CE750A12B718A8BDCF70E80E8659A8330EFC8F86640F21735E8C80E23FE43ABF23507CE3F964AE4EC99D",
|
||||
"ED780CF911E6D1AA8C979B889B0B9DC1ABE261832980BDBFB576901D9EF5AB8048998E31A15BE54B3E5845A4D136AD24D0BDA1C3006168DF2F8AC06729CB0818867398150020131D8F04EDF1923758C9EABB5F735DE5EA1758D4BC0ACFCA98AFD202E9839B8720253693B874C65586C6F0"},
|
||||
{"C92F678EB2208662F5BCF3403EC05F5961E957908A3E79421E1D25FC19054153",
|
||||
"DA0F3A40983D92F2D4C01FED33C7A192",
|
||||
"2B6E9D26DB406A0FAB47608657AA10EFC2B4AA5F459B29FF85AC9A40BFFE7AEB04F77E9A11FAAA116D7F6D4DA417671A9AB02C588E0EF59CB1BFB4B1CC931B63A3B3A159FCEC97A04D1E6F0C7E6A9CEF6B0ABB04758A69F1FE754DF4C2610E8C46B6CF413BDB31351D55BEDCB7B4A13A1C98E10984475E0F2F957853",
|
||||
"F37326A80E08",
|
||||
"83519E53E321D334F7C10B568183775C0E9AAE55F806"},
|
||||
{"6847E0491BE57E72995D186D50094B0B3593957A5146798FCE68B287B2FB37B5",
|
||||
"3EE1182AEBB19A02B128F28E1D5F7F99",
|
||||
"D9F35ABB16D776CE",
|
||||
"DB7566ED8EA95BDF837F23DB277BAFBC5E70D1105ADFD0D9EF15475051B1EF94709C67DCA9F8D5",
|
||||
"2CDCED0C9EBD6E2A508822A685F7DCD1CDD99E7A5FCA786C234E7F7F1D27EC49751AD5DCFA30C5EDA87C43CAE3B919B6BBCFE34C8EDA59"},
|
||||
{"82B019673642C08388D3E42075A4D5D587558C229E4AB8F660E37650C4C41A0A",
|
||||
"336F5D681E0410FAE7B607246092C6DC",
|
||||
"D430CBD8FE435B64214E9E9CDC5DE99D31CFCFB8C10AA0587A49DF276611",
|
||||
"998404153AD77003E1737EDE93ED79859EE6DCCA93CB40C4363AA817ABF2DBBD46E42A14A7183B6CC01E12A577888141363D0AE011EB6E8D28C0B235",
|
||||
"9BEF69EEB60BD3D6065707B7557F25292A8872857CFBD24F2F3C088E4450995333088DA50FD9121221C504DF1D0CD5EFE6A12666C5D5BB12282CF4C19906E9CFAB97E9BDF7F49DC17CFC384B"},
|
||||
{"747B2E269B1859F0622C15C8BAD6A725028B1F94B8DB7326948D1E6ED663A8BC",
|
||||
"AB91F7245DDCE3F1C747872D47BE0A8A",
|
||||
"3B03F786EF1DDD76E1D42646DA4CD2A5165DC5383CE86D1A0B5F13F910DC278A4E451EE0192CBA178E13B3BA27FDC7840DF73D2E104B",
|
||||
"6B803F4701114F3E5FE21718845F8416F70F626303F545BE197189E0A2BA396F37CE06D389EB2658BC7D56D67868708F6D0D32",
|
||||
"1570DDB0BCE75AA25D1957A287A2C36B1A5F2270186DA81BA6112B7F43B0F3D1D0ED072591DCF1F1C99BBB25621FC39B896FF9BD9413A2845363A9DCD310C32CF98E57"},
|
||||
{"02E59853FB29AEDA0FE1C5F19180AD99A12FF2F144670BB2B8BADF09AD812E0A",
|
||||
"C691294EF67CD04D1B9242AF83DD1421",
|
||||
"879334DAE3",
|
||||
"1E17F46A98FEF5CBB40759D95354",
|
||||
"FED8C3FF27DDF6313AED444A2985B36CBA268AAD6AAC563C0BA28F6DB5DB"},
|
||||
{"F6C1FB9B4188F2288FF03BD716023198C3582CF2A037FC2F29760916C2B7FCDB",
|
||||
"4228DA0678CA3534588859E77DFF014C",
|
||||
"D8153CAF35539A61DD8D05B3C9B44F01E564FB9348BCD09A1C23B84195171308861058F0A3CD2A55B912A3AAEE06FF4D356C77275828F2157C2FC7C115DA39E443210CCC56BEDB0CC99BBFB227ABD5CC454F4E7F547C7378A659EEB6A7E809101A84F866503CB18D4484E1FA09B3EC7FC75EB2E35270800AA7",
|
||||
"23B660A779AD285704B12EC1C580387A47BEC7B00D452C6570",
|
||||
"5AA642BBABA8E49849002A2FAF31DB8FC7773EFDD656E469CEC19B3206D4174C9A263D0A05484261F6"},
|
||||
{"8FF6086F1FADB9A3FBE245EAC52640C43B39D43F89526BB5A6EBA47710931446",
|
||||
"943188480C99437495958B0AE4831AA9",
|
||||
"AD5CD0BDA426F6EBA23C8EB23DC73FF9FEC173355EDBD6C9344C4C4383F211888F7CE6B29899A6801DF6B38651A7C77150941A",
|
||||
"80CD5EA8D7F81DDF5070B934937912E8F541A5301877528EB41AB60C020968D459960ED8FB73083329841A",
|
||||
"ABAE8EB7F36FCA2362551E72DAC890BA1BB6794797E0FC3B67426EC9372726ED4725D379EA0AC9147E48DCD0005C502863C2C5358A38817C8264B5"},
|
||||
{"A083B54E6B1FE01B65D42FCD248F97BB477A41462BBFE6FD591006C022C8FD84",
|
||||
"B0490F5BD68A52459556B3749ACDF40E",
|
||||
"8892E047DA5CFBBDF7F3CFCBD1BD21C6D4C80774B1826999234394BD3E513CC7C222BB40E1E3140A152F19B3802F0D036C24A590512AD0E8",
|
||||
"D7B15752789DC94ED0F36778A5C7BBB207BEC32BAC66E702B39966F06E381E090C6757653C3D26A81EC6AD6C364D66867A334C91BB0B8A8A4B6EACDF0783D09010AEBA2DD2062308FE99CC1F",
|
||||
"C071280A732ADC93DF272BF1E613B2BB7D46FC6665EF2DC1671F3E211D6BDE1D6ADDD28DF3AA2E47053FC8BB8AE9271EC8BC8B2CFFA320D225B451685B6D23ACEFDD241FE284F8ADC8DB07F456985B14330BBB66E0FB212213E05B3E"},
|
||||
}
|
92
vendor/github.com/ProtonMail/go-crypto/internal/byteutil/byteutil.go
generated
vendored
Normal file
92
vendor/github.com/ProtonMail/go-crypto/internal/byteutil/byteutil.go
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright (C) 2019 ProtonTech AG
|
||||
// This file contains necessary tools for the aex and ocb packages.
|
||||
//
|
||||
// These functions SHOULD NOT be used elsewhere, since they are optimized for
|
||||
// specific input nature in the EAX and OCB modes of operation.
|
||||
|
||||
package byteutil
|
||||
|
||||
// GfnDouble computes 2 * input in the field of 2^n elements.
|
||||
// The irreducible polynomial in the finite field for n=128 is
|
||||
// x^128 + x^7 + x^2 + x + 1 (equals 0x87)
|
||||
// Constant-time execution in order to avoid side-channel attacks
|
||||
func GfnDouble(input []byte) []byte {
|
||||
if len(input) != 16 {
|
||||
panic("Doubling in GFn only implemented for n = 128")
|
||||
}
|
||||
// If the first bit is zero, return 2L = L << 1
|
||||
// Else return (L << 1) xor 0^120 10000111
|
||||
shifted := ShiftBytesLeft(input)
|
||||
shifted[15] ^= ((input[0] >> 7) * 0x87)
|
||||
return shifted
|
||||
}
|
||||
|
||||
// ShiftBytesLeft outputs the byte array corresponding to x << 1 in binary.
|
||||
func ShiftBytesLeft(x []byte) []byte {
|
||||
l := len(x)
|
||||
dst := make([]byte, l)
|
||||
for i := 0; i < l-1; i++ {
|
||||
dst[i] = (x[i] << 1) | (x[i+1] >> 7)
|
||||
}
|
||||
dst[l-1] = x[l-1] << 1
|
||||
return dst
|
||||
}
|
||||
|
||||
// ShiftNBytesLeft puts in dst the byte array corresponding to x << n in binary.
|
||||
func ShiftNBytesLeft(dst, x []byte, n int) {
|
||||
// Erase first n / 8 bytes
|
||||
copy(dst, x[n/8:])
|
||||
|
||||
// Shift the remaining n % 8 bits
|
||||
bits := uint(n % 8)
|
||||
l := len(dst)
|
||||
for i := 0; i < l-1; i++ {
|
||||
dst[i] = (dst[i] << bits) | (dst[i+1] >> uint(8 - bits))
|
||||
}
|
||||
dst[l-1] = dst[l-1] << bits
|
||||
|
||||
// Append trailing zeroes
|
||||
dst = append(dst, make([]byte, n/8)...)
|
||||
}
|
||||
|
||||
// XorBytesMut assumes equal input length, replaces X with X XOR Y
|
||||
func XorBytesMut(X, Y []byte) {
|
||||
for i := 0; i < len(X); i++ {
|
||||
X[i] ^= Y[i]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// XorBytes assumes equal input length, puts X XOR Y into Z
|
||||
func XorBytes(Z, X, Y []byte) {
|
||||
for i := 0; i < len(X); i++ {
|
||||
Z[i] = X[i] ^ Y[i]
|
||||
}
|
||||
}
|
||||
|
||||
// RightXor XORs smaller input (assumed Y) at the right of the larger input (assumed X)
|
||||
func RightXor(X, Y []byte) []byte {
|
||||
offset := len(X) - len(Y)
|
||||
xored := make([]byte, len(X));
|
||||
copy(xored, X)
|
||||
for i := 0; i < len(Y); i++ {
|
||||
xored[offset + i] ^= Y[i]
|
||||
}
|
||||
return xored
|
||||
}
|
||||
|
||||
// SliceForAppend takes a slice and a requested number of bytes. It returns a
|
||||
// slice with the contents of the given slice followed by that many bytes and a
|
||||
// second slice that aliases into it and contains only the extra bytes. If the
|
||||
// original slice has sufficient capacity then no allocation is performed.
|
||||
func SliceForAppend(in []byte, n int) (head, tail []byte) {
|
||||
if total := len(in) + n; cap(in) >= total {
|
||||
head = in[:total]
|
||||
} else {
|
||||
head = make([]byte, total)
|
||||
copy(head, in)
|
||||
}
|
||||
tail = head[len(in):]
|
||||
return
|
||||
}
|
||||
|
317
vendor/github.com/ProtonMail/go-crypto/ocb/ocb.go
generated
vendored
Normal file
317
vendor/github.com/ProtonMail/go-crypto/ocb/ocb.go
generated
vendored
Normal file
@ -0,0 +1,317 @@
|
||||
// Copyright (C) 2019 ProtonTech AG
|
||||
|
||||
// Package ocb provides an implementation of the OCB (offset codebook) mode of
|
||||
// operation, as described in RFC-7253 of the IRTF and in Rogaway, Bellare,
|
||||
// Black and Krovetz - OCB: A BLOCK-CIPHER MODE OF OPERATION FOR EFFICIENT
|
||||
// AUTHENTICATED ENCRYPTION (2003).
|
||||
// Security considerations (from RFC-7253): A private key MUST NOT be used to
|
||||
// encrypt more than 2^48 blocks. Tag length should be at least 12 bytes (a
|
||||
// brute-force forging adversary succeeds after 2^{tag length} attempts). A
|
||||
// single key SHOULD NOT be used to decrypt ciphertext with different tag
|
||||
// lengths. Nonces need not be secret, but MUST NOT be reused.
|
||||
// This package only supports underlying block ciphers with 128-bit blocks,
|
||||
// such as AES-{128, 192, 256}, but may be extended to other sizes.
|
||||
package ocb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/cipher"
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"github.com/ProtonMail/go-crypto/internal/byteutil"
|
||||
"math/bits"
|
||||
)
|
||||
|
||||
type ocb struct {
|
||||
block cipher.Block
|
||||
tagSize int
|
||||
nonceSize int
|
||||
mask mask
|
||||
// Optimized en/decrypt: For each nonce N used to en/decrypt, the 'Ktop'
|
||||
// internal variable can be reused for en/decrypting with nonces sharing
|
||||
// all but the last 6 bits with N. The prefix of the first nonce used to
|
||||
// compute the new Ktop, and the Ktop value itself, are stored in
|
||||
// reusableKtop. If using incremental nonces, this saves one block cipher
|
||||
// call every 63 out of 64 OCB encryptions, and stores one nonce and one
|
||||
// output of the block cipher in memory only.
|
||||
reusableKtop reusableKtop
|
||||
}
|
||||
|
||||
type mask struct {
|
||||
// L_*, L_$, (L_i)_{i ∈ N}
|
||||
lAst []byte
|
||||
lDol []byte
|
||||
L [][]byte
|
||||
}
|
||||
|
||||
type reusableKtop struct {
|
||||
noncePrefix []byte
|
||||
Ktop []byte
|
||||
}
|
||||
|
||||
const (
|
||||
defaultTagSize = 16
|
||||
defaultNonceSize = 15
|
||||
)
|
||||
|
||||
const (
|
||||
enc = iota
|
||||
dec
|
||||
)
|
||||
|
||||
func (o *ocb) NonceSize() int {
|
||||
return o.nonceSize
|
||||
}
|
||||
|
||||
func (o *ocb) Overhead() int {
|
||||
return o.tagSize
|
||||
}
|
||||
|
||||
// NewOCB returns an OCB instance with the given block cipher and default
|
||||
// tag and nonce sizes.
|
||||
func NewOCB(block cipher.Block) (cipher.AEAD, error) {
|
||||
return NewOCBWithNonceAndTagSize(block, defaultNonceSize, defaultTagSize)
|
||||
}
|
||||
|
||||
// NewOCBWithNonceAndTagSize returns an OCB instance with the given block
|
||||
// cipher, nonce length, and tag length. Panics on zero nonceSize and
|
||||
// exceedingly long tag size.
|
||||
//
|
||||
// It is recommended to use at least 12 bytes as tag length.
|
||||
func NewOCBWithNonceAndTagSize(
|
||||
block cipher.Block, nonceSize, tagSize int) (cipher.AEAD, error) {
|
||||
if block.BlockSize() != 16 {
|
||||
return nil, ocbError("Block cipher must have 128-bit blocks")
|
||||
}
|
||||
if nonceSize < 1 {
|
||||
return nil, ocbError("Incorrect nonce length")
|
||||
}
|
||||
if nonceSize >= block.BlockSize() {
|
||||
return nil, ocbError("Nonce length exceeds blocksize - 1")
|
||||
}
|
||||
if tagSize > block.BlockSize() {
|
||||
return nil, ocbError("Custom tag length exceeds blocksize")
|
||||
}
|
||||
return &ocb{
|
||||
block: block,
|
||||
tagSize: tagSize,
|
||||
nonceSize: nonceSize,
|
||||
mask: initializeMaskTable(block),
|
||||
reusableKtop: reusableKtop{
|
||||
noncePrefix: nil,
|
||||
Ktop: nil,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (o *ocb) Seal(dst, nonce, plaintext, adata []byte) []byte {
|
||||
if len(nonce) > o.nonceSize {
|
||||
panic("crypto/ocb: Incorrect nonce length given to OCB")
|
||||
}
|
||||
ret, out := byteutil.SliceForAppend(dst, len(plaintext)+o.tagSize)
|
||||
o.crypt(enc, out, nonce, adata, plaintext)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (o *ocb) Open(dst, nonce, ciphertext, adata []byte) ([]byte, error) {
|
||||
if len(nonce) > o.nonceSize {
|
||||
panic("Nonce too long for this instance")
|
||||
}
|
||||
if len(ciphertext) < o.tagSize {
|
||||
return nil, ocbError("Ciphertext shorter than tag length")
|
||||
}
|
||||
sep := len(ciphertext) - o.tagSize
|
||||
ret, out := byteutil.SliceForAppend(dst, len(ciphertext))
|
||||
ciphertextData := ciphertext[:sep]
|
||||
tag := ciphertext[sep:]
|
||||
o.crypt(dec, out, nonce, adata, ciphertextData)
|
||||
if subtle.ConstantTimeCompare(ret[sep:], tag) == 1 {
|
||||
ret = ret[:sep]
|
||||
return ret, nil
|
||||
}
|
||||
for i := range out {
|
||||
out[i] = 0
|
||||
}
|
||||
return nil, ocbError("Tag authentication failed")
|
||||
}
|
||||
|
||||
// On instruction enc (resp. dec), crypt is the encrypt (resp. decrypt)
|
||||
// function. It returns the resulting plain/ciphertext with the tag appended.
|
||||
func (o *ocb) crypt(instruction int, Y, nonce, adata, X []byte) []byte {
|
||||
//
|
||||
// Consider X as a sequence of 128-bit blocks
|
||||
//
|
||||
// Note: For encryption (resp. decryption), X is the plaintext (resp., the
|
||||
// ciphertext without the tag).
|
||||
blockSize := o.block.BlockSize()
|
||||
|
||||
//
|
||||
// Nonce-dependent and per-encryption variables
|
||||
//
|
||||
// Zero out the last 6 bits of the nonce into truncatedNonce to see if Ktop
|
||||
// is already computed.
|
||||
truncatedNonce := make([]byte, len(nonce))
|
||||
copy(truncatedNonce, nonce)
|
||||
truncatedNonce[len(truncatedNonce)-1] &= 192
|
||||
Ktop := make([]byte, blockSize)
|
||||
if bytes.Equal(truncatedNonce, o.reusableKtop.noncePrefix) {
|
||||
Ktop = o.reusableKtop.Ktop
|
||||
} else {
|
||||
// Nonce = num2str(TAGLEN mod 128, 7) || zeros(120 - bitlen(N)) || 1 || N
|
||||
paddedNonce := append(make([]byte, blockSize-1-len(nonce)), 1)
|
||||
paddedNonce = append(paddedNonce, truncatedNonce...)
|
||||
paddedNonce[0] |= byte(((8 * o.tagSize) % (8 * blockSize)) << 1)
|
||||
// Last 6 bits of paddedNonce are already zero. Encrypt into Ktop
|
||||
paddedNonce[blockSize-1] &= 192
|
||||
Ktop = paddedNonce
|
||||
o.block.Encrypt(Ktop, Ktop)
|
||||
o.reusableKtop.noncePrefix = truncatedNonce
|
||||
o.reusableKtop.Ktop = Ktop
|
||||
}
|
||||
|
||||
// Stretch = Ktop || ((lower half of Ktop) XOR (lower half of Ktop << 8))
|
||||
xorHalves := make([]byte, blockSize/2)
|
||||
byteutil.XorBytes(xorHalves, Ktop[:blockSize/2], Ktop[1:1+blockSize/2])
|
||||
stretch := append(Ktop, xorHalves...)
|
||||
bottom := int(nonce[len(nonce)-1] & 63)
|
||||
offset := make([]byte, len(stretch))
|
||||
byteutil.ShiftNBytesLeft(offset, stretch, bottom)
|
||||
offset = offset[:blockSize]
|
||||
|
||||
//
|
||||
// Process any whole blocks
|
||||
//
|
||||
// Note: For encryption Y is ciphertext || tag, for decryption Y is
|
||||
// plaintext || tag.
|
||||
checksum := make([]byte, blockSize)
|
||||
m := len(X) / blockSize
|
||||
for i := 0; i < m; i++ {
|
||||
index := bits.TrailingZeros(uint(i + 1))
|
||||
if len(o.mask.L)-1 < index {
|
||||
o.mask.extendTable(index)
|
||||
}
|
||||
byteutil.XorBytesMut(offset, o.mask.L[bits.TrailingZeros(uint(i+1))])
|
||||
blockX := X[i*blockSize : (i+1)*blockSize]
|
||||
blockY := Y[i*blockSize : (i+1)*blockSize]
|
||||
byteutil.XorBytes(blockY, blockX, offset)
|
||||
switch instruction {
|
||||
case enc:
|
||||
o.block.Encrypt(blockY, blockY)
|
||||
byteutil.XorBytesMut(blockY, offset)
|
||||
byteutil.XorBytesMut(checksum, blockX)
|
||||
case dec:
|
||||
o.block.Decrypt(blockY, blockY)
|
||||
byteutil.XorBytesMut(blockY, offset)
|
||||
byteutil.XorBytesMut(checksum, blockY)
|
||||
}
|
||||
}
|
||||
//
|
||||
// Process any final partial block and compute raw tag
|
||||
//
|
||||
tag := make([]byte, blockSize)
|
||||
if len(X)%blockSize != 0 {
|
||||
byteutil.XorBytesMut(offset, o.mask.lAst)
|
||||
pad := make([]byte, blockSize)
|
||||
o.block.Encrypt(pad, offset)
|
||||
chunkX := X[blockSize*m:]
|
||||
chunkY := Y[blockSize*m : len(X)]
|
||||
byteutil.XorBytes(chunkY, chunkX, pad[:len(chunkX)])
|
||||
// P_* || bit(1) || zeroes(127) - len(P_*)
|
||||
switch instruction {
|
||||
case enc:
|
||||
paddedY := append(chunkX, byte(128))
|
||||
paddedY = append(paddedY, make([]byte, blockSize-len(chunkX)-1)...)
|
||||
byteutil.XorBytesMut(checksum, paddedY)
|
||||
case dec:
|
||||
paddedX := append(chunkY, byte(128))
|
||||
paddedX = append(paddedX, make([]byte, blockSize-len(chunkY)-1)...)
|
||||
byteutil.XorBytesMut(checksum, paddedX)
|
||||
}
|
||||
byteutil.XorBytes(tag, checksum, offset)
|
||||
byteutil.XorBytesMut(tag, o.mask.lDol)
|
||||
o.block.Encrypt(tag, tag)
|
||||
byteutil.XorBytesMut(tag, o.hash(adata))
|
||||
copy(Y[blockSize*m+len(chunkY):], tag[:o.tagSize])
|
||||
} else {
|
||||
byteutil.XorBytes(tag, checksum, offset)
|
||||
byteutil.XorBytesMut(tag, o.mask.lDol)
|
||||
o.block.Encrypt(tag, tag)
|
||||
byteutil.XorBytesMut(tag, o.hash(adata))
|
||||
copy(Y[blockSize*m:], tag[:o.tagSize])
|
||||
}
|
||||
return Y
|
||||
}
|
||||
|
||||
// This hash function is used to compute the tag. Per design, on empty input it
|
||||
// returns a slice of zeros, of the same length as the underlying block cipher
|
||||
// block size.
|
||||
func (o *ocb) hash(adata []byte) []byte {
|
||||
//
|
||||
// Consider A as a sequence of 128-bit blocks
|
||||
//
|
||||
A := make([]byte, len(adata))
|
||||
copy(A, adata)
|
||||
blockSize := o.block.BlockSize()
|
||||
|
||||
//
|
||||
// Process any whole blocks
|
||||
//
|
||||
sum := make([]byte, blockSize)
|
||||
offset := make([]byte, blockSize)
|
||||
m := len(A) / blockSize
|
||||
for i := 0; i < m; i++ {
|
||||
chunk := A[blockSize*i : blockSize*(i+1)]
|
||||
index := bits.TrailingZeros(uint(i + 1))
|
||||
// If the mask table is too short
|
||||
if len(o.mask.L)-1 < index {
|
||||
o.mask.extendTable(index)
|
||||
}
|
||||
byteutil.XorBytesMut(offset, o.mask.L[index])
|
||||
byteutil.XorBytesMut(chunk, offset)
|
||||
o.block.Encrypt(chunk, chunk)
|
||||
byteutil.XorBytesMut(sum, chunk)
|
||||
}
|
||||
|
||||
//
|
||||
// Process any final partial block; compute final hash value
|
||||
//
|
||||
if len(A)%blockSize != 0 {
|
||||
byteutil.XorBytesMut(offset, o.mask.lAst)
|
||||
// Pad block with 1 || 0 ^ 127 - bitlength(a)
|
||||
ending := make([]byte, blockSize-len(A)%blockSize)
|
||||
ending[0] = 0x80
|
||||
encrypted := append(A[blockSize*m:], ending...)
|
||||
byteutil.XorBytesMut(encrypted, offset)
|
||||
o.block.Encrypt(encrypted, encrypted)
|
||||
byteutil.XorBytesMut(sum, encrypted)
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func initializeMaskTable(block cipher.Block) mask {
|
||||
//
|
||||
// Key-dependent variables
|
||||
//
|
||||
lAst := make([]byte, block.BlockSize())
|
||||
block.Encrypt(lAst, lAst)
|
||||
lDol := byteutil.GfnDouble(lAst)
|
||||
L := make([][]byte, 1)
|
||||
L[0] = byteutil.GfnDouble(lDol)
|
||||
|
||||
return mask{
|
||||
lAst: lAst,
|
||||
lDol: lDol,
|
||||
L: L,
|
||||
}
|
||||
}
|
||||
|
||||
// Extends the L array of mask m up to L[limit], with L[i] = GfnDouble(L[i-1])
|
||||
func (m *mask) extendTable(limit int) {
|
||||
for i := len(m.L); i <= limit; i++ {
|
||||
m.L = append(m.L, byteutil.GfnDouble(m.L[i-1]))
|
||||
}
|
||||
}
|
||||
|
||||
func ocbError(err string) error {
|
||||
return errors.New("crypto/ocb: " + err)
|
||||
}
|
136
vendor/github.com/ProtonMail/go-crypto/ocb/random_vectors.go
generated
vendored
Normal file
136
vendor/github.com/ProtonMail/go-crypto/ocb/random_vectors.go
generated
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
// In the test vectors provided by RFC 7253, the "bottom"
|
||||
// internal variable, which defines "offset" for the first time, does not
|
||||
// exceed 15. However, it can attain values up to 63.
|
||||
|
||||
// These vectors include key length in {128, 192, 256}, tag size 128, and
|
||||
// random nonce, header, and plaintext lengths.
|
||||
|
||||
// This file was automatically generated.
|
||||
|
||||
package ocb
|
||||
|
||||
var randomVectors = []struct {
|
||||
key, nonce, header, plaintext, ciphertext string
|
||||
}{
|
||||
|
||||
{"9438C5D599308EAF13F800D2D31EA7F0",
|
||||
"C38EE4801BEBFFA1CD8635BE",
|
||||
"0E507B7DADD8A98CDFE272D3CB6B3E8332B56AE583FB049C0874D4200BED16BD1A044182434E9DA0E841F182DFD5B3016B34641CED0784F1745F63AB3D0DA22D3351C9EF9A658B8081E24498EBF61FCE40DA6D8E184536",
|
||||
"962D227786FB8913A8BAD5DC3250",
|
||||
"EEDEF5FFA5986D1E3BF86DDD33EF9ADC79DCA06E215FA772CCBA814F63AD"},
|
||||
{"BA7DE631C7D6712167C6724F5B9A2B1D",
|
||||
"35263EBDA05765DC0E71F1F5",
|
||||
"0103257B4224507C0242FEFE821EA7FA42E0A82863E5F8B68F7D881B4B44FA428A2B6B21D2F591260802D8AB6D83",
|
||||
"9D6D1FC93AE8A64E7889B7B2E3521EFA9B920A8DDB692E6F833DDC4A38AFA535E5E2A3ED82CB7E26404AB86C54D01C4668F28398C2DF33D5D561CBA1C8DCFA7A912F5048E545B59483C0E3221F54B14DAA2E4EB657B3BEF9554F34CAD69B2724AE962D3D8A",
|
||||
"E93852D1985C5E775655E937FA79CE5BF28A585F2AF53A5018853B9634BE3C84499AC0081918FDCE0624494D60E25F76ACD6853AC7576E3C350F332249BFCABD4E73CEABC36BE4EDDA40914E598AE74174A0D7442149B26990899491BDDFE8FC54D6C18E83AE9E9A6FFBF5D376565633862EEAD88D"},
|
||||
{"2E74B25289F6FD3E578C24866E9C72A5",
|
||||
"FD912F15025AF8414642BA1D1D",
|
||||
"FB5FB8C26F365EEDAB5FE260C6E3CCD27806729C8335F146063A7F9EA93290E56CF84576EB446350D22AD730547C267B1F0BBB97EB34E1E2C41A",
|
||||
"6C092EBF78F76EE8C1C6E592277D9545BA16EDB67BC7D8480B9827702DC2F8A129E2B08A2CE710CA7E1DA45CE162BB6CD4B512E632116E2211D3C90871EFB06B8D4B902681C7FB",
|
||||
"6AC0A77F26531BF4F354A1737F99E49BE32ECD909A7A71AD69352906F54B08A9CE9B8CA5D724CBFFC5673437F23F630697F3B84117A1431D6FA8CC13A974FB4AD360300522E09511B99E71065D5AC4BBCB1D791E864EF4"},
|
||||
{"E7EC507C802528F790AFF5303A017B17",
|
||||
"4B97A7A568940A9E3CE7A99E93031E",
|
||||
"28349BDC5A09390C480F9B8AA3EDEA3DDB8B9D64BCA322C570B8225DF0E31190DAB25A4014BA39519E02ABFB12B89AA28BBFD29E486E7FB28734258C817B63CED9912DBAFEBB93E2798AB2890DE3B0ACFCFF906AB15563EF7823CE83D27CDB251195E22BD1337BCBDE65E7C2C427321C463C2777BFE5AEAA",
|
||||
"9455B3EA706B74",
|
||||
"7F33BA3EA848D48A96B9530E26888F43EBD4463C9399B6"},
|
||||
{"6C928AA3224736F28EE7378DE0090191",
|
||||
"8936138E2E4C6A13280017A1622D",
|
||||
"6202717F2631565BDCDC57C6584543E72A7C8BD444D0D108ED35069819633C",
|
||||
"DA0691439E5F035F3E455269D14FE5C201C8C9B0A3FE2D3F86BCC59387C868FE65733D388360B31E3CE28B4BF6A8BE636706B536D5720DB66B47CF1C7A5AFD6F61E0EF90F1726D6B0E169F9A768B2B7AE4EE00A17F630AC905FCAAA1B707FFF25B3A1AAE83B504837C64A5639B2A34002B300EC035C9B43654DA55",
|
||||
"B8804D182AB0F0EEB464FA7BD1329AD6154F982013F3765FEDFE09E26DAC078C9C1439BFC1159D6C02A25E3FF83EF852570117B315852AD5EE20E0FA3AA0A626B0E43BC0CEA38B44579DD36803455FB46989B90E6D229F513FD727AF8372517E9488384C515D6067704119C931299A0982EDDFB9C2E86A90C450C077EB222511EC9CCABC9FCFDB19F70088"},
|
||||
{"ECEA315CA4B3F425B0C9957A17805EA4",
|
||||
"664CDAE18403F4F9BA13015A44FC",
|
||||
"642AFB090D6C6DB46783F08B01A3EF2A8FEB5736B531EAC226E7888FCC8505F396818F83105065FACB3267485B9E5E4A0261F621041C08FCCB2A809A49AB5252A91D0971BCC620B9D614BD77E57A0EED2FA5",
|
||||
"6852C31F8083E20E364CEA21BB7854D67CEE812FE1C9ED2425C0932A90D3780728D1BB",
|
||||
"2ECEF962A9695A463ADABB275BDA9FF8B2BA57AEC2F52EFFB700CD9271A74D2A011C24AEA946051BD6291776429B7E681BA33E"},
|
||||
{"4EE616C4A58AAA380878F71A373461F6",
|
||||
"91B8C9C176D9C385E9C47E52",
|
||||
"CDA440B7F9762C572A718AC754EDEECC119E5EE0CCB9FEA4FFB22EEE75087C032EBF3DA9CDD8A28CC010B99ED45143B41A4BA50EA2A005473F89639237838867A57F23B0F0ED3BF22490E4501DAC9C658A9B9F",
|
||||
"D6E645FA9AE410D15B8123FD757FA356A8DBE9258DDB5BE88832E615910993F497EC",
|
||||
"B70ED7BF959FB2AAED4F36174A2A99BFB16992C8CDF369C782C4DB9C73DE78C5DB8E0615F647243B97ACDB24503BC9CADC48"},
|
||||
{"DCD475773136C830D5E3D0C5FE05B7FF",
|
||||
"BB8E1FBB483BE7616A922C4A",
|
||||
"36FEF2E1CB29E76A6EA663FC3AF66ECD7404F466382F7B040AABED62293302B56E8783EF7EBC21B4A16C3E78A7483A0A403F253A2CDC5BBF79DC3DAE6C73F39A961D8FBBE8D41B",
|
||||
"441E886EA38322B2437ECA7DEB5282518865A66780A454E510878E61BFEC3106A3CD93D2A02052E6F9E1832F9791053E3B76BF4C07EFDD6D4106E3027FABB752E60C1AA425416A87D53938163817A1051EBA1D1DEEB4B9B25C7E97368B52E5911A31810B0EC5AF547559B6142D9F4C4A6EF24A4CF75271BF9D48F62B",
|
||||
"1BE4DD2F4E25A6512C2CC71D24BBB07368589A94C2714962CD0ACE5605688F06342587521E75F0ACAFFD86212FB5C34327D238DB36CF2B787794B9A4412E7CD1410EA5DDD2450C265F29CF96013CD213FD2880657694D718558964BC189B4A84AFCF47EB012935483052399DBA5B088B0A0477F20DFE0E85DCB735E21F22A439FB837DD365A93116D063E607"},
|
||||
{"3FBA2B3D30177FFE15C1C59ED2148BB2C091F5615FBA7C07",
|
||||
"FACF804A4BEBF998505FF9DE",
|
||||
"8213B9263B2971A5BDA18DBD02208EE1",
|
||||
"15B323926993B326EA19F892D704439FC478828322AF72118748284A1FD8A6D814E641F70512FD706980337379F31DC63355974738D7FEA87AD2858C0C2EBBFBE74371C21450072373C7B651B334D7C4D43260B9D7CCD3AF9EDB",
|
||||
"6D35DC1469B26E6AAB26272A41B46916397C24C485B61162E640A062D9275BC33DDCFD3D9E1A53B6C8F51AC89B66A41D59B3574197A40D9B6DCF8A4E2A001409C8112F16B9C389E0096179DB914E05D6D11ED0005AD17E1CE105A2F0BAB8F6B1540DEB968B7A5428FF44"},
|
||||
{"53B52B8D4D748BCDF1DDE68857832FA46227FA6E2F32EFA1",
|
||||
"0B0EF53D4606B28D1398355F",
|
||||
"F23882436349094AF98BCACA8218E81581A043B19009E28EFBF2DE37883E04864148CC01D240552CA8844EC1456F42034653067DA67E80F87105FD06E14FF771246C9612867BE4D215F6D761",
|
||||
"F15030679BD4088D42CAC9BF2E9606EAD4798782FA3ED8C57EBE7F84A53236F51B25967C6489D0CD20C9EEA752F9BC",
|
||||
"67B96E2D67C3729C96DAEAEDF821D61C17E648643A2134C5621FEC621186915AD80864BFD1EB5B238BF526A679385E012A457F583AFA78134242E9D9C1B4E4"},
|
||||
{"0272DD80F23399F49BFC320381A5CD8225867245A49A7D41",
|
||||
"5C83F4896D0738E1366B1836",
|
||||
"69B0337289B19F73A12BAEEA857CCAF396C11113715D9500CCCF48BA08CFF12BC8B4BADB3084E63B85719DB5058FA7C2C11DEB096D7943CFA7CAF5",
|
||||
"C01AD10FC8B562CD17C7BC2FAB3E26CBDFF8D7F4DEA816794BBCC12336991712972F52816AABAB244EB43B0137E2BAC1DD413CE79531E78BEF782E6B439612BB3AEF154DE3502784F287958EBC159419F9EBA27916A28D6307324129F506B1DE80C1755A929F87",
|
||||
"FEFE52DD7159C8DD6E8EC2D3D3C0F37AB6CB471A75A071D17EC4ACDD8F3AA4D7D4F7BB559F3C09099E3D9003E5E8AA1F556B79CECDE66F85B08FA5955E6976BF2695EA076388A62D2AD5BAB7CBF1A7F3F4C8D5CDF37CDE99BD3E30B685D9E5EEE48C7C89118EF4878EB89747F28271FA2CC45F8E9E7601"},
|
||||
{"3EEAED04A455D6E5E5AB53CFD5AFD2F2BC625C7BF4BE49A5",
|
||||
"36B88F63ADBB5668588181D774",
|
||||
"D367E3CB3703E762D23C6533188EF7028EFF9D935A3977150361997EC9DEAF1E4794BDE26AA8B53C124980B1362EC86FCDDFC7A90073171C1BAEE351A53234B86C66E8AB92FAE99EC6967A6D3428892D80",
|
||||
"573454C719A9A55E04437BF7CBAAF27563CCCD92ADD5E515CD63305DFF0687E5EEF790C5DCA5C0033E9AB129505E2775438D92B38F08F3B0356BA142C6F694",
|
||||
"E9F79A5B432D9E682C9AAA5661CFC2E49A0FCB81A431E54B42EB73DD3BED3F377FEC556ABA81624BA64A5D739AD41467460088F8D4F442180A9382CA635745473794C382FCDDC49BA4EB6D8A44AE3C"},
|
||||
{"B695C691538F8CBD60F039D0E28894E3693CC7C36D92D79D",
|
||||
"BC099AEB637361BAC536B57618",
|
||||
"BFFF1A65AE38D1DC142C71637319F5F6508E2CB33C9DCB94202B359ED5A5ED8042E7F4F09231D32A7242976677E6F4C549BF65FADC99E5AF43F7A46FD95E16C2",
|
||||
"081DF3FD85B415D803F0BE5AC58CFF0023FDDED99788296C3731D8",
|
||||
"E50C64E3614D94FE69C47092E46ACC9957C6FEA2CCBF96BC62FBABE7424753C75F9C147C42AE26FE171531"},
|
||||
{"C9ACBD2718F0689A1BE9802A551B6B8D9CF5614DAF5E65ED",
|
||||
"B1B0AAF373B8B026EB80422051D8",
|
||||
"6648C0E61AC733C76119D23FB24548D637751387AA2EAE9D80E912B7BD486CAAD9EAF4D7A5FE2B54AAD481E8EC94BB4D558000896E2010462B70C9FED1E7273080D1",
|
||||
"189F591F6CB6D59AFEDD14C341741A8F1037DC0DF00FC57CE65C30F49E860255CEA5DC6019380CC0FE8880BC1A9E685F41C239C38F36E3F2A1388865C5C311059C0A",
|
||||
"922A5E949B61D03BE34AB5F4E58607D4504EA14017BB363DAE3C873059EA7A1C77A746FB78981671D26C2CF6D9F24952D510044CE02A10177E9DB42D0145211DFE6E84369C5E3BC2669EAB4147B2822895F9"},
|
||||
{"7A832BD2CF5BF4919F353CE2A8C86A5E406DA2D52BE16A72",
|
||||
"2F2F17CECF7E5A756D10785A3CB9DB",
|
||||
"61DA05E3788CC2D8405DBA70C7A28E5AF699863C9F72E6C6770126929F5D6FA267F005EBCF49495CB46400958A3AE80D1289D1C671",
|
||||
"44E91121195A41AF14E8CFDBD39A4B517BE0DF1A72977ED8A3EEF8EEDA1166B2EB6DB2C4AE2E74FA0F0C74537F659BFBD141E5DDEC67E64EDA85AABD3F52C85A785B9FB3CECD70E7DF",
|
||||
"BEDF596EA21288D2B84901E188F6EE1468B14D5161D3802DBFE00D60203A24E2AB62714BF272A45551489838C3A7FEAADC177B591836E73684867CCF4E12901DCF2064058726BBA554E84ADC5136F507E961188D4AF06943D3"},
|
||||
{"1508E8AE9079AA15F1CEC4F776B4D11BCCB061B58AA56C18",
|
||||
"BCA625674F41D1E3AB47672DC0C3",
|
||||
"8B12CF84F16360F0EAD2A41BC021530FFCEC7F3579CAE658E10E2D3D81870F65AFCED0C77C6C4C6E6BA424FF23088C796BA6195ABA35094BF1829E089662E7A95FC90750AE16D0C8AFA55DAC789D7735B970B58D4BE7CEC7341DA82A0179A01929C27A59C5063215B859EA43",
|
||||
"E525422519ECE070E82C",
|
||||
"B47BC07C3ED1C0A43BA52C43CBACBCDBB29CAF1001E09FDF7107"},
|
||||
{"7550C2761644E911FE9ADD119BAC07376BEA442845FEAD876D7E7AC1B713E464",
|
||||
"36D2EC25ADD33CDEDF495205BBC923",
|
||||
"7FCFE81A3790DE97FFC3DE160C470847EA7E841177C2F759571CBD837EA004A6CA8C6F4AEBFF2E9FD552D73EB8A30705D58D70C0B67AEEA280CBBF0A477358ACEF1E7508F2735CD9A0E4F9AC92B8C008F575D3B6278F1C18BD01227E3502E5255F3AB1893632AD00C717C588EF652A51A43209E7EE90",
|
||||
"2B1A62F8FDFAA3C16470A21AD307C9A7D03ADE8EF72C69B06F8D738CDE578D7AEFD0D40BD9C022FB9F580DF5394C998ACCCEFC5471A3996FB8F1045A81FDC6F32D13502EA65A211390C8D882B8E0BEFD8DD8CBEF51D1597B124E9F7F",
|
||||
"C873E02A22DB89EB0787DB6A60B99F7E4A0A085D5C4232A81ADCE2D60AA36F92DDC33F93DD8640AC0E08416B187FB382B3EC3EE85A64B0E6EE41C1366A5AD2A282F66605E87031CCBA2FA7B2DA201D975994AADE3DD1EE122AE09604AD489B84BF0C1AB7129EE16C6934850E"},
|
||||
{"A51300285E554FDBDE7F771A9A9A80955639DD87129FAEF74987C91FB9687C71",
|
||||
"81691D5D20EC818FCFF24B33DECC",
|
||||
"C948093218AA9EB2A8E44A87EEA73FC8B6B75A196819A14BD83709EA323E8DF8B491045220E1D88729A38DBCFFB60D3056DAD4564498FD6574F74512945DEB34B69329ACED9FFC05D5D59DFCD5B973E2ACAFE6AD1EF8BBBC49351A2DD12508ED89ED",
|
||||
"EB861165DAF7625F827C6B574ED703F03215",
|
||||
"C6CD1CE76D2B3679C1B5AA1CFD67CCB55444B6BFD3E22C81CBC9BB738796B83E54E3"},
|
||||
{"8CE0156D26FAEB7E0B9B800BBB2E9D4075B5EAC5C62358B0E7F6FCE610223282",
|
||||
"D2A7B94DD12CDACA909D3AD7",
|
||||
"E021A78F374FC271389AB9A3E97077D755",
|
||||
"7C26000B58929F5095E1CEE154F76C2A299248E299F9B5ADE6C403AA1FD4A67FD4E0232F214CE7B919EE7A1027D2B76C57475715CD078461",
|
||||
"C556FB38DF069B56F337B5FF5775CE6EAA16824DFA754F20B78819028EA635C3BB7AA731DE8776B2DCB67DCA2D33EEDF3C7E52EA450013722A41755A0752433ED17BDD5991AAE77A"},
|
||||
{"1E8000A2CE00A561C9920A30BF0D7B983FEF8A1014C8F04C35CA6970E6BA02BD",
|
||||
"65ED3D63F79F90BBFD19775E",
|
||||
"336A8C0B7243582A46B221AA677647FCAE91",
|
||||
"134A8B34824A290E7B",
|
||||
"914FBEF80D0E6E17F8BDBB6097EBF5FBB0554952DC2B9E5151"},
|
||||
{"53D5607BBE690B6E8D8F6D97F3DF2BA853B682597A214B8AA0EA6E598650AF15",
|
||||
"C391A856B9FE234E14BA1AC7BB40FF",
|
||||
"479682BC21349C4BE1641D5E78FE2C79EC1B9CF5470936DCAD9967A4DCD7C4EFADA593BC9EDE71E6A08829B8580901B61E274227E9D918502DE3",
|
||||
"EAD154DC09C5E26C5D26FF33ED148B27120C7F2C23225CC0D0631B03E1F6C6D96FEB88C1A4052ACB4CE746B884B6502931F407021126C6AAB8C514C077A5A38438AE88EE",
|
||||
"938821286EBB671D999B87C032E1D6055392EB564E57970D55E545FC5E8BAB90E6E3E3C0913F6320995FC636D72CD9919657CC38BD51552F4A502D8D1FE56DB33EBAC5092630E69EBB986F0E15CEE9FC8C052501"},
|
||||
{"294362FCC984F440CEA3E9F7D2C06AF20C53AAC1B3738CA2186C914A6E193ABB",
|
||||
"B15B61C8BB39261A8F55AB178EC3",
|
||||
"D0729B6B75BB",
|
||||
"2BD089ADCE9F334BAE3B065996C7D616DD0C27DF4218DCEEA0FBCA0F968837CE26B0876083327E25681FDDD620A32EC0DA12F73FAE826CC94BFF2B90A54D2651",
|
||||
"AC94B25E4E21DE2437B806966CCD5D9385EF0CD4A51AB9FA6DE675C7B8952D67802E9FEC1FDE9F5D1EAB06057498BC0EEA454804FC9D2068982A3E24182D9AC2E7AB9994DDC899A604264583F63D066B"},
|
||||
{"959DBFEB039B1A5B8CE6A44649B602AAA5F98A906DB96143D202CD2024F749D9",
|
||||
"01D7BDB1133E9C347486C1EFA6",
|
||||
"F3843955BD741F379DD750585EDC55E2CDA05CCBA8C1F4622AC2FE35214BC3A019B8BD12C4CC42D9213D1E1556941E8D8450830287FFB3B763A13722DD4140ED9846FB5FFF745D7B0B967D810A068222E10B259AF1D392035B0D83DC1498A6830B11B2418A840212599171E0258A1C203B05362978",
|
||||
"A21811232C950FA8B12237C2EBD6A7CD2C3A155905E9E0C7C120",
|
||||
"63C1CE397B22F1A03F1FA549B43178BC405B152D3C95E977426D519B3DFCA28498823240592B6EEE7A14"},
|
||||
{"096AE499F5294173F34FF2B375F0E5D5AB79D0D03B33B1A74D7D576826345DF4",
|
||||
"0C52B3D11D636E5910A4DD76D32C",
|
||||
"229E9ECA3053789E937447BC719467075B6138A142DA528DA8F0CF8DDF022FD9AF8E74779BA3AC306609",
|
||||
"8B7A00038783E8BAF6EDEAE0C4EAB48FC8FD501A588C7E4A4DB71E3604F2155A97687D3D2FFF8569261375A513CF4398CE0F87CA1658A1050F6EF6C4EA3E25",
|
||||
"C20B6CF8D3C8241825FD90B2EDAC7593600646E579A8D8DAAE9E2E40C3835FE801B2BE4379131452BC5182C90307B176DFBE2049544222FE7783147B690774F6D9D7CEF52A91E61E298E9AA15464AC"},
|
||||
}
|
78
vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_a.go
generated
vendored
Normal file
78
vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_a.go
generated
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
package ocb
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
// Test vectors from https://tools.ietf.org/html/rfc7253. Note that key is
|
||||
// shared across tests.
|
||||
var testKey, _ = hex.DecodeString("000102030405060708090A0B0C0D0E0F")
|
||||
|
||||
var rfc7253testVectors = []struct {
|
||||
nonce, header, plaintext, ciphertext string
|
||||
}{
|
||||
{"BBAA99887766554433221100",
|
||||
"",
|
||||
"",
|
||||
"785407BFFFC8AD9EDCC5520AC9111EE6"},
|
||||
{"BBAA99887766554433221101",
|
||||
"0001020304050607",
|
||||
"0001020304050607",
|
||||
"6820B3657B6F615A5725BDA0D3B4EB3A257C9AF1F8F03009"},
|
||||
{"BBAA99887766554433221102",
|
||||
"0001020304050607",
|
||||
"",
|
||||
"81017F8203F081277152FADE694A0A00"},
|
||||
{"BBAA99887766554433221103",
|
||||
"",
|
||||
"0001020304050607",
|
||||
"45DD69F8F5AAE72414054CD1F35D82760B2CD00D2F99BFA9"},
|
||||
{"BBAA99887766554433221104",
|
||||
"000102030405060708090A0B0C0D0E0F",
|
||||
"000102030405060708090A0B0C0D0E0F",
|
||||
"571D535B60B277188BE5147170A9A22C3AD7A4FF3835B8C5701C1CCEC8FC3358"},
|
||||
{"BBAA99887766554433221105",
|
||||
"000102030405060708090A0B0C0D0E0F",
|
||||
"",
|
||||
"8CF761B6902EF764462AD86498CA6B97"},
|
||||
{"BBAA99887766554433221106",
|
||||
"",
|
||||
"000102030405060708090A0B0C0D0E0F",
|
||||
"5CE88EC2E0692706A915C00AEB8B2396F40E1C743F52436BDF06D8FA1ECA343D"},
|
||||
{"BBAA99887766554433221107",
|
||||
"000102030405060708090A0B0C0D0E0F1011121314151617",
|
||||
"000102030405060708090A0B0C0D0E0F1011121314151617",
|
||||
"1CA2207308C87C010756104D8840CE1952F09673A448A122C92C62241051F57356D7F3C90BB0E07F"},
|
||||
{"BBAA99887766554433221108",
|
||||
"000102030405060708090A0B0C0D0E0F1011121314151617",
|
||||
"",
|
||||
"6DC225A071FC1B9F7C69F93B0F1E10DE"},
|
||||
{"BBAA99887766554433221109",
|
||||
"",
|
||||
"000102030405060708090A0B0C0D0E0F1011121314151617",
|
||||
"221BD0DE7FA6FE993ECCD769460A0AF2D6CDED0C395B1C3CE725F32494B9F914D85C0B1EB38357FF"},
|
||||
{"BBAA9988776655443322110A",
|
||||
"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
|
||||
"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
|
||||
"BD6F6C496201C69296C11EFD138A467ABD3C707924B964DEAFFC40319AF5A48540FBBA186C5553C68AD9F592A79A4240"},
|
||||
{"BBAA9988776655443322110B",
|
||||
"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
|
||||
"",
|
||||
"FE80690BEE8A485D11F32965BC9D2A32"},
|
||||
{"BBAA9988776655443322110C",
|
||||
"",
|
||||
"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
|
||||
"2942BFC773BDA23CABC6ACFD9BFD5835BD300F0973792EF46040C53F1432BCDFB5E1DDE3BC18A5F840B52E653444D5DF"},
|
||||
{"BBAA9988776655443322110D",
|
||||
"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
|
||||
"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
|
||||
"D5CA91748410C1751FF8A2F618255B68A0A12E093FF454606E59F9C1D0DDC54B65E8628E568BAD7AED07BA06A4A69483A7035490C5769E60"},
|
||||
{"BBAA9988776655443322110E",
|
||||
"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
|
||||
"",
|
||||
"C5CD9D1850C141E358649994EE701B68"},
|
||||
{"BBAA9988776655443322110F",
|
||||
"",
|
||||
"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
|
||||
"4412923493C57D5DE0D700F753CCE0D1D2D95060122E9F15A5DDBFC5787E50B5CC55EE507BCB084E479AD363AC366B95A98CA5F3000B1479"},
|
||||
}
|
24
vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_b.go
generated
vendored
Normal file
24
vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_b.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
package ocb
|
||||
|
||||
// Second set of test vectors from https://tools.ietf.org/html/rfc7253
|
||||
var rfc7253TestVectorTaglen96 = struct {
|
||||
key, nonce, header, plaintext, ciphertext string
|
||||
}{"0F0E0D0C0B0A09080706050403020100",
|
||||
"BBAA9988776655443322110D",
|
||||
"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
|
||||
"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
|
||||
"1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1A0124B0A55BAE884ED93481529C76B6AD0C515F4D1CDD4FDAC4F02AA"}
|
||||
|
||||
var rfc7253AlgorithmTest = []struct {
|
||||
KEYLEN, TAGLEN int
|
||||
OUTPUT string }{
|
||||
{128, 128, "67E944D23256C5E0B6C61FA22FDF1EA2"},
|
||||
{192, 128, "F673F2C3E7174AAE7BAE986CA9F29E17"},
|
||||
{256, 128, "D90EB8E9C977C88B79DD793D7FFA161C"},
|
||||
{128, 96, "77A3D8E73589158D25D01209"},
|
||||
{192, 96, "05D56EAD2752C86BE6932C5E"},
|
||||
{256, 96, "5458359AC23B0CBA9E6330DD"},
|
||||
{128, 64, "192C9B7BD90BA06A"},
|
||||
{192, 64, "0066BC6E0EF34E24"},
|
||||
{256, 64, "7D4EA5D445501CBE"},
|
||||
}
|
153
vendor/github.com/ProtonMail/go-crypto/openpgp/aes/keywrap/keywrap.go
generated
vendored
Normal file
153
vendor/github.com/ProtonMail/go-crypto/openpgp/aes/keywrap/keywrap.go
generated
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
// Copyright 2014 Matthew Endsley
|
||||
// All rights reserved
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted providing that the following conditions
|
||||
// are met:
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Package keywrap is an implementation of the RFC 3394 AES key wrapping
|
||||
// algorithm. This is used in OpenPGP with elliptic curve keys.
|
||||
package keywrap
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrWrapPlaintext is returned if the plaintext is not a multiple
|
||||
// of 64 bits.
|
||||
ErrWrapPlaintext = errors.New("keywrap: plainText must be a multiple of 64 bits")
|
||||
|
||||
// ErrUnwrapCiphertext is returned if the ciphertext is not a
|
||||
// multiple of 64 bits.
|
||||
ErrUnwrapCiphertext = errors.New("keywrap: cipherText must by a multiple of 64 bits")
|
||||
|
||||
// ErrUnwrapFailed is returned if unwrapping a key fails.
|
||||
ErrUnwrapFailed = errors.New("keywrap: failed to unwrap key")
|
||||
|
||||
// NB: the AES NewCipher call only fails if the key is an invalid length.
|
||||
|
||||
// ErrInvalidKey is returned when the AES key is invalid.
|
||||
ErrInvalidKey = errors.New("keywrap: invalid AES key")
|
||||
)
|
||||
|
||||
// Wrap a key using the RFC 3394 AES Key Wrap Algorithm.
|
||||
func Wrap(key, plainText []byte) ([]byte, error) {
|
||||
if len(plainText)%8 != 0 {
|
||||
return nil, ErrWrapPlaintext
|
||||
}
|
||||
|
||||
c, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, ErrInvalidKey
|
||||
}
|
||||
|
||||
nblocks := len(plainText) / 8
|
||||
|
||||
// 1) Initialize variables.
|
||||
var block [aes.BlockSize]byte
|
||||
// - Set A = IV, an initial value (see 2.2.3)
|
||||
for ii := 0; ii < 8; ii++ {
|
||||
block[ii] = 0xA6
|
||||
}
|
||||
|
||||
// - For i = 1 to n
|
||||
// - Set R[i] = P[i]
|
||||
intermediate := make([]byte, len(plainText))
|
||||
copy(intermediate, plainText)
|
||||
|
||||
// 2) Calculate intermediate values.
|
||||
for ii := 0; ii < 6; ii++ {
|
||||
for jj := 0; jj < nblocks; jj++ {
|
||||
// - B = AES(K, A | R[i])
|
||||
copy(block[8:], intermediate[jj*8:jj*8+8])
|
||||
c.Encrypt(block[:], block[:])
|
||||
|
||||
// - A = MSB(64, B) ^ t where t = (n*j)+1
|
||||
t := uint64(ii*nblocks + jj + 1)
|
||||
val := binary.BigEndian.Uint64(block[:8]) ^ t
|
||||
binary.BigEndian.PutUint64(block[:8], val)
|
||||
|
||||
// - R[i] = LSB(64, B)
|
||||
copy(intermediate[jj*8:jj*8+8], block[8:])
|
||||
}
|
||||
}
|
||||
|
||||
// 3) Output results.
|
||||
// - Set C[0] = A
|
||||
// - For i = 1 to n
|
||||
// - C[i] = R[i]
|
||||
return append(block[:8], intermediate...), nil
|
||||
}
|
||||
|
||||
// Unwrap a key using the RFC 3394 AES Key Wrap Algorithm.
|
||||
func Unwrap(key, cipherText []byte) ([]byte, error) {
|
||||
if len(cipherText)%8 != 0 {
|
||||
return nil, ErrUnwrapCiphertext
|
||||
}
|
||||
|
||||
c, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, ErrInvalidKey
|
||||
}
|
||||
|
||||
nblocks := len(cipherText)/8 - 1
|
||||
|
||||
// 1) Initialize variables.
|
||||
var block [aes.BlockSize]byte
|
||||
// - Set A = C[0]
|
||||
copy(block[:8], cipherText[:8])
|
||||
|
||||
// - For i = 1 to n
|
||||
// - Set R[i] = C[i]
|
||||
intermediate := make([]byte, len(cipherText)-8)
|
||||
copy(intermediate, cipherText[8:])
|
||||
|
||||
// 2) Compute intermediate values.
|
||||
for jj := 5; jj >= 0; jj-- {
|
||||
for ii := nblocks - 1; ii >= 0; ii-- {
|
||||
// - B = AES-1(K, (A ^ t) | R[i]) where t = n*j+1
|
||||
// - A = MSB(64, B)
|
||||
t := uint64(jj*nblocks + ii + 1)
|
||||
val := binary.BigEndian.Uint64(block[:8]) ^ t
|
||||
binary.BigEndian.PutUint64(block[:8], val)
|
||||
|
||||
copy(block[8:], intermediate[ii*8:ii*8+8])
|
||||
c.Decrypt(block[:], block[:])
|
||||
|
||||
// - R[i] = LSB(B, 64)
|
||||
copy(intermediate[ii*8:ii*8+8], block[8:])
|
||||
}
|
||||
}
|
||||
|
||||
// 3) Output results.
|
||||
// - If A is an appropriate initial value (see 2.2.3),
|
||||
for ii := 0; ii < 8; ii++ {
|
||||
if block[ii] != 0xA6 {
|
||||
return nil, ErrUnwrapFailed
|
||||
}
|
||||
}
|
||||
|
||||
// - For i = 1 to n
|
||||
// - P[i] = R[i]
|
||||
return intermediate, nil
|
||||
}
|
@ -4,33 +4,25 @@
|
||||
|
||||
// Package armor implements OpenPGP ASCII Armor, see RFC 4880. OpenPGP Armor is
|
||||
// very similar to PEM except that it has an additional CRC checksum.
|
||||
//
|
||||
// Deprecated: this package is unmaintained except for security fixes. New
|
||||
// applications should consider a more focused, modern alternative to OpenPGP
|
||||
// for their specific task. If you are required to interoperate with OpenPGP
|
||||
// systems and need a maintained package, consider a community fork.
|
||||
// See https://golang.org/issue/44226.
|
||||
package armor // import "golang.org/x/crypto/openpgp/armor"
|
||||
package armor // import "github.com/ProtonMail/go-crypto/openpgp/armor"
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"golang.org/x/crypto/openpgp/errors"
|
||||
"github.com/ProtonMail/go-crypto/openpgp/errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
// A Block represents an OpenPGP armored structure.
|
||||
//
|
||||
// The encoded form is:
|
||||
// -----BEGIN Type-----
|
||||
// Headers
|
||||
//
|
||||
// -----BEGIN Type-----
|
||||
// Headers
|
||||
//
|
||||
// base64-encoded Bytes
|
||||
// '=' base64 encoded checksum
|
||||
// -----END Type-----
|
||||
//
|
||||
// base64-encoded Bytes
|
||||
// '=' base64 encoded checksum
|
||||
// -----END Type-----
|
||||
// where Headers is a possibly empty sequence of Key: Value lines.
|
||||
//
|
||||
// Since the armored data can be very large, this package presents a streaming
|
@ -96,8 +96,7 @@ func (l *lineBreaker) Close() (err error) {
|
||||
// trailer.
|
||||
//
|
||||
// It's built into a stack of io.Writers:
|
||||
//
|
||||
// encoding -> base64 encoder -> lineBreaker -> out
|
||||
// encoding -> base64 encoder -> lineBreaker -> out
|
||||
type encoding struct {
|
||||
out io.Writer
|
||||
breaker *lineBreaker
|
@ -4,7 +4,10 @@
|
||||
|
||||
package openpgp
|
||||
|
||||
import "hash"
|
||||
import (
|
||||
"hash"
|
||||
"io"
|
||||
)
|
||||
|
||||
// NewCanonicalTextHash reformats text written to it into the canonical
|
||||
// form and then applies the hash h. See RFC 4880, section 5.2.1.
|
||||
@ -19,28 +22,31 @@ type canonicalTextHash struct {
|
||||
|
||||
var newline = []byte{'\r', '\n'}
|
||||
|
||||
func (cth *canonicalTextHash) Write(buf []byte) (int, error) {
|
||||
func writeCanonical(cw io.Writer, buf []byte, s *int) (int, error) {
|
||||
start := 0
|
||||
|
||||
for i, c := range buf {
|
||||
switch cth.s {
|
||||
switch *s {
|
||||
case 0:
|
||||
if c == '\r' {
|
||||
cth.s = 1
|
||||
*s = 1
|
||||
} else if c == '\n' {
|
||||
cth.h.Write(buf[start:i])
|
||||
cth.h.Write(newline)
|
||||
cw.Write(buf[start:i])
|
||||
cw.Write(newline)
|
||||
start = i + 1
|
||||
}
|
||||
case 1:
|
||||
cth.s = 0
|
||||
*s = 0
|
||||
}
|
||||
}
|
||||
|
||||
cth.h.Write(buf[start:])
|
||||
cw.Write(buf[start:])
|
||||
return len(buf), nil
|
||||
}
|
||||
|
||||
func (cth *canonicalTextHash) Write(buf []byte) (int, error) {
|
||||
return writeCanonical(cth.h, buf, &cth.s)
|
||||
}
|
||||
|
||||
func (cth *canonicalTextHash) Sum(in []byte) []byte {
|
||||
return cth.h.Sum(in)
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user