def __init__(self, name, source, dependencies=None, resources=None): InternalTarget.__init__(self, name, dependencies, is_meta=False) TargetWithSources.__init__(self, name) self.source = self._resolve_paths(self.target_base, [source]).pop() self.resources = self._resolve_paths(self.target_base, resources) if resources else [] self._wikis = {}
def __init__(self, name, sources, dependencies, excludes=None, buildflags=None, is_meta=False, configurations=None): InternalTarget.__init__(self, name, dependencies, is_meta) TargetWithSources.__init__(self, name, is_meta) self.declared_dependencies = set(dependencies or []) self.add_label('jvm') self.sources = self._resolve_paths(self.target_base, sources) or [] for source in self.sources: rel_path = os.path.join(self.target_base, source) TargetWithSources.register_source(rel_path, self) self.excludes = excludes or [] self.buildflags = buildflags or [] custom_antxml = '%s.xml' % self.name buildfile = self.address.buildfile.full_path custom_antxml_path = os.path.join(os.path.dirname(buildfile), custom_antxml) self.custom_antxml_path = custom_antxml_path if os.path.exists( custom_antxml_path) else None self.configurations = configurations
def __init__(self, name, dependencies=(), sources=None, resources=None): InternalTarget.__init__(self, name, dependencies, None) TargetWithSources.__init__(self, name) if not sources: raise TargetDefinitionException(self, 'No sources specified') self.name = name self.sources = self._resolve_paths(self.target_base, sources) self.resources = self._resolve_paths(self.target_base, resources) if resources else []
def test_validation(self): with ParseContext.temp('InternalTargetTest/test_validation'): InternalTarget(name="valid", dependencies=None) self.assertRaises(TargetDefinitionException, InternalTarget, name=1, dependencies=None) InternalTarget(name="valid2", dependencies=Target(name='mybird')) self.assertRaises(TargetDefinitionException, InternalTarget, name='valid3', dependencies=1)
def __init__(self, name, source, dependencies=None, resources=None): InternalTarget.__init__(self, name, dependencies, is_meta=False) TargetWithSources.__init__(self, name) self.sources = self._resolve_paths(self.target_base, [source]) self._source = self.sources.pop() self.resources = self._resolve_paths(self.target_base, resources) if resources else [] self._wikis = {}
def testSort(self): a = MockTarget('a', []) b = MockTarget('b', [a]) c = MockTarget('c', [b]) d = MockTarget('d', [c, a]) e = MockTarget('e', [d]) self.assertEquals(InternalTarget.sort_targets([a,b,c,d,e]), [e,d,c,b,a]) self.assertEquals(InternalTarget.sort_targets([b,d,a,e,c]), [e,d,c,b,a]) self.assertEquals(InternalTarget.sort_targets([e,d,c,b,a]), [e,d,c,b,a])
def __init__(self, name, dependencies=None, num_sources=0, exclusives=None): with ParseContext.temp(): InternalTarget.__init__(self, name, dependencies, exclusives=exclusives) TargetWithSources.__init__(self, name, exclusives=exclusives) self.num_sources = num_sources self.declared_exclusives = defaultdict(set) if exclusives is not None: for k in exclusives: self.declared_exclusives[k] = set([exclusives[k]]) self.exclusives = None
def test_detect_cycle_direct(self): a = MockTarget('a') # no cycles yet InternalTarget.sort_targets([a]) a.update_dependencies([a]) try: InternalTarget.sort_targets([a]) self.fail("Expected a cycle to be detected") except InternalTarget.CycleException: # expected pass
def __init__(self, name, sources, dependencies, excludes=None, buildflags=None, is_meta=False): InternalTarget.__init__(self, name, dependencies, is_meta) TargetWithSources.__init__(self, name, is_meta) self.sources = self._resolve_paths(self.target_base, sources) or [] self.excludes = excludes or [] self.buildflags = buildflags or [] custom_antxml = '%s.xml' % self.name buildfile = self.address.buildfile.full_path custom_antxml_path = os.path.join(os.path.dirname(buildfile), custom_antxml) self.custom_antxml_path = custom_antxml_path if os.path.exists(custom_antxml_path) else None
def exported_targets(self): candidates = set() if self.transitive: candidates.update(self.context.targets()) else: candidates.update(self.context.target_roots) def get_synthetic(lang, target): mappings = self.context.products.get(lang).get(target) if mappings: for generated in mappings.itervalues(): for synthetic in generated: yield synthetic # Handle the case where a code gen target is in the listed roots and the thus the publishable # target is a synthetic twin generated by a code gen task upstream. for candidate in self.context.target_roots: candidates.update(get_synthetic('java', candidate)) candidates.update(get_synthetic('scala', candidate)) def exportable(tgt): return tgt in candidates and tgt.is_exported return OrderedSet(filter(exportable, reversed(InternalTarget.sort_targets(filter(exportable, candidates)))))
def execute(self, targets): java_targets = filter(JavaCompile._is_java, reversed(InternalTarget.sort_targets(targets))) if java_targets: safe_mkdir(self._classes_dir) safe_mkdir(self._depfile_dir) with self.context.state('classpath', []) as cp: for conf in self._confs: cp.insert(0, (conf, self._resources_dir)) cp.insert(0, (conf, self._classes_dir)) if not self._flatten: for target in java_targets: self.execute_single_compilation([target], cp) else: self.execute_single_compilation(java_targets, cp) if self.context.products.isrequired('classes'): genmap = self.context.products.get('classes') # Map generated classes to the owning targets and sources. for target, classes_by_source in self._deps.findclasses(java_targets).items(): for source, classes in classes_by_source.items(): genmap.add(source, self._classes_dir, classes) genmap.add(target, self._classes_dir, classes) # TODO(John Sirois): Map target.resources in the same way # 'Map' (rewrite) annotation processor service info files to the owning targets. for target in java_targets: if is_apt(target) and target.processors: basedir = os.path.join(self._resources_dir, target.id) processor_info_file = os.path.join(basedir, _PROCESSOR_INFO_FILE) self.write_processor_info(processor_info_file, target.processors) genmap.add(target, basedir, [_PROCESSOR_INFO_FILE])
def extract_target(java_targets, is_classpath): primary_target = InternalTarget.sort_targets(java_targets)[0] with ParseContext.temp(primary_target.target_base): internal_deps, jar_deps = _extract_target(java_targets, is_classpath) # TODO(John Sirois): make an empty source set work in ant/compile.xml sources = [ '__no_source__' ] all_deps = OrderedSet() all_deps.update(internal_deps) all_deps.update(jar_deps) if is_java(primary_target): return JavaLibrary('ide', sources, dependencies = all_deps, is_meta = True) elif is_scala(primary_target): return ScalaLibrary('ide', sources, dependencies = all_deps, is_meta = True) else: raise TypeError("Cannot generate IDE configuration for targets: %s" % java_targets)
def _order_target_list(self, targets): """Orders the targets topologically, from least to most dependent.""" target_ids = set([x.id for x in targets]) ordered_targets_and_deps = reversed( InternalTarget.sort_targets(targets)) # Return just the ones that were originally in targets. return filter(lambda x: x.id in target_ids, ordered_targets_and_deps)
def _create_chunks(self): def discriminator(tgt): for group_member in self._group_members: if group_member.predicate(tgt): return group_member.name return None # TODO(John Sirois): coalescing should be made available in another spot, InternalTarget is jvm # specific, and all we care is that the Targets have dependencies defined coalesced = InternalTarget.coalesce_targets(self._targets, discriminator) coalesced = list(reversed(coalesced)) chunks = [] flavor = None chunk_start = 0 for chunk_num, target in enumerate(coalesced): target_flavor = discriminator(target) if target_flavor != flavor and chunk_num > chunk_start: chunks.append(OrderedSet(coalesced[chunk_start:chunk_num])) chunk_start = chunk_num flavor = target_flavor if chunk_start < len(coalesced): chunks.append(OrderedSet(coalesced[chunk_start:])) return chunks
def execute(self, targets): if not self._flatten and len(targets) > 1: topologically_sorted_targets = filter(JavaCompile._is_java, reversed(InternalTarget.sort_targets(targets))) for target in topologically_sorted_targets: self.execute([target]) return self.context.log.info('Compiling targets %s' % str(targets)) java_targets = filter(JavaCompile._is_java, targets) if java_targets: with self.context.state('classpath', []) as cp: for conf in self._confs: cp.insert(0, (conf, self._resources_dir)) cp.insert(0, (conf, self._classes_dir)) with self.changed(java_targets, invalidate_dependants=True) as changed: sources_by_target, processors, fingerprint = self.calculate_sources(changed) if sources_by_target: sources = reduce(lambda all, sources: all.union(sources), sources_by_target.values()) if not sources: self.context.log.warn('Skipping java compile for targets with no sources:\n %s' % '\n '.join(str(t) for t in sources_by_target.keys())) else: classpath = [jar for conf, jar in cp if conf in self._confs] result = self.compile(classpath, sources, fingerprint) if result != 0: default_message = 'Unexpected error - %s returned %d' % (_JMAKE_MAIN, result) raise TaskError(_JMAKE_ERROR_CODES.get(result, default_message)) if processors: # Produce a monolithic apt processor service info file for further compilation rounds # and the unit test classpath. processor_info_file = os.path.join(self._classes_dir, _PROCESSOR_INFO_FILE) if os.path.exists(processor_info_file): with safe_open(processor_info_file, 'r') as f: for processor in f: processors.add(processor.strip()) self.write_processor_info(processor_info_file, processors) if self.context.products.isrequired('classes'): genmap = self.context.products.get('classes') # Map generated classes to the owning targets and sources. dependencies = Dependencies(self._classes_dir, self._dependencies_file) for target, classes_by_source in dependencies.findclasses(targets).items(): for source, classes in classes_by_source.items(): genmap.add(source, self._classes_dir, classes) genmap.add(target, self._classes_dir, classes) # TODO(John Sirois): Map target.resources in the same way # 'Map' (rewrite) annotation processor service info files to the owning targets. for target in targets: if is_apt(target) and target.processors: basedir = os.path.join(self._resources_dir, target.id) processor_info_file = os.path.join(basedir, _PROCESSOR_INFO_FILE) self.write_processor_info(processor_info_file, target.processors) genmap.add(target, basedir, [_PROCESSOR_INFO_FILE])
def _order_target_list(self, targets): """Orders the targets topologically, from least to most dependent.""" target_ids = set([x.id for x in targets]) # Most to least dependent. reverse_ordered_targets_and_deps = InternalTarget.sort_targets(targets) # Least to most dependent. We must build in this order. ordered_targets_and_deps = reversed(reverse_ordered_targets_and_deps) # Return just the ones that were originally in targets. return filter(lambda x: x.id in target_ids, ordered_targets_and_deps)
def execute(self, targets): if not self._flatten and len(targets) > 1: topologically_sorted_targets = filter( is_scala, reversed(InternalTarget.sort_targets(targets))) for target in topologically_sorted_targets: self.execute([target]) return self.context.log.info('Compiling targets %s' % str(targets)) scala_targets = filter(is_scala, targets) if scala_targets: with self.context.state('classpath', []) as cp: for conf in self._confs: cp.insert(0, (conf, self._resources_dir)) cp.insert(0, (conf, self._classes_dir)) with self.changed(scala_targets, invalidate_dependants=True) as changed_targets: sources_by_target = self.calculate_sources(changed_targets) if sources_by_target: sources = reduce(lambda all, sources: all.union(sources), sources_by_target.values()) if not sources: self.context.log.warn( 'Skipping scala compile for targets with no sources:\n %s' % '\n '.join( str(t) for t in sources_by_target.keys())) else: classpath = [ jar for conf, jar in cp if conf in self._confs ] result = self.compile(classpath, sources) if result != 0: raise TaskError('%s returned %d' % (self._main, result)) if self.context.products.isrequired('classes'): genmap = self.context.products.get('classes') # Map generated classes to the owning targets and sources. dependencies = Dependencies(self._classes_dir, self._depfile) for target, classes_by_source in dependencies.findclasses( targets).items(): for source, classes in classes_by_source.items(): genmap.add(source, self._classes_dir, classes) genmap.add(target, self._classes_dir, classes) # TODO(John Sirois): Map target.resources in the same way # Create and Map scala plugin info files to the owning targets. for target in targets: if is_scalac_plugin(target) and target.classname: basedir = self.write_plugin_info(target) genmap.add(target, basedir, [_PLUGIN_INFO_FILE])
def _compute_transitive_deps_by_target(self): """Map from target to all the targets it depends on, transitively.""" # Sort from least to most dependent. sorted_targets = reversed(InternalTarget.sort_targets(self._context.targets())) transitive_deps_by_target = defaultdict(set) # Iterate in dep order, to accumulate the transitive deps for each target. for target in sorted_targets: transitive_deps = set() if hasattr(target, 'dependencies'): for dep in target.dependencies: transitive_deps.update(transitive_deps_by_target.get(dep, [])) transitive_deps.add(dep) transitive_deps_by_target[target] = transitive_deps return transitive_deps_by_target
def _compute_transitive_deps_by_target(self): """Map from target to all the targets it depends on, transitively.""" # Sort from least to most dependent. sorted_targets = reversed( InternalTarget.sort_targets(self._context.targets())) transitive_deps_by_target = defaultdict(set) # Iterate in dep order, to accumulate the transitive deps for each target. for target in sorted_targets: transitive_deps = set() if hasattr(target, 'dependencies'): for dep in target.dependencies: transitive_deps.update( transitive_deps_by_target.get(dep, [])) transitive_deps.add(dep) transitive_deps_by_target[target] = transitive_deps return transitive_deps_by_target
def execute(self, targets): if not self._flatten and len(targets) > 1: topologically_sorted_targets = filter(is_scala, reversed(InternalTarget.sort_targets(targets))) for target in topologically_sorted_targets: self.execute([target]) return self.context.log.info('Compiling targets %s' % str(targets)) scala_targets = filter(is_scala, targets) if scala_targets: with self.context.state('classpath', []) as cp: for conf in self._confs: cp.insert(0, (conf, self._resources_dir)) cp.insert(0, (conf, self._classes_dir)) with self.changed(scala_targets, invalidate_dependants=True) as changed_targets: sources_by_target = self.calculate_sources(changed_targets) if sources_by_target: sources = reduce(lambda all, sources: all.union(sources), sources_by_target.values()) if not sources: self.context.log.warn('Skipping scala compile for targets with no sources:\n %s' % '\n '.join(str(t) for t in sources_by_target.keys())) else: classpath = [jar for conf, jar in cp if conf in self._confs] result = self.compile(classpath, sources) if result != 0: raise TaskError('%s returned %d' % (self._main, result)) if self.context.products.isrequired('classes'): genmap = self.context.products.get('classes') # Map generated classes to the owning targets and sources. dependencies = Dependencies(self._classes_dir, self._depfile) for target, classes_by_source in dependencies.findclasses(targets).items(): for source, classes in classes_by_source.items(): genmap.add(source, self._classes_dir, classes) genmap.add(target, self._classes_dir, classes) # TODO(John Sirois): Map target.resources in the same way # Create and Map scala plugin info files to the owning targets. for target in targets: if is_scalac_plugin(target) and target.classname: basedir = self.write_plugin_info(target) genmap.add(target, basedir, [_PLUGIN_INFO_FILE])
def execute(self, targets): scala_targets = filter(is_scala, reversed(InternalTarget.sort_targets(targets))) if scala_targets: safe_mkdir(self._classes_dir) safe_mkdir(self._depfile_dir) with self.context.state('classpath', []) as cp: for conf in self._confs: cp.insert(0, (conf, self._resources_dir)) # If we're not flattening, we don't want the classes dir on the classpath yet, as we want zinc to # see only the per-compilation output dirs, so it can map them to analysis caches. if self._flatten: cp.insert(0, (conf, self._classes_dir)) if not self._flatten: upstream_analysis_caches = OrderedDict() # output dir -> analysis cache file for the classes in that dir. for target in scala_targets: self.execute_single_compilation([target], cp, upstream_analysis_caches) else: self.execute_single_compilation(scala_targets, cp, {}) if not self._flatten: # Now we can add the global output dir, so that subsequent goals can see it. with self.context.state('classpath', []) as cp: for conf in self._confs: cp.insert(0, (conf, self._classes_dir)) if self.context.products.isrequired('classes'): genmap = self.context.products.get('classes') # Map generated classes to the owning targets and sources. for target, classes_by_source in self._deps.findclasses(scala_targets).items(): for source, classes in classes_by_source.items(): genmap.add(source, self._classes_dir, classes) genmap.add(target, self._classes_dir, classes) # TODO(John Sirois): Map target.resources in the same way # Create and Map scala plugin info files to the owning targets. for target in scala_targets: if is_scalac_plugin(target) and target.classname: basedir = self.write_plugin_info(target) genmap.add(target, basedir, [_PLUGIN_INFO_FILE])
def execute(self, targets): scala_targets = filter(is_scala, reversed(InternalTarget.sort_targets(targets))) if scala_targets: safe_mkdir(self._depfile_dir) safe_mkdir(self._analysis_cache_dir) # Map from output directory to { analysis_cache_dir, [ analysis_cache_file ]} upstream_analysis_caches = self.context.products.get('upstream') with self.context.state('classpath', []) as cp: for conf in self._confs: cp.insert(0, (conf, self._resources_dir)) if self._flatten: self.execute_single_compilation(scala_targets, cp, upstream_analysis_caches) else: for target in scala_targets: self.execute_single_compilation([target], cp, upstream_analysis_caches) # Now we can add the global output dir, so that subsequent goals can see it. with self.context.state('classpath', []) as cp: for conf in self._confs: cp.insert(0, (conf, self._classes_dir)) if self.context.products.isrequired('classes'): genmap = self.context.products.get('classes') # Map generated classes to the owning targets and sources. for target, classes_by_source in self._deps.findclasses(scala_targets).items(): for source, classes in classes_by_source.items(): genmap.add(source, self._classes_dir, classes) genmap.add(target, self._classes_dir, classes) # TODO(John Sirois): Map target.resources in the same way # Create and Map scala plugin info files to the owning targets. for target in scala_targets: if is_scalac_plugin(target) and target.classname: basedir = self.write_plugin_info(target) genmap.add(target, basedir, [_PLUGIN_INFO_FILE])
def _order_target_list(self, targets): """Orders the targets topologically, from least to most dependent.""" targets = set(t for t in targets if isinstance(t, Target)) return filter(targets.__contains__, reversed(InternalTarget.sort_targets(targets)))
def _order_target_list(self, targets): """Orders the targets topologically, from least to most dependent.""" targets = set(filter(has_sources, targets)) return filter(targets.__contains__, reversed(InternalTarget.sort_targets(targets)))
def execute(self, targets): if not self._flatten and len(targets) > 1: topologically_sorted_targets = filter( JavaCompile._is_java, reversed(InternalTarget.sort_targets(targets))) for target in topologically_sorted_targets: self.execute([target]) return self.context.log.info('Compiling targets %s' % str(targets)) java_targets = filter(JavaCompile._is_java, targets) if java_targets: with self.context.state('classpath', []) as cp: for conf in self._confs: cp.insert(0, (conf, self._resources_dir)) cp.insert(0, (conf, self._classes_dir)) with self.changed(java_targets, invalidate_dependants=True) as changed: sources_by_target, processors, fingerprint = self.calculate_sources( changed) if sources_by_target: sources = reduce( lambda all, sources: all.union(sources), sources_by_target.values()) if not sources: self.context.log.warn( 'Skipping java compile for targets with no sources:\n %s' % '\n '.join( str(t) for t in sources_by_target.keys())) else: classpath = [ jar for conf, jar in cp if conf in self._confs ] result = self.compile(classpath, sources, fingerprint) if result != 0: default_message = 'Unexpected error - %s returned %d' % ( _JMAKE_MAIN, result) raise TaskError( _JMAKE_ERROR_CODES.get( result, default_message)) if processors: # Produce a monolithic apt processor service info file for further compilation rounds # and the unit test classpath. processor_info_file = os.path.join( self._classes_dir, _PROCESSOR_INFO_FILE) if os.path.exists(processor_info_file): with safe_open(processor_info_file, 'r') as f: for processor in f: processors.add(processor.strip()) self.write_processor_info(processor_info_file, processors) if self.context.products.isrequired('classes'): genmap = self.context.products.get('classes') # Map generated classes to the owning targets and sources. dependencies = Dependencies(self._classes_dir, self._dependencies_file) for target, classes_by_source in dependencies.findclasses( targets).items(): for source, classes in classes_by_source.items(): genmap.add(source, self._classes_dir, classes) genmap.add(target, self._classes_dir, classes) # TODO(John Sirois): Map target.resources in the same way # 'Map' (rewrite) annotation processor service info files to the owning targets. for target in targets: if is_apt(target) and target.processors: basedir = os.path.join(self._resources_dir, target.id) processor_info_file = os.path.join( basedir, _PROCESSOR_INFO_FILE) self.write_processor_info(processor_info_file, target.processors) genmap.add(target, basedir, [_PROCESSOR_INFO_FILE])