Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions .bazelignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
examples/

1 change: 1 addition & 0 deletions .bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5.1.1
14 changes: 14 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@ jobs:
with:
go-version: "^1.13.1"
- run: sbt test
bazel:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: yarn global add @bazel/bazelisk
- run: bazel build //... --//semanticdb-javac:enabled=true
- run: bazel run lsif-semanticdb:bazel -- --sourceroot "$PWD"
- run: du -h dump.lsif-typed
- run: bazel build //... --@lsif_java//semanticdb-javac:enabled=true
working-directory: examples/bazel-example
- run: bazel run @lsif_java//lsif-semanticdb:bazel -- --sourceroot "$PWD"
working-directory: examples/bazel-example
- run: du -h dump.lsif-typed
working-directory: examples/bazel-example
check:
runs-on: ubuntu-latest
steps:
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,7 @@ dump.lsif

./generated
/sources
bazel-bin
bazel-lsif-java
bazel-out
bazel-testlogs
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
golang 1.17.5
59 changes: 59 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
workspace(name = "lsif_java_tests")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

##############
# Bazel stdlib
##############
# To update this version, copy-paste instructions from https://github.com/bazelbuild/bazel-skylib/releases
http_archive(
name = "bazel_skylib",
sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c",
urls = [
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
],
)

##########
# Protobuf
##########
# To update this version, copy-paste instructions from https://github.com/bazelbuild/rules_proto/releases
http_archive(
name = "rules_proto",
sha256 = "e017528fd1c91c5a33f15493e3a398181a9e821a804eb7ff5acdd1d2d6c2b18d",
strip_prefix = "rules_proto-4.0.0-3.20.0",
urls = [
"https://github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0-3.20.0.tar.gz",
],
)
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
rules_proto_dependencies()
rules_proto_toolchains()

##############
# JVM External
##############
# To update this version, copy-paste instructions from https://github.com/bazelbuild/rules_jvm_external/releases
RULES_JVM_EXTERNAL_TAG = "4.2"
RULES_JVM_EXTERNAL_SHA = "cd1a77b7b02e8e008439ca76fd34f5b07aecb8c752961f9640dea15e9e5ba1ca"
http_archive(
name = "rules_jvm_external",
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
sha256 = RULES_JVM_EXTERNAL_SHA,
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
)
load("@rules_jvm_external//:repositories.bzl", "rules_jvm_external_deps")
rules_jvm_external_deps()
load("@rules_jvm_external//:setup.bzl", "rules_jvm_external_setup")
rules_jvm_external_setup()
load("@rules_jvm_external//:defs.bzl", "maven_install")
maven_install(
artifacts = [
"com.google.protobuf:protobuf-java:3.15.6",
"com.google.protobuf:protobuf-java-util:3.15.6",
"org.projectlombok:lombok:1.18.22",
],
repositories = [
"https://repo1.maven.org/maven2",
],
)
70 changes: 70 additions & 0 deletions examples/bazel-example/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@

# This is an end-to-end example of how to consume lsif-java from an external repository.
workspace(name = "lsif_java_example")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

##############
# Bazel stdlib
##############
# To update this version, copy-paste instructions from https://github.com/bazelbuild/bazel-skylib/releases
http_archive(
name = "bazel_skylib",
sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c",
urls = [
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
],
)

##############
# lsif-java
##############
local_repository(
name = "lsif_java",
path = "../.."
)
# TODO: add commented out `http_archive` example once this workspace file is available on GitHub.

##########
# Protobuf
##########
# To update this version, copy-paste instructions from https://github.com/bazelbuild/rules_proto/releases
http_archive(
name = "rules_proto",
sha256 = "e017528fd1c91c5a33f15493e3a398181a9e821a804eb7ff5acdd1d2d6c2b18d",
strip_prefix = "rules_proto-4.0.0-3.20.0",
urls = [
"https://github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0-3.20.0.tar.gz",
],
)
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
rules_proto_dependencies()
rules_proto_toolchains()

##############
# JVM External
##############
# To update this version, copy-paste instructions from https://github.com/bazelbuild/rules_jvm_external/releases
RULES_JVM_EXTERNAL_TAG = "4.2"
RULES_JVM_EXTERNAL_SHA = "cd1a77b7b02e8e008439ca76fd34f5b07aecb8c752961f9640dea15e9e5ba1ca"
http_archive(
name = "rules_jvm_external",
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
sha256 = RULES_JVM_EXTERNAL_SHA,
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
)
load("@rules_jvm_external//:repositories.bzl", "rules_jvm_external_deps")
rules_jvm_external_deps()
load("@rules_jvm_external//:setup.bzl", "rules_jvm_external_setup")
rules_jvm_external_setup()
load("@rules_jvm_external//:defs.bzl", "maven_install")
maven_install(
artifacts = [
"com.google.protobuf:protobuf-java:3.15.6", # Required dependency by lsif-java.
"com.google.protobuf:protobuf-java-util:3.15.6", # Required dependency by lsif-java.
"com.google.guava:guava:31.0-jre", # Not required dependency, only used by tests.
],
repositories = [
"https://repo1.maven.org/maven2",
],
)
19 changes: 19 additions & 0 deletions examples/bazel-example/src/main/java/example/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# We import the custom `java_library` implementation that automatically adds the
# SemanticDB compiler plugin based on the presence of the flag
# `--@lsif_java//semanticdb-javac:enabled=true`. By default, this java_library
# rule works just like the official java_library rule. Feel free to copy-paste
# the `semanticdb:defs.bzl` file and adapt to your needs. This example is only
# for demonstration purposes.
load("@lsif_java//semanticdb-javac:defs.bzl", "java_library")

package(
default_visibility = ["//visibility:public"],
)

java_library(
name = "example",
srcs = ["Example.java"],
deps = [
"@maven//:com_google_guava_guava",
],
)
9 changes: 9 additions & 0 deletions examples/bazel-example/src/main/java/example/Example.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package example;
import com.google.common.util.concurrent.Futures;

public class Example {
public static void hello() {
System.out.println(Futures.immediateCancelledFuture());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ final case class IndexSemanticdbCommand(
@Description(
"Whether to process the SemanticDB files in parallel"
) parallel: Boolean = true,
@Description(
"Whether to infer the location of SemanticDB files based as produced by Bazel"
) bazel: Boolean = true,
@Description("URL to a PackageHub instance")
@Hidden
packagehub: Option[String] = None,
Expand Down
36 changes: 36 additions & 0 deletions lsif-semanticdb/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
load("@rules_java//java:defs.bzl", "java_binary", "java_library", "java_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_library")

package(
default_visibility = ["//visibility:public"],
)

java_binary(
name = "bazel",
main_class = "com.sourcegraph.lsif_semanticdb.BazelBuildTool",
runtime_deps = [
":lsif-semanticdb",
],
)

java_library(
name = "lsif-semanticdb",
srcs = glob(["src/main/java/**/*.java"]),
deps = [
":all_java_proto",
"//semanticdb-java",
"//semanticdb-java/src/main/protobuf:semanticdb_java_proto",
"@maven//:com_google_protobuf_protobuf_java",
"@maven//:com_google_protobuf_protobuf_java_util",
],
)

java_proto_library(
name = "all_java_proto",
deps = [":all_proto"],
)

proto_library(
name = "all_proto",
srcs = glob(["src/main/protobuf/*.proto"]),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package com.sourcegraph.lsif_semanticdb;

import com.sourcegraph.lsif_java.Bazelbuild;
import com.sourcegraph.lsif_protocol.LsifToolInfo;

import java.io.*;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.sql.Array;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class BazelBuildTool {

public static int runAndReturnExitCode(String[] args) throws IOException {
Optional<BazelOptions> maybeOptions = BazelOptions.parse(args);
if (!maybeOptions.isPresent()) {
return 1;
}
BazelOptions options = maybeOptions.get();
if (options.isHelp) {
BazelOptions.printHelp();
return 0;
}
if (options.isVersion) {
System.out.println(
"This command-line tool has no version because it is supposed to be compiled from source.");
return 0;
}

List<MavenPackage> mavenPackages = mavenPackages(options);
LsifSemanticdbOptions lsifOptions =
new LsifSemanticdbOptions(
options.targetroots,
options.output,
options.sourceroot,
new LsifSemanticdbReporter() {
@Override
public void error(Throwable e) {
e.printStackTrace(System.err);
}
},
LsifToolInfo.newBuilder().setName("lsif-java").setVersion("HEAD").build(),
"java",
LsifOutputFormat.TYPED_PROTOBUF,
options.parallel,
mavenPackages,
"");
LsifSemanticdb.run(lsifOptions);
if (!lsifOptions.reporter.hasErrors()) {
System.out.println("done: " + lsifOptions.output);
}
return 0;
}

public static List<MavenPackage> mavenPackages(BazelOptions options) throws IOException {
ArrayList<MavenPackage> result = new ArrayList<>();
if (!options.isQueryMavenImports) {
return result;
}
Bazelbuild.QueryResult jvmImports = runBazelQuery(options, "kind('.*_import', @maven//...)");
Path baseDirectory =
options.sourceroot.resolve("bazel-bin").resolve("external").resolve("maven");
PathMatcher jarPattern = FileSystems.getDefault().getPathMatcher("glob:**.jar");
for (Bazelbuild.Target target : jvmImports.getTargetList()) {
if (target.getType() != Bazelbuild.Target.Discriminator.RULE) {
continue;
}
Bazelbuild.Rule rule = target.getRule();
MavenPackage basePackage = null;
List<Path> jarDirectories = new ArrayList<>();
for (Bazelbuild.Attribute attribute : rule.getAttributeList()) {
if (attribute.getName().equals("jars")) {
for (String tag : attribute.getStringListValueList()) {
if (tag.startsWith("@maven//:")) {
jarDirectories.add(
baseDirectory.resolve(tag.substring("@maven//:".length())).getParent());
}
}
}
if (attribute.getName().equals("tags")) {
for (String tag : attribute.getStringListValueList()) {
if (tag.startsWith("maven_coordinates=")) {
String[] parts = tag.substring("maven_coordinates=".length()).split(":");
if (parts.length == 3) {
// The jar part is populated via `withJar()` below.
basePackage = new MavenPackage(/* jar = */ null, parts[0], parts[1], parts[2]);
}
}
}
}
}
if (basePackage == null) {
continue;
}
for (Path directory : jarDirectories) {
try (Stream<Path> list = Files.list(directory)) {
List<Path> jars = list.filter(jarPattern::matches).collect(Collectors.toList());
for (Path jar : jars) {
result.add(basePackage.withJar(jar));
}
}
}
}
return result;
}

public static Bazelbuild.QueryResult runBazelQuery(BazelOptions options, String query)
throws IOException {
List<String> command = Arrays.asList(options.bazelBinary, "query", query, "--output=proto");
System.out.println("running: " + String.join(" ", command));
Process bazelQuery = new ProcessBuilder(command).directory(options.sourceroot.toFile()).start();
byte[] bytes = InputStreamBytes.readAll(bazelQuery.getInputStream());
if (bazelQuery.isAlive()) {
throw new RuntimeException(new String(InputStreamBytes.readAll(bazelQuery.getErrorStream())));
}
int exitValue = bazelQuery.exitValue();
if (exitValue != 0) {
throw new RuntimeException("bazel command failed\n" + new String(bytes));
}
return Bazelbuild.QueryResult.parseFrom(bytes);
}

public static void main(String[] args) throws IOException {
System.exit(runAndReturnExitCode(args));
}
}
Loading