Esempio n. 1
0
  def _expand_goals_and_specs(self):
    goals = self.options.goals
    specs = self.options.target_specs
    fail_fast = self.options.for_global_scope().fail_fast

    for goal in goals:
      if self.address_mapper.from_cache(get_buildroot(), goal, must_exist=False).file_exists():
        logger.warning(" Command-line argument '{0}' is ambiguous and was assumed to be "
                       "a goal. If this is incorrect, disambiguate it with ./{0}.".format(goal))

    if self.options.print_help_if_requested():
      sys.exit(0)

    self.requested_goals = goals

    with self.run_tracker.new_workunit(name='setup', labels=[WorkUnit.SETUP]):
      spec_parser = CmdLineSpecParser(self.root_dir, self.address_mapper,
                                      spec_excludes=self.spec_excludes,
                                      exclude_target_regexps=self.global_options.exclude_target_regexp)
      with self.run_tracker.new_workunit(name='parse', labels=[WorkUnit.SETUP]):
        def filter_for_tag(tag):
          return lambda target: tag in map(str, target.tags)
        tag_filter = wrap_filters(create_filters(self.global_options.tag, filter_for_tag))
        for spec in specs:
          for address in spec_parser.parse_addresses(spec, fail_fast):
            self.build_graph.inject_address_closure(address)
            tgt = self.build_graph.get_target(address)
            if tag_filter(tgt):
              self.targets.append(tgt)
    self.goals = [Goal.by_name(goal) for goal in goals]
Esempio n. 2
0
 def test_wrap_filters(self):
   divides_by_6 = wrap_filters(create_filters(['2', '3'], self._divides_by))
   self.assertFalse(divides_by_6(2))
   self.assertFalse(divides_by_6(3))
   self.assertTrue(divides_by_6(6))
   self.assertFalse(divides_by_6(9))
   self.assertTrue(divides_by_6(12))
Esempio n. 3
0
    def _target_tag_matches(self):
        def filter_for_tag(tag):
            return lambda t: tag in [
                str(t_tag) for t_tag in t.kwargs().get("tags", [])
            ]

        return wrap_filters(create_filters(self.tags, filter_for_tag))
Esempio n. 4
0
 def console_output(self, _):
   wrapped_filter = wrap_filters(self._filters)
   filtered = set()
   for target in self.context.target_roots:
     if target not in filtered:
       filtered.add(target)
       if wrapped_filter(target):
         yield target.address.spec
Esempio n. 5
0
 def console_output(self, _):
   wrapped_filter = wrap_filters(self._filters)
   filtered = set()
   for target in self.context.target_roots:
     if target not in filtered:
       filtered.add(target)
       if wrapped_filter(target):
         yield target.address.spec
Esempio n. 6
0
 def test_wrap_filters(self):
     divides_by_6 = wrap_filters(
         create_filters(['2', '3'], self._divides_by))
     self.assertFalse(divides_by_6(2))
     self.assertFalse(divides_by_6(3))
     self.assertTrue(divides_by_6(6))
     self.assertFalse(divides_by_6(9))
     self.assertTrue(divides_by_6(12))
Esempio n. 7
0
    def _target_tag_matches(self):
        def filter_for_tag(tag):
            def filter_target(tgt):
                # `tags` can sometimes be explicitly set to `None`. We convert that to an empty list
                # with `or`.
                tags = tgt.kwargs().get("tags", []) or []
                return tag in [str(t_tag) for t_tag in tags]

            return filter_target

        return wrap_filters(create_filters(self.tags, filter_for_tag))
Esempio n. 8
0
  def _expand_specs(self, specs, fail_fast):
    """Populate the BuildGraph and target list from a set of input specs."""
    with self._run_tracker.new_workunit(name='parse', labels=[WorkUnitLabel.SETUP]):
      def filter_for_tag(tag):
        return lambda target: tag in map(str, target.tags)

      tag_filter = wrap_filters(create_filters(self._tag, filter_for_tag))

      for spec in specs:
        for address in self._spec_parser.parse_addresses(spec, fail_fast):
          self._build_graph.inject_address_closure(address)
          target = self._build_graph.get_target(address)
          if tag_filter(target):
            self._targets.append(target)
Esempio n. 9
0
  def _expand_specs(self, specs, fail_fast):
    """Populate the BuildGraph and target list from a set of input specs."""
    with self._run_tracker.new_workunit(name='parse', labels=[WorkUnitLabel.SETUP]):
      def filter_for_tag(tag):
        return lambda target: tag in map(str, target.tags)

      tag_filter = wrap_filters(create_filters(self._tag, filter_for_tag))

      for spec in specs:
        for address in self._spec_parser.parse_addresses(spec, fail_fast):
          self._build_graph.inject_address_closure(address)
          target = self._build_graph.get_target(address)
          if tag_filter(target):
            self._targets.append(target)
Esempio n. 10
0
  def _roots_to_targets(self, target_roots):
    """Populate the BuildGraph and target list from a set of input TargetRoots."""
    with self._run_tracker.new_workunit(name='parse', labels=[WorkUnitLabel.SETUP]):
      def filter_for_tag(tag):
        return lambda target: tag in map(str, target.tags)

      tag_filter = wrap_filters(create_filters(self._tag, filter_for_tag))

      def generate_targets():
        for address in self._build_graph.inject_roots_closure(target_roots, self._fail_fast):
          target = self._build_graph.get_target(address)
          if tag_filter(target):
            yield target

      return list(generate_targets())
Esempio n. 11
0
  def _expand_specs(self, spec_strs, fail_fast):
    """Populate the BuildGraph and target list from a set of input specs."""
    with self._run_tracker.new_workunit(name='parse', labels=[WorkUnitLabel.SETUP]):
      def filter_for_tag(tag):
        return lambda target: tag in map(str, target.tags)

      tag_filter = wrap_filters(create_filters(self._tag, filter_for_tag))

      # Parse all specs into unique Spec objects.
      spec_parser = CmdLineSpecParser(self._root_dir)
      specs = OrderedSet()
      for spec_str in spec_strs:
        specs.add(spec_parser.parse_spec(spec_str))

      # Then scan them to generate unique Addresses.
      for address in self._build_graph.inject_specs_closure(specs, fail_fast):
        target = self._build_graph.get_target(address)
        if tag_filter(target):
          self._targets.append(target)
Esempio n. 12
0
  def _expand_specs(self, spec_strs, fail_fast):
    """Populate the BuildGraph and target list from a set of input specs."""
    with self._run_tracker.new_workunit(name='parse', labels=[WorkUnitLabel.SETUP]):
      def filter_for_tag(tag):
        return lambda target: tag in map(str, target.tags)

      tag_filter = wrap_filters(create_filters(self._tag, filter_for_tag))

      # Parse all specs into unique Spec objects.
      spec_parser = CmdLineSpecParser(self._root_dir)
      specs = OrderedSet()
      for spec_str in spec_strs:
        specs.add(spec_parser.parse_spec(spec_str))

      # Then scan them to generate unique Addresses.
      for address in self._address_mapper.scan_specs(specs, fail_fast, self._spec_excludes):
        self._build_graph.inject_address_closure(address)
        target = self._build_graph.get_target(address)
        if tag_filter(target):
          self._targets.append(target)
Esempio n. 13
0
def addresses_from_address_families(address_mapper, specs):
  """Given an AddressMapper and list of Specs, return matching BuildFileAddresses.

  Raises a AddressLookupError if:
     - there were no matching AddressFamilies, or
     - the Spec matches no addresses for SingleAddresses.
  """
  # Capture a Snapshot covering all paths for these Specs, then group by directory.
  snapshot = yield Get(Snapshot, PathGlobs, _spec_to_globs(address_mapper, specs))
  dirnames = set(dirname(f.stat.path) for f in snapshot.files)
  address_families = yield [Get(AddressFamily, Dir(d)) for d in dirnames]

  # NB: `@memoized` does not work on local functions.
  def by_directory():
    if by_directory.cached is None:
      by_directory.cached = {af.namespace: af for af in address_families}
    return by_directory.cached
  by_directory.cached = None

  def raise_empty_address_family(spec):
    raise ResolveError('Path "{}" does not contain any BUILD files.'.format(spec.directory))

  def exclude_address(spec):
    if specs.exclude_patterns:
      return any(p.search(spec) is not None for p in specs.exclude_patterns_memo())
    return False

  def filter_for_tag(tag):
    return lambda t: tag in map(str, t.kwargs().get("tags", []))

  include_target = wrap_filters(create_filters(specs.tags if specs.tags else '', filter_for_tag))

  addresses = []
  included = set()
  def include(address_families, predicate=None):
    matched = False
    for af in address_families:
      for (a, t) in af.addressables.items():
        if (predicate is None or predicate(a)):
          if include_target(t) and (not exclude_address(a.spec)):
            matched = True
            if a not in included:
              addresses.append(a)
              included.add(a)
    return matched

  for spec in specs.dependencies:
    if type(spec) is DescendantAddresses:
      matched = include(
        af
        for af in address_families
        if fast_relpath_optional(af.namespace, spec.directory) is not None
      )
      if not matched:
        raise AddressLookupError(
          'Spec {} does not match any targets.'.format(spec))
    elif type(spec) is SiblingAddresses:
      address_family = by_directory().get(spec.directory)
      if not address_family:
        raise_empty_address_family(spec)
      include([address_family])
    elif type(spec) is SingleAddress:
      address_family = by_directory().get(spec.directory)
      if not address_family:
        raise_empty_address_family(spec)
      # spec.name here is generally the root node specified on commandline. equality here implies
      # a root node i.e. node specified on commandline.
      if not include([address_family], predicate=lambda a: a.target_name == spec.name):
        if len(addresses) == 0:
          _raise_did_you_mean(address_family, spec.name)
    elif type(spec) is AscendantAddresses:
      include(
        af
        for af in address_families
        if fast_relpath_optional(spec.directory, af.namespace) is not None
      )
    else:
      raise ValueError('Unrecognized Spec type: {}'.format(spec))
  yield BuildFileAddresses(addresses)
Esempio n. 14
0
 def _target_tag_matches(self):
   def filter_for_tag(tag):
     return lambda t: tag in [str(t_tag) for t_tag in t.kwargs().get("tags", [])]
   return wrap_filters(create_filters(self.tags, filter_for_tag))
Esempio n. 15
0
def addresses_from_address_families(address_mapper, specs):
  """Given an AddressMapper and list of Specs, return matching BuildFileAddresses.

  Raises a AddressLookupError if:
     - there were no matching AddressFamilies, or
     - the Spec matches no addresses for SingleAddresses.
  """
  # Capture a Snapshot covering all paths for these Specs, then group by directory.
  snapshot = yield Get(Snapshot, PathGlobs, _spec_to_globs(address_mapper, specs))
  dirnames = set(dirname(f.stat.path) for f in snapshot.files)
  address_families = yield [Get(AddressFamily, Dir(d)) for d in dirnames]

  # NB: `@memoized` does not work on local functions.
  def by_directory():
    if by_directory.cached is None:
      by_directory.cached = {af.namespace: af for af in address_families}
    return by_directory.cached
  by_directory.cached = None

  def raise_empty_address_family(spec):
    raise ResolveError('Path "{}" does not contain any BUILD files.'.format(spec.directory))

  def exclude_address(spec):
    if specs.exclude_patterns:
      return any(p.search(spec) is not None for p in specs.exclude_patterns_memo())
    return False

  def filter_for_tag(tag):
    return lambda t: tag in [str(t_tag) for t_tag in t.kwargs().get("tags", [])]

  include_target = wrap_filters(create_filters(specs.tags if specs.tags else '', filter_for_tag))

  addresses = []
  included = set()
  def include(address_families, predicate=None):
    matched = False
    for af in address_families:
      for (a, t) in af.addressables.items():
        if (predicate is None or predicate(a)):
          if include_target(t) and (not exclude_address(a.spec)):
            matched = True
            if a not in included:
              addresses.append(a)
              included.add(a)
    return matched

  for spec in specs.dependencies:
    if type(spec) is DescendantAddresses:
      matched = include(
        af
        for af in address_families
        if fast_relpath_optional(af.namespace, spec.directory) is not None
      )
      if not matched:
        raise AddressLookupError(
          'Spec {} does not match any targets.'.format(spec))
    elif type(spec) is SiblingAddresses:
      address_family = by_directory().get(spec.directory)
      if not address_family:
        raise_empty_address_family(spec)
      include([address_family])
    elif type(spec) is SingleAddress:
      address_family = by_directory().get(spec.directory)
      if not address_family:
        raise_empty_address_family(spec)
      # spec.name here is generally the root node specified on commandline. equality here implies
      # a root node i.e. node specified on commandline.
      if not include([address_family], predicate=lambda a: a.target_name == spec.name):
        if len(addresses) == 0:
          _raise_did_you_mean(address_family, spec.name)
    elif type(spec) is AscendantAddresses:
      include(
        af
        for af in address_families
        if fast_relpath_optional(spec.directory, af.namespace) is not None
      )
    else:
      raise ValueError('Unrecognized Spec type: {}'.format(spec))
  yield BuildFileAddresses(addresses)