IJI-3418 build scripts: Bazel: watch for the entire JPS project model to correctly re-run generator on any change

GitOrigin-RevId: 29171ca937e5ec4bf7bee4b9597ebf26b08d83cc
This commit is contained in:
Leonid Shalupov
2026-01-05 02:37:39 +00:00
committed by intellij-monorepo-bot
parent 3e4eb1d7dc
commit 8ee8c401b3
3 changed files with 47 additions and 6 deletions
+1 -1
View File
@@ -325,7 +325,7 @@
},
"//build:jps_dynamic_deps_community.bzl%jps_dynamic_deps_community_extension": {
"general": {
"bzlTransitiveDigest": "3xhuyu/RwZY46XM2F9PzxVuqXwuOnK9XPrCPpt/gKTI=",
"bzlTransitiveDigest": "3CitlyO8eztna/EextdwgGkMSx42lDg2RITKuKTLH0U=",
"usagesDigest": "OSsQY2hkpxdAkgfVzTh+Q1KLtzAuQDVI0/8sRki7FfU=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
+4 -5
View File
@@ -36,6 +36,8 @@ STALENESS & WATCHING:
This repository is invalidated on changes to `.idea/modules.xml` via ctx.watch().
"""
load(":jps_model.bzl", "watch_project_model_files")
def _format_target_list(name, targets):
"""Format a list of targets as a Starlark list assignment."""
if not targets:
@@ -60,11 +62,8 @@ def _targets_repo_impl(ctx):
# SETUP CONTEXT AND WATCHER
root = ctx.path(Label("@community//:MODULE.bazel")).dirname
# we set watcher on .idea/modules.xml, because we only need to regenerate targets' list if a new module was added
# otherwise the list get populated on import and bazel clean invalidates it anyway
idea_dir = root.get_child(".idea")
modules_xml = idea_dir.get_child("modules.xml")
ctx.watch(modules_xml)
# Watch the entire model to re-run generator on changes
watch_project_model_files(ctx, root)
script = (
root
+42
View File
@@ -0,0 +1,42 @@
def _parse_project_relative_module_paths_strict(modules_xml_text):
marker = 'filepath="'
prefix = "$PROJECT_DIR$/"
rels = []
i = 0
# Upper bound: you can't have more attributes than characters.
for _ in range(len(modules_xml_text) + 1):
j = modules_xml_text.find(marker, i)
if j == -1:
break
j += len(marker)
k = modules_xml_text.find('"', j)
if k == -1:
fail("Malformed XML: unterminated filepath attribute (missing closing quote)")
full = modules_xml_text[j:k]
if not full.startswith(prefix):
fail("Unexpected module filepath (expected to start with %r): %r" % (prefix, full))
rels.append(full[len(prefix):])
i = k + 1
if not rels:
fail("No module filepaths found")
return rels
def watch_project_model_files(ctx, project_root):
idea_dir = project_root.get_child(".idea")
modules_xml = idea_dir.get_child("modules.xml")
# Read (to make sure it exists) and watch all modules to re-run generator on changes
for relativeModulePath in _parse_project_relative_module_paths_strict(ctx.read(modules_xml, watch='yes')):
ctx.read(project_root.get_child(relativeModulePath), watch='yes')
# Read (to make sure it exists) and watch all libraries under .idea/libraries to re-run generator on changes
libraries_dir = idea_dir.get_child("libraries")
for library_xml in libraries_dir.readdir(watch='yes'):
ctx.read(library_xml, watch='yes')