Пример #1
0
 def _parse_addresses(self, spec):
   if spec.endswith('::'):
     dir = self._get_dir(spec[:-len('::')])
     for buildfile in BuildFile.scan_buildfiles(self._root_dir, os.path.join(self._root_dir, dir)):
       for address in Target.get_all_addresses(buildfile):
         yield address
   elif spec.endswith(':'):
     dir = self._get_dir(spec[:-len(':')])
     for address in Target.get_all_addresses(BuildFile(self._root_dir, dir)):
       yield address
   else:
     yield Address.parse(self._root_dir, spec)
Пример #2
0
 def parse_jarcoordinate(coordinate):
     components = coordinate.split('#', 1)
     if len(components) == 2:
         org, name = components
         return org, name
     else:
         try:
             address = Address.parse(get_buildroot(), coordinate)
             try:
                 target = Target.get(address)
                 if not target:
                     siblings = Target.get_all_addresses(
                         address.buildfile)
                     prompt = 'did you mean' if len(
                         siblings
                     ) == 1 else 'maybe you meant one of these'
                     raise TaskError('%s => %s?:\n    %s' %
                                     (address, prompt, '\n    '.join(
                                         str(a) for a in siblings)))
                 if not target.is_exported:
                     raise TaskError('%s is not an exported target' %
                                     coordinate)
                 return target.provides.org, target.provides.name
             except (ImportError, SyntaxError, TypeError):
                 raise TaskError('Failed to parse %s' %
                                 address.buildfile.relpath)
         except IOError:
             raise TaskError('No BUILD file could be found at %s' %
                             coordinate)
Пример #3
0
 def parse_jarcoordinate(coordinate):
     components = coordinate.split('#', 1)
     if len(components) == 2:
         org, name = components
         return org, name
     else:
         try:
             # TODO(Eric Ayers) This code is suspect.  Target.get() is a very old method and almost certainly broken.
             # Refactor to use methods from BuildGraph or BuildFileAddressMapper
             address = Address.parse(get_buildroot(), coordinate)
             target = Target.get(address)
             if not target:
                 siblings = Target.get_all_addresses(address.build_file)
                 prompt = 'did you mean' if len(
                     siblings) == 1 else 'maybe you meant one of these'
                 raise TaskError('%s => %s?:\n    %s' %
                                 (address, prompt, '\n    '.join(
                                     str(a) for a in siblings)))
             if not target.is_exported:
                 raise TaskError('%s is not an exported target' %
                                 coordinate)
             return target.provides.org, target.provides.name
         except (BuildFile.BuildFileError,
                 BuildFileParser.BuildFileParserError,
                 AddressLookupError) as e:
             raise TaskError(
                 '{message}\n  Problem with BUILD file  at {coordinate}'
                 .format(message=e, coordinate=coordinate))
Пример #4
0
        def configure_target(target):
            if target not in analyzed:
                analyzed.add(target)

                self.has_scala = not self.skip_scala and (self.has_scala
                                                          or is_scala(target))

                if target.has_resources:
                    resources_by_basedir = defaultdict(set)
                    for resources in target.resources:
                        resources_by_basedir[resources.target_base].update(
                            resources.sources)
                    for basedir, resources in resources_by_basedir.items():
                        self.resource_extensions.update(
                            Project.extract_resource_extensions(resources))
                        configure_source_sets(basedir,
                                              resources,
                                              is_test=False)

                if target.sources:
                    test = target.is_test
                    self.has_tests = self.has_tests or test
                    configure_source_sets(target.target_base,
                                          target.sources,
                                          is_test=test)

                # Other BUILD files may specify sources in the same directory as this target.  Those BUILD
                # files might be in parent directories (globs('a/b/*.java')) or even children directories if
                # this target globs children as well.  Gather all these candidate BUILD files to test for
                # sources they own that live in the directories this targets sources live in.
                target_dirset = find_source_basedirs(target)
                candidates = Target.get_all_addresses(target.address.buildfile)
                for ancestor in target.address.buildfile.ancestors():
                    candidates.update(Target.get_all_addresses(ancestor))
                for sibling in target.address.buildfile.siblings():
                    candidates.update(Target.get_all_addresses(sibling))
                for descendant in target.address.buildfile.descendants():
                    candidates.update(Target.get_all_addresses(descendant))

                def is_sibling(target):
                    return source_target(
                        target) and target_dirset.intersection(
                            find_source_basedirs(target))

                return filter(
                    is_sibling,
                    [Target.get(a) for a in candidates if a != target.address])
Пример #5
0
 def _addresses(self):
   if self.context.target_roots:
     for target in self.context.target_roots:
       yield target.address
   else:
     for buildfile in BuildFile.scan_buildfiles(self._root_dir):
       for address in Target.get_all_addresses(buildfile):
         yield address
Пример #6
0
 def _find_targets(self):
   if len(self.context.target_roots) > 0:
     for target in self.context.target_roots:
       yield target
   else:
     for buildfile in BuildFile.scan_buildfiles(get_buildroot()):
       target_addresses = Target.get_all_addresses(buildfile)
       for target_address in target_addresses:
         yield Target.get(target_address)
Пример #7
0
    def scan_addresses(root_dir, base_path=None):
        """Parses all targets available in BUILD files under base_path and
    returns their addresses.  If no base_path is specified, root_dir is
    assumed to be the base_path"""

        addresses = OrderedSet()
        for buildfile in BuildFile.scan_buildfiles(root_dir, base_path):
            addresses.update(Target.get_all_addresses(buildfile))
        return addresses
Пример #8
0
  def scan_addresses(root_dir, base_path=None):
    """Parses all targets available in BUILD files under base_path and
    returns their addresses.  If no base_path is specified, root_dir is
    assumed to be the base_path"""

    addresses = OrderedSet()
    for buildfile in BuildFile.scan_buildfiles(root_dir, base_path):
      addresses.update(Target.get_all_addresses(buildfile))
    return addresses
Пример #9
0
    def configure_target(target):
      if target not in analyzed:
        analyzed.add(target)

        self.has_scala = not self.skip_scala and (self.has_scala or is_scala(target))

        if target.has_resources:
          resources_by_basedir = defaultdict(set)
          for resources in target.resources:
            resources_by_basedir[resources.target_base].update(resources.sources)
          for basedir, resources in resources_by_basedir.items():
            self.resource_extensions.update(Project.extract_resource_extensions(resources))
            configure_source_sets(basedir, resources, is_test=False)

        if target.sources:
          test = target.is_test
          self.has_tests = self.has_tests or test
          configure_source_sets(target.target_base, target.sources, is_test=test)

        # Other BUILD files may specify sources in the same directory as this target.  Those BUILD
        # files might be in parent directories (globs('a/b/*.java')) or even children directories if
        # this target globs children as well.  Gather all these candidate BUILD files to test for
        # sources they own that live in the directories this targets sources live in.
        target_dirset = find_source_basedirs(target)
        candidates = Target.get_all_addresses(target.address.buildfile)
        for ancestor in target.address.buildfile.ancestors():
          candidates.update(Target.get_all_addresses(ancestor))
        for sibling in target.address.buildfile.siblings():
          candidates.update(Target.get_all_addresses(sibling))
        for descendant in target.address.buildfile.descendants():
          candidates.update(Target.get_all_addresses(descendant))

        def is_sibling(target):
          return source_target(target) and target_dirset.intersection(find_source_basedirs(target))

        return filter(is_sibling, [Target.get(a) for a in candidates if a != target.address])
Пример #10
0
  def __init__(self, context):
    ConsoleTask.__init__(self, context)

    self._print_uptodate = context.options.check_deps_print_uptodate
    self.repos = context.config.getdict('jar-publish', 'repos')
    self._artifacts_to_targets = {}
    all_addresses = (address for buildfile in BuildFile.scan_buildfiles(get_buildroot())
                     for address in Target.get_all_addresses(buildfile))
    for address in all_addresses:
      target = Target.get(address)
      if target.is_exported:
        provided_jar, _, _ = target.get_artifact_info()
        artifact = (provided_jar.org, provided_jar.name)
        if not artifact in self._artifacts_to_targets:
          self._artifacts_to_targets[artifact] = target
Пример #11
0
  def _owning_targets(self, path):
    for build_file in self._candidate_owners(path):
      is_build_file = (build_file.full_path == os.path.join(get_buildroot(), path))
      for address in Target.get_all_addresses(build_file):
        target = Target.get(address)

        # A synthesized target can never own permanent files on disk
        if target != target.derived_from:
          # TODO(John Sirois): tighten up the notion of targets written down in a BUILD by a user
          # vs. targets created by pants at runtime.
          continue

        if target and (is_build_file or ((target.has_sources() or target.has_resources)
                                         and self._owns(target, path))):
          yield target
Пример #12
0
  def console_output(self, _):
    buildfiles = OrderedSet()
    if self._dependees_type:
      base_paths = OrderedSet()
      for dependees_type in self._dependees_type:
        try:
          # Try to do a fully qualified import 1st for filtering on custom types.
          from_list, module, type_name = dependees_type.rsplit('.', 2)
          __import__('%s.%s' % (from_list, module), fromlist=[from_list])
        except (ImportError, ValueError):
          # Fall back on pants provided target types.
          if hasattr(pants.base.build_file_context, dependees_type):
            type_name = getattr(pants.base.build_file_context, dependees_type)
          else:
            raise TaskError('Invalid type name: %s' % dependees_type)
        # Find the SourceRoot for the given input type
        base_paths.update(SourceRoot.roots(type_name))
      if not base_paths:
        raise TaskError('No SourceRoot set for any target type in %s.' % self._dependees_type +
                        '\nPlease define a source root in BUILD file as:' +
                        '\n\tsource_root(\'<src-folder>\', %s)' % ', '.join(self._dependees_type))
      for base_path in base_paths:
        buildfiles.update(BuildFile.scan_buildfiles(get_buildroot(), base_path))
    else:
      buildfiles = BuildFile.scan_buildfiles(get_buildroot())

    dependees_by_target = defaultdict(set)
    for buildfile in buildfiles:
      for address in Target.get_all_addresses(buildfile):
        for target in Target.get(address).resolve():
          # TODO(John Sirois): tighten up the notion of targets written down in a BUILD by a
          # user vs. targets created by pants at runtime.
          target = self.get_concrete_target(target)
          if hasattr(target, 'dependencies'):
            for dependencies in target.dependencies:
              for dependency in dependencies.resolve():
                dependency = self.get_concrete_target(dependency)
                dependees_by_target[dependency].add(target)

    roots = set(self.context.target_roots)
    if self._closed:
      for root in roots:
        yield str(root.address)

    for dependant in self.get_dependants(dependees_by_target, roots):
      yield str(dependant.address)
Пример #13
0
 def parse_jarcoordinate(coordinate):
   components = coordinate.split('#', 1)
   if len(components) == 2:
     org, name = components
     return org, name
   else:
     try:
       # TODO(Eric Ayers) This code is suspect.  Target.get() is a very old method and almost certainly broken.
       # Refactor to use methods from BuildGraph or BuildFileAddressMapper
       address = Address.parse(get_buildroot(), coordinate)
       target = Target.get(address)
       if not target:
         siblings = Target.get_all_addresses(address.build_file)
         prompt = 'did you mean' if len(siblings) == 1 else 'maybe you meant one of these'
         raise TaskError('%s => %s?:\n    %s' % (address, prompt,
                                                 '\n    '.join(str(a) for a in siblings)))
       if not target.is_exported:
         raise TaskError('%s is not an exported target' % coordinate)
       return target.provides.org, target.provides.name
     except (BuildFile.BuildFileError, BuildFileParser.BuildFileParserError, AddressLookupError) as e:
       raise TaskError('{message}\n  Problem with BUILD file  at {coordinate}'
       .format(message=e, coordinate=coordinate))
Пример #14
0
 def parse_jarcoordinate(coordinate):
   components = coordinate.split('#', 1)
   if len(components) == 2:
     org, name = components
     return org, name
   else:
     try:
       address = Address.parse(get_buildroot(), coordinate)  # TODO: This is broken.
       try:
         target = Target.get(address)
         if not target:
           siblings = Target.get_all_addresses(address.buildfile)
           prompt = 'did you mean' if len(siblings) == 1 else 'maybe you meant one of these'
           raise TaskError('%s => %s?:\n    %s' % (address, prompt,
                                                   '\n    '.join(str(a) for a in siblings)))
         if not target.is_exported:
           raise TaskError('%s is not an exported target' % coordinate)
         return target.provides.org, target.provides.name
       except (ImportError, SyntaxError, TypeError):
         raise TaskError('Failed to parse %s' % address.buildfile.relpath)
     except IOError:
       raise TaskError('No BUILD file could be found at %s' % coordinate)
Пример #15
0
  def setup_parser(self, parser, args):
    self.config = Config.load()
    add_global_options(parser)

    # 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()

      # Add some text that we can't put in the epilog, because that formats away newlines.
      print(textwrap.dedent("""
        Note that target specs accept two special forms:
          [dir]:  to include all targets in the specified directory
          [dir]:: to include all targets found recursively under the directory"""))
      sys.exit(0)
    else:
      goals, specs = Goal.parse_args(args)
      self.requested_goals = goals

      with self.run_tracker.new_workunit(name='setup', labels=[WorkUnit.SETUP]):
        # Bootstrap goals by loading any configured bootstrap BUILD files
        with self.check_errors('The following bootstrap_buildfiles cannot be loaded:') as error:
          with self.run_tracker.new_workunit(name='bootstrap', labels=[WorkUnit.SETUP]):
            for path in self.config.getlist('goals', 'bootstrap_buildfiles', default = []):
              try:
                buildfile = BuildFile(get_buildroot(), os.path.relpath(path, get_buildroot()))
                ParseContext(buildfile).parse()
              except (TypeError, ImportError, TaskError, GoalError):
                error(path, include_traceback=True)
              except (IOError, SyntaxError):
                error(path)
        # Now that we've parsed the bootstrap BUILD files, and know about the SCM system.
        self.run_tracker.run_info.add_scm_info()

        # Bootstrap user goals by loading any BUILD files implied by targets.
        spec_parser = SpecParser(self.root_dir)
        with self.check_errors('The following targets could not be loaded:') as error:
          with self.run_tracker.new_workunit(name='parse', labels=[WorkUnit.SETUP]):
            for spec in specs:
              try:
                for target, address in spec_parser.parse(spec):
                  if target:
                    self.targets.append(target)
                    # Force early BUILD file loading if this target is an alias that expands
                    # to others.
                    unused = list(target.resolve())
                  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, TaskError, GoalError):
                error(spec, include_traceback=True)
              except (IOError, SyntaxError, TargetDefinitionException):
                error(spec)

      self.phases = [Phase(goal) for goal in goals]

      rcfiles = self.config.getdefault('rcfiles', type=list,
                                       default=['/etc/pantsrc', '~/.pants.rc'])
      if rcfiles:
        rcfile = RcFile(rcfiles, default_prepend=False, process_default=True)

        # Break down the goals specified on the command line to the full set that will be run so we
        # can apply default flags to inner goal nodes.  Also break down goals by Task subclass and
        # register the task class hierarchy fully qualified names so we can apply defaults to
        # baseclasses.

        sections = OrderedSet()
        for phase in Engine.execution_order(self.phases):
          for goal in phase.goals():
            sections.add(goal.name)
            for clazz in goal.task_type.mro():
              if clazz == Task:
                break
              sections.add('%s.%s' % (clazz.__module__, clazz.__name__))

        augmented_args = rcfile.apply_defaults(sections, args)
        if augmented_args != args:
          del args[:]
          args.extend(augmented_args)
          sys.stderr.write("(using pantsrc expansion: pants goal %s)\n" % ' '.join(augmented_args))

      Phase.setup_parser(parser, args, self.phases)