예제 #1
0
    def test_subclass_equality(self):
        class FPStrategyA(DefaultFingerprintStrategy):
            pass

        class FPStrategyB(DefaultFingerprintStrategy):
            pass

        self.assertNotEqual(FPStrategyA(), DefaultFingerprintStrategy())
        self.assertNotEqual(FPStrategyA(), FPStrategyB())
        self.assertEqual(FPStrategyA(), FPStrategyA())

        self.assertNotEqual(hash(FPStrategyA()),
                            hash(DefaultFingerprintStrategy()))
        self.assertNotEqual(hash(FPStrategyA()), hash(FPStrategyB()))
        self.assertEqual(hash(FPStrategyA()), hash(FPStrategyA()))
예제 #2
0
  def execute(self):
    dist_targets = self.context.targets(is_local_python_dist)
    build_graph = self.context.build_graph

    if dist_targets:
      with self.invalidated(dist_targets,
                            fingerprint_strategy=DefaultFingerprintStrategy(),
                            invalidate_dependents=True) as invalidation_check:
        for vt in invalidation_check.invalid_vts:
          if vt.target.dependencies:
            raise TargetDefinitionException(
              vt.target, 'The `dependencies` field is disallowed on `python_dist` targets. '
                         'List any 3rd party requirements in the install_requirements argument '
                         'of your setup function.'
            )
          self._create_dist(vt.target, vt.results_dir)

        for vt in invalidation_check.all_vts:
          dist = self._get_whl_from_dir(os.path.join(vt.results_dir, 'dist'))
          req_lib_addr = Address.parse('{}__req_lib'.format(vt.target.address.spec))
          self._inject_synthetic_dist_requirements(dist, req_lib_addr)
          # Make any target that depends on the dist depend on the synthetic req_lib,
          # for downstream consumption.
          for dependent in build_graph.dependents_of(vt.target.address):
            build_graph.inject_dependency(dependent, req_lib_addr)
예제 #3
0
파일: target.py 프로젝트: Gabriel439/pants
    def transitive_invalidation_hash(self, fingerprint_strategy=None):
        """
    :param FingerprintStrategy fingerprint_strategy: optional fingerprint strategy to use to compute
    the fingerprint of a target
    :return: A fingerprint representing this target and all of its dependencies.
      The return value can be `None`, indicating that this target and all of its transitive dependencies
      did not contribute to the fingerprint, according to the provided FingerprintStrategy.
    :rtype: string
    """
        fingerprint_strategy = fingerprint_strategy or DefaultFingerprintStrategy(
        )
        if fingerprint_strategy not in self._cached_transitive_fingerprint_map:
            hasher = sha1()

            def dep_hash_iter():
                for dep in self.dependencies:
                    dep_hash = dep.transitive_invalidation_hash(
                        fingerprint_strategy)
                    if dep_hash is not None:
                        yield dep_hash

            dep_hashes = sorted(list(dep_hash_iter()))
            for dep_hash in dep_hashes:
                hasher.update(dep_hash)
            target_hash = self.invalidation_hash(fingerprint_strategy)
            if target_hash is None and not dep_hashes:
                return None
            dependencies_hash = hasher.hexdigest()[:12]
            combined_hash = '{target_hash}.{deps_hash}'.format(
                target_hash=target_hash, deps_hash=dependencies_hash)
            self._cached_transitive_fingerprint_map[
                fingerprint_strategy] = combined_hash
        return self._cached_transitive_fingerprint_map[fingerprint_strategy]
예제 #4
0
파일: target.py 프로젝트: wisechengyi/pants
    def transitive_invalidation_hash(self, fingerprint_strategy=None, depth=0):
        """
        :API: public

        :param FingerprintStrategy fingerprint_strategy: optional fingerprint strategy to use to compute
        the fingerprint of a target
        :return: A fingerprint representing this target and all of its dependencies.
          The return value can be `None`, indicating that this target and all of its transitive dependencies
          did not contribute to the fingerprint, according to the provided FingerprintStrategy.
        :rtype: string
        """
        if depth > self._MAX_RECURSION_DEPTH:
            # NB(zundel) without this catch, we'll eventually hit the python stack limit
            # RuntimeError: maximum recursion depth exceeded while calling a Python object
            raise self.RecursiveDepthError(
                "Max depth of {} exceeded.".format(self._MAX_RECURSION_DEPTH)
            )

        fingerprint_strategy = fingerprint_strategy or DefaultFingerprintStrategy()

        direct = depth == 0 and fingerprint_strategy.direct(self)
        if direct:
            fingerprint_map = self._cached_direct_transitive_fingerprint_map
        else:
            fingerprint_map = self._cached_all_transitive_fingerprint_map

        if fingerprint_strategy not in fingerprint_map:
            hasher = sha1()

            def dep_hash_iter():
                dep_list = fingerprint_strategy.dependencies(self) if direct else self.dependencies
                for dep in dep_list:
                    try:
                        if direct:
                            dep_hash = dep.invalidation_hash(fingerprint_strategy)
                        else:
                            dep_hash = dep.transitive_invalidation_hash(
                                fingerprint_strategy, depth=depth + 1
                            )
                        if dep_hash is not None:
                            yield dep_hash
                    except self.RecursiveDepthError as e:
                        raise self.RecursiveDepthError(
                            "{message}\n  referenced from {spec}".format(
                                message=e, spec=dep.address.spec
                            )
                        )

            dep_hashes = sorted(list(dep_hash_iter()))
            for dep_hash in dep_hashes:
                hasher.update(dep_hash.encode())
            target_hash = self.invalidation_hash(fingerprint_strategy)
            if target_hash is None and not dep_hashes:
                return None
            dependencies_hash = hasher.hexdigest()[:12]
            combined_hash = "{target_hash}.{deps_hash}".format(
                target_hash=target_hash, deps_hash=dependencies_hash
            )
            fingerprint_map[fingerprint_strategy] = combined_hash
        return fingerprint_map[fingerprint_strategy]
  def execute(self):
    dist_targets = self.context.targets(self.filter_target)

    if dist_targets:
      with self.invalidated(dist_targets,
                            fingerprint_strategy=DefaultFingerprintStrategy(),
                            invalidate_dependents=True) as invalidation_check:
        interpreter = self.context.products.get_data(PythonInterpreter)

        for vt in invalidation_check.invalid_vts:
          if vt.target.dependencies:
            raise TargetDefinitionException(
              vt.target, 'The `dependencies` field is disallowed on `python_dist` targets. '
                         'List any 3rd party requirements in the install_requirements argument '
                         'of your setup function.'
            )
          setup_req_dir = os.path.join(vt.results_dir, 'setup_requires_site')
          pythonpath = self._ensure_setup_requires_site_dir(dist_targets, interpreter, setup_req_dir)
          self._create_dist(vt.target, vt.results_dir, interpreter, pythonpath)

        local_wheel_products = self.context.products.get('local_wheels')
        for vt in invalidation_check.all_vts:
          dist = self._get_whl_from_dir(os.path.join(vt.results_dir, 'dist'))
          req_lib_addr = Address.parse('{}__req_lib'.format(vt.target.address.spec))
          self._inject_synthetic_dist_requirements(dist, req_lib_addr)
          # Make any target that depends on the dist depend on the synthetic req_lib,
          # for downstream consumption.
          for dependent in self.context.build_graph.dependents_of(vt.target.address):
            self.context.build_graph.inject_dependency(dependent, req_lib_addr)
          local_wheel_products.add(vt.target, os.path.dirname(dist)).append(os.path.basename(dist))
예제 #6
0
    def execute(self):
        dist_targets = self.context.targets(is_local_python_dist)
        built_dists = set()

        if dist_targets:
            with self.invalidated(
                    dist_targets,
                    fingerprint_strategy=DefaultFingerprintStrategy(),
                    invalidate_dependents=True) as invalidation_check:
                for vt in invalidation_check.all_vts:
                    if vt.valid:
                        built_dists.add(
                            self._get_whl_from_dir(
                                os.path.join(vt.results_dir, 'dist')))
                    else:
                        if vt.target.dependencies:
                            raise TargetDefinitionException(
                                vt.target,
                                'The `dependencies` field is disallowed on `python_dist` targets. List any 3rd '
                                'party requirements in the install_requirements argument of your setup function.'
                            )
                        built_dists.add(
                            self._create_dist(vt.target, vt.results_dir))

        self.context.products.register_data(self.PYTHON_DISTS, built_dists)
예제 #7
0
 def invalidation_hash(self, fingerprint_strategy=None):
     fingerprint_strategy = fingerprint_strategy or DefaultFingerprintStrategy(
     )
     fp_name = fingerprint_strategy.name()
     if fp_name not in self._cached_fingerprint_map:
         self._cached_fingerprint_map[
             fp_name] = self.compute_invalidation_hash(fingerprint_strategy)
     return self._cached_fingerprint_map[fp_name]
예제 #8
0
파일: target.py 프로젝트: lgirault/pants
 def invalidation_hash(self, fingerprint_strategy=None):
   """
   :API: public
   """
   fingerprint_strategy = fingerprint_strategy or DefaultFingerprintStrategy()
   if fingerprint_strategy not in self._cached_fingerprint_map:
     self._cached_fingerprint_map[fingerprint_strategy] = self.compute_invalidation_hash(fingerprint_strategy)
   return self._cached_fingerprint_map[fingerprint_strategy]
예제 #9
0
 def compute_invalidation_hash(self, fingerprint_strategy=None):
   """
    :param FingerprintStrategy fingerprint_strategy: optional fingerprint strategy to use to compute
   the fingerprint of a target
   :return: a fingerprint representing this target (no dependencies)
   :rtype: string
   """
   fingerprint_strategy = fingerprint_strategy or DefaultFingerprintStrategy()
   return fingerprint_strategy.fingerprint_target(self)
예제 #10
0
 def transitive_invalidation_hash(self, fingerprint_strategy=None):
     fingerprint_strategy = fingerprint_strategy or DefaultFingerprintStrategy(
     )
     fp_name = fingerprint_strategy.name()
     if fp_name not in self._cached_transitive_fingerprint_map:
         hasher = sha1()
         direct_deps = sorted(self.dependencies)
         for dep in direct_deps:
             hasher.update(
                 dep.transitive_invalidation_hash(fingerprint_strategy))
         target_hash = self.invalidation_hash(fingerprint_strategy)
         dependencies_hash = hasher.hexdigest()[:12]
         combined_hash = '{target_hash}.{deps_hash}'.format(
             target_hash=target_hash, deps_hash=dependencies_hash)
         self._cached_transitive_fingerprint_map[fp_name] = combined_hash
     return self._cached_transitive_fingerprint_map[fp_name]
예제 #11
0
 def transitive_invalidation_hash(self, fingerprint_strategy=None):
     """
 :param FingerprintStrategy fingerprint_strategy: optional fingerprint strategy to use to compute
 the fingerprint of a target
 :return: a fingerprint representing this target and all of its dependencies
 :rtype: string
 """
     fingerprint_strategy = fingerprint_strategy or DefaultFingerprintStrategy(
     )
     if fingerprint_strategy not in self._cached_transitive_fingerprint_map:
         hasher = sha1()
         direct_deps = sorted(self.dependencies)
         for dep in direct_deps:
             hasher.update(
                 dep.transitive_invalidation_hash(fingerprint_strategy))
         target_hash = self.invalidation_hash(fingerprint_strategy)
         dependencies_hash = hasher.hexdigest()[:12]
         combined_hash = '{target_hash}.{deps_hash}'.format(
             target_hash=target_hash, deps_hash=dependencies_hash)
         self._cached_transitive_fingerprint_map[
             fingerprint_strategy] = combined_hash
     return self._cached_transitive_fingerprint_map[fingerprint_strategy]
예제 #12
0
 def compute_invalidation_hash(self, fingerprint_strategy=None):
     fingerprint_strategy = fingerprint_strategy or DefaultFingerprintStrategy(
     )
     return fingerprint_strategy.fingerprint_target(self)