Merge pull request #1382 from urfave/generating-flags-again
Generate flag types (again?)
This commit is contained in:
commit
48f612c60d
5
.github/workflows/cli.yml
vendored
5
.github/workflows/cli.yml
vendored
@ -87,3 +87,8 @@ jobs:
|
|||||||
|
|
||||||
- name: toc
|
- name: toc
|
||||||
run: go run internal/build/build.go toc docs/v2/manual.md
|
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
|
||||||
|
40
Makefile
Normal file
40
Makefile
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# 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 lint tag-test test check-bin tag-check-bin gfmrun toc
|
||||||
|
|
||||||
|
.PHONY: generate
|
||||||
|
generate:
|
||||||
|
go run internal/build/build.go generate
|
||||||
|
|
||||||
|
.PHONY: lint
|
||||||
|
lint:
|
||||||
|
go run internal/build/build.go vet
|
||||||
|
|
||||||
|
.PHONY: tag-test
|
||||||
|
tag-test:
|
||||||
|
go run internal/build/build.go -tags urfave_cli_no_docs test
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test:
|
||||||
|
go run internal/build/build.go test
|
||||||
|
|
||||||
|
.PHONY: check-bin
|
||||||
|
check-bin:
|
||||||
|
go run internal/build/build.go check-binary-size
|
||||||
|
|
||||||
|
.PHONY: tag-check-bin
|
||||||
|
tag-check-bin:
|
||||||
|
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
|
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,102 @@
|
|||||||
## Contributing
|
## 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
|
> As a general guiding principle, the current maintainers may be notified via the
|
||||||
give it a code review and make sure that it does not break backwards
|
> @urfave/cli GitHub team.
|
||||||
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.
|
|
||||||
|
|
||||||
If you have contributed something significant to the project, we will most
|
All of the current maintainers are *volunteers* who live in various timezones with
|
||||||
likely add you as a collaborator. As a collaborator you are given the ability
|
different scheduling needs, so please understand that your contribution or question may
|
||||||
to merge others pull requests. It is very important that new code does not
|
not get a response for many days.
|
||||||
break existing code, so be careful about what code you do choose to merge.
|
|
||||||
|
|
||||||
If you feel like you have contributed to the project but have not yet been added
|
### semantic versioning adherence
|
||||||
as a collaborator, we probably forgot to add you :sweat_smile:. Please open an
|
|
||||||
issue!
|
The `urfave/cli` project strives to strictly adhere to semantic versioning. 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`
|
||||||
|
|
||||||
|
#### `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).
|
||||||
|
|
||||||
|
#### 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
|
return str + envText
|
||||||
}
|
}
|
||||||
|
|
||||||
func flagNames(name string, aliases []string) []string {
|
func FlagNames(name string, aliases []string) []string {
|
||||||
var ret []string
|
var ret []string
|
||||||
|
|
||||||
for _, part := range append([]string{name}, aliases...) {
|
for _, part := range append([]string{name}, aliases...) {
|
||||||
|
31
flag_bool.go
31
flag_bool.go
@ -6,37 +6,6 @@ import (
|
|||||||
"strconv"
|
"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
|
// IsRequired returns whether or not the flag is required
|
||||||
func (f *BoolFlag) IsRequired() bool {
|
func (f *BoolFlag) IsRequired() bool {
|
||||||
return f.Required
|
return f.Required
|
||||||
|
@ -6,37 +6,6 @@ import (
|
|||||||
"time"
|
"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
|
// IsRequired returns whether or not the flag is required
|
||||||
func (f *DurationFlag) IsRequired() bool {
|
func (f *DurationFlag) IsRequired() bool {
|
||||||
return f.Required
|
return f.Required
|
||||||
|
@ -6,37 +6,6 @@ import (
|
|||||||
"strconv"
|
"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
|
// IsRequired returns whether or not the flag is required
|
||||||
func (f *Float64Flag) IsRequired() bool {
|
func (f *Float64Flag) IsRequired() bool {
|
||||||
return f.Required
|
return f.Required
|
||||||
|
@ -75,36 +75,12 @@ func (f *Float64Slice) Get() interface{} {
|
|||||||
return *f
|
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
|
// String returns a readable representation of this value
|
||||||
// (for usage defaults)
|
// (for usage defaults)
|
||||||
func (f *Float64SliceFlag) String() string {
|
func (f *Float64SliceFlag) String() string {
|
||||||
return withEnvHint(f.GetEnvVars(), stringifyFloat64SliceFlag(f))
|
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
|
// IsRequired returns whether or not the flag is required
|
||||||
func (f *Float64SliceFlag) IsRequired() bool {
|
func (f *Float64SliceFlag) IsRequired() bool {
|
||||||
return f.Required
|
return f.Required
|
||||||
|
@ -11,37 +11,6 @@ type Generic interface {
|
|||||||
String() string
|
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
|
// IsRequired returns whether or not the flag is required
|
||||||
func (f *GenericFlag) IsRequired() bool {
|
func (f *GenericFlag) IsRequired() bool {
|
||||||
return f.Required
|
return f.Required
|
||||||
|
31
flag_int.go
31
flag_int.go
@ -6,37 +6,6 @@ import (
|
|||||||
"strconv"
|
"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
|
// IsRequired returns whether or not the flag is required
|
||||||
func (f *IntFlag) IsRequired() bool {
|
func (f *IntFlag) IsRequired() bool {
|
||||||
return f.Required
|
return f.Required
|
||||||
|
@ -6,37 +6,6 @@ import (
|
|||||||
"strconv"
|
"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
|
// IsRequired returns whether or not the flag is required
|
||||||
func (f *Int64Flag) IsRequired() bool {
|
func (f *Int64Flag) IsRequired() bool {
|
||||||
return f.Required
|
return f.Required
|
||||||
|
@ -76,36 +76,12 @@ func (i *Int64Slice) Get() interface{} {
|
|||||||
return *i
|
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
|
// String returns a readable representation of this value
|
||||||
// (for usage defaults)
|
// (for usage defaults)
|
||||||
func (f *Int64SliceFlag) String() string {
|
func (f *Int64SliceFlag) String() string {
|
||||||
return withEnvHint(f.GetEnvVars(), stringifyInt64SliceFlag(f))
|
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
|
// IsRequired returns whether or not the flag is required
|
||||||
func (f *Int64SliceFlag) IsRequired() bool {
|
func (f *Int64SliceFlag) IsRequired() bool {
|
||||||
return f.Required
|
return f.Required
|
||||||
|
@ -87,36 +87,12 @@ func (i *IntSlice) Get() interface{} {
|
|||||||
return *i
|
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
|
// String returns a readable representation of this value
|
||||||
// (for usage defaults)
|
// (for usage defaults)
|
||||||
func (f *IntSliceFlag) String() string {
|
func (f *IntSliceFlag) String() string {
|
||||||
return withEnvHint(f.GetEnvVars(), stringifyIntSliceFlag(f))
|
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
|
// IsRequired returns whether or not the flag is required
|
||||||
func (f *IntSliceFlag) IsRequired() bool {
|
func (f *IntSliceFlag) IsRequired() bool {
|
||||||
return f.Required
|
return f.Required
|
||||||
|
31
flag_path.go
31
flag_path.go
@ -5,36 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PathFlag struct {
|
type Path = string
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRequired returns whether or not the flag is required
|
// IsRequired returns whether or not the flag is required
|
||||||
func (f *PathFlag) IsRequired() bool {
|
func (f *PathFlag) IsRequired() bool {
|
||||||
|
@ -5,38 +5,6 @@ import (
|
|||||||
"fmt"
|
"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
|
// IsRequired returns whether or not the flag is required
|
||||||
func (f *StringFlag) IsRequired() bool {
|
func (f *StringFlag) IsRequired() bool {
|
||||||
return f.Required
|
return f.Required
|
||||||
|
@ -70,38 +70,12 @@ func (s *StringSlice) Get() interface{} {
|
|||||||
return *s
|
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
|
// String returns a readable representation of this value
|
||||||
// (for usage defaults)
|
// (for usage defaults)
|
||||||
func (f *StringSliceFlag) String() string {
|
func (f *StringSliceFlag) String() string {
|
||||||
return withEnvHint(f.GetEnvVars(), stringifyStringSliceFlag(f))
|
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
|
// IsRequired returns whether or not the flag is required
|
||||||
func (f *StringSliceFlag) IsRequired() bool {
|
func (f *StringSliceFlag) IsRequired() bool {
|
||||||
return f.Required
|
return f.Required
|
||||||
|
@ -58,38 +58,6 @@ func (t *Timestamp) Get() interface{} {
|
|||||||
return *t
|
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
|
// IsRequired returns whether or not the flag is required
|
||||||
func (f *TimestampFlag) IsRequired() bool {
|
func (f *TimestampFlag) IsRequired() bool {
|
||||||
return f.Required
|
return f.Required
|
||||||
|
31
flag_uint.go
31
flag_uint.go
@ -6,37 +6,6 @@ import (
|
|||||||
"strconv"
|
"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
|
// IsRequired returns whether or not the flag is required
|
||||||
func (f *UintFlag) IsRequired() bool {
|
func (f *UintFlag) IsRequired() bool {
|
||||||
return f.Required
|
return f.Required
|
||||||
|
@ -6,37 +6,6 @@ import (
|
|||||||
"strconv"
|
"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
|
// IsRequired returns whether or not the flag is required
|
||||||
func (f *Uint64Flag) IsRequired() bool {
|
func (f *Uint64Flag) IsRequired() bool {
|
||||||
return f.Required
|
return f.Required
|
||||||
|
1
go.mod
1
go.mod
@ -5,6 +5,7 @@ go 1.18
|
|||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v1.1.0
|
github.com/BurntSushi/toml v1.1.0
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.1
|
github.com/cpuguy83/go-md2man/v2 v2.0.1
|
||||||
|
golang.org/x/text v0.3.7
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
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 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
|
||||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
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 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
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 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
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 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
@ -16,9 +15,18 @@ import (
|
|||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var packages = []string{"cli", "altsrc"}
|
|
||||||
|
|
||||||
func main() {
|
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 := cli.NewApp()
|
||||||
|
|
||||||
app.Name = "builder"
|
app.Name = "builder"
|
||||||
@ -45,20 +53,41 @@ func main() {
|
|||||||
Name: "check-binary-size",
|
Name: "check-binary-size",
|
||||||
Action: checkBinarySizeActionFunc,
|
Action: checkBinarySizeActionFunc,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "generate",
|
||||||
|
Action: GenerateActionFunc,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
app.Flags = []cli.Flag{
|
app.Flags = []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "tags",
|
Name: "tags",
|
||||||
Usage: "set build 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 := app.Run(os.Args); err != nil {
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
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 {
|
func runCmd(arg string, args ...string) error {
|
||||||
cmd := exec.Command(arg, args...)
|
cmd := exec.Command(arg, args...)
|
||||||
|
|
||||||
@ -66,78 +95,63 @@ func runCmd(arg string, args ...string) error {
|
|||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
fmt.Fprintf(os.Stderr, "# ---> %s\n", cmd)
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func VetActionFunc(_ *cli.Context) error {
|
func VetActionFunc(cCtx *cli.Context) error {
|
||||||
return runCmd("go", "vet")
|
return runCmd("go", "vet", cCtx.Path("top")+"/...")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestActionFunc(c *cli.Context) error {
|
func TestActionFunc(c *cli.Context) error {
|
||||||
tags := c.String("tags")
|
tags := c.String("tags")
|
||||||
|
|
||||||
for _, pkg := range packages {
|
for _, pkg := range c.StringSlice("packages") {
|
||||||
var packageName string
|
packageName := "github.com/urfave/cli/v2"
|
||||||
|
|
||||||
if pkg == "cli" {
|
if pkg != "cli" {
|
||||||
packageName = "github.com/urfave/cli/v2"
|
|
||||||
} else {
|
|
||||||
packageName = fmt.Sprintf("github.com/urfave/cli/v2/%s", pkg)
|
packageName = fmt.Sprintf("github.com/urfave/cli/v2/%s", pkg)
|
||||||
}
|
}
|
||||||
|
|
||||||
coverProfile := fmt.Sprintf("--coverprofile=%s.coverprofile", pkg)
|
if err := runCmd(
|
||||||
|
"go", "test",
|
||||||
err := runCmd("go", "test", "-tags", tags, "-v", coverProfile, packageName)
|
"-tags", tags,
|
||||||
if err != nil {
|
"-v",
|
||||||
|
"--coverprofile", pkg+".coverprofile",
|
||||||
|
"--covermode", "count",
|
||||||
|
"--cover", packageName,
|
||||||
|
packageName,
|
||||||
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return testCleanup()
|
return testCleanup(c.StringSlice("packages"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCleanup() error {
|
func testCleanup(packages []string) error {
|
||||||
var out bytes.Buffer
|
out := &bytes.Buffer{}
|
||||||
|
|
||||||
|
fmt.Fprintf(out, "mode: count\n")
|
||||||
|
|
||||||
for _, pkg := range packages {
|
for _, pkg := range packages {
|
||||||
file, err := os.Open(fmt.Sprintf("%s.coverprofile", pkg))
|
filename := pkg + ".coverprofile"
|
||||||
|
|
||||||
|
lineBytes, err := os.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := ioutil.ReadAll(file)
|
lines := strings.Split(string(lineBytes), "\n")
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
out.Write(b)
|
fmt.Fprintf(out, strings.Join(lines[1:], "\n"))
|
||||||
err = file.Close()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.Remove(fmt.Sprintf("%s.coverprofile", pkg))
|
if err := os.Remove(filename); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outFile, err := os.Create("coverage.txt")
|
return os.WriteFile("coverage.txt", out.Bytes(), 0644)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = out.WriteTo(outFile)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = outFile.Close()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GfmrunActionFunc(c *cli.Context) error {
|
func GfmrunActionFunc(c *cli.Context) error {
|
||||||
@ -179,17 +193,7 @@ func TocActionFunc(c *cli.Context) error {
|
|||||||
filename = "README.md"
|
filename = "README.md"
|
||||||
}
|
}
|
||||||
|
|
||||||
err := runCmd("markdown-toc", "-i", filename)
|
return runCmd("markdown-toc", "-i", filename)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = runCmd("git", "diff", "--exit-code")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkBinarySizeActionFunc checks the size of an example binary to ensure that we are keeping size down
|
// checkBinarySizeActionFunc checks the size of an example binary to ensure that we are keeping size down
|
||||||
@ -201,7 +205,6 @@ func checkBinarySizeActionFunc(c *cli.Context) (err error) {
|
|||||||
cliBuiltFilePath = "./internal/example-cli/built-example"
|
cliBuiltFilePath = "./internal/example-cli/built-example"
|
||||||
helloSourceFilePath = "./internal/example-hello-world/example-hello-world.go"
|
helloSourceFilePath = "./internal/example-hello-world/example-hello-world.go"
|
||||||
helloBuiltFilePath = "./internal/example-hello-world/built-example"
|
helloBuiltFilePath = "./internal/example-hello-world/built-example"
|
||||||
desiredMinBinarySize = 1.675
|
|
||||||
desiredMaxBinarySize = 2.2
|
desiredMaxBinarySize = 2.2
|
||||||
badNewsEmoji = "🚨"
|
badNewsEmoji = "🚨"
|
||||||
goodNewsEmoji = "✨"
|
goodNewsEmoji = "✨"
|
||||||
@ -209,8 +212,14 @@ func checkBinarySizeActionFunc(c *cli.Context) (err error) {
|
|||||||
mbStringFormatter = "%.1fMB"
|
mbStringFormatter = "%.1fMB"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
desiredMinBinarySize := 1.675
|
||||||
|
|
||||||
tags := c.String("tags")
|
tags := c.String("tags")
|
||||||
|
|
||||||
|
if strings.Contains(tags, "urfave_cli_no_docs") {
|
||||||
|
desiredMinBinarySize = 1.39
|
||||||
|
}
|
||||||
|
|
||||||
// get cli example size
|
// get cli example size
|
||||||
cliSize, err := getSize(cliSourceFilePath, cliBuiltFilePath, tags)
|
cliSize, err := getSize(cliSourceFilePath, cliBuiltFilePath, tags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -280,6 +289,10 @@ func checkBinarySizeActionFunc(c *cli.Context) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GenerateActionFunc(cCtx *cli.Context) error {
|
||||||
|
return runCmd("go", "generate", cCtx.Path("top")+"/...")
|
||||||
|
}
|
||||||
|
|
||||||
func getSize(sourcePath string, builtPath string, tags string) (size int64, err error) {
|
func getSize(sourcePath string, builtPath string, tags string) (size int64, err error) {
|
||||||
// build example binary
|
// build example binary
|
||||||
err = runCmd("go", "build", "-tags", tags, "-o", builtPath, "-ldflags", "-s -w", sourcePath)
|
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")
|
||||||
|
}
|
||||||
|
}
|
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