def test_resolved_jars_with_differing_paths_not_equal(self): jar1 = ResolvedJar(M2Coordinate('org.example', 'lib'), 'ivy2/path', 'path1') jar2 = ResolvedJar(M2Coordinate('org.example', 'lib'), 'ivy2/path', 'path2') self.assertNotEqual(jar1, jar2)
def test_resolved_jars_with_same_paths_equal(self): jar1 = ResolvedJar(M2Coordinate('org.example', 'lib'), 'ivy2/path', 'path') jar2 = ResolvedJar(M2Coordinate('org.example', 'lib'), 'ivy2/path', 'path') self.assertEqual(jar1, jar2)
def test_create_canonical_classpath(self): a = self.make_target('a/b', JvmTarget) jar_path = 'ivy/jars/org.x/lib/x-1.0.jar' jar_path_excluded = 'ivy/jars/org.y/lib/y-1.0.jar' classpath_products = ClasspathProducts(self.pants_workdir) resolved_jar = ResolvedJar(M2Coordinate(org='org', name='x', rev='1.0'), cache_path='somewhere', pants_path=self._path(jar_path)) # org.y should be excluded from result canonical path resolved_jar_to_exclude = ResolvedJar( M2Coordinate(org='org', name='y', rev='1.0'), cache_path='somewhere', pants_path=self._path(jar_path_excluded)) classpath_products.add_for_target( a, [('default', self._path('a.jar')), ('default', self._path('resources'))]) classpath_products.add_jars_for_targets([a], 'default', [resolved_jar]) with temporary_dir() as base_dir: self._test_canonical_classpath_helper( classpath_products, [a], base_dir, True, [ 'a.b.b-0.jar', 'a.b.b-1', 'a.b.b-2.jar', ], { 'a.b.b-classpath.txt': '{}/a.jar:{}/resources:{}/{}\n'.format( self.pants_workdir, self.pants_workdir, self.pants_workdir, jar_path) }, excludes=set([Exclude(org='org', name='y')])) # incrementally delete the resource dendendency classpath_products = ClasspathProducts(self.pants_workdir) classpath_products.add_for_target(a, [('default', self._path('a.jar'))]) self._test_canonical_classpath_helper( classpath_products, [a], base_dir, True, [ 'a.b.b-0.jar', ], {'a.b.b-classpath.txt': '{}/a.jar\n'.format(self.pants_workdir)}) # incrementally add another jar dependency classpath_products = ClasspathProducts(self.pants_workdir) classpath_products.add_for_target(a, [('default', self._path('a.jar')), ('default', self._path('b.jar'))]) self._test_canonical_classpath_helper( classpath_products, [a], base_dir, True, ['a.b.b-0.jar', 'a.b.b-1.jar'], { 'a.b.b-classpath.txt': '{}/a.jar:{}/b.jar\n'.format(self.pants_workdir, self.pants_workdir) })
def to_resolved_jar(jar_module_ref, artifact_path): return ResolvedJar(coordinate=M2Coordinate( org=jar_module_ref.org, name=jar_module_ref.name, rev=jar_module_ref.rev, classifier=jar_module_ref.classifier), cache_path=artifact_path)
def to_resolved_jar(jar_ref, jar_path): return ResolvedJar(coordinate=M2Coordinate(org=jar_ref.org, name=jar_ref.name, rev=jar_ref.rev, classifier=jar_ref.classifier, ext=jar_ref.ext), cache_path=jar_path)
def create_artifact(self, org, name, rev, classifier=None, ext=None, materialize=True): """ :API: public :param string org: The maven dependency `groupId`. :param string name: The maven dependency `artifactId`. :param string rev: The maven dependency `version`. :param string classifier: The maven dependency `classifier`. :param string ext: There is no direct maven parallel, but the maven `packaging` value of the depended-on artifact for simple cases, and in more complex cases the extension of the artifact. For example, 'bundle' packaging implies an extension of 'jar'. Defaults to 'jar'. :param bool materialize: `False` to populate the returned resolved_jar with a `pants_path` that does not exist; defaults to `True` and `touch`es the `pants_path`. :returns: A resolved jar describing the artifact. :rtype: :class:`pants.java.jar.ResolvedJar` """ coordinate = M2Coordinate(org=org, name=name, rev=rev, classifier=classifier, ext=ext) cache_path = 'not/a/real/cache/path' jar_name = coordinate.artifact_filename if materialize: pants_path = self.create_workdir_file(jar_name) else: pants_path = os.path.join(self.pants_workdir, jar_name) return ResolvedJar(coordinate=coordinate, cache_path=cache_path, pants_path=pants_path)
def _populate_compile_classpath(self): products = self.context.products compile_classpath = products.get_data( 'compile_classpath', init_func=ClasspathProducts.init_func( self.get_options().pants_workdir)) sorted_targets = sorted( self.context.targets(predicate=lambda t: t in self.all_jar_libs), key=lambda t: t.address.spec, ) for target in sorted_targets: resolved_jars = [] for coord in sorted( self.target_to_maven_coordinate_closure[target.id]): m2_coord = M2Coordinate( org=coord.groupId, name=coord.artifactId, rev=coord.version, classifier=coord.classifier, ext=coord.packaging, ) sorted_artifact_paths = sorted( artifact.artifact_path for artifact in self.maven_coordinate_to_provided_artifacts[coord]) for artifact_path in sorted_artifact_paths: resolved_jar = ResolvedJar( coordinate=m2_coord, pants_path=os.path.join(self.artifact_symlink_dir, artifact_path), cache_path=os.path.join(self.pom_cache_dir, artifact_path), ) resolved_jars.append(resolved_jar) compile_classpath.add_jars_for_targets([target], 'default', resolved_jars)
def test_create_canonical_classpath_no_duplicate_entry(self): """Test no more than one symlink are created for the same classpath entry.""" jar_path = 'ivy/jars/org.x/lib/x-1.0.jar' resolved_jar = ResolvedJar(M2Coordinate(org='org', name='x', rev='1.0'), cache_path='somewhere', pants_path=self._path(jar_path)) target_a = self.make_target('a', JvmTarget) target_b = self.make_target('b', JvmTarget) classpath_products = ClasspathProducts(self.pants_workdir) # Both target a and target b depend on the same jar library classpath_products.add_jars_for_targets([target_a], 'default', [resolved_jar]) classpath_products.add_jars_for_targets([target_b], 'default', [resolved_jar]) with temporary_dir() as base_dir: # Only target a generates symlink to jar library, target b skips creating the # symlink for the same jar library. Both targets' classpath.txt files should # still contain the jar library. self._test_canonical_classpath_helper( classpath_products, [target_a, target_b], base_dir, ['a.a-0.jar'], { 'a.a-classpath.txt': '{}/{}\n'.format(self.pants_workdir, jar_path), 'b.b-classpath.txt': '{}/{}\n'.format(self.pants_workdir, jar_path), })
def test_classpath_by_targets(self): b = self.make_target('b', JvmTarget) a = self.make_target('a', JvmTarget, dependencies=[b], excludes=[Exclude('com.example', 'lib')]) classpath_products = ClasspathProducts(self.pants_workdir) path1 = self._path('jar/path1') path2 = self._path('jar/path2') path3 = os.path.join(self.pants_workdir, 'jar/path3') resolved_jar = ResolvedJar(M2Coordinate(org='com.example', name='lib', rev='1.0'), cache_path='somewhere', pants_path=path3) classpath_products.add_for_target(a, [('default', path1)]) classpath_products.add_for_target(a, [('non-default', path2)]) classpath_products.add_for_target(b, [('default', path2)]) classpath_products.add_jars_for_targets([b], 'default', [resolved_jar]) classpath_products.add_excludes_for_targets([a]) # (a, path2) filtered because of conf # (b, path3) filtered because of excludes self.assertEquals( OrderedDict([(a, [ClasspathEntry(path1)]), (b, [ClasspathEntry(path2)])]), ClasspathUtil.classpath_by_targets(a.closure(bfs=True), classpath_products))
def resolved_jarlib(name, jar_path): resolved_jar = ResolvedJar(M2Coordinate(org='org.example', name=name, rev='0.0.1'), cache_path=jar_path, pants_path=jar_path) jar_dep = JarDependency(org='org.example', name=name, rev='0.0.1') jar_library = self.make_target(spec='3rdparty:{}'.format(name), target_type=JarLibrary, jars=[jar_dep]) return jar_library, resolved_jar
def test_jar_missing_pants_path_fails_adding(self): b = self.make_target('b', JvmTarget) classpath_products = ClasspathProducts(self.pants_workdir) with self.assertRaises(TaskError) as cm: classpath_products.add_jars_for_targets([b], 'default', [ResolvedJar(M2Coordinate(org='org', name='name'), cache_path='somewhere', pants_path=None)]) self.assertEqual( 'Jar: org:name:::jar has no specified path.', str(cm.exception))
def new_resolved_jar_with_symlink_path(resolved_jar_without_symlink): if resolved_jar_without_symlink.cache_path in symlink_map: key = resolved_jar_without_symlink.cache_path else: key = os.path.realpath(resolved_jar_without_symlink.cache_path) if key not in symlink_map: raise self.UnresolvedJarError( 'Jar {resolved_jar} in {spec} not resolved to the ivy symlink map in conf {conf}.' .format( spec=target.address.spec, resolved_jar=resolved_jar_without_symlink.cache_path, conf=conf)) return ResolvedJar( coordinate=resolved_jar_without_symlink.coordinate, pants_path=symlink_map[key], cache_path=resolved_jar_without_symlink.cache_path)
def test_create_canonical_classpath_with_broken_classpath(self): """Test exception is thrown when the jar file is missing.""" a = self.make_target('a/b', JvmTarget) classpath_products = ClasspathProducts(self.pants_workdir) jar_path = 'ivy/jars/org.x/lib/x-1.0.jar' # this sets the path for the artifact without actually materializing it. resolved_jar = ResolvedJar(M2Coordinate(org='org', name='x', rev='1.0'), cache_path='somewhere', pants_path=os.path.join( self.pants_workdir, jar_path)) classpath_products.add_jars_for_targets([a], 'default', [resolved_jar]) with temporary_dir() as base_dir: with self.assertRaises(MissingClasspathEntryError): self._test_canonical_classpath_helper(classpath_products, [a], base_dir, [], {})
def new_resolved_jar_with_symlink_path(tgt, cnf, resolved_jar_without_symlink): # There is a focus on being lazy here to avoid `os.path.realpath` when we can. def candidate_cache_paths(): yield resolved_jar_without_symlink.cache_path yield os.path.realpath(resolved_jar_without_symlink.cache_path) try: return next( ResolvedJar( coordinate=resolved_jar_without_symlink.coordinate, pants_path=symlink_map[cache_path], cache_path=resolved_jar_without_symlink.cache_path) for cache_path in candidate_cache_paths() if cache_path in symlink_map) except StopIteration: raise self.UnresolvedJarError( 'Jar {resolved_jar} in {spec} not resolved to the ivy ' 'symlink map in conf {conf}.'.format( spec=tgt.address.spec, resolved_jar=resolved_jar_without_symlink.cache_path, conf=cnf))
def _new_resolved_jar_with_symlink_path(self, conf, target, resolved_jar_without_symlink): def candidate_cache_paths(): # There is a focus on being lazy here to avoid `os.path.realpath` when we can. yield resolved_jar_without_symlink.cache_path yield os.path.realpath(resolved_jar_without_symlink.cache_path) for cache_path in candidate_cache_paths(): pants_path = self._symlink_map.get(cache_path) if pants_path: break else: raise IvyResolveMappingError( 'Jar {resolved_jar} in {spec} not resolved to the ivy ' 'symlink map in conf {conf}.' .format(spec=target.address.spec, resolved_jar=resolved_jar_without_symlink.cache_path, conf=conf)) return ResolvedJar(coordinate=resolved_jar_without_symlink.coordinate, pants_path=pants_path, cache_path=resolved_jar_without_symlink.cache_path)
def resolved_example_jar_at(path, org='com.example', name='lib'): return ResolvedJar(M2Coordinate(org=org, name=name), cache_path=os.path.join('resolver-cache-dir', path), pants_path=path)
def resolved_example_jar_at(path, org='com.example', name='lib'): return ResolvedJar(M2Coordinate(org=org, name=name), cache_path=path, pants_path=path)
def test_resolved_jars_with_same_properties(self): jar1 = ResolvedJar(M2Coordinate('org.example', 'lib'), 'path') jar2 = ResolvedJar(M2Coordinate('org.example', 'lib'), 'path') self.assertEqual(jar1, jar2) self.assertEqual(hash(jar1), hash(jar2))