Exemplo n.º 1
0
 def __init__(self, scheduler, symbol_table):
   """
   :param scheduler: The `Scheduler` instance to use for computing file to target mapping
   :param symbol_table: The symbol table.
   """
   self._scheduler = scheduler
   self._symbol_table = symbol_table
   self._mapper = EngineSourceMapper(self._scheduler)
Exemplo n.º 2
0
 def __init__(self, engine, scm):
   """
   :param Engine engine: The `Engine` instance to use for computing file to target mappings.
   :param Scm engine: The `Scm` instance to use for computing changes.
   """
   super(EngineChangeCalculator, self).__init__(scm)
   self._engine = engine
   self._mapper = EngineSourceMapper(engine)
Exemplo n.º 3
0
 def __init__(self, scheduler, symbol_table_cls, scm):
   """
   :param Engine engine: The `Engine` instance to use for computing file to target mappings.
   :param Scm engine: The `Scm` instance to use for computing changes.
   """
   super(EngineChangeCalculator, self).__init__(scm)
   self._scheduler = scheduler
   self._symbol_table_cls = symbol_table_cls
   self._mapper = EngineSourceMapper(self._scheduler)
Exemplo n.º 4
0
 def __init__(self, scheduler, symbol_table, scm):
   """
   :param scheduler: The `Scheduler` instance to use for computing file to target mappings.
   :param symbol_table: The symbol table.
   :param scm: The `Scm` instance to use for change determination.
   """
   super(EngineChangeCalculator, self).__init__(scm or get_scm())
   self._scheduler = scheduler
   self._symbol_table = symbol_table
   self._mapper = EngineSourceMapper(self._scheduler)
Exemplo n.º 5
0
class EngineChangeCalculator(ChangeCalculator):
  """A ChangeCalculator variant that uses the v2 engine for source mapping."""

  def __init__(self, scheduler, symbol_table, scm):
    """
    :param scheduler: The `Scheduler` instance to use for computing file to target mappings.
    :param symbol_table: The symbol table.
    :param scm: The `Scm` instance to use for change determination.
    """
    super(EngineChangeCalculator, self).__init__(scm or get_scm())
    self._scheduler = scheduler
    self._symbol_table = symbol_table
    self._mapper = EngineSourceMapper(self._scheduler)

  def iter_changed_target_addresses(self, changed_request):
    """Given a `ChangedRequest`, compute and yield all affected target addresses."""
    changed_files = self.changed_files(changed_request.changes_since, changed_request.diffspec)
    logger.debug('changed files: %s', changed_files)
    if not changed_files:
      return

    changed_addresses = set(address
                            for address
                            in self._mapper.iter_target_addresses_for_sources(changed_files))
    for address in changed_addresses:
      yield address

    if changed_request.include_dependees not in ('direct', 'transitive'):
      return

    # TODO: For dependee finding, we technically only need to parse all build files to collect target
    # dependencies. But in order to fully validate the graph and account for the fact that deleted
    # targets do not show up as changed roots, we use the `TransitiveHydratedTargets` product.
    #   see https://github.com/pantsbuild/pants/issues/382
    specs = (DescendantAddresses(''),)
    adaptor_iter = (t.adaptor
                    for targets in self._scheduler.product_request(TransitiveHydratedTargets,
                                                                   [Specs(specs)])
                    for t in targets.roots)
    graph = _DependentGraph.from_iterable(target_types_from_symbol_table(self._symbol_table),
                                          adaptor_iter)

    if changed_request.include_dependees == 'direct':
      for address in graph.dependents_of_addresses(changed_addresses):
        yield address
    elif changed_request.include_dependees == 'transitive':
      for address in graph.transitive_dependents_of_addresses(changed_addresses):
        yield address

  def changed_target_addresses(self, changed_request):
    return list(self.iter_changed_target_addresses(changed_request))
Exemplo n.º 6
0
 def __init__(self, scheduler, symbol_table, scm, workspace=None, changes_since=None,
              diffspec=None):
   """
   :param scheduler: The `Scheduler` instance to use for computing file to target mappings.
   :param symbol_table: The symbol table.
   :param scm: The `Scm` instance to use for change determination.
   """
   self._scm = scm or get_scm()
   self._scheduler = scheduler
   self._symbol_table = symbol_table
   self._mapper = EngineSourceMapper(self._scheduler)
   self._workspace = workspace or ScmWorkspace(scm)
   self._changes_since = changes_since
   self._diffspec = diffspec
Exemplo n.º 7
0
class EngineChangeCalculator(ChangeCalculator):
  """A ChangeCalculator variant that uses the v2 engine for source mapping."""

  def __init__(self, scheduler, engine, symbol_table_cls, scm):
    """
    :param Engine engine: The `Engine` instance to use for computing file to target mappings.
    :param Scm engine: The `Scm` instance to use for computing changes.
    """
    super(EngineChangeCalculator, self).__init__(scm)
    self._scheduler = scheduler
    self._engine = engine
    self._symbol_table_cls = symbol_table_cls
    self._mapper = EngineSourceMapper(engine)

  def iter_changed_target_addresses(self, changed_request):
    """Given a `ChangedRequest`, compute and yield all affected target addresses."""
    changed_files = self.changed_files(changed_request.changes_since, changed_request.diffspec)
    logger.debug('changed files: %s', changed_files)
    if not changed_files:
      return

    changed_addresses = set(address
                            for address
                            in self._mapper.iter_target_addresses_for_sources(changed_files))
    for address in changed_addresses:
      yield address

    if changed_request.include_dependees not in ('direct', 'transitive'):
      return

    # For dependee finding, we need to parse all build files.
    graph = LegacyBuildGraph.create(self._scheduler, self._engine, self._symbol_table_cls)
    for _ in graph.inject_specs_closure([DescendantAddresses('')]):
      pass

    if changed_request.include_dependees == 'direct':
      emitted = set()
      for address in changed_addresses:
        for dependee in graph.dependents_of(address):
          if dependee not in emitted:
            emitted.add(dependee)
            yield dependee
    elif changed_request.include_dependees == 'transitive':
      for target in graph.transitive_dependees_of_addresses(changed_addresses):
        yield target.address

  def changed_target_addresses(self, changed_request):
    return list(self.iter_changed_target_addresses(changed_request))
Exemplo n.º 8
0
class EngineChangeCalculator(ChangeCalculator):
  """A ChangeCalculator variant that uses the v2 engine for source mapping."""

  def __init__(self, scheduler, symbol_table, scm):
    """
    :param Engine engine: The `Engine` instance to use for computing file to target mappings.
    :param Scm engine: The `Scm` instance to use for computing changes.
    """
    super(EngineChangeCalculator, self).__init__(scm)
    self._scheduler = scheduler
    self._symbol_table = symbol_table
    self._mapper = EngineSourceMapper(self._scheduler)

  def iter_changed_target_addresses(self, changed_request):
    """Given a `ChangedRequest`, compute and yield all affected target addresses."""
    changed_files = self.changed_files(changed_request.changes_since, changed_request.diffspec)
    logger.debug('changed files: %s', changed_files)
    if not changed_files:
      return

    changed_addresses = set(address
                            for address
                            in self._mapper.iter_target_addresses_for_sources(changed_files))
    for address in changed_addresses:
      yield address

    if changed_request.include_dependees not in ('direct', 'transitive'):
      return

    # For dependee finding, we need to parse all build files.
    product_iter = (t
                    for targets in self._scheduler.product_request(HydratedTargets, [DescendantAddresses('')])
                    for t in targets.dependencies)
    graph = _HydratedTargetDependentGraph.from_iterable(target_types_from_symbol_table(self._symbol_table),
                                                        product_iter)

    if changed_request.include_dependees == 'direct':
      for address in graph.dependents_of_addresses(changed_addresses):
        yield address
    elif changed_request.include_dependees == 'transitive':
      for address in graph.transitive_dependents_of_addresses(changed_addresses):
        yield address

  def changed_target_addresses(self, changed_request):
    return list(self.iter_changed_target_addresses(changed_request))
Exemplo n.º 9
0
class OwnerCalculator(object):
  """An OwnerCalculator that finds the target addresses of the files passed down as arguments
  to --owner-of
  """

  def __init__(self, scheduler, symbol_table):
    """
    :param scheduler: The `Scheduler` instance to use for computing file to target mapping
    :param symbol_table: The symbol table.
    """
    self._scheduler = scheduler
    self._symbol_table = symbol_table
    self._mapper = EngineSourceMapper(self._scheduler)

  def iter_owner_target_addresses(self, owned_files):
    """Given an list of owned files, compute and yield all affected target addresses"""
    owner_addresses = set(address
                          for address
                          in self._mapper.iter_target_addresses_for_sources(owned_files))
    for address in owner_addresses:
      yield address

  def owner_target_addresses(self, owner_request):
    return list(self.iter_owner_target_addresses(owner_request))
class ChangeCalculator(object):
    """A ChangeCalculator that finds the target addresses of changed files based on scm."""
    def __init__(self,
                 scheduler,
                 symbol_table,
                 scm,
                 workspace=None,
                 changes_since=None,
                 diffspec=None):
        """
    :param scheduler: The `Scheduler` instance to use for computing file to target mappings.
    :param symbol_table: The symbol table.
    :param scm: The `Scm` instance to use for change determination.
    """
        self._scm = scm or get_scm()
        self._scheduler = scheduler
        self._symbol_table = symbol_table
        self._mapper = EngineSourceMapper(self._scheduler)
        self._workspace = workspace or ScmWorkspace(scm)
        self._changes_since = changes_since
        self._diffspec = diffspec

    def changed_files(self, changes_since=None, diffspec=None):
        """Determines the files changed according to SCM/workspace and options."""
        diffspec = diffspec or self._diffspec
        if diffspec:
            return self._workspace.changes_in(diffspec)

        changes_since = changes_since or self._changes_since or self._scm.current_rev_identifier(
        )
        return self._workspace.touched_files(changes_since)

    def iter_changed_target_addresses(self, changed_request):
        """Given a `ChangedRequest`, compute and yield all affected target addresses."""
        changed_files = self.changed_files(changed_request.changes_since,
                                           changed_request.diffspec)
        logger.debug('changed files: %s', changed_files)
        if not changed_files:
            return

        changed_addresses = set(
            address
            for address in self._mapper.iter_target_addresses_for_sources(
                changed_files))
        for address in changed_addresses:
            yield address

        if changed_request.include_dependees not in ('direct', 'transitive'):
            return

        # TODO: For dependee finding, we technically only need to parse all build files to collect target
        # dependencies. But in order to fully validate the graph and account for the fact that deleted
        # targets do not show up as changed roots, we use the `TransitiveHydratedTargets` product.
        #   see https://github.com/pantsbuild/pants/issues/382
        specs = (DescendantAddresses(''), )
        adaptor_iter = (t.adaptor
                        for targets in self._scheduler.product_request(
                            TransitiveHydratedTargets, [Specs(specs)])
                        for t in targets.roots)
        graph = _DependentGraph.from_iterable(
            target_types_from_symbol_table(self._symbol_table), adaptor_iter)

        if changed_request.include_dependees == 'direct':
            for address in graph.dependents_of_addresses(changed_addresses):
                yield address
        elif changed_request.include_dependees == 'transitive':
            for address in graph.transitive_dependents_of_addresses(
                    changed_addresses):
                yield address

    def changed_target_addresses(self, changed_request):
        return list(self.iter_changed_target_addresses(changed_request))