[mkgmap-dev] complete list of all mkgmap options
From Chris Miller chris.miller at kbcfp.com on Tue Aug 4 10:35:50 BST 2009
> What I believe we need is some fascist check in the options processing > code that prints a message and quits the program if you specify an > option that isn't recognised. Furthermore, it would then be possible > to list the supported options with nothing left out or spelt > incorrectly, etc. > > Cheers, > > Mark Something we've done at my current job is to write a CLI framework that makes managing command line params very very easy. I think this project could benefit greatly from this approach due to its large number of (frequently changing?) parameters. Unfortunately I can't contribute our code, however I can describe in detail what we did and help with the implementation. Basically each application that uses command line params defines an interface that looks something like this: public interface MkGMapParams { @Option(defaultValue = "0", description = "The Family ID for the generated map") int getFamilyId(); @Option(defaultValue = Option.REQUIRED, description = "The Product ID for the generated map") int getProductId(); @Option(defaultValue = Option.OPTIONAL, description = "The country the map represents") String getCountryName(); @Option(description = "Specify this to make cycleways") boolean isMakeCycleways(); enum MyEnum { One, Two } @Option(name = "custom-enum", defaultValue = "One", description = "My custom enum") MyEnum getEnum(); // etc } To parse the parameters in code, we basically just make a call to our parser as follows: MkGMapParams params = CliParser.parse(MkGMapParams.class, arguments); // where arguments is a String... parameter That's it, the 'params' object now has all our command line params, parsed into the correct type. If any of the parsing failed, error(s) explaining what was wrong, along with a list of valid options and descriptions, are displayed to the user. Some valid usage examples: java -jar mkgmap --product-id 99 --country-name bhutan --make-cycleways java -jar mkgmap --product-id 99 --custom-enum Two Some invalid usage examples: java -jar mkgmap --family-id 99 --country-name bhutan --make-cycleways (fails because --product-id is a required parameter) java -jar mkgmap --product-id 99 --enum One (fails because the 'enum' parameter must be specified as --custom-enum, not --enum) java -jar mkgmap --product-id abc (fails because --product-id is not an integer) java -jar mkgmap --product-id 11 --family-id --make-cycleways (fails because no value was specified for --family-id) Here's how it works under the hood: We have a converter interface defined as follows: interface Converter<T> { T convert(String param) throws Exception; // Convert from the string provided on the command line to a typesafe object. List<String> getValidValues() throws Exception; // Provide a list of valid options (optional). eg a list of enum values. String getDefaultValue() throws Exception; // Returns the default value (or null if the parameter is required). } We then have a map from type to converter class, eg: defaultConverters.put(String.class, StringConverter.class); defaultConverters.put(Integer.class, IntegerConverter.class); defaultConverters.put(Integer.type, IntegerConverter.class); We then use reflection (and the annotation info) to examine the interface and determine what the valid parameters are, whether they're required, what type they are etc. For each parameter we parse we convert the string to the appropriate type using the above map. Once that's done and no errors were found, we use Proxy.newProxyInstance() to create an instance of the parameter interface for the client application. Note that we have a lot of additional functionality too like list handling, custom converters, inter-parameter dependency handling, custom validation, Guice support etc but the above is the guts of it. I hope it doesn't sound like too much work - it's really not! The best thing is it will force people to clearly define their parameters in the MkGMapParams interface since that's the only thing that'll be available anywhere beyond the main() method. It's very easy to use once the scaffolding is in place and it makes for nice centralised management of params and user friendly help and error messages. Chris
- Previous message: [mkgmap-dev] complete list of all mkgmap options
- Next message: [mkgmap-dev] complete list of all mkgmap options
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the mkgmap-dev mailing list