groovy
  1. groovy
  2. GROOVY-4066

Groovy clibuilder doesn't take the parameter when the longOpt name ends with character "s"

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.7.0
    • Fix Version/s: 1.7.2, 1.8-beta-1
    • Component/s: None
    • Labels:
      None
    • Environment:
      Linux, Mac
    • Testcase included:
      yes
    • Number of attachments :
      0

      Description

      When the clibuilder creates a command line option whose longOpt ends with character "s", such as "seconds", the parser can't get the parameter, it is null.

      Here's a simple groovy script that demonstrates the problem. Note that the long option ending with an 's' gets enabled when the non-s option is given.

      $> ./cli.groovy -s
      options.s evaluates to true
      options.seconds evaluates to false
      options.e evaluates to false
      options.second evaluates to false

      $> ./cli.groovy -e
      options.s evaluates to false
      options.seconds evaluates to true
      options.e evaluates to true
      options.second evaluates to true

      def cli = new CliBuilder()
      cli.s longOpt:'seconds', 'a long arg that ends with an "s"'
      cli.e longOpt:'second', 'a long arg that does not end with an "s"'

      def options = cli.parse( args )
      if( null == options )
      {
      return
      }

      if( args.length == 0 || options.h )
      {
      cli.usage()
      }

      println "options.s evaluates to " + (options.s as boolean)
      println "options.seconds evaluates to " + (options.seconds as boolean)
      println "options.e evaluates to " + (options.e as boolean)
      println "options.second evaluates to " + (options.second as boolean)

        Activity

        Hide
        Roshan Dawrani added a comment -

        I don't think that is a bug (may be a documentation issue, but I haven't checked it out yet).

        The longOpt(s) is there to support getting multiple option values.

        Say, if you have an option (short name = D, long name = define) that lets you pass multiple values with it, you can retrieve them as getOptionValues('D') or options.defines (plural form, that internally maps to getOptionValues('D')) - so it removes last 's', takes the option long name as 'define' and then invokes the getOptionValues() to get all associated values.

        Show
        Roshan Dawrani added a comment - I don't think that is a bug (may be a documentation issue, but I haven't checked it out yet). The longOpt(s) is there to support getting multiple option values. Say, if you have an option (short name = D, long name = define) that lets you pass multiple values with it, you can retrieve them as getOptionValues('D') or options.defines (plural form, that internally maps to getOptionValues('D')) - so it removes last 's', takes the option long name as 'define' and then invokes the getOptionValues() to get all associated values.
        Hide
        Paul King added a comment -

        A while back when commons cli looked stalled, I wrote a version of CliBuilder for a different underlying engine. In that, I looked for non-plural forms and only took the 's' off for those cases. It seemed to work well. Perhaps it could be backed ported for our commons cli version.

        Show
        Paul King added a comment - A while back when commons cli looked stalled, I wrote a version of CliBuilder for a different underlying engine. In that, I looked for non-plural forms and only took the 's' off for those cases. It seemed to work well. Perhaps it could be backed ported for our commons cli version.
        Hide
        Roshan Dawrani added a comment -

        I think that will be an improvement - that options.seconds will become plural of options.second only if option "second" is defined, otherwise, it will try to use it as "seconds" itself.

        It won't help where both singular and plural options ("second" and "seconds") are defined, as in this JIRA's case, but is an improvement over current behavior nonetheless.

        Show
        Roshan Dawrani added a comment - I think that will be an improvement - that options.seconds will become plural of options.second only if option "second" is defined, otherwise, it will try to use it as "seconds" itself. It won't help where both singular and plural options ("second" and "seconds") are defined, as in this JIRA's case, but is an improvement over current behavior nonetheless.
        Hide
        mingran wang added a comment -

        Roshan, thanks for the reply. If I use the short option name: "options.s", I still don't get anything. Effectively, it stops people from adding "s" to the end of any long option name, plus, there is no clear documentation on this.

        For instance, I was trying to use a parameter like "number_of_seconds", if I can't add "s" to the longOpt, I have to change the name to "number_of_second" which sounds weird. Also, I took me quite some time to find the trick of trailing "s", since there was no warning or error in runtime. I searched documentation and couldn't find any thing about this trick.

        So from a user point of view, this does make people's life more difficult, especially if they are unaware of this trick.

        Show
        mingran wang added a comment - Roshan, thanks for the reply. If I use the short option name: "options.s", I still don't get anything. Effectively, it stops people from adding "s" to the end of any long option name, plus, there is no clear documentation on this. For instance, I was trying to use a parameter like "number_of_seconds", if I can't add "s" to the longOpt, I have to change the name to "number_of_second" which sounds weird. Also, I took me quite some time to find the trick of trailing "s", since there was no warning or error in runtime. I searched documentation and couldn't find any thing about this trick. So from a user point of view, this does make people's life more difficult, especially if they are unaware of this trick.
        Hide
        Roshan Dawrani added a comment -

        We'll improve the behavior now (as Paul has suggested) as well as update the documentation to talk about this plural trick.

        After the change, it will allow you to have an option like "number_of_seconds" (unless you also have happen to have "number_of_second" because then it will have a conflict with the plural feature again)

        Show
        Roshan Dawrani added a comment - We'll improve the behavior now (as Paul has suggested) as well as update the documentation to talk about this plural trick. After the change, it will allow you to have an option like "number_of_seconds" (unless you also have happen to have "number_of_second" because then it will have a conflict with the plural feature again)
        Hide
        Roshan Dawrani added a comment -

        Fixed, as discussed here. Here is the test that code goes through after the fix:

        def cli = new CliBuilder ()
        cli.s ( longOpt : 'number_of_seconds', 'a long arg that ends with an "s"' )
        
        def options = cli.parse (['-s'])
        
        assert options.hasOption ( 's' )
        assert options.hasOption ( 'number_of_seconds' )
        assert options.s
        assert options.number_of_seconds
        

        Thanks for the hint, Paul.

        Show
        Roshan Dawrani added a comment - Fixed, as discussed here. Here is the test that code goes through after the fix: def cli = new CliBuilder () cli.s ( longOpt : 'number_of_seconds', 'a long arg that ends with an "s" ' ) def options = cli.parse (['-s']) assert options.hasOption ( 's' ) assert options.hasOption ( 'number_of_seconds' ) assert options.s assert options.number_of_seconds Thanks for the hint, Paul.

          People

          • Assignee:
            Roshan Dawrani
            Reporter:
            mingran wang
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: