Move more functionality into internal/build/build.go
and use make targets in CI, pass flag spec YAML through yq includes result of running `make v2approve`
This commit is contained in:
parent
375e5dfc1d
commit
12a3c62e50
108
.github/workflows/cli.yml
vendored
108
.github/workflows/cli.yml
vendored
@ -1,5 +1,4 @@
|
|||||||
name: Run Tests
|
name: Run Tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
@ -9,10 +8,8 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
strategy:
|
strategy:
|
||||||
@ -22,84 +19,46 @@ jobs:
|
|||||||
name: ${{ matrix.os }} @ Go ${{ matrix.go }}
|
name: ${{ matrix.os }} @ Go ${{ matrix.go }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go ${{ matrix.go }}
|
- uses: actions/setup-go@v3
|
||||||
uses: actions/setup-go@v3
|
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go }}
|
go-version: ${{ matrix.go }}
|
||||||
|
|
||||||
- name: Set PATH
|
- name: Set PATH
|
||||||
run: echo "${GITHUB_WORKSPACE}/.local/bin" >>"${GITHUB_PATH}"
|
run: echo "${GITHUB_WORKSPACE}/.local/bin" | tee -a "${GITHUB_PATH}" >/dev/null
|
||||||
|
- if: matrix.go == '1.19.x' && matrix.os == 'ubuntu-latest'
|
||||||
- name: install goimports
|
run: make ensure-goimports
|
||||||
if: matrix.go == '1.19.x' && matrix.os == 'ubuntu-latest'
|
- uses: actions/checkout@v3
|
||||||
run: GOBIN=${PWD}/.local/bin go install golang.org/x/tools/cmd/goimports@latest
|
- if: matrix.go == '1.19.x' && matrix.os == 'ubuntu-latest'
|
||||||
|
run: make lint
|
||||||
- name: Checkout Code
|
- run: make vet
|
||||||
uses: actions/checkout@v3
|
- run: make tag-test
|
||||||
|
- run: make test
|
||||||
- name: goimports check
|
- run: make -C cmd/urfave-cli-genflags
|
||||||
if: matrix.go == '1.19.x' && matrix.os == 'ubuntu-latest'
|
- run: make check-binary-size
|
||||||
run: test -z $(goimports -l .)
|
- run: make tag-check-binary-size
|
||||||
|
- run: make yamlfmt
|
||||||
- name: vet
|
- run: make diffcheck
|
||||||
run: go run internal/build/build.go vet
|
- run: make v2diff
|
||||||
|
- if: success() && matrix.go == '1.19.x' && matrix.os == 'ubuntu-latest'
|
||||||
- name: test with urfave_cli_no_docs tag
|
|
||||||
run: go run internal/build/build.go -tags urfave_cli_no_docs test
|
|
||||||
|
|
||||||
- name: test
|
|
||||||
run: go run internal/build/build.go test
|
|
||||||
|
|
||||||
- name: test urfave-cli-genflags
|
|
||||||
run: make -C cmd/urfave-cli-genflags
|
|
||||||
|
|
||||||
- name: check-binary-size
|
|
||||||
run: go run internal/build/build.go check-binary-size
|
|
||||||
|
|
||||||
- name: check-binary-size with tags (informational only)
|
|
||||||
run: go run internal/build/build.go -tags urfave_cli_no_docs check-binary-size
|
|
||||||
|
|
||||||
- name: Upload coverage to Codecov
|
|
||||||
if: success() && matrix.go == '1.19.x' && matrix.os == 'ubuntu-latest'
|
|
||||||
uses: codecov/codecov-action@v3
|
uses: codecov/codecov-action@v3
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|
||||||
test-docs:
|
test-docs:
|
||||||
name: test-docs
|
name: test-docs
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go
|
- uses: actions/setup-go@v3
|
||||||
uses: actions/setup-go@v3
|
|
||||||
with:
|
with:
|
||||||
go-version: 1.19.x
|
go-version: 1.19.x
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
- name: Use Node.js 16
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
with:
|
||||||
node-version: '16'
|
node-version: '16'
|
||||||
|
|
||||||
- name: Set PATH
|
- name: Set PATH
|
||||||
run: echo "${GITHUB_WORKSPACE}/.local/bin" >>"${GITHUB_PATH}"
|
run: echo "${GITHUB_WORKSPACE}/.local/bin" | tee -a "${GITHUB_PATH}" >/dev/null
|
||||||
|
- uses: actions/checkout@v3
|
||||||
- name: Checkout Code
|
- run: make ensure-gfmrun
|
||||||
uses: actions/checkout@v3
|
- run: make gfmrun
|
||||||
|
- run: make diffcheck
|
||||||
- name: Install Dependencies
|
|
||||||
run: |
|
|
||||||
mkdir -p "${GITHUB_WORKSPACE}/.local/bin"
|
|
||||||
curl -fsSL -o "${GITHUB_WORKSPACE}/.local/bin/gfmrun" "https://github.com/urfave/gfmrun/releases/download/v1.3.0/gfmrun-$(go env GOOS)-$(go env GOARCH)-v1.3.0"
|
|
||||||
chmod +x "${GITHUB_WORKSPACE}/.local/bin/gfmrun"
|
|
||||||
|
|
||||||
- name: gfmrun
|
|
||||||
run: go run internal/build/build.go gfmrun --walk docs/v2/
|
|
||||||
|
|
||||||
- name: diff check
|
|
||||||
run: |
|
|
||||||
git diff --exit-code
|
|
||||||
git diff --cached --exit-code
|
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
@ -108,18 +67,11 @@ jobs:
|
|||||||
needs: [test-docs]
|
needs: [test-docs]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Code
|
- uses: actions/checkout@v3
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
- run: make ci-ensure-mkdocs
|
||||||
- name: Setup mkdocs
|
- run: make set-mkdocs-remote
|
||||||
run: |
|
env:
|
||||||
pip install -U pip
|
MKDOCS_REMOTE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
pip install -r mkdocs-requirements.txt
|
- run: make deploy-mkdocs
|
||||||
git remote rm origin
|
|
||||||
git remote add origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/urfave/cli.git
|
|
||||||
|
|
||||||
- name: Publish Docs
|
|
||||||
run: |
|
|
||||||
mkdocs gh-deploy --force
|
|
||||||
|
20
Makefile
20
Makefile
@ -4,8 +4,10 @@
|
|||||||
# are very important so that maintainers and contributors can focus their
|
# are very important so that maintainers and contributors can focus their
|
||||||
# attention on files that are primarily Go.
|
# attention on files that are primarily Go.
|
||||||
|
|
||||||
|
GO_RUN_BUILD := go run internal/build/build.go
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: generate vet tag-test test check-binary-size tag-check-binary-size gfmrun v2diff
|
all: generate vet tag-test test check-binary-size tag-check-binary-size gfmrun yamlfmt v2diff
|
||||||
|
|
||||||
# NOTE: this is a special catch-all rule to run any of the commands
|
# NOTE: this is a special catch-all rule to run any of the commands
|
||||||
# defined in internal/build/build.go with optional arguments passed
|
# defined in internal/build/build.go with optional arguments passed
|
||||||
@ -13,28 +15,28 @@ all: generate vet tag-test test check-binary-size tag-check-binary-size gfmrun v
|
|||||||
#
|
#
|
||||||
# $ make test GFLAGS='--packages cli'
|
# $ make test GFLAGS='--packages cli'
|
||||||
%:
|
%:
|
||||||
go run internal/build/build.go $(GFLAGS) $* $(FLAGS)
|
$(GO_RUN_BUILD) $(GFLAGS) $* $(FLAGS)
|
||||||
|
|
||||||
.PHONY: tag-test
|
.PHONY: tag-test
|
||||||
tag-test:
|
tag-test:
|
||||||
go run internal/build/build.go -tags urfave_cli_no_docs test
|
$(GO_RUN_BUILD) -tags urfave_cli_no_docs test
|
||||||
|
|
||||||
.PHONY: tag-check-binary-size
|
.PHONY: tag-check-binary-size
|
||||||
tag-check-binary-size:
|
tag-check-binary-size:
|
||||||
go run internal/build/build.go -tags urfave_cli_no_docs check-binary-size
|
$(GO_RUN_BUILD) -tags urfave_cli_no_docs check-binary-size
|
||||||
|
|
||||||
.PHONY: gfmrun
|
.PHONY: gfmrun
|
||||||
gfmrun:
|
gfmrun:
|
||||||
go run internal/build/build.go gfmrun docs/v2/manual.md
|
$(GO_RUN_BUILD) gfmrun --walk docs/v2/
|
||||||
|
|
||||||
|
.PHONY: ci-ensure-mkdocs
|
||||||
|
ci-ensure-mkdocs:
|
||||||
|
$(GO_RUN_BUILD) ensure-mkdocs --upgrade-pip
|
||||||
|
|
||||||
.PHONY: docs
|
.PHONY: docs
|
||||||
docs:
|
docs:
|
||||||
mkdocs build
|
mkdocs build
|
||||||
|
|
||||||
.PHONY: docs-deps
|
|
||||||
docs-deps:
|
|
||||||
pip install -r mkdocs-requirements.txt
|
|
||||||
|
|
||||||
.PHONY: serve-docs
|
.PHONY: serve-docs
|
||||||
serve-docs:
|
serve-docs:
|
||||||
mkdocs serve
|
mkdocs serve
|
||||||
|
@ -107,7 +107,7 @@ following `make` targets may be used if desired:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
# install documentation dependencies with `pip`
|
# install documentation dependencies with `pip`
|
||||||
make docs-deps
|
make ensure-mkdocs
|
||||||
```
|
```
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
# NOTE: this file is used by the tool defined in
|
# NOTE: this file is used by the tool defined in
|
||||||
# ./cmd/urfave-cli-genflags/main.go which uses the
|
# ./cmd/urfave-cli-genflags/main.go which uses the
|
||||||
# `Spec` type that maps to this file structure.
|
# `Spec` type that maps to this file structure.
|
||||||
|
|
||||||
flag_types:
|
flag_types:
|
||||||
bool:
|
bool:
|
||||||
struct_fields:
|
struct_fields:
|
||||||
|
@ -5,12 +5,17 @@ package main
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
@ -21,6 +26,8 @@ const (
|
|||||||
goodNewsEmoji = "✨"
|
goodNewsEmoji = "✨"
|
||||||
checksPassedEmoji = "✅"
|
checksPassedEmoji = "✅"
|
||||||
|
|
||||||
|
gfmrunVersion = "v1.3.0"
|
||||||
|
|
||||||
v2diffWarning = `
|
v2diffWarning = `
|
||||||
# The unified diff above indicates that the public API surface area
|
# The unified diff above indicates that the public API surface area
|
||||||
# has changed. If you feel that the changes are acceptable and adhere
|
# has changed. If you feel that the changes are acceptable and adhere
|
||||||
@ -45,15 +52,13 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
app := cli.NewApp()
|
app := &cli.App{
|
||||||
|
Name: "builder",
|
||||||
app.Name = "builder"
|
Usage: "Do a thing for urfave/cli! (maybe build?)",
|
||||||
app.Usage = "Generates a new urfave/cli build!"
|
Commands: cli.Commands{
|
||||||
|
|
||||||
app.Commands = cli.Commands{
|
|
||||||
{
|
{
|
||||||
Name: "vet",
|
Name: "vet",
|
||||||
Action: VetActionFunc,
|
Action: topRunAction("go", "vet", "./..."),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
@ -78,6 +83,47 @@ func main() {
|
|||||||
Name: "generate",
|
Name: "generate",
|
||||||
Action: GenerateActionFunc,
|
Action: GenerateActionFunc,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "yamlfmt",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.BoolFlag{Name: "strict", Value: false, Usage: "require presence of yq"},
|
||||||
|
},
|
||||||
|
Action: YAMLFmtActionFunc,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "diffcheck",
|
||||||
|
Action: DiffCheckActionFunc,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ensure-goimports",
|
||||||
|
Action: EnsureGoimportsActionFunc,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ensure-gfmrun",
|
||||||
|
Action: EnsureGfmrunActionFunc,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ensure-mkdocs",
|
||||||
|
Action: EnsureMkdocsActionFunc,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.BoolFlag{Name: "upgrade-pip"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "set-mkdocs-remote",
|
||||||
|
Action: SetMkdocsRemoteActionFunc,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{Name: "github-token", Required: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "deploy-mkdocs",
|
||||||
|
Action: topRunAction("mkdocs", "gh-deploy", "--force"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "lint",
|
||||||
|
Action: LintActionFunc,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "v2diff",
|
Name: "v2diff",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
@ -87,10 +133,15 @@ func main() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "v2approve",
|
Name: "v2approve",
|
||||||
Action: V2Approve,
|
Action: topRunAction(
|
||||||
|
"cp",
|
||||||
|
"-v",
|
||||||
|
"godoc-current.txt",
|
||||||
|
filepath.Join("testdata", "godoc-v2.x.txt"),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
app.Flags = []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "tags",
|
Name: "tags",
|
||||||
Usage: "set build tags",
|
Usage: "set build tags",
|
||||||
@ -103,6 +154,7 @@ func main() {
|
|||||||
Name: "packages",
|
Name: "packages",
|
||||||
Value: cli.NewStringSlice("cli", "altsrc", "internal/build"),
|
Value: cli.NewStringSlice("cli", "altsrc", "internal/build"),
|
||||||
},
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := app.Run(os.Args); err != nil {
|
if err := app.Run(os.Args); err != nil {
|
||||||
@ -120,6 +172,14 @@ func sh(exe string, args ...string) (string, error) {
|
|||||||
return string(outBytes), err
|
return string(outBytes), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func topRunAction(arg string, args ...string) cli.ActionFunc {
|
||||||
|
return func(cCtx *cli.Context) error {
|
||||||
|
os.Chdir(cCtx.Path("top"))
|
||||||
|
|
||||||
|
return runCmd(arg, args...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func runCmd(arg string, args ...string) error {
|
func runCmd(arg string, args ...string) error {
|
||||||
cmd := exec.Command(arg, args...)
|
cmd := exec.Command(arg, args...)
|
||||||
|
|
||||||
@ -131,6 +191,43 @@ func runCmd(arg string, args ...string) error {
|
|||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func downloadFile(src, dest string, dirPerm, perm os.FileMode) error {
|
||||||
|
req, err := http.NewRequest(http.MethodGet, src, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode >= 300 {
|
||||||
|
return fmt.Errorf("download response %[1]v", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll(filepath.Dir(dest), dirPerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := os.Create(dest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := io.Copy(out, resp.Body); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := out.Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.Chmod(dest, perm)
|
||||||
|
}
|
||||||
|
|
||||||
func VetActionFunc(cCtx *cli.Context) error {
|
func VetActionFunc(cCtx *cli.Context) error {
|
||||||
return runCmd("go", "vet", cCtx.Path("top")+"/...")
|
return runCmd("go", "vet", cCtx.Path("top")+"/...")
|
||||||
}
|
}
|
||||||
@ -145,15 +242,20 @@ func TestActionFunc(c *cli.Context) error {
|
|||||||
packageName = fmt.Sprintf("github.com/urfave/cli/v2/%s", pkg)
|
packageName = fmt.Sprintf("github.com/urfave/cli/v2/%s", pkg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := runCmd(
|
args := []string{"test"}
|
||||||
"go", "test",
|
if tags != "" {
|
||||||
"-tags", tags,
|
args = append(args, []string{"-tags", tags}...)
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args, []string{
|
||||||
"-v",
|
"-v",
|
||||||
"--coverprofile", pkg + ".coverprofile",
|
"--coverprofile", pkg + ".coverprofile",
|
||||||
"--covermode", "count",
|
"--covermode", "count",
|
||||||
"--cover", packageName,
|
"--cover", packageName,
|
||||||
packageName,
|
packageName,
|
||||||
); err != nil {
|
}...)
|
||||||
|
|
||||||
|
if err := runCmd("go", args...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -411,6 +513,125 @@ func GenerateActionFunc(cCtx *cli.Context) error {
|
|||||||
return runCmd("go", "generate", cCtx.Path("top")+"/...")
|
return runCmd("go", "generate", cCtx.Path("top")+"/...")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func YAMLFmtActionFunc(cCtx *cli.Context) error {
|
||||||
|
yqBin, err := exec.LookPath("yq")
|
||||||
|
if err != nil {
|
||||||
|
if !cCtx.Bool("strict") {
|
||||||
|
fmt.Fprintln(cCtx.App.ErrWriter, "# ---> no yq found; skipping")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Chdir(cCtx.Path("top"))
|
||||||
|
|
||||||
|
return runCmd(yqBin, "eval", "--inplace", "flag-spec.yaml")
|
||||||
|
}
|
||||||
|
|
||||||
|
func DiffCheckActionFunc(cCtx *cli.Context) error {
|
||||||
|
os.Chdir(cCtx.Path("top"))
|
||||||
|
|
||||||
|
if err := runCmd("git", "diff", "--exit-code"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return runCmd("git", "diff", "--cached", "--exit-code")
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureGoimportsActionFunc(cCtx *cli.Context) error {
|
||||||
|
top := cCtx.Path("top")
|
||||||
|
os.Chdir(top)
|
||||||
|
|
||||||
|
if err := runCmd(
|
||||||
|
"goimports",
|
||||||
|
"-d",
|
||||||
|
filepath.Join(top, "internal/build/build.go"),
|
||||||
|
); err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Setenv("GOBIN", filepath.Join(top, ".local/bin"))
|
||||||
|
|
||||||
|
return runCmd("go", "install", "golang.org/x/tools/cmd/goimports@latest")
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureGfmrunActionFunc(cCtx *cli.Context) error {
|
||||||
|
top := cCtx.Path("top")
|
||||||
|
gfmrunExe := filepath.Join(top, ".local/bin/gfmrun")
|
||||||
|
|
||||||
|
os.Chdir(top)
|
||||||
|
|
||||||
|
if v, err := sh(gfmrunExe, "--version"); err == nil && strings.TrimSpace(v) == gfmrunVersion {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
gfmrunURL, err := url.Parse(
|
||||||
|
fmt.Sprintf(
|
||||||
|
"https://github.com/urfave/gfmrun/releases/download/%[1]s/gfmrun-%[2]s-%[3]s-%[1]s",
|
||||||
|
gfmrunVersion, runtime.GOOS, runtime.GOARCH,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return downloadFile(gfmrunURL.String(), gfmrunExe, 0755, 0755)
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureMkdocsActionFunc(cCtx *cli.Context) error {
|
||||||
|
os.Chdir(cCtx.Path("top"))
|
||||||
|
|
||||||
|
if err := runCmd("mkdocs", "--version"); err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if cCtx.Bool("upgrade-pip") {
|
||||||
|
if err := runCmd("pip", "install", "-U", "pip"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return runCmd("pip", "install", "-r", "mkdocs-requirements.txt")
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetMkdocsRemoteActionFunc(cCtx *cli.Context) error {
|
||||||
|
ghToken := strings.TrimSpace(cCtx.String("github-token"))
|
||||||
|
if ghToken == "" {
|
||||||
|
return errors.New("empty github token")
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Chdir(cCtx.Path("top"))
|
||||||
|
|
||||||
|
if err := runCmd("git", "remote", "rm", "origin"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return runCmd(
|
||||||
|
"git", "remote", "add", "origin",
|
||||||
|
fmt.Sprintf("https://x-access-token:%[1]s@github.com/urfave/cli.git", ghToken),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func LintActionFunc(cCtx *cli.Context) error {
|
||||||
|
top := cCtx.Path("top")
|
||||||
|
os.Chdir(top)
|
||||||
|
|
||||||
|
out, err := sh(filepath.Join(top, ".local/bin/goimports"), "-l", ".")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.TrimSpace(out) != "" {
|
||||||
|
fmt.Fprintln(cCtx.App.ErrWriter, "# ---> goimports -l is non-empty:")
|
||||||
|
fmt.Fprintln(cCtx.App.ErrWriter, out)
|
||||||
|
|
||||||
|
return errors.New("goimports needed")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func V2Diff(cCtx *cli.Context) error {
|
func V2Diff(cCtx *cli.Context) error {
|
||||||
os.Chdir(cCtx.Path("top"))
|
os.Chdir(cCtx.Path("top"))
|
||||||
|
|
||||||
@ -439,34 +660,29 @@ func V2Diff(cCtx *cli.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func V2Approve(cCtx *cli.Context) error {
|
func getSize(sourcePath, builtPath, tags string) (int64, error) {
|
||||||
top := cCtx.Path("top")
|
args := []string{"build"}
|
||||||
|
|
||||||
return runCmd(
|
if tags != "" {
|
||||||
"cp",
|
args = append(args, []string{"-tags", tags}...)
|
||||||
"-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) {
|
args = append(args, []string{
|
||||||
// build example binary
|
"-o", builtPath,
|
||||||
err = runCmd("go", "build", "-tags", tags, "-o", builtPath, "-ldflags", "-s -w", sourcePath)
|
"-ldflags", "-s -w",
|
||||||
if err != nil {
|
sourcePath,
|
||||||
|
}...)
|
||||||
|
|
||||||
|
if err := runCmd("go", args...); err != nil {
|
||||||
fmt.Println("issue getting size for example binary")
|
fmt.Println("issue getting size for example binary")
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// get file info
|
|
||||||
fileInfo, err := os.Stat(builtPath)
|
fileInfo, err := os.Stat(builtPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("issue getting size for example binary")
|
fmt.Println("issue getting size for example binary")
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// size!
|
return fileInfo.Size(), nil
|
||||||
size = fileInfo.Size()
|
|
||||||
|
|
||||||
return size, nil
|
|
||||||
}
|
}
|
||||||
|
215
testdata/godoc-v2.x.txt
vendored
215
testdata/godoc-v2.x.txt
vendored
@ -49,8 +49,8 @@ AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
|||||||
|
|
||||||
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
||||||
{{.Name}}:{{range .VisibleCommands}}
|
{{.Name}}:{{range .VisibleCommands}}
|
||||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}}
|
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
|
||||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlagCategories}}
|
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlagCategories}}
|
||||||
|
|
||||||
GLOBAL OPTIONS:{{range .VisibleFlagCategories}}
|
GLOBAL OPTIONS:{{range .VisibleFlagCategories}}
|
||||||
{{if .Name}}{{.Name}}
|
{{if .Name}}{{.Name}}
|
||||||
@ -157,8 +157,8 @@ DESCRIPTION:
|
|||||||
|
|
||||||
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
||||||
{{.Name}}:{{range .VisibleCommands}}
|
{{.Name}}:{{range .VisibleCommands}}
|
||||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}}
|
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
|
||||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
{{range .VisibleFlags}}{{.}}
|
{{range .VisibleFlags}}{{.}}
|
||||||
@ -300,6 +300,8 @@ type App struct {
|
|||||||
CommandNotFound CommandNotFoundFunc
|
CommandNotFound CommandNotFoundFunc
|
||||||
// Execute this function if a usage error occurs
|
// Execute this function if a usage error occurs
|
||||||
OnUsageError OnUsageErrorFunc
|
OnUsageError OnUsageErrorFunc
|
||||||
|
// Execute this function when an invalid flag is accessed from the context
|
||||||
|
InvalidFlagAccessHandler InvalidFlagAccessFunc
|
||||||
// Compilation date
|
// Compilation date
|
||||||
Compiled time.Time
|
Compiled time.Time
|
||||||
// List of all authors who contributed
|
// List of all authors who contributed
|
||||||
@ -450,6 +452,8 @@ type BoolFlag struct {
|
|||||||
|
|
||||||
Aliases []string
|
Aliases []string
|
||||||
EnvVars []string
|
EnvVars []string
|
||||||
|
|
||||||
|
Count *int
|
||||||
}
|
}
|
||||||
BoolFlag is a flag with type bool
|
BoolFlag is a flag with type bool
|
||||||
|
|
||||||
@ -629,6 +633,9 @@ func (cCtx *Context) Args() Args
|
|||||||
func (cCtx *Context) Bool(name string) bool
|
func (cCtx *Context) Bool(name string) bool
|
||||||
Bool looks up the value of a local BoolFlag, returns false if not found
|
Bool looks up the value of a local BoolFlag, returns false if not found
|
||||||
|
|
||||||
|
func (cCtx *Context) Count(name string) int
|
||||||
|
Count returns the num of occurences of this flag
|
||||||
|
|
||||||
func (cCtx *Context) Duration(name string) time.Duration
|
func (cCtx *Context) Duration(name string) time.Duration
|
||||||
Duration looks up the value of a local DurationFlag, returns 0 if not found
|
Duration looks up the value of a local DurationFlag, returns 0 if not found
|
||||||
|
|
||||||
@ -698,9 +705,23 @@ func (cCtx *Context) Uint(name string) uint
|
|||||||
func (cCtx *Context) Uint64(name string) uint64
|
func (cCtx *Context) Uint64(name string) uint64
|
||||||
Uint64 looks up the value of a local Uint64Flag, returns 0 if not found
|
Uint64 looks up the value of a local Uint64Flag, returns 0 if not found
|
||||||
|
|
||||||
|
func (cCtx *Context) Uint64Slice(name string) []uint64
|
||||||
|
Uint64Slice looks up the value of a local Uint64SliceFlag, returns nil if
|
||||||
|
not found
|
||||||
|
|
||||||
|
func (cCtx *Context) UintSlice(name string) []uint
|
||||||
|
UintSlice looks up the value of a local UintSliceFlag, returns nil if not
|
||||||
|
found
|
||||||
|
|
||||||
func (cCtx *Context) Value(name string) interface{}
|
func (cCtx *Context) Value(name string) interface{}
|
||||||
Value returns the value of the flag corresponding to `name`
|
Value returns the value of the flag corresponding to `name`
|
||||||
|
|
||||||
|
type Countable interface {
|
||||||
|
Count() int
|
||||||
|
}
|
||||||
|
Countable is an interface to enable detection of flag values which support
|
||||||
|
repetitive flags
|
||||||
|
|
||||||
type DocGenerationFlag interface {
|
type DocGenerationFlag interface {
|
||||||
Flag
|
Flag
|
||||||
|
|
||||||
@ -1064,7 +1085,7 @@ type GenericFlag struct {
|
|||||||
HasBeenSet bool
|
HasBeenSet bool
|
||||||
|
|
||||||
Value Generic
|
Value Generic
|
||||||
Destination *Generic
|
Destination Generic
|
||||||
|
|
||||||
Aliases []string
|
Aliases []string
|
||||||
EnvVars []string
|
EnvVars []string
|
||||||
@ -1073,7 +1094,7 @@ type GenericFlag struct {
|
|||||||
}
|
}
|
||||||
GenericFlag is a flag with type Generic
|
GenericFlag is a flag with type Generic
|
||||||
|
|
||||||
func (f GenericFlag) Apply(set *flag.FlagSet) error
|
func (f *GenericFlag) Apply(set *flag.FlagSet) error
|
||||||
Apply takes the flagset and calls Set on the generic flag with the value
|
Apply takes the flagset and calls Set on the generic flag with the value
|
||||||
provided by the user for parsing by the flag
|
provided by the user for parsing by the flag
|
||||||
|
|
||||||
@ -1131,6 +1152,8 @@ type Int64Flag struct {
|
|||||||
|
|
||||||
Aliases []string
|
Aliases []string
|
||||||
EnvVars []string
|
EnvVars []string
|
||||||
|
|
||||||
|
Base int
|
||||||
}
|
}
|
||||||
Int64Flag is a flag with type int64
|
Int64Flag is a flag with type int64
|
||||||
|
|
||||||
@ -1280,6 +1303,8 @@ type IntFlag struct {
|
|||||||
|
|
||||||
Aliases []string
|
Aliases []string
|
||||||
EnvVars []string
|
EnvVars []string
|
||||||
|
|
||||||
|
Base int
|
||||||
}
|
}
|
||||||
IntFlag is a flag with type int
|
IntFlag is a flag with type int
|
||||||
|
|
||||||
@ -1416,6 +1441,10 @@ func (f *IntSliceFlag) String() string
|
|||||||
func (f *IntSliceFlag) TakesValue() bool
|
func (f *IntSliceFlag) TakesValue() bool
|
||||||
TakesValue returns true of the flag takes a value, otherwise false
|
TakesValue returns true of the flag takes a value, otherwise false
|
||||||
|
|
||||||
|
type InvalidFlagAccessFunc func(*Context, string)
|
||||||
|
InvalidFlagAccessFunc is executed when an invalid flag is accessed from the
|
||||||
|
context.
|
||||||
|
|
||||||
type MultiError interface {
|
type MultiError interface {
|
||||||
error
|
error
|
||||||
Errors() []error
|
Errors() []error
|
||||||
@ -1850,6 +1879,8 @@ type Uint64Flag struct {
|
|||||||
|
|
||||||
Aliases []string
|
Aliases []string
|
||||||
EnvVars []string
|
EnvVars []string
|
||||||
|
|
||||||
|
Base int
|
||||||
}
|
}
|
||||||
Uint64Flag is a flag with type uint64
|
Uint64Flag is a flag with type uint64
|
||||||
|
|
||||||
@ -1893,6 +1924,89 @@ func (f *Uint64Flag) String() string
|
|||||||
func (f *Uint64Flag) TakesValue() bool
|
func (f *Uint64Flag) TakesValue() bool
|
||||||
TakesValue returns true of the flag takes a value, otherwise false
|
TakesValue returns true of the flag takes a value, otherwise false
|
||||||
|
|
||||||
|
type Uint64Slice struct {
|
||||||
|
// Has unexported fields.
|
||||||
|
}
|
||||||
|
Uint64Slice wraps []int64 to satisfy flag.Value
|
||||||
|
|
||||||
|
func NewUint64Slice(defaults ...uint64) *Uint64Slice
|
||||||
|
NewUint64Slice makes an *Uint64Slice with default values
|
||||||
|
|
||||||
|
func (i *Uint64Slice) Get() interface{}
|
||||||
|
Get returns the slice of ints set by this flag
|
||||||
|
|
||||||
|
func (i *Uint64Slice) Serialize() string
|
||||||
|
Serialize allows Uint64Slice to fulfill Serializer
|
||||||
|
|
||||||
|
func (i *Uint64Slice) Set(value string) error
|
||||||
|
Set parses the value into an integer and appends it to the list of values
|
||||||
|
|
||||||
|
func (i *Uint64Slice) String() string
|
||||||
|
String returns a readable representation of this value (for usage defaults)
|
||||||
|
|
||||||
|
func (i *Uint64Slice) Value() []uint64
|
||||||
|
Value returns the slice of ints set by this flag
|
||||||
|
|
||||||
|
type Uint64SliceFlag struct {
|
||||||
|
Name string
|
||||||
|
|
||||||
|
Category string
|
||||||
|
DefaultText string
|
||||||
|
FilePath string
|
||||||
|
Usage string
|
||||||
|
|
||||||
|
Required bool
|
||||||
|
Hidden bool
|
||||||
|
HasBeenSet bool
|
||||||
|
|
||||||
|
Value *Uint64Slice
|
||||||
|
Destination *Uint64Slice
|
||||||
|
|
||||||
|
Aliases []string
|
||||||
|
EnvVars []string
|
||||||
|
}
|
||||||
|
Uint64SliceFlag is a flag with type *Uint64Slice
|
||||||
|
|
||||||
|
func (f *Uint64SliceFlag) Apply(set *flag.FlagSet) error
|
||||||
|
Apply populates the flag given the flag set and environment
|
||||||
|
|
||||||
|
func (f *Uint64SliceFlag) Get(ctx *Context) []uint64
|
||||||
|
Get returns the flag’s value in the given Context.
|
||||||
|
|
||||||
|
func (f *Uint64SliceFlag) GetCategory() string
|
||||||
|
GetCategory returns the category for the flag
|
||||||
|
|
||||||
|
func (f *Uint64SliceFlag) GetDefaultText() string
|
||||||
|
GetDefaultText returns the default text for this flag
|
||||||
|
|
||||||
|
func (f *Uint64SliceFlag) GetEnvVars() []string
|
||||||
|
GetEnvVars returns the env vars for this flag
|
||||||
|
|
||||||
|
func (f *Uint64SliceFlag) GetUsage() string
|
||||||
|
GetUsage returns the usage string for the flag
|
||||||
|
|
||||||
|
func (f *Uint64SliceFlag) GetValue() string
|
||||||
|
GetValue returns the flags value as string representation and an empty
|
||||||
|
string if the flag takes no value at all.
|
||||||
|
|
||||||
|
func (f *Uint64SliceFlag) IsRequired() bool
|
||||||
|
IsRequired returns whether or not the flag is required
|
||||||
|
|
||||||
|
func (f *Uint64SliceFlag) IsSet() bool
|
||||||
|
IsSet returns whether or not the flag has been set through env or file
|
||||||
|
|
||||||
|
func (f *Uint64SliceFlag) IsVisible() bool
|
||||||
|
IsVisible returns true if the flag is not hidden, otherwise false
|
||||||
|
|
||||||
|
func (f *Uint64SliceFlag) Names() []string
|
||||||
|
Names returns the names of the flag
|
||||||
|
|
||||||
|
func (f *Uint64SliceFlag) String() string
|
||||||
|
String returns a readable representation of this value (for usage defaults)
|
||||||
|
|
||||||
|
func (f *Uint64SliceFlag) TakesValue() bool
|
||||||
|
TakesValue returns true of the flag takes a value, otherwise false
|
||||||
|
|
||||||
type UintFlag struct {
|
type UintFlag struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
@ -1910,6 +2024,8 @@ type UintFlag struct {
|
|||||||
|
|
||||||
Aliases []string
|
Aliases []string
|
||||||
EnvVars []string
|
EnvVars []string
|
||||||
|
|
||||||
|
Base int
|
||||||
}
|
}
|
||||||
UintFlag is a flag with type uint
|
UintFlag is a flag with type uint
|
||||||
|
|
||||||
@ -1953,6 +2069,93 @@ func (f *UintFlag) String() string
|
|||||||
func (f *UintFlag) TakesValue() bool
|
func (f *UintFlag) TakesValue() bool
|
||||||
TakesValue returns true of the flag takes a value, otherwise false
|
TakesValue returns true of the flag takes a value, otherwise false
|
||||||
|
|
||||||
|
type UintSlice struct {
|
||||||
|
// Has unexported fields.
|
||||||
|
}
|
||||||
|
UintSlice wraps []int to satisfy flag.Value
|
||||||
|
|
||||||
|
func NewUintSlice(defaults ...uint) *UintSlice
|
||||||
|
NewUintSlice makes an *UintSlice with default values
|
||||||
|
|
||||||
|
func (i *UintSlice) Get() interface{}
|
||||||
|
Get returns the slice of ints set by this flag
|
||||||
|
|
||||||
|
func (i *UintSlice) Serialize() string
|
||||||
|
Serialize allows UintSlice to fulfill Serializer
|
||||||
|
|
||||||
|
func (i *UintSlice) Set(value string) error
|
||||||
|
Set parses the value into an integer and appends it to the list of values
|
||||||
|
|
||||||
|
func (i *UintSlice) SetUint(value uint)
|
||||||
|
TODO: Consistently have specific Set function for Int64 and Float64 ? SetInt
|
||||||
|
directly adds an integer to the list of values
|
||||||
|
|
||||||
|
func (i *UintSlice) String() string
|
||||||
|
String returns a readable representation of this value (for usage defaults)
|
||||||
|
|
||||||
|
func (i *UintSlice) Value() []uint
|
||||||
|
Value returns the slice of ints set by this flag
|
||||||
|
|
||||||
|
type UintSliceFlag struct {
|
||||||
|
Name string
|
||||||
|
|
||||||
|
Category string
|
||||||
|
DefaultText string
|
||||||
|
FilePath string
|
||||||
|
Usage string
|
||||||
|
|
||||||
|
Required bool
|
||||||
|
Hidden bool
|
||||||
|
HasBeenSet bool
|
||||||
|
|
||||||
|
Value *UintSlice
|
||||||
|
Destination *UintSlice
|
||||||
|
|
||||||
|
Aliases []string
|
||||||
|
EnvVars []string
|
||||||
|
}
|
||||||
|
UintSliceFlag is a flag with type *UintSlice
|
||||||
|
|
||||||
|
func (f *UintSliceFlag) Apply(set *flag.FlagSet) error
|
||||||
|
Apply populates the flag given the flag set and environment
|
||||||
|
|
||||||
|
func (f *UintSliceFlag) Get(ctx *Context) []uint
|
||||||
|
Get returns the flag’s value in the given Context.
|
||||||
|
|
||||||
|
func (f *UintSliceFlag) GetCategory() string
|
||||||
|
GetCategory returns the category for the flag
|
||||||
|
|
||||||
|
func (f *UintSliceFlag) GetDefaultText() string
|
||||||
|
GetDefaultText returns the default text for this flag
|
||||||
|
|
||||||
|
func (f *UintSliceFlag) GetEnvVars() []string
|
||||||
|
GetEnvVars returns the env vars for this flag
|
||||||
|
|
||||||
|
func (f *UintSliceFlag) GetUsage() string
|
||||||
|
GetUsage returns the usage string for the flag
|
||||||
|
|
||||||
|
func (f *UintSliceFlag) GetValue() string
|
||||||
|
GetValue returns the flags value as string representation and an empty
|
||||||
|
string if the flag takes no value at all.
|
||||||
|
|
||||||
|
func (f *UintSliceFlag) IsRequired() bool
|
||||||
|
IsRequired returns whether or not the flag is required
|
||||||
|
|
||||||
|
func (f *UintSliceFlag) IsSet() bool
|
||||||
|
IsSet returns whether or not the flag has been set through env or file
|
||||||
|
|
||||||
|
func (f *UintSliceFlag) IsVisible() bool
|
||||||
|
IsVisible returns true if the flag is not hidden, otherwise false
|
||||||
|
|
||||||
|
func (f *UintSliceFlag) Names() []string
|
||||||
|
Names returns the names of the flag
|
||||||
|
|
||||||
|
func (f *UintSliceFlag) String() string
|
||||||
|
String returns a readable representation of this value (for usage defaults)
|
||||||
|
|
||||||
|
func (f *UintSliceFlag) TakesValue() bool
|
||||||
|
TakesValue returns true of the flag takes a value, otherwise false
|
||||||
|
|
||||||
type VisibleFlag interface {
|
type VisibleFlag interface {
|
||||||
Flag
|
Flag
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user