diff --git a/CHANGELOG b/CHANGELOG index 35a38123e96..1015426b0e5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,12 @@ +v2024.11.05.0.2 +=============== +Fixes: +* Don't require rules_java and rules_python for bazel 7 and older (#7052) +* Fix issues with aspect templates not available in query sync mode (#7048) +* Support aspect template for Python (#7011) +* Properly support non-Java Bazel 8 projects in IntelliJ (#7006) +* Fixed Java enabled condition in SyncAspectTemplateProvider (#6987) + v2024.11.05 =========== Features: diff --git a/aspect/intellij_info_impl.bzl b/aspect/intellij_info_impl.bzl index 6dc96ace39d..e8553042c4c 100644 --- a/aspect/intellij_info_impl.bzl +++ b/aspect/intellij_info_impl.bzl @@ -17,6 +17,8 @@ load(":flag_hack.bzl", "FlagHackInfo") load("@intellij_aspect_template//:java_info.bzl", "get_java_info", "java_info_in_target", "java_info_reference") +load("@intellij_aspect_template//:python_info.bzl", "get_py_info", "py_info_in_target") + load("@intellij_aspect_template//:code_generator_info.bzl", "CODE_GENERATOR_RULE_NAMES") load( @@ -341,7 +343,7 @@ def _do_starlark_string_expansion(ctx, name, strings, extra_targets = []): def collect_py_info(target, ctx, semantics, ide_info, ide_info_file, output_groups): """Updates Python-specific output groups, returns false if not a Python target.""" - if not PyInfo in target or _is_language_specific_proto_library(ctx, target, semantics): + if not py_info_in_target(target) or _is_language_specific_proto_library(ctx, target, semantics): return False py_semantics = getattr(semantics, "py", None) @@ -351,7 +353,7 @@ def collect_py_info(target, ctx, semantics, ide_info, ide_info_file, output_grou py_launcher = None sources = sources_from_target(ctx) - to_build = target[PyInfo].transitive_sources + to_build = get_py_info(target).transitive_sources args = getattr(ctx.rule.attr, "args", []) data_deps = getattr(ctx.rule.attr, "data", []) args = _do_starlark_string_expansion(ctx, "args", args, data_deps) @@ -397,14 +399,14 @@ def collect_py_info(target, ctx, semantics, ide_info, ide_info_file, output_grou def provider_imports_to_attr_imports(): result = [] - for provider_import in target[PyInfo].imports.to_list(): + for provider_import in get_py_info(target).imports.to_list(): attr_import = provider_import_to_attr_import(provider_import) if attr_import: result.append(attr_import) return result - if target[PyInfo].imports: + if get_py_info(target).imports: imports.extend(provider_imports_to_attr_imports()) runfiles = target[DefaultInfo].default_runfiles diff --git a/aspect_template/BUILD b/aspect_template/BUILD index f1c83c2daf0..0ce268dbb73 100644 --- a/aspect_template/BUILD +++ b/aspect_template/BUILD @@ -7,6 +7,8 @@ filegroup( "code_generator_info.template.bzl", "java_info.bzl", "java_info.template.bzl", + "python_info.bzl", + "python_info.template.bzl" ], visibility = ["//visibility:public"], ) @@ -23,6 +25,13 @@ genrule( cmd = STRIP_TEMPLATE_SCRIPT, ) +genrule( + name = "generate_py_info_template", + srcs = ["python_info.bzl"], + outs = ["python_info.template.bzl"], + cmd = STRIP_TEMPLATE_SCRIPT, +) + genrule( name = "generate_code_generator_info_template", srcs = ["code_generator_info.bzl"], diff --git a/aspect_template/python_info.bzl b/aspect_template/python_info.bzl new file mode 100644 index 00000000000..90aaca19d3d --- /dev/null +++ b/aspect_template/python_info.bzl @@ -0,0 +1,37 @@ +# TEMPLATE-INCLUDE-BEGIN +###if( $isPythonEnabled == "true" && $bazel8OrAbove == "true" ) +##load("@rules_python//python:defs.bzl", "PyInfo") +###end +# TEMPLATE-INCLUDE-END + +def py_info_in_target(target): +# TEMPLATE-IGNORE-BEGIN + return PyInfo in target +# TEMPLATE-IGNORE-END + +# TEMPLATE-INCLUDE-BEGIN +## #if( $isPythonEnabled == "true" ) +## return PyInfo in target +## #else +## return None +## #end +# TEMPLATE-INCLUDE-END + +def get_py_info(target): +# TEMPLATE-IGNORE-BEGIN + if PyInfo in target: + return target[PyInfo] + else: + return None +# TEMPLATE-IGNORE-END + +# TEMPLATE-INCLUDE-BEGIN +## #if( $isPythonEnabled == "true" ) +## if PyInfo in target: +## return target[PyInfo] +## else: +## return None +## #else +## return None +## #end +# TEMPLATE-INCLUDE-END \ No newline at end of file diff --git a/base/src/com/google/idea/blaze/base/sync/aspects/strategy/SyncAspectTemplateProvider.java b/base/src/com/google/idea/blaze/base/sync/aspects/strategy/SyncAspectTemplateProvider.java index 87933b32264..49154a64c78 100644 --- a/base/src/com/google/idea/blaze/base/sync/aspects/strategy/SyncAspectTemplateProvider.java +++ b/base/src/com/google/idea/blaze/base/sync/aspects/strategy/SyncAspectTemplateProvider.java @@ -46,6 +46,8 @@ public class SyncAspectTemplateProvider implements SyncListener { private final static String TEMPLATE_JAVA = "java_info.template.bzl"; private final static String REALIZED_JAVA = "java_info.bzl"; + private final static String TEMPLATE_PYTHON = "python_info.template.bzl"; + private final static String REALIZED_PYTHON = "python_info.bzl"; private final static String TEMPLATE_CODE_GENERATOR = "code_generator_info.template.bzl"; private final static String REALIZED_CODE_GENERATOR = "code_generator_info.bzl"; @@ -54,6 +56,15 @@ public void onSyncStart(Project project, BlazeContext context, SyncMode syncMode prepareProjectAspect(project); } + @Override + public void onQuerySyncStart(Project project, BlazeContext context) { + try { + prepareProjectAspect(project); + } catch (SyncFailedException e) { + throw new RuntimeException(e); + } + } + private void prepareProjectAspect(Project project) throws SyncFailedException { var manager = BlazeProjectDataManager.getInstance(project); @@ -77,7 +88,7 @@ private void prepareProjectAspect(Project project) throws SyncFailedException { final var templateAspects = AspectRepositoryProvider.findAspectTemplateDirectory() .orElseThrow(() -> new SyncFailedException("Couldn't find aspect template directory")); - writeJavaInfo(manager, realizedAspectsPath, templateAspects); + writeLanguageInfos(manager, realizedAspectsPath, templateAspects, project); writeCodeGeneratorInfo(manager, project, realizedAspectsPath, templateAspects); } @@ -105,26 +116,46 @@ private void writeCodeGeneratorInfo( } } - private void writeJavaInfo( - BlazeProjectDataManager manager, - Path realizedAspectsPath, - File templateAspects) throws SyncFailedException { - var realizedFile = realizedAspectsPath.resolve(REALIZED_JAVA); + private void writeLanguageInfos( + BlazeProjectDataManager manager, + Path realizedAspectsPath, + File templateAspects, + Project project) throws SyncFailedException { + var templateLanguageStringMap = getLanguageStringMap(manager); + writeLanguageInfo(manager, realizedAspectsPath, templateAspects, TEMPLATE_JAVA, REALIZED_JAVA, templateLanguageStringMap); + writeLanguageInfo(manager, realizedAspectsPath, templateAspects, TEMPLATE_PYTHON, REALIZED_PYTHON, templateLanguageStringMap); + } + + private void writeLanguageInfo( + BlazeProjectDataManager manager, + Path realizedAspectsPath, + File templateAspects, + String templateFileName, + String realizedFileName, + Map templateLanguageStringMap) throws SyncFailedException { + var realizedFile = realizedAspectsPath.resolve(realizedFileName); var templateWriter = new TemplateWriter(templateAspects.toPath()); - var templateVariableMap = getJavaStringStringMap(manager); - if (!templateWriter.writeToFile(TEMPLATE_JAVA, realizedFile, templateVariableMap)) { - throw new SyncFailedException("Could not create template for: " + REALIZED_JAVA); + if (!templateWriter.writeToFile(templateFileName, realizedFile, templateLanguageStringMap)) { + throw new SyncFailedException("Could not create template for: " + realizedFileName); } } - private static @NotNull Map getJavaStringStringMap(BlazeProjectDataManager manager) { - var projectData = Optional.ofNullable(manager.getBlazeProjectData()); // It can be empty on intial sync. Fall back to no lauguage support + private static @NotNull Map getLanguageStringMap(BlazeProjectDataManager manager) { + var projectData = Optional.ofNullable(manager.getBlazeProjectData()); // It can be empty on intial sync. Fall back to no language support var activeLanguages = projectData.map(it -> it.getWorkspaceLanguageSettings().getActiveLanguages()).orElse(ImmutableSet.of()); + // TODO: adapt the logic to query sync + boolean isQuerySync = projectData.map(BlazeProjectData::isQuerySync).orElse(false); + var externalWorkspaceData = isQuerySync ? null : projectData.map(BlazeProjectData::getExternalWorkspaceData).orElse(null); var isAtLeastBazel8 = projectData.map(it -> it.getBlazeVersionData().bazelIsAtLeastVersion(8, 0, 0)).orElse(false); - return Map.of( - "bazel8OrAbove", isAtLeastBazel8 ? "true" : "false", - "isJavaEnabled", activeLanguages.contains(LanguageClass.JAVA) || activeLanguages.contains(LanguageClass.GENERIC) ? "true" : "false" - ); + var isJavaEnabled = activeLanguages.contains(LanguageClass.JAVA) && + (isQuerySync || (externalWorkspaceData != null && (!isAtLeastBazel8 || externalWorkspaceData.getByRepoName("rules_java") != null))); + var isPythonEnabled = activeLanguages.contains(LanguageClass.PYTHON) && + (isQuerySync || (externalWorkspaceData != null && (!isAtLeastBazel8 || externalWorkspaceData.getByRepoName("rules_python") != null))); + return Map.of( + "bazel8OrAbove", isAtLeastBazel8 ? "true" : "false", + "isJavaEnabled", isJavaEnabled ? "true" : "false", + "isPythonEnabled", isPythonEnabled ? "true" : "false" + ); } private static List ruleNamesForLanguageClass(LanguageClass languageClass, ProjectViewSet viewSet) {