Пример #1
0
  def execute(self):
    def add_targets(dir, buildfile):
      try:
        self.targets.extend(Target.get(addr) for addr in Target.get_all_addresses(buildfile))
      except (TypeError, ImportError):
        error(dir, include_traceback=True)
      except (IOError, SyntaxError):
        error(dir)

    if self.options.recursive_directory:
      with self.check_errors('There was a problem scanning the '
                             'following directories for targets:') as error:
        for dir in self.options.recursive_directory:
          for buildfile in BuildFile.scan_buildfiles(self.root_dir, dir):
            add_targets(dir, buildfile)

    if self.options.target_directory:
      with self.check_errors("There was a problem loading targets "
                             "from the following directory's BUILD files") as error:
        for dir in self.options.target_directory:
          add_targets(dir, BuildFile(self.root_dir, dir))

    timer = None
    if self.options.time:
      class Timer(object):
        def now(self):
          return time.time()
        def log(self, message):
          print message
      timer = Timer()

    logger = None
    if self.options.log or self.options.log_level:
      from twitter.common.log import init
      from twitter.common.log.options import LogOptions
      LogOptions.set_stdout_log_level((self.options.log_level or 'info').upper())
      logdir = self.config.get('goals', 'logdir')
      if logdir:
        safe_mkdir(logdir)
        LogOptions.set_log_dir(logdir)
      init('goals')
      logger = log

    context = Context(self.config, self.options, self.targets, log=logger)

    unknown = []
    for phase in self.phases:
      if not phase.goals():
        unknown.append(phase)

    if unknown:
        print 'Unknown goal(s): %s' % ' '.join(phase.name for phase in unknown)
        print
        return Phase.execute(context, 'goals')

    return Phase.attempt(context, self.phases, timer=timer)
Пример #2
0
  def execute(self, targets):
    goal = self.context.options.help_goal
    if goal is None:
      return self.list_goals('You must supply a goal name to provide help for.')
    phase = Phase(goal)
    if not phase.goals():
      return self.list_goals('Goal %s is unknown.' % goal)

    parser = Help.parser()
    parser.set_usage('%s goal %s ([target]...)' % (sys.argv[0], goal))
    parser.epilog = phase.description
    Phase.setup_parser(parser, [], [phase])
    parser.parse_args(['--help'])
Пример #3
0
 def execute(self, targets):
    print 'Installed goals:'
    documented_rows = []
    undocumented = []
    max_width = 0
    for phase, _ in Phase.all():
      if phase.description:
        documented_rows.append((phase.name, phase.description))
        max_width = max(max_width, len(phase.name))
      elif self.context.options.goal_list_all:
        undocumented.append(phase.name)
    for name, description in documented_rows:
      print '  %s: %s' % (name.rjust(max_width), description)
    if undocumented:
      print '\nUndocumented goals:\n  %s' % ' '.join(undocumented)
Пример #4
0
 def list_goals(self, message):
   print message
   print
   return Phase.execute(self.context, 'goals')
Пример #5
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)