def setUp(self): with temporary_file() as ini: ini.write( """ [DEFAULT] answer: 42 scale: 1.2 path: /a/b/%(answer)s embed: %(path)s::foo disclaimer: Let it be known that. [a] fast: True list: [1, 2, 3, %(answer)s] [b] preempt: False dict: { 'a': 1, 'b': %(answer)s, 'c': ['%(answer)s', %(answer)s] } """ ) ini.close() self.config = Config.load(configpath=ini.name)
def setup_parser(self, parser, args): self.config = Config.load() parser.add_option("-x", "--time", action="store_true", dest = "time", default = False, help = "Times goal phases and outputs a report.") parser.add_option("-v", "--log", action="store_true", dest = "log", default = False, help = "[%default] Logs extra build output.") parser.add_option("-l", "--level", dest = "log_level", type="choice", choices=['debug', 'info', 'warn'], help = "[info] Sets the logging level to one of 'debug', 'info' or 'warn', " "implies -v if set.") parser.add_option("--all", dest="target_directory", action="append", help = "Adds all targets found in the given directory's BUILD file. Can " "be specified more than once.") parser.add_option("--all-recursive", dest="recursive_directory", action="append", help = "Adds all targets found recursively under the given directory. Can " "be specified more than once to add more than one root target " "directory to scan.") # We support attempting zero or more goals. Multiple goals must be delimited from further # options and non goal args with a '--'. The key permutations we need to support: # ./pants goal => goals # ./pants goal goals => goals # ./pants goal compile src/java/... => compile # ./pants goal compile -x src/java/... => compile # ./pants goal compile src/java/... -x => compile # ./pants goal compile run -- src/java/... => compile, run # ./pants goal compile run -- src/java/... -x => compile, run # ./pants goal compile run -- -x src/java/... => compile, run if not args: args.append('goals') if len(args) == 1 and args[0] in set(['-h', '--help', 'help']): def format_usage(usages): left_colwidth = 0 for left, right in usages: left_colwidth = max(left_colwidth, len(left)) lines = [] for left, right in usages: lines.append(' %s%s%s' % (left, ' ' * (left_colwidth - len(left) + 1), right)) return '\n'.join(lines) usages = [ ("%prog goal goals ([spec]...)", Phase('goals').description), ("%prog goal help [goal] ([spec]...)", Phase('help').description), ("%prog goal [goal] [spec]...", "Attempt goal against one or more targets."), ("%prog goal [goal] ([goal]...) -- [spec]...", "Attempts all the specified goals."), ] parser.set_usage("\n%s" % format_usage(usages)) parser.epilog = ("Either lists all installed goals, provides extra help for a goal or else " "attempts to achieve the specified goal for the listed targets.") parser.print_help() sys.exit(0) else: goals = [] help = False multi = False for i, arg in enumerate(args): help = help or 'help' == arg goals.append(arg) if '--' == arg: multi = True del args[i] goals.pop() break if arg.startswith('-'): break if not multi: goals = [goals[0]] spec_offset = len(goals) + 1 if help else len(goals) specs = [arg for arg in args[spec_offset:] if not arg.startswith('-')] def parse_build(buildfile): # TODO(John Sirois): kill PANTS_NEW and its usages when pants.new is rolled out ParseContext(buildfile).parse(PANTS_NEW=True) # Bootstrap goals by loading any configured bootstrap BUILD files with self.check_errors('The following bootstrap_buildfiles cannot be loaded:') as error: for path in self.config.getlist('goals', 'bootstrap_buildfiles', default = []): try: buildfile = BuildFile(get_buildroot(), os.path.relpath(path, get_buildroot())) parse_build(buildfile) except (TypeError, ImportError): error(path, include_traceback=True) except (IOError, SyntaxError): error(path) # Bootstrap user goals by loading any BUILD files implied by targets self.targets = [] with self.check_errors('The following targets could not be loaded:') as error: for spec in specs: try: address = Address.parse(get_buildroot(), spec) parse_build(address.buildfile) target = Target.get(address) if target: self.targets.append(target) else: siblings = Target.get_all_addresses(address.buildfile) prompt = 'did you mean' if len(siblings) == 1 else 'maybe you meant one of these' error('%s => %s?:\n %s' % (address, prompt, '\n '.join(str(a) for a in siblings))) except (TypeError, ImportError): error(spec, include_traceback=True) except (IOError, SyntaxError): error(spec) self.phases = [Phase(goal) for goal in goals] Phase.setup_parser(parser, args, self.phases)