Apache Commons CLI - ordering help options?
Asked Answered
F

6

14

I'm using the Apache Commons CLI. By default it orders help options on the command line alphabetically by key. So, what appears is:

-csv
-ip
-msisdn
-xml

But I want to order them as follows:

-csv
-xml
-ip
-msisdn

I know that there is a OptionFormatter class you can use and pass to the HelpFormatter, but can't see any examples on how to use it for my purposes above (http://www.marko.homeunix.org/programming/java/commons-cli/api/org/apache/commons/cli/HelpFormatter.OptionComparator.html).

Just wondering has anyone done anything similar?

Thanks

Ferity answered 31/7, 2012 at 13:47 Comment(1)
wow. You would think that something that simple would work.Pileup
P
3

Currently it is not supported. But it is an open source so, you know what to do...

From the source code:

    private static class OptionComparator
    implements Comparator {

    /**
     * <p>Compares its two arguments for order. Returns a negative 
     * integer, zero, or a positive integer as the first argument 
     * is less than, equal to, or greater than the second.</p>
     *
     * @param o1 The first Option to be compared.
     * @param o2 The second Option to be compared.
     *
     * @return a negative integer, zero, or a positive integer as 
     * the first argument is less than, equal to, or greater than the 
     * second.
     */
    public int compare(Object o1, Object o2)
    {
        Option opt1 = (Option)o1;
        Option opt2 = (Option)o2;

        return opt1.getKey().compareToIgnoreCase(opt2.getKey());
    }
}

You can override the default comparator and define the order you want.

Propertius answered 31/7, 2012 at 14:3 Comment(0)
U
27

Since v1.3 you can call setOptionComparator(null), this way the formatter will skip sorting, and the arguments will be printed in the same order they were added.

HelpFormatter formatter = new HelpFormatter();
formatter.setOptionComparator(null);

Link to the actual issue.

Ulrich answered 2/11, 2016 at 8:57 Comment(0)
Q
10

As of Apache Commons CLI 1.2, you can set the comparator directly on the HelpFormatter class:

setOptionComparator [link]

public void setOptionComparator(Comparator comparator)

Set the comparator used to sort the options when they output in help text. Passing in a null parameter will set the ordering to the default mode.

You should supply your own implementation of Comparator<Option> that sorts your options in the order you desire.

Quatrefoil answered 16/9, 2012 at 17:45 Comment(2)
The default is alphabetic, so passing null doesn't help.Immixture
As of Apache Commons CLI 1.3, they changed the outcome of passing a null comparator to setOptionComparator(Comparator comparator). From the documentation: Passing in a null comparator will keep the options in the order they were declared.Lyophilize
S
9

And the best KISS-way to implement such comparator is:

class OptionComparator<T extends Option> implements Comparator<T> {

    private static final String OPTS_ORDER = "abcdef"; // short option names

    public int compare(T o1, T o2) {
        return OPTS_ORDER.indexOf(o1.getOpt()) - OPTS_ORDER.indexOf(o2.getOpt());
    }
}

 

Sensual answered 18/9, 2012 at 9:1 Comment(1)
I'd rather use a List and then it's indexOf("optName") method. Or even better, I would add the same Option instance added to the Options class to a List<Option>, and then use the list's indexOf(option) method inside the Comparator.Vharat
P
3

Currently it is not supported. But it is an open source so, you know what to do...

From the source code:

    private static class OptionComparator
    implements Comparator {

    /**
     * <p>Compares its two arguments for order. Returns a negative 
     * integer, zero, or a positive integer as the first argument 
     * is less than, equal to, or greater than the second.</p>
     *
     * @param o1 The first Option to be compared.
     * @param o2 The second Option to be compared.
     *
     * @return a negative integer, zero, or a positive integer as 
     * the first argument is less than, equal to, or greater than the 
     * second.
     */
    public int compare(Object o1, Object o2)
    {
        Option opt1 = (Option)o1;
        Option opt2 = (Option)o2;

        return opt1.getKey().compareToIgnoreCase(opt2.getKey());
    }
}

You can override the default comparator and define the order you want.

Propertius answered 31/7, 2012 at 14:3 Comment(0)
B
1

If you know exact order of the options, you can extend Option class to include your ordering number and provider your OrderedOption instances to the Options instance using Options.add(Option opt) method.

Then, create a comparator and compare order numbers in your OrderedOptions... I would recommend not to mix both types of Option instances in one Options instance as it can complicate ordering and also testing for the valid OrderedOption instance in Comparator.

Barns answered 31/7, 2012 at 14:10 Comment(0)
D
0

You can order the help values using the following code:

    HelpFormatter formatter = new HelpFormatter();
    // print the help options in the save order you added 
    formatter.setOptionComparator(new Comparator<Option>() {
        @Override
        public int compare(Option o1, Option o2) {
            List<Option> options = new ArrayList<Option>(getOptions().getOptions());
            Integer indexOfO1 = options.indexOf(o1);
            Integer indexOfO2 = options.indexOf(o2);
            return indexOfO1.compareTo(indexOfO2);
        }
    });
    formatter.printHelp("Commandline syntax", OPTIONS);
Disney answered 18/3, 2022 at 17:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.