def imports(self): """Returns the set of JarDependency instances to be included when compiling this target.""" if self._imports is None: self._imports = JarLibrary.to_jar_dependencies(self.address, self.payload.raw_imports, self._build_graph) return self._imports
def test_validation(self): target = Target(name='mybird', address=SyntheticAddress.parse('//:mybird'), build_graph=self.build_graph) # jars attribute must contain only JarLibrary instances with self.assertRaises(TargetDefinitionException): JarLibrary(name="test", jars=[target])
def test_jar_dependencies(self): jar1 = JarDependency(org='testOrg1', name='testName1', rev='123') jar2 = JarDependency(org='testOrg2', name='testName2', rev='456') lib = JarLibrary(name='foo', address=SyntheticAddress.parse('//:foo'), build_graph=self.build_graph, jars=[jar1, jar2]) self.assertEquals((jar1, jar2), lib.jar_dependencies)
def imported_jars(self): """:returns: the string specs of JarDependencies referenced by imported_jar_library_specs :rtype: list of string """ return JarLibrary.to_jar_dependencies(self.address, self.imported_jar_library_specs, self._build_graph)
def imported_jars(self): """:returns: the string specs of JarDependencies referenced by imported_jar_library_specs :rtype: list of JarDependency """ return JarLibrary.to_jar_dependencies(self.address, self.imported_jar_library_specs(payload=self.payload), self._build_graph)
def test_excludes(self): # TODO(Eric Ayers) There doesn't seem to be any way to set this field at the moment. lib = JarLibrary(name='foo', address=Address.parse('//:foo'), build_graph=self.build_graph, jars=[jar1]) self.assertEquals([], lib.excludes)
def test_jar_dependencies(self): lib = JarLibrary( name="foo", address=Address.parse("//:foo"), build_graph=self.build_graph, jars=[jar1, jar2], ) self.assertEqual((jar1, jar2), lib.jar_dependencies)
def test_jar_dependency(self): with ParseContext.temp(): org, name = "org", "name" # thing to override nay = JarDependency(org, name, "0.0.1") yea = JarDependency(org, name, "0.0.8") # define targets depend on different 'org:c's JarLibrary("c", jars=[nay]) JarLibrary("b", jars=[yea]) # then depend on those targets transitively, and override to the correct version l = Target("a", dependencies=[Pants(":c")], overrides=[":b"]) # confirm that resolving includes the correct version resolved = set(l.resolve()) self.assertTrue(yea in resolved) # and attaches an exclude directly to the JarDependency self.assertTrue(Exclude(org, name) in nay.excludes)
def test_jar_dependency(self): with ParseContext.temp(): org, name = "org", "name" # thing to override nay = JarDependency(org, name, "0.0.1") yea = JarDependency(org, name, "0.0.8") # define targets depend on different 'org:c's JarLibrary("c", [nay]) JarLibrary("b", [yea]) # then depend on those targets transitively, and override to the correct version l = JarLibrary("a", dependencies=[Pants(":c")], overrides=[":b"]) # confirm that resolving includes the correct version resolved = set(l.resolve()) self.assertTrue(yea in resolved) # and attaches an exclude directly to the JarDependency self.assertTrue(Exclude(org, name) in nay.excludes)
def _alternate_target_roots(cls, options, address_mapper, build_graph): processed = set() for jvm_tool in JvmToolMixin.get_registered_tools(): dep_spec = jvm_tool.dep_spec(options) dep_address = Address.parse(dep_spec) # Some JVM tools are requested multiple times, we only need to handle them once. if dep_address not in processed: processed.add(dep_address) try: if build_graph.resolve_address(dep_address): # The user has defined a tool classpath override - we let that stand. continue except AddressLookupError as e: if jvm_tool.classpath is None: raise cls._tool_resolve_error(e, dep_spec, jvm_tool) else: if not jvm_tool.is_default(options): # The user specified a target spec for this jvm tool that doesn't actually exist. # We want to error out here instead of just silently using the default option while # appearing to respect their config. raise cls.ToolResolveError(dedent(""" Failed to resolve target for tool: {tool}. This target was obtained from option {option} in scope {scope}. Make sure you didn't make a typo in the tool's address. You specified that the tool should use the target found at "{tool}". This target has a default classpath configured, so you can simply remove: [{scope}] {option}: {tool} from pants.ini (or any other config file) to use the default tool. The default classpath is: {default_classpath} Note that tool target addresses in pants.ini should be specified *without* quotes. """).strip().format(tool=dep_spec, option=jvm_tool.key, scope=jvm_tool.scope, default_classpath=':'.join(map(str, jvm_tool.classpath or ())))) if jvm_tool.classpath: tool_classpath_target = JarLibrary(name=dep_address.target_name, address=dep_address, build_graph=build_graph, jars=jvm_tool.classpath) else: # The tool classpath is empty by default, so we just inject a dummy target that # ivy resolves as the empty list classpath. JarLibrary won't do since it requires # one or more jars, so we just pick a target type ivy has no resolve work to do for. tool_classpath_target = Target(name=dep_address.target_name, address=dep_address, build_graph=build_graph) build_graph.inject_target(tool_classpath_target, synthetic=True) # We use the trick of not returning alternate roots, but instead just filling the dep_spec # holes with a JarLibrary built from a tool's default classpath JarDependency list if there is # no over-riding targets present. This means we do modify the build_graph, but we at least do # it at a time in the engine lifecycle cut out for handling that. return None
def imported_jars(self): """:returns: the string specs of JarDependencies referenced by imported_jar_library_specs :rtype: list of string """ if self._imported_jars is None: self._imported_jars = JarLibrary.to_jar_dependencies( self.address, self.imported_jar_library_specs, self._build_graph ) return self._imported_jars
def imports(self): """Expected by the IvyImports tasks. :returns: the set of JarDependency instances to be included when compiling this target. """ if self._libraries is None: self._libraries = JarLibrary.to_jar_dependencies(self.address, self.payload.raw_libraries, self._build_graph) return self._libraries
def test_to_jar_dependencies(self): def assert_dep(dep, org, name, rev): self.assertTrue(isinstance(dep, JarDependency)) self.assertEquals(org, dep.org) self.assertEquals(name, dep.name) self.assertEquals(rev, dep.rev) self.add_to_build_file( 'BUILD', dedent(''' jar_library(name='lib1', jars=[ jar(org='testOrg1', name='testName1', rev='123'), ], ) jar_library(name='lib2', jars=[ jar(org='testOrg2', name='testName2', rev='456'), jar(org='testOrg3', name='testName3', rev='789'), ], ) ''')) lib1 = self.target('//:lib1') self.assertIsInstance(lib1, JarLibrary) self.assertEquals(1, len(lib1.jar_dependencies)) assert_dep(lib1.jar_dependencies[0], 'testOrg1', 'testName1', '123') lib2 = self.target('//:lib2') self.assertIsInstance(lib2, JarLibrary) self.assertEquals(2, len(lib2.jar_dependencies)) assert_dep(lib2.jar_dependencies[0], 'testOrg2', 'testName2', '456') assert_dep(lib2.jar_dependencies[1], 'testOrg3', 'testName3', '789') jvm_target = JarLibrary(name='dummy', address=SyntheticAddress.parse("//:dummy"), build_graph=self.build_graph) deps = jvm_target.to_jar_dependencies(jvm_target.address, [':lib1', ':lib2'], self.build_graph) self.assertEquals(3, len(deps)) assert_dep(lib1.jar_dependencies[0], 'testOrg1', 'testName1', '123') assert_dep(lib2.jar_dependencies[0], 'testOrg2', 'testName2', '456') assert_dep(lib2.jar_dependencies[1], 'testOrg3', 'testName3', '789')
def gen_specs(): for fields_tuple in cls.imported_jar_library_spec_fields(): for item in target_representation.get(fields_tuple[field_pos], ()): # For better error handling, this simply skips over non-strings, but we catch them # with a WrongTargetType in JarLibrary.to_jar_dependencies. if not isinstance(item, string_types): raise JarLibrary.ExpectedAddressError( 'expected imports to contain string addresses, got {found_class} instead.' .format(found_class=type(item).__name__)) yield item
def test_to_jar_dependencies(self): def assert_dep(dep, org, name, rev): self.assertTrue(isinstance(dep, JarDependency)) self.assertEquals(org, dep.org) self.assertEquals(name, dep.name) self.assertEquals(rev, dep.rev) self.add_to_build_file('BUILD', dedent(''' jar_library(name='lib1', jars=[ jar(org='testOrg1', name='testName1', rev='123'), ], ) jar_library(name='lib2', jars=[ jar(org='testOrg2', name='testName2', rev='456'), jar(org='testOrg3', name='testName3', rev='789'), ], ) ''')) lib1 = self.target('//:lib1') self.assertIsInstance(lib1, JarLibrary) self.assertEquals(1, len(lib1.jar_dependencies)) assert_dep(lib1.jar_dependencies[0], 'testOrg1', 'testName1', '123') lib2 = self.target('//:lib2') self.assertIsInstance(lib2, JarLibrary) self.assertEquals(2, len(lib2.jar_dependencies)) assert_dep(lib2.jar_dependencies[0], 'testOrg2', 'testName2', '456') assert_dep(lib2.jar_dependencies[1], 'testOrg3', 'testName3', '789') jvm_target = JarLibrary(name='dummy', address=SyntheticAddress.parse("//:dummy"), build_graph=self.build_graph) deps = jvm_target.to_jar_dependencies(jvm_target.address, [':lib1', ':lib2'], self.build_graph) self.assertEquals(3, len(deps)) assert_dep(lib1.jar_dependencies[0], 'testOrg1', 'testName1', '123') assert_dep(lib2.jar_dependencies[0], 'testOrg2', 'testName2', '456') assert_dep(lib2.jar_dependencies[1], 'testOrg3', 'testName3', '789')
def add_payload_fields(cls, build_graph, addresses, payload): # JarLibrary targets have a unique attribute called `managed_dependencies`, which holds a spec of a # `managed_jar_dependency` target. That will not be inserted along with the rest of the jar_library's closure # since at address_mapping time it is not a dependency. We could take care to track them down and insert them # but it looks to me like this handling is already wired into the JarDependency and JarLibrary pipeline. If we # end up seeing misses, we can add the logic to insert them as a special case, but for now I hope to hand that # special casing off. all_jar_deps = JarLibrary.to_jar_dependencies( cls.get_synthetic_address(), [t.spec for t in addresses], build_graph, ) payload.add_fields({ 'jars': JarsField(sorted(all_jar_deps)), }) return payload
def create_synthetic_target(cls, options, address_mapper, build_graph, discovered_targets): """Create a synthetic target that depends on the set of jar_library_targets. The created target is injected into the build graph as an unconnected target with a payload of a JarsField populated by the JarDependencies implied by the jar_library_targets. :param `pants.option.options.Option` options: The Task's scoped options. :param `pants.build_graph.AddressMapper` address_mapper: Populated build_graph instance. :param `pants.build_graph.BuildGraph` build_graph: Populated build_graph instance :param collection[`pants.target.Target`] discovered_targets: Targets newly injected into build graph but possibly not in the context of any target_root. :returns synthetic target: :rtype subclass of `pants.target.Target`: """ synthetic_address = cls.get_synthetic_address() # JarLibrary targets have a unique attribute called `managed_dependencies`, which holds a spec of a # `managed_jar_dependency` target. That will not be inserted along with the rest of the jar_library's closure # since at address_mapping time it is not a dependency. We could take care to track them down and insert them # but it looks to me like this handling is already wired into the JarDependency and JarLibrary pipeline. If we # end up seeing misses, we can add the logic to insert them as a special case, but for now I hope to hand that # special casing off. jar_library_targets = [ t for t in discovered_targets if isinstance(t, JarLibrary) ] all_jar_deps = JarLibrary.to_jar_dependencies( synthetic_address, [t.address.spec for t in jar_library_targets], build_graph, ) payload = Payload() payload.add_fields({ 'jars': JarsField(sorted(all_jar_deps)), }) synthetic_target = cls.inject_synthetic_target( build_graph, synthetic_address, payload=payload, dependencies=[j.address for j in jar_library_targets], ) return synthetic_target
def test_to_jar_dependencies(self): def assert_dep(dep, org, name, rev): self.assertTrue(isinstance(dep, JarDependency)) self.assertEquals(org, dep.org) self.assertEquals(name, dep.name) self.assertEquals(rev, dep.rev) self.add_to_build_file( "BUILD", dedent( """ jar_library(name='lib1', jars=[ jar(org='testOrg1', name='testName1', rev='123'), ], ) jar_library(name='lib2', jars=[ jar(org='testOrg2', name='testName2', rev='456'), jar(org='testOrg3', name='testName3', rev='789'), ], ) """ ), ) lib1 = self.target("//:lib1") self.assertIsInstance(lib1, JarLibrary) self.assertEquals(1, len(lib1.jar_dependencies)) assert_dep(lib1.jar_dependencies[0], "testOrg1", "testName1", "123") lib2 = self.target("//:lib2") self.assertIsInstance(lib2, JarLibrary) self.assertEquals(2, len(lib2.jar_dependencies)) assert_dep(lib2.jar_dependencies[0], "testOrg2", "testName2", "456") assert_dep(lib2.jar_dependencies[1], "testOrg3", "testName3", "789") deps = JarLibrary.to_jar_dependencies(lib1.address, [":lib1", ":lib2"], self.build_graph) self.assertEquals(3, len(deps)) assert_dep(lib1.jar_dependencies[0], "testOrg1", "testName1", "123") assert_dep(lib2.jar_dependencies[0], "testOrg2", "testName2", "456") assert_dep(lib2.jar_dependencies[1], "testOrg3", "testName3", "789")
def test_jar_dependencies(self): lib = JarLibrary(name='foo', address=Address.parse('//:foo'), build_graph=self.build_graph, jars=[jar1, jar2]) self.assertEquals((jar1, jar2), lib.jar_dependencies)