1 // Copyright 2014 The Bazel Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package com.google.devtools.common.options; 16 17 import java.util.Arrays; 18 import java.util.List; 19 20 /** 21 * Interface for parsing options from a single options specification class. 22 * 23 * The {@link Options#parse(Class, String...)} method in this class has no clear 24 * use case. Instead, use the {@link OptionsParser} class directly, as in this 25 * code snippet: 26 * 27 * <pre> 28 * OptionsParser parser = OptionsParser.newOptionsParser(FooOptions.class); 29 * try { 30 * parser.parse(FooOptions.class, args); 31 * } catch (OptionsParsingException e) { 32 * System.err.print("Error parsing options: " + e.getMessage()); 33 * System.err.print(options.getUsage()); 34 * System.exit(1); 35 * } 36 * FooOptions foo = parser.getOptions(FooOptions.class); 37 * List<String> otherArguments = parser.getResidue(); 38 * </pre> 39 * 40 * Using this class in this case actually results in more code. 41 * 42 * @see OptionsParser for parsing options from multiple options specification classes. 43 */ 44 public class Options<O extends OptionsBase> { 45 46 /** 47 * Parse the options provided in args, given the specification in 48 * optionsClass. 49 */ parse(Class<O> optionsClass, String... args)50 public static <O extends OptionsBase> Options<O> parse(Class<O> optionsClass, String... args) 51 throws OptionsParsingException { 52 OptionsParser parser = OptionsParser.newOptionsParser(optionsClass); 53 parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList(args)); 54 List<String> remainingArgs = parser.getResidue(); 55 return new Options<O>(parser.getOptions(optionsClass), 56 remainingArgs.toArray(new String[0])); 57 } 58 59 /** 60 * Returns an options object at its default values. The returned object may 61 * be freely modified by the caller, by assigning its fields. 62 */ getDefaults(Class<O> optionsClass)63 public static <O extends OptionsBase> O getDefaults(Class<O> optionsClass) { 64 try { 65 return parse(optionsClass, new String[0]).getOptions(); 66 } catch (OptionsParsingException e) { 67 String message = "Error while parsing defaults: " + e.getMessage(); 68 throw new AssertionError(message); 69 } 70 } 71 72 /** 73 * Returns a usage string (renders the help information, the defaults, and 74 * of course the option names). 75 */ getUsage(Class<? extends OptionsBase> optionsClass)76 public static String getUsage(Class<? extends OptionsBase> optionsClass) { 77 StringBuilder usage = new StringBuilder(); 78 OptionsUsage.getUsage(optionsClass, usage); 79 return usage.toString(); 80 } 81 82 private O options; 83 private String[] remainingArgs; 84 Options(O options, String[] remainingArgs)85 private Options(O options, String[] remainingArgs) { 86 this.options = options; 87 this.remainingArgs = remainingArgs; 88 } 89 90 /** 91 * Returns an instance of options class O. 92 */ getOptions()93 public O getOptions() { 94 return options; 95 } 96 97 /** 98 * Returns the arguments that we didn't parse. 99 */ getRemainingArgs()100 public String[] getRemainingArgs() { 101 return remainingArgs; 102 } 103 104 } 105