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

config: refactor commands to print help for flags (#3536) #3538

Merged
merged 77 commits into from
Oct 17, 2017

Conversation

magiconair
Copy link
Contributor

This patch refactors the commands that use the mitchellh/cli library to
populate the command line flag set in both the Run() and the Help()
method. Earlier versions of the mitchellh/cli library relied on the
Run() method to populuate the flagset for generating the usage screen.
This has changed in later versions and was previously solved with a
small monkey patch to the library to restore the old behavior.

However, this makes upgrading the library difficult since the patch has
to be restored every time.

This patch addresses this by moving the command line flags into an
initFlags() method where appropriate and also moving all variables for
the flags from the Run() method into the command itself.

Fixes #3536

@magiconair magiconair force-pushed the issue-3536-fix-cli-help branch from 6ed138c to ab6b970 Compare October 6, 2017 10:49
@magiconair magiconair self-assigned this Oct 6, 2017
@magiconair magiconair force-pushed the issue-3536-fix-cli-help branch 8 times, most recently from 912a86a to 98c2faf Compare October 11, 2017 14:49
@preetapan preetapan force-pushed the issue-3536-fix-cli-help branch from 98c2faf to 0083f1a Compare October 11, 2017 17:45
@magiconair magiconair force-pushed the issue-3536-fix-cli-help branch from 9541818 to f028b92 Compare October 17, 2017 11:03
@@ -18,7 +18,6 @@ import (

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was running these in parallel breaking something? The tests were passing on this branch for me when I last touched it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, but it wasn't helping either since go test already does package level parallelization. My CPU burned through all the tests in the same time whether the tests were running in parallel or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried it again. Test run time goes from 55sec to 51sec when running tests in parallel. Maybe I should leave this in.

@magiconair
Copy link
Contributor Author

magiconair commented Oct 17, 2017


Seems to be fixed.

@magiconair magiconair force-pushed the issue-3536-fix-cli-help branch from e4721d1 to bafa5d4 Compare October 17, 2017 14:10
Copy link
Contributor

@slackpad slackpad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few minor things to clean up but the approach LGTM. Once this is merged can you please take it over to the consul-enterprise fork? There will be a minor merge conflict in commands.go and there are a few commands over there that will need to get migrated.

c.http = &flags.HTTPFlags{}
flags.Merge(c.flags, c.http.ClientFlags())
flags.Merge(c.flags, c.http.ServerFlags())
c.help = flags.Usage(help, c.flags, c.http.ClientFlags(), c.http.ServerFlags())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we have to repeat c.http.ClientFlags(), c.http.ServerFlags() in Usage() if they are already merged into c.flags?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c.flags contains the total list of command line flags the command accepts. For the usage we want to group the flags by HTTP API Options and Command Options. Unless we hard-code the names in the flags.Usage method we cannot tell which flag is an HTTP API flag or a Command flag. The BaseCommand did this under the hood by using some bit flags to determine whether a command had HTTP API flags in addition to the command flags. I went through a number of different approaches. I can see whether I can come up with a better approach since this is a cause of errors.

$ bin/consul event -h
Usage: consul event [options] [payload]

  Dispatches a custom user event across a datacenter. An event must provide
  a name, but a payload is optional. Events support filtering using
  regular expressions on node name, service, and tag definitions.

HTTP API Options

  -ca-file=<value>
     Path to a CA file to use for TLS when communicating with Consul.
     This can also be specified via the CONSUL_CACERT environment
     variable.

  -ca-path=<value>
     Path to a directory of CA certificates to use for TLS when
     communicating with Consul. This can also be specified via the
     CONSUL_CAPATH environment variable.

  -client-cert=<value>
     Path to a client cert file to use for TLS when 'verify_incoming'
     is enabled. This can also be specified via the CONSUL_CLIENT_CERT
     environment variable.

  -client-key=<value>
     Path to a client key file to use for TLS when 'verify_incoming'
     is enabled. This can also be specified via the CONSUL_CLIENT_KEY
     environment variable.

  -http-addr=<address>
     The `address` and port of the Consul HTTP agent. The value can be
     an IP address or DNS address, but it must also include the port.
     This can also be specified via the CONSUL_HTTP_ADDR environment
     variable. The default value is http://127.0.0.1:8500. The scheme
     can also be set to HTTPS by setting the environment variable
     CONSUL_HTTP_SSL=true.

  -tls-server-name=<value>
     The server name to use as the SNI host when connecting via
     TLS. This can also be specified via the CONSUL_TLS_SERVER_NAME
     environment variable.

  -token=<value>
     ACL token to use in the request. This can also be specified via the
     CONSUL_HTTP_TOKEN environment variable. If unspecified, the query
     will default to the token of the Consul agent at the HTTP address.

Command Options

  -name=<string>
     Name of the event.

  -node=<string>
     Regular expression to filter on node names.

  -service=<string>
     Regular expression to filter on service instances.

  -tag=<string>
     Regular expression to filter on service tags. Must be used with
     -service.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can simplify that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do like the explicit merge approach vs. the bitfields. I'm wondering if we can search for the ClientFlags and ServerFlags when we render the usage and group them, and filter them out otherwise, since we know what they are.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. With the current code this is no longer necessary. I've refactored the commands so that they extract the HTTP API flags automatically.

c.http = &flags.HTTPFlags{}
flags.Merge(c.flags, c.http.ClientFlags())
flags.Merge(c.flags, c.http.ServerFlags())
c.help = flags.Usage(help, c.flags, c.http.ClientFlags(), c.http.ServerFlags())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an agent-level command so should just have ClientFlags but not ServerFlags.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

if err := c.BaseCommand.Parse(args); err != nil {
c.http = &flags.HTTPFlags{}
flags.Merge(c.flags, c.http.ClientFlags())
flags.Merge(c.flags, c.http.ServerFlags())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No server, just client for this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

c.flags = flag.NewFlagSet("", flag.ContinueOnError)
c.http = &flags.HTTPFlags{}
flags.Merge(c.flags, c.http.ClientFlags())
flags.Merge(c.flags, c.http.ServerFlags())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No server flags on this one.

c.http = &flags.HTTPFlags{}
flags.Merge(c.flags, c.http.ClientFlags())
flags.Merge(c.flags, c.http.ServerFlags())
c.help = flags.Usage(help, c.flags, c.http.ClientFlags(), c.http.ServerFlags())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No server on this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -578,6 +578,12 @@ func (c *CLI) processArgs() {
break
}

// Check for help flags.
if arg == "-h" || arg == "-help" || arg == "--help" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be in this PR or is it a no-op with the de-monkey-patch change that just got merged?

Copy link
Contributor Author

@magiconair magiconair Oct 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the reversal of the monkey patch which was the motivation for this PR in the first place and it should be in this PR. The other de-monkey-patch was for mitchellh/mapstructure not mitchellh/cli.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it - ok.

@magiconair
Copy link
Contributor Author

I'll do the enterprise code as well.

This patch refactors the commands that use the mitchellh/cli library to
populate the command line flag set in both the Run() and the Help()
method. Earlier versions of the mitchellh/cli library relied on the
Run() method to populuate the flagset for generating the usage screen.
This has changed in later versions and was previously solved with a
small monkey patch to the library to restore the old behavior.

However, this makes upgrading the library difficult since the patch has
to be restored every time.

This patch addresses this by moving the command line flags into an
initFlags() method where appropriate and also moving all variables for
the flags from the Run() method into the command itself.

Fixes #3536
@magiconair magiconair force-pushed the issue-3536-fix-cli-help branch from 55fc684 to 0543f65 Compare October 17, 2017 22:07
Copy link
Contributor

@slackpad slackpad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@magiconair
Copy link
Contributor Author

Here we go!

@magiconair magiconair merged commit b3292d1 into master Oct 17, 2017
@magiconair magiconair deleted the issue-3536-fix-cli-help branch October 17, 2017 22:08
@magiconair magiconair added this to the 1.0.1 milestone Oct 17, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants