forked from toolshed/abra
11
vendor/github.com/urfave/cli/v3/.gitignore
generated
vendored
11
vendor/github.com/urfave/cli/v3/.gitignore
generated
vendored
@ -1,11 +0,0 @@
|
||||
*.coverprofile
|
||||
*.exe
|
||||
*.orig
|
||||
.*envrc
|
||||
.envrc
|
||||
.idea
|
||||
/.local/
|
||||
/site/
|
||||
coverage.txt
|
||||
internal/*/built-example
|
||||
vendor
|
5
vendor/github.com/urfave/cli/v3/.golangci.yaml
generated
vendored
5
vendor/github.com/urfave/cli/v3/.golangci.yaml
generated
vendored
@ -1,5 +0,0 @@
|
||||
# https://golangci-lint.run/usage/configuration/
|
||||
linters:
|
||||
enable:
|
||||
- makezero
|
||||
- misspell
|
75
vendor/github.com/urfave/cli/v3/CODE_OF_CONDUCT.md
generated
vendored
75
vendor/github.com/urfave/cli/v3/CODE_OF_CONDUCT.md
generated
vendored
@ -1,75 +0,0 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
education, socio-economic status, nationality, personal appearance, race,
|
||||
religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting urfave-governance@googlegroups.com, a members-only group
|
||||
that is world-postable. All complaints will be reviewed and investigated and
|
||||
will result in a response that is deemed necessary and appropriate to the
|
||||
circumstances. The project team is obligated to maintain confidentiality with
|
||||
regard to the reporter of an incident. Further details of specific enforcement
|
||||
policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
21
vendor/github.com/urfave/cli/v3/LICENSE
generated
vendored
21
vendor/github.com/urfave/cli/v3/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 urfave/cli maintainers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
26
vendor/github.com/urfave/cli/v3/Makefile
generated
vendored
26
vendor/github.com/urfave/cli/v3/Makefile
generated
vendored
@ -1,26 +0,0 @@
|
||||
# NOTE: this Makefile is meant to provide a simplified entry point for humans to
|
||||
# run all of the critical steps to verify one's changes are harmonious in
|
||||
# nature. Keeping target bodies to one line each and abstaining from make magic
|
||||
# are very important so that maintainers and contributors can focus their
|
||||
# attention on files that are primarily Go.
|
||||
|
||||
GO_RUN_BUILD := go run internal/build/build.go
|
||||
|
||||
.PHONY: all
|
||||
all: generate vet test check-binary-size gfmrun
|
||||
|
||||
# NOTE: this is a special catch-all rule to run any of the commands
|
||||
# defined in internal/build/build.go with optional arguments passed
|
||||
# via GFLAGS (global flags) and FLAGS (command-specific flags), e.g.:
|
||||
#
|
||||
# $ make test GFLAGS='--packages cli'
|
||||
%:
|
||||
$(GO_RUN_BUILD) $(GFLAGS) $* $(FLAGS)
|
||||
|
||||
.PHONY: docs
|
||||
docs:
|
||||
mkdocs build
|
||||
|
||||
.PHONY: serve-docs
|
||||
serve-docs:
|
||||
mkdocs serve
|
56
vendor/github.com/urfave/cli/v3/README.md
generated
vendored
56
vendor/github.com/urfave/cli/v3/README.md
generated
vendored
@ -1,56 +0,0 @@
|
||||
# Welcome to urfave/cli
|
||||
|
||||
[![Go Reference][goreference_badge]][goreference_link]
|
||||
[![Go Report Card][goreportcard_badge]][goreportcard_link]
|
||||
[![codecov][codecov_badge]][codecov_link]
|
||||
[![Tests status][test_badge]][test_link]
|
||||
|
||||
urfave/cli is a **declarative**, simple, fast, and fun package for building
|
||||
command line tools in Go featuring:
|
||||
|
||||
- commands and subcommands with alias and prefix match support
|
||||
- flexible and permissive help system
|
||||
- dynamic shell completion for `bash`, `zsh`, `fish`, and `powershell`
|
||||
- no dependencies except Go standard library
|
||||
- input flags for simple types, slices of simple types, time, duration, and
|
||||
others
|
||||
- compound short flag support (`-a` `-b` `-c` can be shortened to `-abc`)
|
||||
- documentation generation in `man` and Markdown (supported via the
|
||||
[`urfave/cli-docs`][urfave/cli-docs] module)
|
||||
- input lookup from:
|
||||
- environment variables
|
||||
- plain text files
|
||||
- structured file formats (supported via the
|
||||
[`urfave/cli-altsrc`][urfave/cli-altsrc] module)
|
||||
|
||||
## Documentation
|
||||
|
||||
See the hosted documentation website at <https://cli.urfave.org>. Contents of
|
||||
this website are built from the [`./docs`](./docs) directory.
|
||||
|
||||
## Support
|
||||
|
||||
Check the [Q&A discussions]. If you don't find answer to your question, [create
|
||||
a new discussion].
|
||||
|
||||
If you found a bug or have a feature request, [create a new issue].
|
||||
|
||||
Please keep in mind that this project is run by unpaid volunteers.
|
||||
|
||||
### License
|
||||
|
||||
See [`LICENSE`](./LICENSE).
|
||||
|
||||
[test_badge]: https://github.com/urfave/cli/actions/workflows/test.yml/badge.svg
|
||||
[test_link]: https://github.com/urfave/cli/actions/workflows/test.yml
|
||||
[goreference_badge]: https://pkg.go.dev/badge/github.com/urfave/cli/v3.svg
|
||||
[goreference_link]: https://pkg.go.dev/github.com/urfave/cli/v3
|
||||
[goreportcard_badge]: https://goreportcard.com/badge/github.com/urfave/cli/v3
|
||||
[goreportcard_link]: https://goreportcard.com/report/github.com/urfave/cli/v3
|
||||
[codecov_badge]: https://codecov.io/gh/urfave/cli/branch/main/graph/badge.svg?token=t9YGWLh05g
|
||||
[codecov_link]: https://codecov.io/gh/urfave/cli
|
||||
[Q&A discussions]: https://github.com/urfave/cli/discussions/categories/q-a
|
||||
[create a new discussion]: https://github.com/urfave/cli/discussions/new?category=q-a
|
||||
[urfave/cli-docs]: https://github.com/urfave/cli-docs
|
||||
[urfave/cli-altsrc]: https://github.com/urfave/cli-altsrc
|
||||
[create a new issue]: https://github.com/urfave/cli/issues/new/choose
|
153
vendor/github.com/urfave/cli/v3/args.go
generated
vendored
153
vendor/github.com/urfave/cli/v3/args.go
generated
vendored
@ -1,153 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Args interface {
|
||||
// Get returns the nth argument, or else a blank string
|
||||
Get(n int) string
|
||||
// First returns the first argument, or else a blank string
|
||||
First() string
|
||||
// Tail returns the rest of the arguments (not the first one)
|
||||
// or else an empty string slice
|
||||
Tail() []string
|
||||
// Len returns the length of the wrapped slice
|
||||
Len() int
|
||||
// Present checks if there are any arguments present
|
||||
Present() bool
|
||||
// Slice returns a copy of the internal slice
|
||||
Slice() []string
|
||||
}
|
||||
|
||||
type stringSliceArgs struct {
|
||||
v []string
|
||||
}
|
||||
|
||||
func (a *stringSliceArgs) Get(n int) string {
|
||||
if len(a.v) > n {
|
||||
return a.v[n]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (a *stringSliceArgs) First() string {
|
||||
return a.Get(0)
|
||||
}
|
||||
|
||||
func (a *stringSliceArgs) Tail() []string {
|
||||
if a.Len() >= 2 {
|
||||
tail := a.v[1:]
|
||||
ret := make([]string, len(tail))
|
||||
copy(ret, tail)
|
||||
return ret
|
||||
}
|
||||
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func (a *stringSliceArgs) Len() int {
|
||||
return len(a.v)
|
||||
}
|
||||
|
||||
func (a *stringSliceArgs) Present() bool {
|
||||
return a.Len() != 0
|
||||
}
|
||||
|
||||
func (a *stringSliceArgs) Slice() []string {
|
||||
ret := make([]string, len(a.v))
|
||||
copy(ret, a.v)
|
||||
return ret
|
||||
}
|
||||
|
||||
type Argument interface {
|
||||
Parse([]string) ([]string, error)
|
||||
Usage() string
|
||||
}
|
||||
|
||||
type ArgumentBase[T any, C any, VC ValueCreator[T, C]] struct {
|
||||
Name string `json:"name"` // the name of this argument
|
||||
Value T `json:"value"` // the default value of this argument
|
||||
Destination *T `json:"-"` // the destination point for this argument
|
||||
Values *[]T `json:"-"` // all the values of this argument, only if multiple are supported
|
||||
UsageText string `json:"usageText"` // the usage text to show
|
||||
Min int `json:"minTimes"` // the min num of occurrences of this argument
|
||||
Max int `json:"maxTimes"` // the max num of occurrences of this argument, set to -1 for unlimited
|
||||
Config C `json:"config"` // config for this argument similar to Flag Config
|
||||
}
|
||||
|
||||
func (a *ArgumentBase[T, C, VC]) Usage() string {
|
||||
if a.UsageText != "" {
|
||||
return a.UsageText
|
||||
}
|
||||
|
||||
usageFormat := ""
|
||||
if a.Min == 0 {
|
||||
if a.Max == 1 {
|
||||
usageFormat = "[%[1]s]"
|
||||
} else {
|
||||
usageFormat = "[%[1]s ...]"
|
||||
}
|
||||
} else {
|
||||
usageFormat = "%[1]s [%[1]s ...]"
|
||||
}
|
||||
return fmt.Sprintf(usageFormat, a.Name)
|
||||
}
|
||||
|
||||
func (a *ArgumentBase[T, C, VC]) Parse(s []string) ([]string, error) {
|
||||
tracef("calling arg%[1] parse with args %[2]", &a.Name, s)
|
||||
if a.Max == 0 {
|
||||
fmt.Printf("WARNING args %s has max 0, not parsing argument", a.Name)
|
||||
return s, nil
|
||||
}
|
||||
if a.Max != -1 && a.Min > a.Max {
|
||||
fmt.Printf("WARNING args %s has min[%d] > max[%d], not parsing argument", a.Name, a.Min, a.Max)
|
||||
return s, nil
|
||||
}
|
||||
|
||||
count := 0
|
||||
var vc VC
|
||||
var t T
|
||||
value := vc.Create(a.Value, &t, a.Config)
|
||||
values := []T{}
|
||||
|
||||
for _, arg := range s {
|
||||
if err := value.Set(arg); err != nil {
|
||||
return s, err
|
||||
}
|
||||
values = append(values, value.Get().(T))
|
||||
count++
|
||||
if count >= a.Max && a.Max > -1 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if count < a.Min {
|
||||
return s, fmt.Errorf("sufficient count of arg %s not provided, given %d expected %d", a.Name, count, a.Min)
|
||||
}
|
||||
|
||||
if a.Values == nil {
|
||||
a.Values = &values
|
||||
} else if count > 0 {
|
||||
*a.Values = values
|
||||
}
|
||||
|
||||
if a.Max == 1 && a.Destination != nil {
|
||||
if len(values) > 0 {
|
||||
*a.Destination = values[0]
|
||||
} else {
|
||||
*a.Destination = t
|
||||
}
|
||||
}
|
||||
|
||||
return s[count:], nil
|
||||
}
|
||||
|
||||
type (
|
||||
FloatArg = ArgumentBase[float64, NoConfig, floatValue]
|
||||
IntArg = ArgumentBase[int64, IntegerConfig, intValue]
|
||||
StringArg = ArgumentBase[string, StringConfig, stringValue]
|
||||
StringMapArg = ArgumentBase[map[string]string, StringConfig, StringMap]
|
||||
TimestampArg = ArgumentBase[time.Time, TimestampConfig, timestampValue]
|
||||
UintArg = ArgumentBase[uint64, IntegerConfig, uintValue]
|
||||
)
|
35
vendor/github.com/urfave/cli/v3/autocomplete/bash_autocomplete
generated
vendored
35
vendor/github.com/urfave/cli/v3/autocomplete/bash_autocomplete
generated
vendored
@ -1,35 +0,0 @@
|
||||
#! /bin/bash
|
||||
|
||||
: ${PROG:=$(basename ${BASH_SOURCE})}
|
||||
|
||||
# Macs have bash3 for which the bash-completion package doesn't include
|
||||
# _init_completion. This is a minimal version of that function.
|
||||
_cli_init_completion() {
|
||||
COMPREPLY=()
|
||||
_get_comp_words_by_ref "$@" cur prev words cword
|
||||
}
|
||||
|
||||
_cli_bash_autocomplete() {
|
||||
if [[ "${COMP_WORDS[0]}" != "source" ]]; then
|
||||
local cur opts base words
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
if declare -F _init_completion >/dev/null 2>&1; then
|
||||
_init_completion -n "=:" || return
|
||||
else
|
||||
_cli_init_completion -n "=:" || return
|
||||
fi
|
||||
words=("${words[@]:0:$cword}")
|
||||
if [[ "$cur" == "-"* ]]; then
|
||||
requestComp="${words[*]} ${cur} --generate-shell-completion"
|
||||
else
|
||||
requestComp="${words[*]} --generate-shell-completion"
|
||||
fi
|
||||
opts=$(eval "${requestComp}" 2>/dev/null)
|
||||
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
complete -o bashdefault -o default -o nospace -F _cli_bash_autocomplete $PROG
|
||||
unset PROG
|
9
vendor/github.com/urfave/cli/v3/autocomplete/powershell_autocomplete.ps1
generated
vendored
9
vendor/github.com/urfave/cli/v3/autocomplete/powershell_autocomplete.ps1
generated
vendored
@ -1,9 +0,0 @@
|
||||
$fn = $($MyInvocation.MyCommand.Name)
|
||||
$name = $fn -replace "(.*)\.ps1$", '$1'
|
||||
Register-ArgumentCompleter -Native -CommandName $name -ScriptBlock {
|
||||
param($commandName, $wordToComplete, $cursorPosition)
|
||||
$other = "$wordToComplete --generate-shell-completion"
|
||||
Invoke-Expression $other | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
||||
}
|
||||
}
|
30
vendor/github.com/urfave/cli/v3/autocomplete/zsh_autocomplete
generated
vendored
30
vendor/github.com/urfave/cli/v3/autocomplete/zsh_autocomplete
generated
vendored
@ -1,30 +0,0 @@
|
||||
#compdef program
|
||||
compdef _program program
|
||||
|
||||
# Replace all occurrences of "program" in this file with the actual name of your
|
||||
# CLI program. We recommend using Find+Replace feature of your editor. Let's say
|
||||
# your CLI program is called "acme", then replace like so:
|
||||
# * program => acme
|
||||
# * _program => _acme
|
||||
|
||||
_program() {
|
||||
local -a opts
|
||||
local cur
|
||||
cur=${words[-1]}
|
||||
if [[ "$cur" == "-"* ]]; then
|
||||
opts=("${(@f)$(${words[@]:0:#words[@]-1} ${cur} --generate-shell-completion)}")
|
||||
else
|
||||
opts=("${(@f)$(${words[@]:0:#words[@]-1} --generate-shell-completion)}")
|
||||
fi
|
||||
|
||||
if [[ "${opts[1]}" != "" ]]; then
|
||||
_describe 'values' opts
|
||||
else
|
||||
_files
|
||||
fi
|
||||
}
|
||||
|
||||
# don't run the completion function when being source-ed or eval-ed
|
||||
if [ "$funcstack[1]" = "_program" ]; then
|
||||
_program
|
||||
fi
|
195
vendor/github.com/urfave/cli/v3/category.go
generated
vendored
195
vendor/github.com/urfave/cli/v3/category.go
generated
vendored
@ -1,195 +0,0 @@
|
||||
package cli
|
||||
|
||||
import "sort"
|
||||
|
||||
// CommandCategories interface allows for category manipulation
|
||||
type CommandCategories interface {
|
||||
// AddCommand adds a command to a category, creating a new category if necessary.
|
||||
AddCommand(category string, command *Command)
|
||||
// Categories returns a slice of categories sorted by name
|
||||
Categories() []CommandCategory
|
||||
}
|
||||
|
||||
type commandCategories []*commandCategory
|
||||
|
||||
func newCommandCategories() CommandCategories {
|
||||
ret := commandCategories([]*commandCategory{})
|
||||
return &ret
|
||||
}
|
||||
|
||||
func (c *commandCategories) Less(i, j int) bool {
|
||||
return lexicographicLess((*c)[i].Name(), (*c)[j].Name())
|
||||
}
|
||||
|
||||
func (c *commandCategories) Len() int {
|
||||
return len(*c)
|
||||
}
|
||||
|
||||
func (c *commandCategories) Swap(i, j int) {
|
||||
(*c)[i], (*c)[j] = (*c)[j], (*c)[i]
|
||||
}
|
||||
|
||||
func (c *commandCategories) AddCommand(category string, command *Command) {
|
||||
for _, commandCategory := range []*commandCategory(*c) {
|
||||
if commandCategory.name == category {
|
||||
commandCategory.commands = append(commandCategory.commands, command)
|
||||
return
|
||||
}
|
||||
}
|
||||
newVal := append(*c,
|
||||
&commandCategory{name: category, commands: []*Command{command}})
|
||||
*c = newVal
|
||||
}
|
||||
|
||||
func (c *commandCategories) Categories() []CommandCategory {
|
||||
ret := make([]CommandCategory, len(*c))
|
||||
for i, cat := range *c {
|
||||
ret[i] = cat
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// CommandCategory is a category containing commands.
|
||||
type CommandCategory interface {
|
||||
// Name returns the category name string
|
||||
Name() string
|
||||
// VisibleCommands returns a slice of the Commands with Hidden=false
|
||||
VisibleCommands() []*Command
|
||||
}
|
||||
|
||||
type commandCategory struct {
|
||||
name string
|
||||
commands []*Command
|
||||
}
|
||||
|
||||
func (c *commandCategory) Name() string {
|
||||
return c.name
|
||||
}
|
||||
|
||||
func (c *commandCategory) VisibleCommands() []*Command {
|
||||
if c.commands == nil {
|
||||
c.commands = []*Command{}
|
||||
}
|
||||
|
||||
var ret []*Command
|
||||
for _, command := range c.commands {
|
||||
if !command.Hidden {
|
||||
ret = append(ret, command)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// FlagCategories interface allows for category manipulation
|
||||
type FlagCategories interface {
|
||||
// AddFlags adds a flag to a category, creating a new category if necessary.
|
||||
AddFlag(category string, fl Flag)
|
||||
// VisibleCategories returns a slice of visible flag categories sorted by name
|
||||
VisibleCategories() []VisibleFlagCategory
|
||||
}
|
||||
|
||||
type defaultFlagCategories struct {
|
||||
m map[string]*defaultVisibleFlagCategory
|
||||
}
|
||||
|
||||
func newFlagCategories() FlagCategories {
|
||||
return &defaultFlagCategories{
|
||||
m: map[string]*defaultVisibleFlagCategory{},
|
||||
}
|
||||
}
|
||||
|
||||
func newFlagCategoriesFromFlags(fs []Flag) FlagCategories {
|
||||
fc := newFlagCategories()
|
||||
|
||||
var categorized bool
|
||||
|
||||
for _, fl := range fs {
|
||||
if cf, ok := fl.(CategorizableFlag); ok {
|
||||
visible := false
|
||||
if vf, ok := fl.(VisibleFlag); ok {
|
||||
visible = vf.IsVisible()
|
||||
}
|
||||
if cat := cf.GetCategory(); cat != "" && visible {
|
||||
fc.AddFlag(cat, fl)
|
||||
categorized = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if categorized {
|
||||
for _, fl := range fs {
|
||||
if cf, ok := fl.(CategorizableFlag); ok {
|
||||
visible := false
|
||||
if vf, ok := fl.(VisibleFlag); ok {
|
||||
visible = vf.IsVisible()
|
||||
}
|
||||
if cf.GetCategory() == "" && visible {
|
||||
fc.AddFlag("", fl)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fc
|
||||
}
|
||||
|
||||
func (f *defaultFlagCategories) AddFlag(category string, fl Flag) {
|
||||
if _, ok := f.m[category]; !ok {
|
||||
f.m[category] = &defaultVisibleFlagCategory{name: category, m: map[string]Flag{}}
|
||||
}
|
||||
|
||||
f.m[category].m[fl.String()] = fl
|
||||
}
|
||||
|
||||
func (f *defaultFlagCategories) VisibleCategories() []VisibleFlagCategory {
|
||||
catNames := []string{}
|
||||
for name := range f.m {
|
||||
catNames = append(catNames, name)
|
||||
}
|
||||
|
||||
sort.Strings(catNames)
|
||||
|
||||
ret := make([]VisibleFlagCategory, len(catNames))
|
||||
for i, name := range catNames {
|
||||
ret[i] = f.m[name]
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// VisibleFlagCategory is a category containing flags.
|
||||
type VisibleFlagCategory interface {
|
||||
// Name returns the category name string
|
||||
Name() string
|
||||
// Flags returns a slice of VisibleFlag sorted by name
|
||||
Flags() []Flag
|
||||
}
|
||||
|
||||
type defaultVisibleFlagCategory struct {
|
||||
name string
|
||||
m map[string]Flag
|
||||
}
|
||||
|
||||
func (fc *defaultVisibleFlagCategory) Name() string {
|
||||
return fc.name
|
||||
}
|
||||
|
||||
func (fc *defaultVisibleFlagCategory) Flags() []Flag {
|
||||
vfNames := []string{}
|
||||
for flName, fl := range fc.m {
|
||||
if vf, ok := fl.(VisibleFlag); ok {
|
||||
if vf.IsVisible() {
|
||||
vfNames = append(vfNames, flName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(vfNames)
|
||||
|
||||
ret := make([]Flag, len(vfNames))
|
||||
for i, flName := range vfNames {
|
||||
ret[i] = fc.m[flName]
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
60
vendor/github.com/urfave/cli/v3/cli.go
generated
vendored
60
vendor/github.com/urfave/cli/v3/cli.go
generated
vendored
@ -1,60 +0,0 @@
|
||||
// Package cli provides a minimal framework for creating and organizing command line
|
||||
// Go applications. cli is designed to be easy to understand and write, the most simple
|
||||
// cli application can be written as follows:
|
||||
//
|
||||
// func main() {
|
||||
// (&cli.Command{}).Run(context.Background(), os.Args)
|
||||
// }
|
||||
//
|
||||
// Of course this application does not do much, so let's make this an actual application:
|
||||
//
|
||||
// func main() {
|
||||
// cmd := &cli.Command{
|
||||
// Name: "greet",
|
||||
// Usage: "say a greeting",
|
||||
// Action: func(c *cli.Context) error {
|
||||
// fmt.Println("Greetings")
|
||||
// return nil
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// cmd.Run(context.Background(), os.Args)
|
||||
// }
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var isTracingOn = os.Getenv("URFAVE_CLI_TRACING") == "on"
|
||||
|
||||
func tracef(format string, a ...any) {
|
||||
if !isTracingOn {
|
||||
return
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(format, "\n") {
|
||||
format = format + "\n"
|
||||
}
|
||||
|
||||
pc, file, line, _ := runtime.Caller(1)
|
||||
cf := runtime.FuncForPC(pc)
|
||||
|
||||
fmt.Fprintf(
|
||||
os.Stderr,
|
||||
strings.Join([]string{
|
||||
"## URFAVE CLI TRACE ",
|
||||
file,
|
||||
":",
|
||||
fmt.Sprintf("%v", line),
|
||||
" ",
|
||||
fmt.Sprintf("(%s)", cf.Name()),
|
||||
" ",
|
||||
format,
|
||||
}, ""),
|
||||
a...,
|
||||
)
|
||||
}
|
1296
vendor/github.com/urfave/cli/v3/command.go
generated
vendored
1296
vendor/github.com/urfave/cli/v3/command.go
generated
vendored
File diff suppressed because it is too large
Load Diff
68
vendor/github.com/urfave/cli/v3/completion.go
generated
vendored
68
vendor/github.com/urfave/cli/v3/completion.go
generated
vendored
@ -1,68 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
const (
|
||||
completionCommandName = "generate-completion"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed autocomplete
|
||||
autoCompleteFS embed.FS
|
||||
|
||||
shellCompletions = map[string]renderCompletion{
|
||||
"bash": getCompletion("autocomplete/bash_autocomplete"),
|
||||
"ps": getCompletion("autocomplete/powershell_autocomplete.ps1"),
|
||||
"zsh": getCompletion("autocomplete/zsh_autocomplete"),
|
||||
"fish": func(c *Command) (string, error) {
|
||||
return c.ToFishCompletion()
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
type renderCompletion func(*Command) (string, error)
|
||||
|
||||
func getCompletion(s string) renderCompletion {
|
||||
return func(c *Command) (string, error) {
|
||||
b, err := autoCompleteFS.ReadFile(s)
|
||||
return string(b), err
|
||||
}
|
||||
}
|
||||
|
||||
func buildCompletionCommand() *Command {
|
||||
return &Command{
|
||||
Name: completionCommandName,
|
||||
Hidden: true,
|
||||
Action: completionCommandAction,
|
||||
}
|
||||
}
|
||||
|
||||
func completionCommandAction(ctx context.Context, cmd *Command) error {
|
||||
var shells []string
|
||||
for k := range shellCompletions {
|
||||
shells = append(shells, k)
|
||||
}
|
||||
|
||||
sort.Strings(shells)
|
||||
|
||||
if cmd.Args().Len() == 0 {
|
||||
return Exit(fmt.Sprintf("no shell provided for completion command. available shells are %+v", shells), 1)
|
||||
}
|
||||
s := cmd.Args().First()
|
||||
|
||||
if rc, ok := shellCompletions[s]; !ok {
|
||||
return Exit(fmt.Sprintf("unknown shell %s, available shells are %+v", s, shells), 1)
|
||||
} else if c, err := rc(cmd); err != nil {
|
||||
return Exit(err, 1)
|
||||
} else {
|
||||
if _, err = cmd.Writer.Write([]byte(c)); err != nil {
|
||||
return Exit(err, 1)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
209
vendor/github.com/urfave/cli/v3/errors.go
generated
vendored
209
vendor/github.com/urfave/cli/v3/errors.go
generated
vendored
@ -1,209 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// OsExiter is the function used when the app exits. If not set defaults to os.Exit.
|
||||
var OsExiter = os.Exit
|
||||
|
||||
// ErrWriter is used to write errors to the user. This can be anything
|
||||
// implementing the io.Writer interface and defaults to os.Stderr.
|
||||
var ErrWriter io.Writer = os.Stderr
|
||||
|
||||
// MultiError is an error that wraps multiple errors.
|
||||
type MultiError interface {
|
||||
error
|
||||
Errors() []error
|
||||
}
|
||||
|
||||
// newMultiError creates a new MultiError. Pass in one or more errors.
|
||||
func newMultiError(err ...error) MultiError {
|
||||
ret := multiError(err)
|
||||
return &ret
|
||||
}
|
||||
|
||||
type multiError []error
|
||||
|
||||
// Error implements the error interface.
|
||||
func (m *multiError) Error() string {
|
||||
errs := make([]string, len(*m))
|
||||
for i, err := range *m {
|
||||
errs[i] = err.Error()
|
||||
}
|
||||
|
||||
return strings.Join(errs, "\n")
|
||||
}
|
||||
|
||||
// Errors returns a copy of the errors slice
|
||||
func (m *multiError) Errors() []error {
|
||||
errs := make([]error, len(*m))
|
||||
copy(errs, *m)
|
||||
return errs
|
||||
}
|
||||
|
||||
type requiredFlagsErr interface {
|
||||
error
|
||||
getMissingFlags() []string
|
||||
}
|
||||
|
||||
type errRequiredFlags struct {
|
||||
missingFlags []string
|
||||
}
|
||||
|
||||
func (e *errRequiredFlags) Error() string {
|
||||
if len(e.missingFlags) == 1 {
|
||||
return fmt.Sprintf("Required flag %q not set", e.missingFlags[0])
|
||||
}
|
||||
joinedMissingFlags := strings.Join(e.missingFlags, ", ")
|
||||
return fmt.Sprintf("Required flags %q not set", joinedMissingFlags)
|
||||
}
|
||||
|
||||
func (e *errRequiredFlags) getMissingFlags() []string {
|
||||
return e.missingFlags
|
||||
}
|
||||
|
||||
type mutuallyExclusiveGroup struct {
|
||||
flag1Name string
|
||||
flag2Name string
|
||||
}
|
||||
|
||||
func (e *mutuallyExclusiveGroup) Error() string {
|
||||
return fmt.Sprintf("option %s cannot be set along with option %s", e.flag1Name, e.flag2Name)
|
||||
}
|
||||
|
||||
type mutuallyExclusiveGroupRequiredFlag struct {
|
||||
flags *MutuallyExclusiveFlags
|
||||
}
|
||||
|
||||
func (e *mutuallyExclusiveGroupRequiredFlag) Error() string {
|
||||
var missingFlags []string
|
||||
for _, grpf := range e.flags.Flags {
|
||||
var grpString []string
|
||||
for _, f := range grpf {
|
||||
grpString = append(grpString, f.Names()...)
|
||||
}
|
||||
if len(e.flags.Flags) == 1 {
|
||||
err := errRequiredFlags{
|
||||
missingFlags: grpString,
|
||||
}
|
||||
return err.Error()
|
||||
}
|
||||
missingFlags = append(missingFlags, strings.Join(grpString, " "))
|
||||
}
|
||||
|
||||
return fmt.Sprintf("one of these flags needs to be provided: %s", strings.Join(missingFlags, ", "))
|
||||
}
|
||||
|
||||
// ErrorFormatter is the interface that will suitably format the error output
|
||||
type ErrorFormatter interface {
|
||||
Format(s fmt.State, verb rune)
|
||||
}
|
||||
|
||||
// ExitCoder is the interface checked by `App` and `Command` for a custom exit
|
||||
// code
|
||||
type ExitCoder interface {
|
||||
error
|
||||
ExitCode() int
|
||||
}
|
||||
|
||||
type exitError struct {
|
||||
exitCode int
|
||||
err error
|
||||
}
|
||||
|
||||
// Exit wraps a message and exit code into an error, which by default is
|
||||
// handled with a call to os.Exit during default error handling.
|
||||
//
|
||||
// This is the simplest way to trigger a non-zero exit code for an App without
|
||||
// having to call os.Exit manually. During testing, this behavior can be avoided
|
||||
// by overriding the ExitErrHandler function on an App or the package-global
|
||||
// OsExiter function.
|
||||
func Exit(message interface{}, exitCode int) ExitCoder {
|
||||
var err error
|
||||
|
||||
switch e := message.(type) {
|
||||
case ErrorFormatter:
|
||||
err = fmt.Errorf("%+v", message)
|
||||
case error:
|
||||
err = e
|
||||
default:
|
||||
err = fmt.Errorf("%+v", message)
|
||||
}
|
||||
|
||||
return &exitError{
|
||||
err: err,
|
||||
exitCode: exitCode,
|
||||
}
|
||||
}
|
||||
|
||||
func (ee *exitError) Error() string {
|
||||
return ee.err.Error()
|
||||
}
|
||||
|
||||
func (ee *exitError) ExitCode() int {
|
||||
return ee.exitCode
|
||||
}
|
||||
|
||||
func (ee *exitError) Unwrap() error {
|
||||
return ee.err
|
||||
}
|
||||
|
||||
// HandleExitCoder handles errors implementing ExitCoder by printing their
|
||||
// message and calling OsExiter with the given exit code.
|
||||
//
|
||||
// If the given error instead implements MultiError, each error will be checked
|
||||
// for the ExitCoder interface, and OsExiter will be called with the last exit
|
||||
// code found, or exit code 1 if no ExitCoder is found.
|
||||
//
|
||||
// This function is the default error-handling behavior for an App.
|
||||
func HandleExitCoder(err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if exitErr, ok := err.(ExitCoder); ok {
|
||||
if err.Error() != "" {
|
||||
if _, ok := exitErr.(ErrorFormatter); ok {
|
||||
_, _ = fmt.Fprintf(ErrWriter, "%+v\n", err)
|
||||
} else {
|
||||
_, _ = fmt.Fprintln(ErrWriter, err)
|
||||
}
|
||||
}
|
||||
OsExiter(exitErr.ExitCode())
|
||||
return
|
||||
}
|
||||
|
||||
if multiErr, ok := err.(MultiError); ok {
|
||||
code := handleMultiError(multiErr)
|
||||
OsExiter(code)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func handleMultiError(multiErr MultiError) int {
|
||||
code := 1
|
||||
for _, merr := range multiErr.Errors() {
|
||||
if multiErr2, ok := merr.(MultiError); ok {
|
||||
code = handleMultiError(multiErr2)
|
||||
} else if merr != nil {
|
||||
fmt.Fprintln(ErrWriter, merr)
|
||||
if exitErr, ok := merr.(ExitCoder); ok {
|
||||
code = exitErr.ExitCode()
|
||||
}
|
||||
}
|
||||
}
|
||||
return code
|
||||
}
|
||||
|
||||
type typeError[T any] struct {
|
||||
other any
|
||||
}
|
||||
|
||||
func (te *typeError[T]) Error() string {
|
||||
var t T
|
||||
return fmt.Sprintf("Expected type %T got instead %T", t, te.other)
|
||||
}
|
183
vendor/github.com/urfave/cli/v3/fish.go
generated
vendored
183
vendor/github.com/urfave/cli/v3/fish.go
generated
vendored
@ -1,183 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
// ToFishCompletion creates a fish completion string for the `*App`
|
||||
// The function errors if either parsing or writing of the string fails.
|
||||
func (cmd *Command) ToFishCompletion() (string, error) {
|
||||
var w bytes.Buffer
|
||||
if err := cmd.writeFishCompletionTemplate(&w); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return w.String(), nil
|
||||
}
|
||||
|
||||
type fishCommandCompletionTemplate struct {
|
||||
Command *Command
|
||||
Completions []string
|
||||
AllCommands []string
|
||||
}
|
||||
|
||||
func (cmd *Command) writeFishCompletionTemplate(w io.Writer) error {
|
||||
const name = "cli"
|
||||
t, err := template.New(name).Parse(FishCompletionTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
allCommands := []string{}
|
||||
|
||||
// Add global flags
|
||||
completions := cmd.prepareFishFlags(cmd.VisibleFlags(), allCommands)
|
||||
|
||||
// Add help flag
|
||||
if !cmd.HideHelp {
|
||||
completions = append(
|
||||
completions,
|
||||
cmd.prepareFishFlags([]Flag{HelpFlag}, allCommands)...,
|
||||
)
|
||||
}
|
||||
|
||||
// Add version flag
|
||||
if !cmd.HideVersion {
|
||||
completions = append(
|
||||
completions,
|
||||
cmd.prepareFishFlags([]Flag{VersionFlag}, allCommands)...,
|
||||
)
|
||||
}
|
||||
|
||||
// Add commands and their flags
|
||||
completions = append(
|
||||
completions,
|
||||
cmd.prepareFishCommands(cmd.VisibleCommands(), &allCommands, []string{})...,
|
||||
)
|
||||
|
||||
return t.ExecuteTemplate(w, name, &fishCommandCompletionTemplate{
|
||||
Command: cmd,
|
||||
Completions: completions,
|
||||
AllCommands: allCommands,
|
||||
})
|
||||
}
|
||||
|
||||
func (cmd *Command) prepareFishCommands(commands []*Command, allCommands *[]string, previousCommands []string) []string {
|
||||
completions := []string{}
|
||||
for _, command := range commands {
|
||||
if command.Hidden {
|
||||
continue
|
||||
}
|
||||
|
||||
var completion strings.Builder
|
||||
completion.WriteString(fmt.Sprintf(
|
||||
"complete -r -c %s -n '%s' -a '%s'",
|
||||
cmd.Name,
|
||||
cmd.fishSubcommandHelper(previousCommands),
|
||||
strings.Join(command.Names(), " "),
|
||||
))
|
||||
|
||||
if command.Usage != "" {
|
||||
completion.WriteString(fmt.Sprintf(" -d '%s'",
|
||||
escapeSingleQuotes(command.Usage)))
|
||||
}
|
||||
|
||||
if !command.HideHelp {
|
||||
completions = append(
|
||||
completions,
|
||||
cmd.prepareFishFlags([]Flag{HelpFlag}, command.Names())...,
|
||||
)
|
||||
}
|
||||
|
||||
*allCommands = append(*allCommands, command.Names()...)
|
||||
completions = append(completions, completion.String())
|
||||
completions = append(
|
||||
completions,
|
||||
cmd.prepareFishFlags(command.VisibleFlags(), command.Names())...,
|
||||
)
|
||||
|
||||
// recursively iterate subcommands
|
||||
if len(command.Commands) > 0 {
|
||||
completions = append(
|
||||
completions,
|
||||
cmd.prepareFishCommands(
|
||||
command.Commands, allCommands, command.Names(),
|
||||
)...,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
|
||||
func (cmd *Command) prepareFishFlags(flags []Flag, previousCommands []string) []string {
|
||||
completions := []string{}
|
||||
for _, f := range flags {
|
||||
completion := &strings.Builder{}
|
||||
completion.WriteString(fmt.Sprintf(
|
||||
"complete -c %s -n '%s'",
|
||||
cmd.Name,
|
||||
cmd.fishSubcommandHelper(previousCommands),
|
||||
))
|
||||
|
||||
fishAddFileFlag(f, completion)
|
||||
|
||||
for idx, opt := range f.Names() {
|
||||
if idx == 0 {
|
||||
completion.WriteString(fmt.Sprintf(
|
||||
" -l %s", strings.TrimSpace(opt),
|
||||
))
|
||||
} else {
|
||||
completion.WriteString(fmt.Sprintf(
|
||||
" -s %s", strings.TrimSpace(opt),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
if flag, ok := f.(DocGenerationFlag); ok {
|
||||
if flag.TakesValue() {
|
||||
completion.WriteString(" -r")
|
||||
}
|
||||
|
||||
if flag.GetUsage() != "" {
|
||||
completion.WriteString(fmt.Sprintf(" -d '%s'",
|
||||
escapeSingleQuotes(flag.GetUsage())))
|
||||
}
|
||||
}
|
||||
|
||||
completions = append(completions, completion.String())
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
|
||||
func fishAddFileFlag(flag Flag, completion *strings.Builder) {
|
||||
switch f := flag.(type) {
|
||||
case *StringFlag:
|
||||
if f.TakesFile {
|
||||
return
|
||||
}
|
||||
case *StringSliceFlag:
|
||||
if f.TakesFile {
|
||||
return
|
||||
}
|
||||
}
|
||||
completion.WriteString(" -f")
|
||||
}
|
||||
|
||||
func (cmd *Command) fishSubcommandHelper(allCommands []string) string {
|
||||
fishHelper := fmt.Sprintf("__fish_%s_no_subcommand", cmd.Name)
|
||||
if len(allCommands) > 0 {
|
||||
fishHelper = fmt.Sprintf(
|
||||
"__fish_seen_subcommand_from %s",
|
||||
strings.Join(allCommands, " "),
|
||||
)
|
||||
}
|
||||
return fishHelper
|
||||
}
|
||||
|
||||
func escapeSingleQuotes(input string) string {
|
||||
return strings.Replace(input, `'`, `\'`, -1)
|
||||
}
|
355
vendor/github.com/urfave/cli/v3/flag.go
generated
vendored
355
vendor/github.com/urfave/cli/v3/flag.go
generated
vendored
@ -1,355 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const defaultPlaceholder = "value"
|
||||
|
||||
var (
|
||||
defaultSliceFlagSeparator = ","
|
||||
defaultMapFlagKeyValueSeparator = "="
|
||||
disableSliceFlagSeparator = false
|
||||
)
|
||||
|
||||
var (
|
||||
slPfx = fmt.Sprintf("sl:::%d:::", time.Now().UTC().UnixNano())
|
||||
|
||||
commaWhitespace = regexp.MustCompile("[, ]+.*")
|
||||
)
|
||||
|
||||
// GenerateShellCompletionFlag enables shell completion
|
||||
var GenerateShellCompletionFlag Flag = &BoolFlag{
|
||||
Name: "generate-shell-completion",
|
||||
Hidden: true,
|
||||
}
|
||||
|
||||
// VersionFlag prints the version for the application
|
||||
var VersionFlag Flag = &BoolFlag{
|
||||
Name: "version",
|
||||
Aliases: []string{"v"},
|
||||
Usage: "print the version",
|
||||
HideDefault: true,
|
||||
Local: true,
|
||||
}
|
||||
|
||||
// HelpFlag prints the help for all commands and subcommands.
|
||||
// Set to nil to disable the flag. The subcommand
|
||||
// will still be added unless HideHelp or HideHelpCommand is set to true.
|
||||
var HelpFlag Flag = &BoolFlag{
|
||||
Name: "help",
|
||||
Aliases: []string{"h"},
|
||||
Usage: "show help",
|
||||
HideDefault: true,
|
||||
Local: true,
|
||||
}
|
||||
|
||||
// FlagStringer converts a flag definition to a string. This is used by help
|
||||
// to display a flag.
|
||||
var FlagStringer FlagStringFunc = stringifyFlag
|
||||
|
||||
// Serializer is used to circumvent the limitations of flag.FlagSet.Set
|
||||
type Serializer interface {
|
||||
Serialize() string
|
||||
}
|
||||
|
||||
// FlagNamePrefixer converts a full flag name and its placeholder into the help
|
||||
// message flag prefix. This is used by the default FlagStringer.
|
||||
var FlagNamePrefixer FlagNamePrefixFunc = prefixedNames
|
||||
|
||||
// FlagEnvHinter annotates flag help message with the environment variable
|
||||
// details. This is used by the default FlagStringer.
|
||||
var FlagEnvHinter FlagEnvHintFunc = withEnvHint
|
||||
|
||||
// FlagFileHinter annotates flag help message with the environment variable
|
||||
// details. This is used by the default FlagStringer.
|
||||
var FlagFileHinter FlagFileHintFunc = withFileHint
|
||||
|
||||
// FlagsByName is a slice of Flag.
|
||||
type FlagsByName []Flag
|
||||
|
||||
func (f FlagsByName) Len() int {
|
||||
return len(f)
|
||||
}
|
||||
|
||||
func (f FlagsByName) Less(i, j int) bool {
|
||||
if len(f[j].Names()) == 0 {
|
||||
return false
|
||||
} else if len(f[i].Names()) == 0 {
|
||||
return true
|
||||
}
|
||||
return lexicographicLess(f[i].Names()[0], f[j].Names()[0])
|
||||
}
|
||||
|
||||
func (f FlagsByName) Swap(i, j int) {
|
||||
f[i], f[j] = f[j], f[i]
|
||||
}
|
||||
|
||||
// ActionableFlag is an interface that wraps Flag interface and RunAction operation.
|
||||
type ActionableFlag interface {
|
||||
RunAction(context.Context, *Command) error
|
||||
}
|
||||
|
||||
// Flag is a common interface related to parsing flags in cli.
|
||||
// For more advanced flag parsing techniques, it is recommended that
|
||||
// this interface be implemented.
|
||||
type Flag interface {
|
||||
fmt.Stringer
|
||||
|
||||
// Apply Flag settings to the given flag set
|
||||
Apply(*flag.FlagSet) error
|
||||
|
||||
// All possible names for this flag
|
||||
Names() []string
|
||||
|
||||
// Whether the flag has been set or not
|
||||
IsSet() bool
|
||||
}
|
||||
|
||||
// RequiredFlag is an interface that allows us to mark flags as required
|
||||
// it allows flags required flags to be backwards compatible with the Flag interface
|
||||
type RequiredFlag interface {
|
||||
// whether the flag is a required flag or not
|
||||
IsRequired() bool
|
||||
}
|
||||
|
||||
// DocGenerationFlag is an interface that allows documentation generation for the flag
|
||||
type DocGenerationFlag interface {
|
||||
// TakesValue returns true if the flag takes a value, otherwise false
|
||||
TakesValue() bool
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
GetUsage() string
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
GetValue() string
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
GetDefaultText() string
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
GetEnvVars() []string
|
||||
|
||||
// IsDefaultVisible returns whether the default value should be shown in
|
||||
// help text
|
||||
IsDefaultVisible() bool
|
||||
}
|
||||
|
||||
// DocGenerationMultiValueFlag extends DocGenerationFlag for slice/map based flags.
|
||||
type DocGenerationMultiValueFlag interface {
|
||||
DocGenerationFlag
|
||||
|
||||
// IsMultiValueFlag returns true for flags that can be given multiple times.
|
||||
IsMultiValueFlag() bool
|
||||
}
|
||||
|
||||
// Countable is an interface to enable detection of flag values which support
|
||||
// repetitive flags
|
||||
type Countable interface {
|
||||
Count() int
|
||||
}
|
||||
|
||||
// VisibleFlag is an interface that allows to check if a flag is visible
|
||||
type VisibleFlag interface {
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
IsVisible() bool
|
||||
}
|
||||
|
||||
// CategorizableFlag is an interface that allows us to potentially
|
||||
// use a flag in a categorized representation.
|
||||
type CategorizableFlag interface {
|
||||
// Returns the category of the flag
|
||||
GetCategory() string
|
||||
|
||||
// Sets the category of the flag
|
||||
SetCategory(string)
|
||||
}
|
||||
|
||||
// LocalFlag is an interface to enable detection of flags which are local
|
||||
// to current command
|
||||
type LocalFlag interface {
|
||||
IsLocal() bool
|
||||
}
|
||||
|
||||
// IsDefaultVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *FlagBase[T, C, V]) IsDefaultVisible() bool {
|
||||
return !f.HideDefault
|
||||
}
|
||||
|
||||
func newFlagSet(name string, flags []Flag) (*flag.FlagSet, error) {
|
||||
set := flag.NewFlagSet(name, flag.ContinueOnError)
|
||||
|
||||
for _, f := range flags {
|
||||
if err := f.Apply(set); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
set.SetOutput(io.Discard)
|
||||
|
||||
return set, nil
|
||||
}
|
||||
|
||||
func visibleFlags(fl []Flag) []Flag {
|
||||
var visible []Flag
|
||||
for _, f := range fl {
|
||||
if vf, ok := f.(VisibleFlag); ok && vf.IsVisible() {
|
||||
visible = append(visible, f)
|
||||
}
|
||||
}
|
||||
return visible
|
||||
}
|
||||
|
||||
func prefixFor(name string) (prefix string) {
|
||||
if len(name) == 1 {
|
||||
prefix = "-"
|
||||
} else {
|
||||
prefix = "--"
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Returns the placeholder, if any, and the unquoted usage string.
|
||||
func unquoteUsage(usage string) (string, string) {
|
||||
for i := 0; i < len(usage); i++ {
|
||||
if usage[i] == '`' {
|
||||
for j := i + 1; j < len(usage); j++ {
|
||||
if usage[j] == '`' {
|
||||
name := usage[i+1 : j]
|
||||
usage = usage[:i] + name + usage[j+1:]
|
||||
return name, usage
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return "", usage
|
||||
}
|
||||
|
||||
func prefixedNames(names []string, placeholder string) string {
|
||||
var prefixed string
|
||||
for i, name := range names {
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
prefixed += prefixFor(name) + name
|
||||
if placeholder != "" {
|
||||
prefixed += " " + placeholder
|
||||
}
|
||||
if i < len(names)-1 {
|
||||
prefixed += ", "
|
||||
}
|
||||
}
|
||||
return prefixed
|
||||
}
|
||||
|
||||
func envFormat(envVars []string, prefix, sep, suffix string) string {
|
||||
if len(envVars) > 0 {
|
||||
return fmt.Sprintf(" [%s%s%s]", prefix, strings.Join(envVars, sep), suffix)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func defaultEnvFormat(envVars []string) string {
|
||||
return envFormat(envVars, "$", ", $", "")
|
||||
}
|
||||
|
||||
func withEnvHint(envVars []string, str string) string {
|
||||
envText := ""
|
||||
if runtime.GOOS != "windows" || os.Getenv("PSHOME") != "" {
|
||||
envText = defaultEnvFormat(envVars)
|
||||
} else {
|
||||
envText = envFormat(envVars, "%", "%, %", "%")
|
||||
}
|
||||
return str + envText
|
||||
}
|
||||
|
||||
func FlagNames(name string, aliases []string) []string {
|
||||
var ret []string
|
||||
|
||||
for _, part := range append([]string{name}, aliases...) {
|
||||
// v1 -> v2 migration warning zone:
|
||||
// Strip off anything after the first found comma or space, which
|
||||
// *hopefully* makes it a tiny bit more obvious that unexpected behavior is
|
||||
// caused by using the v1 form of stringly typed "Name".
|
||||
ret = append(ret, commaWhitespace.ReplaceAllString(part, ""))
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func withFileHint(filePath, str string) string {
|
||||
fileText := ""
|
||||
if filePath != "" {
|
||||
fileText = fmt.Sprintf(" [%s]", filePath)
|
||||
}
|
||||
return str + fileText
|
||||
}
|
||||
|
||||
func formatDefault(format string) string {
|
||||
return " (default: " + format + ")"
|
||||
}
|
||||
|
||||
func stringifyFlag(f Flag) string {
|
||||
// enforce DocGeneration interface on flags to avoid reflection
|
||||
df, ok := f.(DocGenerationFlag)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
placeholder, usage := unquoteUsage(df.GetUsage())
|
||||
needsPlaceholder := df.TakesValue()
|
||||
|
||||
if needsPlaceholder && placeholder == "" {
|
||||
placeholder = defaultPlaceholder
|
||||
}
|
||||
|
||||
defaultValueString := ""
|
||||
|
||||
// don't print default text for required flags
|
||||
if rf, ok := f.(RequiredFlag); !ok || !rf.IsRequired() {
|
||||
isVisible := df.IsDefaultVisible()
|
||||
if s := df.GetDefaultText(); isVisible && s != "" {
|
||||
defaultValueString = fmt.Sprintf(formatDefault("%s"), s)
|
||||
}
|
||||
}
|
||||
|
||||
usageWithDefault := strings.TrimSpace(usage + defaultValueString)
|
||||
|
||||
pn := prefixedNames(f.Names(), placeholder)
|
||||
sliceFlag, ok := f.(DocGenerationMultiValueFlag)
|
||||
if ok && sliceFlag.IsMultiValueFlag() {
|
||||
pn = pn + " [ " + pn + " ]"
|
||||
}
|
||||
|
||||
return withEnvHint(df.GetEnvVars(), fmt.Sprintf("%s\t%s", pn, usageWithDefault))
|
||||
}
|
||||
|
||||
func hasFlag(flags []Flag, fl Flag) bool {
|
||||
for _, existing := range flags {
|
||||
if fl == existing {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func flagSplitMultiValues(val string) []string {
|
||||
if disableSliceFlagSeparator {
|
||||
return []string{val}
|
||||
}
|
||||
|
||||
return strings.Split(val, defaultSliceFlagSeparator)
|
||||
}
|
87
vendor/github.com/urfave/cli/v3/flag_bool.go
generated
vendored
87
vendor/github.com/urfave/cli/v3/flag_bool.go
generated
vendored
@ -1,87 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type BoolFlag = FlagBase[bool, BoolConfig, boolValue]
|
||||
|
||||
// BoolConfig defines the configuration for bool flags
|
||||
type BoolConfig struct {
|
||||
Count *int
|
||||
}
|
||||
|
||||
// boolValue needs to implement the boolFlag internal interface in flag
|
||||
// to be able to capture bool fields and values
|
||||
//
|
||||
// type boolFlag interface {
|
||||
// Value
|
||||
// IsBoolFlag() bool
|
||||
// }
|
||||
type boolValue struct {
|
||||
destination *bool
|
||||
count *int
|
||||
}
|
||||
|
||||
func (cmd *Command) Bool(name string) bool {
|
||||
if v, ok := cmd.Value(name).(bool); ok {
|
||||
tracef("bool available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("bool NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return false
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the ValueCreator interface
|
||||
|
||||
// Create creates the bool value
|
||||
func (b boolValue) Create(val bool, p *bool, c BoolConfig) Value {
|
||||
*p = val
|
||||
if c.Count == nil {
|
||||
c.Count = new(int)
|
||||
}
|
||||
return &boolValue{
|
||||
destination: p,
|
||||
count: c.Count,
|
||||
}
|
||||
}
|
||||
|
||||
// ToString formats the bool value
|
||||
func (b boolValue) ToString(value bool) string {
|
||||
return strconv.FormatBool(value)
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the flag.Value interface
|
||||
|
||||
func (b *boolValue) Set(s string) error {
|
||||
v, err := strconv.ParseBool(s)
|
||||
if err != nil {
|
||||
err = errors.New("parse error")
|
||||
return err
|
||||
}
|
||||
*b.destination = v
|
||||
if b.count != nil {
|
||||
*b.count = *b.count + 1
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *boolValue) Get() interface{} { return *b.destination }
|
||||
|
||||
func (b *boolValue) String() string {
|
||||
if b.destination != nil {
|
||||
return strconv.FormatBool(*b.destination)
|
||||
}
|
||||
return strconv.FormatBool(false)
|
||||
}
|
||||
|
||||
func (b *boolValue) IsBoolFlag() bool { return true }
|
||||
|
||||
func (b *boolValue) Count() int {
|
||||
if b.count != nil {
|
||||
return *b.count
|
||||
}
|
||||
return 0
|
||||
}
|
194
vendor/github.com/urfave/cli/v3/flag_bool_with_inverse.go
generated
vendored
194
vendor/github.com/urfave/cli/v3/flag_bool_with_inverse.go
generated
vendored
@ -1,194 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var DefaultInverseBoolPrefix = "no-"
|
||||
|
||||
type BoolWithInverseFlag struct {
|
||||
// The BoolFlag which the positive and negative flags are generated from
|
||||
*BoolFlag
|
||||
|
||||
// The prefix used to indicate a negative value
|
||||
// Default: `env` becomes `no-env`
|
||||
InversePrefix string
|
||||
|
||||
positiveFlag *BoolFlag
|
||||
negativeFlag *BoolFlag
|
||||
|
||||
// pointers obtained from the embedded bool flag
|
||||
posDest *bool
|
||||
posCount *int
|
||||
|
||||
negDest *bool
|
||||
}
|
||||
|
||||
func (parent *BoolWithInverseFlag) Flags() []Flag {
|
||||
return []Flag{parent.positiveFlag, parent.negativeFlag}
|
||||
}
|
||||
|
||||
func (parent *BoolWithInverseFlag) IsSet() bool {
|
||||
return (*parent.posCount > 0) || (parent.positiveFlag.IsSet() || parent.negativeFlag.IsSet())
|
||||
}
|
||||
|
||||
func (parent *BoolWithInverseFlag) Value() bool {
|
||||
return *parent.posDest
|
||||
}
|
||||
|
||||
func (parent *BoolWithInverseFlag) RunAction(ctx context.Context, cmd *Command) error {
|
||||
if *parent.negDest && *parent.posDest {
|
||||
return fmt.Errorf("cannot set both flags `--%s` and `--%s`", parent.positiveFlag.Name, parent.negativeFlag.Name)
|
||||
}
|
||||
|
||||
if *parent.negDest {
|
||||
err := cmd.Set(parent.positiveFlag.Name, "false")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if parent.BoolFlag.Action != nil {
|
||||
return parent.BoolFlag.Action(ctx, cmd, parent.Value())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Initialize creates a new BoolFlag that has an inverse flag
|
||||
//
|
||||
// consider a bool flag `--env`, there is no way to set it to false
|
||||
// this function allows you to set `--env` or `--no-env` and in the command action
|
||||
// it can be determined that BoolWithInverseFlag.IsSet().
|
||||
func (parent *BoolWithInverseFlag) initialize() {
|
||||
child := parent.BoolFlag
|
||||
|
||||
parent.negDest = new(bool)
|
||||
if child.Destination != nil {
|
||||
parent.posDest = child.Destination
|
||||
} else {
|
||||
parent.posDest = new(bool)
|
||||
}
|
||||
|
||||
if child.Config.Count != nil {
|
||||
parent.posCount = child.Config.Count
|
||||
} else {
|
||||
parent.posCount = new(int)
|
||||
}
|
||||
|
||||
parent.positiveFlag = child
|
||||
parent.positiveFlag.Destination = parent.posDest
|
||||
parent.positiveFlag.Config.Count = parent.posCount
|
||||
|
||||
parent.negativeFlag = &BoolFlag{
|
||||
Category: child.Category,
|
||||
DefaultText: child.DefaultText,
|
||||
Sources: NewValueSourceChain(child.Sources.Chain...),
|
||||
Usage: child.Usage,
|
||||
Required: child.Required,
|
||||
Hidden: child.Hidden,
|
||||
Local: child.Local,
|
||||
Value: child.Value,
|
||||
Destination: parent.negDest,
|
||||
TakesFile: child.TakesFile,
|
||||
OnlyOnce: child.OnlyOnce,
|
||||
hasBeenSet: child.hasBeenSet,
|
||||
applied: child.applied,
|
||||
creator: boolValue{},
|
||||
value: child.value,
|
||||
}
|
||||
|
||||
// Set inverse names ex: --env => --no-env
|
||||
parent.negativeFlag.Name = parent.inverseName()
|
||||
parent.negativeFlag.Aliases = parent.inverseAliases()
|
||||
|
||||
if len(child.Sources.EnvKeys()) > 0 {
|
||||
sources := []ValueSource{}
|
||||
|
||||
for _, envVar := range child.GetEnvVars() {
|
||||
sources = append(sources, &envVarValueSource{Key: strings.ToUpper(parent.InversePrefix) + envVar})
|
||||
}
|
||||
parent.negativeFlag.Sources = NewValueSourceChain(sources...)
|
||||
}
|
||||
}
|
||||
|
||||
func (parent *BoolWithInverseFlag) inverseName() string {
|
||||
if parent.InversePrefix == "" {
|
||||
parent.InversePrefix = DefaultInverseBoolPrefix
|
||||
}
|
||||
|
||||
return parent.InversePrefix + parent.BoolFlag.Name
|
||||
}
|
||||
|
||||
func (parent *BoolWithInverseFlag) inversePrefix() string {
|
||||
if parent.InversePrefix == "" {
|
||||
return DefaultInverseBoolPrefix
|
||||
}
|
||||
|
||||
return parent.InversePrefix
|
||||
}
|
||||
|
||||
func (parent *BoolWithInverseFlag) inverseAliases() (aliases []string) {
|
||||
if len(parent.BoolFlag.Aliases) > 0 {
|
||||
aliases = make([]string, len(parent.BoolFlag.Aliases))
|
||||
for idx, alias := range parent.BoolFlag.Aliases {
|
||||
aliases[idx] = parent.InversePrefix + alias
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (parent *BoolWithInverseFlag) Apply(set *flag.FlagSet) error {
|
||||
if parent.positiveFlag == nil {
|
||||
parent.initialize()
|
||||
}
|
||||
|
||||
if err := parent.positiveFlag.Apply(set); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := parent.negativeFlag.Apply(set); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (parent *BoolWithInverseFlag) Names() []string {
|
||||
// Get Names when flag has not been initialized
|
||||
if parent.positiveFlag == nil {
|
||||
return append(parent.BoolFlag.Names(), FlagNames(parent.inverseName(), parent.inverseAliases())...)
|
||||
}
|
||||
|
||||
if *parent.negDest {
|
||||
return parent.negativeFlag.Names()
|
||||
}
|
||||
|
||||
if *parent.posDest {
|
||||
return parent.positiveFlag.Names()
|
||||
}
|
||||
|
||||
return append(parent.negativeFlag.Names(), parent.positiveFlag.Names()...)
|
||||
}
|
||||
|
||||
// String implements the standard Stringer interface.
|
||||
//
|
||||
// Example for BoolFlag{Name: "env"}
|
||||
// --[no-]env (default: false)
|
||||
func (parent *BoolWithInverseFlag) String() string {
|
||||
out := FlagStringer(parent)
|
||||
i := strings.Index(out, "\t")
|
||||
|
||||
prefix := "--"
|
||||
|
||||
// single character flags are prefixed with `-` instead of `--`
|
||||
if len(parent.Name) == 1 {
|
||||
prefix = "-"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s[%s]%s%s", prefix, parent.inversePrefix(), parent.Name, out[i:])
|
||||
}
|
47
vendor/github.com/urfave/cli/v3/flag_duration.go
generated
vendored
47
vendor/github.com/urfave/cli/v3/flag_duration.go
generated
vendored
@ -1,47 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type DurationFlag = FlagBase[time.Duration, NoConfig, durationValue]
|
||||
|
||||
// -- time.Duration Value
|
||||
type durationValue time.Duration
|
||||
|
||||
// Below functions are to satisfy the ValueCreator interface
|
||||
|
||||
func (d durationValue) Create(val time.Duration, p *time.Duration, c NoConfig) Value {
|
||||
*p = val
|
||||
return (*durationValue)(p)
|
||||
}
|
||||
|
||||
func (d durationValue) ToString(val time.Duration) string {
|
||||
return fmt.Sprintf("%v", val)
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the flag.Value interface
|
||||
|
||||
func (d *durationValue) Set(s string) error {
|
||||
v, err := time.ParseDuration(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*d = durationValue(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *durationValue) Get() any { return time.Duration(*d) }
|
||||
|
||||
func (d *durationValue) String() string { return (*time.Duration)(d).String() }
|
||||
|
||||
func (cmd *Command) Duration(name string) time.Duration {
|
||||
if v, ok := cmd.Value(name).(time.Duration); ok {
|
||||
tracef("duration available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("bool NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return 0
|
||||
}
|
48
vendor/github.com/urfave/cli/v3/flag_ext.go
generated
vendored
48
vendor/github.com/urfave/cli/v3/flag_ext.go
generated
vendored
@ -1,48 +0,0 @@
|
||||
package cli
|
||||
|
||||
import "flag"
|
||||
|
||||
type extFlag struct {
|
||||
f *flag.Flag
|
||||
}
|
||||
|
||||
func (e *extFlag) Apply(fs *flag.FlagSet) error {
|
||||
fs.Var(e.f.Value, e.f.Name, e.f.Usage)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *extFlag) Names() []string {
|
||||
return []string{e.f.Name}
|
||||
}
|
||||
|
||||
func (e *extFlag) IsSet() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (e *extFlag) String() string {
|
||||
return FlagStringer(e)
|
||||
}
|
||||
|
||||
func (e *extFlag) IsVisible() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (e *extFlag) TakesValue() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (e *extFlag) GetUsage() string {
|
||||
return e.f.Usage
|
||||
}
|
||||
|
||||
func (e *extFlag) GetValue() string {
|
||||
return e.f.Value.String()
|
||||
}
|
||||
|
||||
func (e *extFlag) GetDefaultText() string {
|
||||
return e.f.DefValue
|
||||
}
|
||||
|
||||
func (e *extFlag) GetEnvVars() []string {
|
||||
return nil
|
||||
}
|
48
vendor/github.com/urfave/cli/v3/flag_float.go
generated
vendored
48
vendor/github.com/urfave/cli/v3/flag_float.go
generated
vendored
@ -1,48 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type FloatFlag = FlagBase[float64, NoConfig, floatValue]
|
||||
|
||||
// -- float64 Value
|
||||
type floatValue float64
|
||||
|
||||
// Below functions are to satisfy the ValueCreator interface
|
||||
|
||||
func (f floatValue) Create(val float64, p *float64, c NoConfig) Value {
|
||||
*p = val
|
||||
return (*floatValue)(p)
|
||||
}
|
||||
|
||||
func (f floatValue) ToString(b float64) string {
|
||||
return strconv.FormatFloat(b, 'g', -1, 64)
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the flag.Value interface
|
||||
|
||||
func (f *floatValue) Set(s string) error {
|
||||
v, err := strconv.ParseFloat(s, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*f = floatValue(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (f *floatValue) Get() any { return float64(*f) }
|
||||
|
||||
func (f *floatValue) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) }
|
||||
|
||||
// Float looks up the value of a local FloatFlag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Float(name string) float64 {
|
||||
if v, ok := cmd.Value(name).(float64); ok {
|
||||
tracef("float available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("float NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return 0
|
||||
}
|
35
vendor/github.com/urfave/cli/v3/flag_float_slice.go
generated
vendored
35
vendor/github.com/urfave/cli/v3/flag_float_slice.go
generated
vendored
@ -1,35 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
)
|
||||
|
||||
type (
|
||||
FloatSlice = SliceBase[float64, NoConfig, floatValue]
|
||||
FloatSliceFlag = FlagBase[[]float64, NoConfig, FloatSlice]
|
||||
)
|
||||
|
||||
var NewFloatSlice = NewSliceBase[float64, NoConfig, floatValue]
|
||||
|
||||
// FloatSlice looks up the value of a local FloatSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) FloatSlice(name string) []float64 {
|
||||
if flSet := cmd.lookupFlagSet(name); flSet != nil {
|
||||
return lookupFloatSlice(name, flSet, cmd.Name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupFloatSlice(name string, set *flag.FlagSet, cmdName string) []float64 {
|
||||
fl := set.Lookup(name)
|
||||
if fl != nil {
|
||||
if v, ok := fl.Value.(flag.Getter).Get().([]float64); ok {
|
||||
tracef("float slice available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmdName)
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
tracef("float slice NOT available for flag name %[1]q (cmd=%[2]q)", name, cmdName)
|
||||
return nil
|
||||
}
|
286
vendor/github.com/urfave/cli/v3/flag_impl.go
generated
vendored
286
vendor/github.com/urfave/cli/v3/flag_impl.go
generated
vendored
@ -1,286 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Value represents a value as used by cli.
|
||||
// For now it implements the golang flag.Value interface
|
||||
type Value interface {
|
||||
flag.Value
|
||||
flag.Getter
|
||||
}
|
||||
|
||||
type boolFlag interface {
|
||||
IsBoolFlag() bool
|
||||
}
|
||||
|
||||
type fnValue struct {
|
||||
fn func(string) error
|
||||
isBool bool
|
||||
v Value
|
||||
}
|
||||
|
||||
func (f *fnValue) Get() any { return f.v.Get() }
|
||||
func (f *fnValue) Set(s string) error { return f.fn(s) }
|
||||
func (f *fnValue) String() string {
|
||||
if f.v == nil {
|
||||
return ""
|
||||
}
|
||||
return f.v.String()
|
||||
}
|
||||
|
||||
func (f *fnValue) Serialize() string {
|
||||
if s, ok := f.v.(Serializer); ok {
|
||||
return s.Serialize()
|
||||
}
|
||||
return f.v.String()
|
||||
}
|
||||
|
||||
func (f *fnValue) IsBoolFlag() bool { return f.isBool }
|
||||
func (f *fnValue) Count() int {
|
||||
if s, ok := f.v.(Countable); ok {
|
||||
return s.Count()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// ValueCreator is responsible for creating a flag.Value emulation
|
||||
// as well as custom formatting
|
||||
//
|
||||
// T specifies the type
|
||||
// C specifies the config for the type
|
||||
type ValueCreator[T any, C any] interface {
|
||||
Create(T, *T, C) Value
|
||||
ToString(T) string
|
||||
}
|
||||
|
||||
// NoConfig is for flags which dont need a custom configuration
|
||||
type NoConfig struct{}
|
||||
|
||||
// FlagBase [T,C,VC] is a generic flag base which can be used
|
||||
// as a boilerplate to implement the most common interfaces
|
||||
// used by urfave/cli.
|
||||
//
|
||||
// T specifies the type
|
||||
// C specifies the configuration required(if any for that flag type)
|
||||
// VC specifies the value creator which creates the flag.Value emulation
|
||||
type FlagBase[T any, C any, VC ValueCreator[T, C]] struct {
|
||||
Name string `json:"name"` // name of the flag
|
||||
Category string `json:"category"` // category of the flag, if any
|
||||
DefaultText string `json:"defaultText"` // default text of the flag for usage purposes
|
||||
HideDefault bool `json:"hideDefault"` // whether to hide the default value in output
|
||||
Usage string `json:"usage"` // usage string for help output
|
||||
Sources ValueSourceChain `json:"-"` // sources to load flag value from
|
||||
Required bool `json:"required"` // whether the flag is required or not
|
||||
Hidden bool `json:"hidden"` // whether to hide the flag in help output
|
||||
Local bool `json:"local"` // whether the flag needs to be applied to subcommands as well
|
||||
Value T `json:"defaultValue"` // default value for this flag if not set by from any source
|
||||
Destination *T `json:"-"` // destination pointer for value when set
|
||||
Aliases []string `json:"aliases"` // Aliases that are allowed for this flag
|
||||
TakesFile bool `json:"takesFileArg"` // whether this flag takes a file argument, mainly for shell completion purposes
|
||||
Action func(context.Context, *Command, T) error `json:"-"` // Action callback to be called when flag is set
|
||||
Config C `json:"config"` // Additional/Custom configuration associated with this flag type
|
||||
OnlyOnce bool `json:"onlyOnce"` // whether this flag can be duplicated on the command line
|
||||
Validator func(T) error `json:"-"` // custom function to validate this flag value
|
||||
ValidateDefaults bool `json:"validateDefaults"` // whether to validate defaults or not
|
||||
|
||||
// unexported fields for internal use
|
||||
count int // number of times the flag has been set
|
||||
hasBeenSet bool // whether the flag has been set from env or file
|
||||
applied bool // whether the flag has been applied to a flag set already
|
||||
creator VC // value creator for this flag type
|
||||
value Value // value representing this flag's value
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *FlagBase[T, C, V]) GetValue() string {
|
||||
if reflect.TypeOf(f.Value).Kind() == reflect.Bool {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%v", f.Value)
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *FlagBase[T, C, V]) Apply(set *flag.FlagSet) error {
|
||||
tracef("apply (flag=%[1]q)", f.Name)
|
||||
|
||||
// TODO move this phase into a separate flag initialization function
|
||||
// if flag has been applied previously then it would have already been set
|
||||
// from env or file. So no need to apply the env set again. However
|
||||
// lots of units tests prior to persistent flags assumed that the
|
||||
// flag can be applied to different flag sets multiple times while still
|
||||
// keeping the env set.
|
||||
if !f.applied || f.Local {
|
||||
newVal := f.Value
|
||||
|
||||
if val, source, found := f.Sources.LookupWithSource(); found {
|
||||
tmpVal := f.creator.Create(f.Value, new(T), f.Config)
|
||||
if val != "" || reflect.TypeOf(f.Value).Kind() == reflect.String {
|
||||
if err := tmpVal.Set(val); err != nil {
|
||||
return fmt.Errorf(
|
||||
"could not parse %[1]q as %[2]T value from %[3]s for flag %[4]s: %[5]s",
|
||||
val, f.Value, source, f.Name, err,
|
||||
)
|
||||
}
|
||||
} else if val == "" && reflect.TypeOf(f.Value).Kind() == reflect.Bool {
|
||||
val = "false"
|
||||
if err := tmpVal.Set(val); err != nil {
|
||||
return fmt.Errorf(
|
||||
"could not parse %[1]q as %[2]T value from %[3]s for flag %[4]s: %[5]s",
|
||||
val, f.Value, source, f.Name, err,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
newVal = tmpVal.Get().(T)
|
||||
f.hasBeenSet = true
|
||||
}
|
||||
|
||||
if f.Destination == nil {
|
||||
f.value = f.creator.Create(newVal, new(T), f.Config)
|
||||
} else {
|
||||
f.value = f.creator.Create(newVal, f.Destination, f.Config)
|
||||
}
|
||||
|
||||
// Validate the given default or values set from external sources as well
|
||||
if f.Validator != nil && f.ValidateDefaults {
|
||||
if v, ok := f.value.Get().(T); !ok {
|
||||
return &typeError[T]{
|
||||
other: f.value.Get(),
|
||||
}
|
||||
} else if err := f.Validator(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isBool := false
|
||||
if b, ok := f.value.(boolFlag); ok && b.IsBoolFlag() {
|
||||
isBool = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
set.Var(&fnValue{
|
||||
fn: func(val string) error {
|
||||
if f.count == 1 && f.OnlyOnce {
|
||||
return fmt.Errorf("cant duplicate this flag")
|
||||
}
|
||||
f.count++
|
||||
if err := f.value.Set(val); err != nil {
|
||||
return err
|
||||
}
|
||||
f.hasBeenSet = true
|
||||
if f.Validator != nil {
|
||||
if v, ok := f.value.Get().(T); !ok {
|
||||
return &typeError[T]{
|
||||
other: f.value.Get(),
|
||||
}
|
||||
} else if err := f.Validator(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
isBool: isBool,
|
||||
v: f.value,
|
||||
}, name, f.Usage)
|
||||
}
|
||||
|
||||
f.applied = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *FlagBase[T, C, V]) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *FlagBase[T, C, V]) IsSet() bool {
|
||||
return f.hasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *FlagBase[T, C, V]) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *FlagBase[T, C, V]) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *FlagBase[T, C, V]) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// GetCategory returns the category of the flag
|
||||
func (f *FlagBase[T, C, V]) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
func (f *FlagBase[T, C, V]) SetCategory(c string) {
|
||||
f.Category = c
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *FlagBase[T, C, V]) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *FlagBase[T, C, V]) GetEnvVars() []string {
|
||||
return f.Sources.EnvKeys()
|
||||
}
|
||||
|
||||
// TakesValue returns true if the flag takes a value, otherwise false
|
||||
func (f *FlagBase[T, C, V]) TakesValue() bool {
|
||||
var t T
|
||||
return reflect.TypeOf(t).Kind() != reflect.Bool
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *FlagBase[T, C, V]) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
var v V
|
||||
return v.ToString(f.Value)
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Command.
|
||||
func (f *FlagBase[T, C, V]) Get(cmd *Command) T {
|
||||
if v, ok := cmd.Value(f.Name).(T); ok {
|
||||
return v
|
||||
}
|
||||
var t T
|
||||
return t
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *FlagBase[T, C, V]) RunAction(ctx context.Context, cmd *Command) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(ctx, cmd, f.Get(cmd))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsMultiValueFlag returns true if the value type T can take multiple
|
||||
// values from cmd line. This is true for slice and map type flags
|
||||
func (f *FlagBase[T, C, VC]) IsMultiValueFlag() bool {
|
||||
// TBD how to specify
|
||||
kind := reflect.TypeOf(f.Value).Kind()
|
||||
return kind == reflect.Slice || kind == reflect.Map
|
||||
}
|
||||
|
||||
// IsLocal returns false if flag needs to be persistent across subcommands
|
||||
func (f *FlagBase[T, C, VC]) IsLocal() bool {
|
||||
return f.Local
|
||||
}
|
59
vendor/github.com/urfave/cli/v3/flag_int.go
generated
vendored
59
vendor/github.com/urfave/cli/v3/flag_int.go
generated
vendored
@ -1,59 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type IntFlag = FlagBase[int64, IntegerConfig, intValue]
|
||||
|
||||
// IntegerConfig is the configuration for all integer type flags
|
||||
type IntegerConfig struct {
|
||||
Base int
|
||||
}
|
||||
|
||||
// -- int64 Value
|
||||
type intValue struct {
|
||||
val *int64
|
||||
base int
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the ValueCreator interface
|
||||
|
||||
func (i intValue) Create(val int64, p *int64, c IntegerConfig) Value {
|
||||
*p = val
|
||||
return &intValue{
|
||||
val: p,
|
||||
base: c.Base,
|
||||
}
|
||||
}
|
||||
|
||||
func (i intValue) ToString(b int64) string {
|
||||
return strconv.FormatInt(b, 10)
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the flag.Value interface
|
||||
|
||||
func (i *intValue) Set(s string) error {
|
||||
v, err := strconv.ParseInt(s, i.base, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*i.val = v
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *intValue) Get() any { return int64(*i.val) }
|
||||
|
||||
func (i *intValue) String() string { return strconv.FormatInt(int64(*i.val), 10) }
|
||||
|
||||
// Int looks up the value of a local Int64Flag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Int(name string) int64 {
|
||||
if v, ok := cmd.Value(name).(int64); ok {
|
||||
tracef("int available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("int NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return 0
|
||||
}
|
20
vendor/github.com/urfave/cli/v3/flag_int_slice.go
generated
vendored
20
vendor/github.com/urfave/cli/v3/flag_int_slice.go
generated
vendored
@ -1,20 +0,0 @@
|
||||
package cli
|
||||
|
||||
type (
|
||||
IntSlice = SliceBase[int64, IntegerConfig, intValue]
|
||||
IntSliceFlag = FlagBase[[]int64, IntegerConfig, IntSlice]
|
||||
)
|
||||
|
||||
var NewIntSlice = NewSliceBase[int64, IntegerConfig, intValue]
|
||||
|
||||
// IntSlice looks up the value of a local IntSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) IntSlice(name string) []int64 {
|
||||
if v, ok := cmd.Value(name).([]int64); ok {
|
||||
tracef("int slice available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("int slice NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return nil
|
||||
}
|
116
vendor/github.com/urfave/cli/v3/flag_map_impl.go
generated
vendored
116
vendor/github.com/urfave/cli/v3/flag_map_impl.go
generated
vendored
@ -1,116 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MapBase wraps map[string]T to satisfy flag.Value
|
||||
type MapBase[T any, C any, VC ValueCreator[T, C]] struct {
|
||||
dict *map[string]T
|
||||
hasBeenSet bool
|
||||
value Value
|
||||
}
|
||||
|
||||
func (i MapBase[T, C, VC]) Create(val map[string]T, p *map[string]T, c C) Value {
|
||||
*p = map[string]T{}
|
||||
for k, v := range val {
|
||||
(*p)[k] = v
|
||||
}
|
||||
var t T
|
||||
np := new(T)
|
||||
var vc VC
|
||||
return &MapBase[T, C, VC]{
|
||||
dict: p,
|
||||
value: vc.Create(t, np, c),
|
||||
}
|
||||
}
|
||||
|
||||
// NewMapBase makes a *MapBase with default values
|
||||
func NewMapBase[T any, C any, VC ValueCreator[T, C]](defaults map[string]T) *MapBase[T, C, VC] {
|
||||
return &MapBase[T, C, VC]{
|
||||
dict: &defaults,
|
||||
}
|
||||
}
|
||||
|
||||
// Set parses the value and appends it to the list of values
|
||||
func (i *MapBase[T, C, VC]) Set(value string) error {
|
||||
if !i.hasBeenSet {
|
||||
*i.dict = map[string]T{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.dict)
|
||||
i.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, item := range flagSplitMultiValues(value) {
|
||||
key, value, ok := strings.Cut(item, defaultMapFlagKeyValueSeparator)
|
||||
if !ok {
|
||||
return fmt.Errorf("item %q is missing separator %q", item, defaultMapFlagKeyValueSeparator)
|
||||
}
|
||||
if err := i.value.Set(value); err != nil {
|
||||
return err
|
||||
}
|
||||
tmp, ok := i.value.Get().(T)
|
||||
if !ok {
|
||||
return fmt.Errorf("unable to cast %v", i.value)
|
||||
}
|
||||
(*i.dict)[key] = tmp
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (i *MapBase[T, C, VC]) String() string {
|
||||
v := i.Value()
|
||||
var t T
|
||||
if reflect.TypeOf(t).Kind() == reflect.String {
|
||||
return fmt.Sprintf("%v", v)
|
||||
}
|
||||
return fmt.Sprintf("%T{%s}", v, i.ToString(v))
|
||||
}
|
||||
|
||||
// Serialize allows MapBase to fulfill Serializer
|
||||
func (i *MapBase[T, C, VC]) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(i.dict)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the mapping of values set by this flag
|
||||
func (i *MapBase[T, C, VC]) Value() map[string]T {
|
||||
if i.dict == nil {
|
||||
return map[string]T{}
|
||||
}
|
||||
return *i.dict
|
||||
}
|
||||
|
||||
// Get returns the mapping of values set by this flag
|
||||
func (i *MapBase[T, C, VC]) Get() interface{} {
|
||||
return *i.dict
|
||||
}
|
||||
|
||||
func (i MapBase[T, C, VC]) ToString(t map[string]T) string {
|
||||
var defaultVals []string
|
||||
var vc VC
|
||||
for _, k := range sortedKeys(t) {
|
||||
defaultVals = append(defaultVals, k+defaultMapFlagKeyValueSeparator+vc.ToString(t[k]))
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
func sortedKeys[T any](dict map[string]T) []string {
|
||||
keys := make([]string, 0, len(dict))
|
||||
for k := range dict {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
56
vendor/github.com/urfave/cli/v3/flag_mutex.go
generated
vendored
56
vendor/github.com/urfave/cli/v3/flag_mutex.go
generated
vendored
@ -1,56 +0,0 @@
|
||||
package cli
|
||||
|
||||
// MutuallyExclusiveFlags defines a mutually exclusive flag group
|
||||
// Multiple option paths can be provided out of which
|
||||
// only one can be defined on cmdline
|
||||
// So for example
|
||||
// [ --foo | [ --bar something --darth somethingelse ] ]
|
||||
type MutuallyExclusiveFlags struct {
|
||||
// Flag list
|
||||
Flags [][]Flag
|
||||
|
||||
// whether this group is required
|
||||
Required bool
|
||||
|
||||
// Category to apply to all flags within group
|
||||
Category string
|
||||
}
|
||||
|
||||
func (grp MutuallyExclusiveFlags) check(cmd *Command) error {
|
||||
oneSet := false
|
||||
e := &mutuallyExclusiveGroup{}
|
||||
|
||||
for _, grpf := range grp.Flags {
|
||||
for _, f := range grpf {
|
||||
for _, name := range f.Names() {
|
||||
if cmd.IsSet(name) {
|
||||
if oneSet {
|
||||
e.flag2Name = name
|
||||
return e
|
||||
}
|
||||
e.flag1Name = name
|
||||
oneSet = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if oneSet {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !oneSet && grp.Required {
|
||||
return &mutuallyExclusiveGroupRequiredFlag{flags: &grp}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (grp MutuallyExclusiveFlags) propagateCategory() {
|
||||
for _, grpf := range grp.Flags {
|
||||
for _, f := range grpf {
|
||||
if cf, ok := f.(CategorizableFlag); ok {
|
||||
cf.SetCategory(grp.Category)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
110
vendor/github.com/urfave/cli/v3/flag_slice_base.go
generated
vendored
110
vendor/github.com/urfave/cli/v3/flag_slice_base.go
generated
vendored
@ -1,110 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SliceBase wraps []T to satisfy flag.Value
|
||||
type SliceBase[T any, C any, VC ValueCreator[T, C]] struct {
|
||||
slice *[]T
|
||||
hasBeenSet bool
|
||||
value Value
|
||||
}
|
||||
|
||||
func (i SliceBase[T, C, VC]) Create(val []T, p *[]T, c C) Value {
|
||||
*p = []T{}
|
||||
*p = append(*p, val...)
|
||||
var t T
|
||||
np := new(T)
|
||||
var vc VC
|
||||
return &SliceBase[T, C, VC]{
|
||||
slice: p,
|
||||
value: vc.Create(t, np, c),
|
||||
}
|
||||
}
|
||||
|
||||
// NewSliceBase makes a *SliceBase with default values
|
||||
func NewSliceBase[T any, C any, VC ValueCreator[T, C]](defaults ...T) *SliceBase[T, C, VC] {
|
||||
return &SliceBase[T, C, VC]{
|
||||
slice: &defaults,
|
||||
}
|
||||
}
|
||||
|
||||
// SetOne directly adds a value to the list of values
|
||||
func (i *SliceBase[T, C, VC]) SetOne(value T) {
|
||||
if !i.hasBeenSet {
|
||||
*i.slice = []T{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
*i.slice = append(*i.slice, value)
|
||||
}
|
||||
|
||||
// Set parses the value and appends it to the list of values
|
||||
func (i *SliceBase[T, C, VC]) Set(value string) error {
|
||||
if !i.hasBeenSet {
|
||||
*i.slice = []T{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice)
|
||||
i.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, s := range flagSplitMultiValues(value) {
|
||||
if err := i.value.Set(strings.TrimSpace(s)); err != nil {
|
||||
return err
|
||||
}
|
||||
tmp, ok := i.value.Get().(T)
|
||||
if !ok {
|
||||
return fmt.Errorf("unable to cast %v", i.value)
|
||||
}
|
||||
*i.slice = append(*i.slice, tmp)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (i *SliceBase[T, C, VC]) String() string {
|
||||
v := i.Value()
|
||||
var t T
|
||||
if reflect.TypeOf(t).Kind() == reflect.String {
|
||||
return fmt.Sprintf("%v", v)
|
||||
}
|
||||
return fmt.Sprintf("%T{%s}", v, i.ToString(v))
|
||||
}
|
||||
|
||||
// Serialize allows SliceBase to fulfill Serializer
|
||||
func (i *SliceBase[T, C, VC]) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(i.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of values set by this flag
|
||||
func (i *SliceBase[T, C, VC]) Value() []T {
|
||||
if i.slice == nil {
|
||||
return []T{}
|
||||
}
|
||||
return *i.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of values set by this flag
|
||||
func (i *SliceBase[T, C, VC]) Get() interface{} {
|
||||
return *i.slice
|
||||
}
|
||||
|
||||
func (i SliceBase[T, C, VC]) ToString(t []T) string {
|
||||
var defaultVals []string
|
||||
var v VC
|
||||
for _, s := range t {
|
||||
defaultVals = append(defaultVals, v.ToString(s))
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
66
vendor/github.com/urfave/cli/v3/flag_string.go
generated
vendored
66
vendor/github.com/urfave/cli/v3/flag_string.go
generated
vendored
@ -1,66 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type StringFlag = FlagBase[string, StringConfig, stringValue]
|
||||
|
||||
// StringConfig defines the configuration for string flags
|
||||
type StringConfig struct {
|
||||
// Whether to trim whitespace of parsed value
|
||||
TrimSpace bool
|
||||
}
|
||||
|
||||
// -- string Value
|
||||
type stringValue struct {
|
||||
destination *string
|
||||
trimSpace bool
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the ValueCreator interface
|
||||
|
||||
func (s stringValue) Create(val string, p *string, c StringConfig) Value {
|
||||
*p = val
|
||||
return &stringValue{
|
||||
destination: p,
|
||||
trimSpace: c.TrimSpace,
|
||||
}
|
||||
}
|
||||
|
||||
func (s stringValue) ToString(val string) string {
|
||||
if val == "" {
|
||||
return val
|
||||
}
|
||||
return fmt.Sprintf("%q", val)
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the flag.Value interface
|
||||
|
||||
func (s *stringValue) Set(val string) error {
|
||||
if s.trimSpace {
|
||||
val = strings.TrimSpace(val)
|
||||
}
|
||||
*s.destination = val
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stringValue) Get() any { return *s.destination }
|
||||
|
||||
func (s *stringValue) String() string {
|
||||
if s.destination != nil {
|
||||
return *s.destination
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (cmd *Command) String(name string) string {
|
||||
if v, ok := cmd.Value(name).(string); ok {
|
||||
tracef("string available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("string NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return ""
|
||||
}
|
20
vendor/github.com/urfave/cli/v3/flag_string_map.go
generated
vendored
20
vendor/github.com/urfave/cli/v3/flag_string_map.go
generated
vendored
@ -1,20 +0,0 @@
|
||||
package cli
|
||||
|
||||
type (
|
||||
StringMap = MapBase[string, StringConfig, stringValue]
|
||||
StringMapFlag = FlagBase[map[string]string, StringConfig, StringMap]
|
||||
)
|
||||
|
||||
var NewStringMap = NewMapBase[string, StringConfig, stringValue]
|
||||
|
||||
// StringMap looks up the value of a local StringMapFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) StringMap(name string) map[string]string {
|
||||
if v, ok := cmd.Value(name).(map[string]string); ok {
|
||||
tracef("string map available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("string map NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return nil
|
||||
}
|
20
vendor/github.com/urfave/cli/v3/flag_string_slice.go
generated
vendored
20
vendor/github.com/urfave/cli/v3/flag_string_slice.go
generated
vendored
@ -1,20 +0,0 @@
|
||||
package cli
|
||||
|
||||
type (
|
||||
StringSlice = SliceBase[string, StringConfig, stringValue]
|
||||
StringSliceFlag = FlagBase[[]string, StringConfig, StringSlice]
|
||||
)
|
||||
|
||||
var NewStringSlice = NewSliceBase[string, StringConfig, stringValue]
|
||||
|
||||
// StringSlice looks up the value of a local StringSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) StringSlice(name string) []string {
|
||||
if v, ok := cmd.Value(name).([]string); ok {
|
||||
tracef("string slice available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("string slice NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return nil
|
||||
}
|
152
vendor/github.com/urfave/cli/v3/flag_timestamp.go
generated
vendored
152
vendor/github.com/urfave/cli/v3/flag_timestamp.go
generated
vendored
@ -1,152 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TimestampFlag = FlagBase[time.Time, TimestampConfig, timestampValue]
|
||||
|
||||
// TimestampConfig defines the config for timestamp flags
|
||||
type TimestampConfig struct {
|
||||
Timezone *time.Location
|
||||
// Available layouts for flag value.
|
||||
//
|
||||
// Note that value for formats with missing year/date will be interpreted as current year/date respectively.
|
||||
//
|
||||
// Read more about time layouts: https://pkg.go.dev/time#pkg-constants
|
||||
Layouts []string
|
||||
}
|
||||
|
||||
// timestampValue wrap to satisfy golang's flag interface.
|
||||
type timestampValue struct {
|
||||
timestamp *time.Time
|
||||
hasBeenSet bool
|
||||
layouts []string
|
||||
location *time.Location
|
||||
}
|
||||
|
||||
var _ ValueCreator[time.Time, TimestampConfig] = timestampValue{}
|
||||
|
||||
// Below functions are to satisfy the ValueCreator interface
|
||||
|
||||
func (t timestampValue) Create(val time.Time, p *time.Time, c TimestampConfig) Value {
|
||||
*p = val
|
||||
return ×tampValue{
|
||||
timestamp: p,
|
||||
layouts: c.Layouts,
|
||||
location: c.Timezone,
|
||||
}
|
||||
}
|
||||
|
||||
func (t timestampValue) ToString(b time.Time) string {
|
||||
if b.IsZero() {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%v", b)
|
||||
}
|
||||
|
||||
// Timestamp constructor(for internal testing only)
|
||||
func newTimestamp(timestamp time.Time) *timestampValue {
|
||||
return ×tampValue{timestamp: ×tamp}
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the flag.Value interface
|
||||
|
||||
// Parses the string value to timestamp
|
||||
func (t *timestampValue) Set(value string) error {
|
||||
var timestamp time.Time
|
||||
var err error
|
||||
|
||||
if t.location == nil {
|
||||
t.location = time.UTC
|
||||
}
|
||||
|
||||
if len(t.layouts) == 0 {
|
||||
return errors.New("got nil/empty layouts slice")
|
||||
}
|
||||
|
||||
for _, layout := range t.layouts {
|
||||
var locErr error
|
||||
|
||||
timestamp, locErr = time.ParseInLocation(layout, value, t.location)
|
||||
if locErr != nil {
|
||||
if err == nil {
|
||||
err = locErr
|
||||
continue
|
||||
}
|
||||
|
||||
err = newMultiError(err, locErr)
|
||||
continue
|
||||
}
|
||||
|
||||
err = nil
|
||||
break
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defaultTS, _ := time.ParseInLocation(time.TimeOnly, time.TimeOnly, timestamp.Location())
|
||||
|
||||
n := time.Now()
|
||||
|
||||
// If format is missing date (or year only), set it explicitly to current
|
||||
if timestamp.Truncate(time.Hour*24).UnixNano() == defaultTS.Truncate(time.Hour*24).UnixNano() {
|
||||
timestamp = time.Date(
|
||||
n.Year(),
|
||||
n.Month(),
|
||||
n.Day(),
|
||||
timestamp.Hour(),
|
||||
timestamp.Minute(),
|
||||
timestamp.Second(),
|
||||
timestamp.Nanosecond(),
|
||||
timestamp.Location(),
|
||||
)
|
||||
} else if timestamp.Year() == 0 {
|
||||
timestamp = time.Date(
|
||||
n.Year(),
|
||||
timestamp.Month(),
|
||||
timestamp.Day(),
|
||||
timestamp.Hour(),
|
||||
timestamp.Minute(),
|
||||
timestamp.Second(),
|
||||
timestamp.Nanosecond(),
|
||||
timestamp.Location(),
|
||||
)
|
||||
}
|
||||
|
||||
if t.timestamp != nil {
|
||||
*t.timestamp = timestamp
|
||||
}
|
||||
t.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (t *timestampValue) String() string {
|
||||
return fmt.Sprintf("%#v", t.timestamp)
|
||||
}
|
||||
|
||||
// Value returns the timestamp value stored in the flag
|
||||
func (t *timestampValue) Value() *time.Time {
|
||||
return t.timestamp
|
||||
}
|
||||
|
||||
// Get returns the flag structure
|
||||
func (t *timestampValue) Get() any {
|
||||
return *t.timestamp
|
||||
}
|
||||
|
||||
// Timestamp gets the timestamp from a flag name
|
||||
func (cmd *Command) Timestamp(name string) time.Time {
|
||||
if v, ok := cmd.Value(name).(time.Time); ok {
|
||||
tracef("time.Time available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("time.Time NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return time.Time{}
|
||||
}
|
54
vendor/github.com/urfave/cli/v3/flag_uint.go
generated
vendored
54
vendor/github.com/urfave/cli/v3/flag_uint.go
generated
vendored
@ -1,54 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type UintFlag = FlagBase[uint64, IntegerConfig, uintValue]
|
||||
|
||||
// -- uint64 Value
|
||||
type uintValue struct {
|
||||
val *uint64
|
||||
base int
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the ValueCreator interface
|
||||
|
||||
func (i uintValue) Create(val uint64, p *uint64, c IntegerConfig) Value {
|
||||
*p = val
|
||||
return &uintValue{
|
||||
val: p,
|
||||
base: c.Base,
|
||||
}
|
||||
}
|
||||
|
||||
func (i uintValue) ToString(b uint64) string {
|
||||
return strconv.FormatUint(b, 10)
|
||||
}
|
||||
|
||||
// Below functions are to satisfy the flag.Value interface
|
||||
|
||||
func (i *uintValue) Set(s string) error {
|
||||
v, err := strconv.ParseUint(s, i.base, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*i.val = v
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *uintValue) Get() any { return uint64(*i.val) }
|
||||
|
||||
func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i.val), 10) }
|
||||
|
||||
// Uint looks up the value of a local Uint64Flag, returns
|
||||
// 0 if not found
|
||||
func (cmd *Command) Uint(name string) uint64 {
|
||||
if v, ok := cmd.Value(name).(uint64); ok {
|
||||
tracef("uint available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("uint NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return 0
|
||||
}
|
20
vendor/github.com/urfave/cli/v3/flag_uint_slice.go
generated
vendored
20
vendor/github.com/urfave/cli/v3/flag_uint_slice.go
generated
vendored
@ -1,20 +0,0 @@
|
||||
package cli
|
||||
|
||||
type (
|
||||
UintSlice = SliceBase[uint64, IntegerConfig, uintValue]
|
||||
UintSliceFlag = FlagBase[[]uint64, IntegerConfig, UintSlice]
|
||||
)
|
||||
|
||||
var NewUintSlice = NewSliceBase[uint64, IntegerConfig, uintValue]
|
||||
|
||||
// UintSlice looks up the value of a local UintSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cmd *Command) UintSlice(name string) []uint64 {
|
||||
if v, ok := cmd.Value(name).([]uint64); ok {
|
||||
tracef("uint slice available for flag name %[1]q with value=%[2]v (cmd=%[3]q)", name, v, cmd.Name)
|
||||
return v
|
||||
}
|
||||
|
||||
tracef("uint slice NOT available for flag name %[1]q (cmd=%[2]q)", name, cmd.Name)
|
||||
return nil
|
||||
}
|
50
vendor/github.com/urfave/cli/v3/funcs.go
generated
vendored
50
vendor/github.com/urfave/cli/v3/funcs.go
generated
vendored
@ -1,50 +0,0 @@
|
||||
package cli
|
||||
|
||||
import "context"
|
||||
|
||||
// ShellCompleteFunc is an action to execute when the shell completion flag is set
|
||||
type ShellCompleteFunc func(context.Context, *Command)
|
||||
|
||||
// BeforeFunc is an action that executes prior to any subcommands being run once
|
||||
// the context is ready. If a non-nil error is returned, no subcommands are
|
||||
// run.
|
||||
type BeforeFunc func(context.Context, *Command) error
|
||||
|
||||
// AfterFunc is an action that executes after any subcommands are run and have
|
||||
// finished. The AfterFunc is run even if Action() panics.
|
||||
type AfterFunc func(context.Context, *Command) error
|
||||
|
||||
// ActionFunc is the action to execute when no subcommands are specified
|
||||
type ActionFunc func(context.Context, *Command) error
|
||||
|
||||
// CommandNotFoundFunc is executed if the proper command cannot be found
|
||||
type CommandNotFoundFunc func(context.Context, *Command, string)
|
||||
|
||||
// OnUsageErrorFunc is executed if a usage error occurs. This is useful for displaying
|
||||
// customized usage error messages. This function is able to replace the
|
||||
// original error messages. If this function is not set, the "Incorrect usage"
|
||||
// is displayed and the execution is interrupted.
|
||||
type OnUsageErrorFunc func(ctx context.Context, cmd *Command, err error, isSubcommand bool) error
|
||||
|
||||
// InvalidFlagAccessFunc is executed when an invalid flag is accessed from the context.
|
||||
type InvalidFlagAccessFunc func(context.Context, *Command, string)
|
||||
|
||||
// ExitErrHandlerFunc is executed if provided in order to handle exitError values
|
||||
// returned by Actions and Before/After functions.
|
||||
type ExitErrHandlerFunc func(context.Context, *Command, error)
|
||||
|
||||
// FlagStringFunc is used by the help generation to display a flag, which is
|
||||
// expected to be a single line.
|
||||
type FlagStringFunc func(Flag) string
|
||||
|
||||
// FlagNamePrefixFunc is used by the default FlagStringFunc to create prefix
|
||||
// text for a flag's full name.
|
||||
type FlagNamePrefixFunc func(fullName []string, placeholder string) string
|
||||
|
||||
// FlagEnvHintFunc is used by the default FlagStringFunc to annotate flag help
|
||||
// with the environment variable details.
|
||||
type FlagEnvHintFunc func(envVars []string, str string) string
|
||||
|
||||
// FlagFileHintFunc is used by the default FlagStringFunc to annotate flag help
|
||||
// with the file path details.
|
||||
type FlagFileHintFunc func(filePath, str string) string
|
1038
vendor/github.com/urfave/cli/v3/godoc-current.txt
generated
vendored
1038
vendor/github.com/urfave/cli/v3/godoc-current.txt
generated
vendored
File diff suppressed because it is too large
Load Diff
588
vendor/github.com/urfave/cli/v3/help.go
generated
vendored
588
vendor/github.com/urfave/cli/v3/help.go
generated
vendored
@ -1,588 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"text/template"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
helpName = "help"
|
||||
helpAlias = "h"
|
||||
)
|
||||
|
||||
// Prints help for the App or Command
|
||||
type helpPrinter func(w io.Writer, templ string, data interface{})
|
||||
|
||||
// Prints help for the App or Command with custom template function.
|
||||
type helpPrinterCustom func(w io.Writer, templ string, data interface{}, customFunc map[string]interface{})
|
||||
|
||||
// HelpPrinter is a function that writes the help output. If not set explicitly,
|
||||
// this calls HelpPrinterCustom using only the default template functions.
|
||||
//
|
||||
// If custom logic for printing help is required, this function can be
|
||||
// overridden. If the ExtraInfo field is defined on an App, this function
|
||||
// should not be modified, as HelpPrinterCustom will be used directly in order
|
||||
// to capture the extra information.
|
||||
var HelpPrinter helpPrinter = printHelp
|
||||
|
||||
// HelpPrinterCustom is a function that writes the help output. It is used as
|
||||
// the default implementation of HelpPrinter, and may be called directly if
|
||||
// the ExtraInfo field is set on an App.
|
||||
//
|
||||
// In the default implementation, if the customFuncs argument contains a
|
||||
// "wrapAt" key, which is a function which takes no arguments and returns
|
||||
// an int, this int value will be used to produce a "wrap" function used
|
||||
// by the default template to wrap long lines.
|
||||
var HelpPrinterCustom helpPrinterCustom = printHelpCustom
|
||||
|
||||
// VersionPrinter prints the version for the App
|
||||
var VersionPrinter = printVersion
|
||||
|
||||
func buildHelpCommand(withAction bool) *Command {
|
||||
cmd := &Command{
|
||||
Name: helpName,
|
||||
Aliases: []string{helpAlias},
|
||||
Usage: "Shows a list of commands or help for one command",
|
||||
ArgsUsage: "[command]",
|
||||
HideHelp: true,
|
||||
}
|
||||
|
||||
if withAction {
|
||||
cmd.Action = helpCommandAction
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func helpCommandAction(ctx context.Context, cmd *Command) error {
|
||||
args := cmd.Args()
|
||||
firstArg := args.First()
|
||||
|
||||
tracef("doing help for cmd %[1]q with args %[2]q", cmd, args)
|
||||
|
||||
// This action can be triggered by a "default" action of a command
|
||||
// or via cmd.Run when cmd == helpCmd. So we have following possibilities
|
||||
//
|
||||
// 1 $ app
|
||||
// 2 $ app help
|
||||
// 3 $ app foo
|
||||
// 4 $ app help foo
|
||||
// 5 $ app foo help
|
||||
|
||||
// Case 4. when executing a help command set the context to parent
|
||||
// to allow resolution of subsequent args. This will transform
|
||||
// $ app help foo
|
||||
// to
|
||||
// $ app foo
|
||||
// which will then be handled as case 3
|
||||
if cmd.parent != nil && (cmd.HasName(helpName) || cmd.HasName(helpAlias)) {
|
||||
tracef("setting cmd to cmd.parent")
|
||||
cmd = cmd.parent
|
||||
}
|
||||
|
||||
// Case 4. $ app help foo
|
||||
// foo is the command for which help needs to be shown
|
||||
if firstArg != "" {
|
||||
tracef("returning ShowCommandHelp with %[1]q", firstArg)
|
||||
return ShowCommandHelp(ctx, cmd, firstArg)
|
||||
}
|
||||
|
||||
// Case 1 & 2
|
||||
// Special case when running help on main app itself as opposed to individual
|
||||
// commands/subcommands
|
||||
if cmd.parent == nil {
|
||||
tracef("returning ShowAppHelp")
|
||||
_ = ShowAppHelp(cmd)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Case 3, 5
|
||||
if (len(cmd.Commands) == 1 && !cmd.HideHelp) ||
|
||||
(len(cmd.Commands) == 0 && cmd.HideHelp) {
|
||||
|
||||
tmpl := cmd.CustomHelpTemplate
|
||||
if tmpl == "" {
|
||||
tmpl = CommandHelpTemplate
|
||||
}
|
||||
|
||||
tracef("running HelpPrinter with command %[1]q", cmd.Name)
|
||||
HelpPrinter(cmd.Root().Writer, tmpl, cmd)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
tracef("running ShowSubcommandHelp")
|
||||
return ShowSubcommandHelp(cmd)
|
||||
}
|
||||
|
||||
// ShowAppHelpAndExit - Prints the list of subcommands for the app and exits with exit code.
|
||||
func ShowAppHelpAndExit(cmd *Command, exitCode int) {
|
||||
_ = ShowAppHelp(cmd)
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
|
||||
// ShowAppHelp is an action that displays the help.
|
||||
func ShowAppHelp(cmd *Command) error {
|
||||
tmpl := cmd.CustomRootCommandHelpTemplate
|
||||
if tmpl == "" {
|
||||
tracef("using RootCommandHelpTemplate")
|
||||
tmpl = RootCommandHelpTemplate
|
||||
}
|
||||
|
||||
if cmd.ExtraInfo == nil {
|
||||
HelpPrinter(cmd.Root().Writer, tmpl, cmd.Root())
|
||||
return nil
|
||||
}
|
||||
|
||||
tracef("setting ExtraInfo in customAppData")
|
||||
customAppData := func() map[string]any {
|
||||
return map[string]any{
|
||||
"ExtraInfo": cmd.ExtraInfo,
|
||||
}
|
||||
}
|
||||
HelpPrinterCustom(cmd.Root().Writer, tmpl, cmd.Root(), customAppData())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultAppComplete prints the list of subcommands as the default app completion method
|
||||
func DefaultAppComplete(ctx context.Context, cmd *Command) {
|
||||
DefaultCompleteWithFlags(ctx, cmd)
|
||||
}
|
||||
|
||||
func printCommandSuggestions(commands []*Command, writer io.Writer) {
|
||||
for _, command := range commands {
|
||||
if command.Hidden {
|
||||
continue
|
||||
}
|
||||
if strings.HasSuffix(os.Getenv("0"), "zsh") {
|
||||
_, _ = fmt.Fprintf(writer, "%s:%s\n", command.Name, command.Usage)
|
||||
} else {
|
||||
_, _ = fmt.Fprintf(writer, "%s\n", command.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cliArgContains(flagName string) bool {
|
||||
for _, name := range strings.Split(flagName, ",") {
|
||||
name = strings.TrimSpace(name)
|
||||
count := utf8.RuneCountInString(name)
|
||||
if count > 2 {
|
||||
count = 2
|
||||
}
|
||||
flag := fmt.Sprintf("%s%s", strings.Repeat("-", count), name)
|
||||
for _, a := range os.Args {
|
||||
if a == flag {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func printFlagSuggestions(lastArg string, flags []Flag, writer io.Writer) {
|
||||
cur := strings.TrimPrefix(lastArg, "-")
|
||||
cur = strings.TrimPrefix(cur, "-")
|
||||
for _, flag := range flags {
|
||||
if bflag, ok := flag.(*BoolFlag); ok && bflag.Hidden {
|
||||
continue
|
||||
}
|
||||
|
||||
usage := ""
|
||||
if docFlag, ok := flag.(DocGenerationFlag); ok {
|
||||
usage = docFlag.GetUsage()
|
||||
}
|
||||
|
||||
name := strings.TrimSpace(flag.Names()[0])
|
||||
// this will get total count utf8 letters in flag name
|
||||
count := utf8.RuneCountInString(name)
|
||||
if count > 2 {
|
||||
count = 2 // reuse this count to generate single - or -- in flag completion
|
||||
}
|
||||
// if flag name has more than one utf8 letter and last argument in cli has -- prefix then
|
||||
// skip flag completion for short flags example -v or -x
|
||||
if strings.HasPrefix(lastArg, "--") && count == 1 {
|
||||
continue
|
||||
}
|
||||
// match if last argument matches this flag and it is not repeated
|
||||
if strings.HasPrefix(name, cur) && cur != name && !cliArgContains(name) {
|
||||
flagCompletion := fmt.Sprintf("%s%s", strings.Repeat("-", count), name)
|
||||
if usage != "" && strings.HasSuffix(os.Getenv("SHELL"), "zsh") {
|
||||
flagCompletion = fmt.Sprintf("%s:%s", flagCompletion, usage)
|
||||
}
|
||||
fmt.Fprintln(writer, flagCompletion)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultCompleteWithFlags(ctx context.Context, cmd *Command) {
|
||||
args := os.Args
|
||||
if cmd != nil && cmd.flagSet != nil && cmd.parent != nil {
|
||||
args = cmd.Args().Slice()
|
||||
tracef("running default complete with flags[%v] on command %[2]q", args, cmd.Name)
|
||||
} else {
|
||||
tracef("running default complete with os.Args flags[%v]", args)
|
||||
}
|
||||
argsLen := len(args)
|
||||
lastArg := ""
|
||||
// parent command will have --generate-shell-completion so we need
|
||||
// to account for that
|
||||
if argsLen > 1 {
|
||||
lastArg = args[argsLen-2]
|
||||
} else if argsLen > 0 {
|
||||
lastArg = args[argsLen-1]
|
||||
}
|
||||
|
||||
if strings.HasPrefix(lastArg, "-") {
|
||||
tracef("printing flag suggestion for flag[%v] on command %[1]q", lastArg, cmd.Name)
|
||||
printFlagSuggestions(lastArg, cmd.Flags, cmd.Root().Writer)
|
||||
return
|
||||
}
|
||||
|
||||
if cmd != nil {
|
||||
tracef("printing command suggestions on command %[1]q", cmd.Name)
|
||||
printCommandSuggestions(cmd.Commands, cmd.Root().Writer)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// ShowCommandHelpAndExit - exits with code after showing help
|
||||
func ShowCommandHelpAndExit(ctx context.Context, cmd *Command, command string, code int) {
|
||||
_ = ShowCommandHelp(ctx, cmd, command)
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// ShowCommandHelp prints help for the given command
|
||||
func ShowCommandHelp(ctx context.Context, cmd *Command, commandName string) error {
|
||||
for _, subCmd := range cmd.Commands {
|
||||
if !subCmd.HasName(commandName) {
|
||||
continue
|
||||
}
|
||||
|
||||
tmpl := subCmd.CustomHelpTemplate
|
||||
if tmpl == "" {
|
||||
if len(subCmd.Commands) == 0 {
|
||||
tracef("using CommandHelpTemplate")
|
||||
tmpl = CommandHelpTemplate
|
||||
} else {
|
||||
tracef("using SubcommandHelpTemplate")
|
||||
tmpl = SubcommandHelpTemplate
|
||||
}
|
||||
}
|
||||
|
||||
tracef("running HelpPrinter")
|
||||
HelpPrinter(cmd.Root().Writer, tmpl, subCmd)
|
||||
|
||||
tracef("returning nil after printing help")
|
||||
return nil
|
||||
}
|
||||
|
||||
tracef("no matching command found")
|
||||
|
||||
if cmd.CommandNotFound == nil {
|
||||
errMsg := fmt.Sprintf("No help topic for '%v'", commandName)
|
||||
|
||||
if cmd.Suggest {
|
||||
if suggestion := SuggestCommand(cmd.Commands, commandName); suggestion != "" {
|
||||
errMsg += ". " + suggestion
|
||||
}
|
||||
}
|
||||
|
||||
tracef("exiting 3 with errMsg %[1]q", errMsg)
|
||||
return Exit(errMsg, 3)
|
||||
}
|
||||
|
||||
tracef("running CommandNotFound func for %[1]q", commandName)
|
||||
cmd.CommandNotFound(ctx, cmd, commandName)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ShowSubcommandHelpAndExit - Prints help for the given subcommand and exits with exit code.
|
||||
func ShowSubcommandHelpAndExit(cmd *Command, exitCode int) {
|
||||
_ = ShowSubcommandHelp(cmd)
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
|
||||
// ShowSubcommandHelp prints help for the given subcommand
|
||||
func ShowSubcommandHelp(cmd *Command) error {
|
||||
if cmd == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
HelpPrinter(cmd.Root().Writer, SubcommandHelpTemplate, cmd)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ShowVersion prints the version number of the App
|
||||
func ShowVersion(cmd *Command) {
|
||||
tracef("showing version via VersionPrinter (cmd=%[1]q)", cmd.Name)
|
||||
VersionPrinter(cmd)
|
||||
}
|
||||
|
||||
func printVersion(cmd *Command) {
|
||||
_, _ = fmt.Fprintf(cmd.Root().Writer, "%v version %v\n", cmd.Name, cmd.Version)
|
||||
}
|
||||
|
||||
func handleTemplateError(err error) {
|
||||
if err != nil {
|
||||
tracef("error encountered during template parse: %[1]v", err)
|
||||
// If the writer is closed, t.Execute will fail, and there's nothing
|
||||
// we can do to recover.
|
||||
if os.Getenv("CLI_TEMPLATE_ERROR_DEBUG") != "" {
|
||||
_, _ = fmt.Fprintf(ErrWriter, "CLI TEMPLATE ERROR: %#v\n", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// printHelpCustom is the default implementation of HelpPrinterCustom.
|
||||
//
|
||||
// The customFuncs map will be combined with a default template.FuncMap to
|
||||
// allow using arbitrary functions in template rendering.
|
||||
func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs map[string]interface{}) {
|
||||
const maxLineLength = 10000
|
||||
|
||||
tracef("building default funcMap")
|
||||
funcMap := template.FuncMap{
|
||||
"join": strings.Join,
|
||||
"subtract": subtract,
|
||||
"indent": indent,
|
||||
"nindent": nindent,
|
||||
"trim": strings.TrimSpace,
|
||||
"wrap": func(input string, offset int) string { return wrap(input, offset, maxLineLength) },
|
||||
"offset": offset,
|
||||
"offsetCommands": offsetCommands,
|
||||
}
|
||||
|
||||
if wa, ok := customFuncs["wrapAt"]; ok {
|
||||
if wrapAtFunc, ok := wa.(func() int); ok {
|
||||
wrapAt := wrapAtFunc()
|
||||
customFuncs["wrap"] = func(input string, offset int) string {
|
||||
return wrap(input, offset, wrapAt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for key, value := range customFuncs {
|
||||
funcMap[key] = value
|
||||
}
|
||||
|
||||
w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0)
|
||||
t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
|
||||
if _, err := t.New("helpNameTemplate").Parse(helpNameTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("argsTemplate").Parse(argsTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("usageTemplate").Parse(usageTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("descriptionTemplate").Parse(descriptionTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("visibleCommandTemplate").Parse(visibleCommandTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("copyrightTemplate").Parse(copyrightTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("versionTemplate").Parse(versionTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("visibleFlagCategoryTemplate").Parse(visibleFlagCategoryTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("visibleFlagTemplate").Parse(visibleFlagTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("visiblePersistentFlagTemplate").Parse(visiblePersistentFlagTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("visibleGlobalFlagCategoryTemplate").Parse(strings.Replace(visibleFlagCategoryTemplate, "OPTIONS", "GLOBAL OPTIONS", -1)); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("authorsTemplate").Parse(authorsTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
if _, err := t.New("visibleCommandCategoryTemplate").Parse(visibleCommandCategoryTemplate); err != nil {
|
||||
handleTemplateError(err)
|
||||
}
|
||||
|
||||
tracef("executing template")
|
||||
handleTemplateError(t.Execute(w, data))
|
||||
|
||||
_ = w.Flush()
|
||||
}
|
||||
|
||||
func printHelp(out io.Writer, templ string, data interface{}) {
|
||||
HelpPrinterCustom(out, templ, data, nil)
|
||||
}
|
||||
|
||||
func checkVersion(cmd *Command) bool {
|
||||
found := false
|
||||
for _, name := range VersionFlag.Names() {
|
||||
if cmd.Bool(name) {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
func checkShellCompleteFlag(c *Command, arguments []string) (bool, []string) {
|
||||
if (c.parent == nil && !c.EnableShellCompletion) || (c.parent != nil && !c.Root().shellCompletion) {
|
||||
return false, arguments
|
||||
}
|
||||
|
||||
pos := len(arguments) - 1
|
||||
lastArg := arguments[pos]
|
||||
|
||||
if lastArg != "--generate-shell-completion" {
|
||||
return false, arguments
|
||||
}
|
||||
|
||||
for _, arg := range arguments {
|
||||
// If arguments include "--", shell completion is disabled
|
||||
// because after "--" only positional arguments are accepted.
|
||||
// https://unix.stackexchange.com/a/11382
|
||||
if arg == "--" {
|
||||
return false, arguments
|
||||
}
|
||||
}
|
||||
|
||||
return true, arguments[:pos]
|
||||
}
|
||||
|
||||
func checkCompletions(ctx context.Context, cmd *Command) bool {
|
||||
tracef("checking completions on command %[1]q", cmd.Name)
|
||||
|
||||
if !cmd.Root().shellCompletion {
|
||||
return false
|
||||
}
|
||||
|
||||
if argsArguments := cmd.Args(); argsArguments.Present() {
|
||||
name := argsArguments.First()
|
||||
if cmd := cmd.Command(name); cmd != nil {
|
||||
// let the command handle the completion
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if cmd.ShellComplete != nil {
|
||||
tracef("running shell completion func for command %[1]q", cmd.Name)
|
||||
cmd.ShellComplete(ctx, cmd)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func subtract(a, b int) int {
|
||||
return a - b
|
||||
}
|
||||
|
||||
func indent(spaces int, v string) string {
|
||||
pad := strings.Repeat(" ", spaces)
|
||||
return pad + strings.Replace(v, "\n", "\n"+pad, -1)
|
||||
}
|
||||
|
||||
func nindent(spaces int, v string) string {
|
||||
return "\n" + indent(spaces, v)
|
||||
}
|
||||
|
||||
func wrap(input string, offset int, wrapAt int) string {
|
||||
var ss []string
|
||||
|
||||
lines := strings.Split(input, "\n")
|
||||
|
||||
padding := strings.Repeat(" ", offset)
|
||||
|
||||
for i, line := range lines {
|
||||
if line == "" {
|
||||
ss = append(ss, line)
|
||||
} else {
|
||||
wrapped := wrapLine(line, offset, wrapAt, padding)
|
||||
if i == 0 {
|
||||
ss = append(ss, wrapped)
|
||||
} else {
|
||||
ss = append(ss, padding+wrapped)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(ss, "\n")
|
||||
}
|
||||
|
||||
func wrapLine(input string, offset int, wrapAt int, padding string) string {
|
||||
if wrapAt <= offset || len(input) <= wrapAt-offset {
|
||||
return input
|
||||
}
|
||||
|
||||
lineWidth := wrapAt - offset
|
||||
words := strings.Fields(input)
|
||||
if len(words) == 0 {
|
||||
return input
|
||||
}
|
||||
|
||||
wrapped := words[0]
|
||||
spaceLeft := lineWidth - len(wrapped)
|
||||
for _, word := range words[1:] {
|
||||
if len(word)+1 > spaceLeft {
|
||||
wrapped += "\n" + padding + word
|
||||
spaceLeft = lineWidth - len(word)
|
||||
} else {
|
||||
wrapped += " " + word
|
||||
spaceLeft -= 1 + len(word)
|
||||
}
|
||||
}
|
||||
|
||||
return wrapped
|
||||
}
|
||||
|
||||
func offset(input string, fixed int) int {
|
||||
return len(input) + fixed
|
||||
}
|
||||
|
||||
// this function tries to find the max width of the names column
|
||||
// so say we have the following rows for help
|
||||
//
|
||||
// foo1, foo2, foo3 some string here
|
||||
// bar1, b2 some other string here
|
||||
//
|
||||
// We want to offset the 2nd row usage by some amount so that everything
|
||||
// is aligned
|
||||
//
|
||||
// foo1, foo2, foo3 some string here
|
||||
// bar1, b2 some other string here
|
||||
//
|
||||
// to find that offset we find the length of all the rows and use the max
|
||||
// to calculate the offset
|
||||
func offsetCommands(cmds []*Command, fixed int) int {
|
||||
max := 0
|
||||
for _, cmd := range cmds {
|
||||
s := strings.Join(cmd.Names(), ", ")
|
||||
if len(s) > max {
|
||||
max = len(s)
|
||||
}
|
||||
}
|
||||
return max + fixed
|
||||
}
|
5
vendor/github.com/urfave/cli/v3/mkdocs-reqs.txt
generated
vendored
5
vendor/github.com/urfave/cli/v3/mkdocs-reqs.txt
generated
vendored
@ -1,5 +0,0 @@
|
||||
mkdocs-git-revision-date-localized-plugin~=1.2
|
||||
mkdocs-material-extensions~=1.3
|
||||
mkdocs-material~=8.5
|
||||
mkdocs~=1.6
|
||||
pygments~=2.18
|
107
vendor/github.com/urfave/cli/v3/mkdocs.yml
generated
vendored
107
vendor/github.com/urfave/cli/v3/mkdocs.yml
generated
vendored
@ -1,107 +0,0 @@
|
||||
# NOTE: the mkdocs dependencies will need to be installed out of
|
||||
# band until this whole thing gets more automated:
|
||||
#
|
||||
# pip install -r mkdocs-reqs.txt
|
||||
#
|
||||
|
||||
site_name: urfave/cli
|
||||
site_url: https://cli.urfave.org/
|
||||
repo_url: https://github.com/urfave/cli
|
||||
edit_uri: edit/main/docs/
|
||||
nav:
|
||||
- Home:
|
||||
- Welcome: index.md
|
||||
- Contributing: CONTRIBUTING.md
|
||||
- Code of Conduct: CODE_OF_CONDUCT.md
|
||||
- Releasing: RELEASING.md
|
||||
- Security: SECURITY.md
|
||||
- Migrate v1 to v2: migrate-v1-to-v2.md
|
||||
- v2 Manual:
|
||||
- Getting Started: v2/getting-started.md
|
||||
- Migrating From Older Releases: v2/migrating-from-older-releases.md
|
||||
- Examples:
|
||||
- Greet: v2/examples/greet.md
|
||||
- Arguments: v2/examples/arguments.md
|
||||
- Flags: v2/examples/flags.md
|
||||
- Subcommands: v2/examples/subcommands.md
|
||||
- Subcommands Categories: v2/examples/subcommands-categories.md
|
||||
- Exit Codes: v2/examples/exit-codes.md
|
||||
- Combining Short Options: v2/examples/combining-short-options.md
|
||||
- Bash Completions: v2/examples/bash-completions.md
|
||||
- Generated Help Text: v2/examples/generated-help-text.md
|
||||
- Version Flag: v2/examples/version-flag.md
|
||||
- Timestamp Flag: v2/examples/timestamp-flag.md
|
||||
- Suggestions: v2/examples/suggestions.md
|
||||
- Full API Example: v2/examples/full-api-example.md
|
||||
- v1 Manual:
|
||||
- Getting Started: v1/getting-started.md
|
||||
- Migrating to v2: v1/migrating-to-v2.md
|
||||
- Examples:
|
||||
- Greet: v1/examples/greet.md
|
||||
- Arguments: v1/examples/arguments.md
|
||||
- Flags: v1/examples/flags.md
|
||||
- Subcommands: v1/examples/subcommands.md
|
||||
- Subcommands (Categories): v1/examples/subcommands-categories.md
|
||||
- Exit Codes: v1/examples/exit-codes.md
|
||||
- Combining Short Options: v1/examples/combining-short-options.md
|
||||
- Bash Completions: v1/examples/bash-completions.md
|
||||
- Generated Help Text: v1/examples/generated-help-text.md
|
||||
- Version Flag: v1/examples/version-flag.md
|
||||
|
||||
theme:
|
||||
name: material
|
||||
palette:
|
||||
- media: "(prefers-color-scheme: light)"
|
||||
scheme: default
|
||||
toggle:
|
||||
icon: material/brightness-4
|
||||
name: dark mode
|
||||
- media: "(prefers-color-scheme: dark)"
|
||||
scheme: slate
|
||||
toggle:
|
||||
icon: material/brightness-7
|
||||
name: light mode
|
||||
features:
|
||||
- content.code.annotate
|
||||
- navigation.top
|
||||
- navigation.instant
|
||||
- navigation.expand
|
||||
- navigation.sections
|
||||
- navigation.tabs
|
||||
- navigation.tabs.sticky
|
||||
plugins:
|
||||
- git-revision-date-localized
|
||||
- search
|
||||
- tags
|
||||
# NOTE: this is the recommended configuration from
|
||||
# https://squidfunk.github.io/mkdocs-material/setup/extensions/#recommended-configuration
|
||||
markdown_extensions:
|
||||
- abbr
|
||||
- admonition
|
||||
- attr_list
|
||||
- def_list
|
||||
- footnotes
|
||||
- meta
|
||||
- md_in_html
|
||||
- toc:
|
||||
permalink: true
|
||||
- pymdownx.arithmatex:
|
||||
generic: true
|
||||
- pymdownx.betterem:
|
||||
smart_enable: all
|
||||
- pymdownx.caret
|
||||
- pymdownx.details
|
||||
- pymdownx.emoji:
|
||||
emoji_index: !!python/name:material.extensions.emoji.twemoji
|
||||
emoji_generator: !!python/name:material.extensions.emoji.to_svg
|
||||
- pymdownx.highlight
|
||||
- pymdownx.inlinehilite
|
||||
- pymdownx.keys
|
||||
- pymdownx.mark
|
||||
- pymdownx.smartsymbols
|
||||
- pymdownx.superfences
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
- pymdownx.tasklist:
|
||||
custom_checkbox: true
|
||||
- pymdownx.tilde
|
118
vendor/github.com/urfave/cli/v3/parse.go
generated
vendored
118
vendor/github.com/urfave/cli/v3/parse.go
generated
vendored
@ -1,118 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type iterativeParser interface {
|
||||
useShortOptionHandling() bool
|
||||
}
|
||||
|
||||
// To enable short-option handling (e.g., "-it" vs "-i -t") we have to
|
||||
// iteratively catch parsing errors. This way we achieve LR parsing without
|
||||
// transforming any arguments. Otherwise, there is no way we can discriminate
|
||||
// combined short options from common arguments that should be left untouched.
|
||||
// Pass `shellComplete` to continue parsing options on failure during shell
|
||||
// completion when, the user-supplied options may be incomplete.
|
||||
func parseIter(set *flag.FlagSet, ip iterativeParser, args []string, shellComplete bool) error {
|
||||
for {
|
||||
tracef("parsing args %[1]q with %[2]T (name=%[3]q)", args, set, set.Name())
|
||||
|
||||
err := set.Parse(args)
|
||||
if !ip.useShortOptionHandling() || err == nil {
|
||||
if shellComplete {
|
||||
tracef("returning nil due to shellComplete=true")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
tracef("returning err %[1]q", err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
tracef("finding flag from error %[1]q", err)
|
||||
|
||||
trimmed, trimErr := flagFromError(err)
|
||||
if trimErr != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tracef("regenerating the initial args with the split short opts")
|
||||
|
||||
argsWereSplit := false
|
||||
for i, arg := range args {
|
||||
tracef("skipping args that are not part of the error message (i=%[1]v arg=%[2]q)", i, arg)
|
||||
|
||||
if name := strings.TrimLeft(arg, "-"); name != trimmed {
|
||||
continue
|
||||
}
|
||||
|
||||
tracef("trying to split short option (arg=%[1]q)", arg)
|
||||
|
||||
shortOpts := splitShortOptions(set, arg)
|
||||
if len(shortOpts) == 1 {
|
||||
return err
|
||||
}
|
||||
|
||||
tracef(
|
||||
"swapping current argument with the split version (shortOpts=%[1]q args=%[2]q)",
|
||||
shortOpts, args,
|
||||
)
|
||||
|
||||
// do not include args that parsed correctly so far as it would
|
||||
// trigger Value.Set() on those args and would result in
|
||||
// duplicates for slice type flags
|
||||
args = append(shortOpts, args[i+1:]...)
|
||||
argsWereSplit = true
|
||||
break
|
||||
}
|
||||
|
||||
tracef("this should be an impossible to reach code path")
|
||||
// but in case the arg splitting failed to happen, this
|
||||
// will prevent infinite loops
|
||||
if !argsWereSplit {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const providedButNotDefinedErrMsg = "flag provided but not defined: -"
|
||||
|
||||
// flagFromError tries to parse a provided flag from an error message. If the
|
||||
// parsing fails, it returns the input error and an empty string
|
||||
func flagFromError(err error) (string, error) {
|
||||
errStr := err.Error()
|
||||
trimmed := strings.TrimPrefix(errStr, providedButNotDefinedErrMsg)
|
||||
if errStr == trimmed {
|
||||
return "", err
|
||||
}
|
||||
return trimmed, nil
|
||||
}
|
||||
|
||||
func splitShortOptions(set *flag.FlagSet, arg string) []string {
|
||||
shortFlagsExist := func(s string) bool {
|
||||
for _, c := range s[1:] {
|
||||
if f := set.Lookup(string(c)); f == nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
if !isSplittable(arg) || !shortFlagsExist(arg) {
|
||||
return []string{arg}
|
||||
}
|
||||
|
||||
separated := make([]string, 0, len(arg)-1)
|
||||
for _, flagChar := range arg[1:] {
|
||||
separated = append(separated, "-"+string(flagChar))
|
||||
}
|
||||
|
||||
return separated
|
||||
}
|
||||
|
||||
func isSplittable(flagArg string) bool {
|
||||
return strings.HasPrefix(flagArg, "-") && !strings.HasPrefix(flagArg, "--") && len(flagArg) > 2
|
||||
}
|
29
vendor/github.com/urfave/cli/v3/sort.go
generated
vendored
29
vendor/github.com/urfave/cli/v3/sort.go
generated
vendored
@ -1,29 +0,0 @@
|
||||
package cli
|
||||
|
||||
import "unicode"
|
||||
|
||||
// lexicographicLess compares strings alphabetically considering case.
|
||||
func lexicographicLess(i, j string) bool {
|
||||
iRunes := []rune(i)
|
||||
jRunes := []rune(j)
|
||||
|
||||
lenShared := len(iRunes)
|
||||
if lenShared > len(jRunes) {
|
||||
lenShared = len(jRunes)
|
||||
}
|
||||
|
||||
for index := 0; index < lenShared; index++ {
|
||||
ir := iRunes[index]
|
||||
jr := jRunes[index]
|
||||
|
||||
if lir, ljr := unicode.ToLower(ir), unicode.ToLower(jr); lir != ljr {
|
||||
return lir < ljr
|
||||
}
|
||||
|
||||
if ir != jr {
|
||||
return ir < jr
|
||||
}
|
||||
}
|
||||
|
||||
return i < j
|
||||
}
|
1
vendor/github.com/urfave/cli/v3/staticcheck.conf
generated
vendored
1
vendor/github.com/urfave/cli/v3/staticcheck.conf
generated
vendored
@ -1 +0,0 @@
|
||||
checks=["all"]
|
147
vendor/github.com/urfave/cli/v3/suggestions.go
generated
vendored
147
vendor/github.com/urfave/cli/v3/suggestions.go
generated
vendored
@ -1,147 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
const suggestDidYouMeanTemplate = "Did you mean %q?"
|
||||
|
||||
var (
|
||||
SuggestFlag SuggestFlagFunc = suggestFlag
|
||||
SuggestCommand SuggestCommandFunc = suggestCommand
|
||||
SuggestDidYouMeanTemplate string = suggestDidYouMeanTemplate
|
||||
)
|
||||
|
||||
type SuggestFlagFunc func(flags []Flag, provided string, hideHelp bool) string
|
||||
|
||||
type SuggestCommandFunc func(commands []*Command, provided string) string
|
||||
|
||||
// jaroDistance is the measure of similarity between two strings. It returns a
|
||||
// value between 0 and 1, where 1 indicates identical strings and 0 indicates
|
||||
// completely different strings.
|
||||
//
|
||||
// Adapted from https://github.com/xrash/smetrics/blob/5f08fbb34913bc8ab95bb4f2a89a0637ca922666/jaro.go.
|
||||
func jaroDistance(a, b string) float64 {
|
||||
if len(a) == 0 && len(b) == 0 {
|
||||
return 1
|
||||
}
|
||||
if len(a) == 0 || len(b) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
lenA := float64(len(a))
|
||||
lenB := float64(len(b))
|
||||
hashA := make([]bool, len(a))
|
||||
hashB := make([]bool, len(b))
|
||||
maxDistance := int(math.Max(0, math.Floor(math.Max(lenA, lenB)/2.0)-1))
|
||||
|
||||
var matches float64
|
||||
for i := 0; i < len(a); i++ {
|
||||
start := int(math.Max(0, float64(i-maxDistance)))
|
||||
end := int(math.Min(lenB-1, float64(i+maxDistance)))
|
||||
|
||||
for j := start; j <= end; j++ {
|
||||
if hashB[j] {
|
||||
continue
|
||||
}
|
||||
if a[i] == b[j] {
|
||||
hashA[i] = true
|
||||
hashB[j] = true
|
||||
matches++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if matches == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
var transpositions float64
|
||||
var j int
|
||||
for i := 0; i < len(a); i++ {
|
||||
if !hashA[i] {
|
||||
continue
|
||||
}
|
||||
for !hashB[j] {
|
||||
j++
|
||||
}
|
||||
if a[i] != b[j] {
|
||||
transpositions++
|
||||
}
|
||||
j++
|
||||
}
|
||||
|
||||
transpositions /= 2
|
||||
return ((matches / lenA) + (matches / lenB) + ((matches - transpositions) / matches)) / 3.0
|
||||
}
|
||||
|
||||
// jaroWinkler is more accurate when strings have a common prefix up to a
|
||||
// defined maximum length.
|
||||
//
|
||||
// Adapted from https://github.com/xrash/smetrics/blob/5f08fbb34913bc8ab95bb4f2a89a0637ca922666/jaro-winkler.go.
|
||||
func jaroWinkler(a, b string) float64 {
|
||||
const (
|
||||
boostThreshold = 0.7
|
||||
prefixSize = 4
|
||||
)
|
||||
jaroDist := jaroDistance(a, b)
|
||||
if jaroDist <= boostThreshold {
|
||||
return jaroDist
|
||||
}
|
||||
|
||||
prefix := int(math.Min(float64(len(a)), math.Min(float64(prefixSize), float64(len(b)))))
|
||||
|
||||
var prefixMatch float64
|
||||
for i := 0; i < prefix; i++ {
|
||||
if a[i] == b[i] {
|
||||
prefixMatch++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return jaroDist + 0.1*prefixMatch*(1.0-jaroDist)
|
||||
}
|
||||
|
||||
func suggestFlag(flags []Flag, provided string, hideHelp bool) string {
|
||||
distance := 0.0
|
||||
suggestion := ""
|
||||
|
||||
for _, flag := range flags {
|
||||
flagNames := flag.Names()
|
||||
if !hideHelp && HelpFlag != nil {
|
||||
flagNames = append(flagNames, HelpFlag.Names()...)
|
||||
}
|
||||
for _, name := range flagNames {
|
||||
newDistance := jaroWinkler(name, provided)
|
||||
if newDistance > distance {
|
||||
distance = newDistance
|
||||
suggestion = name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(suggestion) == 1 {
|
||||
suggestion = "-" + suggestion
|
||||
} else if len(suggestion) > 1 {
|
||||
suggestion = "--" + suggestion
|
||||
}
|
||||
|
||||
return suggestion
|
||||
}
|
||||
|
||||
// suggestCommand takes a list of commands and a provided string to suggest a
|
||||
// command name
|
||||
func suggestCommand(commands []*Command, provided string) (suggestion string) {
|
||||
distance := 0.0
|
||||
for _, command := range commands {
|
||||
for _, name := range append(command.Names(), helpName, helpAlias) {
|
||||
newDistance := jaroWinkler(name, provided)
|
||||
if newDistance > distance {
|
||||
distance = newDistance
|
||||
suggestion = name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return suggestion
|
||||
}
|
125
vendor/github.com/urfave/cli/v3/template.go
generated
vendored
125
vendor/github.com/urfave/cli/v3/template.go
generated
vendored
@ -1,125 +0,0 @@
|
||||
package cli
|
||||
|
||||
var (
|
||||
helpNameTemplate = `{{$v := offset .FullName 6}}{{wrap .FullName 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}`
|
||||
argsTemplate = `{{if .Arguments}}{{range .Arguments}}{{.Usage}}{{end}}{{end}}`
|
||||
usageTemplate = `{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.FullName}}{{if .VisibleFlags}} [command [command options]]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}{{template "argsTemplate" .}}{{end}}{{end}}`
|
||||
descriptionTemplate = `{{wrap .Description 3}}`
|
||||
authorsTemplate = `{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
||||
{{range $index, $author := .Authors}}{{if $index}}
|
||||
{{end}}{{$author}}{{end}}`
|
||||
)
|
||||
|
||||
var visibleCommandTemplate = `{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
|
||||
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}`
|
||||
|
||||
var visibleCommandCategoryTemplate = `{{range .VisibleCategories}}{{if .Name}}
|
||||
|
||||
{{.Name}}:{{range .VisibleCommands}}
|
||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{template "visibleCommandTemplate" .}}{{end}}{{end}}`
|
||||
|
||||
var visibleFlagCategoryTemplate = `{{range .VisibleFlagCategories}}
|
||||
{{if .Name}}{{.Name}}
|
||||
|
||||
{{end}}{{$flglen := len .Flags}}{{range $i, $e := .Flags}}{{if eq (subtract $flglen $i) 1}}{{$e}}
|
||||
{{else}}{{$e}}
|
||||
{{end}}{{end}}{{end}}`
|
||||
|
||||
var visibleFlagTemplate = `{{range $i, $e := .VisibleFlags}}
|
||||
{{wrap $e.String 6}}{{end}}`
|
||||
|
||||
var visiblePersistentFlagTemplate = `{{range $i, $e := .VisiblePersistentFlags}}
|
||||
{{wrap $e.String 6}}{{end}}`
|
||||
|
||||
var versionTemplate = `{{if .Version}}{{if not .HideVersion}}
|
||||
|
||||
VERSION:
|
||||
{{.Version}}{{end}}{{end}}`
|
||||
|
||||
var copyrightTemplate = `{{wrap .Copyright 3}}`
|
||||
|
||||
// RootCommandHelpTemplate is the text template for the Default help topic.
|
||||
// cli.go uses text/template to render templates. You can
|
||||
// render custom help text by setting this variable.
|
||||
var RootCommandHelpTemplate = `NAME:
|
||||
{{template "helpNameTemplate" .}}
|
||||
|
||||
USAGE:
|
||||
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.FullName}} {{if .VisibleFlags}}[global options]{{end}}{{if .VisibleCommands}} [command [command options]]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
|
||||
|
||||
VERSION:
|
||||
{{.Version}}{{end}}{{end}}{{if .Description}}
|
||||
|
||||
DESCRIPTION:
|
||||
{{template "descriptionTemplate" .}}{{end}}
|
||||
{{- if len .Authors}}
|
||||
|
||||
AUTHOR{{template "authorsTemplate" .}}{{end}}{{if .VisibleCommands}}
|
||||
|
||||
COMMANDS:{{template "visibleCommandCategoryTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||
|
||||
GLOBAL OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||
|
||||
GLOBAL OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}{{if .Copyright}}
|
||||
|
||||
COPYRIGHT:
|
||||
{{template "copyrightTemplate" .}}{{end}}
|
||||
`
|
||||
|
||||
// CommandHelpTemplate is the text template for the command help topic.
|
||||
// cli.go uses text/template to render templates. You can
|
||||
// render custom help text by setting this variable.
|
||||
var CommandHelpTemplate = `NAME:
|
||||
{{template "helpNameTemplate" .}}
|
||||
|
||||
USAGE:
|
||||
{{template "usageTemplate" .}}{{if .Category}}
|
||||
|
||||
CATEGORY:
|
||||
{{.Category}}{{end}}{{if .Description}}
|
||||
|
||||
DESCRIPTION:
|
||||
{{template "descriptionTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||
|
||||
OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||
|
||||
OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}{{if .VisiblePersistentFlags}}
|
||||
|
||||
GLOBAL OPTIONS:{{template "visiblePersistentFlagTemplate" .}}{{end}}
|
||||
`
|
||||
|
||||
// SubcommandHelpTemplate is the text template for the subcommand help topic.
|
||||
// cli.go uses text/template to render templates. You can
|
||||
// render custom help text by setting this variable.
|
||||
var SubcommandHelpTemplate = `NAME:
|
||||
{{template "helpNameTemplate" .}}
|
||||
|
||||
USAGE:
|
||||
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.FullName}} {{if .VisibleCommands}}[command [command options]] {{end}}{{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}}
|
||||
|
||||
CATEGORY:
|
||||
{{.Category}}{{end}}{{if .Description}}
|
||||
|
||||
DESCRIPTION:
|
||||
{{template "descriptionTemplate" .}}{{end}}{{if .VisibleCommands}}
|
||||
|
||||
COMMANDS:{{template "visibleCommandTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||
|
||||
OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||
|
||||
OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}
|
||||
`
|
||||
|
||||
var FishCompletionTemplate = `# {{ .Command.Name }} fish shell completion
|
||||
|
||||
function __fish_{{ .Command.Name }}_no_subcommand --description 'Test if there has been any subcommand yet'
|
||||
for i in (commandline -opc)
|
||||
if contains -- $i{{ range $v := .AllCommands }} {{ $v }}{{ end }}
|
||||
return 1
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
{{ range $v := .Completions }}{{ $v }}
|
||||
{{ end }}`
|
145
vendor/github.com/urfave/cli/v3/value_source.go
generated
vendored
145
vendor/github.com/urfave/cli/v3/value_source.go
generated
vendored
@ -1,145 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ValueSource is a source which can be used to look up a value,
|
||||
// typically for use with a cli.Flag
|
||||
type ValueSource interface {
|
||||
fmt.Stringer
|
||||
fmt.GoStringer
|
||||
|
||||
// Lookup returns the value from the source and if it was found
|
||||
// or returns an empty string and false
|
||||
Lookup() (string, bool)
|
||||
}
|
||||
|
||||
// ValueSourceChain contains an ordered series of ValueSource that
|
||||
// allows for lookup where the first ValueSource to resolve is
|
||||
// returned
|
||||
type ValueSourceChain struct {
|
||||
Chain []ValueSource
|
||||
}
|
||||
|
||||
func NewValueSourceChain(src ...ValueSource) ValueSourceChain {
|
||||
return ValueSourceChain{
|
||||
Chain: src,
|
||||
}
|
||||
}
|
||||
|
||||
func (vsc *ValueSourceChain) Append(other ValueSourceChain) {
|
||||
vsc.Chain = append(vsc.Chain, other.Chain...)
|
||||
}
|
||||
|
||||
func (vsc *ValueSourceChain) EnvKeys() []string {
|
||||
vals := []string{}
|
||||
|
||||
for _, src := range vsc.Chain {
|
||||
if v, ok := src.(*envVarValueSource); ok {
|
||||
vals = append(vals, v.Key)
|
||||
}
|
||||
}
|
||||
|
||||
return vals
|
||||
}
|
||||
|
||||
func (vsc *ValueSourceChain) String() string {
|
||||
s := []string{}
|
||||
|
||||
for _, vs := range vsc.Chain {
|
||||
s = append(s, vs.String())
|
||||
}
|
||||
|
||||
return strings.Join(s, ",")
|
||||
}
|
||||
|
||||
func (vsc *ValueSourceChain) GoString() string {
|
||||
s := []string{}
|
||||
|
||||
for _, vs := range vsc.Chain {
|
||||
s = append(s, vs.GoString())
|
||||
}
|
||||
|
||||
return fmt.Sprintf("&ValueSourceChain{Chain:{%[1]s}}", strings.Join(s, ","))
|
||||
}
|
||||
|
||||
func (vsc *ValueSourceChain) Lookup() (string, bool) {
|
||||
s, _, ok := vsc.LookupWithSource()
|
||||
return s, ok
|
||||
}
|
||||
|
||||
func (vsc *ValueSourceChain) LookupWithSource() (string, ValueSource, bool) {
|
||||
for _, src := range vsc.Chain {
|
||||
if value, found := src.Lookup(); found {
|
||||
return value, src, true
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil, false
|
||||
}
|
||||
|
||||
// envVarValueSource encapsulates a ValueSource from an environment variable
|
||||
type envVarValueSource struct {
|
||||
Key string
|
||||
}
|
||||
|
||||
func (e *envVarValueSource) Lookup() (string, bool) {
|
||||
return os.LookupEnv(strings.TrimSpace(string(e.Key)))
|
||||
}
|
||||
|
||||
func (e *envVarValueSource) String() string { return fmt.Sprintf("environment variable %[1]q", e.Key) }
|
||||
func (e *envVarValueSource) GoString() string {
|
||||
return fmt.Sprintf("&envVarValueSource{Key:%[1]q}", e.Key)
|
||||
}
|
||||
|
||||
func EnvVar(key string) ValueSource {
|
||||
return &envVarValueSource{
|
||||
Key: key,
|
||||
}
|
||||
}
|
||||
|
||||
// EnvVars is a helper function to encapsulate a number of
|
||||
// envVarValueSource together as a ValueSourceChain
|
||||
func EnvVars(keys ...string) ValueSourceChain {
|
||||
vsc := ValueSourceChain{Chain: []ValueSource{}}
|
||||
|
||||
for _, key := range keys {
|
||||
vsc.Chain = append(vsc.Chain, &envVarValueSource{Key: key})
|
||||
}
|
||||
|
||||
return vsc
|
||||
}
|
||||
|
||||
// fileValueSource encapsulates a ValueSource from a file
|
||||
type fileValueSource struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
func (f *fileValueSource) Lookup() (string, bool) {
|
||||
data, err := os.ReadFile(f.Path)
|
||||
return string(data), err == nil
|
||||
}
|
||||
|
||||
func (f *fileValueSource) String() string { return fmt.Sprintf("file %[1]q", f.Path) }
|
||||
func (f *fileValueSource) GoString() string {
|
||||
return fmt.Sprintf("&fileValueSource{Path:%[1]q}", f.Path)
|
||||
}
|
||||
|
||||
func File(path string) ValueSource {
|
||||
return &fileValueSource{Path: path}
|
||||
}
|
||||
|
||||
// Files is a helper function to encapsulate a number of
|
||||
// fileValueSource together as a ValueSourceChain
|
||||
func Files(paths ...string) ValueSourceChain {
|
||||
vsc := ValueSourceChain{Chain: []ValueSource{}}
|
||||
|
||||
for _, path := range paths {
|
||||
vsc.Chain = append(vsc.Chain, &fileValueSource{Path: path})
|
||||
}
|
||||
|
||||
return vsc
|
||||
}
|
3
vendor/modules.txt
vendored
3
vendor/modules.txt
vendored
@ -528,9 +528,6 @@ github.com/theupdateframework/notary/tuf/data
|
||||
github.com/theupdateframework/notary/tuf/signed
|
||||
github.com/theupdateframework/notary/tuf/utils
|
||||
github.com/theupdateframework/notary/tuf/validation
|
||||
# github.com/urfave/cli/v3 v3.0.0-alpha9 => github.com/urfave/cli/v3 v3.0.0-alpha9.1.0.20241019193437-5053ec708a44
|
||||
## explicit; go 1.18
|
||||
github.com/urfave/cli/v3
|
||||
# github.com/xanzy/ssh-agent v0.3.3
|
||||
## explicit; go 1.16
|
||||
github.com/xanzy/ssh-agent
|
||||
|
Reference in New Issue
Block a user