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

A couple of enhancements... #7

Open
stevewi-niteflyte opened this issue Jan 26, 2025 · 4 comments
Open

A couple of enhancements... #7

stevewi-niteflyte opened this issue Jan 26, 2025 · 4 comments

Comments

@stevewi-niteflyte
Copy link

stevewi-niteflyte commented Jan 26, 2025

  1. Implement OptionParser.Separator() to be able to insert stuff in the --help output programmatically (e.g., newlines). See the Ruby doc.

  2. I have a program (called opt) that validates a shell script command line against specification provided in a JSON file. Here's a snippet:

{
   "xyzzy": {
        "short": "x",
        "desc": "Set the xyzzy",
        "type": "range",
         "value": "0..5",
        "default": 3
    }
}

This specification defines -x, --xyzzy as a range. The value of -r, --range must be an integer in the range (0..5) with a default of 3.

I use ParseFrom() to supply the shell script command line to my Go program (via the OptionParser.Extra data). I have a command line flag on my Go program that sets the script name:

opt -f jsonfile.json -n scriptName -- --the script --args

Hopefully, you get the idea...

Lets say that I supply an non-existent argument as part of the Extra(); e.g.

opt -f jsonfile.json -n scriptName -- --the script --args --nonexistent

The map sent to ParseFrom() is [scriptHame --the script --args --nonexistent]. I have a couple of lines of code to ensure that the first item in the map is scriptName.

ParseFrom() generates the appropriate error (as it should):

opt: unknown option nonexistent

I would like this message to be:

scriptName: unknown option nonexistent

So, in a nutshell, if you parse args with ParseFrom(foo), any error messages that ParseFrom() generates should use foo[0] as the program name.

I hope this is clear. Please reply if you have questions.

Thanks in advance...

P.S. It's a simple matter to make foo[0] the program name:

foo := op.Extra
foo = append([]string{"scriptName"}, foo...)

If op.Extra has [--the script --args --nonexistent], foo will have [scriptHame --the script --args --nonexistent].

@pgundlach
Copy link
Member

  1. What is the separator doing exactly? I don't understand "Add separator in summary." as the description of the Ruby command. Where is it added? What is the purpose of it?

  2. ParseFrom() generates the error message unknown option ... where ... is the name of the option. Isn't that enough? I don't understand where you get the prefix opt:.

@stevewi-niteflyte
Copy link
Author

stevewi-niteflyte commented Jan 26, 2025

So, the easy response first... #2 is my bad. I'm generating it. I have a layer on top of os.Stderr that facilitates the same interface for both output to stdout/stderr and to log files. That layer was generating the program name. Sorry...

As for #1, OptionParser.separator is used to add your own text in the --help output. Consider the following Ruby examples:

@options = {}

opts = OptionParser.new do |o|

...
     o.on('-f', "--file FILENAME", String, "Input file ('-' = STDIN)") do |f|
         @options[:file] = f
     end
        
     o.on('-n', '--name SCRIPTNAME', String, "Script name for error msgs ('options')") do |n|
        @options[:name] = n
     end

...

end

will produce the following in the --help output:

   -f, --file FILENAME      Input file ('-' = STDIN)
   -n, --name SCRIPTNAME    Script name for error msgs ('options')

This snippet:

@options = {}

opts = OptionParser.new do |o|

...
     o.on('-f', "--file FILENAME", String, "Input file ('-' = STDIN)") do |f|
         @options[:file] = f
     end
     
     o.separator("\nThe following are foo options:\n")
  
     o.on('-n', '--name SCRIPTNAME', String, "Script name for error msgs ('options')") do |n|
        @options[:name] = n
     end
     
     o.separator("\nThe following are bar options:\n")
  
...

end

will produce the following in the --help output:

   -f, --file FILENAME      Input file ('-' = STDIN)

The following are foo options:

   -n, --name SCRIPTNAME    Script name for error msgs ('options')

The following are bar options:

It's a way to programmatically annotate/decorate the --help output.

Thanks for your consideration...

@pgundlach
Copy link
Member

I am not sure if I understand 2) in full. Is there still some feature request open?

  1. Is interesting, I still need to think about a good way to store the the separator (and perhaps find a different name, separator can be anything, perhaps "section" or something like this is better?

@stevewi-niteflyte
Copy link
Author

I'm not going to quibble about what you call it ;-) I only picked separator because that's what it's called in Ruby optionparser... Actually, I'd prefer to call it what it is -- annotation.

Just as an aside, do you know of a package does something like the Ruby gem thor (also here)? This may be tough to accomplish given the fact that Go doesn't have the object orientation or the dynamic typing that Ruby does.

I looked at urfave/cli and it seems to be the most complete but, OMG!, the setup is horrendous...even for something simple. Maybe I'm missing something...

I'm just getting started with Go after years of programming almost exclusively with Ruby. Ruby has a lot of advantages but it's slow and most gems are not well-maintained. Plus, in order to build the most-performant JIT, you need to install Rust (!!!). Every release lately seems to break something...

Your optionparser is just what I need right now -- it's simple & straightforward and builds on my tribal knowledge about Ruby.

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

No branches or pull requests

2 participants