Merge branch 'main' into applying-pr1218
This commit is contained in:
commit
6c811a82df
5
.github/workflows/cli.yml
vendored
5
.github/workflows/cli.yml
vendored
@ -87,3 +87,8 @@ jobs:
|
||||
|
||||
- name: toc
|
||||
run: go run internal/build/build.go toc docs/v2/manual.md
|
||||
|
||||
- name: diff check
|
||||
run: |
|
||||
git diff --exit-code
|
||||
git diff --cached --exit-code
|
||||
|
32
Makefile
Normal file
32
Makefile
Normal file
@ -0,0 +1,32 @@
|
||||
# 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.
|
||||
|
||||
.PHONY: all
|
||||
all: generate vet tag-test test check-binary-size tag-check-binary-size gfmrun toc v2diff
|
||||
|
||||
# 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 internal/build/build.go $(GFLAGS) $* $(FLAGS)
|
||||
|
||||
.PHONY: tag-test
|
||||
tag-test:
|
||||
go run internal/build/build.go -tags urfave_cli_no_docs test
|
||||
|
||||
.PHONY: tag-check-binary-size
|
||||
tag-check-binary-size:
|
||||
go run internal/build/build.go -tags urfave_cli_no_docs check-binary-size
|
||||
|
||||
.PHONY: gfmrun
|
||||
gfmrun:
|
||||
go run internal/build/build.go gfmrun docs/v2/manual.md
|
||||
|
||||
.PHONY: toc
|
||||
toc:
|
||||
go run internal/build/build.go toc docs/v2/manual.md
|
2
cli.go
2
cli.go
@ -20,4 +20,4 @@
|
||||
// }
|
||||
package cli
|
||||
|
||||
//go:generate go run flag-gen/main.go flag-gen/assets_vfsdata.go
|
||||
//go:generate go run internal/genflags/cmd/genflags/main.go
|
||||
|
@ -1,18 +1,121 @@
|
||||
## Contributing
|
||||
|
||||
Use @urfave/cli to ping the maintainers.
|
||||
Welcome to the `urfave/cli` contributor docs! This goal of this document is to help those
|
||||
interested in joining the 200+ humans who have contributed to this project over the years.
|
||||
|
||||
Feel free to put up a pull request to fix a bug or maybe add a feature. We will
|
||||
give it a code review and make sure that it does not break backwards
|
||||
compatibility. If collaborators agree that it is in line with
|
||||
the vision of the project, we will work with you to get the code into
|
||||
a mergeable state and merge it into the main branch.
|
||||
> As a general guiding principle, the current maintainers may be notified via the
|
||||
> @urfave/cli GitHub team.
|
||||
|
||||
If you have contributed something significant to the project, we will most
|
||||
likely add you as a collaborator. As a collaborator you are given the ability
|
||||
to merge others pull requests. It is very important that new code does not
|
||||
break existing code, so be careful about what code you do choose to merge.
|
||||
All of the current maintainers are *volunteers* who live in various timezones with
|
||||
different scheduling needs, so please understand that your contribution or question may
|
||||
not get a response for many days.
|
||||
|
||||
If you feel like you have contributed to the project but have not yet been added
|
||||
as a collaborator, we probably forgot to add you :sweat_smile:. Please open an
|
||||
issue!
|
||||
### semantic versioning adherence
|
||||
|
||||
The `urfave/cli` project strives to strictly adhere to [semantic
|
||||
versioning](https://semver.org/spec/v2.0.0.html). The active development branches and the
|
||||
milestones and import paths to which they correspond are:
|
||||
|
||||
#### `main` branch
|
||||
|
||||
<https://github.com/urfave/cli/tree/main>
|
||||
|
||||
The majority of active development and issue management is targeting the `main` branch,
|
||||
which **MUST** *only* receive bug fixes and feature *additions*.
|
||||
|
||||
- :arrow_right: [`v2.x`](https://github.com/urfave/cli/milestone/16)
|
||||
- :arrow_right: `github.com/urfave/cli/v2`
|
||||
|
||||
The `main` branch in particular includes tooling to help with keeping the `v2.x` series
|
||||
backward compatible. More details on this process are in the development workflow section
|
||||
below.
|
||||
|
||||
#### `v1` branch
|
||||
|
||||
<https://github.com/urfave/cli/tree/v1>
|
||||
|
||||
The `v1` branch **MUST** only receive bug fixes in the `v1.22.x` series. There is no
|
||||
strict rule regarding bug fixes to the `v2.x` series being backported to the `v1.22.x`
|
||||
series.
|
||||
|
||||
- :arrow_right: [`v1.22.x`](https://github.com/urfave/cli/milestone/11)
|
||||
- :arrow_right: `github.com/urfave/cli`
|
||||
|
||||
#### `v3-dev-main` branch
|
||||
|
||||
<https://github.com/urfave/cli/tree/v3-dev-main>
|
||||
|
||||
The `v3-dev-branch` **MUST** receive all bug fixes and features added to the `main` branch
|
||||
and **MAY** receive feature *removals* and other changes that are otherwise
|
||||
*backward-incompatible* with the `v2.x` series.
|
||||
|
||||
- :arrow_right: [`v3.x`](https://github.com/urfave/cli/milestone/5)
|
||||
- unreleased / unsupported
|
||||
|
||||
### development workflow
|
||||
|
||||
Most of the tooling around the development workflow strives for effective
|
||||
[dogfooding](https://en.wikipedia.org/wiki/Eating_your_own_dog_food). There is a top-level
|
||||
`Makefile` that is maintained strictly for the purpose of easing verification of one's
|
||||
development environment and any changes one may have introduced:
|
||||
|
||||
```sh
|
||||
make
|
||||
```
|
||||
|
||||
Running the default `make` target (`all`) will ensure all of the critical steps are run to
|
||||
verify one's changes are harmonious in nature. The same steps are also run during the
|
||||
[continuous integration
|
||||
phase](https://github.com/urfave/cli/blob/main/.github/workflows/cli.yml).
|
||||
|
||||
In the event that the `v2diff` target exits non-zero, this is a signal that the public API
|
||||
surface area has changed. If the changes adhere to semantic versioning, meaning they are
|
||||
*additions* or *bug fixes*, then manually running the approval step will "promote" the
|
||||
current `go doc` output:
|
||||
|
||||
```sh
|
||||
make v2approve
|
||||
```
|
||||
|
||||
Because the `generate` step includes updating `godoc-current.txt` and
|
||||
`testdata/godoc-v2.x.txt`, these changes *MUST* be part of any proposed pull request so
|
||||
that reviewers have an opportunity to also make an informed decision about the "promotion"
|
||||
step.
|
||||
|
||||
#### generated code
|
||||
|
||||
A significant portion of the project's source code is generated, with the goal being to
|
||||
eliminate repetetive maintenance where other type-safe abstraction is impractical or
|
||||
impossible with Go versions `< 1.18`. In a future where the eldest Go version supported is
|
||||
`1.18.x`, there will likely be efforts to take advantage of
|
||||
[generics](https://go.dev/doc/tutorial/generics).
|
||||
|
||||
The built-in `go generate` command is used to run the commands specified in
|
||||
`//go:generate` directives. Each such command runs a file that also supports a command
|
||||
line help system which may be consulted for further information, e.g.:
|
||||
|
||||
```sh
|
||||
go run internal/genflags/cmd/genflags/main.go --help
|
||||
```
|
||||
|
||||
### pull requests
|
||||
|
||||
Please feel free to open a pull request to fix a bug or add a feature. The @urfave/cli
|
||||
team will review it as soon as possible, giving special attention to maintaining backward
|
||||
compatibility. If the @urfave/cli team agrees that your contribution is in line with the
|
||||
vision of the project, they will work with you to get the code into a mergeable state,
|
||||
merged, and then released.
|
||||
|
||||
### granting of commit bit / admin mode
|
||||
|
||||
Those with a history of contributing to this project will likely be invited to join the
|
||||
@urfave/cli team. As a member of the @urfave/cli team, you will have the ability to fully
|
||||
administer pull requests, issues, and other repository bits.
|
||||
|
||||
If you feel that you should be a member of the @urfave/cli team but have not yet been
|
||||
added, the most likely explanation is that this is an accidental oversight! :sweat_smile:.
|
||||
Please open an issue!
|
||||
|
||||
<!--
|
||||
vim:tw=90
|
||||
-->
|
||||
|
50
flag-spec.yaml
Normal file
50
flag-spec.yaml
Normal file
@ -0,0 +1,50 @@
|
||||
# NOTE: this file is used by the tool defined in
|
||||
# ./internal/genflags/cmd/genflags/main.go which uses the
|
||||
# `genflags.Spec` type that maps to this file structure.
|
||||
|
||||
flag_types:
|
||||
bool: {}
|
||||
float64: {}
|
||||
int64: {}
|
||||
int: {}
|
||||
time.Duration: {}
|
||||
uint64: {}
|
||||
uint: {}
|
||||
|
||||
string:
|
||||
struct_fields:
|
||||
- { name: TakesFile, type: bool }
|
||||
Generic:
|
||||
struct_fields:
|
||||
- { name: TakesFile, type: bool }
|
||||
Path:
|
||||
struct_fields:
|
||||
- { name: TakesFile, type: bool }
|
||||
|
||||
Float64Slice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
Int64Slice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
IntSlice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
StringSlice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- { name: TakesFile, type: bool }
|
||||
Timestamp:
|
||||
value_pointer: true
|
||||
struct_fields:
|
||||
- { name: Layout, type: string }
|
||||
|
||||
# TODO: enable UintSlice
|
||||
# UintSlice: {}
|
||||
# TODO: enable Uint64Slice once #1334 lands
|
||||
# Uint64Slice: {}
|
2
flag.go
2
flag.go
@ -258,7 +258,7 @@ func withEnvHint(envVars []string, str string) string {
|
||||
return str + envText
|
||||
}
|
||||
|
||||
func flagNames(name string, aliases []string) []string {
|
||||
func FlagNames(name string, aliases []string) []string {
|
||||
var ret []string
|
||||
|
||||
for _, part := range append([]string{name}, aliases...) {
|
||||
|
36
flag_bool.go
36
flag_bool.go
@ -6,37 +6,6 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// BoolFlag is a flag with type bool
|
||||
type BoolFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value bool
|
||||
DefaultText string
|
||||
Destination *bool
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *BoolFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *BoolFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *BoolFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *BoolFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
@ -102,6 +71,11 @@ func (f *BoolFlag) Apply(set *flag.FlagSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *BoolFlag) Get(ctx *Context) bool {
|
||||
return ctx.Bool(f.Name)
|
||||
}
|
||||
|
||||
// Bool looks up the value of a local BoolFlag, returns
|
||||
// false if not found
|
||||
func (cCtx *Context) Bool(name string) bool {
|
||||
|
@ -6,37 +6,6 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// DurationFlag is a flag with type time.Duration (see https://golang.org/pkg/time/#ParseDuration)
|
||||
type DurationFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value time.Duration
|
||||
DefaultText string
|
||||
Destination *time.Duration
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *DurationFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *DurationFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *DurationFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *DurationFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
@ -101,6 +70,11 @@ func (f *DurationFlag) Apply(set *flag.FlagSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *DurationFlag) Get(ctx *Context) time.Duration {
|
||||
return ctx.Duration(f.Name)
|
||||
}
|
||||
|
||||
// Duration looks up the value of a local DurationFlag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Duration(name string) time.Duration {
|
||||
|
@ -6,37 +6,6 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Float64Flag is a flag with type float64
|
||||
type Float64Flag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value float64
|
||||
DefaultText string
|
||||
Destination *float64
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Float64Flag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Float64Flag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Float64Flag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Float64Flag) IsRequired() bool {
|
||||
return f.Required
|
||||
@ -101,6 +70,11 @@ func (f *Float64Flag) Apply(set *flag.FlagSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Float64Flag) Get(ctx *Context) float64 {
|
||||
return ctx.Float64(f.Name)
|
||||
}
|
||||
|
||||
// Float64 looks up the value of a local Float64Flag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Float64(name string) float64 {
|
||||
|
@ -75,36 +75,12 @@ func (f *Float64Slice) Get() interface{} {
|
||||
return *f
|
||||
}
|
||||
|
||||
// Float64SliceFlag is a flag with type *Float64Slice
|
||||
type Float64SliceFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value *Float64Slice
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Float64SliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Float64SliceFlag) String() string {
|
||||
return withEnvHint(f.GetEnvVars(), stringifyFloat64SliceFlag(f))
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Float64SliceFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Float64SliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
@ -177,6 +153,11 @@ func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Float64SliceFlag) Get(ctx *Context) []float64 {
|
||||
return ctx.Float64Slice(f.Name)
|
||||
}
|
||||
|
||||
// Float64Slice looks up the value of a local Float64SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) Float64Slice(name string) []float64 {
|
||||
|
@ -11,37 +11,6 @@ type Generic interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
// GenericFlag is a flag with type Generic
|
||||
type GenericFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
TakesFile bool
|
||||
Value Generic
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *GenericFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *GenericFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *GenericFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *GenericFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
@ -104,6 +73,11 @@ func (f GenericFlag) Apply(set *flag.FlagSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *GenericFlag) Get(ctx *Context) interface{} {
|
||||
return ctx.Generic(f.Name)
|
||||
}
|
||||
|
||||
// Generic looks up the value of a local GenericFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) Generic(name string) interface{} {
|
||||
|
36
flag_int.go
36
flag_int.go
@ -6,37 +6,6 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// IntFlag is a flag with type int
|
||||
type IntFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value int
|
||||
DefaultText string
|
||||
Destination *int
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *IntFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *IntFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *IntFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *IntFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
@ -102,6 +71,11 @@ func (f *IntFlag) Apply(set *flag.FlagSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *IntFlag) Get(ctx *Context) int {
|
||||
return ctx.Int(f.Name)
|
||||
}
|
||||
|
||||
// Int looks up the value of a local IntFlag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Int(name string) int {
|
||||
|
@ -6,37 +6,6 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Int64Flag is a flag with type int64
|
||||
type Int64Flag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value int64
|
||||
DefaultText string
|
||||
Destination *int64
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Int64Flag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Int64Flag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Int64Flag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Int64Flag) IsRequired() bool {
|
||||
return f.Required
|
||||
@ -101,6 +70,11 @@ func (f *Int64Flag) Apply(set *flag.FlagSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Int64Flag) Get(ctx *Context) int64 {
|
||||
return ctx.Int64(f.Name)
|
||||
}
|
||||
|
||||
// Int64 looks up the value of a local Int64Flag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Int64(name string) int64 {
|
||||
|
@ -76,36 +76,12 @@ func (i *Int64Slice) Get() interface{} {
|
||||
return *i
|
||||
}
|
||||
|
||||
// Int64SliceFlag is a flag with type *Int64Slice
|
||||
type Int64SliceFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value *Int64Slice
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Int64SliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Int64SliceFlag) String() string {
|
||||
return withEnvHint(f.GetEnvVars(), stringifyInt64SliceFlag(f))
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Int64SliceFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Int64SliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
@ -176,6 +152,11 @@ func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Int64SliceFlag) Get(ctx *Context) []int64 {
|
||||
return ctx.Int64Slice(f.Name)
|
||||
}
|
||||
|
||||
// Int64Slice looks up the value of a local Int64SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) Int64Slice(name string) []int64 {
|
||||
|
@ -87,36 +87,12 @@ func (i *IntSlice) Get() interface{} {
|
||||
return *i
|
||||
}
|
||||
|
||||
// IntSliceFlag is a flag with type *IntSlice
|
||||
type IntSliceFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value *IntSlice
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *IntSliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *IntSliceFlag) String() string {
|
||||
return withEnvHint(f.GetEnvVars(), stringifyIntSliceFlag(f))
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *IntSliceFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *IntSliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
@ -187,6 +163,11 @@ func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *IntSliceFlag) Get(ctx *Context) []int {
|
||||
return ctx.IntSlice(f.Name)
|
||||
}
|
||||
|
||||
// IntSlice looks up the value of a local IntSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) IntSlice(name string) []int {
|
||||
|
36
flag_path.go
36
flag_path.go
@ -5,36 +5,7 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type PathFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
TakesFile bool
|
||||
Value string
|
||||
DefaultText string
|
||||
Destination *string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *PathFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *PathFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *PathFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
type Path = string
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *PathFlag) IsRequired() bool {
|
||||
@ -96,6 +67,11 @@ func (f *PathFlag) Apply(set *flag.FlagSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *PathFlag) Get(ctx *Context) string {
|
||||
return ctx.Path(f.Name)
|
||||
}
|
||||
|
||||
// Path looks up the value of a local PathFlag, returns
|
||||
// "" if not found
|
||||
func (cCtx *Context) Path(name string) string {
|
||||
|
@ -5,38 +5,6 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// StringFlag is a flag with type string
|
||||
type StringFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
TakesFile bool
|
||||
Value string
|
||||
DefaultText string
|
||||
Destination *string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *StringFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *StringFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *StringFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *StringFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
@ -97,6 +65,11 @@ func (f *StringFlag) Apply(set *flag.FlagSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *StringFlag) Get(ctx *Context) string {
|
||||
return ctx.String(f.Name)
|
||||
}
|
||||
|
||||
// String looks up the value of a local StringFlag, returns
|
||||
// "" if not found
|
||||
func (cCtx *Context) String(name string) string {
|
||||
|
@ -70,38 +70,12 @@ func (s *StringSlice) Get() interface{} {
|
||||
return *s
|
||||
}
|
||||
|
||||
// StringSliceFlag is a flag with type *StringSlice
|
||||
type StringSliceFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
TakesFile bool
|
||||
Value *StringSlice
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
Destination *StringSlice
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *StringSliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *StringSliceFlag) String() string {
|
||||
return withEnvHint(f.GetEnvVars(), stringifyStringSliceFlag(f))
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *StringSliceFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *StringSliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
@ -188,6 +162,11 @@ func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *StringSliceFlag) Get(ctx *Context) []string {
|
||||
return ctx.StringSlice(f.Name)
|
||||
}
|
||||
|
||||
// StringSlice looks up the value of a local StringSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) StringSlice(name string) []string {
|
||||
|
124
flag_test.go
124
flag_test.go
@ -51,6 +51,17 @@ func TestBoolFlagApply_SetsAllNames(t *testing.T) {
|
||||
expect(t, v, true)
|
||||
}
|
||||
|
||||
func TestBoolFlagValueFromContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool("trueflag", true, "doc")
|
||||
set.Bool("falseflag", false, "doc")
|
||||
ctx := NewContext(nil, set, nil)
|
||||
tf := &BoolFlag{Name: "trueflag"}
|
||||
ff := &BoolFlag{Name: "falseflag"}
|
||||
expect(t, tf.Get(ctx), true)
|
||||
expect(t, ff.Get(ctx), false)
|
||||
}
|
||||
|
||||
func TestFlagsFromEnv(t *testing.T) {
|
||||
newSetFloat64Slice := func(defaults ...float64) Float64Slice {
|
||||
s := NewFloat64Slice(defaults...)
|
||||
@ -439,6 +450,14 @@ func TestStringFlagApply_SetsAllNames(t *testing.T) {
|
||||
expect(t, v, "YUUUU")
|
||||
}
|
||||
|
||||
func TestStringFlagValueFromContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.String("myflag", "foobar", "doc")
|
||||
ctx := NewContext(nil, set, nil)
|
||||
f := &StringFlag{Name: "myflag"}
|
||||
expect(t, f.Get(ctx), "foobar")
|
||||
}
|
||||
|
||||
var pathFlagTests = []struct {
|
||||
name string
|
||||
aliases []string
|
||||
@ -490,6 +509,14 @@ func TestPathFlagApply_SetsAllNames(t *testing.T) {
|
||||
expect(t, v, "/path/to/file/PATH")
|
||||
}
|
||||
|
||||
func TestPathFlagValueFromContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.String("myflag", "/my/path", "doc")
|
||||
ctx := NewContext(nil, set, nil)
|
||||
f := &PathFlag{Name: "myflag"}
|
||||
expect(t, f.Get(ctx), "/my/path")
|
||||
}
|
||||
|
||||
var _ = []struct {
|
||||
name string
|
||||
env string
|
||||
@ -603,6 +630,14 @@ func TestStringSliceFlagApply_DefaultValueWithDestination(t *testing.T) {
|
||||
expect(t, defValue, fl.Destination.Value())
|
||||
}
|
||||
|
||||
func TestStringSliceFlagValueFromContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Var(NewStringSlice("a", "b", "c"), "myflag", "doc")
|
||||
ctx := NewContext(nil, set, nil)
|
||||
f := &StringSliceFlag{Name: "myflag"}
|
||||
expect(t, f.Get(ctx), []string{"a", "b", "c"})
|
||||
}
|
||||
|
||||
var intFlagTests = []struct {
|
||||
name string
|
||||
expected string
|
||||
@ -652,6 +687,14 @@ func TestIntFlagApply_SetsAllNames(t *testing.T) {
|
||||
expect(t, v, 5)
|
||||
}
|
||||
|
||||
func TestIntFlagValueFromContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Int("myflag", 42, "doc")
|
||||
ctx := NewContext(nil, set, nil)
|
||||
f := &IntFlag{Name: "myflag"}
|
||||
expect(t, f.Get(ctx), 42)
|
||||
}
|
||||
|
||||
var int64FlagTests = []struct {
|
||||
name string
|
||||
expected string
|
||||
@ -690,6 +733,14 @@ func TestInt64FlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInt64FlagValueFromContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Int64("myflag", 42, "doc")
|
||||
ctx := NewContext(nil, set, nil)
|
||||
f := &Int64Flag{Name: "myflag"}
|
||||
expect(t, f.Get(ctx), int64(42))
|
||||
}
|
||||
|
||||
var uintFlagTests = []struct {
|
||||
name string
|
||||
expected string
|
||||
@ -728,6 +779,14 @@ func TestUintFlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUintFlagValueFromContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Uint("myflag", 42, "doc")
|
||||
ctx := NewContext(nil, set, nil)
|
||||
f := &UintFlag{Name: "myflag"}
|
||||
expect(t, f.Get(ctx), uint(42))
|
||||
}
|
||||
|
||||
var uint64FlagTests = []struct {
|
||||
name string
|
||||
expected string
|
||||
@ -766,6 +825,14 @@ func TestUint64FlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUint64FlagValueFromContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Uint64("myflag", 42, "doc")
|
||||
ctx := NewContext(nil, set, nil)
|
||||
f := &Uint64Flag{Name: "myflag"}
|
||||
expect(t, f.Get(ctx), uint64(42))
|
||||
}
|
||||
|
||||
var durationFlagTests = []struct {
|
||||
name string
|
||||
expected string
|
||||
@ -815,6 +882,14 @@ func TestDurationFlagApply_SetsAllNames(t *testing.T) {
|
||||
expect(t, v, time.Hour*30)
|
||||
}
|
||||
|
||||
func TestDurationFlagValueFromContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Duration("myflag", 42*time.Second, "doc")
|
||||
ctx := NewContext(nil, set, nil)
|
||||
f := &DurationFlag{Name: "myflag"}
|
||||
expect(t, f.Get(ctx), 42*time.Second)
|
||||
}
|
||||
|
||||
var intSliceFlagTests = []struct {
|
||||
name string
|
||||
aliases []string
|
||||
@ -904,6 +979,14 @@ func TestIntSliceFlag_SetFromParentContext(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntSliceFlagValueFromContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Var(NewIntSlice(1, 2, 3), "myflag", "doc")
|
||||
ctx := NewContext(nil, set, nil)
|
||||
f := &IntSliceFlag{Name: "myflag"}
|
||||
expect(t, f.Get(ctx), []int{1, 2, 3})
|
||||
}
|
||||
|
||||
var int64SliceFlagTests = []struct {
|
||||
name string
|
||||
aliases []string
|
||||
@ -1000,6 +1083,14 @@ func TestInt64SliceFlag_ReturnNil(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInt64SliceFlagValueFromContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Var(NewInt64Slice(1, 2, 3), "myflag", "doc")
|
||||
ctx := NewContext(nil, set, nil)
|
||||
f := &Int64SliceFlag{Name: "myflag"}
|
||||
expect(t, f.Get(ctx), []int64{1, 2, 3})
|
||||
}
|
||||
|
||||
var float64FlagTests = []struct {
|
||||
name string
|
||||
expected string
|
||||
@ -1049,6 +1140,14 @@ func TestFloat64FlagApply_SetsAllNames(t *testing.T) {
|
||||
expect(t, v, float64(43.33333))
|
||||
}
|
||||
|
||||
func TestFloat64FlagValueFromContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Float64("myflag", 1.23, "doc")
|
||||
ctx := NewContext(nil, set, nil)
|
||||
f := &Float64Flag{Name: "myflag"}
|
||||
expect(t, f.Get(ctx), 1.23)
|
||||
}
|
||||
|
||||
var float64SliceFlagTests = []struct {
|
||||
name string
|
||||
aliases []string
|
||||
@ -1090,6 +1189,14 @@ func TestFloat64SliceFlagWithEnvVarHelpOutput(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFloat64SliceFlagValueFromContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Var(NewFloat64Slice(1.23, 4.56), "myflag", "doc")
|
||||
ctx := NewContext(nil, set, nil)
|
||||
f := &Float64SliceFlag{Name: "myflag"}
|
||||
expect(t, f.Get(ctx), []float64{1.23, 4.56})
|
||||
}
|
||||
|
||||
var genericFlagTests = []struct {
|
||||
name string
|
||||
value Generic
|
||||
@ -1138,6 +1245,14 @@ func TestGenericFlagApply_SetsAllNames(t *testing.T) {
|
||||
expect(t, err, nil)
|
||||
}
|
||||
|
||||
func TestGenericFlagValueFromContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Var(&Parser{"abc", "def"}, "myflag", "doc")
|
||||
ctx := NewContext(nil, set, nil)
|
||||
f := &GenericFlag{Name: "myflag"}
|
||||
expect(t, f.Get(ctx), &Parser{"abc", "def"})
|
||||
}
|
||||
|
||||
func TestParseMultiString(t *testing.T) {
|
||||
_ = (&App{
|
||||
Flags: []Flag{
|
||||
@ -2165,6 +2280,15 @@ func TestTimestampFlagApply_Fail_Parse_Wrong_Time(t *testing.T) {
|
||||
expect(t, err, fmt.Errorf("invalid value \"2006-01-02T15:04:05Z\" for flag -time: parsing time \"2006-01-02T15:04:05Z\" as \"Jan 2, 2006 at 3:04pm (MST)\": cannot parse \"2006-01-02T15:04:05Z\" as \"Jan\""))
|
||||
}
|
||||
|
||||
func TestTimestampFlagValueFromContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
now := time.Now()
|
||||
set.Var(NewTimestamp(now), "myflag", "doc")
|
||||
ctx := NewContext(nil, set, nil)
|
||||
f := &TimestampFlag{Name: "myflag"}
|
||||
expect(t, f.Get(ctx), &now)
|
||||
}
|
||||
|
||||
type flagDefaultTestCase struct {
|
||||
name string
|
||||
flag Flag
|
||||
|
@ -58,38 +58,6 @@ func (t *Timestamp) Get() interface{} {
|
||||
return *t
|
||||
}
|
||||
|
||||
// TimestampFlag is a flag with type time
|
||||
type TimestampFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Layout string
|
||||
Value *Timestamp
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
Destination *Timestamp
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *TimestampFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *TimestampFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *TimestampFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *TimestampFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
@ -164,6 +132,11 @@ func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *TimestampFlag) Get(ctx *Context) *time.Time {
|
||||
return ctx.Timestamp(f.Name)
|
||||
}
|
||||
|
||||
// Timestamp gets the timestamp from a flag name
|
||||
func (cCtx *Context) Timestamp(name string) *time.Time {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
|
36
flag_uint.go
36
flag_uint.go
@ -6,37 +6,6 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// UintFlag is a flag with type uint
|
||||
type UintFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value uint
|
||||
DefaultText string
|
||||
Destination *uint
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *UintFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *UintFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *UintFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *UintFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
@ -101,6 +70,11 @@ func (f *UintFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *UintFlag) Get(ctx *Context) uint {
|
||||
return ctx.Uint(f.Name)
|
||||
}
|
||||
|
||||
// Uint looks up the value of a local UintFlag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Uint(name string) uint {
|
||||
|
@ -6,37 +6,6 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Uint64Flag is a flag with type uint64
|
||||
type Uint64Flag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value uint64
|
||||
DefaultText string
|
||||
Destination *uint64
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Uint64Flag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Uint64Flag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Uint64Flag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Uint64Flag) IsRequired() bool {
|
||||
return f.Required
|
||||
@ -101,6 +70,11 @@ func (f *Uint64Flag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Uint64Flag) Get(ctx *Context) uint64 {
|
||||
return ctx.Uint64(f.Name)
|
||||
}
|
||||
|
||||
// Uint64 looks up the value of a local Uint64Flag, returns
|
||||
// 0 if not found
|
||||
func (cCtx *Context) Uint64(name string) uint64 {
|
||||
|
1
go.mod
1
go.mod
@ -5,6 +5,7 @@ go 1.18
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.1.0
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1
|
||||
golang.org/x/text v0.3.7
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
|
6
go.sum
6
go.sum
@ -1,11 +1,13 @@
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
|
||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
|
2090
godoc-current.txt
Normal file
2090
godoc-current.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -6,19 +6,45 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var packages = []string{"cli", "altsrc"}
|
||||
const (
|
||||
badNewsEmoji = "🚨"
|
||||
goodNewsEmoji = "✨"
|
||||
checksPassedEmoji = "✅"
|
||||
|
||||
v2diffWarning = `
|
||||
# The unified diff above indicates that the public API surface area
|
||||
# has changed. If you feel that the changes are acceptable and adhere
|
||||
# to the semantic versioning promise of the v2.x series described in
|
||||
# docs/CONTRIBUTING.md, please run the following command to promote
|
||||
# the current go docs:
|
||||
#
|
||||
# make v2approve
|
||||
#
|
||||
`
|
||||
)
|
||||
|
||||
func main() {
|
||||
top, err := func() (string, error) {
|
||||
if v, err := sh("git", "rev-parse", "--show-toplevel"); err == nil {
|
||||
return strings.TrimSpace(v), nil
|
||||
}
|
||||
|
||||
return os.Getwd()
|
||||
}()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
app := cli.NewApp()
|
||||
|
||||
app.Name = "builder"
|
||||
@ -45,20 +71,52 @@ func main() {
|
||||
Name: "check-binary-size",
|
||||
Action: checkBinarySizeActionFunc,
|
||||
},
|
||||
{
|
||||
Name: "generate",
|
||||
Action: GenerateActionFunc,
|
||||
},
|
||||
{
|
||||
Name: "v2diff",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{Name: "color", Value: false},
|
||||
},
|
||||
Action: V2Diff,
|
||||
},
|
||||
{
|
||||
Name: "v2approve",
|
||||
Action: V2Approve,
|
||||
},
|
||||
}
|
||||
app.Flags = []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "tags",
|
||||
Usage: "set build tags",
|
||||
},
|
||||
&cli.PathFlag{
|
||||
Name: "top",
|
||||
Value: top,
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "packages",
|
||||
Value: cli.NewStringSlice("cli", "altsrc", "internal/build", "internal/genflags"),
|
||||
},
|
||||
}
|
||||
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func sh(exe string, args ...string) (string, error) {
|
||||
cmd := exec.Command(exe, args...)
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
fmt.Fprintf(os.Stderr, "# ---> %s\n", cmd)
|
||||
outBytes, err := cmd.Output()
|
||||
return string(outBytes), err
|
||||
}
|
||||
|
||||
func runCmd(arg string, args ...string) error {
|
||||
cmd := exec.Command(arg, args...)
|
||||
|
||||
@ -66,78 +124,63 @@ func runCmd(arg string, args ...string) error {
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
fmt.Fprintf(os.Stderr, "# ---> %s\n", cmd)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func VetActionFunc(_ *cli.Context) error {
|
||||
return runCmd("go", "vet")
|
||||
func VetActionFunc(cCtx *cli.Context) error {
|
||||
return runCmd("go", "vet", cCtx.Path("top")+"/...")
|
||||
}
|
||||
|
||||
func TestActionFunc(c *cli.Context) error {
|
||||
tags := c.String("tags")
|
||||
|
||||
for _, pkg := range packages {
|
||||
var packageName string
|
||||
for _, pkg := range c.StringSlice("packages") {
|
||||
packageName := "github.com/urfave/cli/v2"
|
||||
|
||||
if pkg == "cli" {
|
||||
packageName = "github.com/urfave/cli/v2"
|
||||
} else {
|
||||
if pkg != "cli" {
|
||||
packageName = fmt.Sprintf("github.com/urfave/cli/v2/%s", pkg)
|
||||
}
|
||||
|
||||
coverProfile := fmt.Sprintf("--coverprofile=%s.coverprofile", pkg)
|
||||
|
||||
err := runCmd("go", "test", "-tags", tags, "-v", coverProfile, packageName)
|
||||
if err != nil {
|
||||
if err := runCmd(
|
||||
"go", "test",
|
||||
"-tags", tags,
|
||||
"-v",
|
||||
"--coverprofile", pkg+".coverprofile",
|
||||
"--covermode", "count",
|
||||
"--cover", packageName,
|
||||
packageName,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return testCleanup()
|
||||
return testCleanup(c.StringSlice("packages"))
|
||||
}
|
||||
|
||||
func testCleanup() error {
|
||||
var out bytes.Buffer
|
||||
func testCleanup(packages []string) error {
|
||||
out := &bytes.Buffer{}
|
||||
|
||||
fmt.Fprintf(out, "mode: count\n")
|
||||
|
||||
for _, pkg := range packages {
|
||||
file, err := os.Open(fmt.Sprintf("%s.coverprofile", pkg))
|
||||
filename := pkg + ".coverprofile"
|
||||
|
||||
lineBytes, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lines := strings.Split(string(lineBytes), "\n")
|
||||
|
||||
out.Write(b)
|
||||
err = file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(out, strings.Join(lines[1:], "\n"))
|
||||
|
||||
err = os.Remove(fmt.Sprintf("%s.coverprofile", pkg))
|
||||
if err != nil {
|
||||
if err := os.Remove(filename); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
outFile, err := os.Create("coverage.txt")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = out.WriteTo(outFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = outFile.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return os.WriteFile("coverage.txt", out.Bytes(), 0644)
|
||||
}
|
||||
|
||||
func GfmrunActionFunc(c *cli.Context) error {
|
||||
@ -179,17 +222,7 @@ func TocActionFunc(c *cli.Context) error {
|
||||
filename = "README.md"
|
||||
}
|
||||
|
||||
err := runCmd("markdown-toc", "-i", filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = runCmd("git", "diff", "--exit-code")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return runCmd("markdown-toc", "-i", filename)
|
||||
}
|
||||
|
||||
// checkBinarySizeActionFunc checks the size of an example binary to ensure that we are keeping size down
|
||||
@ -201,16 +234,18 @@ func checkBinarySizeActionFunc(c *cli.Context) (err error) {
|
||||
cliBuiltFilePath = "./internal/example-cli/built-example"
|
||||
helloSourceFilePath = "./internal/example-hello-world/example-hello-world.go"
|
||||
helloBuiltFilePath = "./internal/example-hello-world/built-example"
|
||||
desiredMinBinarySize = 1.675
|
||||
desiredMaxBinarySize = 2.2
|
||||
badNewsEmoji = "🚨"
|
||||
goodNewsEmoji = "✨"
|
||||
checksPassedEmoji = "✅"
|
||||
mbStringFormatter = "%.1fMB"
|
||||
)
|
||||
|
||||
desiredMinBinarySize := 1.675
|
||||
|
||||
tags := c.String("tags")
|
||||
|
||||
if strings.Contains(tags, "urfave_cli_no_docs") {
|
||||
desiredMinBinarySize = 1.39
|
||||
}
|
||||
|
||||
// get cli example size
|
||||
cliSize, err := getSize(cliSourceFilePath, cliBuiltFilePath, tags)
|
||||
if err != nil {
|
||||
@ -280,6 +315,69 @@ func checkBinarySizeActionFunc(c *cli.Context) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func GenerateActionFunc(cCtx *cli.Context) error {
|
||||
top := cCtx.Path("top")
|
||||
|
||||
cliDocs, err := sh("go", "doc", "-all", top)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
altsrcDocs, err := sh("go", "doc", "-all", filepath.Join(top, "altsrc"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.WriteFile(
|
||||
filepath.Join(top, "godoc-current.txt"),
|
||||
[]byte(cliDocs+altsrcDocs),
|
||||
0644,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return runCmd("go", "generate", cCtx.Path("top")+"/...")
|
||||
}
|
||||
|
||||
func V2Diff(cCtx *cli.Context) error {
|
||||
os.Chdir(cCtx.Path("top"))
|
||||
|
||||
err := runCmd(
|
||||
"diff",
|
||||
"--ignore-all-space",
|
||||
"--minimal",
|
||||
"--color="+func() string {
|
||||
if cCtx.Bool("color") {
|
||||
return "always"
|
||||
}
|
||||
return "auto"
|
||||
}(),
|
||||
"--unified",
|
||||
"--label=a/godoc",
|
||||
filepath.Join("testdata", "godoc-v2.x.txt"),
|
||||
"--label=b/godoc",
|
||||
"godoc-current.txt",
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("# %v ---> Hey! <---\n", badNewsEmoji)
|
||||
fmt.Println(strings.TrimSpace(v2diffWarning))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func V2Approve(cCtx *cli.Context) error {
|
||||
top := cCtx.Path("top")
|
||||
|
||||
return runCmd(
|
||||
"cp",
|
||||
"-v",
|
||||
filepath.Join(top, "godoc-current.txt"),
|
||||
filepath.Join(top, "testdata", "godoc-v2.x.txt"),
|
||||
)
|
||||
}
|
||||
|
||||
func getSize(sourcePath string, builtPath string, tags string) (size int64, err error) {
|
||||
// build example binary
|
||||
err = runCmd("go", "build", "-tags", tags, "-o", builtPath, "-ldflags", "-s -w", sourcePath)
|
||||
|
163
internal/genflags/cmd/genflags/main.go
Normal file
163
internal/genflags/cmd/genflags/main.go
Normal file
@ -0,0 +1,163 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
_ "embed"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"text/template"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v2/internal/genflags"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultPackageName = "cli"
|
||||
)
|
||||
|
||||
func sh(ctx context.Context, exe string, args ...string) (string, error) {
|
||||
cmd := exec.CommandContext(ctx, exe, args...)
|
||||
cmd.Stderr = os.Stderr
|
||||
outBytes, err := cmd.Output()
|
||||
return string(outBytes), err
|
||||
}
|
||||
|
||||
func main() {
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
top := "../../"
|
||||
if v, err := sh(ctx, "git", "rev-parse", "--show-toplevel"); err == nil {
|
||||
top = strings.TrimSpace(v)
|
||||
}
|
||||
|
||||
app := &cli.App{
|
||||
Name: "genflags",
|
||||
Usage: "Generate flag types for urfave/cli",
|
||||
Flags: []cli.Flag{
|
||||
&cli.PathFlag{
|
||||
Name: "flag-spec-yaml",
|
||||
Aliases: []string{"f"},
|
||||
Value: filepath.Join(top, "flag-spec.yaml"),
|
||||
},
|
||||
&cli.PathFlag{
|
||||
Name: "generated-output",
|
||||
Aliases: []string{"o"},
|
||||
Value: filepath.Join(top, "zz_generated.flags.go"),
|
||||
},
|
||||
&cli.PathFlag{
|
||||
Name: "generated-test-output",
|
||||
Aliases: []string{"t"},
|
||||
Value: filepath.Join(top, "zz_generated.flags_test.go"),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "generated-package-name",
|
||||
Aliases: []string{"p"},
|
||||
Value: defaultPackageName,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "generated-test-package-name",
|
||||
Aliases: []string{"T"},
|
||||
Value: defaultPackageName + "_test",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "urfave-cli-namespace",
|
||||
Aliases: []string{"n"},
|
||||
Value: "",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "urfave-cli-test-namespace",
|
||||
Aliases: []string{"N"},
|
||||
Value: "cli.",
|
||||
},
|
||||
},
|
||||
Action: runGenFlags,
|
||||
}
|
||||
|
||||
if err := app.RunContext(ctx, os.Args); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func runGenFlags(cCtx *cli.Context) error {
|
||||
specBytes, err := os.ReadFile(cCtx.Path("flag-spec-yaml"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
spec := &genflags.Spec{}
|
||||
if err := yaml.Unmarshal(specBytes, spec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cCtx.IsSet("generated-package-name") {
|
||||
spec.PackageName = strings.TrimSpace(cCtx.String("generated-package-name"))
|
||||
}
|
||||
|
||||
if strings.TrimSpace(spec.PackageName) == "" {
|
||||
spec.PackageName = defaultPackageName
|
||||
}
|
||||
|
||||
if cCtx.IsSet("generated-test-package-name") {
|
||||
spec.TestPackageName = strings.TrimSpace(cCtx.String("generated-test-package-name"))
|
||||
}
|
||||
|
||||
if strings.TrimSpace(spec.TestPackageName) == "" {
|
||||
spec.TestPackageName = defaultPackageName + "_test"
|
||||
}
|
||||
|
||||
if cCtx.IsSet("urfave-cli-namespace") {
|
||||
spec.UrfaveCLINamespace = strings.TrimSpace(cCtx.String("urfave-cli-namespace"))
|
||||
}
|
||||
|
||||
if cCtx.IsSet("urfave-cli-test-namespace") {
|
||||
spec.UrfaveCLITestNamespace = strings.TrimSpace(cCtx.String("urfave-cli-test-namespace"))
|
||||
} else {
|
||||
spec.UrfaveCLITestNamespace = "cli."
|
||||
}
|
||||
|
||||
genTmpl, err := template.New("gen").Parse(genflags.TemplateString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
genTestTmpl, err := template.New("gen_test").Parse(genflags.TestTemplateString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
genBuf := &bytes.Buffer{}
|
||||
if err := genTmpl.Execute(genBuf, spec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
genTestBuf := &bytes.Buffer{}
|
||||
if err := genTestTmpl.Execute(genTestBuf, spec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.WriteFile(cCtx.Path("generated-output"), genBuf.Bytes(), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.WriteFile(cCtx.Path("generated-test-output"), genTestBuf.Bytes(), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := sh(cCtx.Context, "goimports", "-w", cCtx.Path("generated-output")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := sh(cCtx.Context, "goimports", "-w", cCtx.Path("generated-test-output")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
53
internal/genflags/generated.gotmpl
Normal file
53
internal/genflags/generated.gotmpl
Normal file
@ -0,0 +1,53 @@
|
||||
// WARNING: this file is generated. DO NOT EDIT
|
||||
|
||||
package {{.PackageName}}
|
||||
|
||||
{{range .SortedFlagTypes}}
|
||||
// {{.TypeName}} is a flag with type {{if .ValuePointer}}*{{end}}{{.GoType}}
|
||||
type {{.TypeName}} struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value {{if .ValuePointer}}*{{end}}{{.GoType}}
|
||||
Destination *{{.GoType}}
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
{{range .StructFields}}
|
||||
{{.Name}} {{.Type}}
|
||||
{{end}}
|
||||
}
|
||||
|
||||
{{if .GenerateFmtStringerInterface}}
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *{{.TypeName}}) String() string {
|
||||
return {{$.UrfaveCLINamespace}}FlagStringer(f)
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{if .GenerateFlagInterface}}
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *{{.TypeName}}) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *{{.TypeName}}) Names() []string {
|
||||
return {{$.UrfaveCLINamespace}}FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
{{end}}{{/* /if .GenerateFlagInterface */}}
|
||||
{{end}}{{/* /range .SortedFlagTypes */}}
|
||||
|
||||
// vim{{/* 👻 */}}:ro
|
||||
{{/*
|
||||
vim:filetype=gotexttmpl
|
||||
*/}}
|
27
internal/genflags/generated_test.gotmpl
Normal file
27
internal/genflags/generated_test.gotmpl
Normal file
@ -0,0 +1,27 @@
|
||||
// WARNING: this file is generated. DO NOT EDIT
|
||||
|
||||
package {{.TestPackageName}}
|
||||
|
||||
{{range .SortedFlagTypes}}
|
||||
{{if .GenerateFlagInterface}}
|
||||
func Test{{.TypeName}}_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f {{$.UrfaveCLITestNamespace}}Flag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{if .GenerateFmtStringerInterface}}
|
||||
func Test{{.TypeName}}_SatisfiesFmtStringerInterface(t *testing.T) {
|
||||
var f fmt.Stringer = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{}
|
||||
|
||||
_ = f.String()
|
||||
}
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
// vim{{/* 👻 */}}:ro
|
||||
{{/*
|
||||
vim:filetype=gotexttmpl
|
||||
*/}}
|
34
internal/genflags/package.go
Normal file
34
internal/genflags/package.go
Normal file
@ -0,0 +1,34 @@
|
||||
package genflags
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed generated.gotmpl
|
||||
TemplateString string
|
||||
|
||||
//go:embed generated_test.gotmpl
|
||||
TestTemplateString string
|
||||
|
||||
titler = cases.Title(language.Und, cases.NoLower)
|
||||
)
|
||||
|
||||
func TypeName(goType string, fc *FlagTypeConfig) string {
|
||||
if fc != nil && strings.TrimSpace(fc.TypeName) != "" {
|
||||
return strings.TrimSpace(fc.TypeName)
|
||||
}
|
||||
|
||||
dotSplit := strings.Split(goType, ".")
|
||||
goType = dotSplit[len(dotSplit)-1]
|
||||
|
||||
if strings.HasPrefix(goType, "[]") {
|
||||
return titler.String(strings.TrimPrefix(goType, "[]")) + "SliceFlag"
|
||||
}
|
||||
|
||||
return titler.String(goType) + "Flag"
|
||||
}
|
41
internal/genflags/package_test.go
Normal file
41
internal/genflags/package_test.go
Normal file
@ -0,0 +1,41 @@
|
||||
package genflags_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/urfave/cli/v2/internal/genflags"
|
||||
)
|
||||
|
||||
func TestTypeName(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
gt string
|
||||
fc *genflags.FlagTypeConfig
|
||||
expected string
|
||||
}{
|
||||
{gt: "int", fc: nil, expected: "IntFlag"},
|
||||
{gt: "int", fc: &genflags.FlagTypeConfig{}, expected: "IntFlag"},
|
||||
{gt: "int", fc: &genflags.FlagTypeConfig{TypeName: "VeryIntyFlag"}, expected: "VeryIntyFlag"},
|
||||
{gt: "[]bool", fc: nil, expected: "BoolSliceFlag"},
|
||||
{gt: "[]bool", fc: &genflags.FlagTypeConfig{}, expected: "BoolSliceFlag"},
|
||||
{gt: "[]bool", fc: &genflags.FlagTypeConfig{TypeName: "ManyTruthsFlag"}, expected: "ManyTruthsFlag"},
|
||||
{gt: "time.Rumination", fc: nil, expected: "RuminationFlag"},
|
||||
{gt: "time.Rumination", fc: &genflags.FlagTypeConfig{}, expected: "RuminationFlag"},
|
||||
{gt: "time.Rumination", fc: &genflags.FlagTypeConfig{TypeName: "PonderFlag"}, expected: "PonderFlag"},
|
||||
} {
|
||||
t.Run(
|
||||
fmt.Sprintf("type=%s,cfg=%v", tc.gt, func() string {
|
||||
if tc.fc != nil {
|
||||
return tc.fc.TypeName
|
||||
}
|
||||
return "nil"
|
||||
}()),
|
||||
func(ct *testing.T) {
|
||||
actual := genflags.TypeName(tc.gt, tc.fc)
|
||||
if tc.expected != actual {
|
||||
ct.Errorf("expected %q, got %q", tc.expected, actual)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
100
internal/genflags/spec.go
Normal file
100
internal/genflags/spec.go
Normal file
@ -0,0 +1,100 @@
|
||||
package genflags
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Spec struct {
|
||||
FlagTypes map[string]*FlagTypeConfig `yaml:"flag_types"`
|
||||
PackageName string `yaml:"package_name"`
|
||||
TestPackageName string `yaml:"test_package_name"`
|
||||
UrfaveCLINamespace string `yaml:"urfave_cli_namespace"`
|
||||
UrfaveCLITestNamespace string `yaml:"urfave_cli_test_namespace"`
|
||||
}
|
||||
|
||||
func (gfs *Spec) SortedFlagTypes() []*FlagType {
|
||||
typeNames := []string{}
|
||||
|
||||
for name := range gfs.FlagTypes {
|
||||
if strings.HasPrefix(name, "[]") {
|
||||
name = strings.TrimPrefix(name, "[]") + "Slice"
|
||||
}
|
||||
|
||||
typeNames = append(typeNames, name)
|
||||
}
|
||||
|
||||
sort.Strings(typeNames)
|
||||
|
||||
ret := make([]*FlagType, len(typeNames))
|
||||
|
||||
for i, typeName := range typeNames {
|
||||
ret[i] = &FlagType{
|
||||
GoType: typeName,
|
||||
Config: gfs.FlagTypes[typeName],
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
type FlagTypeConfig struct {
|
||||
SkipInterfaces []string `yaml:"skip_interfaces"`
|
||||
StructFields []*FlagStructField `yaml:"struct_fields"`
|
||||
TypeName string `yaml:"type_name"`
|
||||
ValuePointer bool `yaml:"value_pointer"`
|
||||
}
|
||||
|
||||
type FlagStructField struct {
|
||||
Name string
|
||||
Type string
|
||||
}
|
||||
|
||||
type FlagType struct {
|
||||
GoType string
|
||||
Config *FlagTypeConfig
|
||||
}
|
||||
|
||||
func (ft *FlagType) StructFields() []*FlagStructField {
|
||||
if ft.Config == nil || ft.Config.StructFields == nil {
|
||||
return []*FlagStructField{}
|
||||
}
|
||||
|
||||
return ft.Config.StructFields
|
||||
}
|
||||
|
||||
func (ft *FlagType) ValuePointer() bool {
|
||||
if ft.Config == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return ft.Config.ValuePointer
|
||||
}
|
||||
|
||||
func (ft *FlagType) TypeName() string {
|
||||
return TypeName(ft.GoType, ft.Config)
|
||||
}
|
||||
|
||||
func (ft *FlagType) GenerateFmtStringerInterface() bool {
|
||||
return ft.skipInterfaceNamed("fmt.Stringer")
|
||||
}
|
||||
|
||||
func (ft *FlagType) GenerateFlagInterface() bool {
|
||||
return ft.skipInterfaceNamed("Flag")
|
||||
}
|
||||
|
||||
func (ft *FlagType) skipInterfaceNamed(name string) bool {
|
||||
if ft.Config == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
lowName := strings.ToLower(name)
|
||||
|
||||
for _, interfaceName := range ft.Config.SkipInterfaces {
|
||||
if strings.ToLower(interfaceName) == lowName {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
112
internal/genflags/spec_test.go
Normal file
112
internal/genflags/spec_test.go
Normal file
@ -0,0 +1,112 @@
|
||||
package genflags_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/urfave/cli/v2/internal/genflags"
|
||||
)
|
||||
|
||||
func TestSpec_SortedFlagTypes(t *testing.T) {
|
||||
spec := &genflags.Spec{
|
||||
FlagTypes: map[string]*genflags.FlagTypeConfig{
|
||||
"nerf": &genflags.FlagTypeConfig{},
|
||||
"gerf": nil,
|
||||
},
|
||||
}
|
||||
|
||||
actual := spec.SortedFlagTypes()
|
||||
expected := []*genflags.FlagType{
|
||||
{
|
||||
GoType: "gerf",
|
||||
Config: nil,
|
||||
},
|
||||
{
|
||||
GoType: "nerf",
|
||||
Config: &genflags.FlagTypeConfig{},
|
||||
},
|
||||
}
|
||||
if !reflect.DeepEqual(expected, actual) {
|
||||
t.Errorf("expected %#v, got %#v", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func genFlagType() *genflags.FlagType {
|
||||
return &genflags.FlagType{
|
||||
GoType: "blerf",
|
||||
Config: &genflags.FlagTypeConfig{
|
||||
SkipInterfaces: []string{"fmt.Stringer"},
|
||||
StructFields: []*genflags.FlagStructField{
|
||||
{
|
||||
Name: "Foibles",
|
||||
Type: "int",
|
||||
},
|
||||
{
|
||||
Name: "Hoopled",
|
||||
Type: "bool",
|
||||
},
|
||||
},
|
||||
TypeName: "YeOldeBlerfFlag",
|
||||
ValuePointer: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlagType_StructFields(t *testing.T) {
|
||||
ft := genFlagType()
|
||||
|
||||
sf := ft.StructFields()
|
||||
if 2 != len(sf) {
|
||||
t.Errorf("expected 2 struct fields, got %v", len(sf))
|
||||
return
|
||||
}
|
||||
|
||||
if "Foibles" != sf[0].Name {
|
||||
t.Errorf("expected struct field order to be retained")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlagType_ValuePointer(t *testing.T) {
|
||||
ft := genFlagType()
|
||||
|
||||
if !ft.ValuePointer() {
|
||||
t.Errorf("expected ValuePointer to be true")
|
||||
return
|
||||
}
|
||||
|
||||
ft.Config = nil
|
||||
|
||||
if ft.ValuePointer() {
|
||||
t.Errorf("expected ValuePointer to be false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlagType_GenerateFmtStringerInterface(t *testing.T) {
|
||||
ft := genFlagType()
|
||||
|
||||
if ft.GenerateFmtStringerInterface() {
|
||||
t.Errorf("expected GenerateFmtStringerInterface to be false")
|
||||
return
|
||||
}
|
||||
|
||||
ft.Config = nil
|
||||
|
||||
if !ft.GenerateFmtStringerInterface() {
|
||||
t.Errorf("expected GenerateFmtStringerInterface to be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlagType_GenerateFlagInterface(t *testing.T) {
|
||||
ft := genFlagType()
|
||||
|
||||
if !ft.GenerateFlagInterface() {
|
||||
t.Errorf("expected GenerateFlagInterface to be true")
|
||||
return
|
||||
}
|
||||
|
||||
ft.Config = nil
|
||||
|
||||
if !ft.GenerateFlagInterface() {
|
||||
t.Errorf("expected GenerateFlagInterface to be true")
|
||||
}
|
||||
}
|
2090
testdata/godoc-v2.x.txt
vendored
Normal file
2090
testdata/godoc-v2.x.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
507
zz_generated.flags.go
Normal file
507
zz_generated.flags.go
Normal file
@ -0,0 +1,507 @@
|
||||
// WARNING: this file is generated. DO NOT EDIT
|
||||
|
||||
package cli
|
||||
|
||||
import "time"
|
||||
|
||||
// Float64SliceFlag is a flag with type *Float64Slice
|
||||
type Float64SliceFlag struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value *Float64Slice
|
||||
Destination *Float64Slice
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Float64SliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Float64SliceFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// GenericFlag is a flag with type Generic
|
||||
type GenericFlag struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value Generic
|
||||
Destination *Generic
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
TakesFile bool
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *GenericFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *GenericFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *GenericFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// Int64SliceFlag is a flag with type *Int64Slice
|
||||
type Int64SliceFlag struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value *Int64Slice
|
||||
Destination *Int64Slice
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Int64SliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Int64SliceFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IntSliceFlag is a flag with type *IntSlice
|
||||
type IntSliceFlag struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value *IntSlice
|
||||
Destination *IntSlice
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *IntSliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *IntSliceFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// PathFlag is a flag with type Path
|
||||
type PathFlag struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value Path
|
||||
Destination *Path
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
TakesFile bool
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *PathFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *PathFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *PathFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// StringSliceFlag is a flag with type *StringSlice
|
||||
type StringSliceFlag struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value *StringSlice
|
||||
Destination *StringSlice
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
TakesFile bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *StringSliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *StringSliceFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// TimestampFlag is a flag with type *Timestamp
|
||||
type TimestampFlag struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value *Timestamp
|
||||
Destination *Timestamp
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
Layout string
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *TimestampFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *TimestampFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *TimestampFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// BoolFlag is a flag with type bool
|
||||
type BoolFlag struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value bool
|
||||
Destination *bool
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *BoolFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *BoolFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *BoolFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// Float64Flag is a flag with type float64
|
||||
type Float64Flag struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value float64
|
||||
Destination *float64
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *Float64Flag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Float64Flag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Float64Flag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IntFlag is a flag with type int
|
||||
type IntFlag struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value int
|
||||
Destination *int
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *IntFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *IntFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *IntFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// Int64Flag is a flag with type int64
|
||||
type Int64Flag struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value int64
|
||||
Destination *int64
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *Int64Flag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Int64Flag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Int64Flag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// StringFlag is a flag with type string
|
||||
type StringFlag struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value string
|
||||
Destination *string
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
TakesFile bool
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *StringFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *StringFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *StringFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// DurationFlag is a flag with type time.Duration
|
||||
type DurationFlag struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value time.Duration
|
||||
Destination *time.Duration
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *DurationFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *DurationFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *DurationFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// UintFlag is a flag with type uint
|
||||
type UintFlag struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value uint
|
||||
Destination *uint
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *UintFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *UintFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *UintFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// Uint64Flag is a flag with type uint64
|
||||
type Uint64Flag struct {
|
||||
Name string
|
||||
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value uint64
|
||||
Destination *uint64
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *Uint64Flag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Uint64Flag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Uint64Flag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// vim:ro
|
183
zz_generated.flags_test.go
Normal file
183
zz_generated.flags_test.go
Normal file
@ -0,0 +1,183 @@
|
||||
// WARNING: this file is generated. DO NOT EDIT
|
||||
|
||||
package cli_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
func TestFloat64SliceFlag_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f cli.Flag = &cli.Float64SliceFlag{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func TestGenericFlag_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f cli.Flag = &cli.GenericFlag{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func TestGenericFlag_SatisfiesFmtStringerInterface(t *testing.T) {
|
||||
var f fmt.Stringer = &cli.GenericFlag{}
|
||||
|
||||
_ = f.String()
|
||||
}
|
||||
|
||||
func TestInt64SliceFlag_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f cli.Flag = &cli.Int64SliceFlag{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func TestIntSliceFlag_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f cli.Flag = &cli.IntSliceFlag{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func TestPathFlag_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f cli.Flag = &cli.PathFlag{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func TestPathFlag_SatisfiesFmtStringerInterface(t *testing.T) {
|
||||
var f fmt.Stringer = &cli.PathFlag{}
|
||||
|
||||
_ = f.String()
|
||||
}
|
||||
|
||||
func TestStringSliceFlag_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f cli.Flag = &cli.StringSliceFlag{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func TestTimestampFlag_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f cli.Flag = &cli.TimestampFlag{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func TestTimestampFlag_SatisfiesFmtStringerInterface(t *testing.T) {
|
||||
var f fmt.Stringer = &cli.TimestampFlag{}
|
||||
|
||||
_ = f.String()
|
||||
}
|
||||
|
||||
func TestBoolFlag_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f cli.Flag = &cli.BoolFlag{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func TestBoolFlag_SatisfiesFmtStringerInterface(t *testing.T) {
|
||||
var f fmt.Stringer = &cli.BoolFlag{}
|
||||
|
||||
_ = f.String()
|
||||
}
|
||||
|
||||
func TestFloat64Flag_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f cli.Flag = &cli.Float64Flag{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func TestFloat64Flag_SatisfiesFmtStringerInterface(t *testing.T) {
|
||||
var f fmt.Stringer = &cli.Float64Flag{}
|
||||
|
||||
_ = f.String()
|
||||
}
|
||||
|
||||
func TestIntFlag_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f cli.Flag = &cli.IntFlag{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func TestIntFlag_SatisfiesFmtStringerInterface(t *testing.T) {
|
||||
var f fmt.Stringer = &cli.IntFlag{}
|
||||
|
||||
_ = f.String()
|
||||
}
|
||||
|
||||
func TestInt64Flag_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f cli.Flag = &cli.Int64Flag{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func TestInt64Flag_SatisfiesFmtStringerInterface(t *testing.T) {
|
||||
var f fmt.Stringer = &cli.Int64Flag{}
|
||||
|
||||
_ = f.String()
|
||||
}
|
||||
|
||||
func TestStringFlag_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f cli.Flag = &cli.StringFlag{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func TestStringFlag_SatisfiesFmtStringerInterface(t *testing.T) {
|
||||
var f fmt.Stringer = &cli.StringFlag{}
|
||||
|
||||
_ = f.String()
|
||||
}
|
||||
|
||||
func TestDurationFlag_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f cli.Flag = &cli.DurationFlag{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func TestDurationFlag_SatisfiesFmtStringerInterface(t *testing.T) {
|
||||
var f fmt.Stringer = &cli.DurationFlag{}
|
||||
|
||||
_ = f.String()
|
||||
}
|
||||
|
||||
func TestUintFlag_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f cli.Flag = &cli.UintFlag{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func TestUintFlag_SatisfiesFmtStringerInterface(t *testing.T) {
|
||||
var f fmt.Stringer = &cli.UintFlag{}
|
||||
|
||||
_ = f.String()
|
||||
}
|
||||
|
||||
func TestUint64Flag_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f cli.Flag = &cli.Uint64Flag{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func TestUint64Flag_SatisfiesFmtStringerInterface(t *testing.T) {
|
||||
var f fmt.Stringer = &cli.Uint64Flag{}
|
||||
|
||||
_ = f.String()
|
||||
}
|
||||
|
||||
// vim:ro
|
Loading…
Reference in New Issue
Block a user