From b4a04b6b06bede15928b0cd7d7d706cb4358e23d Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Wed, 7 Aug 2024 13:44:57 +0100 Subject: [PATCH 01/20] WIP Maven plugin for dumping dependencies --- build.sbt | 30 ++++++ .../maven/DependencyWriterMojo.java | 92 +++++++++++++++++++ .../META-INF/maven/plugin.template.xml | 58 ++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java create mode 100644 maven-plugin/src/main/resources/META-INF/maven/plugin.template.xml diff --git a/build.sbt b/build.sbt index 0c678b4f..e41d003a 100644 --- a/build.sbt +++ b/build.sbt @@ -7,6 +7,8 @@ import java.util.Properties import scala.collection.mutable.ListBuffer import scala.util.control.NoStackTrace +ThisBuild / version := sys.env.get("CI").fold("dev")(_ => version.value) + lazy val V = new { val protobuf = "3.15.6" @@ -205,6 +207,7 @@ lazy val scipProto = project lazy val scip = project .in(file("scip-semanticdb")) .settings( + publishMavenStyle := true, moduleName := "scip-semanticdb", javaToolchainVersion := "8", javaOnlySettings, @@ -214,6 +217,33 @@ lazy val scip = project ) .dependsOn(semanticdb, scipProto) +lazy val mavenPlugin = project + .in(file("maven-plugin")) + .settings( + moduleName := "maven-plugin", + javaToolchainVersion := "8", + javaOnlySettings, + libraryDependencies ++= + Seq( + "org.apache.maven" % "maven-plugin-api" % "3.6.3", + "org.apache.maven.plugin-tools" % "maven-plugin-annotations" % "3.6.4" % + Provided, + "org.apache.maven" % "maven-project" % "2.2.1" + ), + Compile / resourceGenerators += + Def.task { + val dir = (Compile / managedResourceDirectories).value.head / + "META-INF" / "maven" + IO.createDirectory(dir) + val file = dir / "plugin.xml" + val template = IO.read((Compile / resourceDirectory).value / "META-INF" / "maven" / "plugin.template.xml") + + IO.write(file, template.replace("@VERSION@", version.value)) + + Seq(file) + } + ) + lazy val cli = project .in(file("scip-java")) .settings( diff --git a/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java b/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java new file mode 100644 index 00000000..22a06f8c --- /dev/null +++ b/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java @@ -0,0 +1,92 @@ +package com.sourcegraph.maven; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.model.Dependency; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; + +import static java.lang.System.*; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Set; + +@Mojo( + name = "sourcegraphDependencies", + defaultPhase = LifecyclePhase.COMPILE, + requiresDependencyResolution = ResolutionScope.COMPILE, + requiresProject = true) +public class DependencyWriterMojo extends AbstractMojo { + @Parameter(defaultValue = "${project}", required = true, readonly = true) + MavenProject project; + + @Parameter( + property = "semanticdb.targetRoot", + defaultValue = "${session.executionRootDirectory}/target/semanticdb-targetroot") + private String targetRoot; + + public void execute() throws MojoExecutionException, MojoFailureException { + Set artifacts = project.getArtifacts(); + StringBuilder builder = new StringBuilder(); + + String groupID = project.getGroupId(); + String artifactID = project.getArtifactId(); + String version = project.getVersion(); + List sourceRoots = project.getCompileSourceRoots(); + + if (groupID == null || artifactID == null) { + getLog() + .warn( + "Failed to extract groupID and artifactID from the project.\n" + + "This will not prevent a SCIP index from being created, but the symbols \n" + + "extracted from this project won't be available for cross-repository navigation,\n" + + "as this project doesn't define any Maven coordinates by which it can be referred back to.\n" + + "See here for more details: https://sourcegraph.github.io/scip-java/docs/manual-configuration.html#step-5-optional-enable-cross-repository-navigation\n"); + } else { + for (Object root : sourceRoots) { + if (root instanceof String) { + String rootString = (String) root; + builder.append( + String.format("%s\t%s\t%s\t%s\n", groupID, artifactID, version, rootString)); + } + } + } + + for (Object dep : artifacts) { + if (dep instanceof Artifact) { + Artifact artifact = (Artifact) dep; + builder.append( + String.format( + "%s\t%s\t%s\t%s\n", + artifact.getGroupId(), + artifact.getArtifactId(), + artifact.getVersion(), + artifact.getFile())); + } + } + + Path dependenciesFile = Paths.get(targetRoot).resolve("dependencies.txt"); + + try { + Files.createDirectories(dependenciesFile.getParent()); + try (BufferedWriter writer = Files.newBufferedWriter(dependenciesFile)) { + writer.write(builder.toString()); + } + } catch (IOException e) { + throw new MojoFailureException( + "Failed to write dependencies to file " + dependenciesFile.toString(), e); + } + + getLog().info("Dependencies were written to " + dependenciesFile.toAbsolutePath().toString()); + } +} diff --git a/maven-plugin/src/main/resources/META-INF/maven/plugin.template.xml b/maven-plugin/src/main/resources/META-INF/maven/plugin.template.xml new file mode 100644 index 00000000..e0cb1c27 --- /dev/null +++ b/maven-plugin/src/main/resources/META-INF/maven/plugin.template.xml @@ -0,0 +1,58 @@ + + + + + + Sourcegraph scip-java Maven plugin + A Maven plugin which exports your project's dependencies in a format scip-java can understand + com.sourcegraph + maven-plugin + @VERSION@ + sourcegraph + false + true + 1.8 + 3.9.5 + + + sourcegraphDependencies + false + true + false + false + false + true + generate-resources + com.sourcegraph.maven.DependencyWriterMojo + java + per-lookup + once-per-session + test + true + + + project + org.apache.maven.project.MavenProject + true + false + The maven project. + + + targetRoot + java.lang.String + false + true + Location where `dependencies.txt` file will be written (should match the Semanticdb targetroot option) + + + + ${project} + ${session.executionRootDirectory}/target/semanticdb-targetroot + + + + + + + + From b4c13bf7bbaf69d99872894a31b2941f42942b5a Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Wed, 7 Aug 2024 14:11:36 +0100 Subject: [PATCH 02/20] remove version override --- build.sbt | 2 -- 1 file changed, 2 deletions(-) diff --git a/build.sbt b/build.sbt index e41d003a..dac48a91 100644 --- a/build.sbt +++ b/build.sbt @@ -7,8 +7,6 @@ import java.util.Properties import scala.collection.mutable.ListBuffer import scala.util.control.NoStackTrace -ThisBuild / version := sys.env.get("CI").fold("dev")(_ => version.value) - lazy val V = new { val protobuf = "3.15.6" From 485db58e1db718d2c1f9a6ef869d8394ff2909d2 Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Wed, 7 Aug 2024 15:37:19 +0100 Subject: [PATCH 03/20] Add `build` command which packages CLI in a reasonable location --- build.sbt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index dac48a91..3e0bdc8f 100644 --- a/build.sbt +++ b/build.sbt @@ -234,7 +234,10 @@ lazy val mavenPlugin = project "META-INF" / "maven" IO.createDirectory(dir) val file = dir / "plugin.xml" - val template = IO.read((Compile / resourceDirectory).value / "META-INF" / "maven" / "plugin.template.xml") + val template = IO.read( + (Compile / resourceDirectory).value / "META-INF" / "maven" / + "plugin.template.xml" + ) IO.write(file, template.replace("@VERSION@", version.value)) @@ -630,3 +633,14 @@ dumpScipJavaVersion := { IO.write((ThisBuild / baseDirectory).value / "VERSION", versionValue) } + + +lazy val build = taskKey[Unit]( + "Build `scip-java` CLI and place it in the out/bin/scip-java. " +) + +build := { + val source = (cli / pack).value + val newValue = (ThisBuild / baseDirectory).value / "out" + IO.copyDirectory(source, newValue) +} From d4f1f0224f4f1e315c4b1c69df627e3bd5642d49 Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Wed, 7 Aug 2024 15:37:36 +0100 Subject: [PATCH 04/20] update SBT --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 04267b14..ee4c672c 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.9 +sbt.version=1.10.1 From 28c65c5a4ef4ed1e1589e78ade2760c10d9d65f5 Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Wed, 7 Aug 2024 15:38:09 +0100 Subject: [PATCH 05/20] Clean up the maven plugin --- .../maven/DependencyWriterMojo.java | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java b/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java index 22a06f8c..c8b3d918 100644 --- a/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java +++ b/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java @@ -1,7 +1,6 @@ package com.sourcegraph.maven; import org.apache.maven.artifact.Artifact; -import org.apache.maven.model.Dependency; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -11,8 +10,6 @@ import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; -import static java.lang.System.*; - import java.io.BufferedWriter; import java.io.IOException; import java.nio.file.Files; @@ -65,13 +62,21 @@ public void execute() throws MojoExecutionException, MojoFailureException { for (Object dep : artifacts) { if (dep instanceof Artifact) { Artifact artifact = (Artifact) dep; - builder.append( - String.format( - "%s\t%s\t%s\t%s\n", - artifact.getGroupId(), - artifact.getArtifactId(), - artifact.getVersion(), - artifact.getFile())); + if (artifact.getFile() != null) { + builder.append( + String.format( + "%s\t%s\t%s\t%s\n", + artifact.getGroupId(), + artifact.getArtifactId(), + artifact.getVersion(), + artifact.getFile())); + } else { + getLog() + .warn( + "Dependency " + + summariseArtifact(artifact) + + " does not have a resolved file, so it won't be added to the dependencies.txt"); + } } } @@ -89,4 +94,9 @@ public void execute() throws MojoExecutionException, MojoFailureException { getLog().info("Dependencies were written to " + dependenciesFile.toAbsolutePath().toString()); } + + private String summariseArtifact(Artifact artifact) { + return String.format( + "%:%:%", artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion()); + } } From 2c3b1ca0bdc975fb719184702d756639291d5971 Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Wed, 7 Aug 2024 15:38:36 +0100 Subject: [PATCH 06/20] move benchmark tests to check job --- .github/workflows/ci.yml | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c642c435..b627de91 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,26 +17,15 @@ jobs: java: [8, 11, 17, 21] steps: - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: distribution: "temurin" cache: "sbt" java-version: ${{ matrix.java }} - - name: Main project tests - run: sbt test - benchmarks-test: - runs-on: ubuntu-latest - name: Benchmark tests - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 - with: - distribution: "temurin" - cache: "sbt" - java-version: 17 - - name: Run sample benchmarks - run: sbt 'bench/Jmh/run -i 1 -f1 -t1 -foe true' + - name: Main project tests + run: sbt test docker_test: runs-on: ${{ matrix.os }} @@ -116,4 +105,10 @@ jobs: distribution: "temurin" java-version: 17 cache: "sbt" + - run: sbt checkAll + + - name: Run sample benchmarks + run: sbt 'bench/Jmh/run -i 1 -f1 -t1 -foe true' + + From 65f18a29300a5cb27a7154f912c7316b1e111263 Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Wed, 7 Aug 2024 15:38:53 +0100 Subject: [PATCH 07/20] Add a new maven workflow --- .github/workflows/ci.yml | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b627de91..b3d1f27f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,8 +83,8 @@ jobs: steps: - uses: actions/checkout@v2 - run: yarn global add @bazel/bazelisk - - run: sbt cli/pack - - run: echo "$PWD/scip-java/target/pack/bin" >> $GITHUB_PATH + - run: sbt build + - run: echo "out/bin" >> $GITHUB_PATH - name: Auto-index scip-java codebase run: | scip-java index --build-tool=bazel --bazel-scip-java-binary=$(which scip-java) @@ -112,3 +112,25 @@ jobs: run: sbt 'bench/Jmh/run -i 1 -f1 -t1 -foe true' + maven: + runs-on: ubuntu-latest + name: Tests + strategy: + fail-fast: false + matrix: + java: [8, 11, 17, 21] + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-java@v4 + with: + distribution: "temurin" + cache: "sbt" + java-version: ${{ matrix.java }} + + - run: sbt build publishM2 dumpScipJavaVersion + - run: | + mvn clean verify -DskipTests -Dscip-java.version=$(cat VERSION) sourcegraph:sourcegraphDependencies + - run: out/bin/scip-java index-semanticdb target/semanticdb-root + - run: du -h index.scip + From 0db33d61f762602641f008a9c1bf45e4f8e12808 Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Wed, 7 Aug 2024 15:39:05 +0100 Subject: [PATCH 08/20] Add a Maven example with plugin enabled --- examples/maven-example/pom.xml | 100 ++++++++++++++++++ examples/maven-example/src/main/java/App.java | 13 +++ .../maven-example/src/test/java/AppTest.java | 20 ++++ 3 files changed, 133 insertions(+) create mode 100644 examples/maven-example/pom.xml create mode 100644 examples/maven-example/src/main/java/App.java create mode 100644 examples/maven-example/src/test/java/AppTest.java diff --git a/examples/maven-example/pom.xml b/examples/maven-example/pom.xml new file mode 100644 index 00000000..20c686fd --- /dev/null +++ b/examples/maven-example/pom.xml @@ -0,0 +1,100 @@ + + + + 4.0.0 + + com.sourcegraph + example + 1.0-SNAPSHOT + + example + + http://www.example.com + + + UTF-8 + 1.8 + 1.8 + + + + + junit + junit + 4.11 + test + + + com.sourcegraph + semanticdb-javac + ${scip-java.version} + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + -Xplugin:semanticdb -sourceroot:${session.executionRootDirectory} -targetroot:${session.executionRootDirectory}/target/semanticdb-targetroot + + + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + com.sourcegraph + maven-plugin + ${scip-java.version} + + + + sourcegraphDependencies + + + + + + + + + + + diff --git a/examples/maven-example/src/main/java/App.java b/examples/maven-example/src/main/java/App.java new file mode 100644 index 00000000..b8e9695d --- /dev/null +++ b/examples/maven-example/src/main/java/App.java @@ -0,0 +1,13 @@ +package test; + +/** + * Hello world! + * + */ +public class App +{ + public static void main( String[] args ) + { + System.out.println( "Hello World!" ); + } +} diff --git a/examples/maven-example/src/test/java/AppTest.java b/examples/maven-example/src/test/java/AppTest.java new file mode 100644 index 00000000..fc84e0f6 --- /dev/null +++ b/examples/maven-example/src/test/java/AppTest.java @@ -0,0 +1,20 @@ +package test; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Unit test for simple App. + */ +public class AppTest +{ + /** + * Rigorous Test :-) + */ + @Test + public void shouldAnswerWithTrue() + { + assertTrue( true ); + } +} From 3907bb8d2e0464971fcd9ea1fac624019b76d7a1 Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Wed, 7 Aug 2024 15:45:13 +0100 Subject: [PATCH 09/20] Run in correct folder --- .github/workflows/ci.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b3d1f27f..6f7b7428 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -114,7 +114,7 @@ jobs: maven: runs-on: ubuntu-latest - name: Tests + name: Maven tests strategy: fail-fast: false matrix: @@ -128,9 +128,16 @@ jobs: cache: "sbt" java-version: ${{ matrix.java }} + - run: sbt build publishM2 dumpScipJavaVersion + - run: | mvn clean verify -DskipTests -Dscip-java.version=$(cat VERSION) sourcegraph:sourcegraphDependencies + working-directory: examples/maven-example + - run: out/bin/scip-java index-semanticdb target/semanticdb-root + working-directory: examples/maven-example + - run: du -h index.scip + working-directory: examples/maven-example From 6787e9f30b550a0fee23426a868ea785df84d3bd Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Wed, 7 Aug 2024 15:45:48 +0100 Subject: [PATCH 10/20] Use absolute path --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6f7b7428..f4af9137 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,7 +84,7 @@ jobs: - uses: actions/checkout@v2 - run: yarn global add @bazel/bazelisk - run: sbt build - - run: echo "out/bin" >> $GITHUB_PATH + - run: echo "$PWD/out/bin" >> $GITHUB_PATH - name: Auto-index scip-java codebase run: | scip-java index --build-tool=bazel --bazel-scip-java-binary=$(which scip-java) From 6a53c057d9a9c808200e787fd8c9f5aefe0dde70 Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Wed, 7 Aug 2024 15:50:51 +0100 Subject: [PATCH 11/20] use env variables instead --- .github/workflows/ci.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f4af9137..214dbf93 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -129,13 +129,16 @@ jobs: java-version: ${{ matrix.java }} - - run: sbt build publishM2 dumpScipJavaVersion + - run: | + sbt build publishM2 publishLocal dumpScipJavaVersion + echo "SCIP_JAVA_VERSION=$(cat VERSION)" >> $GITHUB_ENV + echo "SCIP_JAVA_CLI=$PWD/out/bin/scip-java" >> $GITHUB_ENV - run: | - mvn clean verify -DskipTests -Dscip-java.version=$(cat VERSION) sourcegraph:sourcegraphDependencies + mvn clean verify -DskipTests -Dscip-java.version=$SCIP_JAVA_VERSION sourcegraph:sourcegraphDependencies working-directory: examples/maven-example - - run: out/bin/scip-java index-semanticdb target/semanticdb-root + - run: $SCIP_JAVA_CLI index-semanticdb target/semanticdb-root working-directory: examples/maven-example - run: du -h index.scip From 4a0a611f7375729d1fc800f7dbc6390a874d38e1 Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Wed, 7 Aug 2024 15:57:58 +0100 Subject: [PATCH 12/20] Run extra checks on the outputs --- .github/workflows/ci.yml | 8 +++++++- build.sbt | 5 ++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 214dbf93..0b1bac21 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -138,7 +138,13 @@ jobs: mvn clean verify -DskipTests -Dscip-java.version=$SCIP_JAVA_VERSION sourcegraph:sourcegraphDependencies working-directory: examples/maven-example - - run: $SCIP_JAVA_CLI index-semanticdb target/semanticdb-root + - run: $SCIP_JAVA_CLI index-semanticdb target/semanticdb-targetroot + working-directory: examples/maven-example + + - run: | + set -e + grep org.hamcrest target/semanticdb-targetroot/dependencies.txt + grep $PWD/src/main/java target/semanticdb-targetroot/dependencies.txt working-directory: examples/maven-example - run: du -h index.scip diff --git a/build.sbt b/build.sbt index 3e0bdc8f..7549aee0 100644 --- a/build.sbt +++ b/build.sbt @@ -634,13 +634,12 @@ dumpScipJavaVersion := { IO.write((ThisBuild / baseDirectory).value / "VERSION", versionValue) } - lazy val build = taskKey[Unit]( "Build `scip-java` CLI and place it in the out/bin/scip-java. " ) build := { val source = (cli / pack).value - val newValue = (ThisBuild / baseDirectory).value / "out" - IO.copyDirectory(source, newValue) + val destination = (ThisBuild / baseDirectory).value / "out" + IO.copyDirectory(source, destination) } From f73c9490acf0058c27b0ecb531f1398aa24786fe Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Wed, 7 Aug 2024 16:18:12 +0100 Subject: [PATCH 13/20] use "Maven CI friendly" versions https://maven.apache.org/maven-ci-friendly.html --- examples/maven-example/pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/maven-example/pom.xml b/examples/maven-example/pom.xml index 20c686fd..b61149a7 100644 --- a/examples/maven-example/pom.xml +++ b/examples/maven-example/pom.xml @@ -6,7 +6,7 @@ com.sourcegraph example - 1.0-SNAPSHOT + ${revision} example @@ -16,6 +16,7 @@ UTF-8 1.8 1.8 + 1.0.0-SNAPSHOT From 46d43ab5e09b4ea21bfd8da9bf4ff08b572ea1c8 Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Wed, 7 Aug 2024 18:30:42 +0100 Subject: [PATCH 14/20] Fix artifact rendering in error message --- .../main/java/com/sourcegraph/maven/DependencyWriterMojo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java b/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java index c8b3d918..fdab05d8 100644 --- a/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java +++ b/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java @@ -97,6 +97,6 @@ public void execute() throws MojoExecutionException, MojoFailureException { private String summariseArtifact(Artifact artifact) { return String.format( - "%:%:%", artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion()); + "%s:%s:%s", artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion()); } } From 9b5af9dc244091f4c979ef8458039b7616fff233 Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Thu, 8 Aug 2024 15:58:13 +0100 Subject: [PATCH 15/20] Write dependencies files unique identified by the maven project --- .../sourcegraph/maven/DependencyWriterMojo.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java b/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java index fdab05d8..e38caada 100644 --- a/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java +++ b/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java @@ -4,10 +4,7 @@ import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.plugins.annotations.*; import org.apache.maven.project.MavenProject; import java.io.BufferedWriter; @@ -21,7 +18,7 @@ @Mojo( name = "sourcegraphDependencies", defaultPhase = LifecyclePhase.COMPILE, - requiresDependencyResolution = ResolutionScope.COMPILE, + requiresDependencyResolution = ResolutionScope.TEST, requiresProject = true) public class DependencyWriterMojo extends AbstractMojo { @Parameter(defaultValue = "${project}", required = true, readonly = true) @@ -33,6 +30,7 @@ public class DependencyWriterMojo extends AbstractMojo { private String targetRoot; public void execute() throws MojoExecutionException, MojoFailureException { + String sanitisedProjectId = project.getId().replaceAll("[^0-9_a-zA-Z()%\\-.]", "_"); Set artifacts = project.getArtifacts(); StringBuilder builder = new StringBuilder(); @@ -51,6 +49,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { + "See here for more details: https://sourcegraph.github.io/scip-java/docs/manual-configuration.html#step-5-optional-enable-cross-repository-navigation\n"); } else { for (Object root : sourceRoots) { + getLog().info(root.toString()); if (root instanceof String) { String rootString = (String) root; builder.append( @@ -80,7 +79,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { } } - Path dependenciesFile = Paths.get(targetRoot).resolve("dependencies.txt"); + Path dependenciesFile = Paths.get(targetRoot).resolve(sanitisedProjectId + ".dependencies.txt"); try { Files.createDirectories(dependenciesFile.getParent()); @@ -89,10 +88,10 @@ public void execute() throws MojoExecutionException, MojoFailureException { } } catch (IOException e) { throw new MojoFailureException( - "Failed to write dependencies to file " + dependenciesFile.toString(), e); + "Failed to write dependencies to file " + dependenciesFile, e); } - getLog().info("Dependencies were written to " + dependenciesFile.toAbsolutePath().toString()); + getLog().info("Dependencies were written to " + dependenciesFile.toAbsolutePath()); } private String summariseArtifact(Artifact artifact) { From 81ceda0989aa21ab92e5e903505ecb1017925e7f Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Thu, 8 Aug 2024 16:01:25 +0100 Subject: [PATCH 16/20] Read classpath entries from possibly any number of *dependencies.txt --- .../scip_java/buildtools/ClasspathEntry.scala | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/ClasspathEntry.scala b/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/ClasspathEntry.scala index b7caebcd..061e5e7f 100644 --- a/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/ClasspathEntry.scala +++ b/scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/ClasspathEntry.scala @@ -38,6 +38,9 @@ object ClasspathEntry { * - javacopts.txt: line-separated list of Java compiler options. * - dependencies.txt: line-separated list of dependency information. * + * Note that the targetroot can contain several files with names ending in + * "dependencies.txt" - for example if they come from a multi-module build. + * * @param targetroot * @return */ @@ -46,18 +49,34 @@ object ClasspathEntry { sourceroot: Path ): List[ClasspathEntry] = { val javacopts = targetroot.resolve("javacopts.txt") - val dependencies = targetroot.resolve("dependencies.txt") - if (Files.isRegularFile(dependencies)) { - fromDependencies(dependencies) - } else if (Files.isRegularFile(javacopts)) { + if (Files.isRegularFile(javacopts)) fromJavacopts(javacopts, sourceroot) - } else { - Nil - } + else + discoverDependenciesFromFiles(targetroot) + } + + /** + * Discover all files that end in "dependencies.txt" directly under + * targetroot. There can be many files because we will be writing dependencies + * for multiple projects. + * + * @param targetroot + * @return classpath entries read from the discovered files + */ + private def discoverDependenciesFromFiles( + targetroot: Path + ): List[ClasspathEntry] = { + os.list + .stream(os.Path(targetroot)) + .filter(p => os.isFile(p) && p.last.endsWith("dependencies.txt")) + .map(path => fromDependencies(path.toNIO)) + .toList + .flatten + .distinct } /** - * Parses ClasspathEntry from a "dependencies.txt" file in the targetroot. + * Parses ClasspathEntry from a "dependencies.txt" file * * Every line of the file is a tab separated value with the following columns: * groupId, artifactId, version, path to the jar file OR classes directory From c9314815cfaa159a3ba31c503b92b5f04e96cad1 Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Thu, 8 Aug 2024 16:01:48 +0100 Subject: [PATCH 17/20] Add documentation for maven plugin --- docs/manual-configuration.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/manual-configuration.md b/docs/manual-configuration.md index 3b1c1c03..60744883 100644 --- a/docs/manual-configuration.md +++ b/docs/manual-configuration.md @@ -156,6 +156,9 @@ index.scip: JSON data ## Step 5 (optional): Enable cross-repository navigation +Cross-repository navigation is a feature that allows "goto definition" and "find +references" to show results from multiple repositories. + By default, the `index.scip` file only enables navigation within the local repository. You can optionally enable cross-repository navigation by creating one of the following files in the SemanticDB _targetroot_ directory (the path in @@ -193,5 +196,35 @@ one of the following files in the SemanticDB _targetroot_ directory (the path in your Sourcegraph instance has another repository that defines that symbol, the cross-repository navigation should succeed. +### Maven plugin + +To simplify setting up cross-repo navigation for Maven projects, we provide a +plugin that can dump the project's dependencies in a format that scip-java understands. + +You can either use it directly from commandline: + +``` +$ mvn com.sourcegraph:maven-plugin:@STABLE_VERSION@:sourcegraphDependencies +``` + +Or add it to your build like any other maven plugin: + +```xml + + com.sourcegraph + maven-plugin + @STABLE_VERSION@ + + + + sourcegraphDependencies + + + + +``` + +Which allows you to invoke it by simply running `mvn sourcegraph:sourcegraphDependencies`. + Cross-repository navigation is a feature that allows "goto definition" and "find references" to show results from multiple repositories. From 15a9669a9a88bdad02ea724b07c6009f3479fbdd Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Thu, 8 Aug 2024 16:02:10 +0100 Subject: [PATCH 18/20] formatting --- .../main/java/com/sourcegraph/maven/DependencyWriterMojo.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java b/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java index e38caada..3e944967 100644 --- a/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java +++ b/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java @@ -87,8 +87,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { writer.write(builder.toString()); } } catch (IOException e) { - throw new MojoFailureException( - "Failed to write dependencies to file " + dependenciesFile, e); + throw new MojoFailureException("Failed to write dependencies to file " + dependenciesFile, e); } getLog().info("Dependencies were written to " + dependenciesFile.toAbsolutePath()); From 8604307911d419a174937eb7280f5d466bf1742b Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Thu, 8 Aug 2024 16:12:18 +0100 Subject: [PATCH 19/20] Relax path matching in maven CI --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0b1bac21..5ea69719 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -143,8 +143,8 @@ jobs: - run: | set -e - grep org.hamcrest target/semanticdb-targetroot/dependencies.txt - grep $PWD/src/main/java target/semanticdb-targetroot/dependencies.txt + grep org.hamcrest target/semanticdb-targetroot/*dependencies.txt + grep $PWD/src/main/java target/semanticdb-targetroot/*dependencies.txt working-directory: examples/maven-example - run: du -h index.scip From 3967d268e1ea419f65462b3931a0e47164a7e934 Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Thu, 8 Aug 2024 16:34:03 +0100 Subject: [PATCH 20/20] Remove print --- .../main/java/com/sourcegraph/maven/DependencyWriterMojo.java | 1 - 1 file changed, 1 deletion(-) diff --git a/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java b/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java index 3e944967..2b1dbd6b 100644 --- a/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java +++ b/maven-plugin/src/main/java/com/sourcegraph/maven/DependencyWriterMojo.java @@ -49,7 +49,6 @@ public void execute() throws MojoExecutionException, MojoFailureException { + "See here for more details: https://sourcegraph.github.io/scip-java/docs/manual-configuration.html#step-5-optional-enable-cross-repository-navigation\n"); } else { for (Object root : sourceRoots) { - getLog().info(root.toString()); if (root instanceof String) { String rootString = (String) root; builder.append(