Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions scala/private/common_outputs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ common_outputs = {
"manifest": "%{name}_MANIFEST.MF",
"statsfile": "%{name}.statsfile",
"diagnosticsfile": "%{name}.diagnosticsproto",
"jdeps": "%{name}.jdep",
}
6 changes: 5 additions & 1 deletion scala/private/phases/phase_compile.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ def _compile_or_empty(
manifest,
ctx.outputs.statsfile,
ctx.outputs.diagnosticsfile,
ctx.outputs.jdeps,
sources,
jars,
all_srcjars,
Expand Down Expand Up @@ -269,6 +270,7 @@ rm -f {jar_output}
# ensures that empty src targets still emit a statsfile and a diagnosticsfile
touch {statsfile}
touch {diagnosticsfile}
touch {jdepsfile}
""" + ijar_cmd

cmd = cmd.format(
Expand All @@ -277,9 +279,10 @@ touch {diagnosticsfile}
zipper = ctx.executable._zipper.path,
statsfile = ctx.outputs.statsfile.path,
diagnosticsfile = ctx.outputs.diagnosticsfile.path,
jdepsfile = ctx.outputs.jdeps.path,
)

outs = [ctx.outputs.jar, ctx.outputs.statsfile, ctx.outputs.diagnosticsfile]
outs = [ctx.outputs.jar, ctx.outputs.statsfile, ctx.outputs.diagnosticsfile, ctx.outputs.jdeps]
inputs = ctx.files.resources + [ctx.outputs.manifest]

ctx.actions.run_shell(
Expand All @@ -303,6 +306,7 @@ def _create_scala_compilation_provider(ctx, ijar, source_jar, deps_providers):
compile_jar = ijar,
source_jar = source_jar,
deps = deps_providers,
jdeps = ctx.outputs.jdeps,
exports = exports,
runtime_deps = runtime_deps,
neverlink = ctx.attr.neverlink,
Expand Down
6 changes: 6 additions & 0 deletions scala/private/rule_impls.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def compile_scala(
manifest,
statsfile,
diagnosticsfile,
jdepsPath,
sources,
cjars,
all_srcjars,
Expand Down Expand Up @@ -79,6 +80,8 @@ def compile_scala(
args.add("--Manifest", manifest)
args.add("--PrintCompileTime", print_compile_time)
args.add("--ExpectJavaOutput", expect_java_output)
if jdepsPath != None:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When jdepsPath can be None? Maybe there is no need for None and null checks?

args.add("--JDepsFilePath", jdepsPath)
args.add("--StrictDepsMode", dependency_info.strict_deps_mode)
args.add("--UnusedDependencyCheckerMode", dependency_info.unused_deps_mode)
args.add("--DependencyTrackingMethod", dependency_info.dependency_tracking_method)
Expand Down Expand Up @@ -111,6 +114,9 @@ def compile_scala(

outs = [output, statsfile, diagnosticsfile]

if jdepsPath != None:
outs.append(jdepsPath)

ins = depset(
direct = [manifest] + sources + classpath_resources + resources + resource_jars,
transitive = [compiler_classpath_jars, all_srcjars, plugins],
Expand Down
3 changes: 3 additions & 0 deletions scala_proto/private/scala_proto_aspect.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def _compile_sources(ctx, toolchain, proto, src_jars, deps, stamp_label):
write_manifest_file(ctx.actions, manifest, None)
statsfile = ctx.actions.declare_file(ctx.label.name + "_scalac.statsfile")
diagnosticsfile = ctx.actions.declare_file(ctx.label.name + "_scalac.diagnosticsproto")
jdepsfile = ctx.actions.declare_file(ctx.label.name + ".jdeps")
compile_deps = deps + _compile_deps(ctx, toolchain)
merged_deps = java_common.merge(compile_deps)

Expand All @@ -103,6 +104,7 @@ def _compile_sources(ctx, toolchain, proto, src_jars, deps, stamp_label):
manifest,
statsfile,
diagnosticsfile,
jdepsfile,
sources = [],
cjars = merged_deps.compile_jars,
all_srcjars = depset(src_jars),
Expand All @@ -127,6 +129,7 @@ def _compile_sources(ctx, toolchain, proto, src_jars, deps, stamp_label):
output_jar = output,
compile_jar = output,
deps = compile_deps,
jdeps = jdepsfile,
exports = compile_deps,
runtime_deps = compile_deps,
)
Expand Down
11 changes: 11 additions & 0 deletions src/java/io/bazel/rulesscala/jdeps/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
load("@rules_java//java:defs.bzl", "java_library")

java_library(
name = "jdeps",
srcs = ["JdepsWriter.java"],
visibility = ["//visibility:public"],
deps = [
"@bazel_tools//src/main/protobuf:deps_java_proto",
"@com_google_protobuf//:protobuf_java",
],
)
30 changes: 30 additions & 0 deletions src/java/io/bazel/rulesscala/jdeps/JdepsWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.bazel.rulesscala.jdeps;

import com.google.devtools.build.lib.view.proto.Deps;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class JdepsWriter {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think according whole ceremony this class should be final with private constructor. But I'm fine with the way it is now.


public static void write(String jdpesPath, String currentTarget, String[] classpath)
throws IOException {

Deps.Dependencies.Builder builder = Deps.Dependencies.newBuilder();
builder.setSuccess(true);
builder.setRuleLabel(currentTarget);

for (String jar : classpath) {
Deps.Dependency.Builder dependencyBuilder = Deps.Dependency.newBuilder();
dependencyBuilder.setKind(Deps.Dependency.Kind.EXPLICIT);
dependencyBuilder.setPath(jar);
builder.addDependency(dependencyBuilder.build());
}

try (OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(jdpesPath))) {
outputStream.write(builder.build().toByteArray());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think builder.build().writeTo(outputStream) should me more effective as it doesn't construct intermediary byte array.

}
}

}
1 change: 1 addition & 0 deletions src/java/io/bazel/rulesscala/scalac/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ java_binary(
deps = [
"//scala/private/toolchain_deps:scala_compile_classpath",
"//src/java/io/bazel/rulesscala/io_utils",
"//src/java/io/bazel/rulesscala/jdeps",
"//third_party/bazel/src/main/protobuf:worker_protocol_java_proto",
"@io_bazel_rules_scala//src/java/io/bazel/rulesscala/jar",
"@io_bazel_rules_scala//src/java/io/bazel/rulesscala/worker",
Expand Down
16 changes: 16 additions & 0 deletions src/java/io/bazel/rulesscala/scalac/CompileOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class CompileOptions {
public final String[] unusedDepsIgnoredTargets;
public final String[] indirectJars;
public final String[] indirectTargets;
public final String jdepsFilePath;
public final String strictDepsMode;
public final String unusedDependencyCheckerMode;
public final String currentTarget;
Expand Down Expand Up @@ -60,6 +61,7 @@ public CompileOptions(String[] lines) {
indirectJars = args.getOrEmpty("IndirectJars");
indirectTargets = args.getOrEmpty("IndirectTargets");

jdepsFilePath = args.getSingleOrNull("JDepsFilePath");
strictDepsMode = args.getSingleOrError("StrictDepsMode");
unusedDependencyCheckerMode = args.getSingleOrError("UnusedDependencyCheckerMode");
currentTarget = args.getSingleOrError("CurrentTarget");
Expand Down Expand Up @@ -105,5 +107,19 @@ String getSingleOrError(String k) {
throw new RuntimeException("Missing required arg " + k);
}
}

String getSingleOrNull(String k) {
if (index.containsKey(k)) {
String[] v = index.get(k);
if (v.length == 1) {
return v[0];
} else {
throw new RuntimeException(
k + " expected to contain single value but got " + Arrays.toString(v));
}
}

return null;
}
}
}
21 changes: 17 additions & 4 deletions src/java/io/bazel/rulesscala/scalac/ScalacWorker.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,18 @@

import io.bazel.rulesscala.io_utils.StreamCopy;
import io.bazel.rulesscala.jar.JarCreator;
import io.bazel.rulesscala.jdeps.JdepsWriter;
import io.bazel.rulesscala.worker.Worker;
import java.io.*;
import java.nio.file.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -61,6 +70,10 @@ public void work(String[] args) throws Exception {
compileScalaSources(ops, scalaSources, classes);
}

if (ops.jdepsFilePath != null) {
JdepsWriter.write(ops.jdepsFilePath, ops.currentTarget, ops.classpath);
}

/** Copy the resources */
copyResources(ops.resourceSources, ops.resourceTargets, classes);

Expand Down Expand Up @@ -95,7 +108,7 @@ private static String[] collectSrcJarSources(
}

private static List<File> filterFilesByExtension(List<File> files, String extension) {
List<File> filtered = new ArrayList<File>();
List<File> filtered = new ArrayList<>();
for (File f : files) {
if (f.toString().endsWith(extension)) {
filtered.add(f);
Expand Down Expand Up @@ -238,7 +251,7 @@ private static String[] getPluginParamsFrom(CompileOptions ops) {
}

private static void compileScalaSources(CompileOptions ops, String[] scalaSources, Path classes)
throws IllegalAccessException, IOException {
throws IOException {

String[] pluginArgs = buildPluginArgs(ops.plugins);
String[] pluginParams = getPluginParamsFrom(ops);
Expand Down
6 changes: 6 additions & 0 deletions src/java/io/bazel/rulesscala/scalac/ScalacWorker3.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.bazel.rulesscala.scalac;

import static java.io.File.pathSeparator;

import io.bazel.rulesscala.jdeps.JdepsWriter;
import scala.Tuple2;
import io.bazel.rulesscala.io_utils.StreamCopy;
import io.bazel.rulesscala.jar.JarCreator;
Expand Down Expand Up @@ -76,6 +78,10 @@ public void work(String[] args) throws Exception {
compileScalaSources(ops, scalaSources, tmpPath);
}

if (ops.jdepsFilePath != null) {
JdepsWriter.write(ops.jdepsFilePath, ops.currentTarget, ops.classpath);
}

/** Copy the resources */
copyResources(ops.resourceSources, ops.resourceTargets, tmpPath);

Expand Down
13 changes: 13 additions & 0 deletions test/src/main/java/rulesscala/test/jdeps/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
load("@rules_java//java:defs.bzl", "java_test")

java_test(
name = "jdeps",
srcs = ["JdepsWriterTest.java"],
test_class = "jdeps.JdepsWriterTest",
deps = [
"//src/java/io/bazel/rulesscala/jdeps",
"@bazel_tools//src/main/protobuf:deps_java_proto",
"@com_google_protobuf//:protobuf_java",
"@io_bazel_rules_scala_junit_junit",
],
)
45 changes: 45 additions & 0 deletions test/src/main/java/rulesscala/test/jdeps/JdepsWriterTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package jdeps;

import static org.junit.Assert.assertArrayEquals;

import com.google.devtools.build.lib.view.proto.Deps;
import com.google.devtools.build.lib.view.proto.Deps.Dependency;
import io.bazel.rulesscala.jdeps.JdepsWriter;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import org.junit.Test;

public class JdepsWriterTest {

@Test
public void writesJarListToJdepsFile() throws IOException {
File jdepsPath = Files
.createTempDirectory("jdeps-test-tempdir-")
.resolve("some-target.jdeps")
.toFile();

String[] classpath = {"foo.jar", "baz/zoo.class"};

JdepsWriter.write(
jdepsPath.getPath(),
"some-target",
classpath
);

assertArrayEquals(readJarsFromJdepsFile(jdepsPath), classpath);
}

private String[] readJarsFromJdepsFile(File jdepsPath) throws IOException {
Deps.Dependencies dependencies = Deps.Dependencies
.parseFrom(new BufferedInputStream(new FileInputStream(jdepsPath)));

return dependencies
.getDependencyList()
.stream()
.map(Dependency::getPath)
.toArray(String[]::new);
}
}
7 changes: 7 additions & 0 deletions twitter_scrooge/twitter_scrooge.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@ def _compile_generated_scala(
label.name + "_scalac.diagnosticsproto",
sibling = scrooge_jar,
)

jdepsFile = ctx.actions.declare_file(
label.name + ".jdeps",
sibling = scrooge_jar,
)

all_deps = _concat_lists(deps_java_info, implicit_deps)
merged_deps = java_common.merge(all_deps)

Expand All @@ -262,6 +268,7 @@ def _compile_generated_scala(
manifest,
statsfile,
diagnosticsfile,
jdepsFile,
sources = [],
cjars = merged_deps.transitive_compile_time_jars,
all_srcjars = depset([scrooge_jar]),
Expand Down