intellij/indexing.bzl (198 lines of code) (raw):
load("@bazel_skylib//lib:paths.bzl", "paths")
IntellijIndexInfo = provider(
doc = "Information about intellij target indexes",
fields = {
"ijx": "index file",
"metadata": "metadata json file",
"sha256": "sha sum"
},
)
IntellijTransitiveIndexInfo = provider(
doc = "Transitive information about intellij target indexes",
fields = {
"index": "IntellijIndexInfo",
"transitive": "transitive IntellijIndexInfo",
},
)
def _map_path(x):
return x.path
def _stringify_label(l):
result = str(l)
if result.startswith("@"):
return result[1:]
return result
def _stringify_name(n):
return n.replace("/", "_")
def _create_worker_defs(ctx, intellij, intellij_project, java_runtime):
env = {}
if hasattr(ctx.attr, "_debug_log"):
env["INTELLIJ_WORKER_DEBUG"] = ctx.attr._debug_log
worker_args = ctx.actions.args()
worker_args.add_all("--project_dir", [ intellij_project.project_dir ])
tools = []
tools += intellij_project.project_files
if hasattr(ctx.attr, "_debug_endpoint"):
worker_args.add_all("--debug_endpoint", [ ctx.attr._debug_endpoint ])
elif hasattr(ctx.attr, "_debug_domain_socket"):
worker_args.add_all("--debug_domain_socket", [ ctx.attr._debug_domain_socket ])
else:
worker_args.add_all("--java_binary", [ java_runtime.java_executable_exec_path ])
worker_args.add_all("--ide_home_dir", [ intellij.home_directory ])
worker_args.add_all("--ide_binary", [ intellij.binary.files_to_run.executable.path ])
worker_args.add_all("--plugins_directory", [ paths.dirname(intellij.plugins[0].path) ])
tools += intellij.binary.default_runfiles.files.to_list()
tools += [
intellij.binary.files_to_run.executable,
intellij.binary.files_to_run.runfiles_manifest,
]
tools += intellij.files
tools += intellij.plugins
return struct(
tools = tools,
args = [ worker_args ],
env = env,
)
def _create_indexing_defs(ctx, inputs):
name = _stringify_name(ctx.rule.attr.name)
info = IntellijIndexInfo(
ijx = ctx.actions.declare_file("%s.ijx" % name),
metadata = ctx.actions.declare_file("%s.ijx.metadata.json" % name),
sha256 = ctx.actions.declare_file("%s.ijx.sha256" % name),
)
args_file = ctx.actions.declare_file(ctx.rule.attr.name + "_args_file")
indexing_args = ctx.actions.args()
indexing_args.add_all("--out_dir", [ paths.dirname(info.ijx.path) ])
indexing_args.add_all("--target", [ _stringify_label(ctx.label) ])
indexing_args.add_all("--name", [ name ])
indexing_args.add_all(inputs, map_each=_map_path, before_each="-s")
ctx.actions.write(
output = args_file,
content = indexing_args,
)
return struct(
info = info,
args_file = args_file,
inputs = inputs + [ args_file ],
outputs = [
info.ijx,
info.metadata,
info.sha256,
],
)
def _run_indexing(ctx, intellij, intellij_project, java_runtime, inputs):
worker_defs = _create_worker_defs(ctx, intellij, intellij_project, java_runtime)
indexing_defs = _create_indexing_defs(ctx, inputs)
ctx.actions.run(
mnemonic = "IntellijIndexing",
executable = ctx.executable._worker,
tools = worker_defs.tools,
inputs = indexing_defs.inputs,
outputs = indexing_defs.outputs,
env = worker_defs.env,
execution_requirements = {
"worker-key-mnemonic": "IntellijIndexing",
"supports-multiplex-workers": "1",
"requires-worker-protocol": "proto",
},
arguments = worker_defs.args + ["@" + indexing_defs.args_file.path],
)
return indexing_defs.info
def _collect_sources_to_index(ctx):
to_index = []
if hasattr(ctx.rule.attr, "srcs"):
for src in ctx.rule.attr.srcs:
to_index.append(src.files)
return depset(transitive = to_index).to_list()
def _collect_transitive_index_infos(deps):
cur = []
transitive = []
for dep in deps:
if not IntellijTransitiveIndexInfo in dep:
continue
index_info = dep[IntellijTransitiveIndexInfo]
cur.append(index_info.index)
transitive.append(index_info.transitive)
return depset(cur, transitive = transitive)
def _indexing_aspect_impl(target, ctx):
indexed = _run_indexing(
ctx = ctx,
intellij = ctx.toolchains["@rules_intellij//intellij:intellij_toolchain_type"].intellij,
intellij_project = ctx.toolchains["@rules_intellij//intellij:intellij_project_toolchain_type"].intellij_project,
java_runtime = ctx.toolchains["@bazel_tools//tools/jdk:runtime_toolchain_type"].java_runtime,
inputs = _collect_sources_to_index(ctx),
)
return [
IntellijTransitiveIndexInfo(
index = indexed,
transitive = _collect_transitive_index_infos(
ctx.rule.attr.deps if hasattr(ctx.rule.attr, "deps") else []
),
),
OutputGroupInfo(indexed_files = depset([
indexed.ijx,
indexed.metadata,
indexed.sha256,
])),
]
_indexing_aspect = aspect(
implementation = _indexing_aspect_impl,
attr_aspects = ["deps"],
attrs = {
"_worker": attr.label(
default = "@rules_intellij//src/main/kotlin/rules_intellij/worker",
executable = True,
cfg = "exec",
),
# "_debug_log": attr.string(default = "/tmp/intellij_debug"),
# "_debug_domain_socket": attr.string(default = "/tmp/test.sock"),
# "_debug_endpoint": attr.string(default = "127.0.0.1:9000"),
},
toolchains = [
"@rules_intellij//intellij:intellij_project_toolchain_type",
"@rules_intellij//intellij:intellij_toolchain_type",
"@bazel_tools//tools/jdk:runtime_toolchain_type",
],
)
def _generate_indexes_impl(ctx):
index_infos = _collect_transitive_index_infos(ctx.attr.deps).to_list()
all_indexed_files = []
all_ijx_files = []
for indexed in index_infos:
all_indexed_files += [
indexed.ijx,
indexed.metadata,
indexed.sha256,
]
all_ijx_files.append(indexed.ijx)
out_json = ctx.actions.declare_file("%s.json" % ctx.attr.name)
ctx.actions.write(
out_json,
json.encode({
"shared-indexes": [ x.path for x in all_ijx_files]
}),
)
return [
DefaultInfo(
files = depset([out_json]),
runfiles = ctx.runfiles(files = [out_json] + all_ijx_files),
),
OutputGroupInfo(
indexed_files = depset(all_indexed_files)
),
]
_generate_indexes = rule(
implementation = _generate_indexes_impl,
attrs = {
"deps": attr.label_list(
allow_empty = False,
mandatory = True,
aspects = [ _indexing_aspect ],
providers = [ IntellijTransitiveIndexInfo ],
),
},
)
def generate_indexes(name, deps):
_generate_indexes(
name = name,
deps = deps,
)