Compare commits
102 Commits
0.11.0-bet
...
fix/deps
| Author | SHA1 | Date | |
|---|---|---|---|
|
45af67d22d
|
|||
|
db7c4042d0
|
|||
|
ed1a66dc5f
|
|||
|
bb93e4266a
|
|||
|
a2cc70b2f5
|
|||
|
ce1aa3d870
|
|||
|
d75700c8a9
|
|||
|
0ccc4aae72
|
|||
|
ec22d5d51d
|
|||
|
ab42584d05
|
|||
| 40eb6e9a18 | |||
| 35eb9d4a89 | |||
|
08cc63d523
|
|||
| 797b8d899b | |||
|
fb786306b5
|
|||
| c3a2048eba | |||
| 1bdc11ba62 | |||
| cc8703310c | |||
|
fcd5bd863d
|
|||
|
e6af2da9dd
|
|||
| 4b688825e0 | |||
| b0cf2a1f8e | |||
| 6b7020d457 | |||
| efdac610bd | |||
| cd6021f116 | |||
| ee8de8ef5c | |||
|
e5a653c002
|
|||
|
2cca04de90
|
|||
| f2f79e2df8 | |||
|
dd83741a9f
|
|||
|
dc2cd85d91
|
|||
|
96e59cf196
|
|||
|
11656c009d
|
|||
|
e4e1b58501
|
|||
|
3b8f12643c
|
|||
|
e5f5154197
|
|||
|
6c1c0a8a8a
|
|||
| 662f45008c | |||
|
708c5f5223
|
|||
| d58552b748 | |||
|
51fe809851
|
|||
| 3f6a22747f | |||
|
4e75b96914
|
|||
| fd4ee75ab7 | |||
|
964ed834ee
|
|||
| fcb3167394 | |||
|
3845b40aa3
|
|||
| 0dc5c307af | |||
| fc5855ff28 | |||
|
5b504a1550
|
|||
| fc16a21f1c | |||
|
7b4d2d7230
|
|||
|
d0ccb805c6
|
|||
|
2460dd9438
|
|||
| 9c648a2566 | |||
|
22ecfb9c4c
|
|||
|
9f3cf718be
|
|||
|
b737ce2107
|
|||
|
a3d0ece7cb
|
|||
|
d63a1c28ea
|
|||
| 1c10e64c58 | |||
|
21826ec555
|
|||
|
4b4c56d406
|
|||
|
4314195dd7
|
|||
| df4447b038 | |||
|
3fa660e579
|
|||
|
a430b1e4fd
|
|||
| 896c434f38 | |||
|
847b7238c5
|
|||
|
89d5fc91b0
|
|||
| 5af3c5f56e | |||
|
beb3864b2d
|
|||
|
581e6ef538
|
|||
|
fd642ddb84
|
|||
|
1ad8c127d9
|
|||
| 40aab6a6c1 | |||
|
4d33a24a07
|
|||
|
ee59eb350b
|
|||
|
5da13ff15a
|
|||
|
491c594ad3
|
|||
|
c794d533be
|
|||
|
a6daf7030e
|
|||
|
fe3b7ffa9c
|
|||
|
4c066a92d8
|
|||
|
7899b57781
|
|||
|
6e0a901887
|
|||
|
713fdebc90
|
|||
|
6944d138c6
|
|||
|
fbb1f16470
|
|||
|
2473cafdf5
|
|||
| 0ccfbd253e | |||
|
6c4bee0ac7
|
|||
| 4fa9f536eb | |||
|
033c9bfc13
|
|||
| 0db1ee87fc | |||
|
d180bb924f
|
|||
|
d50d68d95a
|
|||
|
f468bc7443
|
|||
|
dee2d9d104
|
|||
|
5c892b1d6a
|
|||
|
81b96fc7b1
|
|||
| c92a0d0703 |
@ -4,5 +4,4 @@
|
|||||||
Dockerfile
|
Dockerfile
|
||||||
abra
|
abra
|
||||||
dist
|
dist
|
||||||
kadabra
|
|
||||||
tags
|
tags
|
||||||
|
|||||||
@ -11,10 +11,15 @@ steps:
|
|||||||
image: git.coopcloud.tech/toolshed/drone-xgettext-go:latest
|
image: git.coopcloud.tech/toolshed/drone-xgettext-go:latest
|
||||||
settings:
|
settings:
|
||||||
keyword: i18n.G
|
keyword: i18n.G
|
||||||
|
keyword_ctx: i18n.GC
|
||||||
out: pkg/i18n/locales/abra.pot
|
out: pkg/i18n/locales/abra.pot
|
||||||
comments_tag: translators
|
comments_tag: translators
|
||||||
depends_on:
|
depends_on:
|
||||||
- make check
|
- make check
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
exclude:
|
||||||
|
- tag
|
||||||
|
|
||||||
- name: xgettext-go status
|
- name: xgettext-go status
|
||||||
image: golang:1.24-alpine3.22
|
image: golang:1.24-alpine3.22
|
||||||
@ -27,6 +32,10 @@ steps:
|
|||||||
- git diff-files --exit-code
|
- git diff-files --exit-code
|
||||||
depends_on:
|
depends_on:
|
||||||
- xgettext-go
|
- xgettext-go
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
exclude:
|
||||||
|
- tag
|
||||||
|
|
||||||
- name: make test
|
- name: make test
|
||||||
image: golang:1.24
|
image: golang:1.24
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,6 +4,6 @@
|
|||||||
.envrc
|
.envrc
|
||||||
.vscode/
|
.vscode/
|
||||||
/abra
|
/abra
|
||||||
/kadabra
|
/bin
|
||||||
dist/
|
dist/
|
||||||
tests/integration/.bats
|
tests/integration/.bats
|
||||||
|
|||||||
@ -32,31 +32,6 @@ builds:
|
|||||||
- "-s"
|
- "-s"
|
||||||
- "-w"
|
- "-w"
|
||||||
|
|
||||||
- id: kadabra
|
|
||||||
binary: kadabra
|
|
||||||
dir: cmd/kadabra
|
|
||||||
env:
|
|
||||||
- CGO_ENABLED=0
|
|
||||||
goos:
|
|
||||||
- linux
|
|
||||||
- darwin
|
|
||||||
goarch:
|
|
||||||
- 386
|
|
||||||
- amd64
|
|
||||||
- arm
|
|
||||||
- arm64
|
|
||||||
goarm:
|
|
||||||
- 5
|
|
||||||
- 6
|
|
||||||
- 7
|
|
||||||
gcflags:
|
|
||||||
- "all=-l -B"
|
|
||||||
ldflags:
|
|
||||||
- "-X 'main.Commit={{ .Commit }}'"
|
|
||||||
- "-X 'main.Version={{ .Version }}'"
|
|
||||||
- "-s"
|
|
||||||
- "-w"
|
|
||||||
|
|
||||||
checksum:
|
checksum:
|
||||||
name_template: "checksums.txt"
|
name_template: "checksums.txt"
|
||||||
|
|
||||||
|
|||||||
39
Makefile
39
Makefile
@ -1,5 +1,5 @@
|
|||||||
ABRA := ./cmd/abra
|
ABRA := ./cmd/abra
|
||||||
KADABRA := ./cmd/kadabra
|
XGETTEXT := ./bin/xgettext-go
|
||||||
COMMIT := $(shell git rev-list -1 HEAD)
|
COMMIT := $(shell git rev-list -1 HEAD)
|
||||||
GOPATH := $(shell go env GOPATH)
|
GOPATH := $(shell go env GOPATH)
|
||||||
GOVERSION := 1.24
|
GOVERSION := 1.24
|
||||||
@ -13,40 +13,23 @@ LINGUAS := $(basename $(POFILES))
|
|||||||
|
|
||||||
export GOPRIVATE=coopcloud.tech
|
export GOPRIVATE=coopcloud.tech
|
||||||
|
|
||||||
# NOTE(d1): default `make` optimised for Abra hacking
|
all: format check build
|
||||||
all: format check build-abra test
|
|
||||||
|
|
||||||
run-abra:
|
run:
|
||||||
@go run -gcflags=$(GCFLAGS) -ldflags=$(LDFLAGS) $(ABRA)
|
@go run -gcflags=$(GCFLAGS) -ldflags=$(LDFLAGS) $(ABRA)
|
||||||
|
|
||||||
run-kadabra:
|
install:
|
||||||
@go run -gcflags=$(GCFLAGS) -ldflags=$(LDFLAGS) $(KADABRA)
|
|
||||||
|
|
||||||
install-abra:
|
|
||||||
@go install -gcflags=$(GCFLAGS) -ldflags=$(LDFLAGS) $(ABRA)
|
@go install -gcflags=$(GCFLAGS) -ldflags=$(LDFLAGS) $(ABRA)
|
||||||
|
|
||||||
install-kadabra:
|
build:
|
||||||
@go install -gcflags=$(GCFLAGS) -ldflags=$(LDFLAGS) $(KADABRA)
|
|
||||||
|
|
||||||
install: install-abra install-kadabra
|
|
||||||
|
|
||||||
build-abra:
|
|
||||||
@go build -v -gcflags=$(GCFLAGS) -ldflags=$(DIST_LDFLAGS) $(ABRA)
|
@go build -v -gcflags=$(GCFLAGS) -ldflags=$(DIST_LDFLAGS) $(ABRA)
|
||||||
|
|
||||||
build-kadabra:
|
build-docker:
|
||||||
@go build -v -gcflags=$(GCFLAGS) -ldflags=$(DIST_LDFLAGS) $(KADABRA)
|
|
||||||
|
|
||||||
build: build-abra build-kadabra
|
|
||||||
|
|
||||||
build-docker-abra:
|
|
||||||
@docker run -it -v $(PWD):/abra golang:$(GOVERSION) \
|
@docker run -it -v $(PWD):/abra golang:$(GOVERSION) \
|
||||||
bash -c 'cd /abra; ./scripts/docker/build.sh'
|
bash -c 'cd /abra; ./scripts/docker/build.sh'
|
||||||
|
|
||||||
build-docker: build-docker-abra
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm '$(GOPATH)/bin/abra'
|
@rm '$(GOPATH)/bin/abra'
|
||||||
@rm '$(GOPATH)/bin/kadabra'
|
|
||||||
|
|
||||||
format:
|
format:
|
||||||
@gofmt -s -w $$(find . -type f -name '*.go' | grep -v "/vendor/")
|
@gofmt -s -w $$(find . -type f -name '*.go' | grep -v "/vendor/")
|
||||||
@ -78,14 +61,20 @@ update-po:
|
|||||||
done
|
done
|
||||||
|
|
||||||
.PHONY: update-pot
|
.PHONY: update-pot
|
||||||
update-pot:
|
update-pot: $(XGETTEXT)
|
||||||
@xgettext-go \
|
@${XGETTEXT} \
|
||||||
-o pkg/i18n/locales/$(DOMAIN).pot \
|
-o pkg/i18n/locales/$(DOMAIN).pot \
|
||||||
--keyword=i18n.G \
|
--keyword=i18n.G \
|
||||||
|
--keyword-ctx=i18n.GC \
|
||||||
--sort-output \
|
--sort-output \
|
||||||
--add-comments-tag="translators" \
|
--add-comments-tag="translators" \
|
||||||
$$(find . -name "*.go" -not -path "*vendor*" | sort)
|
$$(find . -name "*.go" -not -path "*vendor*" | sort)
|
||||||
|
|
||||||
|
${XGETTEXT}:
|
||||||
|
@mkdir -p ./bin && \
|
||||||
|
wget -O ./bin/xgettext-go https://git.coopcloud.tech/toolshed/xgettext-go/raw/branch/main/xgettext-go && \
|
||||||
|
chmod +x ./bin/xgettext-go
|
||||||
|
|
||||||
.PHONY: update-pot-po-metadata
|
.PHONY: update-pot-po-metadata
|
||||||
update-pot-po-metadata:
|
update-pot-po-metadata:
|
||||||
@sed -i "s/charset=CHARSET/charset=UTF-8/g" pkg/i18n/locales/*.po pkg/i18n/locales/*.pot
|
@sed -i "s/charset=CHARSET/charset=UTF-8/g" pkg/i18n/locales/*.po pkg/i18n/locales/*.pot
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
// translators: `abra app` aliases. use a comma separated list of aliases with
|
// translators: `abra app` aliases. use a comma separated list of aliases with
|
||||||
// no spaces in between
|
// no spaces in between
|
||||||
var appAliases = i18n.G("a")
|
var appAliases = i18n.GC("a", "abra app")
|
||||||
|
|
||||||
var AppCommand = &cobra.Command{
|
var AppCommand = &cobra.Command{
|
||||||
// translators: `app` command group
|
// translators: `app` command group
|
||||||
|
|||||||
@ -268,7 +268,7 @@ func init() {
|
|||||||
AppBackupListCommand.Flags().BoolVarP(
|
AppBackupListCommand.Flags().BoolVarP(
|
||||||
&showAllPaths,
|
&showAllPaths,
|
||||||
i18n.G("all"),
|
i18n.G("all"),
|
||||||
i18n.G("a"),
|
i18n.GC("a", "app backup list"),
|
||||||
false,
|
false,
|
||||||
i18n.G("show all paths"),
|
i18n.G("show all paths"),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package app
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
@ -103,18 +104,17 @@ checkout as-is. Recipe commit hashes are also supported as values for
|
|||||||
|
|
||||||
toDeployVersion, err = getDeployVersion(args, deployMeta, app)
|
toDeployVersion, err = getDeployVersion(args, deployMeta, app)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(i18n.G("get deploy version: %s", err))
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
versionIsChaos := false
|
|
||||||
if !internal.Chaos {
|
if !internal.Chaos {
|
||||||
var err error
|
isChaosCommit, err := app.Recipe.EnsureVersion(toDeployVersion)
|
||||||
versionIsChaos, err = app.Recipe.EnsureVersion(toDeployVersion)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(i18n.G("ensure recipe: %s", err))
|
log.Fatal(i18n.G("ensure recipe: %s", err))
|
||||||
}
|
}
|
||||||
if versionIsChaos {
|
if isChaosCommit {
|
||||||
log.Warnf(i18n.G("version '%s' appears to be a chaos commit, but --chaos/-C was not provided", toDeployVersion))
|
log.Warnf(i18n.G("version '%s' appears to be a chaos commit, but --chaos/-C was not provided", toDeployVersion))
|
||||||
|
internal.Chaos = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,14 +152,26 @@ checkout as-is. Recipe commit hashes are also supported as values for
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
appPkg.ExposeAllEnv(stackName, compose, app.Env)
|
|
||||||
appPkg.SetRecipeLabel(compose, stackName, app.Recipe.Name)
|
appPkg.SetRecipeLabel(compose, stackName, app.Recipe.Name)
|
||||||
appPkg.SetChaosLabel(compose, stackName, internal.Chaos || versionIsChaos)
|
appPkg.SetChaosLabel(compose, stackName, internal.Chaos)
|
||||||
if internal.Chaos {
|
if internal.Chaos {
|
||||||
appPkg.SetChaosVersionLabel(compose, stackName, toDeployVersion)
|
appPkg.SetChaosVersionLabel(compose, stackName, toDeployVersion)
|
||||||
}
|
}
|
||||||
appPkg.SetUpdateLabel(compose, stackName, app.Env)
|
|
||||||
appPkg.SetVersionLabel(compose, stackName, toDeployVersion)
|
versionLabel := toDeployVersion
|
||||||
|
if internal.Chaos {
|
||||||
|
for _, service := range compose.Services {
|
||||||
|
if service.Name == "app" {
|
||||||
|
labelKey := fmt.Sprintf("coop-cloud.%s.version", stackName)
|
||||||
|
// NOTE(d1): keep non-chaos version labbeling when doing chaos ops
|
||||||
|
versionLabel = service.Deploy.Labels[labelKey]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appPkg.SetVersionLabel(compose, stackName, versionLabel)
|
||||||
|
|
||||||
|
newRecipeWithDeployVersion := fmt.Sprintf("%s:%s", app.Recipe.Name, toDeployVersion)
|
||||||
|
appPkg.ExposeAllEnv(stackName, compose, app.Env, newRecipeWithDeployVersion)
|
||||||
|
|
||||||
envVars, err := appPkg.CheckEnv(app)
|
envVars, err := appPkg.CheckEnv(app)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -186,9 +198,12 @@ checkout as-is. Recipe commit hashes are also supported as values for
|
|||||||
log.Debug(i18n.G("skipping domain checks"))
|
log.Debug(i18n.G("skipping domain checks"))
|
||||||
}
|
}
|
||||||
|
|
||||||
deployedVersion := config.NO_VERSION_DEFAULT
|
deployedVersion := config.MISSING_DEFAULT
|
||||||
if deployMeta.IsDeployed {
|
if deployMeta.IsDeployed {
|
||||||
deployedVersion = deployMeta.Version
|
deployedVersion = deployMeta.Version
|
||||||
|
if deployMeta.IsChaos {
|
||||||
|
deployedVersion = deployMeta.ChaosVersion
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gather secrets
|
// Gather secrets
|
||||||
@ -245,6 +260,7 @@ checkout as-is. Recipe commit hashes are also supported as values for
|
|||||||
app.Name,
|
app.Name,
|
||||||
app.Server,
|
app.Server,
|
||||||
internal.DontWaitConverge,
|
internal.DontWaitConverge,
|
||||||
|
internal.NoInput,
|
||||||
f,
|
f,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -300,6 +316,16 @@ func validateArgsAndFlags(args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func validateSecrets(cl *dockerClient.Client, app appPkg.App) error {
|
func validateSecrets(cl *dockerClient.Client, app appPkg.App) error {
|
||||||
|
composeFiles, err := app.Recipe.GetComposeFiles(app.Env)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
secretsConfig, err := secret.ReadSecretsConfig(app.Path, composeFiles, app.StackName())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
secStats, err := secret.PollSecretsStatus(cl, app)
|
secStats, err := secret.PollSecretsStatus(cl, app)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -307,6 +333,10 @@ func validateSecrets(cl *dockerClient.Client, app appPkg.App) error {
|
|||||||
|
|
||||||
for _, secStat := range secStats {
|
for _, secStat := range secStats {
|
||||||
if !secStat.CreatedOnRemote {
|
if !secStat.CreatedOnRemote {
|
||||||
|
secretConfig := secretsConfig[secStat.LocalName]
|
||||||
|
if secretConfig.SkipGenerate {
|
||||||
|
return errors.New(i18n.G("secret not inserted (#generate=false): %s", secStat.LocalName))
|
||||||
|
}
|
||||||
return errors.New(i18n.G("secret not generated: %s", secStat.LocalName))
|
return errors.New(i18n.G("secret not generated: %s", secStat.LocalName))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -334,7 +364,12 @@ func getDeployVersion(cliArgs []string, deployMeta stack.DeployMeta, app appPkg.
|
|||||||
// Check if the recipe has a version in the .env file
|
// Check if the recipe has a version in the .env file
|
||||||
if app.Recipe.EnvVersion != "" && !internal.DeployLatest {
|
if app.Recipe.EnvVersion != "" && !internal.DeployLatest {
|
||||||
if strings.HasSuffix(app.Recipe.EnvVersionRaw, "+U") {
|
if strings.HasSuffix(app.Recipe.EnvVersionRaw, "+U") {
|
||||||
return "", errors.New(i18n.G("version: can not redeploy chaos version %s", app.Recipe.EnvVersionRaw))
|
// NOTE(d1): use double-line 5 spaces ("FATA ") trick to make a more
|
||||||
|
// informative error message. it's ugly but that's our logging situation
|
||||||
|
// atm
|
||||||
|
return "", errors.New(i18n.G(`cannot redeploy previous chaos version (%s), did you mean to use "--chaos"?
|
||||||
|
to return to a regular release, specify a release tag, commit SHA or use "--latest"`,
|
||||||
|
formatter.BoldDirtyDefault(app.Recipe.EnvVersionRaw)))
|
||||||
}
|
}
|
||||||
log.Debug(i18n.G("version: taking version from .env file: %s", app.Recipe.EnvVersion))
|
log.Debug(i18n.G("version: taking version from .env file: %s", app.Recipe.EnvVersion))
|
||||||
return app.Recipe.EnvVersion, nil
|
return app.Recipe.EnvVersion, nil
|
||||||
|
|||||||
311
cli/app/env.go
311
cli/app/env.go
@ -1,28 +1,50 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
|
"coopcloud.tech/abra/pkg/app"
|
||||||
|
appPkg "coopcloud.tech/abra/pkg/app"
|
||||||
"coopcloud.tech/abra/pkg/autocomplete"
|
"coopcloud.tech/abra/pkg/autocomplete"
|
||||||
|
"coopcloud.tech/abra/pkg/client"
|
||||||
|
"coopcloud.tech/abra/pkg/config"
|
||||||
|
containerPkg "coopcloud.tech/abra/pkg/container"
|
||||||
|
contextPkg "coopcloud.tech/abra/pkg/context"
|
||||||
"coopcloud.tech/abra/pkg/formatter"
|
"coopcloud.tech/abra/pkg/formatter"
|
||||||
"coopcloud.tech/abra/pkg/i18n"
|
"coopcloud.tech/abra/pkg/i18n"
|
||||||
|
"coopcloud.tech/abra/pkg/log"
|
||||||
|
"coopcloud.tech/abra/pkg/upstream/stack"
|
||||||
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
// translators: `abra app env` aliases. use a comma separated list of aliases with
|
// translators: `abra app env` aliases. use a comma separated list of aliases
|
||||||
// no spaces in between
|
// with no spaces in between
|
||||||
var appEnvAliases = i18n.G("e")
|
var appEnvAliases = i18n.G("e")
|
||||||
|
|
||||||
var AppEnvCommand = &cobra.Command{
|
// translators: `abra app env list` aliases. use a comma separated list of
|
||||||
// translators: `app env` command
|
// aliases with no spaces in between
|
||||||
Use: i18n.G("env <domain> [flags]"),
|
var appEnvListAliases = i18n.G("l,ls")
|
||||||
Aliases: strings.Split(appEnvAliases, ","),
|
|
||||||
// translators: Short description for `app env` command
|
// translators: `abra app env pull` aliases. use a comma separated list of
|
||||||
Short: i18n.G("Show app .env values"),
|
// aliases with no spaces in between
|
||||||
Example: i18n.G(" abra app env 1312.net"),
|
var appEnvPullAliases = i18n.G("pl,p")
|
||||||
|
|
||||||
|
var AppEnvListCommand = &cobra.Command{
|
||||||
|
// translators: `app env list` command
|
||||||
|
Use: i18n.G("list <domain> [flags]"),
|
||||||
|
Aliases: strings.Split(appEnvListAliases, ","),
|
||||||
|
// translators: Short description for `app env list` command
|
||||||
|
Short: i18n.G("List all app environment values"),
|
||||||
|
Example: i18n.G(" abra app env list 1312.net"),
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
ValidArgsFunction: func(
|
ValidArgsFunction: func(
|
||||||
cmd *cobra.Command,
|
cmd *cobra.Command,
|
||||||
@ -49,3 +71,274 @@ var AppEnvCommand = &cobra.Command{
|
|||||||
fmt.Println(overview)
|
fmt.Println(overview)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var AppEnvPullCommand = &cobra.Command{
|
||||||
|
// translators: `app pull` command
|
||||||
|
Use: i18n.G("pull <domain> [flags]"),
|
||||||
|
Aliases: strings.Split(appEnvPullAliases, ","),
|
||||||
|
// translators: Short description for `app env pull` command
|
||||||
|
Short: i18n.G("Pull app environment values from a deployed app"),
|
||||||
|
Long: i18n.G(`Pull app environment values from a deploymed app.
|
||||||
|
|
||||||
|
A convenient command for when you've lost your app environment file or want to
|
||||||
|
synchronize your local app environment values with what is deployed live.`),
|
||||||
|
Example: i18n.G(` # pull existing .env file and overwrite local values
|
||||||
|
abra app env pull 1312.net --force
|
||||||
|
|
||||||
|
# pull lost app .env file
|
||||||
|
abra app env pull my.gitea.net --server 1312.net`),
|
||||||
|
Args: cobra.MaximumNArgs(2),
|
||||||
|
ValidArgsFunction: func(
|
||||||
|
cmd *cobra.Command,
|
||||||
|
args []string,
|
||||||
|
toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
return autocomplete.AppNameComplete()
|
||||||
|
},
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
appName := args[0]
|
||||||
|
|
||||||
|
appEnvPath := path.Join(config.ABRA_DIR, "servers", server, fmt.Sprintf("%s.env", appName))
|
||||||
|
if _, err := os.Stat(appEnvPath); !os.IsNotExist(err) {
|
||||||
|
log.Fatal(i18n.G("%s already exists?", appEnvPath))
|
||||||
|
}
|
||||||
|
|
||||||
|
if server == "" {
|
||||||
|
log.Fatal(i18n.G("unable to determine server of app %s, please pass --server/-s", appName))
|
||||||
|
}
|
||||||
|
|
||||||
|
serverDir := filepath.Join(config.SERVERS_DIR, server)
|
||||||
|
if _, err := os.Stat(serverDir); os.IsNotExist(err) {
|
||||||
|
log.Fatal(i18n.G("unknown server %s, run \"abra server add %s\"?", server, server))
|
||||||
|
}
|
||||||
|
|
||||||
|
store := contextPkg.NewDefaultDockerContextStore()
|
||||||
|
contexts, err := store.Store.List()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(i18n.G("unable to look up server context for %s: %s", server, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
var contextCreated bool
|
||||||
|
if server == "default" {
|
||||||
|
contextCreated = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, context := range contexts {
|
||||||
|
if context.Name == server {
|
||||||
|
contextCreated = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !contextCreated {
|
||||||
|
log.Fatal(i18n.G("%s missing context, run \"abra server add %s\"?", server, server))
|
||||||
|
}
|
||||||
|
|
||||||
|
cl, err := client.New(server)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
deployMeta, err := stack.IsDeployed(context.Background(), cl, appPkg.StackName(appName))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !deployMeta.IsDeployed {
|
||||||
|
log.Fatal(i18n.G("%s is not deployed?", appName))
|
||||||
|
}
|
||||||
|
|
||||||
|
filters := filters.NewArgs()
|
||||||
|
filters.Add("name", fmt.Sprintf("^%s_%s", app.StackName(appName), "app"))
|
||||||
|
targetContainer, err := containerPkg.GetContainer(context.Background(), cl, filters, internal.NoInput)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(i18n.G("unable to retrieve container for %s: %s", appName, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
inspectResult, err := cl.ContainerInspect(context.Background(), targetContainer.ID)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(i18n.G("unable to inspect container for %s: %s", appName, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
deploymentEnv := make(map[string]string)
|
||||||
|
for _, envVar := range inspectResult.Config.Env {
|
||||||
|
split := strings.SplitN(envVar, "=", 2)
|
||||||
|
if len(split) != 2 {
|
||||||
|
log.Debug(i18n.G("no value attached to %s", envVar))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
key, val := split[0], split[1]
|
||||||
|
deploymentEnv[key] = val
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug(i18n.G("pulled env values from %s deployment: %s", appName, deploymentEnv))
|
||||||
|
|
||||||
|
var (
|
||||||
|
recipeEnvVar string
|
||||||
|
recipeKey string
|
||||||
|
)
|
||||||
|
|
||||||
|
if r, ok := deploymentEnv["TYPE"]; ok {
|
||||||
|
recipeKey = "TYPE"
|
||||||
|
recipeEnvVar = r
|
||||||
|
}
|
||||||
|
|
||||||
|
if r, ok := deploymentEnv["RECIPE"]; ok {
|
||||||
|
recipeKey = "RECIPE"
|
||||||
|
recipeEnvVar = r
|
||||||
|
}
|
||||||
|
|
||||||
|
if recipeEnvVar == "" {
|
||||||
|
log.Fatal(i18n.G("unable to determine recipe type from %s, env: %v", appName, inspectResult.Config.Env))
|
||||||
|
}
|
||||||
|
|
||||||
|
var recipeName = recipeEnvVar
|
||||||
|
if strings.Contains(recipeEnvVar, ":") {
|
||||||
|
split := strings.Split(recipeEnvVar, ":")
|
||||||
|
recipeName = split[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
recipe := internal.ValidateRecipe(
|
||||||
|
[]string{recipeName},
|
||||||
|
cmd.Name(),
|
||||||
|
)
|
||||||
|
|
||||||
|
version := deployMeta.Version
|
||||||
|
if deployMeta.IsChaos {
|
||||||
|
version = deployMeta.ChaosVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := recipe.EnsureVersion(version); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mergedEnv, err := recipe.SampleEnv()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug(i18n.G("retrieved env values from .env.sample of %s: %s", recipe.Name, mergedEnv))
|
||||||
|
|
||||||
|
for k, v := range deploymentEnv {
|
||||||
|
mergedEnv[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(recipeEnvVar, ":") {
|
||||||
|
mergedEnv[recipeKey] = fmt.Sprintf("%s:%s", mergedEnv[recipeKey], version)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug(i18n.G("final merged env values for %s are: %s", appName, mergedEnv))
|
||||||
|
|
||||||
|
envSample, err := os.ReadFile(recipe.SampleEnvPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(appEnvPath, envSample, 0o664)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(i18n.G("unable to write new env %s: %s", appEnvPath, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
read, err := os.ReadFile(appEnvPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(i18n.G("unable to read new env %s: %s", appEnvPath, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
sampleEnv, err := recipe.SampleEnv()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var composeFileUpdated bool
|
||||||
|
newContents := string(read)
|
||||||
|
for key, val := range mergedEnv {
|
||||||
|
if sampleEnv[key] == val {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if key == "COMPOSE_FILE" {
|
||||||
|
composeFileUpdated = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if m, _ := regexp.MatchString(fmt.Sprintf(`#%s=`, key), newContents); m {
|
||||||
|
log.Debug(i18n.G("uncommenting %s", key))
|
||||||
|
re := regexp.MustCompile(fmt.Sprintf(`#%s=`, key))
|
||||||
|
newContents = re.ReplaceAllString(newContents, fmt.Sprintf("%s=", key))
|
||||||
|
}
|
||||||
|
|
||||||
|
if m, _ := regexp.MatchString(fmt.Sprintf(`# %s=`, key), newContents); m {
|
||||||
|
log.Debug(i18n.G("uncommenting %s", key))
|
||||||
|
re := regexp.MustCompile(fmt.Sprintf(`# %s=`, key))
|
||||||
|
newContents = re.ReplaceAllString(newContents, fmt.Sprintf("%s=", key))
|
||||||
|
}
|
||||||
|
|
||||||
|
if m, _ := regexp.MatchString(fmt.Sprintf(`%s=".*"`, key), newContents); m {
|
||||||
|
log.Debug(i18n.G(`inserting %s="%s" (double quotes)`, key, val))
|
||||||
|
re := regexp.MustCompile(fmt.Sprintf(`%s=".*"`, key))
|
||||||
|
newContents = re.ReplaceAllString(newContents, fmt.Sprintf(`%s="%s"`, key, val))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if m, _ := regexp.MatchString(fmt.Sprintf(`%s='.*'`, key), newContents); m {
|
||||||
|
log.Debug(i18n.G(`inserting %s='%s' (single quotes)`, key, val))
|
||||||
|
re := regexp.MustCompile(fmt.Sprintf(`%s='.*'`, key))
|
||||||
|
newContents = re.ReplaceAllString(newContents, fmt.Sprintf(`%s='%s'`, key, val))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if m, _ := regexp.MatchString(fmt.Sprintf("%s=.*", key), newContents); m {
|
||||||
|
log.Debug(i18n.G("inserting %s=%s (no quotes)", key, val))
|
||||||
|
re := regexp.MustCompile(fmt.Sprintf("%s=.*", key))
|
||||||
|
newContents = re.ReplaceAllString(newContents, fmt.Sprintf("%s=%s", key, val))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(appEnvPath, []byte(newContents), 0)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(i18n.G("unable to write new env %s: %s", appEnvPath, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info(i18n.G("%s successfully created", appEnvPath))
|
||||||
|
|
||||||
|
if composeFileUpdated {
|
||||||
|
log.Warn(i18n.G("manual update required: COMPOSE_FILE=\"%s\"", mergedEnv["COMPOSE_FILE"]))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var AppEnvCommand = &cobra.Command{
|
||||||
|
// translators: `app env` command group
|
||||||
|
Use: i18n.G("env [cmd] [args] [flags]"),
|
||||||
|
Aliases: strings.Split(appEnvAliases, ","),
|
||||||
|
// translators: Short description for `app env` command group
|
||||||
|
Short: i18n.G("Manage app environment values"),
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
server string
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
AppEnvPullCommand.Flags().BoolVarP(
|
||||||
|
&internal.Force,
|
||||||
|
i18n.G("force"),
|
||||||
|
i18n.G("f"),
|
||||||
|
false,
|
||||||
|
i18n.G("perform action without further prompt"),
|
||||||
|
)
|
||||||
|
|
||||||
|
AppEnvPullCommand.Flags().StringVarP(
|
||||||
|
&server,
|
||||||
|
i18n.G("server"),
|
||||||
|
i18n.G("s"),
|
||||||
|
"",
|
||||||
|
i18n.G("server associated with deployed app"),
|
||||||
|
)
|
||||||
|
|
||||||
|
AppEnvPullCommand.RegisterFlagCompletionFunc(
|
||||||
|
i18n.G("server"),
|
||||||
|
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
return autocomplete.ServerNameComplete()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@ -25,7 +25,6 @@ type appStatus struct {
|
|||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Chaos string `json:"chaos"`
|
Chaos string `json:"chaos"`
|
||||||
ChaosVersion string `json:"chaosVersion"`
|
ChaosVersion string `json:"chaosVersion"`
|
||||||
AutoUpdate string `json:"autoUpdate"`
|
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
Upgrade string `json:"upgrade"`
|
Upgrade string `json:"upgrade"`
|
||||||
}
|
}
|
||||||
@ -118,7 +117,6 @@ Use "--status/-S" flag to query all servers for the live deployment status.`),
|
|||||||
version := i18n.G("unknown")
|
version := i18n.G("unknown")
|
||||||
chaos := i18n.G("unknown")
|
chaos := i18n.G("unknown")
|
||||||
chaosVersion := i18n.G("unknown")
|
chaosVersion := i18n.G("unknown")
|
||||||
autoUpdate := i18n.G("unknown")
|
|
||||||
if statusMeta, ok := statuses[app.StackName()]; ok {
|
if statusMeta, ok := statuses[app.StackName()]; ok {
|
||||||
if currentVersion, exists := statusMeta["version"]; exists {
|
if currentVersion, exists := statusMeta["version"]; exists {
|
||||||
if currentVersion != "" {
|
if currentVersion != "" {
|
||||||
@ -131,9 +129,6 @@ Use "--status/-S" flag to query all servers for the live deployment status.`),
|
|||||||
if chaosDeployVersion, exists := statusMeta["chaosVersion"]; exists {
|
if chaosDeployVersion, exists := statusMeta["chaosVersion"]; exists {
|
||||||
chaosVersion = chaosDeployVersion
|
chaosVersion = chaosDeployVersion
|
||||||
}
|
}
|
||||||
if autoUpdateState, exists := statusMeta["autoUpdate"]; exists {
|
|
||||||
autoUpdate = autoUpdateState
|
|
||||||
}
|
|
||||||
if statusMeta["status"] != "" {
|
if statusMeta["status"] != "" {
|
||||||
status = statusMeta["status"]
|
status = statusMeta["status"]
|
||||||
}
|
}
|
||||||
@ -146,7 +141,6 @@ Use "--status/-S" flag to query all servers for the live deployment status.`),
|
|||||||
appStats.Chaos = chaos
|
appStats.Chaos = chaos
|
||||||
appStats.ChaosVersion = chaosVersion
|
appStats.ChaosVersion = chaosVersion
|
||||||
appStats.Version = version
|
appStats.Version = version
|
||||||
appStats.AutoUpdate = autoUpdate
|
|
||||||
|
|
||||||
var newUpdates []string
|
var newUpdates []string
|
||||||
if version != "unknown" && chaos == "false" {
|
if version != "unknown" && chaos == "false" {
|
||||||
@ -165,6 +159,11 @@ Use "--status/-S" flag to query all servers for the live deployment status.`),
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, update := range updates {
|
for _, update := range updates {
|
||||||
|
if ok := tagcmp.IsParsable(update); !ok {
|
||||||
|
log.Debug(i18n.G("unable to parse %s, skipping as upgrade option", update))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
parsedUpdate, err := tagcmp.Parse(update)
|
parsedUpdate, err := tagcmp.Parse(update)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -226,7 +225,6 @@ Use "--status/-S" flag to query all servers for the live deployment status.`),
|
|||||||
i18n.G("CHAOS"),
|
i18n.G("CHAOS"),
|
||||||
i18n.G("VERSION"),
|
i18n.G("VERSION"),
|
||||||
i18n.G("UPGRADE"),
|
i18n.G("UPGRADE"),
|
||||||
i18n.G("AUTOUPDATE"),
|
|
||||||
}...,
|
}...,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -257,8 +255,7 @@ Use "--status/-S" flag to query all servers for the live deployment status.`),
|
|||||||
appStat.Status,
|
appStat.Status,
|
||||||
chaosStatus,
|
chaosStatus,
|
||||||
appStat.Version,
|
appStat.Version,
|
||||||
appStat.Upgrade,
|
appStat.Upgrade}...,
|
||||||
appStat.AutoUpdate}...,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -128,6 +128,10 @@ Use "--dry-run/-r" to see which secrets and volumes will be moved.`),
|
|||||||
secretName := strings.Join(sname[:len(sname)-1], "_")
|
secretName := strings.Join(sname[:len(sname)-1], "_")
|
||||||
data := resources.Secrets[secretName]
|
data := resources.Secrets[secretName]
|
||||||
if err := client.StoreSecret(newServerClient, s.Spec.Name, data); err != nil {
|
if err := client.StoreSecret(newServerClient, s.Spec.Name, data); err != nil {
|
||||||
|
if strings.Contains(err.Error(), "already exists") {
|
||||||
|
log.Info(i18n.G("skipping secret (because it already exists) on %s: %s", s.Spec.Name, newServer))
|
||||||
|
continue
|
||||||
|
}
|
||||||
log.Fatal(i18n.G("failed to store secret on %s: %s", err, newServer))
|
log.Fatal(i18n.G("failed to store secret on %s: %s", err, newServer))
|
||||||
}
|
}
|
||||||
log.Info(i18n.G("created secret on %s: %s", s.Spec.Name, newServer))
|
log.Info(i18n.G("created secret on %s: %s", s.Spec.Name, newServer))
|
||||||
|
|||||||
@ -192,7 +192,27 @@ var AppNewCommand = &cobra.Command{
|
|||||||
log.Info(i18n.G("%s created (version: %s)", appDomain, recipeVersion))
|
log.Info(i18n.G("%s created (version: %s)", appDomain, recipeVersion))
|
||||||
|
|
||||||
if len(secretsConfig) > 0 {
|
if len(secretsConfig) > 0 {
|
||||||
log.Warn(i18n.G("%s requires secret generation before deploying, run \"abra app secret generate %s --all\"", recipe.Name, appDomain))
|
var (
|
||||||
|
hasSecretToGenerate bool
|
||||||
|
hasSecretToSkip bool
|
||||||
|
)
|
||||||
|
|
||||||
|
for _, secretConfig := range secretsConfig {
|
||||||
|
if secretConfig.SkipGenerate {
|
||||||
|
hasSecretToSkip = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
hasSecretToGenerate = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasSecretToGenerate && !generateSecrets {
|
||||||
|
log.Warn(i18n.G("%s requires secret generation before deploy, run \"abra app secret generate %s --all\"", recipe.Name, appDomain))
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasSecretToSkip {
|
||||||
|
log.Warn(i18n.G("%s requires secret insertion before deploy (#generate=false)", recipe.Name))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(appSecrets) > 0 {
|
if len(appSecrets) > 0 {
|
||||||
|
|||||||
@ -128,6 +128,7 @@ Pass "--all-services/-a" to restart all services.`),
|
|||||||
AppName: app.Name,
|
AppName: app.Name,
|
||||||
ServerName: app.Server,
|
ServerName: app.Server,
|
||||||
Filters: f,
|
Filters: f,
|
||||||
|
NoInput: internal.NoInput,
|
||||||
NoLog: true,
|
NoLog: true,
|
||||||
Quiet: true,
|
Quiet: true,
|
||||||
}
|
}
|
||||||
@ -166,7 +167,7 @@ func init() {
|
|||||||
AppRestartCommand.Flags().BoolVarP(
|
AppRestartCommand.Flags().BoolVarP(
|
||||||
&allServices,
|
&allServices,
|
||||||
i18n.G("all-services"),
|
i18n.G("all-services"),
|
||||||
i18n.G("a"),
|
i18n.GC("a", "app restart"),
|
||||||
false,
|
false,
|
||||||
i18n.G("restart all services"),
|
i18n.G("restart all services"),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package app
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
appPkg "coopcloud.tech/abra/pkg/app"
|
appPkg "coopcloud.tech/abra/pkg/app"
|
||||||
@ -177,13 +178,14 @@ beforehand. See "abra app backup" for more.`),
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
appPkg.ExposeAllEnv(stackName, compose, app.Env)
|
newRecipeWithDowngradeVersion := fmt.Sprintf("%s:%s", app.Recipe.Name, chosenDowngrade)
|
||||||
|
appPkg.ExposeAllEnv(stackName, compose, app.Env, newRecipeWithDowngradeVersion)
|
||||||
|
|
||||||
appPkg.SetRecipeLabel(compose, stackName, app.Recipe.Name)
|
appPkg.SetRecipeLabel(compose, stackName, app.Recipe.Name)
|
||||||
appPkg.SetChaosLabel(compose, stackName, internal.Chaos)
|
appPkg.SetChaosLabel(compose, stackName, internal.Chaos)
|
||||||
if internal.Chaos {
|
if internal.Chaos {
|
||||||
appPkg.SetChaosVersionLabel(compose, stackName, chosenDowngrade)
|
appPkg.SetChaosVersionLabel(compose, stackName, chosenDowngrade)
|
||||||
}
|
}
|
||||||
appPkg.SetUpdateLabel(compose, stackName, app.Env)
|
|
||||||
|
|
||||||
// Gather secrets
|
// Gather secrets
|
||||||
secretInfo, err := deploy.GatherSecretsForDeploy(cl, app, internal.ShowUnchanged)
|
secretInfo, err := deploy.GatherSecretsForDeploy(cl, app, internal.ShowUnchanged)
|
||||||
@ -203,10 +205,15 @@ beforehand. See "abra app backup" for more.`),
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deployedVersion := deployMeta.Version
|
||||||
|
if deployMeta.IsChaos {
|
||||||
|
deployedVersion = deployMeta.ChaosVersion
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE(d1): no release notes implemeneted for rolling back
|
// NOTE(d1): no release notes implemeneted for rolling back
|
||||||
if err := internal.DeployOverview(
|
if err := internal.DeployOverview(
|
||||||
app,
|
app,
|
||||||
deployMeta.Version,
|
deployedVersion,
|
||||||
chosenDowngrade,
|
chosenDowngrade,
|
||||||
"",
|
"",
|
||||||
downgradeWarnMessages,
|
downgradeWarnMessages,
|
||||||
@ -239,6 +246,7 @@ beforehand. See "abra app backup" for more.`),
|
|||||||
stackName,
|
stackName,
|
||||||
app.Server,
|
app.Server,
|
||||||
internal.DontWaitConverge,
|
internal.DontWaitConverge,
|
||||||
|
internal.NoInput,
|
||||||
f,
|
f,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|||||||
@ -165,7 +165,7 @@ var AppSecretInsertCommand = &cobra.Command{
|
|||||||
Arbitrary secret insertion is not supported. Secrets that are inserted must
|
Arbitrary secret insertion is not supported. Secrets that are inserted must
|
||||||
match those configured in the recipe beforehand.
|
match those configured in the recipe beforehand.
|
||||||
|
|
||||||
This can be useful when you want to manually generate secrets for an app
|
This command can be useful when you want to manually generate secrets for an app
|
||||||
environment. Typically, you can let Abra generate them for you on app creation
|
environment. Typically, you can let Abra generate them for you on app creation
|
||||||
(see "abra app new --secrets/-S" for more).`),
|
(see "abra app new --secrets/-S" for more).`),
|
||||||
Example: i18n.G(` # insert regular secret
|
Example: i18n.G(` # insert regular secret
|
||||||
@ -574,7 +574,7 @@ func init() {
|
|||||||
AppSecretGenerateCommand.Flags().BoolVarP(
|
AppSecretGenerateCommand.Flags().BoolVarP(
|
||||||
&generateAllSecrets,
|
&generateAllSecrets,
|
||||||
i18n.G("all"),
|
i18n.G("all"),
|
||||||
i18n.G("a"),
|
i18n.GC("a", "app secret generate"),
|
||||||
false,
|
false,
|
||||||
i18n.G("generate all secrets"),
|
i18n.G("generate all secrets"),
|
||||||
)
|
)
|
||||||
@ -614,7 +614,7 @@ func init() {
|
|||||||
AppSecretRmCommand.Flags().BoolVarP(
|
AppSecretRmCommand.Flags().BoolVarP(
|
||||||
&rmAllSecrets,
|
&rmAllSecrets,
|
||||||
i18n.G("all"),
|
i18n.G("all"),
|
||||||
i18n.G("a"),
|
i18n.GC("a", "app secret rm"),
|
||||||
false,
|
false,
|
||||||
i18n.G("remove all secrets"),
|
i18n.G("remove all secrets"),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -28,6 +28,7 @@ var AppUndeployCommand = &cobra.Command{
|
|||||||
Use: i18n.G("undeploy <domain> [flags]"),
|
Use: i18n.G("undeploy <domain> [flags]"),
|
||||||
// translators: Short description for `app undeploy` command
|
// translators: Short description for `app undeploy` command
|
||||||
Aliases: strings.Split(appUndeployAliases, ","),
|
Aliases: strings.Split(appUndeployAliases, ","),
|
||||||
|
Short: i18n.G("Undeploy a deployed app"),
|
||||||
Long: i18n.G(`This does not destroy any application data.
|
Long: i18n.G(`This does not destroy any application data.
|
||||||
|
|
||||||
However, you should remain vigilant, as your swarm installation will consider
|
However, you should remain vigilant, as your swarm installation will consider
|
||||||
@ -65,10 +66,15 @@ Passing "--prune/-p" does not remove those volumes.`),
|
|||||||
log.Fatal(i18n.G("%s is not deployed?", app.Name))
|
log.Fatal(i18n.G("%s is not deployed?", app.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version := deployMeta.Version
|
||||||
|
if deployMeta.IsChaos {
|
||||||
|
version = deployMeta.ChaosVersion
|
||||||
|
}
|
||||||
|
|
||||||
if err := internal.DeployOverview(
|
if err := internal.DeployOverview(
|
||||||
app,
|
app,
|
||||||
deployMeta.Version,
|
version,
|
||||||
config.NO_DOMAIN_DEFAULT,
|
config.MISSING_DEFAULT,
|
||||||
"",
|
"",
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
@ -110,7 +116,7 @@ Passing "--prune/-p" does not remove those volumes.`),
|
|||||||
|
|
||||||
log.Info(i18n.G("undeploy succeeded 🟢"))
|
log.Info(i18n.G("undeploy succeeded 🟢"))
|
||||||
|
|
||||||
if err := app.WriteRecipeVersion(deployMeta.Version, false); err != nil {
|
if err := app.WriteRecipeVersion(version, false); err != nil {
|
||||||
log.Fatal(i18n.G("writing recipe version failed: %s", err))
|
log.Fatal(i18n.G("writing recipe version failed: %s", err))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -190,13 +190,14 @@ beforehand. See "abra app backup" for more.`),
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
appPkg.ExposeAllEnv(stackName, compose, app.Env)
|
newRecipeWithUpgradeVersion := fmt.Sprintf("%s:%s", app.Recipe.Name, chosenUpgrade)
|
||||||
|
appPkg.ExposeAllEnv(stackName, compose, app.Env, newRecipeWithUpgradeVersion)
|
||||||
|
|
||||||
appPkg.SetRecipeLabel(compose, stackName, app.Recipe.Name)
|
appPkg.SetRecipeLabel(compose, stackName, app.Recipe.Name)
|
||||||
appPkg.SetChaosLabel(compose, stackName, internal.Chaos)
|
appPkg.SetChaosLabel(compose, stackName, internal.Chaos)
|
||||||
if internal.Chaos {
|
if internal.Chaos {
|
||||||
appPkg.SetChaosVersionLabel(compose, stackName, chosenUpgrade)
|
appPkg.SetChaosVersionLabel(compose, stackName, chosenUpgrade)
|
||||||
}
|
}
|
||||||
appPkg.SetUpdateLabel(compose, stackName, app.Env)
|
|
||||||
|
|
||||||
envVars, err := appPkg.CheckEnv(app)
|
envVars, err := appPkg.CheckEnv(app)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -241,9 +242,14 @@ beforehand. See "abra app backup" for more.`),
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deployedVersion := deployMeta.Version
|
||||||
|
if deployMeta.IsChaos {
|
||||||
|
deployedVersion = deployMeta.ChaosVersion
|
||||||
|
}
|
||||||
|
|
||||||
if err := internal.DeployOverview(
|
if err := internal.DeployOverview(
|
||||||
app,
|
app,
|
||||||
deployMeta.Version,
|
deployedVersion,
|
||||||
chosenUpgrade,
|
chosenUpgrade,
|
||||||
upgradeReleaseNotes,
|
upgradeReleaseNotes,
|
||||||
upgradeWarnMessages,
|
upgradeWarnMessages,
|
||||||
@ -276,6 +282,7 @@ beforehand. See "abra app backup" for more.`),
|
|||||||
stackName,
|
stackName,
|
||||||
app.Server,
|
app.Server,
|
||||||
internal.DontWaitConverge,
|
internal.DontWaitConverge,
|
||||||
|
internal.NoInput,
|
||||||
f,
|
f,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|||||||
@ -64,14 +64,14 @@ func DeployOverview(
|
|||||||
server = "local"
|
server = "local"
|
||||||
}
|
}
|
||||||
|
|
||||||
domain := app.Domain
|
domain := fmt.Sprintf("https://%s", app.Domain)
|
||||||
if domain == "" {
|
if domain == "" {
|
||||||
domain = config.NO_DOMAIN_DEFAULT
|
domain = config.MISSING_DEFAULT
|
||||||
}
|
}
|
||||||
|
|
||||||
envVersion := app.Recipe.EnvVersionRaw
|
envVersion := app.Recipe.EnvVersionRaw
|
||||||
if envVersion == "" {
|
if envVersion == "" {
|
||||||
envVersion = config.NO_VERSION_DEFAULT
|
envVersion = config.MISSING_DEFAULT
|
||||||
}
|
}
|
||||||
|
|
||||||
rows := [][]string{
|
rows := [][]string{
|
||||||
@ -140,32 +140,40 @@ func DeployOverview(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getDeployType(currentVersion, newVersion string) string {
|
func getDeployType(currentVersion, newVersion string) string {
|
||||||
if newVersion == config.NO_DOMAIN_DEFAULT {
|
if newVersion == config.MISSING_DEFAULT {
|
||||||
return i18n.G("UNDEPLOY")
|
return i18n.G("UNDEPLOY")
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(newVersion, "+U") {
|
if strings.Contains(newVersion, "+U") {
|
||||||
return i18n.G("CHAOS DEPLOY")
|
return i18n.G("CHAOS DEPLOY")
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(currentVersion, "+U") {
|
if strings.Contains(currentVersion, "+U") {
|
||||||
return i18n.G("UNCHAOS DEPLOY")
|
return i18n.G("UNCHAOS DEPLOY")
|
||||||
}
|
}
|
||||||
|
|
||||||
if currentVersion == newVersion {
|
if currentVersion == newVersion {
|
||||||
return ("REDEPLOY")
|
return ("REDEPLOY")
|
||||||
}
|
}
|
||||||
if currentVersion == config.NO_VERSION_DEFAULT {
|
|
||||||
|
if currentVersion == config.MISSING_DEFAULT {
|
||||||
return i18n.G("NEW DEPLOY")
|
return i18n.G("NEW DEPLOY")
|
||||||
}
|
}
|
||||||
|
|
||||||
currentParsed, err := tagcmp.Parse(currentVersion)
|
currentParsed, err := tagcmp.Parse(currentVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return i18n.G("DEPLOY")
|
return i18n.G("DEPLOY")
|
||||||
}
|
}
|
||||||
|
|
||||||
newParsed, err := tagcmp.Parse(newVersion)
|
newParsed, err := tagcmp.Parse(newVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return i18n.G("DEPLOY")
|
return i18n.G("DEPLOY")
|
||||||
}
|
}
|
||||||
|
|
||||||
if currentParsed.IsLessThan(newParsed) {
|
if currentParsed.IsLessThan(newParsed) {
|
||||||
return i18n.G("UPGRADE")
|
return i18n.G("UPGRADE")
|
||||||
}
|
}
|
||||||
|
|
||||||
return i18n.G("DOWNGRADE")
|
return i18n.G("DOWNGRADE")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,17 +191,17 @@ func MoveOverview(
|
|||||||
|
|
||||||
domain := app.Domain
|
domain := app.Domain
|
||||||
if domain == "" {
|
if domain == "" {
|
||||||
domain = config.NO_DOMAIN_DEFAULT
|
domain = config.MISSING_DEFAULT
|
||||||
}
|
}
|
||||||
|
|
||||||
secretsOverview := strings.Join(secrets, "\n")
|
secretsOverview := strings.Join(secrets, "\n")
|
||||||
if len(secrets) == 0 {
|
if len(secrets) == 0 {
|
||||||
secretsOverview = config.NO_SECRETS_DEFAULT
|
secretsOverview = config.MISSING_DEFAULT
|
||||||
}
|
}
|
||||||
|
|
||||||
volumesOverview := strings.Join(volumes, "\n")
|
volumesOverview := strings.Join(volumes, "\n")
|
||||||
if len(volumes) == 0 {
|
if len(volumes) == 0 {
|
||||||
volumesOverview = config.NO_VOLUMES_DEFAULT
|
volumesOverview = config.MISSING_DEFAULT
|
||||||
}
|
}
|
||||||
|
|
||||||
rows := [][]string{
|
rows := [][]string{
|
||||||
|
|||||||
@ -119,7 +119,7 @@ func init() {
|
|||||||
RecipeFetchCommand.Flags().BoolVarP(
|
RecipeFetchCommand.Flags().BoolVarP(
|
||||||
&fetchAllRecipes,
|
&fetchAllRecipes,
|
||||||
i18n.G("all"),
|
i18n.G("all"),
|
||||||
i18n.G("a"),
|
i18n.GC("a", "recipe fetch"),
|
||||||
false,
|
false,
|
||||||
i18n.G("fetch all recipes"),
|
i18n.G("fetch all recipes"),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -135,14 +135,23 @@ your private key and enter your passphrase beforehand.
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if tagString == "" && (!internal.Major && !internal.Minor && !internal.Patch) {
|
labelVersion, err := getLabelVersion(recipe, false)
|
||||||
var err error
|
if err != nil {
|
||||||
tagString, err = getLabelVersion(recipe, false)
|
log.Fatal(err)
|
||||||
if err != nil {
|
}
|
||||||
log.Fatal(err)
|
|
||||||
|
for _, tag := range tags {
|
||||||
|
previousTagLeftHand := strings.Split(tag, "+")[0]
|
||||||
|
newTagStringLeftHand := strings.Split(labelVersion, "+")[0]
|
||||||
|
if previousTagLeftHand == newTagStringLeftHand {
|
||||||
|
log.Fatal(i18n.G("%s+... conflicts with a previous release: %s", newTagStringLeftHand, tag))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tagString == "" && (!internal.Major && !internal.Minor && !internal.Patch) {
|
||||||
|
tagString = labelVersion
|
||||||
|
}
|
||||||
|
|
||||||
isClean, err := gitPkg.IsClean(recipe.Dir)
|
isClean, err := gitPkg.IsClean(recipe.Dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -321,7 +330,7 @@ func addReleaseNotes(recipe recipe.Recipe, tag string) error {
|
|||||||
|
|
||||||
if !internal.NoInput {
|
if !internal.NoInput {
|
||||||
prompt := &survey.Confirm{
|
prompt := &survey.Confirm{
|
||||||
Message: i18n.G("Use release note in release/next?"),
|
Message: i18n.G("use release note in release/next?"),
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := survey.AskOne(prompt, &addNextAsReleaseNotes); err != nil {
|
if err := survey.AskOne(prompt, &addNextAsReleaseNotes); err != nil {
|
||||||
|
|||||||
@ -140,13 +140,15 @@ likely to change.
|
|||||||
if serviceVersions, ok := recipeVersion[latestRecipeVersion]; ok {
|
if serviceVersions, ok := recipeVersion[latestRecipeVersion]; ok {
|
||||||
for serviceName := range serviceVersions {
|
for serviceName := range serviceVersions {
|
||||||
serviceMeta := serviceVersions[serviceName]
|
serviceMeta := serviceVersions[serviceName]
|
||||||
changesTable.Row(
|
|
||||||
[]string{
|
existingImageTag := fmt.Sprintf("%s:%s", serviceMeta.Image, serviceMeta.Tag)
|
||||||
serviceName,
|
newImageTag := fmt.Sprintf("%s:%s", serviceMeta.Image, imagesTmp[serviceMeta.Image])
|
||||||
fmt.Sprintf("%s:%s", serviceMeta.Image, serviceMeta.Tag),
|
|
||||||
fmt.Sprintf("%s:%s", serviceMeta.Image, imagesTmp[serviceMeta.Image]),
|
if existingImageTag == newImageTag {
|
||||||
}...,
|
continue
|
||||||
)
|
}
|
||||||
|
|
||||||
|
changesTable.Row([]string{serviceName, existingImageTag, newImageTag}...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -381,7 +381,7 @@ func init() {
|
|||||||
RecipeUpgradeCommand.Flags().BoolVarP(
|
RecipeUpgradeCommand.Flags().BoolVarP(
|
||||||
&allTags,
|
&allTags,
|
||||||
i18n.G("all-tags"),
|
i18n.G("all-tags"),
|
||||||
i18n.G("a"),
|
i18n.GC("a", "recipe upgrade"),
|
||||||
false,
|
false,
|
||||||
i18n.G("list all tags, not just upgrades"),
|
i18n.G("list all tags, not just upgrades"),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -283,6 +283,11 @@ Config:
|
|||||||
app.AppBackupSnapshotsCommand,
|
app.AppBackupSnapshotsCommand,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
app.AppEnvCommand.AddCommand(
|
||||||
|
app.AppEnvListCommand,
|
||||||
|
app.AppEnvPullCommand,
|
||||||
|
)
|
||||||
|
|
||||||
app.AppCommand.AddCommand(
|
app.AppCommand.AddCommand(
|
||||||
app.AppBackupCommand,
|
app.AppBackupCommand,
|
||||||
app.AppCheckCommand,
|
app.AppCheckCommand,
|
||||||
|
|||||||
@ -20,7 +20,7 @@ import (
|
|||||||
|
|
||||||
// translators: `abra server add` aliases. use a comma separated list of
|
// translators: `abra server add` aliases. use a comma separated list of
|
||||||
// aliases with no spaces in between
|
// aliases with no spaces in between
|
||||||
var serverAddAliases = i18n.G("a")
|
var serverAddAliases = i18n.GC("a", "server add")
|
||||||
|
|
||||||
var ServerAddCommand = &cobra.Command{
|
var ServerAddCommand = &cobra.Command{
|
||||||
// translators: `server add` command
|
// translators: `server add` command
|
||||||
|
|||||||
@ -96,7 +96,7 @@ func init() {
|
|||||||
ServerPruneCommand.Flags().BoolVarP(
|
ServerPruneCommand.Flags().BoolVarP(
|
||||||
&allFilter,
|
&allFilter,
|
||||||
i18n.G("all"),
|
i18n.G("all"),
|
||||||
i18n.G("a"),
|
i18n.GC("a", "server prune"),
|
||||||
false,
|
false,
|
||||||
i18n.G("remove all unused images"),
|
i18n.G("remove all unused images"),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,558 +0,0 @@
|
|||||||
package updater
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
|
||||||
appPkg "coopcloud.tech/abra/pkg/app"
|
|
||||||
"coopcloud.tech/abra/pkg/client"
|
|
||||||
"coopcloud.tech/abra/pkg/deploy"
|
|
||||||
"coopcloud.tech/abra/pkg/envfile"
|
|
||||||
"coopcloud.tech/abra/pkg/i18n"
|
|
||||||
"coopcloud.tech/abra/pkg/lint"
|
|
||||||
"coopcloud.tech/abra/pkg/recipe"
|
|
||||||
"coopcloud.tech/abra/pkg/upstream/convert"
|
|
||||||
"coopcloud.tech/abra/pkg/upstream/stack"
|
|
||||||
"coopcloud.tech/tagcmp"
|
|
||||||
charmLog "github.com/charmbracelet/log"
|
|
||||||
composetypes "github.com/docker/cli/cli/compose/types"
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
dockerclient "github.com/docker/docker/client"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
"coopcloud.tech/abra/pkg/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
const SERVER = "localhost"
|
|
||||||
|
|
||||||
// translators: `kadabra notify` aliases. use a comma separated list of aliases
|
|
||||||
// with no spaces in between
|
|
||||||
var notifyAliases = i18n.G("n")
|
|
||||||
|
|
||||||
// NotifyCommand checks for available upgrades.
|
|
||||||
var NotifyCommand = &cobra.Command{
|
|
||||||
// translators: `notify` command
|
|
||||||
Use: i18n.G("notify [flags]"),
|
|
||||||
Aliases: strings.Split(notifyAliases, ","),
|
|
||||||
// translators: Short description for `notify` command
|
|
||||||
Short: i18n.G("Check for available upgrades"),
|
|
||||||
Long: i18n.G(`Notify on new versions for deployed apps.
|
|
||||||
|
|
||||||
If a new patch/minor version is available, a notification is printed.
|
|
||||||
|
|
||||||
Use "--major/-m" to include new major versions.`),
|
|
||||||
Args: cobra.NoArgs,
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
cl, err := client.New("default")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
stacks, err := stack.GetStacks(cl)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, stackInfo := range stacks {
|
|
||||||
stackName := stackInfo.Name
|
|
||||||
recipeName, err := getLabel(cl, stackName, "recipe")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if recipeName != "" {
|
|
||||||
_, err = getLatestUpgrade(cl, stackName, recipeName)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// translators: `kadabra upgrade` aliases. use a comma separated list of aliases with
|
|
||||||
// no spaces in between
|
|
||||||
var upgradeAliases = i18n.G("u")
|
|
||||||
|
|
||||||
// UpgradeCommand upgrades apps.
|
|
||||||
var UpgradeCommand = &cobra.Command{
|
|
||||||
// translators: `app upgrade` command
|
|
||||||
Use: i18n.G("upgrade [[stack] [recipe] | --all] [flags]"),
|
|
||||||
Aliases: strings.Split(upgradeAliases, ","),
|
|
||||||
// translators: Short description for `app upgrade` command
|
|
||||||
Short: i18n.G("Upgrade apps"),
|
|
||||||
Long: i18n.G(`Upgrade an app by specifying stack name and recipe.
|
|
||||||
|
|
||||||
Use "--all" to upgrade every deployed app.
|
|
||||||
|
|
||||||
For each app with auto updates enabled, the deployed version is compared with
|
|
||||||
the current recipe catalogue version. If a new patch/minor version is
|
|
||||||
available, the app is upgraded.
|
|
||||||
|
|
||||||
To include major versions use the "--major/-m" flag. You probably don't want
|
|
||||||
that as it will break things. Only apps that are not deployed with "--chaos/-C"
|
|
||||||
are upgraded, to update chaos deployments use the "--chaos/-C" flag. Use it
|
|
||||||
with care.`),
|
|
||||||
Args: cobra.RangeArgs(0, 2),
|
|
||||||
// TODO(d1): complete stack/recipe
|
|
||||||
// ValidArgsFunction: func(
|
|
||||||
// cmd *cobra.Command,
|
|
||||||
// args []string,
|
|
||||||
// toComplete string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
// },
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
cl, err := client.New("default")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !updateAll && len(args) != 2 {
|
|
||||||
log.Fatal(i18n.G("missing arguments or --all/-a flag"))
|
|
||||||
}
|
|
||||||
|
|
||||||
if !updateAll {
|
|
||||||
stackName := args[0]
|
|
||||||
recipeName := args[1]
|
|
||||||
|
|
||||||
err = tryUpgrade(cl, stackName, recipeName)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
stacks, err := stack.GetStacks(cl)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, stackInfo := range stacks {
|
|
||||||
stackName := stackInfo.Name
|
|
||||||
recipeName, err := getLabel(cl, stackName, "recipe")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = tryUpgrade(cl, stackName, recipeName)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// getLabel reads docker labels from running services in the format of "coop-cloud.${STACK_NAME}.${LABEL}".
|
|
||||||
func getLabel(cl *dockerclient.Client, stackName string, label string) (string, error) {
|
|
||||||
filter := filters.NewArgs()
|
|
||||||
filter.Add("label", fmt.Sprintf("%s=%s", convert.LabelNamespace, stackName))
|
|
||||||
|
|
||||||
services, err := cl.ServiceList(context.Background(), types.ServiceListOptions{Filters: filter})
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, service := range services {
|
|
||||||
labelKey := fmt.Sprintf("coop-cloud.%s.%s", stackName, label)
|
|
||||||
if labelValue, ok := service.Spec.Labels[labelKey]; ok {
|
|
||||||
return labelValue, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debug(i18n.G("no %s label found for %s", label, stackName))
|
|
||||||
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getBoolLabel reads a boolean docker label from running services
|
|
||||||
func getBoolLabel(cl *dockerclient.Client, stackName string, label string) (bool, error) {
|
|
||||||
lableValue, err := getLabel(cl, stackName, label)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if lableValue != "" {
|
|
||||||
value, err := strconv.ParseBool(lableValue)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return value, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debug(i18n.G("boolean label %s could not be found for %s, set default to false.", label, stackName))
|
|
||||||
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getEnv reads env variables from docker services.
|
|
||||||
func getEnv(cl *dockerclient.Client, stackName string) (envfile.AppEnv, error) {
|
|
||||||
envMap := make(map[string]string)
|
|
||||||
filter := filters.NewArgs()
|
|
||||||
filter.Add("label", fmt.Sprintf("%s=%s", convert.LabelNamespace, stackName))
|
|
||||||
|
|
||||||
services, err := cl.ServiceList(context.Background(), types.ServiceListOptions{Filters: filter})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, service := range services {
|
|
||||||
envList := service.Spec.TaskTemplate.ContainerSpec.Env
|
|
||||||
for _, envString := range envList {
|
|
||||||
splitString := strings.SplitN(envString, "=", 2)
|
|
||||||
if len(splitString) != 2 {
|
|
||||||
log.Debug(i18n.G("can't separate key from value: %s (this variable is probably unset)", envString))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
k := splitString[0]
|
|
||||||
v := splitString[1]
|
|
||||||
log.Debugf(i18n.G("for %s read env %s with value: %s from docker service", stackName, k, v))
|
|
||||||
envMap[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return envMap, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getLatestUpgrade returns the latest available version for an app respecting
|
|
||||||
// the "--major" flag if it is newer than the currently deployed version.
|
|
||||||
func getLatestUpgrade(cl *dockerclient.Client, stackName string, recipeName string) (string, error) {
|
|
||||||
deployedVersion, err := getDeployedVersion(cl, stackName, recipeName)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
availableUpgrades, err := getAvailableUpgrades(cl, stackName, recipeName, deployedVersion)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(availableUpgrades) == 0 {
|
|
||||||
log.Debugf(i18n.G("no available upgrades for %s", stackName))
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var chosenUpgrade string
|
|
||||||
if len(availableUpgrades) > 0 {
|
|
||||||
chosenUpgrade = availableUpgrades[len(availableUpgrades)-1]
|
|
||||||
log.Info(i18n.G("%s (%s) can be upgraded from version %s to %s", stackName, recipeName, deployedVersion, chosenUpgrade))
|
|
||||||
}
|
|
||||||
|
|
||||||
return chosenUpgrade, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getDeployedVersion returns the currently deployed version of an app.
|
|
||||||
func getDeployedVersion(cl *dockerclient.Client, stackName string, recipeName string) (string, error) {
|
|
||||||
log.Debug(i18n.G("retrieve deployed version whether %s is already deployed", stackName))
|
|
||||||
|
|
||||||
deployMeta, err := stack.IsDeployed(context.Background(), cl, stackName)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !deployMeta.IsDeployed {
|
|
||||||
return "", errors.New(i18n.G("%s is not deployed?", stackName))
|
|
||||||
}
|
|
||||||
|
|
||||||
if deployMeta.Version == "unknown" {
|
|
||||||
return "", errors.New(i18n.G("failed to determine deployed version of %s", stackName))
|
|
||||||
}
|
|
||||||
|
|
||||||
return deployMeta.Version, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getAvailableUpgrades returns all available versions of an app that are newer
|
|
||||||
// than the deployed version. It only includes major upgrades if the "--major"
|
|
||||||
// flag is set.
|
|
||||||
func getAvailableUpgrades(cl *dockerclient.Client, stackName string, recipeName string,
|
|
||||||
deployedVersion string) ([]string, error) {
|
|
||||||
catl, err := recipe.ReadRecipeCatalogue(internal.Offline)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
versions, err := recipe.GetRecipeCatalogueVersions(recipeName, catl)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(versions) == 0 {
|
|
||||||
log.Warn(i18n.G("no published releases for %s in the recipe catalogue?", recipeName))
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var availableUpgrades []string
|
|
||||||
for _, version := range versions {
|
|
||||||
parsedDeployedVersion, err := tagcmp.Parse(deployedVersion)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
parsedVersion, err := tagcmp.Parse(version)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
versionDelta, err := parsedDeployedVersion.UpgradeDelta(parsedVersion)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if 0 < versionDelta.UpgradeType() && (versionDelta.UpgradeType() < 4 || includeMajorUpdates) {
|
|
||||||
availableUpgrades = append(availableUpgrades, version)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debug(i18n.G("available updates for %s: %s", stackName, availableUpgrades))
|
|
||||||
|
|
||||||
return availableUpgrades, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// processRecipeRepoVersion clones, pulls, checks out the version and lints the
|
|
||||||
// recipe repository.
|
|
||||||
func processRecipeRepoVersion(r recipe.Recipe, version string) error {
|
|
||||||
if err := r.EnsureExists(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := r.EnsureUpToDate(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := r.EnsureVersion(version); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := lint.LintForErrors(r); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// createDeployConfig merges and enriches the compose config for the deployment.
|
|
||||||
func createDeployConfig(r recipe.Recipe, stackName string, env envfile.AppEnv) (*composetypes.Config, stack.Deploy, error) {
|
|
||||||
env["STACK_NAME"] = stackName
|
|
||||||
|
|
||||||
deployOpts := stack.Deploy{
|
|
||||||
Namespace: stackName,
|
|
||||||
Prune: false,
|
|
||||||
ResolveImage: stack.ResolveImageAlways,
|
|
||||||
Detach: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
composeFiles, err := r.GetComposeFiles(env)
|
|
||||||
if err != nil {
|
|
||||||
return nil, deployOpts, err
|
|
||||||
}
|
|
||||||
|
|
||||||
deployOpts.Composefiles = composeFiles
|
|
||||||
compose, err := appPkg.GetAppComposeConfig(stackName, deployOpts, env)
|
|
||||||
if err != nil {
|
|
||||||
return nil, deployOpts, err
|
|
||||||
}
|
|
||||||
|
|
||||||
appPkg.ExposeAllEnv(stackName, compose, env)
|
|
||||||
|
|
||||||
// after the upgrade the deployment won't be in chaos state anymore
|
|
||||||
appPkg.SetChaosLabel(compose, stackName, false)
|
|
||||||
appPkg.SetRecipeLabel(compose, stackName, r.Name)
|
|
||||||
appPkg.SetUpdateLabel(compose, stackName, env)
|
|
||||||
|
|
||||||
return compose, deployOpts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// tryUpgrade performs the upgrade if all the requirements are fulfilled.
|
|
||||||
func tryUpgrade(cl *dockerclient.Client, stackName, recipeName string) error {
|
|
||||||
if recipeName == "" {
|
|
||||||
log.Debug(i18n.G("don't update %s due to missing recipe name", stackName))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
chaos, err := getBoolLabel(cl, stackName, "chaos")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if chaos && !internal.Chaos {
|
|
||||||
log.Debug(i18n.G("don't update %s due to chaos deployment", stackName))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
updatesEnabled, err := getBoolLabel(cl, stackName, "autoupdate")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !updatesEnabled {
|
|
||||||
log.Debug(i18n.G("don't update %s due to disabled auto updates or missing ENABLE_AUTO_UPDATE env", stackName))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
upgradeVersion, err := getLatestUpgrade(cl, stackName, recipeName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if upgradeVersion == "" {
|
|
||||||
log.Debug(i18n.G("don't update %s due to no new version", stackName))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err = upgrade(cl, stackName, recipeName, upgradeVersion)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// upgrade performs all necessary steps to upgrade an app.
|
|
||||||
func upgrade(cl *dockerclient.Client, stackName, recipeName, upgradeVersion string) error {
|
|
||||||
env, err := getEnv(cl, stackName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
app := appPkg.App{
|
|
||||||
Name: stackName,
|
|
||||||
Recipe: recipe.Get(recipeName),
|
|
||||||
Server: SERVER,
|
|
||||||
Env: env,
|
|
||||||
}
|
|
||||||
|
|
||||||
r := recipe.Get(recipeName)
|
|
||||||
|
|
||||||
if err = processRecipeRepoVersion(r, upgradeVersion); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = deploy.MergeAbraShEnv(app.Recipe, app.Env); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
compose, deployOpts, err := createDeployConfig(r, stackName, app.Env)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info(i18n.G("upgrade %s (%s) to version %s", stackName, recipeName, upgradeVersion))
|
|
||||||
|
|
||||||
serviceNames, err := appPkg.GetAppServiceNames(app.Name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := app.Filters(true, false, serviceNames...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = stack.RunDeploy(
|
|
||||||
cl,
|
|
||||||
deployOpts,
|
|
||||||
compose,
|
|
||||||
stackName,
|
|
||||||
app.Server,
|
|
||||||
true,
|
|
||||||
f,
|
|
||||||
)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func newKadabraApp(version, commit string) *cobra.Command {
|
|
||||||
rootCmd := &cobra.Command{
|
|
||||||
// translators: `kadabra` binary name
|
|
||||||
Use: i18n.G("kadabra [cmd] [flags]"),
|
|
||||||
Version: fmt.Sprintf("%s-%s", version, commit[:7]),
|
|
||||||
// translators: Short description for `kababra` binary
|
|
||||||
Short: i18n.G("The Co-op Cloud auto-updater 🤖 🚀"),
|
|
||||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
|
||||||
log.Logger.SetStyles(charmLog.DefaultStyles())
|
|
||||||
charmLog.SetDefault(log.Logger)
|
|
||||||
|
|
||||||
if internal.Debug {
|
|
||||||
log.SetLevel(log.DebugLevel)
|
|
||||||
log.SetOutput(os.Stderr)
|
|
||||||
log.SetReportCaller(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debug(i18n.G("kadabra version %s, commit %s", version, commit))
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
rootCmd.PersistentFlags().BoolVarP(
|
|
||||||
&internal.Debug,
|
|
||||||
i18n.G("debug"),
|
|
||||||
i18n.G("d"),
|
|
||||||
false,
|
|
||||||
i18n.G("show debug messages"),
|
|
||||||
)
|
|
||||||
|
|
||||||
rootCmd.PersistentFlags().BoolVarP(
|
|
||||||
&internal.NoInput,
|
|
||||||
i18n.G("no-input"),
|
|
||||||
i18n.G("n"),
|
|
||||||
false,
|
|
||||||
i18n.G("toggle non-interactive mode"),
|
|
||||||
)
|
|
||||||
|
|
||||||
rootCmd.AddCommand(
|
|
||||||
NotifyCommand,
|
|
||||||
UpgradeCommand,
|
|
||||||
)
|
|
||||||
|
|
||||||
return rootCmd
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunApp runs CLI abra app.
|
|
||||||
func RunApp(version, commit string) {
|
|
||||||
app := newKadabraApp(version, commit)
|
|
||||||
|
|
||||||
if err := app.Execute(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
includeMajorUpdates bool
|
|
||||||
updateAll bool
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
NotifyCommand.Flags().BoolVarP(
|
|
||||||
&includeMajorUpdates,
|
|
||||||
"major",
|
|
||||||
"m",
|
|
||||||
false,
|
|
||||||
"check for major updates",
|
|
||||||
)
|
|
||||||
|
|
||||||
UpgradeCommand.Flags().BoolVarP(
|
|
||||||
&internal.Chaos,
|
|
||||||
i18n.G("chaos"),
|
|
||||||
i18n.G("C"),
|
|
||||||
false,
|
|
||||||
i18n.G("ignore uncommitted recipes changes"),
|
|
||||||
)
|
|
||||||
|
|
||||||
UpgradeCommand.Flags().BoolVarP(
|
|
||||||
&includeMajorUpdates,
|
|
||||||
i18n.G("major"),
|
|
||||||
i18n.G("m"),
|
|
||||||
false,
|
|
||||||
i18n.G("check for major updates"),
|
|
||||||
)
|
|
||||||
|
|
||||||
UpgradeCommand.Flags().BoolVarP(
|
|
||||||
&updateAll,
|
|
||||||
i18n.G("all"),
|
|
||||||
i18n.G("a"),
|
|
||||||
false,
|
|
||||||
i18n.G("update all deployed apps"),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
// Package main provides the command-line entrypoint.
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"coopcloud.tech/abra/cli/updater"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Version is the current version of Kadabra.
|
|
||||||
var Version string
|
|
||||||
|
|
||||||
// Commit is the current git commit of Kadabra.
|
|
||||||
var Commit string
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
if Version == "" {
|
|
||||||
Version = "dev"
|
|
||||||
}
|
|
||||||
if Commit == "" {
|
|
||||||
Commit = " "
|
|
||||||
}
|
|
||||||
|
|
||||||
updater.RunApp(Version, Commit)
|
|
||||||
}
|
|
||||||
106
go.mod
106
go.mod
@ -1,28 +1,26 @@
|
|||||||
module coopcloud.tech/abra
|
module coopcloud.tech/abra
|
||||||
|
|
||||||
go 1.24.0
|
go 1.24.2
|
||||||
|
|
||||||
toolchain go1.24.1
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
coopcloud.tech/tagcmp v0.0.0-20250818180036-0ec1b205b5ca
|
coopcloud.tech/tagcmp v0.0.0-20250818180036-0ec1b205b5ca
|
||||||
git.coopcloud.tech/toolshed/godotenv v1.5.2-0.20250103171850-4d0ca41daa5c
|
git.coopcloud.tech/toolshed/godotenv v1.5.2-0.20250103171850-4d0ca41daa5c
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||||
github.com/charmbracelet/bubbletea v1.3.6
|
github.com/charmbracelet/bubbletea v1.3.10
|
||||||
github.com/charmbracelet/lipgloss v1.1.0
|
github.com/charmbracelet/lipgloss v1.1.0
|
||||||
github.com/charmbracelet/log v0.4.2
|
github.com/charmbracelet/log v0.4.2
|
||||||
github.com/distribution/reference v0.6.0
|
github.com/distribution/reference v0.6.0
|
||||||
github.com/docker/cli v28.3.3+incompatible
|
github.com/docker/cli v29.0.0+incompatible
|
||||||
github.com/docker/docker v28.3.3+incompatible
|
github.com/docker/docker v28.5.2+incompatible
|
||||||
github.com/docker/go-units v0.5.0
|
github.com/docker/go-units v0.5.0
|
||||||
github.com/go-git/go-git/v5 v5.16.2
|
github.com/go-git/go-git/v5 v5.16.3
|
||||||
github.com/google/go-cmp v0.7.0
|
github.com/google/go-cmp v0.7.0
|
||||||
github.com/leonelquinteros/gotext v1.7.2
|
github.com/leonelquinteros/gotext v1.7.2
|
||||||
github.com/moby/sys/signal v0.7.1
|
github.com/moby/sys/signal v0.7.1
|
||||||
github.com/moby/term v0.5.2
|
github.com/moby/term v0.5.2
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/schollz/progressbar/v3 v3.18.0
|
github.com/schollz/progressbar/v3 v3.18.0
|
||||||
golang.org/x/term v0.34.0
|
golang.org/x/term v0.36.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
gotest.tools/v3 v3.5.2
|
gotest.tools/v3 v3.5.2
|
||||||
)
|
)
|
||||||
@ -38,17 +36,21 @@ require (
|
|||||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||||
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/charmbracelet/colorprofile v0.3.2 // indirect
|
github.com/charmbracelet/colorprofile v0.3.3 // indirect
|
||||||
github.com/charmbracelet/x/ansi v0.10.1 // indirect
|
github.com/charmbracelet/x/ansi v0.11.0 // indirect
|
||||||
github.com/charmbracelet/x/cellbuf v0.0.13 // indirect
|
github.com/charmbracelet/x/cellbuf v0.0.14 // indirect
|
||||||
github.com/charmbracelet/x/term v0.2.1 // indirect
|
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 // indirect
|
||||||
|
github.com/charmbracelet/x/term v0.2.2 // indirect
|
||||||
|
github.com/clipperhouse/displaywidth v0.5.0 // indirect
|
||||||
|
github.com/clipperhouse/stringish v0.1.1 // indirect
|
||||||
|
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
|
||||||
github.com/cloudflare/circl v1.6.1 // indirect
|
github.com/cloudflare/circl v1.6.1 // indirect
|
||||||
github.com/containerd/errdefs v1.0.0 // indirect
|
github.com/containerd/errdefs v1.0.0 // indirect
|
||||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||||
github.com/containerd/log v0.1.0 // indirect
|
github.com/containerd/log v0.1.0 // indirect
|
||||||
github.com/containerd/platforms v0.2.1 // indirect
|
github.com/containerd/platforms v0.2.1 // indirect
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
|
||||||
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
github.com/cyphar/filepath-securejoin v0.6.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||||
github.com/docker/go-connections v0.6.0 // indirect
|
github.com/docker/go-connections v0.6.0 // indirect
|
||||||
@ -60,30 +62,32 @@ require (
|
|||||||
github.com/ghodss/yaml v1.0.0 // indirect
|
github.com/ghodss/yaml v1.0.0 // indirect
|
||||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||||
github.com/go-git/go-billy/v5 v5.6.2 // indirect
|
github.com/go-git/go-billy/v5 v5.6.2 // indirect
|
||||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
github.com/go-logfmt/logfmt v0.6.1 // indirect
|
||||||
github.com/go-logr/logr v1.4.3 // indirect
|
github.com/go-logr/logr v1.4.3 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
|
||||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
github.com/kevinburke/ssh_config v1.4.0 // indirect
|
||||||
github.com/klauspost/compress v1.18.0 // indirect
|
github.com/klauspost/compress v1.18.1 // indirect
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||||
|
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mattn/go-localereader v0.0.1 // indirect
|
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
github.com/mattn/go-runewidth v0.0.19 // indirect
|
||||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||||
github.com/miekg/pkcs11 v1.1.1 // indirect
|
github.com/miekg/pkcs11 v1.1.1 // indirect
|
||||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
|
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
|
||||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||||
github.com/moby/go-archive v0.1.0 // indirect
|
github.com/moby/go-archive v0.1.0 // indirect
|
||||||
|
github.com/moby/moby/api v1.52.0 // indirect
|
||||||
|
github.com/moby/moby/client v0.1.0 // indirect
|
||||||
github.com/moby/sys/atomicwriter v0.1.0 // indirect
|
github.com/moby/sys/atomicwriter v0.1.0 // indirect
|
||||||
github.com/moby/sys/user v0.4.0 // indirect
|
github.com/moby/sys/user v0.4.0 // indirect
|
||||||
github.com/moby/sys/userns v0.1.0 // indirect
|
github.com/moby/sys/userns v0.1.0 // indirect
|
||||||
@ -95,42 +99,42 @@ require (
|
|||||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
github.com/opencontainers/runc v1.1.13 // indirect
|
github.com/opencontainers/runc v1.1.13 // indirect
|
||||||
github.com/opencontainers/runtime-spec v1.1.0 // indirect
|
github.com/opencontainers/runtime-spec v1.1.0 // indirect
|
||||||
github.com/pjbgf/sha1cd v0.4.0 // indirect
|
github.com/pjbgf/sha1cd v0.5.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/prometheus/client_model v0.6.2 // indirect
|
github.com/prometheus/client_model v0.6.2 // indirect
|
||||||
github.com/prometheus/common v0.65.0 // indirect
|
github.com/prometheus/common v0.67.2 // indirect
|
||||||
github.com/prometheus/procfs v0.17.0 // indirect
|
github.com/prometheus/procfs v0.19.2 // indirect
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||||
github.com/skeema/knownhosts v1.3.1 // indirect
|
github.com/skeema/knownhosts v1.3.2 // indirect
|
||||||
github.com/spf13/pflag v1.0.7 // indirect
|
github.com/spf13/pflag v1.0.10 // indirect
|
||||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.37.0 // indirect
|
go.opentelemetry.io/otel v1.38.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.37.0 // indirect
|
go.opentelemetry.io/otel/metric v1.38.0 // indirect
|
||||||
go.opentelemetry.io/otel/sdk v1.37.0 // indirect
|
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect
|
go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.37.0 // indirect
|
go.opentelemetry.io/otel/trace v1.38.0 // indirect
|
||||||
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
|
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
|
||||||
golang.org/x/crypto v0.41.0 // indirect
|
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||||
golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 // indirect
|
golang.org/x/crypto v0.43.0 // indirect
|
||||||
golang.org/x/net v0.43.0 // indirect
|
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect
|
||||||
golang.org/x/sync v0.16.0 // indirect
|
golang.org/x/net v0.46.0 // indirect
|
||||||
golang.org/x/text v0.28.0 // indirect
|
golang.org/x/text v0.30.0 // indirect
|
||||||
golang.org/x/time v0.12.0 // indirect
|
golang.org/x/time v0.14.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20251110190251-83f479183930 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251110190251-83f479183930 // indirect
|
||||||
google.golang.org/grpc v1.74.2 // indirect
|
google.golang.org/grpc v1.76.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.7 // indirect
|
google.golang.org/protobuf v1.36.10 // indirect
|
||||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
)
|
)
|
||||||
@ -139,7 +143,7 @@ require (
|
|||||||
github.com/containers/image v3.0.2+incompatible
|
github.com/containers/image v3.0.2+incompatible
|
||||||
github.com/containers/storage v1.38.2 // indirect
|
github.com/containers/storage v1.38.2 // indirect
|
||||||
github.com/decentral1se/passgen v1.0.1
|
github.com/decentral1se/passgen v1.0.1
|
||||||
github.com/docker/docker-credential-helpers v0.9.3 // indirect
|
github.com/docker/docker-credential-helpers v0.9.4 // indirect
|
||||||
github.com/fvbommel/sortorder v1.1.0 // indirect
|
github.com/fvbommel/sortorder v1.1.0 // indirect
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||||
github.com/gorilla/mux v1.8.1 // indirect
|
github.com/gorilla/mux v1.8.1 // indirect
|
||||||
@ -147,11 +151,11 @@ require (
|
|||||||
github.com/moby/patternmatcher v0.6.0 // indirect
|
github.com/moby/patternmatcher v0.6.0 // indirect
|
||||||
github.com/moby/sys/sequential v0.6.0 // indirect
|
github.com/moby/sys/sequential v0.6.0 // indirect
|
||||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||||
github.com/prometheus/client_golang v1.23.0 // indirect
|
github.com/prometheus/client_golang v1.23.2 // indirect
|
||||||
github.com/sergi/go-diff v1.4.0 // indirect
|
github.com/sergi/go-diff v1.4.0 // indirect
|
||||||
github.com/spf13/cobra v1.9.1
|
github.com/spf13/cobra v1.10.1
|
||||||
github.com/stretchr/testify v1.10.0
|
github.com/stretchr/testify v1.11.1
|
||||||
github.com/theupdateframework/notary v0.7.0 // indirect
|
github.com/theupdateframework/notary v0.7.0 // indirect
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||||
golang.org/x/sys v0.35.0
|
golang.org/x/sys v0.38.0
|
||||||
)
|
)
|
||||||
|
|||||||
235
go.sum
235
go.sum
@ -129,26 +129,35 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY
|
|||||||
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
|
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
|
||||||
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
|
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/charmbracelet/bubbletea v1.3.6 h1:VkHIxPJQeDt0aFJIsVxw8BQdh/F/L2KKZGsK6et5taU=
|
github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
|
||||||
github.com/charmbracelet/bubbletea v1.3.6/go.mod h1:oQD9VCRQFF8KplacJLo28/jofOI2ToOfGYeFgBBxHOc=
|
github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4=
|
||||||
github.com/charmbracelet/colorprofile v0.3.2 h1:9J27WdztfJQVAQKX2WOlSSRB+5gaKqqITmrvb1uTIiI=
|
github.com/charmbracelet/colorprofile v0.3.2 h1:9J27WdztfJQVAQKX2WOlSSRB+5gaKqqITmrvb1uTIiI=
|
||||||
github.com/charmbracelet/colorprofile v0.3.2/go.mod h1:mTD5XzNeWHj8oqHb+S1bssQb7vIHbepiebQ2kPKVKbI=
|
github.com/charmbracelet/colorprofile v0.3.2/go.mod h1:mTD5XzNeWHj8oqHb+S1bssQb7vIHbepiebQ2kPKVKbI=
|
||||||
|
github.com/charmbracelet/colorprofile v0.3.3 h1:DjJzJtLP6/NZ8p7Cgjno0CKGr7wwRJGxWUwh2IyhfAI=
|
||||||
|
github.com/charmbracelet/colorprofile v0.3.3/go.mod h1:nB1FugsAbzq284eJcjfah2nhdSLppN2NqvfotkfRYP4=
|
||||||
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
|
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
|
||||||
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
|
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
|
||||||
github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig=
|
github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig=
|
||||||
github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw=
|
github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw=
|
||||||
github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ=
|
github.com/charmbracelet/x/ansi v0.10.2 h1:ith2ArZS0CJG30cIUfID1LXN7ZFXRCww6RUvAPA+Pzw=
|
||||||
github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
|
github.com/charmbracelet/x/ansi v0.10.2/go.mod h1:HbLdJjQH4UH4AqA2HpRWuWNluRE6zxJH/yteYEYCFa8=
|
||||||
|
github.com/charmbracelet/x/ansi v0.11.0 h1:uuIVK7GIplwX6UBIz8S2TF8nkr7xRlygSsBRjSJqIvA=
|
||||||
|
github.com/charmbracelet/x/ansi v0.11.0/go.mod h1:uQt8bOrq/xgXjlGcFMc8U2WYbnxyjrKhnvTQluvfCaE=
|
||||||
github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k=
|
github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k=
|
||||||
github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
|
github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
|
||||||
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a h1:G99klV19u0QnhiizODirwVksQB91TJKV/UaTnACcG30=
|
github.com/charmbracelet/x/cellbuf v0.0.14 h1:iUEMryGyFTelKW3THW4+FfPgi4fkmKnnaLOXuc+/Kj4=
|
||||||
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
|
github.com/charmbracelet/x/cellbuf v0.0.14/go.mod h1:P447lJl49ywBbil/KjCk2HexGh4tEY9LH0/1QrZZ9rA=
|
||||||
|
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ=
|
||||||
|
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
|
||||||
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
|
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
|
||||||
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
|
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
|
||||||
|
github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=
|
||||||
|
github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=
|
||||||
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
|
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
|
||||||
github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
|
github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
|
||||||
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
|
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
|
||||||
@ -164,6 +173,14 @@ github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJ
|
|||||||
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||||
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
|
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/clipperhouse/displaywidth v0.5.0 h1:AIG5vQaSL2EKqzt0M9JMnvNxOCRTKUc4vUnLWGgP89I=
|
||||||
|
github.com/clipperhouse/displaywidth v0.5.0/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
|
||||||
|
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
|
||||||
|
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
|
||||||
|
github.com/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY=
|
||||||
|
github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
|
||||||
|
github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
|
||||||
|
github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
|
||||||
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
|
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
|
||||||
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
||||||
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||||
@ -296,8 +313,10 @@ github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
|||||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||||
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||||
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
github.com/cyphar/filepath-securejoin v0.5.0 h1:hIAhkRBMQ8nIeuVwcAoymp7MY4oherZdAxD+m0u9zaw=
|
||||||
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
github.com/cyphar/filepath-securejoin v0.5.0/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||||
|
github.com/cyphar/filepath-securejoin v0.6.0 h1:BtGB77njd6SVO6VztOHfPxKitJvd/VPT+OFBFMOi1Is=
|
||||||
|
github.com/cyphar/filepath-securejoin v0.6.0/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc=
|
||||||
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
|
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
|
||||||
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
|
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
|
||||||
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
|
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
|
||||||
@ -316,19 +335,25 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
|
|||||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||||
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||||
github.com/docker/cli v28.3.3+incompatible h1:fp9ZHAr1WWPGdIWBM1b3zLtgCF+83gRdVMTJsUeiyAo=
|
github.com/docker/cli v28.4.0+incompatible h1:RBcf3Kjw2pMtwui5V0DIMdyeab8glEw5QY0UUU4C9kY=
|
||||||
github.com/docker/cli v28.3.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
github.com/docker/cli v28.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||||
|
github.com/docker/cli v29.0.0+incompatible h1:KgsN2RUFMNM8wChxryicn4p46BdQWpXOA1XLGBGPGAw=
|
||||||
|
github.com/docker/cli v29.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||||
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
||||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI=
|
github.com/docker/docker v28.4.0+incompatible h1:KVC7bz5zJY/4AZe/78BIvCnPsLaC9T/zh72xnlrTTOk=
|
||||||
github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v28.4.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
|
github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM=
|
||||||
|
github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
||||||
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
|
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
|
||||||
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
|
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
|
||||||
|
github.com/docker/docker-credential-helpers v0.9.4 h1:76ItO69/AP/V4yT9V4uuuItG0B1N8hvt0T0c0NN/DzI=
|
||||||
|
github.com/docker/docker-credential-helpers v0.9.4/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c=
|
||||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
||||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q=
|
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q=
|
||||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||||
@ -393,6 +418,8 @@ github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMj
|
|||||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||||
github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM=
|
github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM=
|
||||||
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
||||||
|
github.com/go-git/go-git/v5 v5.16.3 h1:Z8BtvxZ09bYm/yYNgPKCzgWtaRqDTgIKRgIRHBfU6Z8=
|
||||||
|
github.com/go-git/go-git/v5 v5.16.3/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
@ -403,6 +430,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
|
|||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
||||||
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||||
|
github.com/go-logfmt/logfmt v0.6.1 h1:4hvbpePJKnIzH1B+8OR/JPbTx37NktoI9LE2QZBBkvE=
|
||||||
|
github.com/go-logfmt/logfmt v0.6.1/go.mod h1:EV2pOAQoZaT1ZXZbqDl5hrymndi4SY9ED9/z6CO0XAk=
|
||||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
@ -439,7 +468,6 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV
|
|||||||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||||
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
@ -528,9 +556,12 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de
|
|||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww=
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU=
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90=
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4=
|
||||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||||
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
@ -579,8 +610,8 @@ github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVE
|
|||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
github.com/kevinburke/ssh_config v1.4.0 h1:6xxtP5bZ2E4NF5tuQulISpTO2z8XbtH8cg1PWkxoFkQ=
|
||||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
github.com/kevinburke/ssh_config v1.4.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M=
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
@ -590,6 +621,10 @@ github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdY
|
|||||||
github.com/klauspost/compress v1.14.2/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
github.com/klauspost/compress v1.14.2/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||||
|
github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co=
|
||||||
|
github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||||
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
@ -611,8 +646,8 @@ github.com/leonelquinteros/gotext v1.7.2 h1:bDPndU8nt+/kRo1m4l/1OXiiy2v7Z7dfPQ9+
|
|||||||
github.com/leonelquinteros/gotext v1.7.2/go.mod h1:9/haCkm5P7Jay1sxKDGJ5WIg4zkz8oZKw4ekNpALob8=
|
github.com/leonelquinteros/gotext v1.7.2/go.mod h1:9/haCkm5P7Jay1sxKDGJ5WIg4zkz8oZKw4ekNpALob8=
|
||||||
github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo=
|
github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo=
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag=
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||||
github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
@ -631,8 +666,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
|
|||||||
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
|
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
|
||||||
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
|
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
|
||||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
|
||||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
|
||||||
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||||
github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||||
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||||
@ -659,6 +694,10 @@ github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6U
|
|||||||
github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
|
github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
|
||||||
github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo=
|
github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo=
|
||||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||||
|
github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg=
|
||||||
|
github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc=
|
||||||
|
github.com/moby/moby/client v0.1.0 h1:nt+hn6O9cyJQqq5UWnFGqsZRTS/JirUqzPjEl0Bdc/8=
|
||||||
|
github.com/moby/moby/client v0.1.0/go.mod h1:O+/tw5d4a1Ha/ZA/tPxIZJapJRUS6LNZ1wiVRxYHyUE=
|
||||||
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
|
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
|
||||||
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||||
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
|
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
|
||||||
@ -758,8 +797,8 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt
|
|||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||||
github.com/pjbgf/sha1cd v0.4.0 h1:NXzbL1RvjTUi6kgYZCX3fPwwl27Q1LJndxtUDVfJGRY=
|
github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0=
|
||||||
github.com/pjbgf/sha1cd v0.4.0/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
|
github.com/pjbgf/sha1cd v0.5.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
@ -775,8 +814,8 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
|
|||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||||
github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
|
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
|
||||||
github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
|
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
|
||||||
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
@ -790,8 +829,10 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
|||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||||
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
|
github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
|
||||||
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
|
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
|
||||||
|
github.com/prometheus/common v0.67.2 h1:PcBAckGFTIHt2+L3I33uNRTlKTplNzFctXcWhPyAEN8=
|
||||||
|
github.com/prometheus/common v0.67.2/go.mod h1:63W3KZb1JOKgcjlIr64WW/LvFGAqKPj0atm+knVGEko=
|
||||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
@ -805,8 +846,9 @@ github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
|
|||||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||||
github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
|
github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
|
||||||
github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
|
github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
|
||||||
|
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
|
||||||
|
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
|
||||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
|
||||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
@ -814,6 +856,8 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
|
|||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||||
|
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
|
||||||
|
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
@ -839,6 +883,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ
|
|||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
|
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
|
||||||
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
|
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
|
||||||
|
github.com/skeema/knownhosts v1.3.2 h1:EDL9mgf4NzwMXCTfaxSD/o/a5fxDw/xL9nkU28JjdBg=
|
||||||
|
github.com/skeema/knownhosts v1.3.2/go.mod h1:bEg3iQAuw+jyiw+484wwFJoKSLwcfd7fqRy+N0QTiow=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
@ -851,8 +897,8 @@ github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3
|
|||||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||||
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
|
||||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
|
||||||
github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
@ -861,9 +907,9 @@ github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bd
|
|||||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
|
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||||
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
|
github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
|
||||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||||
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
|
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
|
||||||
@ -878,8 +924,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
|||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||||
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
|
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
|
||||||
@ -937,37 +983,41 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
|||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
|
||||||
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
||||||
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 h1:zG8GlgXCJQd5BU98C0hZnBbElszTmUgCNCfYneaDL0A=
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0/go.mod h1:hOfBCz8kv/wuq73Mx2H2QnWokh/kHZxkh6SNF2bdKtw=
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
|
||||||
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
|
||||||
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
|
||||||
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
|
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
|
||||||
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
|
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
|
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
|
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
|
||||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
|
||||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
|
||||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||||
go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
|
go.opentelemetry.io/proto/otlp v1.8.0 h1:fRAZQDcAFHySxpJ1TwlA1cJ4tvcrw7nXl9xWWC8N5CE=
|
||||||
go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
|
go.opentelemetry.io/proto/otlp v1.8.0/go.mod h1:tIeYOeNBU4cvmPqpaji1P+KbB4Oloai8wN4rWzRrFF0=
|
||||||
|
go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=
|
||||||
|
go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4=
|
||||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
|
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
|
||||||
|
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
|
||||||
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
@ -986,8 +1036,10 @@ golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWP
|
|||||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
|
||||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
|
||||||
|
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||||
|
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@ -998,8 +1050,10 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
|||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||||
golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 h1:SbTAbRFnd5kjQXbczszQ0hdk3ctwYf3qBNH9jIsGclE=
|
golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU=
|
||||||
golang.org/x/exp v0.0.0-20250813145105-42675adae3e6/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4=
|
golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk=
|
||||||
|
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY=
|
||||||
|
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70=
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
@ -1063,8 +1117,10 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
|
|||||||
golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
|
||||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||||
|
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
|
||||||
|
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@ -1082,8 +1138,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
|
||||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@ -1162,13 +1216,17 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
||||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
|
||||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
|
||||||
|
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
|
||||||
|
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@ -1178,16 +1236,20 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||||
|
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||||
|
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI=
|
||||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||||
|
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||||
|
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
@ -1237,6 +1299,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
|||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||||
|
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||||
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||||
@ -1281,10 +1345,14 @@ google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfG
|
|||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||||
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a h1:DMCgtIAIQGZqJXMVzJF4MV8BlWoJh2ZuFiRdAleyr58=
|
google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4 h1:8XJ4pajGwOlasW+L13MnEGA8W4115jJySQtVfS2/IBU=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a/go.mod h1:y2yVLIE/CSMCPXaHnSKXxu1spLPnglFLegmgdY23uuE=
|
google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4/go.mod h1:NnuHhy+bxcg30o7FnVAZbXsPHUDQ9qKWAQKCD7VxFtk=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a h1:tPE/Kp+x9dMSwUm/uM0JKK0IfdiJkwAbSMSeZBXXJXc=
|
google.golang.org/genproto/googleapis/api v0.0.0-20251110190251-83f479183930 h1:8BWFtrvJRbplrKV5VHlIm4YM726eeBPPAL2QDNWhRrU=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo=
|
google.golang.org/genproto/googleapis/api v0.0.0-20251110190251-83f479183930/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4 h1:i8QOKZfYg6AbGVZzUAY3LrNWCKF8O6zFisU9Wl9RER4=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251110190251-83f479183930 h1:tK4fkUnnRhig9TsTp4otV1FxwBFYgbKUq1RY0V6KZ4U=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251110190251-83f479183930/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
||||||
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||||
google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
@ -1304,8 +1372,10 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp
|
|||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||||
google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
|
google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
|
||||||
google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
|
google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||||
|
google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
|
||||||
|
google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
@ -1319,8 +1389,10 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
|||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
|
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||||
google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||||
|
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||||
|
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/cenkalti/backoff.v2 v2.2.1/go.mod h1:S0QdOvT2AlerfSBkp0O+dk+bbIMaNbEmVk876gPCthU=
|
gopkg.in/cenkalti/backoff.v2 v2.2.1/go.mod h1:S0QdOvT2AlerfSBkp0O+dk+bbIMaNbEmVk876gPCthU=
|
||||||
@ -1358,6 +1430,7 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||||
|
|||||||
@ -471,13 +471,6 @@ func GetAppStatuses(apps []App, MachineReadable bool) (map[string]map[string]str
|
|||||||
result["chaosVersion"] = chaosVersion
|
result["chaosVersion"] = chaosVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
labelKey = fmt.Sprintf("coop-cloud.%s.autoupdate", name)
|
|
||||||
if autoUpdate, ok := service.Spec.Labels[labelKey]; ok {
|
|
||||||
result["autoUpdate"] = autoUpdate
|
|
||||||
} else {
|
|
||||||
result["autoUpdate"] = "false"
|
|
||||||
}
|
|
||||||
|
|
||||||
labelKey = fmt.Sprintf("coop-cloud.%s.version", name)
|
labelKey = fmt.Sprintf("coop-cloud.%s.version", name)
|
||||||
if version, ok := service.Spec.Labels[labelKey]; ok {
|
if version, ok := service.Spec.Labels[labelKey]; ok {
|
||||||
result["version"] = version
|
result["version"] = version
|
||||||
@ -509,7 +502,11 @@ func GetAppComposeConfig(recipe string, opts stack.Deploy, appEnv envfile.AppEnv
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ExposeAllEnv exposes all env variables to the app container
|
// ExposeAllEnv exposes all env variables to the app container
|
||||||
func ExposeAllEnv(stackName string, compose *composetypes.Config, appEnv envfile.AppEnv) {
|
func ExposeAllEnv(
|
||||||
|
stackName string,
|
||||||
|
compose *composetypes.Config,
|
||||||
|
appEnv envfile.AppEnv,
|
||||||
|
toDeployVersion string) {
|
||||||
for _, service := range compose.Services {
|
for _, service := range compose.Services {
|
||||||
if service.Name == "app" {
|
if service.Name == "app" {
|
||||||
log.Debug(i18n.G("adding env vars to %s service config", stackName))
|
log.Debug(i18n.G("adding env vars to %s service config", stackName))
|
||||||
@ -517,6 +514,11 @@ func ExposeAllEnv(stackName string, compose *composetypes.Config, appEnv envfile
|
|||||||
_, exists := service.Environment[k]
|
_, exists := service.Environment[k]
|
||||||
if !exists {
|
if !exists {
|
||||||
value := v
|
value := v
|
||||||
|
if k == "TYPE" || k == "RECIPE" {
|
||||||
|
// NOTE(d1): don't use the wrong version from the app env
|
||||||
|
// since we are deploying a new version
|
||||||
|
value = toDeployVersion
|
||||||
|
}
|
||||||
service.Environment[k] = &value
|
service.Environment[k] = &value
|
||||||
log.Debug(i18n.G("%s: %s: %s", stackName, k, value))
|
log.Debug(i18n.G("%s: %s: %s", stackName, k, value))
|
||||||
}
|
}
|
||||||
@ -631,6 +633,11 @@ func (a App) WipeRecipeVersion() error {
|
|||||||
|
|
||||||
// WriteRecipeVersion writes the recipe version to the app .env file.
|
// WriteRecipeVersion writes the recipe version to the app .env file.
|
||||||
func (a App) WriteRecipeVersion(version string, dryRun bool) error {
|
func (a App) WriteRecipeVersion(version string, dryRun bool) error {
|
||||||
|
if version == config.UNKNOWN_DEFAULT {
|
||||||
|
log.Debug(i18n.G("version is unknown, skipping env write"))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
file, err := os.Open(a.Path)
|
file, err := os.Open(a.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@ -224,3 +224,16 @@ func TestWriteRecipeVersionOverwrite(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(t, "foo", app.Recipe.EnvVersion)
|
assert.Equal(t, "foo", app.Recipe.EnvVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWriteRecipeVersionUnknown(t *testing.T) {
|
||||||
|
app, err := appPkg.GetApp(testPkg.ExpectedAppFiles, testPkg.AppName)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := app.WriteRecipeVersion(config.UNKNOWN_DEFAULT, false); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NotEqual(t, config.UNKNOWN_DEFAULT, app.Recipe.EnvVersion)
|
||||||
|
}
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"coopcloud.tech/abra/pkg/envfile"
|
|
||||||
"coopcloud.tech/abra/pkg/i18n"
|
"coopcloud.tech/abra/pkg/i18n"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
composetypes "github.com/docker/cli/cli/compose/types"
|
composetypes "github.com/docker/cli/cli/compose/types"
|
||||||
@ -56,23 +55,6 @@ func SetVersionLabel(compose *composetypes.Config, stackName string, version str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetUpdateLabel adds env ENABLE_AUTO_UPDATE as label to enable/disable the
|
|
||||||
// auto update process for this app. The default if this variable is not set is to disable
|
|
||||||
// the auto update process.
|
|
||||||
func SetUpdateLabel(compose *composetypes.Config, stackName string, appEnv envfile.AppEnv) {
|
|
||||||
for _, service := range compose.Services {
|
|
||||||
if service.Name == "app" {
|
|
||||||
enable_auto_update, exists := appEnv["ENABLE_AUTO_UPDATE"]
|
|
||||||
if !exists {
|
|
||||||
enable_auto_update = "false"
|
|
||||||
}
|
|
||||||
log.Debug(i18n.G("set label 'coop-cloud.%s.autoupdate' to %s for %s", stackName, enable_auto_update, stackName))
|
|
||||||
labelKey := fmt.Sprintf("coop-cloud.%s.autoupdate", stackName)
|
|
||||||
service.Deploy.Labels[labelKey] = enable_auto_update
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetLabel reads docker labels in the format of "coop-cloud.${STACK_NAME}.${LABEL}" from the local compose files
|
// GetLabel reads docker labels in the format of "coop-cloud.${STACK_NAME}.${LABEL}" from the local compose files
|
||||||
func GetLabel(compose *composetypes.Config, stackName string, label string) string {
|
func GetLabel(compose *composetypes.Config, stackName string, label string) string {
|
||||||
for _, service := range compose.Services {
|
for _, service := range compose.Services {
|
||||||
|
|||||||
@ -6,9 +6,11 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"coopcloud.tech/abra/pkg/config"
|
||||||
contextPkg "coopcloud.tech/abra/pkg/context"
|
contextPkg "coopcloud.tech/abra/pkg/context"
|
||||||
"coopcloud.tech/abra/pkg/i18n"
|
"coopcloud.tech/abra/pkg/i18n"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
@ -35,13 +37,27 @@ func WithTimeout(timeout int) Opt {
|
|||||||
// New initiates a new Docker client. New client connections are validated so
|
// New initiates a new Docker client. New client connections are validated so
|
||||||
// that we ensure connections via SSH to the daemon can succeed. It takes into
|
// that we ensure connections via SSH to the daemon can succeed. It takes into
|
||||||
// account that you may only want the local client and not communicate via SSH.
|
// account that you may only want the local client and not communicate via SSH.
|
||||||
// For this use-case, please pass "default" as the contextName.
|
// For this use-case, please pass "default" as the serverName.
|
||||||
func New(serverName string, opts ...Opt) (*client.Client, error) {
|
func New(serverName string, opts ...Opt) (*client.Client, error) {
|
||||||
var clientOpts []client.Opt
|
var clientOpts []client.Opt
|
||||||
|
|
||||||
ctx, err := GetContext(serverName)
|
ctx, err := GetContext(serverName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New(i18n.G("unknown server, run \"abra server add %s\"?", serverName))
|
serverDir := path.Join(config.SERVERS_DIR, serverName)
|
||||||
|
if _, err := os.Stat(serverDir); err != nil {
|
||||||
|
return nil, errors.New(i18n.G("server missing, run \"abra server add %s\"?", serverName))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(p4u1): when the docker context does not exist but the server folder
|
||||||
|
// is there, let's create a new docker context.
|
||||||
|
if err = CreateContext(serverName); err != nil {
|
||||||
|
return nil, errors.New(i18n.G("server missing context, context creation failed: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, err = GetContext(serverName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New(i18n.G("server missing context, run \"abra server add %s\"?", serverName))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxEndpoint, err := contextPkg.GetContextEndpoint(ctx)
|
ctxEndpoint, err := contextPkg.GetContextEndpoint(ctx)
|
||||||
|
|||||||
@ -116,10 +116,7 @@ var (
|
|||||||
|
|
||||||
DIRTY_DEFAULT = "+U"
|
DIRTY_DEFAULT = "+U"
|
||||||
|
|
||||||
NO_DOMAIN_DEFAULT = "N/A"
|
MISSING_DEFAULT = "-"
|
||||||
NO_VERSION_DEFAULT = "N/A"
|
|
||||||
NO_SECRETS_DEFAULT = "N/A"
|
|
||||||
NO_VOLUMES_DEFAULT = "N/A"
|
|
||||||
|
|
||||||
UNKNOWN_DEFAULT = "unknown"
|
UNKNOWN_DEFAULT = "unknown"
|
||||||
)
|
)
|
||||||
|
|||||||
@ -20,6 +20,7 @@ var (
|
|||||||
Locale = DefaultLocale
|
Locale = DefaultLocale
|
||||||
_, Mo = LoadLocale()
|
_, Mo = LoadLocale()
|
||||||
G = Mo.Get
|
G = Mo.Get
|
||||||
|
GC = Mo.GetC
|
||||||
)
|
)
|
||||||
|
|
||||||
func LoadLocale() (string, *gotext.Mo) {
|
func LoadLocale() (string, *gotext.Mo) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -49,7 +49,7 @@ func (r Recipe) Ensure(ctx EnsureContext) error {
|
|||||||
if r.EnvVersion != "" && !ctx.IgnoreEnvVersion {
|
if r.EnvVersion != "" && !ctx.IgnoreEnvVersion {
|
||||||
log.Debug(i18n.G("ensuring env version %s", r.EnvVersion))
|
log.Debug(i18n.G("ensuring env version %s", r.EnvVersion))
|
||||||
if strings.Contains(r.EnvVersion, "+U") {
|
if strings.Contains(r.EnvVersion, "+U") {
|
||||||
return errors.New(i18n.G("can not redeploy chaos version (%s) without --chaos", r.EnvVersion))
|
return errors.New(i18n.G(`cannot redeploy previous chaos version (%s), did you mean to use "--chaos"?`))
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := r.EnsureVersion(r.EnvVersion); err != nil {
|
if _, err := r.EnsureVersion(r.EnvVersion); err != nil {
|
||||||
|
|||||||
@ -379,7 +379,7 @@ func ReadRecipeCatalogue(offline bool) (RecipeCatalogue, error) {
|
|||||||
|
|
||||||
if !offline {
|
if !offline {
|
||||||
if err := catalogue.EnsureUpToDate(); err != nil {
|
if err := catalogue.EnsureUpToDate(); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("unable to update catalogue: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -50,6 +50,11 @@ type Secret struct {
|
|||||||
// Will have this remote name:
|
// Will have this remote name:
|
||||||
// test_example_com_test_pass_two_v2
|
// test_example_com_test_pass_two_v2
|
||||||
RemoteName string
|
RemoteName string
|
||||||
|
|
||||||
|
// LocalName iis the name of the secret in the recipe config. This is also
|
||||||
|
// the name that you pass to `abra app secret insert` and is shown on `abra
|
||||||
|
// app secret list`
|
||||||
|
LocalName string
|
||||||
}
|
}
|
||||||
|
|
||||||
// GeneratePassword generates passwords.
|
// GeneratePassword generates passwords.
|
||||||
@ -133,7 +138,12 @@ func ReadSecretsConfig(appEnvPath string, composeFiles []string, stackName strin
|
|||||||
|
|
||||||
lastIdx := strings.LastIndex(secretConfig.Name, "_")
|
lastIdx := strings.LastIndex(secretConfig.Name, "_")
|
||||||
secretVersion := secretConfig.Name[lastIdx+1:]
|
secretVersion := secretConfig.Name[lastIdx+1:]
|
||||||
value := Secret{Version: secretVersion, RemoteName: secretConfig.Name}
|
|
||||||
|
value := Secret{
|
||||||
|
Version: secretVersion,
|
||||||
|
RemoteName: secretConfig.Name,
|
||||||
|
LocalName: secretId,
|
||||||
|
}
|
||||||
|
|
||||||
if len(value.RemoteName) > config.MAX_DOCKER_SECRET_LENGTH {
|
if len(value.RemoteName) > config.MAX_DOCKER_SECRET_LENGTH {
|
||||||
return nil, errors.New(i18n.G("secret %s is > %d chars when combined with %s", secretId, config.MAX_DOCKER_SECRET_LENGTH, stackName))
|
return nil, errors.New(i18n.G("secret %s is > %d chars when combined with %s", secretId, config.MAX_DOCKER_SECRET_LENGTH, stackName))
|
||||||
@ -178,6 +188,8 @@ func ReadSecretsConfig(appEnvPath string, composeFiles []string, stackName strin
|
|||||||
// resolveCharset sets the passgen Alphabet required for a secret
|
// resolveCharset sets the passgen Alphabet required for a secret
|
||||||
func resolveCharset(input string) string {
|
func resolveCharset(input string) string {
|
||||||
switch strings.ToLower(input) {
|
switch strings.ToLower(input) {
|
||||||
|
case "hex":
|
||||||
|
return passgen.AlphabetNumericAmbiguous + "abcdef"
|
||||||
case "special":
|
case "special":
|
||||||
return passgen.AlphabetSpecial
|
return passgen.AlphabetSpecial
|
||||||
case "safespecial":
|
case "safespecial":
|
||||||
|
|||||||
@ -48,6 +48,12 @@ func TestReadSecretsConfig(t *testing.T) {
|
|||||||
assert.Equal(t, "v1", secretsFromConfig["test_pass_six"].Version)
|
assert.Equal(t, "v1", secretsFromConfig["test_pass_six"].Version)
|
||||||
assert.Equal(t, 0, secretsFromConfig["test_pass_six"].Length)
|
assert.Equal(t, 0, secretsFromConfig["test_pass_six"].Length)
|
||||||
assert.Equal(t, "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789!@#$%^&*_-+=", secretsFromConfig["test_pass_six"].Charset)
|
assert.Equal(t, "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789!@#$%^&*_-+=", secretsFromConfig["test_pass_six"].Charset)
|
||||||
|
|
||||||
|
// Has a length modifier and a charset=hex modifier
|
||||||
|
assert.Equal(t, "test_example_com_test_pass_seven_v1", secretsFromConfig["test_pass_seven"].RemoteName)
|
||||||
|
assert.Equal(t, "v1", secretsFromConfig["test_pass_seven"].Version)
|
||||||
|
assert.Equal(t, 32, secretsFromConfig["test_pass_seven"].Length)
|
||||||
|
assert.Equal(t, "0123456789abcdef", secretsFromConfig["test_pass_seven"].Charset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadSecretsConfigWithLongDomain(t *testing.T) {
|
func TestReadSecretsConfigWithLongDomain(t *testing.T) {
|
||||||
|
|||||||
@ -4,3 +4,4 @@ SECRET_TEST_PASS_THREE_VERSION=v2
|
|||||||
SECRET_TEST_PASS_FOUR_VERSION=v1 # length=12 charset=default,safespecial
|
SECRET_TEST_PASS_FOUR_VERSION=v1 # length=12 charset=default,safespecial
|
||||||
SECRET_TEST_PASS_FIVE_VERSION=v1 # length=12 charset=default,special
|
SECRET_TEST_PASS_FIVE_VERSION=v1 # length=12 charset=default,special
|
||||||
SECRET_TEST_PASS_SIX_VERSION=v1 # charset=default,special
|
SECRET_TEST_PASS_SIX_VERSION=v1 # charset=default,special
|
||||||
|
SECRET_TEST_PASS_SEVEN_VERSION=v1 # length=32 charset=hex
|
||||||
|
|||||||
@ -11,6 +11,7 @@ services:
|
|||||||
- test_pass_four
|
- test_pass_four
|
||||||
- test_pass_five
|
- test_pass_five
|
||||||
- test_pass_six
|
- test_pass_six
|
||||||
|
- test_pass_seven
|
||||||
|
|
||||||
secrets:
|
secrets:
|
||||||
test_pass_one:
|
test_pass_one:
|
||||||
@ -31,3 +32,6 @@ secrets:
|
|||||||
test_pass_six:
|
test_pass_six:
|
||||||
external: true
|
external: true
|
||||||
name: ${STACK_NAME}_test_pass_six_${SECRET_TEST_PASS_SIX_VERSION}
|
name: ${STACK_NAME}_test_pass_six_${SECRET_TEST_PASS_SIX_VERSION}
|
||||||
|
test_pass_seven:
|
||||||
|
external: true
|
||||||
|
name: ${STACK_NAME}_test_pass_seven_${SECRET_TEST_PASS_SEVEN_VERSION}
|
||||||
|
|||||||
@ -247,7 +247,7 @@ func waitOnTasks(ctx context.Context, client apiclient.APIClient, namespace stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if terminalStatesReached == len(tasks) {
|
if terminalStatesReached >= len(tasks) {
|
||||||
log.Debug(i18n.G("all tasks reached terminal state"))
|
log.Debug(i18n.G("all tasks reached terminal state"))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/ui"
|
"coopcloud.tech/abra/pkg/ui"
|
||||||
"coopcloud.tech/abra/pkg/upstream/convert"
|
"coopcloud.tech/abra/pkg/upstream/convert"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/stack/formatter"
|
"github.com/docker/cli/cli/command/formatter"
|
||||||
composetypes "github.com/docker/cli/cli/compose/types"
|
composetypes "github.com/docker/cli/cli/compose/types"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
@ -201,6 +201,7 @@ func RunDeploy(
|
|||||||
appName string,
|
appName string,
|
||||||
serverName string,
|
serverName string,
|
||||||
dontWait bool,
|
dontWait bool,
|
||||||
|
noInput bool,
|
||||||
filters filters.Args,
|
filters filters.Args,
|
||||||
) error {
|
) error {
|
||||||
log.Info(i18n.G("initialising deployment"))
|
log.Info(i18n.G("initialising deployment"))
|
||||||
@ -226,6 +227,7 @@ func RunDeploy(
|
|||||||
appName,
|
appName,
|
||||||
serverName,
|
serverName,
|
||||||
dontWait,
|
dontWait,
|
||||||
|
noInput,
|
||||||
filters,
|
filters,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -248,6 +250,7 @@ func deployCompose(
|
|||||||
appName string,
|
appName string,
|
||||||
serverName string,
|
serverName string,
|
||||||
dontWait bool,
|
dontWait bool,
|
||||||
|
noInput bool,
|
||||||
filters filters.Args,
|
filters filters.Args,
|
||||||
) error {
|
) error {
|
||||||
namespace := convert.NewNamespace(opts.Namespace)
|
namespace := convert.NewNamespace(opts.Namespace)
|
||||||
@ -311,6 +314,7 @@ func deployCompose(
|
|||||||
Services: serviceIDs,
|
Services: serviceIDs,
|
||||||
AppName: appName,
|
AppName: appName,
|
||||||
ServerName: serverName,
|
ServerName: serverName,
|
||||||
|
NoInput: noInput,
|
||||||
Filters: filters,
|
Filters: filters,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,6 +565,7 @@ func timestamp() string {
|
|||||||
type WaitOpts struct {
|
type WaitOpts struct {
|
||||||
AppName string
|
AppName string
|
||||||
Filters filters.Args
|
Filters filters.Args
|
||||||
|
NoInput bool
|
||||||
NoLog bool
|
NoLog bool
|
||||||
Quiet bool
|
Quiet bool
|
||||||
ServerName string
|
ServerName string
|
||||||
@ -570,7 +575,13 @@ type WaitOpts struct {
|
|||||||
func WaitOnServices(ctx context.Context, cl *dockerClient.Client, opts WaitOpts) error {
|
func WaitOnServices(ctx context.Context, cl *dockerClient.Client, opts WaitOpts) error {
|
||||||
timeout := time.Duration(WaitTimeout) * time.Second
|
timeout := time.Duration(WaitTimeout) * time.Second
|
||||||
model := ui.DeployInitialModel(ctx, cl, opts.Services, opts.AppName, timeout, opts.Filters)
|
model := ui.DeployInitialModel(ctx, cl, opts.Services, opts.AppName, timeout, opts.Filters)
|
||||||
tui := tea.NewProgram(model)
|
|
||||||
|
var tui *tea.Program
|
||||||
|
if opts.NoInput {
|
||||||
|
tui = tea.NewProgram(model, tea.WithoutRenderer(), tea.WithInput(nil))
|
||||||
|
} else {
|
||||||
|
tui = tea.NewProgram(model)
|
||||||
|
}
|
||||||
|
|
||||||
if !opts.Quiet {
|
if !opts.Quiet {
|
||||||
log.Info(i18n.G("polling deployment status"))
|
log.Info(i18n.G("polling deployment status"))
|
||||||
|
|||||||
5
scripts/cloud-init/README.md
Normal file
5
scripts/cloud-init/README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# cloud-init
|
||||||
|
|
||||||
|
This folder contains cloud-init files for installing Abra and its dependencies.
|
||||||
|
|
||||||
|
For more information, see <https://cloudinit.readthedocs.io/en/latest/index.html>
|
||||||
49
scripts/cloud-init/cloud-init.yaml
Normal file
49
scripts/cloud-init/cloud-init.yaml
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#cloud-config
|
||||||
|
|
||||||
|
package_update: true
|
||||||
|
package_upgrade: true
|
||||||
|
package_reboot_if_required: true
|
||||||
|
|
||||||
|
# https://packages.debian.org/bookworm/docker.io
|
||||||
|
packages:
|
||||||
|
- ca-certificates
|
||||||
|
- curl
|
||||||
|
- docker.io
|
||||||
|
- docker-compose
|
||||||
|
# https://stackoverflow.com/a/74084180
|
||||||
|
- apparmor
|
||||||
|
|
||||||
|
# https://docs.coopcloud.tech/operators/tutorial/#server-setup
|
||||||
|
runcmd:
|
||||||
|
- curl -fsSL https://install.abra.coopcloud.tech | env HOME=/root bash
|
||||||
|
- docker swarm init
|
||||||
|
- docker network create -d overlay proxy
|
||||||
|
|
||||||
|
write_files:
|
||||||
|
# Add abra to PATH and set EDITOR
|
||||||
|
- path: /etc/profile.d/custom_path.sh
|
||||||
|
content: |
|
||||||
|
export PATH=$PATH:$HOME/.local/bin
|
||||||
|
export EDITOR=vim
|
||||||
|
owner: root:root
|
||||||
|
permissions: '0755'
|
||||||
|
# Send container log to journald: https://docs.coopcloud.tech/operators/handbook/#how-do-i-persist-container-logs-after-they-go-away
|
||||||
|
- path: /etc/docker/daemon.json
|
||||||
|
content: |
|
||||||
|
{
|
||||||
|
"log-driver": "journald",
|
||||||
|
"log-opts": {
|
||||||
|
"labels":"com.docker.swarm.service.name"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
owner: root:root
|
||||||
|
permissions: '0644'
|
||||||
|
# Rotate logs
|
||||||
|
- path: /etc/systemd/journald.conf
|
||||||
|
content: |
|
||||||
|
[Journal]
|
||||||
|
Storage=persistent
|
||||||
|
SystemMaxUse=5G
|
||||||
|
MaxFileSec=1month
|
||||||
|
owner: root:root
|
||||||
|
permissions: '0644'
|
||||||
@ -1,8 +1,8 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
ABRA_VERSION="0.11.0-beta"
|
ABRA_VERSION="0.12.0-beta"
|
||||||
ABRA_RELEASE_URL="https://git.coopcloud.tech/api/v1/repos/toolshed/abra/releases/tags/$ABRA_VERSION"
|
ABRA_RELEASE_URL="https://git.coopcloud.tech/api/v1/repos/toolshed/abra/releases/tags/$ABRA_VERSION"
|
||||||
RC_VERSION="0.11.0-beta"
|
RC_VERSION="0.12.0-beta"
|
||||||
RC_VERSION_URL="https://git.coopcloud.tech/api/v1/repos/toolshed/abra/releases/tags/$RC_VERSION"
|
RC_VERSION_URL="https://git.coopcloud.tech/api/v1/repos/toolshed/abra/releases/tags/$RC_VERSION"
|
||||||
|
|
||||||
for arg in "$@"; do
|
for arg in "$@"; do
|
||||||
@ -14,15 +14,15 @@ done
|
|||||||
|
|
||||||
function show_banner {
|
function show_banner {
|
||||||
echo ""
|
echo ""
|
||||||
echo " ____ ____ _ _ "
|
echo " ____ ____ _ _ "
|
||||||
echo " / ___|___ ___ _ __ / ___| | ___ _ _ __| |"
|
echo " / ___|___ ___ _ __ / ___| | ___ _ _ __| |"
|
||||||
echo " | | / _ \ _____ / _ \| '_ \ | | | |/ _ \| | | |/ _' |"
|
echo " | | / _ \ ___ / _ \| '_ \ | | | |/ _ \| | | |/ _' |"
|
||||||
echo " | |__| (_) |_____| (_) | |_) | | |___| | (_) | |_| | (_| |"
|
echo " | |__| (_) |___| (_) | |_) | | |___| | (_) | |_| | (_| |"
|
||||||
echo " \____\___/ \___/| .__/ \____|_|\___/ \__,_|\__,_|"
|
echo " \____\___/ \___/| .__/ \____|_|\___/ \__,_|\__,_|"
|
||||||
echo " |_|"
|
echo " |_|"
|
||||||
echo ""
|
echo ""
|
||||||
echo ""
|
echo ""
|
||||||
echo " === Public interest infrastructure === "
|
echo " === Public interest infrastructure === "
|
||||||
echo ""
|
echo ""
|
||||||
echo ""
|
echo ""
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,7 +51,7 @@ echo "========================================================================"
|
|||||||
echo "BUILDING ABRA"
|
echo "BUILDING ABRA"
|
||||||
echo "========================================================================"
|
echo "========================================================================"
|
||||||
export PATH="/usr/lib/go-1.21/bin:$PATH"
|
export PATH="/usr/lib/go-1.21/bin:$PATH"
|
||||||
make build-abra
|
make build
|
||||||
echo "========================================================================"
|
echo "========================================================================"
|
||||||
|
|
||||||
echo "========================================================================"
|
echo "========================================================================"
|
||||||
|
|||||||
@ -175,7 +175,7 @@ teardown(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
# bats test_tags=slow
|
# bats test_tags=slow
|
||||||
@test "bail if env has a hash but no --chaos" {
|
@test "do not bail if env version is a hash but no --chaos" {
|
||||||
wantHash=$(_get_n_hash 3)
|
wantHash=$(_get_n_hash 3)
|
||||||
|
|
||||||
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" reset --hard HEAD~3
|
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" reset --hard HEAD~3
|
||||||
@ -250,6 +250,7 @@ teardown(){
|
|||||||
run $ABRA app deploy "$TEST_APP_DOMAIN" \
|
run $ABRA app deploy "$TEST_APP_DOMAIN" \
|
||||||
--no-input --no-converge-checks --chaos
|
--no-input --no-converge-checks --chaos
|
||||||
assert_success
|
assert_success
|
||||||
|
assert_output --regexp "NEW DEPLOYMENT.*${_get_head_hash:0:8}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# bats test_tags=slow
|
# bats test_tags=slow
|
||||||
@ -367,6 +368,21 @@ teardown(){
|
|||||||
|
|
||||||
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input --no-converge-checks
|
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input --no-converge-checks
|
||||||
assert_failure
|
assert_failure
|
||||||
|
assert_output --partial "secret not generated"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "error if secret not inserted" {
|
||||||
|
run sed -i 's/COMPOSE_FILE="compose.yml"/COMPOSE_FILE="compose.yml:compose.skip_pass.yml"/g' \
|
||||||
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run sed -i 's/#SECRET_TEST_SKIP_PASS_VERSION=v1/SECRET_TEST_SKIP_PASS_VERSION=v1/g' \
|
||||||
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input --no-converge-checks
|
||||||
|
assert_failure
|
||||||
|
assert_output --partial "secret not inserted"
|
||||||
}
|
}
|
||||||
|
|
||||||
# bats test_tags=slow
|
# bats test_tags=slow
|
||||||
@ -527,7 +543,7 @@ teardown(){
|
|||||||
|
|
||||||
# bats test_tags=slow
|
# bats test_tags=slow
|
||||||
@test "ignore timeout when not present in env" {
|
@test "ignore timeout when not present in env" {
|
||||||
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input --no-converge-checks --debug
|
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input --no-converge-checks
|
||||||
assert_success
|
assert_success
|
||||||
refute_output --partial "timeout: set to"
|
refute_output --partial "timeout: set to"
|
||||||
}
|
}
|
||||||
@ -538,6 +554,7 @@ teardown(){
|
|||||||
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
assert_success
|
assert_success
|
||||||
|
|
||||||
|
# NOTE(d1}: --debug required
|
||||||
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input --no-converge-checks --debug
|
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input --no-converge-checks --debug
|
||||||
assert_success
|
assert_success
|
||||||
assert_output --partial "timeout: set to 120"
|
assert_output --partial "timeout: set to 120"
|
||||||
@ -561,3 +578,27 @@ teardown(){
|
|||||||
assert_success
|
assert_success
|
||||||
refute_output --partial "IMAGES"
|
refute_output --partial "IMAGES"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# bats test_tags=slow
|
||||||
|
@test "re-deploy updates existing env vars" {
|
||||||
|
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' \
|
||||||
|
$(docker ps -f name="$TEST_APP_DOMAIN_$TEST_SERVER" -q)
|
||||||
|
assert_success
|
||||||
|
assert_output --partial "WITH_COMMENT=foo"
|
||||||
|
|
||||||
|
run sed -i 's/WITH_COMMENT=foo/WITH_COMMENT=bar/g' \
|
||||||
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input --force
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' \
|
||||||
|
$(docker ps -f name="$TEST_APP_DOMAIN_$TEST_SERVER" -q)
|
||||||
|
assert_success
|
||||||
|
refute_output --partial "WITH_COMMENT=foo"
|
||||||
|
assert_output --partial "WITH_COMMENT=bar"
|
||||||
|
}
|
||||||
|
|||||||
@ -127,3 +127,14 @@ teardown(){
|
|||||||
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
assert_success
|
assert_success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# bats test_tags=slow
|
||||||
|
@test "new env version written to container env" {
|
||||||
|
run $ABRA app deploy "$TEST_APP_DOMAIN" "0.1.0+1.20.0" --no-input
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' \
|
||||||
|
$(docker ps -f name="$TEST_APP_DOMAIN_$TEST_SERVER" -q)
|
||||||
|
assert_success
|
||||||
|
assert_output --partial "$TEST_RECIIPE:0.1.0+1.20.0"
|
||||||
|
}
|
||||||
|
|||||||
@ -38,8 +38,8 @@ teardown(){
|
|||||||
assert_success
|
assert_success
|
||||||
|
|
||||||
assert_output --partial 'NEW DEPLOY OVERVIEW'
|
assert_output --partial 'NEW DEPLOY OVERVIEW'
|
||||||
assert_output --partial 'CURRENT DEPLOYMENT N/A'
|
assert_output --partial 'CURRENT DEPLOYMENT -'
|
||||||
assert_output --partial 'ENV VERSION N/A'
|
assert_output --partial 'ENV VERSION -'
|
||||||
assert_output --partial "NEW DEPLOYMENT ${latestRelease}"
|
assert_output --partial "NEW DEPLOYMENT ${latestRelease}"
|
||||||
assert_output --partial "IMAGES nginx: ${latestRelease##*+} (new)"
|
assert_output --partial "IMAGES nginx: ${latestRelease##*+} (new)"
|
||||||
assert_output --partial "CONFIGS test_conf: v1 (new)"
|
assert_output --partial "CONFIGS test_conf: v1 (new)"
|
||||||
@ -57,7 +57,7 @@ teardown(){
|
|||||||
assert_success
|
assert_success
|
||||||
|
|
||||||
assert_output --partial 'NEW DEPLOY OVERVIEW'
|
assert_output --partial 'NEW DEPLOY OVERVIEW'
|
||||||
assert_output --partial "CURRENT DEPLOYMENT N/A"
|
assert_output --partial "CURRENT DEPLOYMENT -"
|
||||||
assert_output --partial "ENV VERSION ${latestRelease}"
|
assert_output --partial "ENV VERSION ${latestRelease}"
|
||||||
assert_output --partial "NEW DEPLOYMENT ${latestRelease}"
|
assert_output --partial "NEW DEPLOYMENT ${latestRelease}"
|
||||||
assert_output --partial "IMAGES nginx: ${latestRelease##*+} (new)"
|
assert_output --partial "IMAGES nginx: ${latestRelease##*+} (new)"
|
||||||
@ -68,6 +68,13 @@ teardown(){
|
|||||||
assert_success
|
assert_success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "domain shown with https" {
|
||||||
|
run $ABRA app deploy "$TEST_APP_DOMAIN" \
|
||||||
|
--no-input --no-converge-checks
|
||||||
|
assert_success
|
||||||
|
assert_output --partial "https://$TEST_DOMAIN"
|
||||||
|
}
|
||||||
|
|
||||||
# bats test_tags=slow
|
# bats test_tags=slow
|
||||||
@test "show changed config version on re-deploy" {
|
@test "show changed config version on re-deploy" {
|
||||||
run $ABRA app deploy "$TEST_APP_DOMAIN" \
|
run $ABRA app deploy "$TEST_APP_DOMAIN" \
|
||||||
@ -102,7 +109,7 @@ teardown(){
|
|||||||
assert_success
|
assert_success
|
||||||
|
|
||||||
assert_output --partial 'NEW DEPLOY OVERVIEW'
|
assert_output --partial 'NEW DEPLOY OVERVIEW'
|
||||||
assert_output --partial "CURRENT DEPLOYMENT N/A"
|
assert_output --partial "CURRENT DEPLOYMENT -"
|
||||||
assert_output --partial "ENV VERSION 0.1.1+1.20.2"
|
assert_output --partial "ENV VERSION 0.1.1+1.20.2"
|
||||||
assert_output --partial "NEW DEPLOYMENT 0.1.1+1.20.2"
|
assert_output --partial "NEW DEPLOYMENT 0.1.1+1.20.2"
|
||||||
|
|
||||||
@ -125,7 +132,7 @@ teardown(){
|
|||||||
assert_success
|
assert_success
|
||||||
|
|
||||||
assert_output --partial 'NEW DEPLOY OVERVIEW'
|
assert_output --partial 'NEW DEPLOY OVERVIEW'
|
||||||
assert_output --partial "CURRENT DEPLOYMENT N/A"
|
assert_output --partial "CURRENT DEPLOYMENT -"
|
||||||
assert_output --partial "ENV VERSION 0.1.1+1.20.2"
|
assert_output --partial "ENV VERSION 0.1.1+1.20.2"
|
||||||
assert_output --partial "NEW DEPLOYMENT ${latestRelease}"
|
assert_output --partial "NEW DEPLOYMENT ${latestRelease}"
|
||||||
|
|
||||||
@ -163,7 +170,7 @@ teardown(){
|
|||||||
assert_success
|
assert_success
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "can not redeploy chaos version without --chaos" {
|
@test "cannot redeploy chaos version without --chaos" {
|
||||||
headHash=$(_get_head_hash)
|
headHash=$(_get_head_hash)
|
||||||
latestRelease=$(_latest_release)
|
latestRelease=$(_latest_release)
|
||||||
|
|
||||||
@ -181,7 +188,7 @@ teardown(){
|
|||||||
run $ABRA app deploy "$TEST_APP_DOMAIN" \
|
run $ABRA app deploy "$TEST_APP_DOMAIN" \
|
||||||
--no-input --no-converge-checks --force --debug
|
--no-input --no-converge-checks --force --debug
|
||||||
assert_failure
|
assert_failure
|
||||||
assert_output --regexp 'can not redeploy chaos version .*' + "${headHash:0:8}+U"
|
assert_output --regexp 'cannot redeploy previous chaos version .*' + "${headHash:0:8}+U"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "deploy then force commit deploy" {
|
@test "deploy then force commit deploy" {
|
||||||
@ -219,7 +226,7 @@ teardown(){
|
|||||||
assert_success
|
assert_success
|
||||||
|
|
||||||
assert_output --partial 'NEW DEPLOY OVERVIEW'
|
assert_output --partial 'NEW DEPLOY OVERVIEW'
|
||||||
assert_output --partial "CURRENT DEPLOYMENT N/A"
|
assert_output --partial "CURRENT DEPLOYMENT -"
|
||||||
assert_output --partial "ENV VERSION ${latestRelease}"
|
assert_output --partial "ENV VERSION ${latestRelease}"
|
||||||
assert_output --partial "NEW DEPLOYMENT ${headHash:0:8}"
|
assert_output --partial "NEW DEPLOYMENT ${headHash:0:8}"
|
||||||
|
|
||||||
|
|||||||
@ -28,17 +28,17 @@ teardown(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
@test "validate app argument" {
|
@test "validate app argument" {
|
||||||
run $ABRA app env
|
run $ABRA app env list
|
||||||
assert_failure
|
assert_failure
|
||||||
|
|
||||||
run $ABRA app env DOESNTEXIST
|
run $ABRA app env list DOESNTEXIST
|
||||||
assert_failure
|
assert_failure
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "show env version" {
|
@test "show env version" {
|
||||||
latestRelease=$(_latest_release)
|
latestRelease=$(_latest_release)
|
||||||
|
|
||||||
run $ABRA app env "$TEST_APP_DOMAIN"
|
run $ABRA app env list "$TEST_APP_DOMAIN"
|
||||||
assert_success
|
assert_success
|
||||||
assert_output --partial "$latestRelease"
|
assert_output --partial "$latestRelease"
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ teardown(){
|
|||||||
assert_success
|
assert_success
|
||||||
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
||||||
|
|
||||||
run $ABRA app env "$TEST_APP_DOMAIN"
|
run $ABRA app env list "$TEST_APP_DOMAIN"
|
||||||
assert_success
|
assert_success
|
||||||
|
|
||||||
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
||||||
@ -57,3 +57,44 @@ teardown(){
|
|||||||
run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
||||||
assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "app env pull explodes when no deployed app" {
|
||||||
|
run $ABRA app env pull "$TEST_APP_DOMAIN" -s "$TEST_SERVER"
|
||||||
|
assert_failure
|
||||||
|
}
|
||||||
|
|
||||||
|
# bats test_tags=slow
|
||||||
|
@test "app env pull recreates app env when missing" {
|
||||||
|
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run rm -rf "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
assert_success
|
||||||
|
assert_not_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
|
||||||
|
run $ABRA app env pull "$TEST_APP_DOMAIN" -s "$TEST_SERVER"
|
||||||
|
assert_success
|
||||||
|
assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
}
|
||||||
|
|
||||||
|
# bats test_tags=slow
|
||||||
|
@test "app env pull recreates correct version" {
|
||||||
|
run $ABRA app deploy "$TEST_APP_DOMAIN" "0.1.0+1.20.0" --no-input
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \
|
||||||
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run rm -rf "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
assert_success
|
||||||
|
assert_not_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
|
||||||
|
run $ABRA app env pull "$TEST_APP_DOMAIN" -s "$TEST_SERVER"
|
||||||
|
assert_success
|
||||||
|
assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
|
||||||
|
run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \
|
||||||
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ teardown_file(){
|
|||||||
_undeploy_app
|
_undeploy_app
|
||||||
_rm_app
|
_rm_app
|
||||||
_rm_server
|
_rm_server
|
||||||
|
_reset_recipe
|
||||||
|
|
||||||
if [[ -d "$ABRA_DIR/servers/foo" ]]; then
|
if [[ -d "$ABRA_DIR/servers/foo" ]]; then
|
||||||
run rm -rf "$ABRA_DIR/servers/foo"
|
run rm -rf "$ABRA_DIR/servers/foo"
|
||||||
@ -159,23 +160,6 @@ teardown(){
|
|||||||
assert_not_exists "$ABRA_DIR/servers/foo.com"
|
assert_not_exists "$ABRA_DIR/servers/foo.com"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "list with status skips unknown servers" {
|
|
||||||
if [[ ! -d "$ABRA_DIR/servers/foo" ]]; then
|
|
||||||
run mkdir -p "$ABRA_DIR/servers/foo"
|
|
||||||
assert_success
|
|
||||||
assert_exists "$ABRA_DIR/servers/foo"
|
|
||||||
|
|
||||||
run cp "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" \
|
|
||||||
"$ABRA_DIR/servers/foo/$TEST_APP_DOMAIN.env"
|
|
||||||
assert_success
|
|
||||||
assert_exists "$ABRA_DIR/servers/foo/$TEST_APP_DOMAIN.env"
|
|
||||||
fi
|
|
||||||
|
|
||||||
run $ABRA app ls --status
|
|
||||||
assert_success
|
|
||||||
assert_output --partial "unknown server"
|
|
||||||
}
|
|
||||||
|
|
||||||
# bats test_tags=slow
|
# bats test_tags=slow
|
||||||
@test "list does not fail if missing .env" {
|
@test "list does not fail if missing .env" {
|
||||||
_deploy_app
|
_deploy_app
|
||||||
@ -193,3 +177,16 @@ teardown(){
|
|||||||
<(jq -S "." <(echo '{}'))
|
<(jq -S "." <(echo '{}'))
|
||||||
assert_success
|
assert_success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# bats test_tags=slow
|
||||||
|
@test "list ignores borked tags" {
|
||||||
|
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" tag \
|
||||||
|
-a "2.4.8_1" -m "feat: completely borked tag"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
_deploy_app
|
||||||
|
|
||||||
|
run $ABRA app ls --status --debug
|
||||||
|
assert_success
|
||||||
|
assert_output --partial "unable to parse 2.4.8_1"
|
||||||
|
}
|
||||||
|
|||||||
@ -22,8 +22,15 @@ teardown(){
|
|||||||
_reset_recipe
|
_reset_recipe
|
||||||
_reset_tags
|
_reset_tags
|
||||||
|
|
||||||
run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
if [[ -f "$ABRA_DIR/recipes/$TEST_RECIPE/foo" ]]; then
|
||||||
assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
||||||
|
assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "$ABRA_DIR/servers/$TEST_SERVER/rauthy.$TEST_APP_DOMAIN.env" ]]; then
|
||||||
|
run rm -rf "$ABRA_DIR/servers/$TEST_SERVER/rauthy.$TEST_APP_DOMAIN.env"
|
||||||
|
assert_not_exists "$ABRA_DIR/servers/$TEST_SERVER/rauthy.$TEST_APP_DOMAIN.env"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "create new app" {
|
@test "create new app" {
|
||||||
@ -270,3 +277,32 @@ teardown(){
|
|||||||
assert_success
|
assert_success
|
||||||
refute_output --partial "requires secret generation"
|
refute_output --partial "requires secret generation"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "do not warn about generation when generate=false" {
|
||||||
|
run $ABRA app new --domain "$TEST_APP_DOMAIN" renovate "1.0.1+41-full"
|
||||||
|
assert_success
|
||||||
|
refute_output --partial "requires secret generation"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "warn about insertion when generate=false" {
|
||||||
|
run $ABRA app new --domain "$TEST_APP_DOMAIN" renovate "1.0.1+41-full"
|
||||||
|
assert_success
|
||||||
|
assert_output --partial "requires secret insertion"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "warn about both insert/generate when generate=false/true" {
|
||||||
|
run $ABRA app new rauthy "1.0.0+0.32.3" \
|
||||||
|
--no-input \
|
||||||
|
--server "$TEST_SERVER" \
|
||||||
|
--domain "rauthy.$TEST_APP_DOMAIN"
|
||||||
|
assert_success
|
||||||
|
assert_exists "$ABRA_DIR/servers/$TEST_SERVER/rauthy.$TEST_APP_DOMAIN.env"
|
||||||
|
assert_output --partial "requires secret generation"
|
||||||
|
assert_output --partial "requires secret insertion"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "no warn about generation if already generated" {
|
||||||
|
run $ABRA app new "$TEST_RECIPE" --domain "$TEST_APP_DOMAIN" --secrets
|
||||||
|
assert_success
|
||||||
|
refute_output --partial "requires secret generation"
|
||||||
|
}
|
||||||
|
|||||||
@ -181,7 +181,7 @@ teardown(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
# bats test_tags=slow
|
# bats test_tags=slow
|
||||||
@test "rollback chaos deployment is not possible" {
|
@test "rollback chaos deployment is possible" {
|
||||||
tagHash=$(_get_tag_hash "0.2.0+1.21.0")
|
tagHash=$(_get_tag_hash "0.2.0+1.21.0")
|
||||||
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" checkout "$tagHash"
|
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" checkout "$tagHash"
|
||||||
assert_success
|
assert_success
|
||||||
@ -191,12 +191,13 @@ teardown(){
|
|||||||
assert_output --partial "${tagHash:0:8}"
|
assert_output --partial "${tagHash:0:8}"
|
||||||
|
|
||||||
run $ABRA app rollback "$TEST_APP_DOMAIN" "0.1.1+1.20.2" --no-input --no-converge-checks
|
run $ABRA app rollback "$TEST_APP_DOMAIN" "0.1.1+1.20.2" --no-input --no-converge-checks
|
||||||
assert_failure
|
assert_success
|
||||||
assert_output --partial 'current deployment' + "${tagHash:0:8}" + 'is not a known version'
|
assert_output --regexp "CURRENT DEPLOYMENT.*${tagHash:0:8}"
|
||||||
|
assert_output --regexp "ENV VERSION.*${tagHash:0:8}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# bats test_tags=slow
|
# bats test_tags=slow
|
||||||
@test "chaos commit rollback not possible" {
|
@test "specific chaos commit rollback not possible" {
|
||||||
_deploy_app
|
_deploy_app
|
||||||
|
|
||||||
tagHash=$(_get_tag_hash "0.2.0+1.21.0")
|
tagHash=$(_get_tag_hash "0.2.0+1.21.0")
|
||||||
|
|||||||
@ -33,10 +33,29 @@ teardown(){
|
|||||||
assert_success
|
assert_success
|
||||||
|
|
||||||
run $ABRA app rollback "$TEST_APP_DOMAIN" "0.1.0+1.20.0" \
|
run $ABRA app rollback "$TEST_APP_DOMAIN" "0.1.0+1.20.0" \
|
||||||
--no-input --no-converge-checks --debug
|
--no-input --no-converge-checks
|
||||||
assert_success
|
assert_success
|
||||||
|
|
||||||
run grep -q "TYPE=abra-test-recipe:0.1.0+1.20.0" \
|
run grep -q "TYPE=abra-test-recipe:0.1.0+1.20.0" \
|
||||||
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
assert_success
|
assert_success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# bats test_tags=slow
|
||||||
|
@test "new env version written to container env" {
|
||||||
|
run $ABRA app deploy "$TEST_APP_DOMAIN" "0.2.0+1.21.0" --no-input
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run grep -q "TYPE=abra-test-recipe:0.2.0+1.21.0" \
|
||||||
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run $ABRA app rollback "$TEST_APP_DOMAIN" "0.1.0+1.20.0" \
|
||||||
|
--no-input
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' \
|
||||||
|
$(docker ps -f name="$TEST_APP_DOMAIN_$TEST_SERVER" -q)
|
||||||
|
assert_success
|
||||||
|
assert_output --partial "$TEST_RECIIPE:0.1.0+1.20.0"
|
||||||
|
}
|
||||||
|
|||||||
@ -75,7 +75,7 @@ teardown(){
|
|||||||
|
|
||||||
assert_output --partial 'DOWNGRADE OVERVIEW'
|
assert_output --partial 'DOWNGRADE OVERVIEW'
|
||||||
assert_output --partial 'CURRENT DEPLOYMENT 0.2.0+1.21.0'
|
assert_output --partial 'CURRENT DEPLOYMENT 0.2.0+1.21.0'
|
||||||
assert_output --partial 'ENV VERSION N/A'
|
assert_output --partial 'ENV VERSION -'
|
||||||
assert_output --partial 'NEW DEPLOYMENT 0.1.0+1.20.0'
|
assert_output --partial 'NEW DEPLOYMENT 0.1.0+1.20.0'
|
||||||
|
|
||||||
run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \
|
run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \
|
||||||
|
|||||||
@ -106,6 +106,7 @@ teardown(){
|
|||||||
|
|
||||||
run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input
|
run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input
|
||||||
assert_success
|
assert_success
|
||||||
|
assert_output --regexp "CURRENT DEPLOYMENT.*${_get_head_hash:0:8}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# bats test_tags=slow
|
# bats test_tags=slow
|
||||||
|
|||||||
@ -36,7 +36,7 @@ teardown(){
|
|||||||
assert_output --partial 'UNDEPLOY OVERVIEW'
|
assert_output --partial 'UNDEPLOY OVERVIEW'
|
||||||
assert_output --partial 'CURRENT DEPLOYMENT 0.1.0+1.20.0'
|
assert_output --partial 'CURRENT DEPLOYMENT 0.1.0+1.20.0'
|
||||||
assert_output --partial 'ENV VERSION 0.1.0+1.20.0'
|
assert_output --partial 'ENV VERSION 0.1.0+1.20.0'
|
||||||
assert_output --partial 'NEW DEPLOYMENT N/A'
|
assert_output --partial 'NEW DEPLOYMENT -'
|
||||||
|
|
||||||
run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \
|
run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \
|
||||||
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
@ -57,7 +57,7 @@ teardown(){
|
|||||||
assert_output --partial 'UNDEPLOY OVERVIEW'
|
assert_output --partial 'UNDEPLOY OVERVIEW'
|
||||||
assert_output --partial "CURRENT DEPLOYMENT ${headHash:0:8}"
|
assert_output --partial "CURRENT DEPLOYMENT ${headHash:0:8}"
|
||||||
assert_output --partial "ENV VERSION ${headHash:0:8}"
|
assert_output --partial "ENV VERSION ${headHash:0:8}"
|
||||||
assert_output --partial 'NEW DEPLOYMENT N/A'
|
assert_output --partial 'NEW DEPLOYMENT -'
|
||||||
|
|
||||||
run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \
|
run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \
|
||||||
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
@ -81,7 +81,7 @@ teardown(){
|
|||||||
assert_output --partial 'UNDEPLOY OVERVIEW'
|
assert_output --partial 'UNDEPLOY OVERVIEW'
|
||||||
assert_output --partial "CURRENT DEPLOYMENT ${headHash:0:8}+U"
|
assert_output --partial "CURRENT DEPLOYMENT ${headHash:0:8}+U"
|
||||||
assert_output --partial "ENV VERSION ${headHash:0:8}+U"
|
assert_output --partial "ENV VERSION ${headHash:0:8}+U"
|
||||||
assert_output --partial 'NEW DEPLOYMENT N/A'
|
assert_output --partial 'NEW DEPLOYMENT -'
|
||||||
|
|
||||||
run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \
|
run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \
|
||||||
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
|||||||
@ -256,7 +256,7 @@ teardown(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
# bats test_tags=slow
|
# bats test_tags=slow
|
||||||
@test "upgrade commit deployment not possible" {
|
@test "specific version upgrade after chaos deploy" {
|
||||||
tagHash=$(_get_tag_hash "0.1.0+1.20.0")
|
tagHash=$(_get_tag_hash "0.1.0+1.20.0")
|
||||||
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" checkout "$tagHash"
|
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" checkout "$tagHash"
|
||||||
assert_success
|
assert_success
|
||||||
@ -266,20 +266,29 @@ teardown(){
|
|||||||
assert_output --partial "${tagHash:0:8}"
|
assert_output --partial "${tagHash:0:8}"
|
||||||
|
|
||||||
run $ABRA app upgrade "$TEST_APP_DOMAIN" "0.1.1+1.20.2" --no-input --no-converge-checks
|
run $ABRA app upgrade "$TEST_APP_DOMAIN" "0.1.1+1.20.2" --no-input --no-converge-checks
|
||||||
assert_failure
|
assert_success
|
||||||
assert_output --partial "not a known version"
|
assert_output --regexp "CURRENT DEPLOYMENT.*${tagHash:0:8}"
|
||||||
|
assert_output --regexp "ENV VERSION.*${tagHash:0:8}"
|
||||||
|
assert_output --regexp "NEW DEPLOYMENT.*0\.1\.1\+1\.20\.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "chaos commit upgrade not possible" {
|
# bats test_tags=slow
|
||||||
run $ABRA app deploy "$TEST_APP_DOMAIN" "0.1.0+1.20.0" --no-input --no-converge-checks
|
@test "upgrade to latest after chaos deploy" {
|
||||||
|
latestRelease=$(_latest_release)
|
||||||
|
|
||||||
|
tagHash=$(_get_tag_hash "0.1.0+1.20.0")
|
||||||
|
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" checkout "$tagHash"
|
||||||
assert_success
|
assert_success
|
||||||
assert_output --partial '0.1.0+1.20.0'
|
|
||||||
|
|
||||||
tagHash=$(_get_tag_hash "0.2.0+1.21.0")
|
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input --no-converge-checks --chaos
|
||||||
|
assert_success
|
||||||
|
assert_output --partial "${tagHash:0:8}"
|
||||||
|
|
||||||
run $ABRA app upgrade "$TEST_APP_DOMAIN" "$tagHash" --no-input --no-converge-checks
|
run $ABRA app upgrade "$TEST_APP_DOMAIN" --no-input --no-converge-checks
|
||||||
assert_failure
|
assert_success
|
||||||
assert_output --partial "not a known version"
|
assert_output --regexp "CURRENT DEPLOYMENT.*${tagHash:0:8}"
|
||||||
|
assert_output --regexp "ENV VERSION.*${tagHash:0:8}"
|
||||||
|
assert_output --partial "${latestRelease}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# bats test_tags=slow
|
# bats test_tags=slow
|
||||||
|
|||||||
@ -40,3 +40,21 @@ teardown(){
|
|||||||
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
assert_success
|
assert_success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# bats test_tags=slow
|
||||||
|
@test "new env version written to container env" {
|
||||||
|
run $ABRA app deploy "$TEST_APP_DOMAIN" "0.1.0+1.20.0" --no-input
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run grep -q "TYPE=abra-test-recipe:0.1.0+1.20.0" \
|
||||||
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run $ABRA app upgrade "$TEST_APP_DOMAIN" "0.2.0+1.21.0" --no-input
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' \
|
||||||
|
$(docker ps -f name="$TEST_APP_DOMAIN_$TEST_SERVER" -q)
|
||||||
|
assert_success
|
||||||
|
assert_output --partial "$TEST_RECIIPE:0.2.0+1.21.0"
|
||||||
|
}
|
||||||
|
|||||||
@ -75,7 +75,7 @@ teardown(){
|
|||||||
|
|
||||||
assert_output --partial 'UPGRADE OVERVIEW'
|
assert_output --partial 'UPGRADE OVERVIEW'
|
||||||
assert_output --partial 'CURRENT DEPLOYMENT 0.2.0+1.21.0'
|
assert_output --partial 'CURRENT DEPLOYMENT 0.2.0+1.21.0'
|
||||||
assert_output --partial 'ENV VERSION N/A'
|
assert_output --partial 'ENV VERSION -'
|
||||||
assert_output --partial "NEW DEPLOYMENT $latestRelease"
|
assert_output --partial "NEW DEPLOYMENT $latestRelease"
|
||||||
|
|
||||||
run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \
|
run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \
|
||||||
|
|||||||
@ -53,7 +53,8 @@ teardown(){
|
|||||||
--domain "foobar.$TEST_SERVER"
|
--domain "foobar.$TEST_SERVER"
|
||||||
assert_success
|
assert_success
|
||||||
|
|
||||||
run $ABRA app deploy "foobar.$TEST_SERVER" --no-input
|
run $ABRA app deploy "foobar.$TEST_SERVER" \
|
||||||
|
--no-input --no-converge-checks
|
||||||
assert_success
|
assert_success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -101,6 +101,9 @@ teardown() {
|
|||||||
assert_success
|
assert_success
|
||||||
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
||||||
|
|
||||||
|
run $ABRA recipe sync "$TEST_RECIPE" --no-input --patch
|
||||||
|
assert_success
|
||||||
|
|
||||||
run $ABRA recipe release "$TEST_RECIPE" --no-input --patch
|
run $ABRA recipe release "$TEST_RECIPE" --no-input --patch
|
||||||
assert_success
|
assert_success
|
||||||
assert_output --partial 'no -p/--publish passed, not publishing'
|
assert_output --partial 'no -p/--publish passed, not publishing'
|
||||||
@ -119,6 +122,9 @@ teardown() {
|
|||||||
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" commit -m "added some release notes"
|
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" commit -m "added some release notes"
|
||||||
assert_success
|
assert_success
|
||||||
|
|
||||||
|
run $ABRA recipe sync "$TEST_RECIPE" --no-input --patch
|
||||||
|
assert_success
|
||||||
|
|
||||||
run $ABRA recipe release "$TEST_RECIPE" --no-input --minor
|
run $ABRA recipe release "$TEST_RECIPE" --no-input --minor
|
||||||
assert_success
|
assert_success
|
||||||
assert_output --partial 'no -p/--publish passed, not publishing'
|
assert_output --partial 'no -p/--publish passed, not publishing'
|
||||||
@ -127,3 +133,27 @@ teardown() {
|
|||||||
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/release/0.4.0+1.21.0"
|
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/release/0.4.0+1.21.0"
|
||||||
assert_file_contains "$ABRA_DIR/recipes/$TEST_RECIPE/release/0.4.0+1.21.0" "those are some release notes for the next release"
|
assert_file_contains "$ABRA_DIR/recipes/$TEST_RECIPE/release/0.4.0+1.21.0" "those are some release notes for the next release"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "recipe release conflict fails" {
|
||||||
|
tagHash=$(_get_tag_hash "0.2.0+1.21.0")
|
||||||
|
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" checkout "$tagHash"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run sed -i "s/nginx:1.21.0/nginx:1.29.1/g" "$ABRA_DIR/recipes/$TEST_RECIPE/compose.yml"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" diff
|
||||||
|
assert_success
|
||||||
|
assert_output --regexp 'nginx:1.29.1'
|
||||||
|
|
||||||
|
run sed -i "s/0.2.0+1.21.0/0.2.0+1.29.1/g" "$ABRA_DIR/recipes/$TEST_RECIPE/compose.yml"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" diff
|
||||||
|
assert_success
|
||||||
|
assert_output --regexp 'coop-cloud\.\$\{STACK_NAME\}\.version=0\.2\.0\+1\.29\.1'
|
||||||
|
|
||||||
|
run $ABRA recipe release "$TEST_RECIPE" --no-input --minor
|
||||||
|
assert_failure
|
||||||
|
assert_output --partial '0.2.0+... conflicts with a previous release: 0.2.0+1.21.0'
|
||||||
|
}
|
||||||
|
|||||||
@ -19,6 +19,10 @@ setup(){
|
|||||||
teardown(){
|
teardown(){
|
||||||
_reset_recipe
|
_reset_recipe
|
||||||
_reset_tags
|
_reset_tags
|
||||||
|
if [[ -d "$ABRA_DIR/recipes/foobar" ]]; then
|
||||||
|
run rm -rf "$ABRA_DIR/recipes/foobar"
|
||||||
|
assert_success
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "validate recipe argument" {
|
@test "validate recipe argument" {
|
||||||
@ -126,3 +130,71 @@ teardown(){
|
|||||||
assert_line --index 0 --partial 'synced label'
|
assert_line --index 0 --partial 'synced label'
|
||||||
refute_line --index 1 --partial 'synced label'
|
refute_line --index 1 --partial 'synced label'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "sync with no tags or previous release" {
|
||||||
|
_remove_tags
|
||||||
|
|
||||||
|
run $ABRA recipe upgrade "$TEST_RECIPE" --no-input --patch
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" diff
|
||||||
|
assert_success
|
||||||
|
assert_output --partial 'image: nginx:1.21.6'
|
||||||
|
|
||||||
|
# NOTE(d1): ensure the latest tag is the one we expect
|
||||||
|
_remove_tags
|
||||||
|
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" tag \
|
||||||
|
-a "0.3.0+1.21.0" -m "fake: 0.3.0+1.21.0"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run $ABRA recipe sync "$TEST_RECIPE" --no-input --patch
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" diff
|
||||||
|
assert_success
|
||||||
|
assert_output --regexp 'coop-cloud\.\$\{STACK_NAME\}\.version=0\.3\.1\+1\.2.*'
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "sync recipe without input fails with prompt" {
|
||||||
|
run $ABRA recipe new foobar
|
||||||
|
assert_success
|
||||||
|
assert_exists "$ABRA_DIR/recipes/foobar"
|
||||||
|
|
||||||
|
run $ABRA recipe sync foobar --no-input --patch
|
||||||
|
assert_failure
|
||||||
|
assert_output --partial "input required for initial version"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "sync new recipe: development release" {
|
||||||
|
run $ABRA recipe new foobar
|
||||||
|
assert_success
|
||||||
|
assert_exists "$ABRA_DIR/recipes/foobar"
|
||||||
|
|
||||||
|
run bash -c "echo 0.1.0 | $ABRA recipe sync foobar --patch"
|
||||||
|
assert_success
|
||||||
|
assert_output --regexp 'coop-cloud\.\$\{STACK_NAME\}\.version=0\.1\.0\+1\.2.*'
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "sync new recipe: public release" {
|
||||||
|
run $ABRA recipe new foobar
|
||||||
|
assert_success
|
||||||
|
assert_exists "$ABRA_DIR/recipes/foobar"
|
||||||
|
|
||||||
|
run bash -c "echo 1.0.0 | $ABRA recipe sync foobar --patch"
|
||||||
|
assert_success
|
||||||
|
assert_output --regexp 'coop-cloud\.\$\{STACK_NAME\}\.version=1\.0\.0\+1\.2.*'
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "sync newly created recipe with no version label" {
|
||||||
|
run $ABRA recipe new foobar
|
||||||
|
assert_success
|
||||||
|
assert_exists "$ABRA_DIR/recipes/foobar"
|
||||||
|
|
||||||
|
run sed -i 's/- "coop-cloud.${STACK_NAME}.version="/#- "coop-cloud.${STACK_NAME}.version="/g' \
|
||||||
|
"$ABRA_DIR/recipes/foobar/compose.yml"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run bash -c "echo 0.1.0 | $ABRA recipe sync foobar --patch"
|
||||||
|
assert_failure
|
||||||
|
assert_output --partial "automagic insertion not supported yet"
|
||||||
|
}
|
||||||
|
|||||||
@ -12,11 +12,7 @@ setup_suite(){
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! -f "$PWD/abra" ]]; then
|
if [[ ! -f "$PWD/abra" ]]; then
|
||||||
make build-abra
|
make
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -f "$PWD/kadabra" ]]; then
|
|
||||||
make build-kadabra
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -d "$ABRA_DIR" ]]; then
|
if [[ -d "$ABRA_DIR" ]]; then
|
||||||
|
|||||||
4
vendor/github.com/charmbracelet/bubbletea/.golangci.yml
generated
vendored
4
vendor/github.com/charmbracelet/bubbletea/.golangci.yml
generated
vendored
@ -26,6 +26,10 @@ linters:
|
|||||||
- whitespace
|
- whitespace
|
||||||
- wrapcheck
|
- wrapcheck
|
||||||
exclusions:
|
exclusions:
|
||||||
|
rules:
|
||||||
|
- text: '(slog|log)\.\w+'
|
||||||
|
linters:
|
||||||
|
- noctx
|
||||||
generated: lax
|
generated: lax
|
||||||
presets:
|
presets:
|
||||||
- common-false-positives
|
- common-false-positives
|
||||||
|
|||||||
2
vendor/github.com/charmbracelet/bubbletea/LICENSE
generated
vendored
2
vendor/github.com/charmbracelet/bubbletea/LICENSE
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2020-2023 Charmbracelet, Inc
|
Copyright (c) 2020-2025 Charmbracelet, Inc
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
4
vendor/github.com/charmbracelet/bubbletea/README.md
generated
vendored
4
vendor/github.com/charmbracelet/bubbletea/README.md
generated
vendored
@ -9,7 +9,7 @@
|
|||||||
<br>
|
<br>
|
||||||
<a href="https://github.com/charmbracelet/bubbletea/releases"><img src="https://img.shields.io/github/release/charmbracelet/bubbletea.svg" alt="Latest Release"></a>
|
<a href="https://github.com/charmbracelet/bubbletea/releases"><img src="https://img.shields.io/github/release/charmbracelet/bubbletea.svg" alt="Latest Release"></a>
|
||||||
<a href="https://pkg.go.dev/github.com/charmbracelet/bubbletea?tab=doc"><img src="https://godoc.org/github.com/charmbracelet/bubbletea?status.svg" alt="GoDoc"></a>
|
<a href="https://pkg.go.dev/github.com/charmbracelet/bubbletea?tab=doc"><img src="https://godoc.org/github.com/charmbracelet/bubbletea?status.svg" alt="GoDoc"></a>
|
||||||
<a href="https://github.com/charmbracelet/bubbletea/actions"><img src="https://github.com/charmbracelet/bubbletea/actions/workflows/build.yml/badge.svg" alt="Build Status"></a>
|
<a href="https://github.com/charmbracelet/bubbletea/actions"><img src="https://github.com/charmbracelet/bubbletea/actions/workflows/build.yml/badge.svg?branch=main" alt="Build Status"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
The fun, functional and stateful way to build terminal apps. A Go framework
|
The fun, functional and stateful way to build terminal apps. A Go framework
|
||||||
@ -395,6 +395,6 @@ of days past.
|
|||||||
|
|
||||||
Part of [Charm](https://charm.sh).
|
Part of [Charm](https://charm.sh).
|
||||||
|
|
||||||
<a href="https://charm.sh/"><img alt="The Charm logo" src="https://stuff.charm.sh/charm-badge.jpg" width="400"></a>
|
<a href="https://charm.sh/"><img alt="The Charm logo" src="https://stuff.charm.sh/charm-banner-next.jpg" width="400"></a>
|
||||||
|
|
||||||
Charm热爱开源 • Charm loves open source • نحنُ نحب المصادر المفتوحة
|
Charm热爱开源 • Charm loves open source • نحنُ نحب المصادر المفتوحة
|
||||||
|
|||||||
38
vendor/github.com/charmbracelet/bubbletea/commands.go
generated
vendored
38
vendor/github.com/charmbracelet/bubbletea/commands.go
generated
vendored
@ -13,6 +13,27 @@ import (
|
|||||||
// return tea.Batch(someCommand, someOtherCommand)
|
// return tea.Batch(someCommand, someOtherCommand)
|
||||||
// }
|
// }
|
||||||
func Batch(cmds ...Cmd) Cmd {
|
func Batch(cmds ...Cmd) Cmd {
|
||||||
|
return compactCmds[BatchMsg](cmds)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BatchMsg is a message used to perform a bunch of commands concurrently with
|
||||||
|
// no ordering guarantees. You can send a BatchMsg with Batch.
|
||||||
|
type BatchMsg []Cmd
|
||||||
|
|
||||||
|
// Sequence runs the given commands one at a time, in order. Contrast this with
|
||||||
|
// Batch, which runs commands concurrently.
|
||||||
|
func Sequence(cmds ...Cmd) Cmd {
|
||||||
|
return compactCmds[sequenceMsg](cmds)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sequenceMsg is used internally to run the given commands in order.
|
||||||
|
type sequenceMsg []Cmd
|
||||||
|
|
||||||
|
// compactCmds ignores any nil commands in cmds, and returns the most direct
|
||||||
|
// command possible. That is, considering the non-nil commands, if there are
|
||||||
|
// none it returns nil, if there is exactly one it returns that command
|
||||||
|
// directly, else it returns the non-nil commands as type T.
|
||||||
|
func compactCmds[T ~[]Cmd](cmds []Cmd) Cmd {
|
||||||
var validCmds []Cmd //nolint:prealloc
|
var validCmds []Cmd //nolint:prealloc
|
||||||
for _, c := range cmds {
|
for _, c := range cmds {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
@ -27,26 +48,11 @@ func Batch(cmds ...Cmd) Cmd {
|
|||||||
return validCmds[0]
|
return validCmds[0]
|
||||||
default:
|
default:
|
||||||
return func() Msg {
|
return func() Msg {
|
||||||
return BatchMsg(validCmds)
|
return T(validCmds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BatchMsg is a message used to perform a bunch of commands concurrently with
|
|
||||||
// no ordering guarantees. You can send a BatchMsg with Batch.
|
|
||||||
type BatchMsg []Cmd
|
|
||||||
|
|
||||||
// Sequence runs the given commands one at a time, in order. Contrast this with
|
|
||||||
// Batch, which runs commands concurrently.
|
|
||||||
func Sequence(cmds ...Cmd) Cmd {
|
|
||||||
return func() Msg {
|
|
||||||
return sequenceMsg(cmds)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sequenceMsg is used internally to run the given commands in order.
|
|
||||||
type sequenceMsg []Cmd
|
|
||||||
|
|
||||||
// Every is a command that ticks in sync with the system clock. So, if you
|
// Every is a command that ticks in sync with the system clock. So, if you
|
||||||
// wanted to tick with the system clock every second, minute or hour you
|
// wanted to tick with the system clock every second, minute or hour you
|
||||||
// could use this. It's also handy for having different things tick in sync.
|
// could use this. It's also handy for having different things tick in sync.
|
||||||
|
|||||||
2
vendor/github.com/charmbracelet/bubbletea/inputreader_windows.go
generated
vendored
2
vendor/github.com/charmbracelet/bubbletea/inputreader_windows.go
generated
vendored
@ -108,7 +108,7 @@ func prepareConsole(input windows.Handle, modes ...uint32) (originalMode uint32,
|
|||||||
return originalMode, nil
|
return originalMode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// cancelMixin represents a goroutine-safe cancelation status.
|
// cancelMixin represents a goroutine-safe cancellation status.
|
||||||
type cancelMixin struct {
|
type cancelMixin struct {
|
||||||
unsafeCanceled bool
|
unsafeCanceled bool
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
|
|||||||
16
vendor/github.com/charmbracelet/bubbletea/key_windows.go
generated
vendored
16
vendor/github.com/charmbracelet/bubbletea/key_windows.go
generated
vendored
@ -109,12 +109,12 @@ func peekAndReadConsInput(con *conInputReader) ([]coninput.InputRecord, error) {
|
|||||||
return events, nil
|
return events, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert i to unit32 or panic if it cannot be converted. Check satisifes lint G115.
|
// Convert i to unit32 or panic if it cannot be converted. Check satisfies lint G115.
|
||||||
func intToUint32OrDie(i int) uint32 {
|
func intToUint32OrDie(i int) uint32 {
|
||||||
if i < 0 {
|
if i < 0 {
|
||||||
panic("cannot convert numEvents " + fmt.Sprint(i) + " to uint32")
|
panic("cannot convert numEvents " + fmt.Sprint(i) + " to uint32")
|
||||||
}
|
}
|
||||||
return uint32(i)
|
return uint32(i) //nolint:gosec
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keeps peeking until there is data or the input is cancelled.
|
// Keeps peeking until there is data or the input is cancelled.
|
||||||
@ -158,16 +158,16 @@ func mouseEventButton(p, s coninput.ButtonState) (button MouseButton, action Mou
|
|||||||
return button, action
|
return button, action
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch btn {
|
||||||
case btn == coninput.FROM_LEFT_1ST_BUTTON_PRESSED: // left button
|
case coninput.FROM_LEFT_1ST_BUTTON_PRESSED: // left button
|
||||||
button = MouseButtonLeft
|
button = MouseButtonLeft
|
||||||
case btn == coninput.RIGHTMOST_BUTTON_PRESSED: // right button
|
case coninput.RIGHTMOST_BUTTON_PRESSED: // right button
|
||||||
button = MouseButtonRight
|
button = MouseButtonRight
|
||||||
case btn == coninput.FROM_LEFT_2ND_BUTTON_PRESSED: // middle button
|
case coninput.FROM_LEFT_2ND_BUTTON_PRESSED: // middle button
|
||||||
button = MouseButtonMiddle
|
button = MouseButtonMiddle
|
||||||
case btn == coninput.FROM_LEFT_3RD_BUTTON_PRESSED: // unknown (possibly mouse backward)
|
case coninput.FROM_LEFT_3RD_BUTTON_PRESSED: // unknown (possibly mouse backward)
|
||||||
button = MouseButtonBackward
|
button = MouseButtonBackward
|
||||||
case btn == coninput.FROM_LEFT_4TH_BUTTON_PRESSED: // unknown (possibly mouse forward)
|
case coninput.FROM_LEFT_4TH_BUTTON_PRESSED: // unknown (possibly mouse forward)
|
||||||
button = MouseButtonForward
|
button = MouseButtonForward
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
vendor/github.com/charmbracelet/bubbletea/screen.go
generated
vendored
2
vendor/github.com/charmbracelet/bubbletea/screen.go
generated
vendored
@ -131,7 +131,7 @@ func EnableBracketedPaste() Msg {
|
|||||||
type enableBracketedPasteMsg struct{}
|
type enableBracketedPasteMsg struct{}
|
||||||
|
|
||||||
// DisableBracketedPaste is a special command that tells the Bubble Tea program
|
// DisableBracketedPaste is a special command that tells the Bubble Tea program
|
||||||
// to accept bracketed paste input.
|
// to stop processing bracketed paste input.
|
||||||
//
|
//
|
||||||
// Note that bracketed paste will be automatically disabled when the
|
// Note that bracketed paste will be automatically disabled when the
|
||||||
// program quits.
|
// program quits.
|
||||||
|
|||||||
2
vendor/github.com/charmbracelet/bubbletea/standard_renderer.go
generated
vendored
2
vendor/github.com/charmbracelet/bubbletea/standard_renderer.go
generated
vendored
@ -277,7 +277,7 @@ func (r *standardRenderer) flush() {
|
|||||||
// using the full terminal window.
|
// using the full terminal window.
|
||||||
buf.WriteString(ansi.CursorPosition(0, len(newLines)))
|
buf.WriteString(ansi.CursorPosition(0, len(newLines)))
|
||||||
} else {
|
} else {
|
||||||
buf.WriteString(ansi.CursorBackward(r.width))
|
buf.WriteByte('\r')
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _ = r.out.Write(buf.Bytes())
|
_, _ = r.out.Write(buf.Bytes())
|
||||||
|
|||||||
109
vendor/github.com/charmbracelet/bubbletea/tea.go
generated
vendored
109
vendor/github.com/charmbracelet/bubbletea/tea.go
generated
vendored
@ -24,7 +24,6 @@ import (
|
|||||||
|
|
||||||
"github.com/charmbracelet/x/term"
|
"github.com/charmbracelet/x/term"
|
||||||
"github.com/muesli/cancelreader"
|
"github.com/muesli/cancelreader"
|
||||||
"golang.org/x/sync/errgroup"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrProgramPanic is returned by [Program.Run] when the program recovers from a panic.
|
// ErrProgramPanic is returned by [Program.Run] when the program recovers from a panic.
|
||||||
@ -73,7 +72,7 @@ const (
|
|||||||
customInput
|
customInput
|
||||||
)
|
)
|
||||||
|
|
||||||
// String implements the stringer interface for [inputType]. It is inteded to
|
// String implements the stringer interface for [inputType]. It is intended to
|
||||||
// be used in testing.
|
// be used in testing.
|
||||||
func (i inputType) String() string {
|
func (i inputType) String() string {
|
||||||
return [...]string{
|
return [...]string{
|
||||||
@ -220,7 +219,7 @@ func Suspend() Msg {
|
|||||||
// You can send this message with [Suspend()].
|
// You can send this message with [Suspend()].
|
||||||
type SuspendMsg struct{}
|
type SuspendMsg struct{}
|
||||||
|
|
||||||
// ResumeMsg can be listen to to do something once a program is resumed back
|
// ResumeMsg can be listen to do something once a program is resumed back
|
||||||
// from a suspend state.
|
// from a suspend state.
|
||||||
type ResumeMsg struct{}
|
type ResumeMsg struct{}
|
||||||
|
|
||||||
@ -472,42 +471,12 @@ func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) {
|
|||||||
p.exec(msg.cmd, msg.fn)
|
p.exec(msg.cmd, msg.fn)
|
||||||
|
|
||||||
case BatchMsg:
|
case BatchMsg:
|
||||||
for _, cmd := range msg {
|
go p.execBatchMsg(msg)
|
||||||
select {
|
|
||||||
case <-p.ctx.Done():
|
|
||||||
return model, nil
|
|
||||||
case cmds <- cmd:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
case sequenceMsg:
|
case sequenceMsg:
|
||||||
go func() {
|
go p.execSequenceMsg(msg)
|
||||||
// Execute commands one at a time, in order.
|
continue
|
||||||
for _, cmd := range msg {
|
|
||||||
if cmd == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
msg := cmd()
|
|
||||||
if batchMsg, ok := msg.(BatchMsg); ok {
|
|
||||||
g, _ := errgroup.WithContext(p.ctx)
|
|
||||||
for _, cmd := range batchMsg {
|
|
||||||
cmd := cmd
|
|
||||||
g.Go(func() error {
|
|
||||||
p.Send(cmd())
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
//nolint:errcheck,gosec
|
|
||||||
g.Wait() // wait for all commands from batch msg to finish
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
p.Send(msg)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
case setWindowTitleMsg:
|
case setWindowTitleMsg:
|
||||||
p.SetWindowTitle(string(msg))
|
p.SetWindowTitle(string(msg))
|
||||||
@ -535,6 +504,74 @@ func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Program) execSequenceMsg(msg sequenceMsg) {
|
||||||
|
if !p.startupOptions.has(withoutCatchPanics) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
p.recoverFromGoPanic(r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute commands one at a time, in order.
|
||||||
|
for _, cmd := range msg {
|
||||||
|
if cmd == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
msg := cmd()
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case BatchMsg:
|
||||||
|
p.execBatchMsg(msg)
|
||||||
|
case sequenceMsg:
|
||||||
|
p.execSequenceMsg(msg)
|
||||||
|
default:
|
||||||
|
p.Send(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Program) execBatchMsg(msg BatchMsg) {
|
||||||
|
if !p.startupOptions.has(withoutCatchPanics) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
p.recoverFromGoPanic(r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute commands one at a time.
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
for _, cmd := range msg {
|
||||||
|
if cmd == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
if !p.startupOptions.has(withoutCatchPanics) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
p.recoverFromGoPanic(r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := cmd()
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case BatchMsg:
|
||||||
|
p.execBatchMsg(msg)
|
||||||
|
case sequenceMsg:
|
||||||
|
p.execSequenceMsg(msg)
|
||||||
|
default:
|
||||||
|
p.Send(msg)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait() // wait for all commands from batch msg to finish
|
||||||
|
}
|
||||||
|
|
||||||
// Run initializes the program and runs its event loops, blocking until it gets
|
// Run initializes the program and runs its event loops, blocking until it gets
|
||||||
// terminated by either [Program.Quit], [Program.Kill], or its signal handler.
|
// terminated by either [Program.Quit], [Program.Kill], or its signal handler.
|
||||||
// Returns the final model.
|
// Returns the final model.
|
||||||
|
|||||||
2
vendor/github.com/charmbracelet/bubbletea/tty_windows.go
generated
vendored
2
vendor/github.com/charmbracelet/bubbletea/tty_windows.go
generated
vendored
@ -56,7 +56,7 @@ func (p *Program) initInput() (err error) {
|
|||||||
|
|
||||||
// Open the Windows equivalent of a TTY.
|
// Open the Windows equivalent of a TTY.
|
||||||
func openInputTTY() (*os.File, error) {
|
func openInputTTY() (*os.File, error) {
|
||||||
f, err := os.OpenFile("CONIN$", os.O_RDWR, 0o644)
|
f, err := os.OpenFile("CONIN$", os.O_RDWR, 0o644) //nolint:gosec
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error opening file: %w", err)
|
return nil, fmt.Errorf("error opening file: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
33
vendor/github.com/charmbracelet/colorprofile/env.go
generated
vendored
33
vendor/github.com/charmbracelet/colorprofile/env.go
generated
vendored
@ -153,29 +153,24 @@ func envColorProfile(env environ) (p Profile) {
|
|||||||
p = ANSI
|
p = ANSI
|
||||||
}
|
}
|
||||||
|
|
||||||
parts := strings.Split(term, "-")
|
switch {
|
||||||
switch parts[0] {
|
case strings.Contains(term, "alacritty"),
|
||||||
case "alacritty",
|
strings.Contains(term, "contour"),
|
||||||
"contour",
|
strings.Contains(term, "foot"),
|
||||||
"foot",
|
strings.Contains(term, "ghostty"),
|
||||||
"ghostty",
|
strings.Contains(term, "kitty"),
|
||||||
"kitty",
|
strings.Contains(term, "rio"),
|
||||||
"rio",
|
strings.Contains(term, "st"),
|
||||||
"st",
|
strings.Contains(term, "wezterm"):
|
||||||
"wezterm":
|
|
||||||
return TrueColor
|
return TrueColor
|
||||||
case "xterm":
|
case strings.HasPrefix(term, "tmux"), strings.HasPrefix(term, "screen"):
|
||||||
if len(parts) > 1 {
|
|
||||||
switch parts[1] {
|
|
||||||
case "ghostty", "kitty":
|
|
||||||
// These terminals can be defined as xterm-TERMNAME
|
|
||||||
return TrueColor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "tmux", "screen":
|
|
||||||
if p < ANSI256 {
|
if p < ANSI256 {
|
||||||
p = ANSI256
|
p = ANSI256
|
||||||
}
|
}
|
||||||
|
case strings.HasPrefix(term, "xterm"):
|
||||||
|
if p < ANSI {
|
||||||
|
p = ANSI
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if isCloudShell, _ := strconv.ParseBool(env.get("GOOGLE_CLOUD_SHELL")); isCloudShell {
|
if isCloudShell, _ := strconv.ParseBool(env.get("GOOGLE_CLOUD_SHELL")); isCloudShell {
|
||||||
|
|||||||
24
vendor/github.com/charmbracelet/x/ansi/inband.go
generated
vendored
Normal file
24
vendor/github.com/charmbracelet/x/ansi/inband.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package ansi
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// InBandResize encodes an in-band terminal resize event sequence.
|
||||||
|
//
|
||||||
|
// CSI 48 ; height_cells ; widht_cells ; height_pixels ; width_pixels t
|
||||||
|
//
|
||||||
|
// See https://gist.github.com/rockorager/e695fb2924d36b2bcf1fff4a3704bd83
|
||||||
|
func InBandResize(heightCells, widthCells, heightPixels, widthPixels int) string {
|
||||||
|
if heightCells < 0 {
|
||||||
|
heightCells = 0
|
||||||
|
}
|
||||||
|
if widthCells < 0 {
|
||||||
|
widthCells = 0
|
||||||
|
}
|
||||||
|
if heightPixels < 0 {
|
||||||
|
heightPixels = 0
|
||||||
|
}
|
||||||
|
if widthPixels < 0 {
|
||||||
|
widthPixels = 0
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("\x1b[48;%d;%d;%d;%dt", heightCells, widthCells, heightPixels, widthPixels)
|
||||||
|
}
|
||||||
465
vendor/github.com/charmbracelet/x/ansi/mode.go
generated
vendored
465
vendor/github.com/charmbracelet/x/ansi/mode.go
generated
vendored
@ -108,7 +108,7 @@ func DECRST(modes ...Mode) string {
|
|||||||
|
|
||||||
func setMode(reset bool, modes ...Mode) (s string) {
|
func setMode(reset bool, modes ...Mode) (s string) {
|
||||||
if len(modes) == 0 {
|
if len(modes) == 0 {
|
||||||
return //nolint:nakedret
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := "h"
|
cmd := "h"
|
||||||
@ -142,7 +142,7 @@ func setMode(reset bool, modes ...Mode) (s string) {
|
|||||||
if len(dec) > 0 {
|
if len(dec) > 0 {
|
||||||
s += seq + "?" + strings.Join(dec, ";") + cmd
|
s += seq + "?" + strings.Join(dec, ";") + cmd
|
||||||
}
|
}
|
||||||
return //nolint:nakedret
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestMode (DECRQM) returns a sequence to request a mode from the terminal.
|
// RequestMode (DECRQM) returns a sequence to request a mode from the terminal.
|
||||||
@ -228,12 +228,12 @@ func (m DECMode) Mode() int {
|
|||||||
//
|
//
|
||||||
// See: https://vt100.net/docs/vt510-rm/KAM.html
|
// See: https://vt100.net/docs/vt510-rm/KAM.html
|
||||||
const (
|
const (
|
||||||
KeyboardActionMode = ANSIMode(2)
|
ModeKeyboardAction = ANSIMode(2)
|
||||||
KAM = KeyboardActionMode
|
KAM = ModeKeyboardAction
|
||||||
|
|
||||||
SetKeyboardActionMode = "\x1b[2h"
|
SetModeKeyboardAction = "\x1b[2h"
|
||||||
ResetKeyboardActionMode = "\x1b[2l"
|
ResetModeKeyboardAction = "\x1b[2l"
|
||||||
RequestKeyboardActionMode = "\x1b[2$p"
|
RequestModeKeyboardAction = "\x1b[2$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Insert/Replace Mode (IRM) is a mode that determines whether characters are
|
// Insert/Replace Mode (IRM) is a mode that determines whether characters are
|
||||||
@ -245,12 +245,12 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://vt100.net/docs/vt510-rm/IRM.html
|
// See: https://vt100.net/docs/vt510-rm/IRM.html
|
||||||
const (
|
const (
|
||||||
InsertReplaceMode = ANSIMode(4)
|
ModeInsertReplace = ANSIMode(4)
|
||||||
IRM = InsertReplaceMode
|
IRM = ModeInsertReplace
|
||||||
|
|
||||||
SetInsertReplaceMode = "\x1b[4h"
|
SetModeInsertReplace = "\x1b[4h"
|
||||||
ResetInsertReplaceMode = "\x1b[4l"
|
ResetModeInsertReplace = "\x1b[4l"
|
||||||
RequestInsertReplaceMode = "\x1b[4$p"
|
RequestModeInsertReplace = "\x1b[4$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BiDirectional Support Mode (BDSM) is a mode that determines whether the
|
// BiDirectional Support Mode (BDSM) is a mode that determines whether the
|
||||||
@ -260,12 +260,12 @@ const (
|
|||||||
//
|
//
|
||||||
// See ECMA-48 7.2.1.
|
// See ECMA-48 7.2.1.
|
||||||
const (
|
const (
|
||||||
BiDirectionalSupportMode = ANSIMode(8)
|
ModeBiDirectionalSupport = ANSIMode(8)
|
||||||
BDSM = BiDirectionalSupportMode
|
BDSM = ModeBiDirectionalSupport
|
||||||
|
|
||||||
SetBiDirectionalSupportMode = "\x1b[8h"
|
SetModeBiDirectionalSupport = "\x1b[8h"
|
||||||
ResetBiDirectionalSupportMode = "\x1b[8l"
|
ResetModeBiDirectionalSupport = "\x1b[8l"
|
||||||
RequestBiDirectionalSupportMode = "\x1b[8$p"
|
RequestModeBiDirectionalSupport = "\x1b[8$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Send Receive Mode (SRM) or Local Echo Mode is a mode that determines whether
|
// Send Receive Mode (SRM) or Local Echo Mode is a mode that determines whether
|
||||||
@ -274,17 +274,17 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://vt100.net/docs/vt510-rm/SRM.html
|
// See: https://vt100.net/docs/vt510-rm/SRM.html
|
||||||
const (
|
const (
|
||||||
SendReceiveMode = ANSIMode(12)
|
ModeSendReceive = ANSIMode(12)
|
||||||
LocalEchoMode = SendReceiveMode
|
ModeLocalEcho = ModeSendReceive
|
||||||
SRM = SendReceiveMode
|
SRM = ModeSendReceive
|
||||||
|
|
||||||
SetSendReceiveMode = "\x1b[12h"
|
SetModeSendReceive = "\x1b[12h"
|
||||||
ResetSendReceiveMode = "\x1b[12l"
|
ResetModeSendReceive = "\x1b[12l"
|
||||||
RequestSendReceiveMode = "\x1b[12$p"
|
RequestModeSendReceive = "\x1b[12$p"
|
||||||
|
|
||||||
SetLocalEchoMode = "\x1b[12h"
|
SetModeLocalEcho = "\x1b[12h"
|
||||||
ResetLocalEchoMode = "\x1b[12l"
|
ResetModeLocalEcho = "\x1b[12l"
|
||||||
RequestLocalEchoMode = "\x1b[12$p"
|
RequestModeLocalEcho = "\x1b[12$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Line Feed/New Line Mode (LNM) is a mode that determines whether the terminal
|
// Line Feed/New Line Mode (LNM) is a mode that determines whether the terminal
|
||||||
@ -299,12 +299,12 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://vt100.net/docs/vt510-rm/LNM.html
|
// See: https://vt100.net/docs/vt510-rm/LNM.html
|
||||||
const (
|
const (
|
||||||
LineFeedNewLineMode = ANSIMode(20)
|
ModeLineFeedNewLine = ANSIMode(20)
|
||||||
LNM = LineFeedNewLineMode
|
LNM = ModeLineFeedNewLine
|
||||||
|
|
||||||
SetLineFeedNewLineMode = "\x1b[20h"
|
SetModeLineFeedNewLine = "\x1b[20h"
|
||||||
ResetLineFeedNewLineMode = "\x1b[20l"
|
ResetModeLineFeedNewLine = "\x1b[20l"
|
||||||
RequestLineFeedNewLineMode = "\x1b[20$p"
|
RequestModeLineFeedNewLine = "\x1b[20$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Cursor Keys Mode (DECCKM) is a mode that determines whether the cursor keys
|
// Cursor Keys Mode (DECCKM) is a mode that determines whether the cursor keys
|
||||||
@ -312,18 +312,12 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://vt100.net/docs/vt510-rm/DECCKM.html
|
// See: https://vt100.net/docs/vt510-rm/DECCKM.html
|
||||||
const (
|
const (
|
||||||
CursorKeysMode = DECMode(1)
|
ModeCursorKeys = DECMode(1)
|
||||||
DECCKM = CursorKeysMode
|
DECCKM = ModeCursorKeys
|
||||||
|
|
||||||
SetCursorKeysMode = "\x1b[?1h"
|
SetModeCursorKeys = "\x1b[?1h"
|
||||||
ResetCursorKeysMode = "\x1b[?1l"
|
ResetModeCursorKeys = "\x1b[?1l"
|
||||||
RequestCursorKeysMode = "\x1b[?1$p"
|
RequestModeCursorKeys = "\x1b[?1$p"
|
||||||
)
|
|
||||||
|
|
||||||
// Deprecated: use [SetCursorKeysMode] and [ResetCursorKeysMode] instead.
|
|
||||||
const (
|
|
||||||
EnableCursorKeys = "\x1b[?1h" //nolint:revive // grouped constants
|
|
||||||
DisableCursorKeys = "\x1b[?1l"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Origin Mode (DECOM) is a mode that determines whether the cursor moves to the
|
// Origin Mode (DECOM) is a mode that determines whether the cursor moves to the
|
||||||
@ -331,12 +325,12 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://vt100.net/docs/vt510-rm/DECOM.html
|
// See: https://vt100.net/docs/vt510-rm/DECOM.html
|
||||||
const (
|
const (
|
||||||
OriginMode = DECMode(6)
|
ModeOrigin = DECMode(6)
|
||||||
DECOM = OriginMode
|
DECOM = ModeOrigin
|
||||||
|
|
||||||
SetOriginMode = "\x1b[?6h"
|
SetModeOrigin = "\x1b[?6h"
|
||||||
ResetOriginMode = "\x1b[?6l"
|
ResetModeOrigin = "\x1b[?6l"
|
||||||
RequestOriginMode = "\x1b[?6$p"
|
RequestModeOrigin = "\x1b[?6$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Auto Wrap Mode (DECAWM) is a mode that determines whether the cursor wraps
|
// Auto Wrap Mode (DECAWM) is a mode that determines whether the cursor wraps
|
||||||
@ -344,12 +338,12 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://vt100.net/docs/vt510-rm/DECAWM.html
|
// See: https://vt100.net/docs/vt510-rm/DECAWM.html
|
||||||
const (
|
const (
|
||||||
AutoWrapMode = DECMode(7)
|
ModeAutoWrap = DECMode(7)
|
||||||
DECAWM = AutoWrapMode
|
DECAWM = ModeAutoWrap
|
||||||
|
|
||||||
SetAutoWrapMode = "\x1b[?7h"
|
SetModeAutoWrap = "\x1b[?7h"
|
||||||
ResetAutoWrapMode = "\x1b[?7l"
|
ResetModeAutoWrap = "\x1b[?7l"
|
||||||
RequestAutoWrapMode = "\x1b[?7$p"
|
RequestModeAutoWrap = "\x1b[?7$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// X10 Mouse Mode is a mode that determines whether the mouse reports on button
|
// X10 Mouse Mode is a mode that determines whether the mouse reports on button
|
||||||
@ -364,39 +358,29 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
||||||
const (
|
const (
|
||||||
X10MouseMode = DECMode(9)
|
ModeMouseX10 = DECMode(9)
|
||||||
|
|
||||||
SetX10MouseMode = "\x1b[?9h"
|
SetModeMouseX10 = "\x1b[?9h"
|
||||||
ResetX10MouseMode = "\x1b[?9l"
|
ResetModeMouseX10 = "\x1b[?9l"
|
||||||
RequestX10MouseMode = "\x1b[?9$p"
|
RequestModeMouseX10 = "\x1b[?9$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Text Cursor Enable Mode (DECTCEM) is a mode that shows/hides the cursor.
|
// Text Cursor Enable Mode (DECTCEM) is a mode that shows/hides the cursor.
|
||||||
//
|
//
|
||||||
// See: https://vt100.net/docs/vt510-rm/DECTCEM.html
|
// See: https://vt100.net/docs/vt510-rm/DECTCEM.html
|
||||||
const (
|
const (
|
||||||
TextCursorEnableMode = DECMode(25)
|
ModeTextCursorEnable = DECMode(25)
|
||||||
DECTCEM = TextCursorEnableMode
|
DECTCEM = ModeTextCursorEnable
|
||||||
|
|
||||||
SetTextCursorEnableMode = "\x1b[?25h"
|
SetModeTextCursorEnable = "\x1b[?25h"
|
||||||
ResetTextCursorEnableMode = "\x1b[?25l"
|
ResetModeTextCursorEnable = "\x1b[?25l"
|
||||||
RequestTextCursorEnableMode = "\x1b[?25$p"
|
RequestModeTextCursorEnable = "\x1b[?25$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// These are aliases for [SetTextCursorEnableMode] and [ResetTextCursorEnableMode].
|
// These are aliases for [SetModeTextCursorEnable] and [ResetModeTextCursorEnable].
|
||||||
const (
|
const (
|
||||||
ShowCursor = SetTextCursorEnableMode
|
ShowCursor = SetModeTextCursorEnable
|
||||||
HideCursor = ResetTextCursorEnableMode
|
HideCursor = ResetModeTextCursorEnable
|
||||||
)
|
|
||||||
|
|
||||||
// Text Cursor Enable Mode (DECTCEM) is a mode that shows/hides the cursor.
|
|
||||||
//
|
|
||||||
// See: https://vt100.net/docs/vt510-rm/DECTCEM.html
|
|
||||||
//
|
|
||||||
// Deprecated: use [SetTextCursorEnableMode] and [ResetTextCursorEnableMode] instead.
|
|
||||||
const (
|
|
||||||
CursorEnableMode = DECMode(25)
|
|
||||||
RequestCursorVisibility = "\x1b[?25$p"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Numeric Keypad Mode (DECNKM) is a mode that determines whether the keypad
|
// Numeric Keypad Mode (DECNKM) is a mode that determines whether the keypad
|
||||||
@ -406,12 +390,12 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://vt100.net/docs/vt510-rm/DECNKM.html
|
// See: https://vt100.net/docs/vt510-rm/DECNKM.html
|
||||||
const (
|
const (
|
||||||
NumericKeypadMode = DECMode(66)
|
ModeNumericKeypad = DECMode(66)
|
||||||
DECNKM = NumericKeypadMode
|
DECNKM = ModeNumericKeypad
|
||||||
|
|
||||||
SetNumericKeypadMode = "\x1b[?66h"
|
SetModeNumericKeypad = "\x1b[?66h"
|
||||||
ResetNumericKeypadMode = "\x1b[?66l"
|
ResetModeNumericKeypad = "\x1b[?66l"
|
||||||
RequestNumericKeypadMode = "\x1b[?66$p"
|
RequestModeNumericKeypad = "\x1b[?66$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Backarrow Key Mode (DECBKM) is a mode that determines whether the backspace
|
// Backarrow Key Mode (DECBKM) is a mode that determines whether the backspace
|
||||||
@ -419,12 +403,12 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://vt100.net/docs/vt510-rm/DECBKM.html
|
// See: https://vt100.net/docs/vt510-rm/DECBKM.html
|
||||||
const (
|
const (
|
||||||
BackarrowKeyMode = DECMode(67)
|
ModeBackarrowKey = DECMode(67)
|
||||||
DECBKM = BackarrowKeyMode
|
DECBKM = ModeBackarrowKey
|
||||||
|
|
||||||
SetBackarrowKeyMode = "\x1b[?67h"
|
SetModeBackarrowKey = "\x1b[?67h"
|
||||||
ResetBackarrowKeyMode = "\x1b[?67l"
|
ResetModeBackarrowKey = "\x1b[?67l"
|
||||||
RequestBackarrowKeyMode = "\x1b[?67$p"
|
RequestModeBackarrowKey = "\x1b[?67$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Left Right Margin Mode (DECLRMM) is a mode that determines whether the left
|
// Left Right Margin Mode (DECLRMM) is a mode that determines whether the left
|
||||||
@ -432,47 +416,33 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://vt100.net/docs/vt510-rm/DECLRMM.html
|
// See: https://vt100.net/docs/vt510-rm/DECLRMM.html
|
||||||
const (
|
const (
|
||||||
LeftRightMarginMode = DECMode(69)
|
ModeLeftRightMargin = DECMode(69)
|
||||||
DECLRMM = LeftRightMarginMode
|
DECLRMM = ModeLeftRightMargin
|
||||||
|
|
||||||
SetLeftRightMarginMode = "\x1b[?69h"
|
SetModeLeftRightMargin = "\x1b[?69h"
|
||||||
ResetLeftRightMarginMode = "\x1b[?69l"
|
ResetModeLeftRightMargin = "\x1b[?69l"
|
||||||
RequestLeftRightMarginMode = "\x1b[?69$p"
|
RequestModeLeftRightMargin = "\x1b[?69$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Normal Mouse Mode is a mode that determines whether the mouse reports on
|
// Normal Mouse Mode is a mode that determines whether the mouse reports on
|
||||||
// button presses and releases. It will also report modifier keys, wheel
|
// button presses and releases. It will also report modifier keys, wheel
|
||||||
// events, and extra buttons.
|
// events, and extra buttons.
|
||||||
//
|
//
|
||||||
// It uses the same encoding as [X10MouseMode] with a few differences:
|
// It uses the same encoding as [ModeMouseX10] with a few differences:
|
||||||
//
|
//
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
||||||
const (
|
const (
|
||||||
NormalMouseMode = DECMode(1000)
|
ModeMouseNormal = DECMode(1000)
|
||||||
|
|
||||||
SetNormalMouseMode = "\x1b[?1000h"
|
SetModeMouseNormal = "\x1b[?1000h"
|
||||||
ResetNormalMouseMode = "\x1b[?1000l"
|
ResetModeMouseNormal = "\x1b[?1000l"
|
||||||
RequestNormalMouseMode = "\x1b[?1000$p"
|
RequestModeMouseNormal = "\x1b[?1000$p"
|
||||||
)
|
|
||||||
|
|
||||||
// VT Mouse Tracking is a mode that determines whether the mouse reports on
|
|
||||||
// button press and release.
|
|
||||||
//
|
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
|
||||||
//
|
|
||||||
// Deprecated: use [NormalMouseMode] instead.
|
|
||||||
const (
|
|
||||||
MouseMode = DECMode(1000)
|
|
||||||
|
|
||||||
EnableMouse = "\x1b[?1000h"
|
|
||||||
DisableMouse = "\x1b[?1000l"
|
|
||||||
RequestMouse = "\x1b[?1000$p"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Highlight Mouse Tracking is a mode that determines whether the mouse reports
|
// Highlight Mouse Tracking is a mode that determines whether the mouse reports
|
||||||
// on button presses, releases, and highlighted cells.
|
// on button presses, releases, and highlighted cells.
|
||||||
//
|
//
|
||||||
// It uses the same encoding as [NormalMouseMode] with a few differences:
|
// It uses the same encoding as [ModeMouseNormal] with a few differences:
|
||||||
//
|
//
|
||||||
// On highlight events, the terminal responds with the following encoding:
|
// On highlight events, the terminal responds with the following encoding:
|
||||||
//
|
//
|
||||||
@ -481,11 +451,11 @@ const (
|
|||||||
//
|
//
|
||||||
// Where the parameters are startx, starty, endx, endy, mousex, and mousey.
|
// Where the parameters are startx, starty, endx, endy, mousex, and mousey.
|
||||||
const (
|
const (
|
||||||
HighlightMouseMode = DECMode(1001)
|
ModeMouseHighlight = DECMode(1001)
|
||||||
|
|
||||||
SetHighlightMouseMode = "\x1b[?1001h"
|
SetModeMouseHighlight = "\x1b[?1001h"
|
||||||
ResetHighlightMouseMode = "\x1b[?1001l"
|
ResetModeMouseHighlight = "\x1b[?1001l"
|
||||||
RequestHighlightMouseMode = "\x1b[?1001$p"
|
RequestModeMouseHighlight = "\x1b[?1001$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// VT Hilite Mouse Tracking is a mode that determines whether the mouse reports on
|
// VT Hilite Mouse Tracking is a mode that determines whether the mouse reports on
|
||||||
@ -493,65 +463,29 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
||||||
//
|
//
|
||||||
// Deprecated: use [HighlightMouseMode] instead.
|
|
||||||
const (
|
|
||||||
MouseHiliteMode = DECMode(1001)
|
|
||||||
|
|
||||||
EnableMouseHilite = "\x1b[?1001h"
|
// Button Event Mouse Tracking is essentially the same as [ModeMouseNormal],
|
||||||
DisableMouseHilite = "\x1b[?1001l"
|
|
||||||
RequestMouseHilite = "\x1b[?1001$p"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Button Event Mouse Tracking is essentially the same as [NormalMouseMode],
|
|
||||||
// but it also reports button-motion events when a button is pressed.
|
// but it also reports button-motion events when a button is pressed.
|
||||||
//
|
//
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
||||||
const (
|
const (
|
||||||
ButtonEventMouseMode = DECMode(1002)
|
ModeMouseButtonEvent = DECMode(1002)
|
||||||
|
|
||||||
SetButtonEventMouseMode = "\x1b[?1002h"
|
SetModeMouseButtonEvent = "\x1b[?1002h"
|
||||||
ResetButtonEventMouseMode = "\x1b[?1002l"
|
ResetModeMouseButtonEvent = "\x1b[?1002l"
|
||||||
RequestButtonEventMouseMode = "\x1b[?1002$p"
|
RequestModeMouseButtonEvent = "\x1b[?1002$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Cell Motion Mouse Tracking is a mode that determines whether the mouse
|
// Any Event Mouse Tracking is the same as [ModeMouseButtonEvent], except that
|
||||||
// reports on button press, release, and motion events.
|
|
||||||
//
|
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
|
||||||
//
|
|
||||||
// Deprecated: use [ButtonEventMouseMode] instead.
|
|
||||||
const (
|
|
||||||
MouseCellMotionMode = DECMode(1002)
|
|
||||||
|
|
||||||
EnableMouseCellMotion = "\x1b[?1002h"
|
|
||||||
DisableMouseCellMotion = "\x1b[?1002l"
|
|
||||||
RequestMouseCellMotion = "\x1b[?1002$p"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Any Event Mouse Tracking is the same as [ButtonEventMouseMode], except that
|
|
||||||
// all motion events are reported even if no mouse buttons are pressed.
|
// all motion events are reported even if no mouse buttons are pressed.
|
||||||
//
|
//
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
||||||
const (
|
const (
|
||||||
AnyEventMouseMode = DECMode(1003)
|
ModeMouseAnyEvent = DECMode(1003)
|
||||||
|
|
||||||
SetAnyEventMouseMode = "\x1b[?1003h"
|
SetModeMouseAnyEvent = "\x1b[?1003h"
|
||||||
ResetAnyEventMouseMode = "\x1b[?1003l"
|
ResetModeMouseAnyEvent = "\x1b[?1003l"
|
||||||
RequestAnyEventMouseMode = "\x1b[?1003$p"
|
RequestModeMouseAnyEvent = "\x1b[?1003$p"
|
||||||
)
|
|
||||||
|
|
||||||
// All Mouse Tracking is a mode that determines whether the mouse reports on
|
|
||||||
// button press, release, motion, and highlight events.
|
|
||||||
//
|
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
|
||||||
//
|
|
||||||
// Deprecated: use [AnyEventMouseMode] instead.
|
|
||||||
const (
|
|
||||||
MouseAllMotionMode = DECMode(1003)
|
|
||||||
|
|
||||||
EnableMouseAllMotion = "\x1b[?1003h"
|
|
||||||
DisableMouseAllMotion = "\x1b[?1003l"
|
|
||||||
RequestMouseAllMotion = "\x1b[?1003$p"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Focus Event Mode is a mode that determines whether the terminal reports focus
|
// Focus Event Mode is a mode that determines whether the terminal reports focus
|
||||||
@ -564,22 +498,11 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Focus-Tracking
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Focus-Tracking
|
||||||
const (
|
const (
|
||||||
FocusEventMode = DECMode(1004)
|
ModeFocusEvent = DECMode(1004)
|
||||||
|
|
||||||
SetFocusEventMode = "\x1b[?1004h"
|
SetModeFocusEvent = "\x1b[?1004h"
|
||||||
ResetFocusEventMode = "\x1b[?1004l"
|
ResetModeFocusEvent = "\x1b[?1004l"
|
||||||
RequestFocusEventMode = "\x1b[?1004$p"
|
RequestModeFocusEvent = "\x1b[?1004$p"
|
||||||
)
|
|
||||||
|
|
||||||
// Deprecated: use [SetFocusEventMode], [ResetFocusEventMode], and
|
|
||||||
// [RequestFocusEventMode] instead.
|
|
||||||
// Focus reporting mode constants.
|
|
||||||
const (
|
|
||||||
ReportFocusMode = DECMode(1004) //nolint:revive // grouped constants
|
|
||||||
|
|
||||||
EnableReportFocus = "\x1b[?1004h"
|
|
||||||
DisableReportFocus = "\x1b[?1004l"
|
|
||||||
RequestReportFocus = "\x1b[?1004$p"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SGR Extended Mouse Mode is a mode that changes the mouse tracking encoding
|
// SGR Extended Mouse Mode is a mode that changes the mouse tracking encoding
|
||||||
@ -589,24 +512,15 @@ const (
|
|||||||
//
|
//
|
||||||
// CSI < Cb ; Cx ; Cy M
|
// CSI < Cb ; Cx ; Cy M
|
||||||
//
|
//
|
||||||
// Where Cb is the same as [NormalMouseMode], and Cx and Cy are the x and y.
|
// Where Cb is the same as [ModeMouseNormal], and Cx and Cy are the x and y.
|
||||||
//
|
//
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
||||||
const (
|
const (
|
||||||
SgrExtMouseMode = DECMode(1006)
|
ModeMouseExtSgr = DECMode(1006)
|
||||||
|
|
||||||
SetSgrExtMouseMode = "\x1b[?1006h"
|
SetModeMouseExtSgr = "\x1b[?1006h"
|
||||||
ResetSgrExtMouseMode = "\x1b[?1006l"
|
ResetModeMouseExtSgr = "\x1b[?1006l"
|
||||||
RequestSgrExtMouseMode = "\x1b[?1006$p"
|
RequestModeMouseExtSgr = "\x1b[?1006$p"
|
||||||
)
|
|
||||||
|
|
||||||
// Deprecated: use [SgrExtMouseMode] [SetSgrExtMouseMode],
|
|
||||||
// [ResetSgrExtMouseMode], and [RequestSgrExtMouseMode] instead.
|
|
||||||
const (
|
|
||||||
MouseSgrExtMode = DECMode(1006) //nolint:revive // grouped constants
|
|
||||||
EnableMouseSgrExt = "\x1b[?1006h"
|
|
||||||
DisableMouseSgrExt = "\x1b[?1006l"
|
|
||||||
RequestMouseSgrExt = "\x1b[?1006$p"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// UTF-8 Extended Mouse Mode is a mode that changes the mouse tracking encoding
|
// UTF-8 Extended Mouse Mode is a mode that changes the mouse tracking encoding
|
||||||
@ -614,11 +528,11 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
||||||
const (
|
const (
|
||||||
Utf8ExtMouseMode = DECMode(1005)
|
ModeMouseExtUtf8 = DECMode(1005)
|
||||||
|
|
||||||
SetUtf8ExtMouseMode = "\x1b[?1005h"
|
SetModeMouseExtUtf8 = "\x1b[?1005h"
|
||||||
ResetUtf8ExtMouseMode = "\x1b[?1005l"
|
ResetModeMouseExtUtf8 = "\x1b[?1005l"
|
||||||
RequestUtf8ExtMouseMode = "\x1b[?1005$p"
|
RequestModeMouseExtUtf8 = "\x1b[?1005$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// URXVT Extended Mouse Mode is a mode that changes the mouse tracking encoding
|
// URXVT Extended Mouse Mode is a mode that changes the mouse tracking encoding
|
||||||
@ -626,25 +540,25 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
||||||
const (
|
const (
|
||||||
UrxvtExtMouseMode = DECMode(1015)
|
ModeMouseExtUrxvt = DECMode(1015)
|
||||||
|
|
||||||
SetUrxvtExtMouseMode = "\x1b[?1015h"
|
SetModeMouseExtUrxvt = "\x1b[?1015h"
|
||||||
ResetUrxvtExtMouseMode = "\x1b[?1015l"
|
ResetModeMouseExtUrxvt = "\x1b[?1015l"
|
||||||
RequestUrxvtExtMouseMode = "\x1b[?1015$p"
|
RequestModeMouseExtUrxvt = "\x1b[?1015$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SGR Pixel Extended Mouse Mode is a mode that changes the mouse tracking
|
// SGR Pixel Extended Mouse Mode is a mode that changes the mouse tracking
|
||||||
// encoding to use SGR parameters with pixel coordinates.
|
// encoding to use SGR parameters with pixel coordinates.
|
||||||
//
|
//
|
||||||
// This is similar to [SgrExtMouseMode], but also reports pixel coordinates.
|
// This is similar to [ModeMouseExtSgr], but also reports pixel coordinates.
|
||||||
//
|
//
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
|
||||||
const (
|
const (
|
||||||
SgrPixelExtMouseMode = DECMode(1016)
|
ModeMouseExtSgrPixel = DECMode(1016)
|
||||||
|
|
||||||
SetSgrPixelExtMouseMode = "\x1b[?1016h"
|
SetModeMouseExtSgrPixel = "\x1b[?1016h"
|
||||||
ResetSgrPixelExtMouseMode = "\x1b[?1016l"
|
ResetModeMouseExtSgrPixel = "\x1b[?1016l"
|
||||||
RequestSgrPixelExtMouseMode = "\x1b[?1016$p"
|
RequestModeMouseExtSgrPixel = "\x1b[?1016$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Alternate Screen Mode is a mode that determines whether the alternate screen
|
// Alternate Screen Mode is a mode that determines whether the alternate screen
|
||||||
@ -653,11 +567,11 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
|
||||||
const (
|
const (
|
||||||
AltScreenMode = DECMode(1047)
|
ModeAltScreen = DECMode(1047)
|
||||||
|
|
||||||
SetAltScreenMode = "\x1b[?1047h"
|
SetModeAltScreen = "\x1b[?1047h"
|
||||||
ResetAltScreenMode = "\x1b[?1047l"
|
ResetModeAltScreen = "\x1b[?1047l"
|
||||||
RequestAltScreenMode = "\x1b[?1047$p"
|
RequestModeAltScreen = "\x1b[?1047$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Save Cursor Mode is a mode that saves the cursor position.
|
// Save Cursor Mode is a mode that saves the cursor position.
|
||||||
@ -665,42 +579,24 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
|
||||||
const (
|
const (
|
||||||
SaveCursorMode = DECMode(1048)
|
ModeSaveCursor = DECMode(1048)
|
||||||
|
|
||||||
SetSaveCursorMode = "\x1b[?1048h"
|
SetModeSaveCursor = "\x1b[?1048h"
|
||||||
ResetSaveCursorMode = "\x1b[?1048l"
|
ResetModeSaveCursor = "\x1b[?1048l"
|
||||||
RequestSaveCursorMode = "\x1b[?1048$p"
|
RequestModeSaveCursor = "\x1b[?1048$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Alternate Screen Save Cursor Mode is a mode that saves the cursor position as in
|
// Alternate Screen Save Cursor Mode is a mode that saves the cursor position as in
|
||||||
// [SaveCursorMode], switches to the alternate screen buffer as in [AltScreenMode],
|
// [ModeSaveCursor], switches to the alternate screen buffer as in [ModeAltScreen],
|
||||||
// and clears the screen on switch.
|
// and clears the screen on switch.
|
||||||
//
|
//
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
|
||||||
const (
|
const (
|
||||||
AltScreenSaveCursorMode = DECMode(1049)
|
ModeAltScreenSaveCursor = DECMode(1049)
|
||||||
|
|
||||||
SetAltScreenSaveCursorMode = "\x1b[?1049h"
|
SetModeAltScreenSaveCursor = "\x1b[?1049h"
|
||||||
ResetAltScreenSaveCursorMode = "\x1b[?1049l"
|
ResetModeAltScreenSaveCursor = "\x1b[?1049l"
|
||||||
RequestAltScreenSaveCursorMode = "\x1b[?1049$p"
|
RequestModeAltScreenSaveCursor = "\x1b[?1049$p"
|
||||||
)
|
|
||||||
|
|
||||||
// Alternate Screen Buffer is a mode that determines whether the alternate screen
|
|
||||||
// buffer is active.
|
|
||||||
//
|
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
|
|
||||||
//
|
|
||||||
// Deprecated: use [AltScreenSaveCursorMode] instead.
|
|
||||||
const (
|
|
||||||
AltScreenBufferMode = DECMode(1049)
|
|
||||||
|
|
||||||
SetAltScreenBufferMode = "\x1b[?1049h"
|
|
||||||
ResetAltScreenBufferMode = "\x1b[?1049l"
|
|
||||||
RequestAltScreenBufferMode = "\x1b[?1049$p"
|
|
||||||
|
|
||||||
EnableAltScreenBuffer = "\x1b[?1049h"
|
|
||||||
DisableAltScreenBuffer = "\x1b[?1049l"
|
|
||||||
RequestAltScreenBuffer = "\x1b[?1049$p"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Bracketed Paste Mode is a mode that determines whether pasted text is
|
// Bracketed Paste Mode is a mode that determines whether pasted text is
|
||||||
@ -709,19 +605,11 @@ const (
|
|||||||
// See: https://cirw.in/blog/bracketed-paste
|
// See: https://cirw.in/blog/bracketed-paste
|
||||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Bracketed-Paste-Mode
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Bracketed-Paste-Mode
|
||||||
const (
|
const (
|
||||||
BracketedPasteMode = DECMode(2004)
|
ModeBracketedPaste = DECMode(2004)
|
||||||
|
|
||||||
SetBracketedPasteMode = "\x1b[?2004h"
|
SetModeBracketedPaste = "\x1b[?2004h"
|
||||||
ResetBracketedPasteMode = "\x1b[?2004l"
|
ResetModeBracketedPaste = "\x1b[?2004l"
|
||||||
RequestBracketedPasteMode = "\x1b[?2004$p"
|
RequestModeBracketedPaste = "\x1b[?2004$p"
|
||||||
)
|
|
||||||
|
|
||||||
// Deprecated: use [SetBracketedPasteMode], [ResetBracketedPasteMode], and
|
|
||||||
// [RequestBracketedPasteMode] instead.
|
|
||||||
const (
|
|
||||||
EnableBracketedPaste = "\x1b[?2004h" //nolint:revive // grouped constants
|
|
||||||
DisableBracketedPaste = "\x1b[?2004l"
|
|
||||||
RequestBracketedPaste = "\x1b[?2004$p"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Synchronized Output Mode is a mode that determines whether output is
|
// Synchronized Output Mode is a mode that determines whether output is
|
||||||
@ -729,23 +617,11 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036
|
// See: https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036
|
||||||
const (
|
const (
|
||||||
SynchronizedOutputMode = DECMode(2026)
|
ModeSynchronizedOutput = DECMode(2026)
|
||||||
|
|
||||||
SetSynchronizedOutputMode = "\x1b[?2026h"
|
SetModeSynchronizedOutput = "\x1b[?2026h"
|
||||||
ResetSynchronizedOutputMode = "\x1b[?2026l"
|
ResetModeSynchronizedOutput = "\x1b[?2026l"
|
||||||
RequestSynchronizedOutputMode = "\x1b[?2026$p"
|
RequestModeSynchronizedOutput = "\x1b[?2026$p"
|
||||||
)
|
|
||||||
|
|
||||||
// Synchronized Output Mode. See [SynchronizedOutputMode].
|
|
||||||
//
|
|
||||||
// Deprecated: use [SynchronizedOutputMode], [SetSynchronizedOutputMode], and
|
|
||||||
// [ResetSynchronizedOutputMode], and [RequestSynchronizedOutputMode] instead.
|
|
||||||
const (
|
|
||||||
SyncdOutputMode = DECMode(2026)
|
|
||||||
|
|
||||||
EnableSyncdOutput = "\x1b[?2026h"
|
|
||||||
DisableSyncdOutput = "\x1b[?2026l"
|
|
||||||
RequestSyncdOutput = "\x1b[?2026$p"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Unicode Core Mode is a mode that determines whether the terminal should use
|
// Unicode Core Mode is a mode that determines whether the terminal should use
|
||||||
@ -754,41 +630,16 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://github.com/contour-terminal/terminal-unicode-core
|
// See: https://github.com/contour-terminal/terminal-unicode-core
|
||||||
const (
|
const (
|
||||||
UnicodeCoreMode = DECMode(2027)
|
ModeUnicodeCore = DECMode(2027)
|
||||||
|
|
||||||
SetUnicodeCoreMode = "\x1b[?2027h"
|
SetModeUnicodeCore = "\x1b[?2027h"
|
||||||
ResetUnicodeCoreMode = "\x1b[?2027l"
|
ResetModeUnicodeCore = "\x1b[?2027l"
|
||||||
RequestUnicodeCoreMode = "\x1b[?2027$p"
|
RequestModeUnicodeCore = "\x1b[?2027$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Grapheme Clustering Mode is a mode that determines whether the terminal
|
|
||||||
// should look for grapheme clusters instead of single runes in the rendered
|
|
||||||
// text. This makes the terminal properly render combining characters such as
|
|
||||||
// emojis.
|
|
||||||
//
|
//
|
||||||
// See: https://github.com/contour-terminal/terminal-unicode-core
|
|
||||||
//
|
|
||||||
// Deprecated: use [GraphemeClusteringMode], [SetUnicodeCoreMode],
|
|
||||||
// [ResetUnicodeCoreMode], and [RequestUnicodeCoreMode] instead.
|
|
||||||
const (
|
|
||||||
GraphemeClusteringMode = DECMode(2027)
|
|
||||||
|
|
||||||
SetGraphemeClusteringMode = "\x1b[?2027h"
|
// ModeLightDark is a mode that enables reporting the operating system's color
|
||||||
ResetGraphemeClusteringMode = "\x1b[?2027l"
|
|
||||||
RequestGraphemeClusteringMode = "\x1b[?2027$p"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Grapheme Clustering Mode. See [GraphemeClusteringMode].
|
|
||||||
//
|
|
||||||
// Deprecated: use [SetUnicodeCoreMode], [ResetUnicodeCoreMode], and
|
|
||||||
// [RequestUnicodeCoreMode] instead.
|
|
||||||
const (
|
|
||||||
EnableGraphemeClustering = "\x1b[?2027h"
|
|
||||||
DisableGraphemeClustering = "\x1b[?2027l"
|
|
||||||
RequestGraphemeClustering = "\x1b[?2027$p"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LightDarkMode is a mode that enables reporting the operating system's color
|
|
||||||
// scheme (light or dark) preference. It reports the color scheme as a [DSR]
|
// scheme (light or dark) preference. It reports the color scheme as a [DSR]
|
||||||
// and [LightDarkReport] escape sequences encoded as follows:
|
// and [LightDarkReport] escape sequences encoded as follows:
|
||||||
//
|
//
|
||||||
@ -802,14 +653,14 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://contour-terminal.org/vt-extensions/color-palette-update-notifications/
|
// See: https://contour-terminal.org/vt-extensions/color-palette-update-notifications/
|
||||||
const (
|
const (
|
||||||
LightDarkMode = DECMode(2031)
|
ModeLightDark = DECMode(2031)
|
||||||
|
|
||||||
SetLightDarkMode = "\x1b[?2031h"
|
SetModeLightDark = "\x1b[?2031h"
|
||||||
ResetLightDarkMode = "\x1b[?2031l"
|
ResetModeLightDark = "\x1b[?2031l"
|
||||||
RequestLightDarkMode = "\x1b[?2031$p"
|
RequestModeLightDark = "\x1b[?2031$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InBandResizeMode is a mode that reports terminal resize events as escape
|
// ModeInBandResize is a mode that reports terminal resize events as escape
|
||||||
// sequences. This is useful for systems that do not support [SIGWINCH] like
|
// sequences. This is useful for systems that do not support [SIGWINCH] like
|
||||||
// Windows.
|
// Windows.
|
||||||
//
|
//
|
||||||
@ -819,11 +670,11 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://gist.github.com/rockorager/e695fb2924d36b2bcf1fff4a3704bd83
|
// See: https://gist.github.com/rockorager/e695fb2924d36b2bcf1fff4a3704bd83
|
||||||
const (
|
const (
|
||||||
InBandResizeMode = DECMode(2048)
|
ModeInBandResize = DECMode(2048)
|
||||||
|
|
||||||
SetInBandResizeMode = "\x1b[?2048h"
|
SetModeInBandResize = "\x1b[?2048h"
|
||||||
ResetInBandResizeMode = "\x1b[?2048l"
|
ResetModeInBandResize = "\x1b[?2048l"
|
||||||
RequestInBandResizeMode = "\x1b[?2048$p"
|
RequestModeInBandResize = "\x1b[?2048$p"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Win32Input is a mode that determines whether input is processed by the
|
// Win32Input is a mode that determines whether input is processed by the
|
||||||
@ -831,17 +682,9 @@ const (
|
|||||||
//
|
//
|
||||||
// See: https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md
|
// See: https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md
|
||||||
const (
|
const (
|
||||||
Win32InputMode = DECMode(9001)
|
ModeWin32Input = DECMode(9001)
|
||||||
|
|
||||||
SetWin32InputMode = "\x1b[?9001h"
|
SetModeWin32Input = "\x1b[?9001h"
|
||||||
ResetWin32InputMode = "\x1b[?9001l"
|
ResetModeWin32Input = "\x1b[?9001l"
|
||||||
RequestWin32InputMode = "\x1b[?9001$p"
|
RequestModeWin32Input = "\x1b[?9001$p"
|
||||||
)
|
|
||||||
|
|
||||||
// Deprecated: use [SetWin32InputMode], [ResetWin32InputMode], and
|
|
||||||
// [RequestWin32InputMode] instead.
|
|
||||||
const (
|
|
||||||
EnableWin32Input = "\x1b[?9001h" //nolint:revive // grouped constants
|
|
||||||
DisableWin32Input = "\x1b[?9001l"
|
|
||||||
RequestWin32Input = "\x1b[?9001$p"
|
|
||||||
)
|
)
|
||||||
|
|||||||
495
vendor/github.com/charmbracelet/x/ansi/mode_deprecated.go
generated
vendored
Normal file
495
vendor/github.com/charmbracelet/x/ansi/mode_deprecated.go
generated
vendored
Normal file
@ -0,0 +1,495 @@
|
|||||||
|
package ansi
|
||||||
|
|
||||||
|
// Keyboard Action Mode (KAM) controls locking of the keyboard.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeKeyboardAction] instead.
|
||||||
|
const (
|
||||||
|
KeyboardActionMode = ANSIMode(2)
|
||||||
|
|
||||||
|
SetKeyboardActionMode = "\x1b[2h"
|
||||||
|
ResetKeyboardActionMode = "\x1b[2l"
|
||||||
|
RequestKeyboardActionMode = "\x1b[2$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Insert/Replace Mode (IRM) determines whether characters are inserted or replaced.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeInsertReplace] instead.
|
||||||
|
const (
|
||||||
|
InsertReplaceMode = ANSIMode(4)
|
||||||
|
|
||||||
|
SetInsertReplaceMode = "\x1b[4h"
|
||||||
|
ResetInsertReplaceMode = "\x1b[4l"
|
||||||
|
RequestInsertReplaceMode = "\x1b[4$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BiDirectional Support Mode (BDSM) determines whether the terminal supports bidirectional text.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeBiDirectionalSupport] instead.
|
||||||
|
const (
|
||||||
|
BiDirectionalSupportMode = ANSIMode(8)
|
||||||
|
|
||||||
|
SetBiDirectionalSupportMode = "\x1b[8h"
|
||||||
|
ResetBiDirectionalSupportMode = "\x1b[8l"
|
||||||
|
RequestBiDirectionalSupportMode = "\x1b[8$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Send Receive Mode (SRM) or Local Echo Mode determines whether the terminal echoes characters.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeSendReceive] instead.
|
||||||
|
const (
|
||||||
|
SendReceiveMode = ANSIMode(12)
|
||||||
|
LocalEchoMode = SendReceiveMode
|
||||||
|
|
||||||
|
SetSendReceiveMode = "\x1b[12h"
|
||||||
|
ResetSendReceiveMode = "\x1b[12l"
|
||||||
|
RequestSendReceiveMode = "\x1b[12$p"
|
||||||
|
|
||||||
|
SetLocalEchoMode = "\x1b[12h"
|
||||||
|
ResetLocalEchoMode = "\x1b[12l"
|
||||||
|
RequestLocalEchoMode = "\x1b[12$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Line Feed/New Line Mode (LNM) determines whether the terminal interprets line feed as new line.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeLineFeedNewLine] instead.
|
||||||
|
const (
|
||||||
|
LineFeedNewLineMode = ANSIMode(20)
|
||||||
|
|
||||||
|
SetLineFeedNewLineMode = "\x1b[20h"
|
||||||
|
ResetLineFeedNewLineMode = "\x1b[20l"
|
||||||
|
RequestLineFeedNewLineMode = "\x1b[20$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Cursor Keys Mode (DECCKM) determines whether cursor keys send ANSI or application sequences.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeCursorKeys] instead.
|
||||||
|
const (
|
||||||
|
CursorKeysMode = DECMode(1)
|
||||||
|
|
||||||
|
SetCursorKeysMode = "\x1b[?1h"
|
||||||
|
ResetCursorKeysMode = "\x1b[?1l"
|
||||||
|
RequestCursorKeysMode = "\x1b[?1$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Cursor Keys mode.
|
||||||
|
//
|
||||||
|
// Deprecated: use [SetModeCursorKeys] and [ResetModeCursorKeys] instead.
|
||||||
|
const (
|
||||||
|
EnableCursorKeys = "\x1b[?1h"
|
||||||
|
DisableCursorKeys = "\x1b[?1l"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Origin Mode (DECOM) determines whether the cursor moves to home or margin position.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeOrigin] instead.
|
||||||
|
const (
|
||||||
|
OriginMode = DECMode(6)
|
||||||
|
|
||||||
|
SetOriginMode = "\x1b[?6h"
|
||||||
|
ResetOriginMode = "\x1b[?6l"
|
||||||
|
RequestOriginMode = "\x1b[?6$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Auto Wrap Mode (DECAWM) determines whether the cursor wraps to the next line.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeAutoWrap] instead.
|
||||||
|
const (
|
||||||
|
AutoWrapMode = DECMode(7)
|
||||||
|
|
||||||
|
SetAutoWrapMode = "\x1b[?7h"
|
||||||
|
ResetAutoWrapMode = "\x1b[?7l"
|
||||||
|
RequestAutoWrapMode = "\x1b[?7$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// X10 Mouse Mode determines whether the mouse reports on button presses.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeMouseX10] instead.
|
||||||
|
const (
|
||||||
|
X10MouseMode = DECMode(9)
|
||||||
|
|
||||||
|
SetX10MouseMode = "\x1b[?9h"
|
||||||
|
ResetX10MouseMode = "\x1b[?9l"
|
||||||
|
RequestX10MouseMode = "\x1b[?9$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Text Cursor Enable Mode (DECTCEM) shows/hides the cursor.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeTextCursorEnable] instead.
|
||||||
|
const (
|
||||||
|
TextCursorEnableMode = DECMode(25)
|
||||||
|
|
||||||
|
SetTextCursorEnableMode = "\x1b[?25h"
|
||||||
|
ResetTextCursorEnableMode = "\x1b[?25l"
|
||||||
|
RequestTextCursorEnableMode = "\x1b[?25$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Text Cursor Enable mode.
|
||||||
|
//
|
||||||
|
// Deprecated: use [SetModeTextCursorEnable] and [ResetModeTextCursorEnable] instead.
|
||||||
|
const (
|
||||||
|
CursorEnableMode = DECMode(25)
|
||||||
|
RequestCursorVisibility = "\x1b[?25$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Numeric Keypad Mode (DECNKM) determines whether the keypad sends application or numeric sequences.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeNumericKeypad] instead.
|
||||||
|
const (
|
||||||
|
NumericKeypadMode = DECMode(66)
|
||||||
|
|
||||||
|
SetNumericKeypadMode = "\x1b[?66h"
|
||||||
|
ResetNumericKeypadMode = "\x1b[?66l"
|
||||||
|
RequestNumericKeypadMode = "\x1b[?66$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Backarrow Key Mode (DECBKM) determines whether the backspace key sends backspace or delete.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeBackarrowKey] instead.
|
||||||
|
const (
|
||||||
|
BackarrowKeyMode = DECMode(67)
|
||||||
|
|
||||||
|
SetBackarrowKeyMode = "\x1b[?67h"
|
||||||
|
ResetBackarrowKeyMode = "\x1b[?67l"
|
||||||
|
RequestBackarrowKeyMode = "\x1b[?67$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Left Right Margin Mode (DECLRMM) determines whether left and right margins can be set.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeLeftRightMargin] instead.
|
||||||
|
const (
|
||||||
|
LeftRightMarginMode = DECMode(69)
|
||||||
|
|
||||||
|
SetLeftRightMarginMode = "\x1b[?69h"
|
||||||
|
ResetLeftRightMarginMode = "\x1b[?69l"
|
||||||
|
RequestLeftRightMarginMode = "\x1b[?69$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Normal Mouse Mode determines whether the mouse reports on button presses and releases.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeMouseNormal] instead.
|
||||||
|
const (
|
||||||
|
NormalMouseMode = DECMode(1000)
|
||||||
|
|
||||||
|
SetNormalMouseMode = "\x1b[?1000h"
|
||||||
|
ResetNormalMouseMode = "\x1b[?1000l"
|
||||||
|
RequestNormalMouseMode = "\x1b[?1000$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// VT Mouse Tracking mode.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeMouseNormal] instead.
|
||||||
|
const (
|
||||||
|
MouseMode = DECMode(1000)
|
||||||
|
|
||||||
|
EnableMouse = "\x1b[?1000h"
|
||||||
|
DisableMouse = "\x1b[?1000l"
|
||||||
|
RequestMouse = "\x1b[?1000$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Highlight Mouse Tracking determines whether the mouse reports on button presses and highlighted cells.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeMouseHighlight] instead.
|
||||||
|
const (
|
||||||
|
HighlightMouseMode = DECMode(1001)
|
||||||
|
|
||||||
|
SetHighlightMouseMode = "\x1b[?1001h"
|
||||||
|
ResetHighlightMouseMode = "\x1b[?1001l"
|
||||||
|
RequestHighlightMouseMode = "\x1b[?1001$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// VT Hilite Mouse Tracking mode.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeMouseHighlight] instead.
|
||||||
|
const (
|
||||||
|
MouseHiliteMode = DECMode(1001)
|
||||||
|
|
||||||
|
EnableMouseHilite = "\x1b[?1001h"
|
||||||
|
DisableMouseHilite = "\x1b[?1001l"
|
||||||
|
RequestMouseHilite = "\x1b[?1001$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Button Event Mouse Tracking reports button-motion events when a button is pressed.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeMouseButtonEvent] instead.
|
||||||
|
const (
|
||||||
|
ButtonEventMouseMode = DECMode(1002)
|
||||||
|
|
||||||
|
SetButtonEventMouseMode = "\x1b[?1002h"
|
||||||
|
ResetButtonEventMouseMode = "\x1b[?1002l"
|
||||||
|
RequestButtonEventMouseMode = "\x1b[?1002$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Cell Motion Mouse Tracking mode.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeMouseButtonEvent] instead.
|
||||||
|
const (
|
||||||
|
MouseCellMotionMode = DECMode(1002)
|
||||||
|
|
||||||
|
EnableMouseCellMotion = "\x1b[?1002h"
|
||||||
|
DisableMouseCellMotion = "\x1b[?1002l"
|
||||||
|
RequestMouseCellMotion = "\x1b[?1002$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Any Event Mouse Tracking reports all motion events.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeMouseAnyEvent] instead.
|
||||||
|
const (
|
||||||
|
AnyEventMouseMode = DECMode(1003)
|
||||||
|
|
||||||
|
SetAnyEventMouseMode = "\x1b[?1003h"
|
||||||
|
ResetAnyEventMouseMode = "\x1b[?1003l"
|
||||||
|
RequestAnyEventMouseMode = "\x1b[?1003$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// All Mouse Tracking mode.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeMouseAnyEvent] instead.
|
||||||
|
const (
|
||||||
|
MouseAllMotionMode = DECMode(1003)
|
||||||
|
|
||||||
|
EnableMouseAllMotion = "\x1b[?1003h"
|
||||||
|
DisableMouseAllMotion = "\x1b[?1003l"
|
||||||
|
RequestMouseAllMotion = "\x1b[?1003$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Focus Event Mode determines whether the terminal reports focus and blur events.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeFocusEvent] instead.
|
||||||
|
const (
|
||||||
|
FocusEventMode = DECMode(1004)
|
||||||
|
|
||||||
|
SetFocusEventMode = "\x1b[?1004h"
|
||||||
|
ResetFocusEventMode = "\x1b[?1004l"
|
||||||
|
RequestFocusEventMode = "\x1b[?1004$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Focus reporting mode.
|
||||||
|
//
|
||||||
|
// Deprecated: use [SetModeFocusEvent], [ResetModeFocusEvent], and
|
||||||
|
// [RequestModeFocusEvent] instead.
|
||||||
|
const (
|
||||||
|
ReportFocusMode = DECMode(1004)
|
||||||
|
|
||||||
|
EnableReportFocus = "\x1b[?1004h"
|
||||||
|
DisableReportFocus = "\x1b[?1004l"
|
||||||
|
RequestReportFocus = "\x1b[?1004$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UTF-8 Extended Mouse Mode changes the mouse tracking encoding to use UTF-8 parameters.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeMouseExtUtf8] instead.
|
||||||
|
const (
|
||||||
|
Utf8ExtMouseMode = DECMode(1005)
|
||||||
|
|
||||||
|
SetUtf8ExtMouseMode = "\x1b[?1005h"
|
||||||
|
ResetUtf8ExtMouseMode = "\x1b[?1005l"
|
||||||
|
RequestUtf8ExtMouseMode = "\x1b[?1005$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SGR Extended Mouse Mode changes the mouse tracking encoding to use SGR parameters.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeMouseExtSgr] instead.
|
||||||
|
const (
|
||||||
|
SgrExtMouseMode = DECMode(1006)
|
||||||
|
|
||||||
|
SetSgrExtMouseMode = "\x1b[?1006h"
|
||||||
|
ResetSgrExtMouseMode = "\x1b[?1006l"
|
||||||
|
RequestSgrExtMouseMode = "\x1b[?1006$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Mouse SGR Extended mode.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeMouseExtSgr], [SetModeMouseExtSgr],
|
||||||
|
// [ResetModeMouseExtSgr], and [RequestModeMouseExtSgr] instead.
|
||||||
|
const (
|
||||||
|
MouseSgrExtMode = DECMode(1006)
|
||||||
|
EnableMouseSgrExt = "\x1b[?1006h"
|
||||||
|
DisableMouseSgrExt = "\x1b[?1006l"
|
||||||
|
RequestMouseSgrExt = "\x1b[?1006$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// URXVT Extended Mouse Mode changes the mouse tracking encoding to use an alternate encoding.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeMouseUrxvtExt] instead.
|
||||||
|
const (
|
||||||
|
UrxvtExtMouseMode = DECMode(1015)
|
||||||
|
|
||||||
|
SetUrxvtExtMouseMode = "\x1b[?1015h"
|
||||||
|
ResetUrxvtExtMouseMode = "\x1b[?1015l"
|
||||||
|
RequestUrxvtExtMouseMode = "\x1b[?1015$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SGR Pixel Extended Mouse Mode changes the mouse tracking encoding to use SGR parameters with pixel coordinates.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeMouseExtSgrPixel] instead.
|
||||||
|
const (
|
||||||
|
SgrPixelExtMouseMode = DECMode(1016)
|
||||||
|
|
||||||
|
SetSgrPixelExtMouseMode = "\x1b[?1016h"
|
||||||
|
ResetSgrPixelExtMouseMode = "\x1b[?1016l"
|
||||||
|
RequestSgrPixelExtMouseMode = "\x1b[?1016$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Alternate Screen Mode determines whether the alternate screen buffer is active.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeAltScreen] instead.
|
||||||
|
const (
|
||||||
|
AltScreenMode = DECMode(1047)
|
||||||
|
|
||||||
|
SetAltScreenMode = "\x1b[?1047h"
|
||||||
|
ResetAltScreenMode = "\x1b[?1047l"
|
||||||
|
RequestAltScreenMode = "\x1b[?1047$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Save Cursor Mode saves the cursor position.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeSaveCursor] instead.
|
||||||
|
const (
|
||||||
|
SaveCursorMode = DECMode(1048)
|
||||||
|
|
||||||
|
SetSaveCursorMode = "\x1b[?1048h"
|
||||||
|
ResetSaveCursorMode = "\x1b[?1048l"
|
||||||
|
RequestSaveCursorMode = "\x1b[?1048$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Alternate Screen Save Cursor Mode saves the cursor position and switches to alternate screen.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeAltScreenSaveCursor] instead.
|
||||||
|
const (
|
||||||
|
AltScreenSaveCursorMode = DECMode(1049)
|
||||||
|
|
||||||
|
SetAltScreenSaveCursorMode = "\x1b[?1049h"
|
||||||
|
ResetAltScreenSaveCursorMode = "\x1b[?1049l"
|
||||||
|
RequestAltScreenSaveCursorMode = "\x1b[?1049$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Alternate Screen Buffer mode.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeAltScreenSaveCursor] instead.
|
||||||
|
const (
|
||||||
|
AltScreenBufferMode = DECMode(1049)
|
||||||
|
|
||||||
|
SetAltScreenBufferMode = "\x1b[?1049h"
|
||||||
|
ResetAltScreenBufferMode = "\x1b[?1049l"
|
||||||
|
RequestAltScreenBufferMode = "\x1b[?1049$p"
|
||||||
|
|
||||||
|
EnableAltScreenBuffer = "\x1b[?1049h"
|
||||||
|
DisableAltScreenBuffer = "\x1b[?1049l"
|
||||||
|
RequestAltScreenBuffer = "\x1b[?1049$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Bracketed Paste Mode determines whether pasted text is bracketed with escape sequences.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeBracketedPaste] instead.
|
||||||
|
const (
|
||||||
|
BracketedPasteMode = DECMode(2004)
|
||||||
|
|
||||||
|
SetBracketedPasteMode = "\x1b[?2004h"
|
||||||
|
ResetBracketedPasteMode = "\x1b[?2004l"
|
||||||
|
RequestBracketedPasteMode = "\x1b[?2004$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Deprecated: use [SetModeBracketedPaste], [ResetModeBracketedPaste], and
|
||||||
|
// [RequestModeBracketedPaste] instead.
|
||||||
|
const (
|
||||||
|
EnableBracketedPaste = "\x1b[?2004h" //nolint:revive
|
||||||
|
DisableBracketedPaste = "\x1b[?2004l"
|
||||||
|
RequestBracketedPaste = "\x1b[?2004$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Synchronized Output Mode determines whether output is synchronized with the terminal.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeSynchronizedOutput] instead.
|
||||||
|
const (
|
||||||
|
SynchronizedOutputMode = DECMode(2026)
|
||||||
|
|
||||||
|
SetSynchronizedOutputMode = "\x1b[?2026h"
|
||||||
|
ResetSynchronizedOutputMode = "\x1b[?2026l"
|
||||||
|
RequestSynchronizedOutputMode = "\x1b[?2026$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Synchronized output mode.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeSynchronizedOutput], [SetModeSynchronizedOutput],
|
||||||
|
// [ResetModeSynchronizedOutput], and [RequestModeSynchronizedOutput] instead.
|
||||||
|
const (
|
||||||
|
SyncdOutputMode = DECMode(2026)
|
||||||
|
|
||||||
|
EnableSyncdOutput = "\x1b[?2026h"
|
||||||
|
DisableSyncdOutput = "\x1b[?2026l"
|
||||||
|
RequestSyncdOutput = "\x1b[?2026$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Unicode Core Mode determines whether the terminal uses Unicode grapheme clustering.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeUnicodeCore] instead.
|
||||||
|
const (
|
||||||
|
UnicodeCoreMode = DECMode(2027)
|
||||||
|
|
||||||
|
SetUnicodeCoreMode = "\x1b[?2027h"
|
||||||
|
ResetUnicodeCoreMode = "\x1b[?2027l"
|
||||||
|
RequestUnicodeCoreMode = "\x1b[?2027$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Grapheme Clustering Mode determines whether the terminal looks for grapheme clusters.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeUnicodeCore], [SetModeUnicodeCore],
|
||||||
|
// [ResetModeUnicodeCore], and [RequestModeUnicodeCore] instead.
|
||||||
|
const (
|
||||||
|
GraphemeClusteringMode = DECMode(2027)
|
||||||
|
|
||||||
|
SetGraphemeClusteringMode = "\x1b[?2027h"
|
||||||
|
ResetGraphemeClusteringMode = "\x1b[?2027l"
|
||||||
|
RequestGraphemeClusteringMode = "\x1b[?2027$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Unicode Core mode.
|
||||||
|
//
|
||||||
|
// Deprecated: use [SetModeUnicodeCore], [ResetModeUnicodeCore], and
|
||||||
|
// [RequestModeUnicodeCore] instead.
|
||||||
|
const (
|
||||||
|
EnableGraphemeClustering = "\x1b[?2027h"
|
||||||
|
DisableGraphemeClustering = "\x1b[?2027l"
|
||||||
|
RequestGraphemeClustering = "\x1b[?2027$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Light Dark Mode enables reporting the operating system's color scheme preference.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeLightDark] instead.
|
||||||
|
const (
|
||||||
|
LightDarkMode = DECMode(2031)
|
||||||
|
|
||||||
|
SetLightDarkMode = "\x1b[?2031h"
|
||||||
|
ResetLightDarkMode = "\x1b[?2031l"
|
||||||
|
RequestLightDarkMode = "\x1b[?2031$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// In Band Resize Mode reports terminal resize events as escape sequences.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeInBandResize] instead.
|
||||||
|
const (
|
||||||
|
InBandResizeMode = DECMode(2048)
|
||||||
|
|
||||||
|
SetInBandResizeMode = "\x1b[?2048h"
|
||||||
|
ResetInBandResizeMode = "\x1b[?2048l"
|
||||||
|
RequestInBandResizeMode = "\x1b[?2048$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Win32Input determines whether input is processed by the Win32 console and Conpty.
|
||||||
|
//
|
||||||
|
// Deprecated: use [ModeWin32Input] instead.
|
||||||
|
const (
|
||||||
|
Win32InputMode = DECMode(9001)
|
||||||
|
|
||||||
|
SetWin32InputMode = "\x1b[?9001h"
|
||||||
|
ResetWin32InputMode = "\x1b[?9001l"
|
||||||
|
RequestWin32InputMode = "\x1b[?9001$p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Deprecated: use [SetModeWin32Input], [ResetModeWin32Input], and
|
||||||
|
// [RequestModeWin32Input] instead.
|
||||||
|
const (
|
||||||
|
EnableWin32Input = "\x1b[?9001h" //nolint:revive
|
||||||
|
DisableWin32Input = "\x1b[?9001l"
|
||||||
|
RequestWin32Input = "\x1b[?9001$p"
|
||||||
|
)
|
||||||
2
vendor/github.com/charmbracelet/x/ansi/mouse.go
generated
vendored
2
vendor/github.com/charmbracelet/x/ansi/mouse.go
generated
vendored
@ -134,7 +134,7 @@ func EncodeMouseButton(b MouseButton, motion, shift, alt, ctrl bool) (m byte) {
|
|||||||
m |= bitMotion
|
m |= bitMotion
|
||||||
}
|
}
|
||||||
|
|
||||||
return //nolint:nakedret
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
// x10Offset is the offset for X10 mouse events.
|
// x10Offset is the offset for X10 mouse events.
|
||||||
|
|||||||
19
vendor/github.com/charmbracelet/x/ansi/notification.go
generated
vendored
19
vendor/github.com/charmbracelet/x/ansi/notification.go
generated
vendored
@ -1,5 +1,10 @@
|
|||||||
package ansi
|
package ansi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// Notify sends a desktop notification using iTerm's OSC 9.
|
// Notify sends a desktop notification using iTerm's OSC 9.
|
||||||
//
|
//
|
||||||
// OSC 9 ; Mc ST
|
// OSC 9 ; Mc ST
|
||||||
@ -11,3 +16,17 @@ package ansi
|
|||||||
func Notify(s string) string {
|
func Notify(s string) string {
|
||||||
return "\x1b]9;" + s + "\x07"
|
return "\x1b]9;" + s + "\x07"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DesktopNotification sends a desktop notification based on the extensible OSC
|
||||||
|
// 99 escape code.
|
||||||
|
//
|
||||||
|
// OSC 99 ; <metadata> ; <payload> ST
|
||||||
|
// OSC 99 ; <metadata> ; <payload> BEL
|
||||||
|
//
|
||||||
|
// Where <metadata> is a colon-separated list of key-value pairs, and
|
||||||
|
// <payload> is the notification body.
|
||||||
|
//
|
||||||
|
// See: https://sw.kovidgoyal.net/kitty/desktop-notifications/
|
||||||
|
func DesktopNotification(payload string, metadata ...string) string {
|
||||||
|
return fmt.Sprintf("\x1b]99;%s;%s\x07", strings.Join(metadata, ":"), payload)
|
||||||
|
}
|
||||||
|
|||||||
34
vendor/github.com/charmbracelet/x/ansi/palette.go
generated
vendored
Normal file
34
vendor/github.com/charmbracelet/x/ansi/palette.go
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package ansi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"image/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetPalette sets the palette color for the given index. The index is a 16
|
||||||
|
// color index between 0 and 15. The color is a 24-bit RGB color.
|
||||||
|
//
|
||||||
|
// OSC P n rrggbb BEL
|
||||||
|
//
|
||||||
|
// Where n is the color index in hex (0-f), and rrggbb is the color in
|
||||||
|
// hexadecimal format (e.g., ff0000 for red).
|
||||||
|
//
|
||||||
|
// This sequence is specific to the Linux Console and may not work in other
|
||||||
|
// terminal emulators.
|
||||||
|
//
|
||||||
|
// See https://man7.org/linux/man-pages/man4/console_codes.4.html
|
||||||
|
func SetPalette(i int, c color.Color) string {
|
||||||
|
if c == nil || i < 0 || i > 15 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
r, g, b, _ := c.RGBA()
|
||||||
|
return fmt.Sprintf("\x1b]P%x%02x%02x%02x\x07", i, r>>8, g>>8, b>>8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetPalette resets the color palette to the default values.
|
||||||
|
//
|
||||||
|
// This sequence is specific to the Linux Console and may not work in other
|
||||||
|
// terminal emulators.
|
||||||
|
//
|
||||||
|
// See https://man7.org/linux/man-pages/man4/console_codes.4.html
|
||||||
|
const ResetPalette = "\x1b]R\x07"
|
||||||
33
vendor/github.com/charmbracelet/x/ansi/parser_decode.go
generated
vendored
33
vendor/github.com/charmbracelet/x/ansi/parser_decode.go
generated
vendored
@ -4,8 +4,9 @@ import (
|
|||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/charmbracelet/x/ansi/parser"
|
"github.com/charmbracelet/x/ansi/parser"
|
||||||
|
"github.com/clipperhouse/displaywidth"
|
||||||
|
"github.com/clipperhouse/uax29/v2/graphemes"
|
||||||
"github.com/mattn/go-runewidth"
|
"github.com/mattn/go-runewidth"
|
||||||
"github.com/rivo/uniseg"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// State represents the state of the ANSI escape sequence parser used by
|
// State represents the state of the ANSI escape sequence parser used by
|
||||||
@ -176,10 +177,7 @@ func decodeSequence[T string | []byte](m Method, b T, state State, p *Parser) (s
|
|||||||
}
|
}
|
||||||
|
|
||||||
if utf8.RuneStart(c) {
|
if utf8.RuneStart(c) {
|
||||||
seq, _, width, _ = FirstGraphemeCluster(b, -1)
|
seq, width = FirstGraphemeCluster(b, m)
|
||||||
if m == WcWidth {
|
|
||||||
width = runewidth.StringWidth(string(seq))
|
|
||||||
}
|
|
||||||
i += len(seq)
|
i += len(seq)
|
||||||
return b[:i], width, i, NormalState
|
return b[:i], width, i, NormalState
|
||||||
}
|
}
|
||||||
@ -434,17 +432,22 @@ func HasEscPrefix[T string | []byte](b T) bool {
|
|||||||
return len(b) > 0 && b[0] == ESC
|
return len(b) > 0 && b[0] == ESC
|
||||||
}
|
}
|
||||||
|
|
||||||
// FirstGraphemeCluster returns the first grapheme cluster in the given string or byte slice.
|
// FirstGraphemeCluster returns the first grapheme cluster in the given string
|
||||||
// This is a syntactic sugar function that wraps
|
// or byte slice, and its monospace display width.
|
||||||
// uniseg.FirstGraphemeClusterInString and uniseg.FirstGraphemeCluster.
|
func FirstGraphemeCluster[T string | []byte](b T, m Method) (T, int) {
|
||||||
func FirstGraphemeCluster[T string | []byte](b T, state int) (T, T, int, int) {
|
|
||||||
switch b := any(b).(type) {
|
switch b := any(b).(type) {
|
||||||
case string:
|
case string:
|
||||||
cluster, rest, width, newState := uniseg.FirstGraphemeClusterInString(b, state)
|
cluster := graphemes.FromString(b).First()
|
||||||
return T(cluster), T(rest), width, newState
|
if m == WcWidth {
|
||||||
|
return T(cluster), runewidth.StringWidth(cluster)
|
||||||
|
}
|
||||||
|
return T(cluster), displaywidth.String(cluster)
|
||||||
case []byte:
|
case []byte:
|
||||||
cluster, rest, width, newState := uniseg.FirstGraphemeCluster(b, state)
|
cluster := graphemes.FromBytes(b).First()
|
||||||
return T(cluster), T(rest), width, newState
|
if m == WcWidth {
|
||||||
|
return T(cluster), runewidth.StringWidth(string(cluster))
|
||||||
|
}
|
||||||
|
return T(cluster), displaywidth.Bytes(cluster)
|
||||||
}
|
}
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
@ -490,7 +493,7 @@ func Command(prefix, inter, final byte) (c int) {
|
|||||||
c = int(final)
|
c = int(final)
|
||||||
c |= int(prefix) << parser.PrefixShift
|
c |= int(prefix) << parser.PrefixShift
|
||||||
c |= int(inter) << parser.IntermedShift
|
c |= int(inter) << parser.IntermedShift
|
||||||
return
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Param represents a sequence parameter. Sequence parameters with
|
// Param represents a sequence parameter. Sequence parameters with
|
||||||
@ -520,5 +523,5 @@ func Parameter(p int, hasMore bool) (s int) {
|
|||||||
if hasMore {
|
if hasMore {
|
||||||
s |= parser.HasMoreFlag
|
s |= parser.HasMoreFlag
|
||||||
}
|
}
|
||||||
return
|
return s
|
||||||
}
|
}
|
||||||
|
|||||||
49
vendor/github.com/charmbracelet/x/ansi/progress.go
generated
vendored
Normal file
49
vendor/github.com/charmbracelet/x/ansi/progress.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package ansi
|
||||||
|
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
|
// ResetProgressBar is a sequence that resets the progress bar to its default
|
||||||
|
// state (hidden).
|
||||||
|
//
|
||||||
|
// OSC 9 ; 4 ; 0 BEL
|
||||||
|
//
|
||||||
|
// See: https://learn.microsoft.com/en-us/windows/terminal/tutorials/progress-bar-sequences
|
||||||
|
const ResetProgressBar = "\x1b]9;4;0\x07"
|
||||||
|
|
||||||
|
// SetProgressBar returns a sequence for setting the progress bar to a specific
|
||||||
|
// percentage (0-100) in the "default" state.
|
||||||
|
//
|
||||||
|
// OSC 9 ; 4 ; 1 Percentage BEL
|
||||||
|
//
|
||||||
|
// See: https://learn.microsoft.com/en-us/windows/terminal/tutorials/progress-bar-sequences
|
||||||
|
func SetProgressBar(percentage int) string {
|
||||||
|
return "\x1b]9;4;1;" + strconv.Itoa(min(max(0, percentage), 100)) + "\x07"
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetErrorProgressBar returns a sequence for setting the progress bar to a
|
||||||
|
// specific percentage (0-100) in the "Error" state..
|
||||||
|
//
|
||||||
|
// OSC 9 ; 4 ; 2 Percentage BEL
|
||||||
|
//
|
||||||
|
// See: https://learn.microsoft.com/en-us/windows/terminal/tutorials/progress-bar-sequences
|
||||||
|
func SetErrorProgressBar(percentage int) string {
|
||||||
|
return "\x1b]9;4;2;" + strconv.Itoa(min(max(0, percentage), 100)) + "\x07"
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetIndeterminateProgressBar is a sequence that sets the progress bar to the
|
||||||
|
// indeterminate state.
|
||||||
|
//
|
||||||
|
// OSC 9 ; 4 ; 3 BEL
|
||||||
|
//
|
||||||
|
// See: https://learn.microsoft.com/en-us/windows/terminal/tutorials/progress-bar-sequences
|
||||||
|
const SetIndeterminateProgressBar = "\x1b]9;4;3\x07"
|
||||||
|
|
||||||
|
// SetWarningProgressBar is a sequence that sets the progress bar to the
|
||||||
|
// "Warning" state.
|
||||||
|
//
|
||||||
|
// OSC 9 ; 4 ; 4 Percentage BEL
|
||||||
|
//
|
||||||
|
// See: https://learn.microsoft.com/en-us/windows/terminal/tutorials/progress-bar-sequences
|
||||||
|
func SetWarningProgressBar(percentage int) string {
|
||||||
|
return "\x1b]9;4;4;" + strconv.Itoa(min(max(0, percentage), 100)) + "\x07"
|
||||||
|
}
|
||||||
110
vendor/github.com/charmbracelet/x/ansi/sgr.go
generated
vendored
110
vendor/github.com/charmbracelet/x/ansi/sgr.go
generated
vendored
@ -21,59 +21,59 @@ func SGR(ps ...Attr) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var attrStrings = map[int]string{
|
var attrStrings = map[int]string{
|
||||||
ResetAttr: resetAttr,
|
AttrReset: attrReset,
|
||||||
BoldAttr: boldAttr,
|
AttrBold: attrBold,
|
||||||
FaintAttr: faintAttr,
|
AttrFaint: attrFaint,
|
||||||
ItalicAttr: italicAttr,
|
AttrItalic: attrItalic,
|
||||||
UnderlineAttr: underlineAttr,
|
AttrUnderline: attrUnderline,
|
||||||
SlowBlinkAttr: slowBlinkAttr,
|
AttrBlink: attrBlink,
|
||||||
RapidBlinkAttr: rapidBlinkAttr,
|
AttrRapidBlink: attrRapidBlink,
|
||||||
ReverseAttr: reverseAttr,
|
AttrReverse: attrReverse,
|
||||||
ConcealAttr: concealAttr,
|
AttrConceal: attrConceal,
|
||||||
StrikethroughAttr: strikethroughAttr,
|
AttrStrikethrough: attrStrikethrough,
|
||||||
NormalIntensityAttr: normalIntensityAttr,
|
AttrNormalIntensity: attrNormalIntensity,
|
||||||
NoItalicAttr: noItalicAttr,
|
AttrNoItalic: attrNoItalic,
|
||||||
NoUnderlineAttr: noUnderlineAttr,
|
AttrNoUnderline: attrNoUnderline,
|
||||||
NoBlinkAttr: noBlinkAttr,
|
AttrNoBlink: attrNoBlink,
|
||||||
NoReverseAttr: noReverseAttr,
|
AttrNoReverse: attrNoReverse,
|
||||||
NoConcealAttr: noConcealAttr,
|
AttrNoConceal: attrNoConceal,
|
||||||
NoStrikethroughAttr: noStrikethroughAttr,
|
AttrNoStrikethrough: attrNoStrikethrough,
|
||||||
BlackForegroundColorAttr: blackForegroundColorAttr,
|
AttrBlackForegroundColor: attrBlackForegroundColor,
|
||||||
RedForegroundColorAttr: redForegroundColorAttr,
|
AttrRedForegroundColor: attrRedForegroundColor,
|
||||||
GreenForegroundColorAttr: greenForegroundColorAttr,
|
AttrGreenForegroundColor: attrGreenForegroundColor,
|
||||||
YellowForegroundColorAttr: yellowForegroundColorAttr,
|
AttrYellowForegroundColor: attrYellowForegroundColor,
|
||||||
BlueForegroundColorAttr: blueForegroundColorAttr,
|
AttrBlueForegroundColor: attrBlueForegroundColor,
|
||||||
MagentaForegroundColorAttr: magentaForegroundColorAttr,
|
AttrMagentaForegroundColor: attrMagentaForegroundColor,
|
||||||
CyanForegroundColorAttr: cyanForegroundColorAttr,
|
AttrCyanForegroundColor: attrCyanForegroundColor,
|
||||||
WhiteForegroundColorAttr: whiteForegroundColorAttr,
|
AttrWhiteForegroundColor: attrWhiteForegroundColor,
|
||||||
ExtendedForegroundColorAttr: extendedForegroundColorAttr,
|
AttrExtendedForegroundColor: attrExtendedForegroundColor,
|
||||||
DefaultForegroundColorAttr: defaultForegroundColorAttr,
|
AttrDefaultForegroundColor: attrDefaultForegroundColor,
|
||||||
BlackBackgroundColorAttr: blackBackgroundColorAttr,
|
AttrBlackBackgroundColor: attrBlackBackgroundColor,
|
||||||
RedBackgroundColorAttr: redBackgroundColorAttr,
|
AttrRedBackgroundColor: attrRedBackgroundColor,
|
||||||
GreenBackgroundColorAttr: greenBackgroundColorAttr,
|
AttrGreenBackgroundColor: attrGreenBackgroundColor,
|
||||||
YellowBackgroundColorAttr: yellowBackgroundColorAttr,
|
AttrYellowBackgroundColor: attrYellowBackgroundColor,
|
||||||
BlueBackgroundColorAttr: blueBackgroundColorAttr,
|
AttrBlueBackgroundColor: attrBlueBackgroundColor,
|
||||||
MagentaBackgroundColorAttr: magentaBackgroundColorAttr,
|
AttrMagentaBackgroundColor: attrMagentaBackgroundColor,
|
||||||
CyanBackgroundColorAttr: cyanBackgroundColorAttr,
|
AttrCyanBackgroundColor: attrCyanBackgroundColor,
|
||||||
WhiteBackgroundColorAttr: whiteBackgroundColorAttr,
|
AttrWhiteBackgroundColor: attrWhiteBackgroundColor,
|
||||||
ExtendedBackgroundColorAttr: extendedBackgroundColorAttr,
|
AttrExtendedBackgroundColor: attrExtendedBackgroundColor,
|
||||||
DefaultBackgroundColorAttr: defaultBackgroundColorAttr,
|
AttrDefaultBackgroundColor: attrDefaultBackgroundColor,
|
||||||
ExtendedUnderlineColorAttr: extendedUnderlineColorAttr,
|
AttrExtendedUnderlineColor: attrExtendedUnderlineColor,
|
||||||
DefaultUnderlineColorAttr: defaultUnderlineColorAttr,
|
AttrDefaultUnderlineColor: attrDefaultUnderlineColor,
|
||||||
BrightBlackForegroundColorAttr: brightBlackForegroundColorAttr,
|
AttrBrightBlackForegroundColor: attrBrightBlackForegroundColor,
|
||||||
BrightRedForegroundColorAttr: brightRedForegroundColorAttr,
|
AttrBrightRedForegroundColor: attrBrightRedForegroundColor,
|
||||||
BrightGreenForegroundColorAttr: brightGreenForegroundColorAttr,
|
AttrBrightGreenForegroundColor: attrBrightGreenForegroundColor,
|
||||||
BrightYellowForegroundColorAttr: brightYellowForegroundColorAttr,
|
AttrBrightYellowForegroundColor: attrBrightYellowForegroundColor,
|
||||||
BrightBlueForegroundColorAttr: brightBlueForegroundColorAttr,
|
AttrBrightBlueForegroundColor: attrBrightBlueForegroundColor,
|
||||||
BrightMagentaForegroundColorAttr: brightMagentaForegroundColorAttr,
|
AttrBrightMagentaForegroundColor: attrBrightMagentaForegroundColor,
|
||||||
BrightCyanForegroundColorAttr: brightCyanForegroundColorAttr,
|
AttrBrightCyanForegroundColor: attrBrightCyanForegroundColor,
|
||||||
BrightWhiteForegroundColorAttr: brightWhiteForegroundColorAttr,
|
AttrBrightWhiteForegroundColor: attrBrightWhiteForegroundColor,
|
||||||
BrightBlackBackgroundColorAttr: brightBlackBackgroundColorAttr,
|
AttrBrightBlackBackgroundColor: attrBrightBlackBackgroundColor,
|
||||||
BrightRedBackgroundColorAttr: brightRedBackgroundColorAttr,
|
AttrBrightRedBackgroundColor: attrBrightRedBackgroundColor,
|
||||||
BrightGreenBackgroundColorAttr: brightGreenBackgroundColorAttr,
|
AttrBrightGreenBackgroundColor: attrBrightGreenBackgroundColor,
|
||||||
BrightYellowBackgroundColorAttr: brightYellowBackgroundColorAttr,
|
AttrBrightYellowBackgroundColor: attrBrightYellowBackgroundColor,
|
||||||
BrightBlueBackgroundColorAttr: brightBlueBackgroundColorAttr,
|
AttrBrightBlueBackgroundColor: attrBrightBlueBackgroundColor,
|
||||||
BrightMagentaBackgroundColorAttr: brightMagentaBackgroundColorAttr,
|
AttrBrightMagentaBackgroundColor: attrBrightMagentaBackgroundColor,
|
||||||
BrightCyanBackgroundColorAttr: brightCyanBackgroundColorAttr,
|
AttrBrightCyanBackgroundColor: attrBrightCyanBackgroundColor,
|
||||||
BrightWhiteBackgroundColorAttr: brightWhiteBackgroundColorAttr,
|
AttrBrightWhiteBackgroundColor: attrBrightWhiteBackgroundColor,
|
||||||
}
|
}
|
||||||
|
|||||||
603
vendor/github.com/charmbracelet/x/ansi/style.go
generated
vendored
603
vendor/github.com/charmbracelet/x/ansi/style.go
generated
vendored
@ -17,7 +17,9 @@ type Attr = int
|
|||||||
// Style represents an ANSI SGR (Select Graphic Rendition) style.
|
// Style represents an ANSI SGR (Select Graphic Rendition) style.
|
||||||
type Style []string
|
type Style []string
|
||||||
|
|
||||||
// NewStyle returns a new style with the given attributes.
|
// NewStyle returns a new style with the given attributes. Attributes are SGR
|
||||||
|
// (Select Graphic Rendition) codes that control text formatting like bold,
|
||||||
|
// italic, colors, etc.
|
||||||
func NewStyle(attrs ...Attr) Style {
|
func NewStyle(attrs ...Attr) Style {
|
||||||
if len(attrs) == 0 {
|
if len(attrs) == 0 {
|
||||||
return Style{}
|
return Style{}
|
||||||
@ -46,7 +48,8 @@ func (s Style) String() string {
|
|||||||
return "\x1b[" + strings.Join(s, ";") + "m"
|
return "\x1b[" + strings.Join(s, ";") + "m"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Styled returns a styled string with the given style applied.
|
// Styled returns a styled string with the given style applied. The style is
|
||||||
|
// applied at the beginning and reset at the end of the string.
|
||||||
func (s Style) Styled(str string) string {
|
func (s Style) Styled(str string) string {
|
||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
return str
|
return str
|
||||||
@ -54,161 +57,211 @@ func (s Style) Styled(str string) string {
|
|||||||
return s.String() + str + ResetStyle
|
return s.String() + str + ResetStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset appends the reset style attribute to the style.
|
// Reset appends the reset style attribute to the style. This resets all
|
||||||
|
// formatting attributes to their defaults.
|
||||||
func (s Style) Reset() Style {
|
func (s Style) Reset() Style {
|
||||||
return append(s, resetAttr)
|
return append(s, attrReset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bold appends the bold style attribute to the style.
|
// Bold appends the bold or normal intensity style attribute to the style.
|
||||||
|
// You can use [Style.Normal] to reset to normal intensity.
|
||||||
func (s Style) Bold() Style {
|
func (s Style) Bold() Style {
|
||||||
return append(s, boldAttr)
|
return append(s, attrBold)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Faint appends the faint style attribute to the style.
|
// Faint appends the faint or normal intensity style attribute to the style.
|
||||||
|
// You can use [Style.Normal] to reset to normal intensity.
|
||||||
func (s Style) Faint() Style {
|
func (s Style) Faint() Style {
|
||||||
return append(s, faintAttr)
|
return append(s, attrFaint)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Italic appends the italic style attribute to the style.
|
// Italic appends the italic or no italic style attribute to the style.
|
||||||
func (s Style) Italic() Style {
|
// When v is true, text is rendered in italic. When false, italic is disabled.
|
||||||
return append(s, italicAttr)
|
func (s Style) Italic(v bool) Style {
|
||||||
|
if v {
|
||||||
|
return append(s, attrItalic)
|
||||||
|
}
|
||||||
|
return append(s, attrNoItalic)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Underline appends the underline style attribute to the style.
|
// Underline appends the underline or no underline style attribute to the style.
|
||||||
func (s Style) Underline() Style {
|
// When v is true, text is underlined. When false, underline is disabled.
|
||||||
return append(s, underlineAttr)
|
func (s Style) Underline(v bool) Style {
|
||||||
|
if v {
|
||||||
|
return append(s, attrUnderline)
|
||||||
|
}
|
||||||
|
return append(s, attrNoUnderline)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnderlineStyle appends the underline style attribute to the style.
|
// UnderlineStyle appends the underline style attribute to the style.
|
||||||
|
// Supports various underline styles including single, double, curly, dotted,
|
||||||
|
// and dashed.
|
||||||
func (s Style) UnderlineStyle(u UnderlineStyle) Style {
|
func (s Style) UnderlineStyle(u UnderlineStyle) Style {
|
||||||
switch u {
|
switch u {
|
||||||
case NoUnderlineStyle:
|
case UnderlineStyleNone:
|
||||||
return s.NoUnderline()
|
return s.Underline(false)
|
||||||
case SingleUnderlineStyle:
|
case UnderlineStyleSingle:
|
||||||
return s.Underline()
|
return s.Underline(true)
|
||||||
case DoubleUnderlineStyle:
|
case UnderlineStyleDouble:
|
||||||
return append(s, doubleUnderlineStyle)
|
return append(s, underlineStyleDouble)
|
||||||
case CurlyUnderlineStyle:
|
case UnderlineStyleCurly:
|
||||||
return append(s, curlyUnderlineStyle)
|
return append(s, underlineStyleCurly)
|
||||||
case DottedUnderlineStyle:
|
case UnderlineStyleDotted:
|
||||||
return append(s, dottedUnderlineStyle)
|
return append(s, underlineStyleDotted)
|
||||||
case DashedUnderlineStyle:
|
case UnderlineStyleDashed:
|
||||||
return append(s, dashedUnderlineStyle)
|
return append(s, underlineStyleDashed)
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoubleUnderline appends the double underline style attribute to the style.
|
// Blink appends the slow blink or no blink style attribute to the style.
|
||||||
// This is a convenience method for UnderlineStyle(DoubleUnderlineStyle).
|
// When v is true, text blinks slowly (less than 150 per minute). When false,
|
||||||
func (s Style) DoubleUnderline() Style {
|
// blinking is disabled.
|
||||||
return s.UnderlineStyle(DoubleUnderlineStyle)
|
func (s Style) Blink(v bool) Style {
|
||||||
|
if v {
|
||||||
|
return append(s, attrBlink)
|
||||||
|
}
|
||||||
|
return append(s, attrNoBlink)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurlyUnderline appends the curly underline style attribute to the style.
|
// RapidBlink appends the rapid blink or no blink style attribute to the style.
|
||||||
// This is a convenience method for UnderlineStyle(CurlyUnderlineStyle).
|
// When v is true, text blinks rapidly (150+ per minute). When false, blinking
|
||||||
func (s Style) CurlyUnderline() Style {
|
// is disabled.
|
||||||
return s.UnderlineStyle(CurlyUnderlineStyle)
|
//
|
||||||
|
// Note that this is not widely supported in terminal emulators.
|
||||||
|
func (s Style) RapidBlink(v bool) Style {
|
||||||
|
if v {
|
||||||
|
return append(s, attrRapidBlink)
|
||||||
|
}
|
||||||
|
return append(s, attrNoBlink)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DottedUnderline appends the dotted underline style attribute to the style.
|
// Reverse appends the reverse or no reverse style attribute to the style.
|
||||||
// This is a convenience method for UnderlineStyle(DottedUnderlineStyle).
|
// When v is true, foreground and background colors are swapped. When false,
|
||||||
func (s Style) DottedUnderline() Style {
|
// reverse video is disabled.
|
||||||
return s.UnderlineStyle(DottedUnderlineStyle)
|
func (s Style) Reverse(v bool) Style {
|
||||||
|
if v {
|
||||||
|
return append(s, attrReverse)
|
||||||
|
}
|
||||||
|
return append(s, attrNoReverse)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DashedUnderline appends the dashed underline style attribute to the style.
|
// Conceal appends the conceal or no conceal style attribute to the style.
|
||||||
// This is a convenience method for UnderlineStyle(DashedUnderlineStyle).
|
// When v is true, text is hidden/concealed. When false, concealment is
|
||||||
func (s Style) DashedUnderline() Style {
|
// disabled.
|
||||||
return s.UnderlineStyle(DashedUnderlineStyle)
|
func (s Style) Conceal(v bool) Style {
|
||||||
|
if v {
|
||||||
|
return append(s, attrConceal)
|
||||||
|
}
|
||||||
|
return append(s, attrNoConceal)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SlowBlink appends the slow blink style attribute to the style.
|
// Strikethrough appends the strikethrough or no strikethrough style attribute
|
||||||
func (s Style) SlowBlink() Style {
|
// to the style. When v is true, text is rendered with a horizontal line through
|
||||||
return append(s, slowBlinkAttr)
|
// it. When false, strikethrough is disabled.
|
||||||
|
func (s Style) Strikethrough(v bool) Style {
|
||||||
|
if v {
|
||||||
|
return append(s, attrStrikethrough)
|
||||||
|
}
|
||||||
|
return append(s, attrNoStrikethrough)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RapidBlink appends the rapid blink style attribute to the style.
|
// Normal appends the normal intensity style attribute to the style. This
|
||||||
func (s Style) RapidBlink() Style {
|
// resets [Style.Bold] and [Style.Faint] attributes.
|
||||||
return append(s, rapidBlinkAttr)
|
func (s Style) Normal() Style {
|
||||||
}
|
return append(s, attrNormalIntensity)
|
||||||
|
|
||||||
// Reverse appends the reverse style attribute to the style.
|
|
||||||
func (s Style) Reverse() Style {
|
|
||||||
return append(s, reverseAttr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Conceal appends the conceal style attribute to the style.
|
|
||||||
func (s Style) Conceal() Style {
|
|
||||||
return append(s, concealAttr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strikethrough appends the strikethrough style attribute to the style.
|
|
||||||
func (s Style) Strikethrough() Style {
|
|
||||||
return append(s, strikethroughAttr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NormalIntensity appends the normal intensity style attribute to the style.
|
|
||||||
func (s Style) NormalIntensity() Style {
|
|
||||||
return append(s, normalIntensityAttr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoItalic appends the no italic style attribute to the style.
|
// NoItalic appends the no italic style attribute to the style.
|
||||||
|
//
|
||||||
|
// Deprecated: use [Style.Italic](false) instead.
|
||||||
func (s Style) NoItalic() Style {
|
func (s Style) NoItalic() Style {
|
||||||
return append(s, noItalicAttr)
|
return append(s, attrNoItalic)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoUnderline appends the no underline style attribute to the style.
|
// NoUnderline appends the no underline style attribute to the style.
|
||||||
|
//
|
||||||
|
// Deprecated: use [Style.Underline](false) instead.
|
||||||
func (s Style) NoUnderline() Style {
|
func (s Style) NoUnderline() Style {
|
||||||
return append(s, noUnderlineAttr)
|
return append(s, attrNoUnderline)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoBlink appends the no blink style attribute to the style.
|
// NoBlink appends the no blink style attribute to the style.
|
||||||
|
//
|
||||||
|
// Deprecated: use [Style.Blink](false) or [Style.RapidBlink](false) instead.
|
||||||
func (s Style) NoBlink() Style {
|
func (s Style) NoBlink() Style {
|
||||||
return append(s, noBlinkAttr)
|
return append(s, attrNoBlink)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoReverse appends the no reverse style attribute to the style.
|
// NoReverse appends the no reverse style attribute to the style.
|
||||||
|
//
|
||||||
|
// Deprecated: use [Style.Reverse](false) instead.
|
||||||
func (s Style) NoReverse() Style {
|
func (s Style) NoReverse() Style {
|
||||||
return append(s, noReverseAttr)
|
return append(s, attrNoReverse)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoConceal appends the no conceal style attribute to the style.
|
// NoConceal appends the no conceal style attribute to the style.
|
||||||
|
//
|
||||||
|
// Deprecated: use [Style.Conceal](false) instead.
|
||||||
func (s Style) NoConceal() Style {
|
func (s Style) NoConceal() Style {
|
||||||
return append(s, noConcealAttr)
|
return append(s, attrNoConceal)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoStrikethrough appends the no strikethrough style attribute to the style.
|
// NoStrikethrough appends the no strikethrough style attribute to the style.
|
||||||
|
//
|
||||||
|
// Deprecated: use [Style.Strikethrough](false) instead.
|
||||||
func (s Style) NoStrikethrough() Style {
|
func (s Style) NoStrikethrough() Style {
|
||||||
return append(s, noStrikethroughAttr)
|
return append(s, attrNoStrikethrough)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultForegroundColor appends the default foreground color style attribute to the style.
|
// DefaultForegroundColor appends the default foreground color style attribute to the style.
|
||||||
|
//
|
||||||
|
// Deprecated: use [Style.ForegroundColor](nil) instead.
|
||||||
func (s Style) DefaultForegroundColor() Style {
|
func (s Style) DefaultForegroundColor() Style {
|
||||||
return append(s, defaultForegroundColorAttr)
|
return append(s, attrDefaultForegroundColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultBackgroundColor appends the default background color style attribute to the style.
|
// DefaultBackgroundColor appends the default background color style attribute to the style.
|
||||||
|
//
|
||||||
|
// Deprecated: use [Style.BackgroundColor](nil) instead.
|
||||||
func (s Style) DefaultBackgroundColor() Style {
|
func (s Style) DefaultBackgroundColor() Style {
|
||||||
return append(s, defaultBackgroundColorAttr)
|
return append(s, attrDefaultBackgroundColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultUnderlineColor appends the default underline color style attribute to the style.
|
// DefaultUnderlineColor appends the default underline color style attribute to the style.
|
||||||
|
//
|
||||||
|
// Deprecated: use [Style.UnderlineColor](nil) instead.
|
||||||
func (s Style) DefaultUnderlineColor() Style {
|
func (s Style) DefaultUnderlineColor() Style {
|
||||||
return append(s, defaultUnderlineColorAttr)
|
return append(s, attrDefaultUnderlineColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForegroundColor appends the foreground color style attribute to the style.
|
// ForegroundColor appends the foreground color style attribute to the style.
|
||||||
|
// If c is nil, the default foreground color is used. Supports [BasicColor],
|
||||||
|
// [IndexedColor] (256-color), and [color.Color] (24-bit RGB).
|
||||||
func (s Style) ForegroundColor(c Color) Style {
|
func (s Style) ForegroundColor(c Color) Style {
|
||||||
|
if c == nil {
|
||||||
|
return append(s, attrDefaultForegroundColor)
|
||||||
|
}
|
||||||
return append(s, foregroundColorString(c))
|
return append(s, foregroundColorString(c))
|
||||||
}
|
}
|
||||||
|
|
||||||
// BackgroundColor appends the background color style attribute to the style.
|
// BackgroundColor appends the background color style attribute to the style.
|
||||||
|
// If c is nil, the default background color is used. Supports [BasicColor],
|
||||||
|
// [IndexedColor] (256-color), and [color.Color] (24-bit RGB).
|
||||||
func (s Style) BackgroundColor(c Color) Style {
|
func (s Style) BackgroundColor(c Color) Style {
|
||||||
|
if c == nil {
|
||||||
|
return append(s, attrDefaultBackgroundColor)
|
||||||
|
}
|
||||||
return append(s, backgroundColorString(c))
|
return append(s, backgroundColorString(c))
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnderlineColor appends the underline color style attribute to the style.
|
// UnderlineColor appends the underline color style attribute to the style.
|
||||||
|
// If c is nil, the default underline color is used. Supports [BasicColor],
|
||||||
|
// [IndexedColor] (256-color), and [color.Color] (24-bit RGB).
|
||||||
func (s Style) UnderlineColor(c Color) Style {
|
func (s Style) UnderlineColor(c Color) Style {
|
||||||
|
if c == nil {
|
||||||
|
return append(s, attrDefaultUnderlineColor)
|
||||||
|
}
|
||||||
return append(s, underlineColorString(c))
|
return append(s, underlineColorString(c))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,146 +270,216 @@ func (s Style) UnderlineColor(c Color) Style {
|
|||||||
type UnderlineStyle = byte
|
type UnderlineStyle = byte
|
||||||
|
|
||||||
const (
|
const (
|
||||||
doubleUnderlineStyle = "4:2"
|
underlineStyleDouble = "4:2"
|
||||||
curlyUnderlineStyle = "4:3"
|
underlineStyleCurly = "4:3"
|
||||||
dottedUnderlineStyle = "4:4"
|
underlineStyleDotted = "4:4"
|
||||||
dashedUnderlineStyle = "4:5"
|
underlineStyleDashed = "4:5"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Underline styles constants.
|
||||||
|
const (
|
||||||
|
UnderlineStyleNone UnderlineStyle = iota
|
||||||
|
UnderlineStyleSingle
|
||||||
|
UnderlineStyleDouble
|
||||||
|
UnderlineStyleCurly
|
||||||
|
UnderlineStyleDotted
|
||||||
|
UnderlineStyleDashed
|
||||||
|
)
|
||||||
|
|
||||||
|
// Underline styles constants.
|
||||||
|
//
|
||||||
|
// Deprecated: use [UnderlineStyleNone], [UnderlineStyleSingle], etc. instead.
|
||||||
const (
|
const (
|
||||||
// NoUnderlineStyle is the default underline style.
|
|
||||||
NoUnderlineStyle UnderlineStyle = iota
|
NoUnderlineStyle UnderlineStyle = iota
|
||||||
// SingleUnderlineStyle is a single underline style.
|
|
||||||
SingleUnderlineStyle
|
SingleUnderlineStyle
|
||||||
// DoubleUnderlineStyle is a double underline style.
|
|
||||||
DoubleUnderlineStyle
|
DoubleUnderlineStyle
|
||||||
// CurlyUnderlineStyle is a curly underline style.
|
|
||||||
CurlyUnderlineStyle
|
CurlyUnderlineStyle
|
||||||
// DottedUnderlineStyle is a dotted underline style.
|
|
||||||
DottedUnderlineStyle
|
DottedUnderlineStyle
|
||||||
// DashedUnderlineStyle is a dashed underline style.
|
|
||||||
DashedUnderlineStyle
|
DashedUnderlineStyle
|
||||||
)
|
)
|
||||||
|
|
||||||
// SGR (Select Graphic Rendition) style attributes.
|
// SGR (Select Graphic Rendition) style attributes.
|
||||||
// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
|
// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
|
||||||
const (
|
const (
|
||||||
ResetAttr Attr = 0
|
AttrReset Attr = 0
|
||||||
BoldAttr Attr = 1
|
AttrBold Attr = 1
|
||||||
FaintAttr Attr = 2
|
AttrFaint Attr = 2
|
||||||
ItalicAttr Attr = 3
|
AttrItalic Attr = 3
|
||||||
UnderlineAttr Attr = 4
|
AttrUnderline Attr = 4
|
||||||
SlowBlinkAttr Attr = 5
|
AttrBlink Attr = 5
|
||||||
RapidBlinkAttr Attr = 6
|
AttrRapidBlink Attr = 6
|
||||||
ReverseAttr Attr = 7
|
AttrReverse Attr = 7
|
||||||
ConcealAttr Attr = 8
|
AttrConceal Attr = 8
|
||||||
StrikethroughAttr Attr = 9
|
AttrStrikethrough Attr = 9
|
||||||
NormalIntensityAttr Attr = 22
|
AttrNormalIntensity Attr = 22
|
||||||
NoItalicAttr Attr = 23
|
AttrNoItalic Attr = 23
|
||||||
NoUnderlineAttr Attr = 24
|
AttrNoUnderline Attr = 24
|
||||||
NoBlinkAttr Attr = 25
|
AttrNoBlink Attr = 25
|
||||||
NoReverseAttr Attr = 27
|
AttrNoReverse Attr = 27
|
||||||
NoConcealAttr Attr = 28
|
AttrNoConceal Attr = 28
|
||||||
NoStrikethroughAttr Attr = 29
|
AttrNoStrikethrough Attr = 29
|
||||||
BlackForegroundColorAttr Attr = 30
|
AttrBlackForegroundColor Attr = 30
|
||||||
RedForegroundColorAttr Attr = 31
|
AttrRedForegroundColor Attr = 31
|
||||||
GreenForegroundColorAttr Attr = 32
|
AttrGreenForegroundColor Attr = 32
|
||||||
YellowForegroundColorAttr Attr = 33
|
AttrYellowForegroundColor Attr = 33
|
||||||
BlueForegroundColorAttr Attr = 34
|
AttrBlueForegroundColor Attr = 34
|
||||||
MagentaForegroundColorAttr Attr = 35
|
AttrMagentaForegroundColor Attr = 35
|
||||||
CyanForegroundColorAttr Attr = 36
|
AttrCyanForegroundColor Attr = 36
|
||||||
WhiteForegroundColorAttr Attr = 37
|
AttrWhiteForegroundColor Attr = 37
|
||||||
ExtendedForegroundColorAttr Attr = 38
|
AttrExtendedForegroundColor Attr = 38
|
||||||
DefaultForegroundColorAttr Attr = 39
|
AttrDefaultForegroundColor Attr = 39
|
||||||
BlackBackgroundColorAttr Attr = 40
|
AttrBlackBackgroundColor Attr = 40
|
||||||
RedBackgroundColorAttr Attr = 41
|
AttrRedBackgroundColor Attr = 41
|
||||||
GreenBackgroundColorAttr Attr = 42
|
AttrGreenBackgroundColor Attr = 42
|
||||||
YellowBackgroundColorAttr Attr = 43
|
AttrYellowBackgroundColor Attr = 43
|
||||||
BlueBackgroundColorAttr Attr = 44
|
AttrBlueBackgroundColor Attr = 44
|
||||||
MagentaBackgroundColorAttr Attr = 45
|
AttrMagentaBackgroundColor Attr = 45
|
||||||
CyanBackgroundColorAttr Attr = 46
|
AttrCyanBackgroundColor Attr = 46
|
||||||
WhiteBackgroundColorAttr Attr = 47
|
AttrWhiteBackgroundColor Attr = 47
|
||||||
ExtendedBackgroundColorAttr Attr = 48
|
AttrExtendedBackgroundColor Attr = 48
|
||||||
DefaultBackgroundColorAttr Attr = 49
|
AttrDefaultBackgroundColor Attr = 49
|
||||||
ExtendedUnderlineColorAttr Attr = 58
|
AttrExtendedUnderlineColor Attr = 58
|
||||||
DefaultUnderlineColorAttr Attr = 59
|
AttrDefaultUnderlineColor Attr = 59
|
||||||
BrightBlackForegroundColorAttr Attr = 90
|
AttrBrightBlackForegroundColor Attr = 90
|
||||||
BrightRedForegroundColorAttr Attr = 91
|
AttrBrightRedForegroundColor Attr = 91
|
||||||
BrightGreenForegroundColorAttr Attr = 92
|
AttrBrightGreenForegroundColor Attr = 92
|
||||||
BrightYellowForegroundColorAttr Attr = 93
|
AttrBrightYellowForegroundColor Attr = 93
|
||||||
BrightBlueForegroundColorAttr Attr = 94
|
AttrBrightBlueForegroundColor Attr = 94
|
||||||
BrightMagentaForegroundColorAttr Attr = 95
|
AttrBrightMagentaForegroundColor Attr = 95
|
||||||
BrightCyanForegroundColorAttr Attr = 96
|
AttrBrightCyanForegroundColor Attr = 96
|
||||||
BrightWhiteForegroundColorAttr Attr = 97
|
AttrBrightWhiteForegroundColor Attr = 97
|
||||||
BrightBlackBackgroundColorAttr Attr = 100
|
AttrBrightBlackBackgroundColor Attr = 100
|
||||||
BrightRedBackgroundColorAttr Attr = 101
|
AttrBrightRedBackgroundColor Attr = 101
|
||||||
BrightGreenBackgroundColorAttr Attr = 102
|
AttrBrightGreenBackgroundColor Attr = 102
|
||||||
BrightYellowBackgroundColorAttr Attr = 103
|
AttrBrightYellowBackgroundColor Attr = 103
|
||||||
BrightBlueBackgroundColorAttr Attr = 104
|
AttrBrightBlueBackgroundColor Attr = 104
|
||||||
BrightMagentaBackgroundColorAttr Attr = 105
|
AttrBrightMagentaBackgroundColor Attr = 105
|
||||||
BrightCyanBackgroundColorAttr Attr = 106
|
AttrBrightCyanBackgroundColor Attr = 106
|
||||||
BrightWhiteBackgroundColorAttr Attr = 107
|
AttrBrightWhiteBackgroundColor Attr = 107
|
||||||
|
|
||||||
RGBColorIntroducerAttr Attr = 2
|
AttrRGBColorIntroducer Attr = 2
|
||||||
ExtendedColorIntroducerAttr Attr = 5
|
AttrExtendedColorIntroducer Attr = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
// SGR (Select Graphic Rendition) style attributes.
|
||||||
|
//
|
||||||
|
// Deprecated: use Attr* constants instead.
|
||||||
|
const (
|
||||||
|
ResetAttr = AttrReset
|
||||||
|
BoldAttr = AttrBold
|
||||||
|
FaintAttr = AttrFaint
|
||||||
|
ItalicAttr = AttrItalic
|
||||||
|
UnderlineAttr = AttrUnderline
|
||||||
|
SlowBlinkAttr = AttrBlink
|
||||||
|
RapidBlinkAttr = AttrRapidBlink
|
||||||
|
ReverseAttr = AttrReverse
|
||||||
|
ConcealAttr = AttrConceal
|
||||||
|
StrikethroughAttr = AttrStrikethrough
|
||||||
|
NormalIntensityAttr = AttrNormalIntensity
|
||||||
|
NoItalicAttr = AttrNoItalic
|
||||||
|
NoUnderlineAttr = AttrNoUnderline
|
||||||
|
NoBlinkAttr = AttrNoBlink
|
||||||
|
NoReverseAttr = AttrNoReverse
|
||||||
|
NoConcealAttr = AttrNoConceal
|
||||||
|
NoStrikethroughAttr = AttrNoStrikethrough
|
||||||
|
BlackForegroundColorAttr = AttrBlackForegroundColor
|
||||||
|
RedForegroundColorAttr = AttrRedForegroundColor
|
||||||
|
GreenForegroundColorAttr = AttrGreenForegroundColor
|
||||||
|
YellowForegroundColorAttr = AttrYellowForegroundColor
|
||||||
|
BlueForegroundColorAttr = AttrBlueForegroundColor
|
||||||
|
MagentaForegroundColorAttr = AttrMagentaForegroundColor
|
||||||
|
CyanForegroundColorAttr = AttrCyanForegroundColor
|
||||||
|
WhiteForegroundColorAttr = AttrWhiteForegroundColor
|
||||||
|
ExtendedForegroundColorAttr = AttrExtendedForegroundColor
|
||||||
|
DefaultForegroundColorAttr = AttrDefaultForegroundColor
|
||||||
|
BlackBackgroundColorAttr = AttrBlackBackgroundColor
|
||||||
|
RedBackgroundColorAttr = AttrRedBackgroundColor
|
||||||
|
GreenBackgroundColorAttr = AttrGreenBackgroundColor
|
||||||
|
YellowBackgroundColorAttr = AttrYellowBackgroundColor
|
||||||
|
BlueBackgroundColorAttr = AttrBlueBackgroundColor
|
||||||
|
MagentaBackgroundColorAttr = AttrMagentaBackgroundColor
|
||||||
|
CyanBackgroundColorAttr = AttrCyanBackgroundColor
|
||||||
|
WhiteBackgroundColorAttr = AttrWhiteBackgroundColor
|
||||||
|
ExtendedBackgroundColorAttr = AttrExtendedBackgroundColor
|
||||||
|
DefaultBackgroundColorAttr = AttrDefaultBackgroundColor
|
||||||
|
ExtendedUnderlineColorAttr = AttrExtendedUnderlineColor
|
||||||
|
DefaultUnderlineColorAttr = AttrDefaultUnderlineColor
|
||||||
|
BrightBlackForegroundColorAttr = AttrBrightBlackForegroundColor
|
||||||
|
BrightRedForegroundColorAttr = AttrBrightRedForegroundColor
|
||||||
|
BrightGreenForegroundColorAttr = AttrBrightGreenForegroundColor
|
||||||
|
BrightYellowForegroundColorAttr = AttrBrightYellowForegroundColor
|
||||||
|
BrightBlueForegroundColorAttr = AttrBrightBlueForegroundColor
|
||||||
|
BrightMagentaForegroundColorAttr = AttrBrightMagentaForegroundColor
|
||||||
|
BrightCyanForegroundColorAttr = AttrBrightCyanForegroundColor
|
||||||
|
BrightWhiteForegroundColorAttr = AttrBrightWhiteForegroundColor
|
||||||
|
BrightBlackBackgroundColorAttr = AttrBrightBlackBackgroundColor
|
||||||
|
BrightRedBackgroundColorAttr = AttrBrightRedBackgroundColor
|
||||||
|
BrightGreenBackgroundColorAttr = AttrBrightGreenBackgroundColor
|
||||||
|
BrightYellowBackgroundColorAttr = AttrBrightYellowBackgroundColor
|
||||||
|
BrightBlueBackgroundColorAttr = AttrBrightBlueBackgroundColor
|
||||||
|
BrightMagentaBackgroundColorAttr = AttrBrightMagentaBackgroundColor
|
||||||
|
BrightCyanBackgroundColorAttr = AttrBrightCyanBackgroundColor
|
||||||
|
BrightWhiteBackgroundColorAttr = AttrBrightWhiteBackgroundColor
|
||||||
|
RGBColorIntroducerAttr = AttrRGBColorIntroducer
|
||||||
|
ExtendedColorIntroducerAttr = AttrExtendedColorIntroducer
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
resetAttr = "0"
|
attrReset = "0"
|
||||||
boldAttr = "1"
|
attrBold = "1"
|
||||||
faintAttr = "2"
|
attrFaint = "2"
|
||||||
italicAttr = "3"
|
attrItalic = "3"
|
||||||
underlineAttr = "4"
|
attrUnderline = "4"
|
||||||
slowBlinkAttr = "5"
|
attrBlink = "5"
|
||||||
rapidBlinkAttr = "6"
|
attrRapidBlink = "6"
|
||||||
reverseAttr = "7"
|
attrReverse = "7"
|
||||||
concealAttr = "8"
|
attrConceal = "8"
|
||||||
strikethroughAttr = "9"
|
attrStrikethrough = "9"
|
||||||
normalIntensityAttr = "22"
|
attrNormalIntensity = "22"
|
||||||
noItalicAttr = "23"
|
attrNoItalic = "23"
|
||||||
noUnderlineAttr = "24"
|
attrNoUnderline = "24"
|
||||||
noBlinkAttr = "25"
|
attrNoBlink = "25"
|
||||||
noReverseAttr = "27"
|
attrNoReverse = "27"
|
||||||
noConcealAttr = "28"
|
attrNoConceal = "28"
|
||||||
noStrikethroughAttr = "29"
|
attrNoStrikethrough = "29"
|
||||||
blackForegroundColorAttr = "30"
|
attrBlackForegroundColor = "30"
|
||||||
redForegroundColorAttr = "31"
|
attrRedForegroundColor = "31"
|
||||||
greenForegroundColorAttr = "32"
|
attrGreenForegroundColor = "32"
|
||||||
yellowForegroundColorAttr = "33"
|
attrYellowForegroundColor = "33"
|
||||||
blueForegroundColorAttr = "34"
|
attrBlueForegroundColor = "34"
|
||||||
magentaForegroundColorAttr = "35"
|
attrMagentaForegroundColor = "35"
|
||||||
cyanForegroundColorAttr = "36"
|
attrCyanForegroundColor = "36"
|
||||||
whiteForegroundColorAttr = "37"
|
attrWhiteForegroundColor = "37"
|
||||||
extendedForegroundColorAttr = "38"
|
attrExtendedForegroundColor = "38"
|
||||||
defaultForegroundColorAttr = "39"
|
attrDefaultForegroundColor = "39"
|
||||||
blackBackgroundColorAttr = "40"
|
attrBlackBackgroundColor = "40"
|
||||||
redBackgroundColorAttr = "41"
|
attrRedBackgroundColor = "41"
|
||||||
greenBackgroundColorAttr = "42"
|
attrGreenBackgroundColor = "42"
|
||||||
yellowBackgroundColorAttr = "43"
|
attrYellowBackgroundColor = "43"
|
||||||
blueBackgroundColorAttr = "44"
|
attrBlueBackgroundColor = "44"
|
||||||
magentaBackgroundColorAttr = "45"
|
attrMagentaBackgroundColor = "45"
|
||||||
cyanBackgroundColorAttr = "46"
|
attrCyanBackgroundColor = "46"
|
||||||
whiteBackgroundColorAttr = "47"
|
attrWhiteBackgroundColor = "47"
|
||||||
extendedBackgroundColorAttr = "48"
|
attrExtendedBackgroundColor = "48"
|
||||||
defaultBackgroundColorAttr = "49"
|
attrDefaultBackgroundColor = "49"
|
||||||
extendedUnderlineColorAttr = "58"
|
attrExtendedUnderlineColor = "58"
|
||||||
defaultUnderlineColorAttr = "59"
|
attrDefaultUnderlineColor = "59"
|
||||||
brightBlackForegroundColorAttr = "90"
|
attrBrightBlackForegroundColor = "90"
|
||||||
brightRedForegroundColorAttr = "91"
|
attrBrightRedForegroundColor = "91"
|
||||||
brightGreenForegroundColorAttr = "92"
|
attrBrightGreenForegroundColor = "92"
|
||||||
brightYellowForegroundColorAttr = "93"
|
attrBrightYellowForegroundColor = "93"
|
||||||
brightBlueForegroundColorAttr = "94"
|
attrBrightBlueForegroundColor = "94"
|
||||||
brightMagentaForegroundColorAttr = "95"
|
attrBrightMagentaForegroundColor = "95"
|
||||||
brightCyanForegroundColorAttr = "96"
|
attrBrightCyanForegroundColor = "96"
|
||||||
brightWhiteForegroundColorAttr = "97"
|
attrBrightWhiteForegroundColor = "97"
|
||||||
brightBlackBackgroundColorAttr = "100"
|
attrBrightBlackBackgroundColor = "100"
|
||||||
brightRedBackgroundColorAttr = "101"
|
attrBrightRedBackgroundColor = "101"
|
||||||
brightGreenBackgroundColorAttr = "102"
|
attrBrightGreenBackgroundColor = "102"
|
||||||
brightYellowBackgroundColorAttr = "103"
|
attrBrightYellowBackgroundColor = "103"
|
||||||
brightBlueBackgroundColorAttr = "104"
|
attrBrightBlueBackgroundColor = "104"
|
||||||
brightMagentaBackgroundColorAttr = "105"
|
attrBrightMagentaBackgroundColor = "105"
|
||||||
brightCyanBackgroundColorAttr = "106"
|
attrBrightCyanBackgroundColor = "106"
|
||||||
brightWhiteBackgroundColorAttr = "107"
|
attrBrightWhiteBackgroundColor = "107"
|
||||||
)
|
)
|
||||||
|
|
||||||
// foregroundColorString returns the style SGR attribute for the given
|
// foregroundColorString returns the style SGR attribute for the given
|
||||||
@ -369,37 +492,37 @@ func foregroundColorString(c Color) string {
|
|||||||
// "3<n>" or "9<n>" where n is the color number from 0 to 7
|
// "3<n>" or "9<n>" where n is the color number from 0 to 7
|
||||||
switch c {
|
switch c {
|
||||||
case Black:
|
case Black:
|
||||||
return blackForegroundColorAttr
|
return attrBlackForegroundColor
|
||||||
case Red:
|
case Red:
|
||||||
return redForegroundColorAttr
|
return attrRedForegroundColor
|
||||||
case Green:
|
case Green:
|
||||||
return greenForegroundColorAttr
|
return attrGreenForegroundColor
|
||||||
case Yellow:
|
case Yellow:
|
||||||
return yellowForegroundColorAttr
|
return attrYellowForegroundColor
|
||||||
case Blue:
|
case Blue:
|
||||||
return blueForegroundColorAttr
|
return attrBlueForegroundColor
|
||||||
case Magenta:
|
case Magenta:
|
||||||
return magentaForegroundColorAttr
|
return attrMagentaForegroundColor
|
||||||
case Cyan:
|
case Cyan:
|
||||||
return cyanForegroundColorAttr
|
return attrCyanForegroundColor
|
||||||
case White:
|
case White:
|
||||||
return whiteForegroundColorAttr
|
return attrWhiteForegroundColor
|
||||||
case BrightBlack:
|
case BrightBlack:
|
||||||
return brightBlackForegroundColorAttr
|
return attrBrightBlackForegroundColor
|
||||||
case BrightRed:
|
case BrightRed:
|
||||||
return brightRedForegroundColorAttr
|
return attrBrightRedForegroundColor
|
||||||
case BrightGreen:
|
case BrightGreen:
|
||||||
return brightGreenForegroundColorAttr
|
return attrBrightGreenForegroundColor
|
||||||
case BrightYellow:
|
case BrightYellow:
|
||||||
return brightYellowForegroundColorAttr
|
return attrBrightYellowForegroundColor
|
||||||
case BrightBlue:
|
case BrightBlue:
|
||||||
return brightBlueForegroundColorAttr
|
return attrBrightBlueForegroundColor
|
||||||
case BrightMagenta:
|
case BrightMagenta:
|
||||||
return brightMagentaForegroundColorAttr
|
return attrBrightMagentaForegroundColor
|
||||||
case BrightCyan:
|
case BrightCyan:
|
||||||
return brightCyanForegroundColorAttr
|
return attrBrightCyanForegroundColor
|
||||||
case BrightWhite:
|
case BrightWhite:
|
||||||
return brightWhiteForegroundColorAttr
|
return attrBrightWhiteForegroundColor
|
||||||
}
|
}
|
||||||
case ExtendedColor:
|
case ExtendedColor:
|
||||||
// 256-color ANSI foreground
|
// 256-color ANSI foreground
|
||||||
@ -414,7 +537,7 @@ func foregroundColorString(c Color) string {
|
|||||||
strconv.FormatUint(uint64(shift(g)), 10) + ";" +
|
strconv.FormatUint(uint64(shift(g)), 10) + ";" +
|
||||||
strconv.FormatUint(uint64(shift(b)), 10)
|
strconv.FormatUint(uint64(shift(b)), 10)
|
||||||
}
|
}
|
||||||
return defaultForegroundColorAttr
|
return attrDefaultForegroundColor
|
||||||
}
|
}
|
||||||
|
|
||||||
// backgroundColorString returns the style SGR attribute for the given
|
// backgroundColorString returns the style SGR attribute for the given
|
||||||
@ -427,37 +550,37 @@ func backgroundColorString(c Color) string {
|
|||||||
// "4<n>" or "10<n>" where n is the color number from 0 to 7
|
// "4<n>" or "10<n>" where n is the color number from 0 to 7
|
||||||
switch c {
|
switch c {
|
||||||
case Black:
|
case Black:
|
||||||
return blackBackgroundColorAttr
|
return attrBlackBackgroundColor
|
||||||
case Red:
|
case Red:
|
||||||
return redBackgroundColorAttr
|
return attrRedBackgroundColor
|
||||||
case Green:
|
case Green:
|
||||||
return greenBackgroundColorAttr
|
return attrGreenBackgroundColor
|
||||||
case Yellow:
|
case Yellow:
|
||||||
return yellowBackgroundColorAttr
|
return attrYellowBackgroundColor
|
||||||
case Blue:
|
case Blue:
|
||||||
return blueBackgroundColorAttr
|
return attrBlueBackgroundColor
|
||||||
case Magenta:
|
case Magenta:
|
||||||
return magentaBackgroundColorAttr
|
return attrMagentaBackgroundColor
|
||||||
case Cyan:
|
case Cyan:
|
||||||
return cyanBackgroundColorAttr
|
return attrCyanBackgroundColor
|
||||||
case White:
|
case White:
|
||||||
return whiteBackgroundColorAttr
|
return attrWhiteBackgroundColor
|
||||||
case BrightBlack:
|
case BrightBlack:
|
||||||
return brightBlackBackgroundColorAttr
|
return attrBrightBlackBackgroundColor
|
||||||
case BrightRed:
|
case BrightRed:
|
||||||
return brightRedBackgroundColorAttr
|
return attrBrightRedBackgroundColor
|
||||||
case BrightGreen:
|
case BrightGreen:
|
||||||
return brightGreenBackgroundColorAttr
|
return attrBrightGreenBackgroundColor
|
||||||
case BrightYellow:
|
case BrightYellow:
|
||||||
return brightYellowBackgroundColorAttr
|
return attrBrightYellowBackgroundColor
|
||||||
case BrightBlue:
|
case BrightBlue:
|
||||||
return brightBlueBackgroundColorAttr
|
return attrBrightBlueBackgroundColor
|
||||||
case BrightMagenta:
|
case BrightMagenta:
|
||||||
return brightMagentaBackgroundColorAttr
|
return attrBrightMagentaBackgroundColor
|
||||||
case BrightCyan:
|
case BrightCyan:
|
||||||
return brightCyanBackgroundColorAttr
|
return attrBrightCyanBackgroundColor
|
||||||
case BrightWhite:
|
case BrightWhite:
|
||||||
return brightWhiteBackgroundColorAttr
|
return attrBrightWhiteBackgroundColor
|
||||||
}
|
}
|
||||||
case ExtendedColor:
|
case ExtendedColor:
|
||||||
// 256-color ANSI foreground
|
// 256-color ANSI foreground
|
||||||
@ -472,7 +595,7 @@ func backgroundColorString(c Color) string {
|
|||||||
strconv.FormatUint(uint64(shift(g)), 10) + ";" +
|
strconv.FormatUint(uint64(shift(g)), 10) + ";" +
|
||||||
strconv.FormatUint(uint64(shift(b)), 10)
|
strconv.FormatUint(uint64(shift(b)), 10)
|
||||||
}
|
}
|
||||||
return defaultBackgroundColorAttr
|
return attrDefaultBackgroundColor
|
||||||
}
|
}
|
||||||
|
|
||||||
// underlineColorString returns the style SGR attribute for the given underline
|
// underlineColorString returns the style SGR attribute for the given underline
|
||||||
@ -498,7 +621,7 @@ func underlineColorString(c Color) string {
|
|||||||
strconv.FormatUint(uint64(shift(g)), 10) + ";" +
|
strconv.FormatUint(uint64(shift(g)), 10) + ";" +
|
||||||
strconv.FormatUint(uint64(shift(b)), 10)
|
strconv.FormatUint(uint64(shift(b)), 10)
|
||||||
}
|
}
|
||||||
return defaultUnderlineColorAttr
|
return attrDefaultUnderlineColor
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadStyleColor decodes a color from a slice of parameters. It returns the
|
// ReadStyleColor decodes a color from a slice of parameters. It returns the
|
||||||
@ -526,7 +649,7 @@ func underlineColorString(c Color) string {
|
|||||||
// 2. Support ignoring and omitting the color space id (second parameter) with respect to RGB colors
|
// 2. Support ignoring and omitting the color space id (second parameter) with respect to RGB colors
|
||||||
// 3. Support ignoring and omitting the 6th parameter with respect to RGB and CMY colors
|
// 3. Support ignoring and omitting the 6th parameter with respect to RGB and CMY colors
|
||||||
// 4. Support reading RGBA colors
|
// 4. Support reading RGBA colors
|
||||||
func ReadStyleColor(params Params, co *color.Color) (n int) {
|
func ReadStyleColor(params Params, co *color.Color) int {
|
||||||
if len(params) < 2 { // Need at least SGR type and color type
|
if len(params) < 2 { // Need at least SGR type and color type
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@ -535,7 +658,7 @@ func ReadStyleColor(params Params, co *color.Color) (n int) {
|
|||||||
s := params[0]
|
s := params[0]
|
||||||
p := params[1]
|
p := params[1]
|
||||||
colorType := p.Param(0)
|
colorType := p.Param(0)
|
||||||
n = 2
|
n := 2
|
||||||
|
|
||||||
paramsfn := func() (p1, p2, p3, p4 int) {
|
paramsfn := func() (p1, p2, p3, p4 int) {
|
||||||
// Where should we start reading the color?
|
// Where should we start reading the color?
|
||||||
@ -594,7 +717,7 @@ func ReadStyleColor(params Params, co *color.Color) (n int) {
|
|||||||
B: uint8(b), //nolint:gosec
|
B: uint8(b), //nolint:gosec
|
||||||
A: 0xff,
|
A: 0xff,
|
||||||
}
|
}
|
||||||
return //nolint:nakedret
|
return n
|
||||||
|
|
||||||
case 3: // CMY direct color
|
case 3: // CMY direct color
|
||||||
if len(params) < 5 {
|
if len(params) < 5 {
|
||||||
@ -612,7 +735,7 @@ func ReadStyleColor(params Params, co *color.Color) (n int) {
|
|||||||
Y: uint8(y), //nolint:gosec
|
Y: uint8(y), //nolint:gosec
|
||||||
K: 0,
|
K: 0,
|
||||||
}
|
}
|
||||||
return //nolint:nakedret
|
return n
|
||||||
|
|
||||||
case 4: // CMYK direct color
|
case 4: // CMYK direct color
|
||||||
if len(params) < 6 {
|
if len(params) < 6 {
|
||||||
@ -630,7 +753,7 @@ func ReadStyleColor(params Params, co *color.Color) (n int) {
|
|||||||
Y: uint8(y), //nolint:gosec
|
Y: uint8(y), //nolint:gosec
|
||||||
K: uint8(k), //nolint:gosec
|
K: uint8(k), //nolint:gosec
|
||||||
}
|
}
|
||||||
return //nolint:nakedret
|
return n
|
||||||
|
|
||||||
case 5: // indexed color
|
case 5: // indexed color
|
||||||
if len(params) < 3 {
|
if len(params) < 3 {
|
||||||
@ -665,7 +788,7 @@ func ReadStyleColor(params Params, co *color.Color) (n int) {
|
|||||||
B: uint8(b), //nolint:gosec
|
B: uint8(b), //nolint:gosec
|
||||||
A: uint8(a), //nolint:gosec
|
A: uint8(a), //nolint:gosec
|
||||||
}
|
}
|
||||||
return //nolint:nakedret
|
return n
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
57
vendor/github.com/charmbracelet/x/ansi/truncate.go
generated
vendored
57
vendor/github.com/charmbracelet/x/ansi/truncate.go
generated
vendored
@ -1,11 +1,11 @@
|
|||||||
package ansi
|
package ansi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"strings"
|
||||||
|
|
||||||
"github.com/charmbracelet/x/ansi/parser"
|
"github.com/charmbracelet/x/ansi/parser"
|
||||||
"github.com/mattn/go-runewidth"
|
"github.com/clipperhouse/displaywidth"
|
||||||
"github.com/rivo/uniseg"
|
"github.com/clipperhouse/uax29/v2/graphemes"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Cut the string, without adding any prefix or tail strings. This function is
|
// Cut the string, without adding any prefix or tail strings. This function is
|
||||||
@ -74,12 +74,11 @@ func truncate(m Method, s string, length int, tail string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
var cluster []byte
|
var cluster string
|
||||||
var buf bytes.Buffer
|
var buf strings.Builder
|
||||||
curWidth := 0
|
curWidth := 0
|
||||||
ignoring := false
|
ignoring := false
|
||||||
pstate := parser.GroundState // initial state
|
pstate := parser.GroundState // initial state
|
||||||
b := []byte(s)
|
|
||||||
i := 0
|
i := 0
|
||||||
|
|
||||||
// Here we iterate over the bytes of the string and collect printable
|
// Here we iterate over the bytes of the string and collect printable
|
||||||
@ -88,16 +87,12 @@ func truncate(m Method, s string, length int, tail string) string {
|
|||||||
//
|
//
|
||||||
// Once we reach the given length, we start ignoring characters and only
|
// Once we reach the given length, we start ignoring characters and only
|
||||||
// collect ANSI escape codes until we reach the end of string.
|
// collect ANSI escape codes until we reach the end of string.
|
||||||
for i < len(b) {
|
for i < len(s) {
|
||||||
state, action := parser.Table.Transition(pstate, b[i])
|
state, action := parser.Table.Transition(pstate, s[i])
|
||||||
if state == parser.Utf8State {
|
if state == parser.Utf8State {
|
||||||
// This action happens when we transition to the Utf8State.
|
// This action happens when we transition to the Utf8State.
|
||||||
var width int
|
var width int
|
||||||
cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1)
|
cluster, width = FirstGraphemeCluster(s[i:], m)
|
||||||
if m == WcWidth {
|
|
||||||
width = runewidth.StringWidth(string(cluster))
|
|
||||||
}
|
|
||||||
|
|
||||||
// increment the index by the length of the cluster
|
// increment the index by the length of the cluster
|
||||||
i += len(cluster)
|
i += len(cluster)
|
||||||
curWidth += width
|
curWidth += width
|
||||||
@ -118,7 +113,7 @@ func truncate(m Method, s string, length int, tail string) string {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.Write(cluster)
|
buf.WriteString(cluster)
|
||||||
|
|
||||||
// Done collecting, now we're back in the ground state.
|
// Done collecting, now we're back in the ground state.
|
||||||
pstate = parser.GroundState
|
pstate = parser.GroundState
|
||||||
@ -152,7 +147,7 @@ func truncate(m Method, s string, length int, tail string) string {
|
|||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
default:
|
default:
|
||||||
buf.WriteByte(b[i])
|
buf.WriteByte(s[i])
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,27 +188,23 @@ func truncateLeft(m Method, s string, n int, prefix string) string {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
var cluster []byte
|
var cluster string
|
||||||
var buf bytes.Buffer
|
var buf strings.Builder
|
||||||
curWidth := 0
|
curWidth := 0
|
||||||
ignoring := true
|
ignoring := true
|
||||||
pstate := parser.GroundState
|
pstate := parser.GroundState
|
||||||
b := []byte(s)
|
|
||||||
i := 0
|
i := 0
|
||||||
|
|
||||||
for i < len(b) {
|
for i < len(s) {
|
||||||
if !ignoring {
|
if !ignoring {
|
||||||
buf.Write(b[i:])
|
buf.WriteString(s[i:])
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
state, action := parser.Table.Transition(pstate, b[i])
|
state, action := parser.Table.Transition(pstate, s[i])
|
||||||
if state == parser.Utf8State {
|
if state == parser.Utf8State {
|
||||||
var width int
|
var width int
|
||||||
cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1)
|
cluster, width = FirstGraphemeCluster(s[i:], m)
|
||||||
if m == WcWidth {
|
|
||||||
width = runewidth.StringWidth(string(cluster))
|
|
||||||
}
|
|
||||||
|
|
||||||
i += len(cluster)
|
i += len(cluster)
|
||||||
curWidth += width
|
curWidth += width
|
||||||
@ -224,7 +215,7 @@ func truncateLeft(m Method, s string, n int, prefix string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if curWidth > n {
|
if curWidth > n {
|
||||||
buf.Write(cluster)
|
buf.WriteString(cluster)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ignoring {
|
if ignoring {
|
||||||
@ -259,7 +250,7 @@ func truncateLeft(m Method, s string, n int, prefix string) string {
|
|||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
default:
|
default:
|
||||||
buf.WriteByte(b[i])
|
buf.WriteByte(s[i])
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,22 +269,22 @@ func truncateLeft(m Method, s string, n int, prefix string) string {
|
|||||||
// You can use this with [Truncate], [TruncateLeft], and [Cut].
|
// You can use this with [Truncate], [TruncateLeft], and [Cut].
|
||||||
func ByteToGraphemeRange(str string, byteStart, byteStop int) (charStart, charStop int) {
|
func ByteToGraphemeRange(str string, byteStart, byteStop int) (charStart, charStop int) {
|
||||||
bytePos, charPos := 0, 0
|
bytePos, charPos := 0, 0
|
||||||
gr := uniseg.NewGraphemes(str)
|
gr := graphemes.FromString(str)
|
||||||
for byteStart > bytePos {
|
for byteStart > bytePos {
|
||||||
if !gr.Next() {
|
if !gr.Next() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
bytePos += len(gr.Str())
|
bytePos += len(gr.Value())
|
||||||
charPos += max(1, gr.Width())
|
charPos += max(1, displaywidth.String(gr.Value()))
|
||||||
}
|
}
|
||||||
charStart = charPos
|
charStart = charPos
|
||||||
for byteStop > bytePos {
|
for byteStop > bytePos {
|
||||||
if !gr.Next() {
|
if !gr.Next() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
bytePos += len(gr.Str())
|
bytePos += len(gr.Value())
|
||||||
charPos += max(1, gr.Width())
|
charPos += max(1, displaywidth.String(gr.Value()))
|
||||||
}
|
}
|
||||||
charStop = charPos
|
charStop = charPos
|
||||||
return
|
return charStart, charStop
|
||||||
}
|
}
|
||||||
|
|||||||
17
vendor/github.com/charmbracelet/x/ansi/urxvt.go
generated
vendored
Normal file
17
vendor/github.com/charmbracelet/x/ansi/urxvt.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package ansi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// URxvtExt returns an escape sequence for calling a URxvt perl extension with
|
||||||
|
// the given name and parameters.
|
||||||
|
//
|
||||||
|
// OSC 777 ; extension_name ; param1 ; param2 ; ... ST
|
||||||
|
// OSC 777 ; extension_name ; param1 ; param2 ; ... BEL
|
||||||
|
//
|
||||||
|
// See: https://man.archlinux.org/man/extra/rxvt-unicode/urxvt.7.en#XTerm_Operating_System_Commands
|
||||||
|
func URxvtExt(extension string, params ...string) string {
|
||||||
|
return fmt.Sprintf("\x1b]777;%s;%s\x07", extension, strings.Join(params, ";"))
|
||||||
|
}
|
||||||
14
vendor/github.com/charmbracelet/x/ansi/width.go
generated
vendored
14
vendor/github.com/charmbracelet/x/ansi/width.go
generated
vendored
@ -4,8 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
|
|
||||||
"github.com/charmbracelet/x/ansi/parser"
|
"github.com/charmbracelet/x/ansi/parser"
|
||||||
"github.com/mattn/go-runewidth"
|
|
||||||
"github.com/rivo/uniseg"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Strip removes ANSI escape codes from a string.
|
// Strip removes ANSI escape codes from a string.
|
||||||
@ -83,20 +81,16 @@ func stringWidth(m Method, s string) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
pstate = parser.GroundState // initial state
|
pstate = parser.GroundState // initial state
|
||||||
cluster string
|
width int
|
||||||
width int
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
state, action := parser.Table.Transition(pstate, s[i])
|
state, action := parser.Table.Transition(pstate, s[i])
|
||||||
if state == parser.Utf8State {
|
if state == parser.Utf8State {
|
||||||
var w int
|
cluster, w := FirstGraphemeCluster(s[i:], m)
|
||||||
cluster, _, w, _ = uniseg.FirstGraphemeClusterInString(s[i:], -1)
|
|
||||||
if m == WcWidth {
|
|
||||||
w = runewidth.StringWidth(cluster)
|
|
||||||
}
|
|
||||||
width += w
|
width += w
|
||||||
|
|
||||||
i += len(cluster) - 1
|
i += len(cluster) - 1
|
||||||
pstate = parser.GroundState
|
pstate = parser.GroundState
|
||||||
continue
|
continue
|
||||||
|
|||||||
6
vendor/github.com/charmbracelet/x/ansi/winop.go
generated
vendored
6
vendor/github.com/charmbracelet/x/ansi/winop.go
generated
vendored
@ -8,16 +8,22 @@ import (
|
|||||||
const (
|
const (
|
||||||
// ResizeWindowWinOp is a window operation that resizes the terminal
|
// ResizeWindowWinOp is a window operation that resizes the terminal
|
||||||
// window.
|
// window.
|
||||||
|
//
|
||||||
|
// Deprecated: Use constant number directly with [WindowOp].
|
||||||
ResizeWindowWinOp = 4
|
ResizeWindowWinOp = 4
|
||||||
|
|
||||||
// RequestWindowSizeWinOp is a window operation that requests a report of
|
// RequestWindowSizeWinOp is a window operation that requests a report of
|
||||||
// the size of the terminal window in pixels. The response is in the form:
|
// the size of the terminal window in pixels. The response is in the form:
|
||||||
// CSI 4 ; height ; width t
|
// CSI 4 ; height ; width t
|
||||||
|
//
|
||||||
|
// Deprecated: Use constant number directly with [WindowOp].
|
||||||
RequestWindowSizeWinOp = 14
|
RequestWindowSizeWinOp = 14
|
||||||
|
|
||||||
// RequestCellSizeWinOp is a window operation that requests a report of
|
// RequestCellSizeWinOp is a window operation that requests a report of
|
||||||
// the size of the terminal cell size in pixels. The response is in the form:
|
// the size of the terminal cell size in pixels. The response is in the form:
|
||||||
// CSI 6 ; height ; width t
|
// CSI 6 ; height ; width t
|
||||||
|
//
|
||||||
|
// Deprecated: Use constant number directly with [WindowOp].
|
||||||
RequestCellSizeWinOp = 16
|
RequestCellSizeWinOp = 16
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
50
vendor/github.com/charmbracelet/x/ansi/wrap.go
generated
vendored
50
vendor/github.com/charmbracelet/x/ansi/wrap.go
generated
vendored
@ -2,12 +2,11 @@ package ansi
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/charmbracelet/x/ansi/parser"
|
"github.com/charmbracelet/x/ansi/parser"
|
||||||
"github.com/mattn/go-runewidth"
|
|
||||||
"github.com/rivo/uniseg"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// nbsp is a non-breaking space.
|
// nbsp is a non-breaking space.
|
||||||
@ -55,12 +54,9 @@ func hardwrap(m Method, s string, limit int, preserveSpace bool) string {
|
|||||||
i := 0
|
i := 0
|
||||||
for i < len(b) {
|
for i < len(b) {
|
||||||
state, action := parser.Table.Transition(pstate, b[i])
|
state, action := parser.Table.Transition(pstate, b[i])
|
||||||
if state == parser.Utf8State { //nolint:nestif
|
if state == parser.Utf8State {
|
||||||
var width int
|
var width int
|
||||||
cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1)
|
cluster, width = FirstGraphemeCluster(b[i:], m)
|
||||||
if m == WcWidth {
|
|
||||||
width = runewidth.StringWidth(string(cluster))
|
|
||||||
}
|
|
||||||
i += len(cluster)
|
i += len(cluster)
|
||||||
|
|
||||||
if curWidth+width > limit {
|
if curWidth+width > limit {
|
||||||
@ -192,10 +188,7 @@ func wordwrap(m Method, s string, limit int, breakpoints string) string {
|
|||||||
state, action := parser.Table.Transition(pstate, b[i])
|
state, action := parser.Table.Transition(pstate, b[i])
|
||||||
if state == parser.Utf8State { //nolint:nestif
|
if state == parser.Utf8State { //nolint:nestif
|
||||||
var width int
|
var width int
|
||||||
cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1)
|
cluster, width = FirstGraphemeCluster(b[i:], m)
|
||||||
if m == WcWidth {
|
|
||||||
width = runewidth.StringWidth(string(cluster))
|
|
||||||
}
|
|
||||||
i += len(cluster)
|
i += len(cluster)
|
||||||
|
|
||||||
r, _ := utf8.DecodeRune(cluster)
|
r, _ := utf8.DecodeRune(cluster)
|
||||||
@ -303,7 +296,7 @@ func wrap(m Method, s string, limit int, breakpoints string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cluster []byte
|
cluster string
|
||||||
buf bytes.Buffer
|
buf bytes.Buffer
|
||||||
word bytes.Buffer
|
word bytes.Buffer
|
||||||
space bytes.Buffer
|
space bytes.Buffer
|
||||||
@ -311,10 +304,12 @@ func wrap(m Method, s string, limit int, breakpoints string) string {
|
|||||||
curWidth int // written width of the line
|
curWidth int // written width of the line
|
||||||
wordLen int // word buffer len without ANSI escape codes
|
wordLen int // word buffer len without ANSI escape codes
|
||||||
pstate = parser.GroundState // initial state
|
pstate = parser.GroundState // initial state
|
||||||
b = []byte(s)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
addSpace := func() {
|
addSpace := func() {
|
||||||
|
if spaceWidth == 0 && space.Len() == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
curWidth += spaceWidth
|
curWidth += spaceWidth
|
||||||
buf.Write(space.Bytes())
|
buf.Write(space.Bytes())
|
||||||
space.Reset()
|
space.Reset()
|
||||||
@ -341,30 +336,27 @@ func wrap(m Method, s string, limit int, breakpoints string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
for i < len(b) {
|
for i < len(s) {
|
||||||
state, action := parser.Table.Transition(pstate, b[i])
|
state, action := parser.Table.Transition(pstate, s[i])
|
||||||
if state == parser.Utf8State { //nolint:nestif
|
if state == parser.Utf8State { //nolint:nestif
|
||||||
var width int
|
var width int
|
||||||
cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1)
|
cluster, width = FirstGraphemeCluster(s[i:], m)
|
||||||
if m == WcWidth {
|
|
||||||
width = runewidth.StringWidth(string(cluster))
|
|
||||||
}
|
|
||||||
i += len(cluster)
|
i += len(cluster)
|
||||||
|
|
||||||
r, _ := utf8.DecodeRune(cluster)
|
r, _ := utf8.DecodeRuneInString(cluster)
|
||||||
switch {
|
switch {
|
||||||
case r != utf8.RuneError && unicode.IsSpace(r) && r != nbsp: // nbsp is a non-breaking space
|
case r != utf8.RuneError && unicode.IsSpace(r) && r != nbsp: // nbsp is a non-breaking space
|
||||||
addWord()
|
addWord()
|
||||||
space.WriteRune(r)
|
space.WriteRune(r)
|
||||||
spaceWidth += width
|
spaceWidth += width
|
||||||
case bytes.ContainsAny(cluster, breakpoints):
|
case strings.ContainsAny(cluster, breakpoints):
|
||||||
addSpace()
|
addSpace()
|
||||||
if curWidth+wordLen+width > limit {
|
if curWidth+wordLen+width > limit {
|
||||||
word.Write(cluster)
|
word.WriteString(cluster)
|
||||||
wordLen += width
|
wordLen += width
|
||||||
} else {
|
} else {
|
||||||
addWord()
|
addWord()
|
||||||
buf.Write(cluster)
|
buf.WriteString(cluster)
|
||||||
curWidth += width
|
curWidth += width
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -373,12 +365,17 @@ func wrap(m Method, s string, limit int, breakpoints string) string {
|
|||||||
addWord()
|
addWord()
|
||||||
}
|
}
|
||||||
|
|
||||||
word.Write(cluster)
|
word.WriteString(cluster)
|
||||||
wordLen += width
|
wordLen += width
|
||||||
|
|
||||||
if curWidth+wordLen+spaceWidth > limit {
|
if curWidth+wordLen+spaceWidth > limit {
|
||||||
addNewline()
|
addNewline()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if wordLen == limit {
|
||||||
|
// Hardwrap the word if it's too long
|
||||||
|
addWord()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pstate = parser.GroundState
|
pstate = parser.GroundState
|
||||||
@ -387,7 +384,7 @@ func wrap(m Method, s string, limit int, breakpoints string) string {
|
|||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
case parser.PrintAction, parser.ExecuteAction:
|
case parser.PrintAction, parser.ExecuteAction:
|
||||||
switch r := rune(b[i]); {
|
switch r := rune(s[i]); {
|
||||||
case r == '\n':
|
case r == '\n':
|
||||||
if wordLen == 0 {
|
if wordLen == 0 {
|
||||||
if curWidth+spaceWidth > limit {
|
if curWidth+spaceWidth > limit {
|
||||||
@ -424,6 +421,7 @@ func wrap(m Method, s string, limit int, breakpoints string) string {
|
|||||||
if curWidth == limit {
|
if curWidth == limit {
|
||||||
addNewline()
|
addNewline()
|
||||||
}
|
}
|
||||||
|
|
||||||
word.WriteRune(r)
|
word.WriteRune(r)
|
||||||
wordLen++
|
wordLen++
|
||||||
|
|
||||||
@ -438,7 +436,7 @@ func wrap(m Method, s string, limit int, breakpoints string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
word.WriteByte(b[i])
|
word.WriteByte(s[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
// We manage the UTF8 state separately manually above.
|
// We manage the UTF8 state separately manually above.
|
||||||
|
|||||||
15
vendor/github.com/charmbracelet/x/cellbuf/buffer.go
generated
vendored
15
vendor/github.com/charmbracelet/x/cellbuf/buffer.go
generated
vendored
@ -1,3 +1,4 @@
|
|||||||
|
// Package cellbuf provides terminal cell buffer functionality.
|
||||||
package cellbuf
|
package cellbuf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -24,7 +25,7 @@ func NewCell(r rune, comb ...rune) (c *Cell) {
|
|||||||
}
|
}
|
||||||
c.Comb = comb
|
c.Comb = comb
|
||||||
c.Width = runewidth.StringWidth(string(append([]rune{r}, comb...)))
|
c.Width = runewidth.StringWidth(string(append([]rune{r}, comb...)))
|
||||||
return
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCellString returns a new cell with the given string content. This is a
|
// NewCellString returns a new cell with the given string content. This is a
|
||||||
@ -46,7 +47,7 @@ func NewCellString(s string) (c *Cell) {
|
|||||||
c.Comb = append(c.Comb, r)
|
c.Comb = append(c.Comb, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGraphemeCell returns a new cell. This is a convenience function that
|
// NewGraphemeCell returns a new cell. This is a convenience function that
|
||||||
@ -71,7 +72,7 @@ func newGraphemeCell(s string, w int) (c *Cell) {
|
|||||||
c.Comb = append(c.Comb, r)
|
c.Comb = append(c.Comb, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Line represents a line in the terminal.
|
// Line represents a line in the terminal.
|
||||||
@ -104,7 +105,7 @@ func (l Line) String() (s string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
s = strings.TrimRight(s, " ")
|
s = strings.TrimRight(s, " ")
|
||||||
return
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// At returns the cell at the given x position.
|
// At returns the cell at the given x position.
|
||||||
@ -150,7 +151,7 @@ func (l Line) set(x int, c *Cell, clone bool) bool {
|
|||||||
for j := 1; j < maxCellWidth && x-j >= 0; j++ {
|
for j := 1; j < maxCellWidth && x-j >= 0; j++ {
|
||||||
wide := l.At(x - j)
|
wide := l.At(x - j)
|
||||||
if wide != nil && wide.Width > 1 && j < wide.Width {
|
if wide != nil && wide.Width > 1 && j < wide.Width {
|
||||||
for k := 0; k < wide.Width; k++ {
|
for k := range wide.Width {
|
||||||
l[x-j+k] = wide.Clone().Blank()
|
l[x-j+k] = wide.Clone().Blank()
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@ -206,7 +207,7 @@ func (b *Buffer) String() (s string) {
|
|||||||
s += "\r\n"
|
s += "\r\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Line returns a pointer to the line at the given y position.
|
// Line returns a pointer to the line at the given y position.
|
||||||
@ -296,7 +297,7 @@ func (b *Buffer) FillRect(c *Cell, rect Rectangle) {
|
|||||||
}
|
}
|
||||||
for y := rect.Min.Y; y < rect.Max.Y; y++ {
|
for y := rect.Min.Y; y < rect.Max.Y; y++ {
|
||||||
for x := rect.Min.X; x < rect.Max.X; x += cellWidth {
|
for x := rect.Min.X; x < rect.Max.X; x += cellWidth {
|
||||||
b.setCell(x, y, c, false) //nolint:errcheck
|
b.setCell(x, y, c, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
83
vendor/github.com/charmbracelet/x/cellbuf/cell.go
generated
vendored
83
vendor/github.com/charmbracelet/x/cellbuf/cell.go
generated
vendored
@ -96,7 +96,7 @@ func (c *Cell) Clear() bool {
|
|||||||
func (c *Cell) Clone() (n *Cell) {
|
func (c *Cell) Clone() (n *Cell) {
|
||||||
n = new(Cell)
|
n = new(Cell)
|
||||||
*n = *c
|
*n = *c
|
||||||
return
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blank makes the cell a blank cell by setting the rune to a space, comb to
|
// Blank makes the cell a blank cell by setting the rune to a space, comb to
|
||||||
@ -164,12 +164,12 @@ type UnderlineStyle = ansi.UnderlineStyle
|
|||||||
|
|
||||||
// These are the available underline styles.
|
// These are the available underline styles.
|
||||||
const (
|
const (
|
||||||
NoUnderline = ansi.NoUnderlineStyle
|
NoUnderline = ansi.UnderlineStyleNone
|
||||||
SingleUnderline = ansi.SingleUnderlineStyle
|
SingleUnderline = ansi.UnderlineStyleSingle
|
||||||
DoubleUnderline = ansi.DoubleUnderlineStyle
|
DoubleUnderline = ansi.UnderlineStyleDouble
|
||||||
CurlyUnderline = ansi.CurlyUnderlineStyle
|
CurlyUnderline = ansi.UnderlineStyleCurly
|
||||||
DottedUnderline = ansi.DottedUnderlineStyle
|
DottedUnderline = ansi.UnderlineStyleDotted
|
||||||
DashedUnderline = ansi.DashedUnderlineStyle
|
DashedUnderline = ansi.UnderlineStyleDashed
|
||||||
)
|
)
|
||||||
|
|
||||||
// Style represents the Style of a cell.
|
// Style represents the Style of a cell.
|
||||||
@ -189,7 +189,7 @@ func (s Style) Sequence() string {
|
|||||||
|
|
||||||
var b ansi.Style
|
var b ansi.Style
|
||||||
|
|
||||||
if s.Attrs != 0 {
|
if s.Attrs != 0 { //nolint:nestif
|
||||||
if s.Attrs&BoldAttr != 0 {
|
if s.Attrs&BoldAttr != 0 {
|
||||||
b = b.Bold()
|
b = b.Bold()
|
||||||
}
|
}
|
||||||
@ -197,36 +197,31 @@ func (s Style) Sequence() string {
|
|||||||
b = b.Faint()
|
b = b.Faint()
|
||||||
}
|
}
|
||||||
if s.Attrs&ItalicAttr != 0 {
|
if s.Attrs&ItalicAttr != 0 {
|
||||||
b = b.Italic()
|
b = b.Italic(true)
|
||||||
}
|
}
|
||||||
if s.Attrs&SlowBlinkAttr != 0 {
|
if s.Attrs&SlowBlinkAttr != 0 {
|
||||||
b = b.SlowBlink()
|
b = b.Blink(true)
|
||||||
}
|
}
|
||||||
if s.Attrs&RapidBlinkAttr != 0 {
|
if s.Attrs&RapidBlinkAttr != 0 {
|
||||||
b = b.RapidBlink()
|
b = b.RapidBlink(true)
|
||||||
}
|
}
|
||||||
if s.Attrs&ReverseAttr != 0 {
|
if s.Attrs&ReverseAttr != 0 {
|
||||||
b = b.Reverse()
|
b = b.Reverse(true)
|
||||||
}
|
}
|
||||||
if s.Attrs&ConcealAttr != 0 {
|
if s.Attrs&ConcealAttr != 0 {
|
||||||
b = b.Conceal()
|
b = b.Conceal(true)
|
||||||
}
|
}
|
||||||
if s.Attrs&StrikethroughAttr != 0 {
|
if s.Attrs&StrikethroughAttr != 0 {
|
||||||
b = b.Strikethrough()
|
b = b.Strikethrough(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.UlStyle != NoUnderline {
|
if s.UlStyle != NoUnderline {
|
||||||
switch s.UlStyle {
|
switch u := s.UlStyle; u {
|
||||||
case SingleUnderline:
|
case NoUnderline:
|
||||||
b = b.Underline()
|
b = b.Underline(false)
|
||||||
case DoubleUnderline:
|
default:
|
||||||
b = b.DoubleUnderline()
|
b = b.Underline(true)
|
||||||
case CurlyUnderline:
|
b = b.UnderlineStyle(u)
|
||||||
b = b.CurlyUnderline()
|
|
||||||
case DottedUnderline:
|
|
||||||
b = b.DottedUnderline()
|
|
||||||
case DashedUnderline:
|
|
||||||
b = b.DashedUnderline()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.Fg != nil {
|
if s.Fg != nil {
|
||||||
@ -268,64 +263,48 @@ func (s Style) DiffSequence(o Style) string {
|
|||||||
isNormal bool
|
isNormal bool
|
||||||
)
|
)
|
||||||
|
|
||||||
if s.Attrs != o.Attrs {
|
if s.Attrs != o.Attrs { //nolint:nestif
|
||||||
if s.Attrs&BoldAttr != o.Attrs&BoldAttr {
|
if s.Attrs&BoldAttr != o.Attrs&BoldAttr {
|
||||||
if s.Attrs&BoldAttr != 0 {
|
if s.Attrs&BoldAttr != 0 {
|
||||||
b = b.Bold()
|
b = b.Bold()
|
||||||
} else if !isNormal {
|
} else if !isNormal {
|
||||||
isNormal = true
|
isNormal = true
|
||||||
b = b.NormalIntensity()
|
b = b.Normal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.Attrs&FaintAttr != o.Attrs&FaintAttr {
|
if s.Attrs&FaintAttr != o.Attrs&FaintAttr {
|
||||||
if s.Attrs&FaintAttr != 0 {
|
if s.Attrs&FaintAttr != 0 {
|
||||||
b = b.Faint()
|
b = b.Faint()
|
||||||
} else if !isNormal {
|
} else if !isNormal {
|
||||||
b = b.NormalIntensity()
|
b = b.Normal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.Attrs&ItalicAttr != o.Attrs&ItalicAttr {
|
if s.Attrs&ItalicAttr != o.Attrs&ItalicAttr {
|
||||||
if s.Attrs&ItalicAttr != 0 {
|
b = b.Italic(s.Attrs&ItalicAttr != 0)
|
||||||
b = b.Italic()
|
|
||||||
} else {
|
|
||||||
b = b.NoItalic()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if s.Attrs&SlowBlinkAttr != o.Attrs&SlowBlinkAttr {
|
if s.Attrs&SlowBlinkAttr != o.Attrs&SlowBlinkAttr {
|
||||||
if s.Attrs&SlowBlinkAttr != 0 {
|
if s.Attrs&SlowBlinkAttr != 0 {
|
||||||
b = b.SlowBlink()
|
b = b.Blink(true)
|
||||||
} else if !noBlink {
|
} else if !noBlink {
|
||||||
noBlink = true
|
noBlink = true
|
||||||
b = b.NoBlink()
|
b = b.Blink(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.Attrs&RapidBlinkAttr != o.Attrs&RapidBlinkAttr {
|
if s.Attrs&RapidBlinkAttr != o.Attrs&RapidBlinkAttr {
|
||||||
if s.Attrs&RapidBlinkAttr != 0 {
|
if s.Attrs&RapidBlinkAttr != 0 {
|
||||||
b = b.RapidBlink()
|
b = b.RapidBlink(true)
|
||||||
} else if !noBlink {
|
} else if !noBlink {
|
||||||
b = b.NoBlink()
|
b = b.Blink(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.Attrs&ReverseAttr != o.Attrs&ReverseAttr {
|
if s.Attrs&ReverseAttr != o.Attrs&ReverseAttr {
|
||||||
if s.Attrs&ReverseAttr != 0 {
|
b = b.Reverse(s.Attrs&ReverseAttr != 0)
|
||||||
b = b.Reverse()
|
|
||||||
} else {
|
|
||||||
b = b.NoReverse()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if s.Attrs&ConcealAttr != o.Attrs&ConcealAttr {
|
if s.Attrs&ConcealAttr != o.Attrs&ConcealAttr {
|
||||||
if s.Attrs&ConcealAttr != 0 {
|
b = b.Conceal(s.Attrs&ConcealAttr != 0)
|
||||||
b = b.Conceal()
|
|
||||||
} else {
|
|
||||||
b = b.NoConceal()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if s.Attrs&StrikethroughAttr != o.Attrs&StrikethroughAttr {
|
if s.Attrs&StrikethroughAttr != o.Attrs&StrikethroughAttr {
|
||||||
if s.Attrs&StrikethroughAttr != 0 {
|
b = b.Strikethrough(s.Attrs&StrikethroughAttr != 0)
|
||||||
b = b.Strikethrough()
|
|
||||||
} else {
|
|
||||||
b = b.NoStrikethrough()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
vendor/github.com/charmbracelet/x/cellbuf/geom.go
generated
vendored
2
vendor/github.com/charmbracelet/x/cellbuf/geom.go
generated
vendored
@ -12,7 +12,7 @@ func Pos(x, y int) Position {
|
|||||||
return image.Pt(x, y)
|
return image.Pt(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rectange represents a rectangle.
|
// Rectangle represents a rectangle.
|
||||||
type Rectangle = image.Rectangle
|
type Rectangle = image.Rectangle
|
||||||
|
|
||||||
// Rect is a shorthand for Rectangle.
|
// Rect is a shorthand for Rectangle.
|
||||||
|
|||||||
19
vendor/github.com/charmbracelet/x/cellbuf/hardscroll.go
generated
vendored
19
vendor/github.com/charmbracelet/x/cellbuf/hardscroll.go
generated
vendored
@ -75,7 +75,7 @@ func (s *Screen) scrolln(n, top, bot, maxY int) (v bool) { //nolint:unparam
|
|||||||
)
|
)
|
||||||
|
|
||||||
blank := s.clearBlank()
|
blank := s.clearBlank()
|
||||||
if n > 0 {
|
if n > 0 { //nolint:nestif
|
||||||
// Scroll up (forward)
|
// Scroll up (forward)
|
||||||
v = s.scrollUp(n, top, bot, 0, maxY, blank)
|
v = s.scrollUp(n, top, bot, 0, maxY, blank)
|
||||||
if !v {
|
if !v {
|
||||||
@ -99,7 +99,7 @@ func (s *Screen) scrolln(n, top, bot, maxY int) (v bool) { //nolint:unparam
|
|||||||
s.move(0, bot-n+1)
|
s.move(0, bot-n+1)
|
||||||
s.clearToBottom(nil)
|
s.clearToBottom(nil)
|
||||||
} else {
|
} else {
|
||||||
for i := 0; i < n; i++ {
|
for i := range n {
|
||||||
s.move(0, bot-i)
|
s.move(0, bot-i)
|
||||||
s.clearToEnd(nil, false)
|
s.clearToEnd(nil, false)
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ func (s *Screen) scrolln(n, top, bot, maxY int) (v bool) { //nolint:unparam
|
|||||||
// Clear newly shifted-in lines.
|
// Clear newly shifted-in lines.
|
||||||
if v &&
|
if v &&
|
||||||
(nonDestScrollRegion || (memoryBelow && top == 0)) {
|
(nonDestScrollRegion || (memoryBelow && top == 0)) {
|
||||||
for i := 0; i < -n; i++ {
|
for i := range -n {
|
||||||
s.move(0, top+i)
|
s.move(0, top+i)
|
||||||
s.clearToEnd(nil, false)
|
s.clearToEnd(nil, false)
|
||||||
}
|
}
|
||||||
@ -133,7 +133,7 @@ func (s *Screen) scrolln(n, top, bot, maxY int) (v bool) { //nolint:unparam
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !v {
|
if !v {
|
||||||
return
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
s.scrollBuffer(s.curbuf, n, top, bot, blank)
|
s.scrollBuffer(s.curbuf, n, top, bot, blank)
|
||||||
@ -193,7 +193,7 @@ func (s *Screen) touchLine(width, height, y, n int, changed bool) {
|
|||||||
|
|
||||||
// scrollUp scrolls the screen up by n lines.
|
// scrollUp scrolls the screen up by n lines.
|
||||||
func (s *Screen) scrollUp(n, top, bot, minY, maxY int, blank *Cell) bool {
|
func (s *Screen) scrollUp(n, top, bot, minY, maxY int, blank *Cell) bool {
|
||||||
if n == 1 && top == minY && bot == maxY {
|
if n == 1 && top == minY && bot == maxY { //nolint:nestif
|
||||||
s.move(0, bot)
|
s.move(0, bot)
|
||||||
s.updatePen(blank)
|
s.updatePen(blank)
|
||||||
s.buf.WriteByte('\n')
|
s.buf.WriteByte('\n')
|
||||||
@ -202,13 +202,14 @@ func (s *Screen) scrollUp(n, top, bot, minY, maxY int, blank *Cell) bool {
|
|||||||
s.updatePen(blank)
|
s.updatePen(blank)
|
||||||
s.buf.WriteString(ansi.DeleteLine(1))
|
s.buf.WriteString(ansi.DeleteLine(1))
|
||||||
} else if top == minY && bot == maxY {
|
} else if top == minY && bot == maxY {
|
||||||
if s.xtermLike {
|
supportsSU := s.caps.Contains(capSU)
|
||||||
|
if supportsSU {
|
||||||
s.move(0, bot)
|
s.move(0, bot)
|
||||||
} else {
|
} else {
|
||||||
s.move(0, top)
|
s.move(0, top)
|
||||||
}
|
}
|
||||||
s.updatePen(blank)
|
s.updatePen(blank)
|
||||||
if s.xtermLike {
|
if supportsSU {
|
||||||
s.buf.WriteString(ansi.ScrollUp(n))
|
s.buf.WriteString(ansi.ScrollUp(n))
|
||||||
} else {
|
} else {
|
||||||
s.buf.WriteString(strings.Repeat("\n", n))
|
s.buf.WriteString(strings.Repeat("\n", n))
|
||||||
@ -225,7 +226,7 @@ func (s *Screen) scrollUp(n, top, bot, minY, maxY int, blank *Cell) bool {
|
|||||||
|
|
||||||
// scrollDown scrolls the screen down by n lines.
|
// scrollDown scrolls the screen down by n lines.
|
||||||
func (s *Screen) scrollDown(n, top, bot, minY, maxY int, blank *Cell) bool {
|
func (s *Screen) scrollDown(n, top, bot, minY, maxY int, blank *Cell) bool {
|
||||||
if n == 1 && top == minY && bot == maxY {
|
if n == 1 && top == minY && bot == maxY { //nolint:nestif
|
||||||
s.move(0, top)
|
s.move(0, top)
|
||||||
s.updatePen(blank)
|
s.updatePen(blank)
|
||||||
s.buf.WriteString(ansi.ReverseIndex)
|
s.buf.WriteString(ansi.ReverseIndex)
|
||||||
@ -236,7 +237,7 @@ func (s *Screen) scrollDown(n, top, bot, minY, maxY int, blank *Cell) bool {
|
|||||||
} else if top == minY && bot == maxY {
|
} else if top == minY && bot == maxY {
|
||||||
s.move(0, top)
|
s.move(0, top)
|
||||||
s.updatePen(blank)
|
s.updatePen(blank)
|
||||||
if s.xtermLike {
|
if s.caps.Contains(capSD) {
|
||||||
s.buf.WriteString(ansi.ScrollDown(n))
|
s.buf.WriteString(ansi.ScrollDown(n))
|
||||||
} else {
|
} else {
|
||||||
s.buf.WriteString(strings.Repeat(ansi.ReverseIndex, n))
|
s.buf.WriteString(strings.Repeat(ansi.ReverseIndex, n))
|
||||||
|
|||||||
16
vendor/github.com/charmbracelet/x/cellbuf/hashmap.go
generated
vendored
16
vendor/github.com/charmbracelet/x/cellbuf/hashmap.go
generated
vendored
@ -15,7 +15,7 @@ func hash(l Line) (h uint64) {
|
|||||||
}
|
}
|
||||||
h += (h << 5) + uint64(r)
|
h += (h << 5) + uint64(r)
|
||||||
}
|
}
|
||||||
return
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
// hashmap represents a single [Line] hash.
|
// hashmap represents a single [Line] hash.
|
||||||
@ -33,7 +33,7 @@ func (s *Screen) updateHashmap() {
|
|||||||
height := s.newbuf.Height()
|
height := s.newbuf.Height()
|
||||||
if len(s.oldhash) >= height && len(s.newhash) >= height {
|
if len(s.oldhash) >= height && len(s.newhash) >= height {
|
||||||
// rehash changed lines
|
// rehash changed lines
|
||||||
for i := 0; i < height; i++ {
|
for i := range height {
|
||||||
_, ok := s.touch[i]
|
_, ok := s.touch[i]
|
||||||
if ok {
|
if ok {
|
||||||
s.oldhash[i] = hash(s.curbuf.Line(i))
|
s.oldhash[i] = hash(s.curbuf.Line(i))
|
||||||
@ -48,14 +48,14 @@ func (s *Screen) updateHashmap() {
|
|||||||
if len(s.newhash) != height {
|
if len(s.newhash) != height {
|
||||||
s.newhash = make([]uint64, height)
|
s.newhash = make([]uint64, height)
|
||||||
}
|
}
|
||||||
for i := 0; i < height; i++ {
|
for i := range height {
|
||||||
s.oldhash[i] = hash(s.curbuf.Line(i))
|
s.oldhash[i] = hash(s.curbuf.Line(i))
|
||||||
s.newhash[i] = hash(s.newbuf.Line(i))
|
s.newhash[i] = hash(s.newbuf.Line(i))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.hashtab = make([]hashmap, height*2)
|
s.hashtab = make([]hashmap, height*2)
|
||||||
for i := 0; i < height; i++ {
|
for i := range height {
|
||||||
hashval := s.oldhash[i]
|
hashval := s.oldhash[i]
|
||||||
|
|
||||||
// Find matching hash or empty slot
|
// Find matching hash or empty slot
|
||||||
@ -71,7 +71,7 @@ func (s *Screen) updateHashmap() {
|
|||||||
s.hashtab[idx].oldcount++
|
s.hashtab[idx].oldcount++
|
||||||
s.hashtab[idx].oldindex = i
|
s.hashtab[idx].oldindex = i
|
||||||
}
|
}
|
||||||
for i := 0; i < height; i++ {
|
for i := range height {
|
||||||
hashval := s.newhash[i]
|
hashval := s.newhash[i]
|
||||||
|
|
||||||
// Find matching hash or empty slot
|
// Find matching hash or empty slot
|
||||||
@ -130,7 +130,7 @@ func (s *Screen) updateHashmap() {
|
|||||||
s.growHunks()
|
s.growHunks()
|
||||||
}
|
}
|
||||||
|
|
||||||
// scrollOldhash
|
// scrollOldhash.
|
||||||
func (s *Screen) scrollOldhash(n, top, bot int) {
|
func (s *Screen) scrollOldhash(n, top, bot int) {
|
||||||
if len(s.oldhash) == 0 {
|
if len(s.oldhash) == 0 {
|
||||||
return
|
return
|
||||||
@ -287,7 +287,7 @@ func (s *Screen) updateCost(from, to Line) (cost int) {
|
|||||||
cost++
|
cost++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return cost
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Screen) updateCostBlank(to Line) (cost int) {
|
func (s *Screen) updateCostBlank(to Line) (cost int) {
|
||||||
@ -297,5 +297,5 @@ func (s *Screen) updateCostBlank(to Line) (cost int) {
|
|||||||
cost++
|
cost++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return cost
|
||||||
}
|
}
|
||||||
|
|||||||
2
vendor/github.com/charmbracelet/x/cellbuf/link.go
generated
vendored
2
vendor/github.com/charmbracelet/x/cellbuf/link.go
generated
vendored
@ -4,7 +4,7 @@ import (
|
|||||||
"github.com/charmbracelet/colorprofile"
|
"github.com/charmbracelet/colorprofile"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Convert converts a hyperlink to respect the given color profile.
|
// ConvertLink converts a hyperlink to respect the given color profile.
|
||||||
func ConvertLink(h Link, p colorprofile.Profile) Link {
|
func ConvertLink(h Link, p colorprofile.Profile) Link {
|
||||||
if p == colorprofile.NoTTY {
|
if p == colorprofile.NoTTY {
|
||||||
return Link{}
|
return Link{}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user