Skip to content

Commit 00c500e

Browse files
authored
Merge pull request #7 from stackb/pcj/fix-external-module-names
fix: external module names
2 parents 5220aff + 2ac058e commit 00c500e

File tree

4 files changed

+140
-30
lines changed

4 files changed

+140
-30
lines changed

rules/defs.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
load("//rules/private:closure_ts_compile.bzl", _closure_ts_compile = "closure_ts_compile")
2+
load("//rules/private:closure_ts_archive.bzl", _closure_ts_archive = "closure_ts_archive")
23

34
closure_ts_compile = _closure_ts_compile
5+
closure_ts_archive = _closure_ts_archive
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
"""closure_ts_archive builds zip files of closure js sources"""
2+
3+
load(":closure_ts_compile.bzl", "ClosureTsCompileInfo")
4+
5+
def _get_zip_runfiles_path(path):
6+
if path.startswith("../"):
7+
parts = path.split("/")
8+
path = "/".join(parts[2:])
9+
return path
10+
11+
def _zip_action(ctx):
12+
srcs = ctx.files.srcs
13+
14+
transitive_outs = [dep[ClosureTsCompileInfo].transitive_outs for dep in ctx.attr.deps]
15+
direct_outs = [dep[ClosureTsCompileInfo].direct_outs for dep in ctx.attr.deps]
16+
if ctx.attr.transitive:
17+
inputs = depset(srcs, transitive = transitive_outs)
18+
else:
19+
inputs = depset(srcs, transitive = direct_outs)
20+
21+
def map_zip_runfiles(file):
22+
return "{}={}".format(
23+
_get_zip_runfiles_path(file.short_path),
24+
file.path,
25+
)
26+
27+
manifest = ctx.actions.args()
28+
manifest.use_param_file("@%s", use_always = True)
29+
manifest.set_param_file_format("multiline")
30+
manifest.add_all(inputs, map_each = map_zip_runfiles, allow_closure = True)
31+
32+
zip_cli_args = ctx.actions.args()
33+
zip_cli_args.add("cC")
34+
zip_cli_args.add(ctx.outputs.zip)
35+
36+
ctx.actions.run(
37+
executable = ctx.executable._zipper,
38+
arguments = [zip_cli_args, manifest],
39+
inputs = inputs,
40+
outputs = [ctx.outputs.zip],
41+
use_default_shell_env = True,
42+
mnemonic = "ClosureTsZip",
43+
progress_message = "Building zip: %{label}",
44+
)
45+
46+
def _closure_ts_archive_impl(ctx):
47+
_zip_action(ctx)
48+
49+
return [
50+
DefaultInfo(
51+
files = depset([ctx.outputs.zip]),
52+
),
53+
]
54+
55+
closure_ts_archive = rule(
56+
implementation = _closure_ts_archive_impl,
57+
attrs = {
58+
"srcs": attr.label_list(
59+
doc = "additional sources to add to the archive",
60+
allow_files = True,
61+
),
62+
"deps": attr.label_list(
63+
doc = "closure ts compile dependencies to archive",
64+
providers = [ClosureTsCompileInfo],
65+
),
66+
"transitive": attr.bool(
67+
doc = "archive transitive dependencies into a single archive",
68+
),
69+
"_zipper": attr.label(
70+
cfg = "exec",
71+
executable = True,
72+
default = "@bazel_tools//tools/zip:zipper",
73+
),
74+
},
75+
outputs = {
76+
"zip": "%{name}.js.zip",
77+
},
78+
)

rules/private/closure_ts_compile.bzl

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
load("@bazel_skylib//lib:paths.bzl", "paths")
44

55
ClosureTsCompileInfo = provider(doc = "info about a closure ts compile rule", fields = {
6-
"sources": "DepSet<File>: direct + transitive sources",
6+
"direct_srcs": "DepSet<File>: direct sources",
7+
"transitive_srcs": "DepSet<File>: transitive sources",
8+
"direct_outs": "DepSet<File>: direct outputs",
9+
"transitive_outs": "DepSet<File>: transitive outputs",
710
})
811

912
def _output_for_ts_input(ctx, src):
@@ -13,58 +16,54 @@ def _output_for_ts_input(ctx, src):
1316
def _output_for_externs(ctx):
1417
return ctx.actions.declare_file(ctx.label.name + ".externs.js")
1518

16-
def _tsickle_action(ctx):
17-
direct = ctx.files.srcs
18-
transitive = [dep[ClosureTsCompileInfo].sources for dep in ctx.attr.deps]
19+
def _closure_ts_compile_impl(ctx):
20+
direct_srcs = ctx.files.srcs
21+
transitive_srcs = [dep[ClosureTsCompileInfo].transitive_srcs for dep in ctx.attr.deps]
22+
transitive_outs = [dep[ClosureTsCompileInfo].transitive_outs for dep in ctx.attr.deps]
1923

2024
args = ctx.actions.args()
21-
args.add_all([src.short_path for src in direct])
25+
args.add_all(direct_srcs)
2226

2327
env = {
2428
"BAZEL_BINDIR": ctx.bin_dir.path,
25-
"BAZEL_WORKSPACE": ctx.label.workspace_name,
2629
"BAZEL_PACKAGE": ctx.label.package,
2730
}
2831

2932
direct_ts = []
3033
direct_dts = []
31-
for src in direct:
34+
for src in direct_srcs:
3235
if src.basename.endswith(".d.ts"):
3336
direct_dts.append(src)
3437
else:
3538
direct_ts.append(src)
3639

37-
outputs = [_output_for_ts_input(ctx, f) for f in direct_ts]
40+
direct_outs = [_output_for_ts_input(ctx, f) for f in direct_ts]
3841
if len(direct_dts) > 0:
3942
externs_output = _output_for_externs(ctx)
40-
outputs.append(externs_output)
41-
env["EXTERNS_PATH"] = externs_output.short_path
43+
direct_outs.append(externs_output)
44+
env["EXTERNS_PATH"] = externs_output.short_path.replace("../", "external/")
4245

43-
inputs = depset(direct = direct, transitive = transitive)
46+
all_srcs = depset(direct = direct_srcs, transitive = transitive_srcs)
47+
all_outs = depset(direct = direct_outs, transitive = transitive_outs)
4448

4549
ctx.actions.run(
4650
mnemonic = "TsickleCompile",
4751
executable = ctx.executable._compiler,
4852
arguments = [args],
49-
inputs = inputs,
50-
outputs = outputs,
53+
inputs = all_srcs,
54+
outputs = direct_outs,
5155
env = env,
5256
)
5357

54-
return struct(
55-
inputs = inputs,
56-
outputs = outputs,
57-
)
58-
59-
def _closure_ts_compile_impl(ctx):
60-
result = _tsickle_action(ctx)
61-
6258
return [
6359
DefaultInfo(
64-
files = depset(result.outputs),
60+
files = depset(direct_outs),
6561
),
6662
ClosureTsCompileInfo(
67-
sources = result.inputs,
63+
direct_srcs = direct_srcs,
64+
transitive_srcs = all_srcs,
65+
direct_outs = depset(direct_outs),
66+
transitive_outs = all_outs,
6867
),
6968
]
7069

tools/tsicklecompiler/index.ts

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,35 @@ function getTsCompilerOptions(): ts.CompilerOptions {
5353
};
5454
}
5555

56+
/**
57+
* stripExternalName is used to remove external workspace identifiers from bazel
58+
* paths. This allows the filenames
59+
* BAZEL_BIN/external/io_bazel_rules_closure+/google3/third_party/javascript/safevalues/builders/html_sanitizer/sanitizer_table/sanitizer_table.js
60+
* and
61+
* BAZEL_BIN/google3/third_party/javascript/safevalues/builders/html_sanitizer/sanitizer_table/sanitizer_table.js
62+
* to generate the same moduleName.
63+
*
64+
* @param moduleName the module name to strip
65+
* @returns
66+
*/
67+
function stripExternalName(moduleName: string): string {
68+
if (!moduleName.startsWith('external.')) {
69+
return moduleName;
70+
}
71+
const parts = moduleName.split('.');
72+
if (parts.length <= 2) {
73+
return moduleName;
74+
}
75+
return parts.slice(2).join('.');
76+
}
77+
5678
function run(
5779
options: ts.CompilerOptions,
5880
fileNames: string[],
5981
writeFile: ts.WriteFileCallback,
6082
): tsickle.EmitResult {
61-
// Use absolute paths to determine what files to process since files may be imported using
62-
// relative or absolute paths
83+
// Use absolute paths to determine what files to process since files may be
84+
// imported using relative or absolute paths
6385
fileNames = fileNames.map(i => path.resolve(i));
6486

6587
const compilerHost = ts.createCompilerHost(options);
@@ -73,9 +95,20 @@ function run(
7395
return !filesToProcess.has(path.resolve(fileName));
7496
},
7597
shouldIgnoreWarningsForPath: (fileName: string) => false,
76-
pathToModuleName: (context, fileName) =>
77-
tsickle.pathToModuleName(rootModulePath, context, fileName),
78-
fileNameToModuleId: (fileName) => path.relative(rootModulePath, fileName),
98+
pathToModuleName: (context, fileName) => {
99+
const moduleName = stripExternalName(tsickle.pathToModuleName(rootModulePath, context, fileName));
100+
if (DEBUG) {
101+
console.log(`pathToModuleName: ${fileName} => ${moduleName}`);
102+
}
103+
return moduleName;
104+
},
105+
fileNameToModuleId: (fileName) => {
106+
const moduleId = path.relative(rootModulePath, fileName);
107+
if (DEBUG) {
108+
console.log(`fileNameToModuleId: ${fileName} => ${moduleId}`);
109+
}
110+
return moduleId;
111+
},
79112
googmodule: true,
80113
transformDecorators: true,
81114
transformTypesToClosure: true,
@@ -109,8 +142,6 @@ async function main() {
109142
const execRoot = getExecRoot();
110143
const externsPath = getExternsPath();
111144

112-
await listExecrootFiles();
113-
114145
const args = process.argv.slice(2);
115146
const inputFiles = getInputFiles(execRoot, args);
116147
if (inputFiles.length === 0) {

0 commit comments

Comments
 (0)