def generate_project(self): outdir = os.path.abspath(self.intellij_output_dir) if not os.path.exists(outdir): os.makedirs(outdir) scm = get_scm() configured_project = TemplateData( root_dir=get_buildroot(), outdir=outdir, git_root=scm.worktree if scm else None, java=TemplateData(encoding=self.java_encoding, jdk=self.java_jdk, language_level='JDK_1_{}'.format( self.java_language_level)), debug_port=self.get_options().debug_port, ) abs_target_specs = [ os.path.join(get_buildroot(), spec) for spec in self.context.options.specs ] configured_workspace = TemplateData( targets=json.dumps(abs_target_specs), project_path=os.path.join(get_buildroot(), abs_target_specs[0].split(':')[0]), idea_plugin_version=IDEA_PLUGIN_VERSION, incremental_import=self.get_options().incremental_import, dep_as_jar=self.get_options().dep_as_jar, ) # Generate (without merging in any extra components). safe_mkdir(os.path.abspath(self.intellij_output_dir)) safe_mkdir(os.path.abspath(self.intellij_idea_dir)) def gen_file(template_file_name, **mustache_kwargs): return self._generate_to_tempfile( Generator( pkgutil.get_data(__name__, template_file_name).decode(), **mustache_kwargs)) idea_ws = gen_file(self.idea_workspace_template, workspace=configured_workspace) idea_modules = gen_file(self.idea_modules_template, project=configured_project) shutil.move(idea_ws, self.idea_workspace_filename) shutil.move(idea_modules, self.idea_modules_filename) return self.gen_project_workdir
class TemplateDataTest(unittest.TestCase): def setUp(self): self.data = TemplateData(foo='bar', baz=42) def test_member_access(self): try: self.data.bip self.fail("Access to undefined template data slots should raise") except AttributeError: # expected pass def test_member_mutation(self): try: self.data.baz = 1 / 137 self.fail("Mutation of a template data's slots should not be allowed") except AttributeError: # expected pass def test_extend(self): self.assertEqual(self.data.extend(jake=0.3), TemplateData(baz=42, foo='bar', jake=0.3)) def test_equals(self): self.assertEqual(self.data, TemplateData(baz=42).extend(foo='bar'))
def gen_tasks_options_reference_data(options): """Generate the template data for the options reference rst doc.""" goal_dict = {} goal_names = [] def fill_template(options, task_type): for authored_task_type in task_type.mro(): if authored_task_type.__module__ != 'abc': break doc_rst = indent_docstring_by_n(authored_task_type.__doc__ or '', 2) doc_html = rst_to_html(dedent_docstring(authored_task_type.__doc__)) parser = options.get_parser(task_type.options_scope) oschi = HelpInfoExtracter.get_option_scope_help_info_from_parser( parser) impl = '{0}.{1}'.format(authored_task_type.__module__, authored_task_type.__name__) return TemplateData(impl=impl, doc_html=doc_html, doc_rst=doc_rst, ogroup=oref_template_data_from_help_info(oschi)) for goal in Goal.all(): tasks = {} for task_name, task_type in goal.task_items(): # task_type may actually be a synthetic subclass of the authored class from the source code. # We want to display the authored class's name in the docs. tasks[task_name] = fill_template(options, task_type) sorted_tasks = [tasks[k] for k in sorted(tasks.keys())] goal_dict[goal.name] = TemplateData(goal=goal, tasks=sorted_tasks) goal_names.append(goal.name) goals = [ goal_dict[name] for name in sorted(goal_names, key=lambda x: x.lower()) ] return goals
class TemplateDataTest(unittest.TestCase): def setUp(self): self.data = TemplateData(foo="bar", baz=42) def test_member_access(self): try: self.data.bip self.fail("Access to undefined template data slots should raise") except AttributeError: # expected pass def test_member_mutation(self): try: self.data.baz = 1 / 137 self.fail("Mutation of a template data's slots should not be allowed") except AttributeError: # expected pass def test_extend(self): self.assertEqual(self.data.extend(jake=0.3), TemplateData(baz=42, foo="bar", jake=0.3)) def test_equals(self): self.assertEqual(self.data, TemplateData(baz=42).extend(foo="bar"))
def _generate_ivy(self, targets, jars, excludes, ivyxml, confs): org, name = self.identify(targets) # As it turns out force is not transitive - it only works for dependencies pants knows about # directly (declared in BUILD files - present in generated ivy.xml). The user-level ivy docs # don't make this clear [1], but the source code docs do (see isForce docs) [2]. I was able to # edit the generated ivy.xml and use the override feature [3] though and that does work # transitively as you'd hope. # # [1] http://ant.apache.org/ivy/history/2.3.0/settings/conflict-managers.html # [2] https://svn.apache.org/repos/asf/ant/ivy/core/branches/2.3.0/ # src/java/org/apache/ivy/core/module/descriptor/DependencyDescriptor.java # [3] http://ant.apache.org/ivy/history/2.3.0/ivyfile/override.html dependencies = [self._generate_jar_template(jar, confs) for jar in jars] overrides = [self._generate_override_template(dep) for dep in dependencies if dep.force] excludes = [self._generate_exclude_template(exclude) for exclude in excludes] template_data = TemplateData( org=org, module=name, version='latest.integration', publications=None, configurations=confs, dependencies=dependencies, excludes=excludes, overrides=overrides) safe_mkdir(os.path.dirname(ivyxml)) with open(ivyxml, 'w') as output: generator = Generator(pkgutil.get_data(__name__, self._template_path), root_dir=get_buildroot(), lib=template_data) generator.write(output)
def entry(nom, classdoc_rst=None, classdoc_html=None, msg_rst=None, msg_html=None, argspec=None, funcdoc_rst=None, funcdoc_html=None, methods=None, paramdocs=None, impl=None, indent=1): """Create a struct that our template expects to see. :param nom: Symbol name, e.g. python_binary :param classdoc_rst: plain text appears above argspec :param msg_rst: reST. useful in hand-crafted entries :param argspec: arg string like (x, y="deflt") :param funcdoc_rst: function's __doc__, plain text :param methods: list of entries for class' methods :param impl: name of thing that implements this. E.g., "pants.backend.core.tasks.builddict.BuildBuildDictionary" :param indent: spaces to indent; rst uses this for outline level """ return TemplateData( nom=nom.strip(), classdoc_rst=indent_docstring_by_n(classdoc_rst), classdoc_html=classdoc_html, msg_html=msg_html, msg_rst=indent_docstring_by_n(msg_rst, indent), argspec=argspec, funcdoc_html=funcdoc_html, funcdoc_rst=indent_docstring_by_n(funcdoc_rst, indent), methods=methods, showmethods=len(methods or []) > 0, paramdocs=paramdocs, showparams=paramdocs and (len(paramdocs) > 0), impl=impl)
def test_publish_classifiers(self): artifacts = map(lambda x: IvyArtifact(x, classifier=x), ['a', 'c', 'b']) p = PomWriter(None, None) c = p.classifiers('a', artifacts) r = map(lambda x: TemplateData(classifier=x), ['a', 'b', 'c']) self.assertEquals(r, c)
def jardep(self, jar): return TemplateData( org=jar.org, name=jar.name, rev=jar.rev, scope='compile', excludes=[self.create_exclude(exclude) for exclude in jar.excludes if exclude.name])
def generate_project(self): outdir = os.path.abspath(self.intellij_output_dir) if not os.path.exists(outdir): os.makedirs(outdir) scm = get_scm() configured_project = TemplateData( root_dir=get_buildroot(), outdir=outdir, git_root=scm.worktree, java=TemplateData(encoding=self.java_encoding, jdk=self.java_jdk, language_level='JDK_1_{}'.format( self.java_language_level)), debug_port=self.get_options().debug_port, ) if not self.context.options.target_specs: raise TaskError("No targets specified.") abs_target_specs = [ os.path.join(get_buildroot(), spec) for spec in self.context.options.target_specs ] configured_workspace = TemplateData( targets=json.dumps(abs_target_specs), project_path=os.path.join(get_buildroot(), abs_target_specs[0].split(':')[0]), idea_plugin_version=IDEA_PLUGIN_VERSION, incremental_import=self.get_options().incremental_import, ) # Generate (without merging in any extra components). safe_mkdir(os.path.abspath(self.intellij_output_dir)) ipr = self._generate_to_tempfile( Generator(pkgutil.get_data(__name__, self.project_template), project=configured_project)) iws = self._generate_to_tempfile( Generator(pkgutil.get_data(__name__, self.workspace_template), workspace=configured_workspace)) self._outstream.write(self.gen_project_workdir) shutil.move(ipr, self.project_filename) shutil.move(iws, self.workspace_filename) return self.project_filename
def _generate_jar_template(cls, jars): Dependency = namedtuple( 'DependencyAttributes', ['org', 'name', 'rev', 'mutable', 'force', 'transitive']) global_dep_attributes = set( Dependency(org=jar.org, name=jar.name, rev=jar.rev, mutable=jar.mutable, force=jar.force, transitive=jar.transitive) for jar in jars) if len(global_dep_attributes) != 1: # TODO(John Sirois): Need to provide information about where these came from - could be # far-flung JarLibrary targets. The jars here were collected from targets via # `calculate_classpath` above and so merging of the 2 could provide the context needed. # See: https://github.com/pantsbuild/pants/issues/2239 conflicting_dependencies = sorted( str(g) for g in global_dep_attributes) raise cls.IvyResolveConflictingDepsError( 'Found conflicting dependencies:\n\t{}'.format( '\n\t'.join(conflicting_dependencies))) jar_attributes = global_dep_attributes.pop() excludes = set() for jar in jars: excludes.update(jar.excludes) any_have_url = False Artifact = namedtuple('Artifact', ['name', 'type_', 'ext', 'url', 'classifier']) artifacts = OrderedDict() for jar in jars: ext = jar.ext url = jar.url if url: any_have_url = True classifier = jar.classifier artifact = Artifact(name=jar.name, type_=ext or 'jar', ext=ext, url=url, classifier=classifier) artifacts[(ext, url, classifier)] = artifact template = TemplateData(org=jar_attributes.org, module=jar_attributes.name, version=jar_attributes.rev, mutable=jar_attributes.mutable, force=jar_attributes.force, transitive=jar_attributes.transitive, artifacts=artifacts.values(), any_have_url=any_have_url, excludes=[ cls._generate_exclude_template(exclude) for exclude in excludes ]) return template
def create_content_root(source_set): root_relative_path = os.path.join(source_set.source_base, source_set.path) \ if source_set.path else source_set.source_base sources = TemplateData(path=root_relative_path, package_prefix=source_set.path.replace( '/', '.') if source_set.path else None, is_test=is_test(source_set)) return TemplateData( path=root_relative_path, sources=[sources], exclude_paths=[ os.path.join(source_set.source_base, x) for x in source_set.excludes ], )
def jardep(self, jar, classifier=None): return TemplateData( classifiers=self.classifiers(classifier, jar.artifacts), artifact_id=jar.name, group_id=jar.org, version=jar.rev, scope='compile', excludes=[self.create_exclude(exclude) for exclude in jar.excludes if exclude.name])
def gref_template_data_from_options(og): """Get data for the Goals Reference from an optparse.OptionGroup""" if not og: return None title = og.title or "" xref = "".join([c for c in title if c.isalnum()]) option_l = [] for o in og.option_list: default = None if o.default and not str(o.default).startswith("('NO',"): default = o.default hlp = None if o.help: hlp = indent_docstring_by_n( o.help.replace("[%default]", "").strip(), 6) option_l.append( TemplateData(st=str(o), default=default, hlp=hlp, typ=o.type)) return TemplateData(title=title, options=option_l, xref=xref)
def generate_ivy(cls, targets, jars, excludes, ivyxml, confs, resolve_hash_name=None): if resolve_hash_name: org = IvyUtils.INTERNAL_ORG_NAME name = resolve_hash_name else: org, name = cls.identify(targets) extra_configurations = [ conf for conf in confs if conf and conf != 'default' ] jars_by_key = OrderedDict() for jar in jars: jars = jars_by_key.setdefault((jar.org, jar.name), []) jars.append(jar) dependencies = [ cls._generate_jar_template(jars) for jars in jars_by_key.values() ] # As it turns out force is not transitive - it only works for dependencies pants knows about # directly (declared in BUILD files - present in generated ivy.xml). The user-level ivy docs # don't make this clear [1], but the source code docs do (see isForce docs) [2]. I was able to # edit the generated ivy.xml and use the override feature [3] though and that does work # transitively as you'd hope. # # [1] http://ant.apache.org/ivy/history/2.3.0/settings/conflict-managers.html # [2] https://svn.apache.org/repos/asf/ant/ivy/core/branches/2.3.0/ # src/java/org/apache/ivy/core/module/descriptor/DependencyDescriptor.java # [3] http://ant.apache.org/ivy/history/2.3.0/ivyfile/override.html overrides = [ cls._generate_override_template(dep) for dep in dependencies if dep.force ] excludes = [ cls._generate_exclude_template(exclude) for exclude in excludes ] template_data = TemplateData(org=org, module=name, extra_configurations=extra_configurations, dependencies=dependencies, excludes=excludes, overrides=overrides) template_relpath = os.path.join('templates', 'ivy_utils', 'ivy.mustache') template_text = pkgutil.get_data(__name__, template_relpath) generator = Generator(template_text, lib=template_data) with safe_open(ivyxml, 'w') as output: generator.write(output)
def gen_goals_glopts_reference_data(): global_option_parser = optparse.OptionParser(add_help_option=False) add_global_options(global_option_parser) glopts = [] for o in global_option_parser.option_list: hlp = None if o.help: hlp = indent_docstring_by_n(o.help.replace('[%default]', '').strip(), 2) glopts.append(TemplateData(st=str(o), hlp=hlp)) return glopts
def _generate_resolve_ivy(cls, jars, excludes, ivyxml, confs, resolve_hash_name, pinned_artifacts=None, jar_dep_manager=None): org = IvyUtils.INTERNAL_ORG_NAME name = resolve_hash_name extra_configurations = [conf for conf in confs if conf and conf != 'default'] jars_by_key = OrderedDict() for jar in jars: jars = jars_by_key.setdefault((jar.org, jar.name), []) jars.append(jar) manager = jar_dep_manager or JarDependencyManagement.global_instance() artifact_set = PinnedJarArtifactSet(pinned_artifacts) # Copy, because we're modifying it. for jars in jars_by_key.values(): for i, dep in enumerate(jars): direct_coord = M2Coordinate.create(dep) managed_coord = artifact_set[direct_coord] if direct_coord.rev != managed_coord.rev: # It may be necessary to actually change the version number of the jar we want to resolve # here, because overrides do not apply directly (they are exclusively transitive). This is # actually a good thing, because it gives us more control over what happens. coord = manager.resolve_version_conflict(managed_coord, direct_coord, force=dep.force) jars[i] = dep.copy(rev=coord.rev) elif dep.force: # If this dependency is marked as 'force' and there is no version conflict, use the normal # pants behavior for 'force'. artifact_set.put(direct_coord) dependencies = [cls._generate_jar_template(jars) for jars in jars_by_key.values()] # As it turns out force is not transitive - it only works for dependencies pants knows about # directly (declared in BUILD files - present in generated ivy.xml). The user-level ivy docs # don't make this clear [1], but the source code docs do (see isForce docs) [2]. I was able to # edit the generated ivy.xml and use the override feature [3] though and that does work # transitively as you'd hope. # # [1] http://ant.apache.org/ivy/history/2.3.0/settings/conflict-managers.html # [2] https://svn.apache.org/repos/asf/ant/ivy/core/branches/2.3.0/ # src/java/org/apache/ivy/core/module/descriptor/DependencyDescriptor.java # [3] http://ant.apache.org/ivy/history/2.3.0/ivyfile/override.html overrides = [cls._generate_override_template(_coord) for _coord in artifact_set] excludes = [cls._generate_exclude_template(exclude) for exclude in excludes] template_data = TemplateData( org=org, module=name, extra_configurations=extra_configurations, dependencies=dependencies, excludes=excludes, overrides=overrides) template_relpath = os.path.join('templates', 'ivy_utils', 'ivy.mustache') cls._write_ivy_xml_file(ivyxml, template_data, template_relpath)
def create_content_root(source_set): root_relative_path = os.path.join(source_set.source_base, source_set.path) \ if source_set.path else source_set.source_base if self.get_options().infer_test_from_siblings: is_test = IdeaGen._sibling_is_test(source_set) else: is_test = source_set.is_test sources = TemplateData( path=root_relative_path, package_prefix=source_set.path.replace('/', '.') if source_set.path else None, is_test=is_test ) return TemplateData( path=root_relative_path, sources=[sources], exclude_paths=[os.path.join(source_set.source_base, x) for x in source_set.excludes], )
def _jardep(self, jar, transitive=True, configurations='default'): return TemplateData( org=jar.org, module=jar.name, version=jar.rev, mutable=False, force=jar.force, excludes=[self.create_exclude(exclude) for exclude in jar.excludes], transitive=transitive, artifacts=jar.artifacts, configurations=configurations)
def _generate_jar_template(self, jar, confs): template = TemplateData( org=jar.org, module=jar.name, version=jar.rev, mutable=self._is_mutable(jar), force=jar.force, excludes=[self._generate_exclude_template(exclude) for exclude in jar.excludes], transitive=jar.transitive, artifacts=jar.artifacts, configurations=[conf for conf in jar.configurations if conf in confs]) return template
def _generate_jar_template(cls, jar, confs): template = TemplateData( org=jar.org, module=jar.name, version=jar.rev, mutable=cls._is_mutable(jar), force=jar.force, excludes=[cls._generate_exclude_template(exclude) for exclude in jar.excludes], transitive=jar.transitive, artifacts=jar.artifacts, configurations=maybe_list(confs)) return template
def gref_template_data_from_options(scope, argparser): """Get data for the Goals Reference from a CustomArgumentParser instance.""" if not argparser: return None title = scope or '' pantsref = ''.join([c for c in title if c.isalnum()]) option_l = [] for o in argparser.walk_actions(): st = '/'.join(o.option_strings) # Argparse elides the type in various circumstances, so we have to reverse that logic here. typ = o.type or (type(o.const) if isinstance( o, argparse._StoreConstAction) else str) default = None if o.default and not str(o.default).startswith("('NO',"): default = o.default hlp = None if o.help: hlp = indent_docstring_by_n( o.help.replace('[%default]', '').strip(), 6) option_l.append( TemplateData(st=st, default=default, hlp=hlp, typ=typ.__name__)) return TemplateData(title=title, options=option_l, pantsref=pantsref)
def gen_tasks_goals_reference_data(): """Generate the template data for the goals reference rst doc.""" goal_dict = {} goal_names = [] for goal in Goal.all(): parser = optparse.OptionParser(add_help_option=False) Goal.setup_parser(parser, [], [goal]) options_by_title = defaultdict(lambda: None) for group in parser.option_groups: options_by_title[group.title] = group found_option_groups = set() tasks = [] for task_name in goal.ordered_task_names(): task_type = goal.task_type_by_name(task_name) doc = indent_docstring_by_n(task_type.__doc__ or '', 2) options_title = Goal.option_group_title(goal, task_name) og = options_by_title[options_title] if og: found_option_groups.add(options_title) impl = '{0}.{1}'.format(task_type.__module__, task_type.__name__) tasks.append(TemplateData( impl=impl, doc=doc, ogroup=gref_template_data_from_options(og))) leftover_option_groups = [] for group in parser.option_groups: if group.title in found_option_groups: continue leftover_option_groups.append(gref_template_data_from_options(group)) leftover_options = [] for option in parser.option_list: leftover_options.append(TemplateData(st=str(option))) goal_dict[goal.name] = TemplateData(goal=goal, tasks=tasks, leftover_opts=leftover_options, leftover_ogs=leftover_option_groups) goal_names.append(goal.name) goals = [goal_dict[name] for name in sorted(goal_names, key=_lower)] return goals
def gen_goals_phases_reference_data(): """Generate the goals reference rst doc.""" phase_dict = {} phase_names = [] for phase, raw_goals in Phase.all(): parser = optparse.OptionParser(add_help_option=False) phase.setup_parser(parser, [], [phase]) options_by_title = defaultdict(lambda: None) for group in parser.option_groups: options_by_title[group.title] = group found_option_groups = set() goals = [] for goal in sorted(raw_goals, key=(lambda x: x.name.lower())): doc = indent_docstring_by_n(goal.task_type.__doc__ or "", 2) options_title = goal.title_for_option_group(phase) og = options_by_title[options_title] if og: found_option_groups.add(options_title) goals.append( TemplateData(name=goal.task_type.__name__, doc=doc, ogroup=gref_template_data_from_options(og))) leftover_option_groups = [] for group in parser.option_groups: if group.title in found_option_groups: continue leftover_option_groups.append( gref_template_data_from_options(group)) leftover_options = [] for option in parser.option_list: leftover_options.append(TemplateData(st=str(option))) phase_dict[phase.name] = TemplateData( phase=phase, goals=goals, leftover_opts=leftover_options, leftover_ogs=leftover_option_groups) phase_names.append(phase.name) phases = [phase_dict[name] for name in sorted(phase_names, key=_lower)] return phases
def generate_ivysettings(self, publishedjars, publish_local=None): template_relpath = os.path.join('templates', 'jar_publish', 'ivysettings.mustache') template = pkgutil.get_data(__name__, template_relpath) with safe_open(os.path.join(self.workdir, 'ivysettings.xml'), 'w') as wrapper: generator = Generator(template, ivysettings=self.ivysettings, dir=self.workdir, cachedir=self.cachedir, published=[TemplateData(org=jar.org, name=jar.name) for jar in publishedjars], publish_local=publish_local) generator.write(wrapper) return wrapper.name
def gen_tasks_goals_reference_data(): """Generate the template data for the goals reference rst doc.""" goal_dict = {} goal_names = [] for goal in Goal.all(): tasks = [] for task_name in goal.ordered_task_names(): task_type = goal.task_type_by_name(task_name) doc_rst = indent_docstring_by_n(task_type.__doc__ or '', 2) doc_html = rst_to_html(dedent_docstring(task_type.__doc__)) option_parser = Parser(env={}, config={}, scope='', parent_parser=None) task_type.register_options(option_parser.register) argparser = option_parser._help_argparser scope = Goal.scope(goal.name, task_name) # task_type may actually be a synthetic subclass of the authored class from the source code. # We want to display the authored class's name in the docs (but note that we must use the # subclass for registering options above) for authored_task_type in task_type.mro(): if authored_task_type.__module__ != 'abc': break impl = '{0}.{1}'.format(authored_task_type.__module__, authored_task_type.__name__) tasks.append( TemplateData(impl=impl, doc_html=doc_html, doc_rst=doc_rst, ogroup=gref_template_data_from_options( scope, argparser))) goal_dict[goal.name] = TemplateData(goal=goal, tasks=tasks) goal_names.append(goal.name) goals = [ goal_dict[name] for name in sorted(goal_names, key=lambda x: x.lower()) ] return goals
def fill_template(options, task_type): for authored_task_type in task_type.mro(): if authored_task_type.__module__ != 'abc': break doc_rst = indent_docstring_by_n(authored_task_type.__doc__ or '', 2) doc_html = rst_to_html(dedent_docstring(authored_task_type.__doc__)) parser = options.get_parser(task_type.options_scope) oschi = HelpInfoExtracter.get_option_scope_help_info_from_parser(parser) impl = '{0}.{1}'.format(authored_task_type.__module__, authored_task_type.__name__) return TemplateData( impl=impl, doc_html=doc_html, doc_rst=doc_rst, ogroup=oref_template_data_from_help_info(oschi))
def param_docshards_to_template_datas(funcdoc_shards): template_datas = [] if funcdoc_shards: for param, parts in funcdoc_shards.items(): if 'type' in parts: type_ = parts['type'] else: type_ = None if 'param' in parts: desc = rst_to_html(dedent_docstring(parts['param'])) else: desc = None template_datas.append(TemplateData(param=param, typ=type_, desc=desc)) return template_datas
def oref_template_data_from_help_info(oschi): """Get data for the Options Reference from an OptionScopeHelpInfo instance.""" def sub_buildroot(s): if isinstance(s, string_types): return s.replace(buildroot, '<buildroot>') else: return s title = oschi.scope pantsref = ''.join([c for c in title if c.isalnum()]) option_l = [] for ohi in oschi.basic: st = '/'.join(ohi.display_args) hlp = None if ohi.help: hlp = indent_docstring_by_n(sub_buildroot(ohi.help), 6) option_l.append( TemplateData(st=st, fromfile=ohi.fromfile, default=sub_buildroot(ohi.default), hlp=hlp, typ=ohi.typ.__name__)) return TemplateData(title=title, options=option_l, pantsref=pantsref)
def _generate_jar_template(cls, jars): global_dep_attributes = set(Dependency(org=jar.org, name=jar.name, rev=jar.rev, mutable=jar.mutable, force=jar.force, transitive=jar.transitive) for jar in jars) if len(global_dep_attributes) != 1: # TODO: Need to provide information about where these came from - could be # far-flung JarLibrary targets. The jars here were collected from targets via # `calculate_classpath` above so executing this step there instead may make more # sense. conflicting_dependencies = sorted(str(g) for g in global_dep_attributes) raise cls.IvyResolveConflictingDepsError('Found conflicting dependencies:\n\t{}' .format('\n\t'.join(conflicting_dependencies))) jar_attributes = global_dep_attributes.pop() excludes = set() for jar in jars: excludes.update(jar.excludes) any_have_url = False artifacts = OrderedDict() for jar in jars: ext = jar.ext url = jar.url if url: any_have_url = True classifier = jar.classifier artifact = Artifact(name=jar.name, type_=ext or 'jar', ext=ext, url=url, classifier=classifier) artifacts[(ext, url, classifier)] = artifact template = TemplateData( org=jar_attributes.org, module=jar_attributes.name, version=jar_attributes.rev, mutable=jar_attributes.mutable, force=jar_attributes.force, transitive=jar_attributes.transitive, artifacts=artifacts.values(), any_have_url=any_have_url, excludes=[cls._generate_exclude_template(exclude) for exclude in excludes]) return template
def tags_tocl(d, tag_list, title): """Generate specialized TOC. E.g., tags_tocl(d, ["python", "anylang"], "Python") tag_list: if an entry's tags contains any of these, use it title: pretty title """ filtered_anchors = [] for anc in sorted(d.keys(), key=_lower): entry = d[anc] if not "tags" in entry: continue found = [t for t in tag_list if t in entry["tags"]] if not found: continue filtered_anchors.append(anc) return TemplateData(t=title, e=filtered_anchors)
def create_content_root(source_set): root_relative_path = os.path.join(source_set.source_base, source_set.path) \ if source_set.path else source_set.source_base if source_set.resources_only: if source_set.is_test: content_type = 'java-test-resource' else: content_type = 'java-resource' else: content_type = '' sources = TemplateData( path=root_relative_path, package_prefix=source_set.path.replace('/', '.') if source_set.path else None, is_test=source_set.is_test, content_type=content_type ) return TemplateData( path=root_relative_path, sources=[sources], exclude_paths=[os.path.join(source_set.source_base, x) for x in source_set.excludes], )
def setUp(self): self.data = TemplateData(foo='bar', baz=42)
def generate_project(self, project): def create_content_root(source_set): root_relative_path = os.path.join(source_set.source_base, source_set.path) \ if source_set.path else source_set.source_base if self.get_options().infer_test_from_siblings: is_test = IdeaGen._sibling_is_test(source_set) else: is_test = source_set.is_test if source_set.resources_only: if source_set.is_test: content_type = 'java-test-resource' else: content_type = 'java-resource' else: content_type = '' sources = TemplateData( path=root_relative_path, package_prefix=source_set.path.replace('/', '.') if source_set.path else None, is_test=is_test, content_type=content_type ) return TemplateData( path=root_relative_path, sources=[sources], exclude_paths=[os.path.join(source_set.source_base, x) for x in source_set.excludes], ) content_roots = [create_content_root(source_set) for source_set in project.sources] if project.has_python: content_roots.extend(create_content_root(source_set) for source_set in project.py_sources) scala = None if project.has_scala: scala = TemplateData( language_level=self.scala_language_level, maximum_heap_size=self.scala_maximum_heap_size, fsc=self.fsc, compiler_classpath=project.scala_compiler_classpath ) exclude_folders = [] if self.get_options().exclude_maven_target: exclude_folders += IdeaGen._maven_targets_excludes(get_buildroot()) exclude_folders += self.get_options().exclude_folders java_language_level = None for target in project.targets: if isinstance(target, JvmTarget): if java_language_level is None or java_language_level < target.platform.source_level: java_language_level = target.platform.source_level if java_language_level is not None: java_language_level = 'JDK_{0}_{1}'.format(*java_language_level.components[:2]) configured_module = TemplateData( root_dir=get_buildroot(), path=self.module_filename, content_roots=content_roots, bash=self.bash, python=project.has_python, scala=scala, internal_jars=[cp_entry.jar for cp_entry in project.internal_jars], internal_source_jars=[cp_entry.source_jar for cp_entry in project.internal_jars if cp_entry.source_jar], external_jars=[cp_entry.jar for cp_entry in project.external_jars], external_javadoc_jars=[cp_entry.javadoc_jar for cp_entry in project.external_jars if cp_entry.javadoc_jar], external_source_jars=[cp_entry.source_jar for cp_entry in project.external_jars if cp_entry.source_jar], annotation_processing=self.annotation_processing_template, extra_components=[], exclude_folders=exclude_folders, java_language_level=java_language_level, ) outdir = os.path.abspath(self.intellij_output_dir) if not os.path.exists(outdir): os.makedirs(outdir) configured_project = TemplateData( root_dir=get_buildroot(), outdir=outdir, git_root=Git.detect_worktree(), modules=[configured_module], java=TemplateData( encoding=self.java_encoding, maximum_heap_size=self.java_maximum_heap_size, jdk=self.java_jdk, language_level='JDK_1_{}'.format(self.java_language_level) ), resource_extensions=list(project.resource_extensions), scala=scala, checkstyle_classpath=';'.join(project.checkstyle_classpath), debug_port=project.debug_port, annotation_processing=self.annotation_processing_template, extra_components=[], ) existing_project_components = None existing_module_components = None if not self.nomerge: # Grab the existing components, which may include customized ones. existing_project_components = self._parse_xml_component_elements(self.project_filename) existing_module_components = self._parse_xml_component_elements(self.module_filename) # Generate (without merging in any extra components). safe_mkdir(os.path.abspath(self.intellij_output_dir)) ipr = self._generate_to_tempfile( Generator(pkgutil.get_data(__name__, self.project_template), project=configured_project)) iml = self._generate_to_tempfile( Generator(pkgutil.get_data(__name__, self.module_template), module=configured_module)) if not self.nomerge: # Get the names of the components we generated, and then delete the # generated files. Clunky, but performance is not an issue, and this # is an easy way to get those component names from the templates. extra_project_components = self._get_components_to_merge(existing_project_components, ipr) extra_module_components = self._get_components_to_merge(existing_module_components, iml) os.remove(ipr) os.remove(iml) # Generate again, with the extra components. ipr = self._generate_to_tempfile(Generator(pkgutil.get_data(__name__, self.project_template), project=configured_project.extend(extra_components=extra_project_components))) iml = self._generate_to_tempfile(Generator(pkgutil.get_data(__name__, self.module_template), module=configured_module.extend(extra_components=extra_module_components))) self.context.log.info('Generated IntelliJ project in {directory}' .format(directory=self.gen_project_workdir)) shutil.move(ipr, self.project_filename) shutil.move(iml, self.module_filename) return self.project_filename if self.open else None
def generate_project(self, project): def is_test(source_set): # Non test targets that otherwise live in test target roots (say a java_library), must # be marked as test for IDEA to correctly link the targets with the test code that uses # them. Therefore we check the base instead of the is_test flag. return source_set.source_base in SourceSet.TEST_BASES def create_content_root(source_set): root_relative_path = os.path.join(source_set.source_base, source_set.path) \ if source_set.path else source_set.source_base sources = TemplateData( path=root_relative_path, package_prefix=source_set.path.replace('/', '.') if source_set.path else None, is_test=is_test(source_set) ) return TemplateData( path=root_relative_path, sources=[sources], exclude_paths=[os.path.join(source_set.source_base, x) for x in source_set.excludes], ) content_roots = [create_content_root(source_set) for source_set in project.sources] if project.has_python: content_roots.extend(create_content_root(source_set) for source_set in project.py_sources) scala = None if project.has_scala: scala = TemplateData( language_level=self.scala_language_level, maximum_heap_size=self.scala_maximum_heap_size, fsc=self.fsc, compiler_classpath=project.scala_compiler_classpath ) configured_module = TemplateData( root_dir=get_buildroot(), path=self.module_filename, content_roots=content_roots, bash=self.bash, python=project.has_python, scala=scala, internal_jars=[cp_entry.jar for cp_entry in project.internal_jars], internal_source_jars=[cp_entry.source_jar for cp_entry in project.internal_jars if cp_entry.source_jar], external_jars=[cp_entry.jar for cp_entry in project.external_jars], external_javadoc_jars=[cp_entry.javadoc_jar for cp_entry in project.external_jars if cp_entry.javadoc_jar], external_source_jars=[cp_entry.source_jar for cp_entry in project.external_jars if cp_entry.source_jar], extra_components=[], ) outdir = os.path.abspath(self.intellij_output_dir) if not os.path.exists(outdir): os.makedirs(outdir) configured_project = TemplateData( root_dir=get_buildroot(), outdir=outdir, modules=[ configured_module ], java=TemplateData( encoding=self.java_encoding, maximum_heap_size=self.java_maximum_heap_size, jdk=self.java_jdk, language_level = 'JDK_1_%d' % self.java_language_level ), resource_extensions=list(project.resource_extensions), scala=scala, checkstyle_suppression_files=','.join(project.checkstyle_suppression_files), checkstyle_classpath=';'.join(project.checkstyle_classpath), debug_port=project.debug_port, extra_components=[], ) existing_project_components = None existing_module_components = None if not self.nomerge: # Grab the existing components, which may include customized ones. existing_project_components = self._parse_xml_component_elements(self.project_filename) existing_module_components = self._parse_xml_component_elements(self.module_filename) # Generate (without merging in any extra components). safe_mkdir(os.path.abspath(self.intellij_output_dir)) ipr = self._generate_to_tempfile( Generator(pkgutil.get_data(__name__, self.project_template), project = configured_project)) iml = self._generate_to_tempfile( Generator(pkgutil.get_data(__name__, self.module_template), module = configured_module)) if not self.nomerge: # Get the names of the components we generated, and then delete the # generated files. Clunky, but performance is not an issue, and this # is an easy way to get those component names from the templates. extra_project_components = self._get_components_to_merge(existing_project_components, ipr) extra_module_components = self._get_components_to_merge(existing_module_components, iml) os.remove(ipr) os.remove(iml) # Generate again, with the extra components. ipr = self._generate_to_tempfile(Generator(pkgutil.get_data(__name__, self.project_template), project = configured_project.extend(extra_components = extra_project_components))) iml = self._generate_to_tempfile(Generator(pkgutil.get_data(__name__, self.module_template), module = configured_module.extend(extra_components = extra_module_components))) shutil.move(ipr, self.project_filename) shutil.move(iml, self.module_filename) print('\nGenerated project at %s%s' % (self.gen_project_workdir, os.sep)) return self.project_filename if self.open else None