Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Command-actions with subcommands do not receive initialized context #1217

Closed
5 of 7 tasks
nicerobot opened this issue Dec 29, 2020 · 9 comments
Closed
5 of 7 tasks

Command-actions with subcommands do not receive initialized context #1217

nicerobot opened this issue Dec 29, 2020 · 9 comments
Labels
area/v2 relates to / is being considered for v2 kind/bug describes or fixes a bug pinned should not be marked stale status/triage maintainers still need to look into this status/waiting-for-response Waiting for response from original requester
Milestone

Comments

@nicerobot
Copy link

nicerobot commented Dec 29, 2020

my urfave/cli version is

github.com/urfave/cli/v2 v2.3.0

Checklist

Dependency Management

  • My project is using go modules.
  • My project is using vendoring.
  • My project is automatically downloading the latest version.
  • I am unsure of what my dependency management setup is.

Describe the bug

Calling commands that have subcommands does not pass an initialized context to the action.

To reproduce

Run this Playground Example
package main

import (
	"fmt"

	"github.com/urfave/cli/v2"
)

//
func main() {
	action := func(ctx *cli.Context) error {
		fmt.Printf("%#v\n", ctx.Command)
		return nil
	}
	sub := cli.Commands{{Name: "sub", Action: action}}
	withsub := &cli.Command{Name: "withsub", Action: action, Subcommands: sub}
	withoutsub := &cli.Command{Name: "withoutsub", Action: action}
	app := &cli.App{Commands: cli.Commands{withsub, withoutsub}}

	// These two work fine
	_ = app.Run([]string{"play", "withsub", "sub"})
	_ = app.Run([]string{"play", "withoutsub"})

	// This one does not pass a properly initialized context
	fmt.Println("Notice the Command.Name is empty:")
	_ = app.Run([]string{"play", "withsub"})

	// It calls this:            https://github.com/urfave/cli/blob/master/command.go#L94
	// without first doing this: https://github.com/urfave/cli/blob/master/command.go#L162
}

Observed behavior

&cli.Command{Name:"sub", Aliases:[]string(nil), Usage:"", UsageText:"", Description:"", ArgsUsage:"", Category:"", BashComplete:(cli.BashCompleteFunc)(nil), Before:(cli.BeforeFunc)(nil), After:(cli.AfterFunc)(nil), Action:(cli.ActionFunc)(0x58d640), OnUsageError:(cli.OnUsageErrorFunc)(nil), Subcommands:[]*cli.Command(nil), Flags:[]cli.Flag{(*cli.BoolFlag)(0x71b060)}, SkipFlagParsing:false, HideHelp:false, HideHelpCommand:false, Hidden:false, UseShortOptionHandling:false, HelpName:"play withsub sub", commandNamePath:[]string{"withsub", "sub"}, CustomHelpTemplate:""}
&cli.Command{Name:"withoutsub", Aliases:[]string(nil), Usage:"", UsageText:"", Description:"", ArgsUsage:"", Category:"", BashComplete:(cli.BashCompleteFunc)(nil), Before:(cli.BeforeFunc)(nil), After:(cli.AfterFunc)(nil), Action:(cli.ActionFunc)(0x58d640), OnUsageError:(cli.OnUsageErrorFunc)(nil), Subcommands:[]*cli.Command(nil), Flags:[]cli.Flag{(*cli.BoolFlag)(0x71b060)}, SkipFlagParsing:false, HideHelp:false, HideHelpCommand:false, Hidden:false, UseShortOptionHandling:false, HelpName:"play withoutsub", commandNamePath:[]string(nil), CustomHelpTemplate:""}
Notice the Command.Name is empty:
&cli.Command{Name:"", Aliases:[]string(nil), Usage:"", UsageText:"", Description:"", ArgsUsage:"", Category:"", BashComplete:(cli.BashCompleteFunc)(nil), Before:(cli.BeforeFunc)(nil), After:(cli.AfterFunc)(nil), Action:(cli.ActionFunc)(nil), OnUsageError:(cli.OnUsageErrorFunc)(nil), Subcommands:[]*cli.Command(nil), Flags:[]cli.Flag(nil), SkipFlagParsing:false, HideHelp:false, HideHelpCommand:false, Hidden:false, UseShortOptionHandling:false, HelpName:"", commandNamePath:[]string(nil), CustomHelpTemplate:""}

Expected behavior

When a command is called that has a subcommand but the subcommand is not on the command-line, the action receives a context initialized with the right command.

Want to fix this yourself?

We'd love to have more contributors on this project! If the fix for this bug is easily explained and very small, free free to create a pull request for it.

Run go version and paste its output here

go version go1.15.6 darwin/amd64

Run go env and paste its output here

GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="REDACTED/Library/Caches/go-build"
GOENV="REDACTED/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="REDACTED/go/pkg/mod"
GONOPROXY="REDACTED"
GONOSUMDB="REDACTED"
GOOS="darwin"
GOPATH="REDACTED/go"
GOPRIVATE="REDACTED"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.15.6/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.15.6/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="REDACTED/src/go/sub/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/lq/0w5qv41s33g8hzgcwqxqfrjmfw3hpz/T/go-build005396178=/tmp/go-build -gno-record-gcc-switches -fno-common"
@nicerobot nicerobot added area/v2 relates to / is being considered for v2 kind/bug describes or fixes a bug status/triage maintainers still need to look into this labels Dec 29, 2020
@nicerobot nicerobot changed the title v2 bug: ( your bug title goes here ) v2 bug: Command-actions with subcommands do not receive initialized context Dec 29, 2020
@stale
Copy link

stale bot commented Apr 18, 2021

This issue or PR has been automatically marked as stale because it has not had recent activity. Please add a comment bumping this if you're still interested in it's resolution! Thanks for your help, please let us know if you need anything else.

@stale stale bot added the status/stale stale due to the age of it's last update label Apr 18, 2021
@nicerobot
Copy link
Author

This bug persists. Please keep the bug open.

@stale
Copy link

stale bot commented Apr 18, 2021

This issue or PR has been bumped and is no longer marked as stale! Feel free to bump it again in the future, if it's still relevant.

@stale stale bot removed the status/stale stale due to the age of it's last update label Apr 18, 2021
@stale
Copy link

stale bot commented Jul 19, 2021

This issue or PR has been automatically marked as stale because it has not had recent activity. Please add a comment bumping this if you're still interested in it's resolution! Thanks for your help, please let us know if you need anything else.

@stale stale bot added the status/stale stale due to the age of it's last update label Jul 19, 2021
@nicerobot
Copy link
Author

Please s not close this.

@stale
Copy link

stale bot commented Jul 20, 2021

This issue or PR has been bumped and is no longer marked as stale! Feel free to bump it again in the future, if it's still relevant.

@stale stale bot removed the status/stale stale due to the age of it's last update label Jul 20, 2021
@rliebz rliebz added the pinned should not be marked stale label Jul 21, 2021
@jalavosus
Copy link
Contributor

@nicerobot try implementing a(n essentially empty) After() on your new cli.App. After() fires off, well, after the context is initialized but before commands are actually run. It might provide the right little bit of whatever to make your context work.

@nicerobot
Copy link
Author

No luck

Run this updated Playground Example
package main

import (
	"fmt"

	"github.com/urfave/cli/v2"
)

//
func main() {
	before := func(ctx *cli.Context) error {
		fmt.Printf("\nbefore %#v\n", ctx.Command)
		return nil
	}
	action := func(ctx *cli.Context) error {
		fmt.Printf("action %#v\n", ctx.Command)
		return nil
	}
	after := func(ctx *cli.Context) error {
		fmt.Printf("after  %#v\n", ctx.Command)
		return nil
	}
	sub := cli.Commands{{Name: "sub", Usage: "sub", Action: action, After: after, Before: before}}
	withsub := &cli.Command{Name: "withsub", Usage: "withsub", Action: action, After: after, Before: before, Subcommands: sub}
	withoutsub := &cli.Command{Name: "withoutsub", Usage: "withoutsub", Action: action, After: after, Before: before}
	app := &cli.App{Commands: cli.Commands{withsub, withoutsub}}

	// These two work fine
	_ = app.Run([]string{"play", "withsub", "sub"})
	_ = app.Run([]string{"play", "withoutsub"})

	// This one does not pass a properly initialized context
	fmt.Println("Notice the Command.Name is empty:")
	_ = app.Run([]string{"play", "withsub"})

	// It calls this:            https://github.com/urfave/cli/blob/master/command.go#L94
	// without first doing this: https://github.com/urfave/cli/blob/master/command.go#L162
}

@meatballhat meatballhat changed the title v2 bug: Command-actions with subcommands do not receive initialized context Command-actions with subcommands do not receive initialized context Apr 21, 2022
@dearchap
Copy link
Contributor

@nicerobot The latest release which optimizes the app/cmd code actually fixed this. Can you test ?

@dearchap dearchap added the status/waiting-for-response Waiting for response from original requester label Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/v2 relates to / is being considered for v2 kind/bug describes or fixes a bug pinned should not be marked stale status/triage maintainers still need to look into this status/waiting-for-response Waiting for response from original requester
Projects
None yet
Development

No branches or pull requests

5 participants