Skip to content

Commit cfa47a6

Browse files
authored
Merge pull request #14677 from github/criemen/js-bazel
JS: Move the language pack build and tests to Bazel
2 parents db045e0 + b4ec132 commit cfa47a6

22 files changed

+249
-7
lines changed

javascript/BUILD.bazel

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
load("@//:dist.bzl", "dist")
2+
load("@rules_pkg//pkg:mappings.bzl", "pkg_files")
3+
load("@//buildutils-internal:zipmerge.bzl", "zipmerge")
4+
15
package(default_visibility = ["//visibility:public"])
26

37
alias(
@@ -9,3 +13,36 @@ alias(
913
name = "dbscheme-stats",
1014
actual = "//javascript/ql/lib:dbscheme-stats",
1115
)
16+
17+
pkg_files(
18+
name = "dbscheme-group",
19+
srcs = [
20+
":dbscheme",
21+
":dbscheme-stats",
22+
],
23+
strip_prefix = None,
24+
)
25+
26+
dist(
27+
name = "javascript-extractor-pack",
28+
srcs = [
29+
":dbscheme-group",
30+
"//javascript/downgrades",
31+
"//javascript/externs",
32+
"//javascript/extractor:tools-extractor",
33+
"@//language-packs/javascript:resources",
34+
],
35+
prefix = "javascript",
36+
)
37+
38+
# We have to zipmerge in the typescript parser wrapper, as it's generated by a genrule
39+
# and we don't know a list of its output files. Therefore, we sidestep the
40+
# rules_pkg tooling here, and generate the zip for the language pack manually.
41+
zipmerge(
42+
name = "javascript",
43+
srcs = [
44+
":javascript-extractor-pack.zip",
45+
"//javascript/extractor/lib/typescript",
46+
],
47+
out = "javascript.zip",
48+
)

javascript/downgrades/BUILD.bazel

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
load("@//:dist.bzl", "pack_zip")
2+
3+
pack_zip(
4+
name = "downgrades",
5+
srcs = glob(
6+
["**/*"],
7+
exclude = ["BUILD.bazel"],
8+
),
9+
prefix = "downgrades",
10+
visibility = ["//visibility:public"],
11+
)

javascript/externs/BUILD.bazel

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
load("@//:dist.bzl", "pack_zip")
2+
3+
pack_zip(
4+
name = "externs",
5+
srcs = glob(
6+
["**/*"],
7+
exclude = ["BUILD.bazel"],
8+
),
9+
prefix = "tools/data/externs",
10+
visibility = ["//visibility:public"],
11+
)

javascript/extractor/BUILD.bazel

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,63 @@
1-
load("@//:common.bzl", "codeql_java_project")
1+
load("@//:common.bzl", "codeql_fat_jar", "codeql_java_project")
2+
load("@rules_pkg//pkg:mappings.bzl", "pkg_files")
3+
4+
java_library(
5+
name = "deps",
6+
visibility = [":__subpackages__"],
7+
exports = [
8+
"@//extractor:html",
9+
"@//extractor:yaml",
10+
"@//resources/lib/java:commons-compress",
11+
"@//resources/lib/java:gson",
12+
"@//resources/lib/java:jericho-html",
13+
"@//resources/lib/java:slf4j-api",
14+
"@//resources/lib/java:snakeyaml",
15+
"@//third_party:jackson",
16+
"@//third_party:logback",
17+
"@//util-java7",
18+
"@//util-java8",
19+
],
20+
)
221

322
codeql_java_project(
423
name = "extractor",
524
deps = [
6-
"@//extractor",
25+
":deps",
26+
],
27+
)
28+
29+
pkg_files(
30+
name = "javascript-extractor-resources",
31+
srcs = glob(["resources/**"]),
32+
strip_prefix = "resources",
33+
)
34+
35+
codeql_fat_jar(
36+
name = "extractor-javascript",
37+
srcs = [
38+
":extractor",
39+
"@//extractor:html",
40+
"@//extractor:xml-trap-writer",
41+
"@//extractor:yaml",
742
"@//resources/lib/java:commons-compress",
843
"@//resources/lib/java:gson",
944
"@//resources/lib/java:jericho-html",
1045
"@//resources/lib/java:slf4j-api",
1146
"@//resources/lib/java:snakeyaml",
12-
"@//resources/lib/java/DO_NOT_DISTRIBUTE:junit",
1347
"@//third_party:jackson",
1448
"@//third_party:logback",
1549
"@//util-java7",
1650
"@//util-java8",
1751
],
52+
files = [":javascript-extractor-resources"],
53+
main_class = "com.semmle.js.extractor.Main",
54+
)
55+
56+
pkg_files(
57+
name = "tools-extractor",
58+
srcs = [
59+
":extractor-javascript",
60+
],
61+
prefix = "tools",
62+
visibility = ["//visibility:public"],
1863
)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
load("@//:common.bzl", "on_windows")
2+
3+
# Builds a zip file of the compiled typscript-parser-wrapper and its dependencies.
4+
genrule(
5+
name = "typescript",
6+
srcs = [
7+
"tsconfig.json",
8+
"package.json",
9+
"package-lock.json",
10+
] + glob(["src/**"]),
11+
outs = ["javascript.zip"],
12+
cmd = "\n".join([
13+
# the original working directory is not preserved anywhere, but needs to be accessible, as
14+
# all paths are relative to this
15+
# unfortunately, we need to change the working directory to run npm.
16+
"export BAZEL_ROOT=$$(pwd)",
17+
# we need a temp dir, and unfortunately, $TMPDIR is not set on Windows
18+
"export TEMP=$$(mktemp -d)",
19+
# Add node to the path so that npm run can find it - it's calling env node
20+
"export PATH=$$PATH:$$BAZEL_ROOT/$$(dirname $(execpath @nodejs//:node_bin))",
21+
"export NPM=$$BAZEL_ROOT/$(execpath @nodejs//:npm_bin)",
22+
# npm has a global cache which doesn't work on macos, where absolute paths aren't filtered out by the sandbox.
23+
# Therefore, set a temporary cache directory.
24+
"export NPM_CONFIG_USERCONFIG=$$TEMP/npmrc",
25+
"$$NPM config set cache $$TEMP/npm",
26+
"$$NPM config set update-notifier false",
27+
"rm -rf $(RULEDIR)/inputs",
28+
"cp -L -R $$(dirname $(execpath package.json)) $(RULEDIR)/inputs",
29+
"cd $(RULEDIR)/inputs",
30+
"$$NPM install",
31+
"$$NPM run build",
32+
"rm -rf node_modules",
33+
# Install again with only runtime deps
34+
"$$NPM install --prod",
35+
"mv node_modules build/",
36+
"mkdir -p javascript/tools/typescript-parser-wrapper",
37+
"mv build/* javascript/tools/typescript-parser-wrapper",
38+
"",
39+
]) + on_windows(
40+
" && ".join([
41+
"$$BAZEL_ROOT/$(execpath @bazel_tools//tools/zip:zipper) cC $$(cygpath -w $$BAZEL_ROOT/$@) $$(find javascript -name '*' -print)",
42+
"rm -rf $$TEMP",
43+
]),
44+
" && ".join([
45+
"$$BAZEL_ROOT/$(execpath @bazel_tools//tools/zip:zipper) cC $$BAZEL_ROOT/$@ $$(find javascript -name '*' -print)",
46+
"rm -rf $$TEMP",
47+
]),
48+
),
49+
tools = [
50+
"@bazel_tools//tools/zip:zipper",
51+
"@nodejs//:node_bin",
52+
"@nodejs//:npm_bin",
53+
],
54+
visibility = ["//visibility:public"],
55+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
filegroup(
2+
name = "parser-tests",
3+
srcs = glob(["**/*"]),
4+
visibility = ["//visibility:public"],
5+
)

javascript/extractor/src/com/semmle/js/extractor/test/ASTMatchingTests.java renamed to javascript/extractor/test/com/semmle/js/extractor/test/ASTMatchingTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.semmle.js.ast.AST2JSON;
1313
import com.semmle.js.ast.Program;
1414
import com.semmle.util.io.WholeIO;
15+
import com.semmle.util.tests.TestPaths;
1516
import java.io.File;
1617
import java.util.Iterator;
1718
import java.util.Map.Entry;
@@ -54,7 +55,7 @@ protected void assertMatch(String path, JsonElement expected, JsonElement actual
5455
}
5556
}
5657

57-
private static final File BABYLON_BASE = new File("parser-tests/babylon").getAbsoluteFile();
58+
private static final File BABYLON_BASE = TestPaths.get("parser-tests/babylon").toAbsolutePath().toFile();
5859

5960
protected void babylonTest(String dir) {
6061
babylonTest(dir, new Options().esnext(true));

javascript/extractor/src/com/semmle/js/extractor/test/AutoBuildTests.java renamed to javascript/extractor/test/com/semmle/js/extractor/test/AutoBuildTests.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.semmle.js.extractor.FileExtractor.FileType;
3131
import com.semmle.js.extractor.VirtualSourceRoot;
3232
import com.semmle.util.data.StringUtil;
33+
import com.semmle.util.exception.Exceptions;
3334
import com.semmle.util.exception.UserError;
3435
import com.semmle.util.files.FileUtil;
3536
import com.semmle.util.files.FileUtil8;
@@ -443,8 +444,12 @@ public void excludeByClassificationBadPath() throws IOException {
443444

444445
/** Hide {@code p} on using {@link DosFileAttributeView} if available; otherwise do nothing. */
445446
private void hide(Path p) throws IOException {
447+
try {
446448
DosFileAttributeView attrs = Files.getFileAttributeView(p, DosFileAttributeView.class);
447449
if (attrs != null) attrs.setHidden(true);
450+
} catch (IOException e) {
451+
Exceptions.ignore(e, "On Linux within the bazel sandbox, we get a DosFileAttributeView that then throws an exception upon use");
452+
}
448453
}
449454

450455
@Test
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
java_test(
2+
name = "test_jar",
3+
srcs = glob(["**/*.java"]),
4+
test_class = "com.semmle.js.extractor.test.AllTests",
5+
deps = [
6+
"//javascript/extractor",
7+
"//javascript/extractor:deps",
8+
"@//resources/lib/java/DO_NOT_DISTRIBUTE:junit",
9+
],
10+
)
11+
12+
# We need to unzip the typescript wrapper, and provide node on the path.
13+
# Therefore, we're wrapping the java_test inside a sh_test.
14+
sh_test(
15+
name = "test",
16+
size = "small",
17+
srcs = ["run_tests.sh"],
18+
args = [
19+
"$(execpath @nodejs//:node_bin)",
20+
"$(JAVABASE)/bin/java",
21+
"$(rootpath //javascript/extractor/lib/typescript)",
22+
"$(rootpath test_jar_deploy.jar)",
23+
],
24+
data = [
25+
":test_jar_deploy.jar",
26+
"//javascript/extractor/lib/typescript",
27+
"//javascript/extractor/parser-tests",
28+
"//javascript/extractor/tests",
29+
"@bazel_tools//tools/jdk:current_java_runtime",
30+
"@nodejs//:node_bin",
31+
],
32+
toolchains = ["@bazel_tools//tools/jdk:current_java_runtime"],
33+
)

javascript/extractor/src/com/semmle/js/extractor/test/JSXTests.java renamed to javascript/extractor/test/com/semmle/js/extractor/test/JSXTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.semmle.js.ast.Program;
1111
import com.semmle.util.files.FileUtil;
1212
import com.semmle.util.io.WholeIO;
13+
import com.semmle.util.tests.TestPaths;
1314
import java.io.File;
1415
import java.util.ArrayList;
1516
import java.util.List;
@@ -25,7 +26,7 @@
2526
*/
2627
@RunWith(Parameterized.class)
2728
public class JSXTests extends ASTMatchingTests {
28-
private static final File BASE = new File("parser-tests/jcorn-jsx").getAbsoluteFile();
29+
private static final File BASE = TestPaths.get("parser-tests/jcorn-jsx").toAbsolutePath().toFile();
2930

3031
@Parameters(name = "{0}")
3132
public static Iterable<Object[]> tests() {

javascript/extractor/src/com/semmle/js/extractor/test/RobustnessTests.java renamed to javascript/extractor/test/com/semmle/js/extractor/test/RobustnessTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.semmle.jcorn.Options;
44
import com.semmle.jcorn.Parser;
55
import com.semmle.util.io.WholeIO;
6+
import com.semmle.util.tests.TestPaths;
67
import java.io.File;
78
import java.nio.charset.StandardCharsets;
89
import org.junit.Test;
@@ -11,7 +12,7 @@ public class RobustnessTests {
1112

1213
@Test
1314
public void letLookheadTest() {
14-
File test = new File("parser-tests/robustness/letLookahead.js");
15+
File test = TestPaths.get("parser-tests/robustness/letLookahead.js").toFile();
1516
String src = new WholeIO(StandardCharsets.UTF_8.name()).strictread(test);
1617
new Parser(new Options(), src, 0).parse();
1718
}

javascript/extractor/src/com/semmle/js/extractor/test/TrapTests.java renamed to javascript/extractor/test/com/semmle/js/extractor/test/TrapTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.semmle.util.io.WholeIO;
1414
import com.semmle.util.process.Env;
1515
import com.semmle.util.srcarchive.DummySourceArchive;
16+
import com.semmle.util.tests.TestPaths;
1617
import com.semmle.util.trap.ITrapWriterFactory;
1718
import com.semmle.util.trap.TrapWriter;
1819
import com.semmle.util.trap.pathtransformers.ProjectLayoutTransformer;
@@ -35,7 +36,7 @@
3536

3637
@RunWith(Parameterized.class)
3738
public class TrapTests {
38-
private static final File BASE = new File("tests").getAbsoluteFile();
39+
private static final File BASE = TestPaths.get("tests").toAbsolutePath().toFile();
3940

4041
@Parameters(name = "{0}:{1}")
4142
public static Iterable<Object[]> tests() {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
NODE=$1
2+
JAVA=$2
3+
PARSER_WRAPPER=$3
4+
TEST_JAR=$4
5+
6+
TEMP=$(mktemp -d)
7+
8+
UNAME=$(uname -s)
9+
echo $UNAME
10+
# On Windows, the symlink set up by bazel that points at the test jar is a msys2/linux-style path
11+
# The JVM can't resolve that, therefore copy the jar to the temp directory, and then set the
12+
# windows path to it
13+
if [[ "$UNAME" =~ _NT ]]; then
14+
cp $TEST_JAR $TEMP/test.jar
15+
TEST_JAR=$(cygpath -w $TEMP/test.jar)
16+
echo "On Windows, new test jar: $TEST_JAR"
17+
fi
18+
19+
# unpack parser wrapper
20+
unzip -q $PARSER_WRAPPER -d $TEMP/parser_wrapper
21+
export SEMMLE_TYPESCRIPT_PARSER_WRAPPER=$TEMP/parser_wrapper/javascript/tools/typescript-parser-wrapper/main.js
22+
23+
# setup node on path
24+
NODE=$(realpath $NODE)
25+
export PATH="$PATH:$(dirname $NODE)"
26+
27+
$JAVA -Dbazel.test_suite=com.semmle.js.extractor.test.AllTests -jar $TEST_JAR
28+
EXIT_CODE=$?
29+
30+
rm -rf $TEMP
31+
exit $EXIT_CODE
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
filegroup(
2+
name = "tests",
3+
srcs = glob(["**/*"]),
4+
visibility = ["//visibility:public"],
5+
)

0 commit comments

Comments
 (0)