Example #1
0
    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)
Example #2
0
  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)