-
-
Notifications
You must be signed in to change notification settings - Fork 260
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* maven_jar migration script WIP * WIP: Java version of maven_jar migration tool * Add automatic buildozer feature * Remove shell script * remove unused sh_binary * Fix imports and refactor * Fixed package * Generate compat repositories and pin versions by default * Add a note about maven_install.json * Revert "Add a note about maven_install.json" This reverts commit 4703d6e. * Address laurent's comments * Add note about buildozer prerequisite.
- Loading branch information
Showing
6 changed files
with
235 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
licenses(["notice"]) | ||
|
||
exports_files(["maven_jar_migrator_deps.bzl"]) | ||
|
||
java_binary( | ||
name = "maven_jar", | ||
srcs = ["java/rules/jvm/external/MavenJarMigrator.java"], | ||
main_class = "rules.jvm.external.MavenJarMigrator", | ||
resources = ["java/rules/jvm/external/resources/workspace_template.txt"], | ||
deps = [ | ||
"@maven_jar_migrator//:com_google_guava_guava", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# `maven_jar` migration tool | ||
|
||
`maven_jar` will be removed from Bazel 2.0 onwards. See [this issue](https://github.com/bazelbuild/bazel/issues/6799) for more information. | ||
|
||
This tool helps to automatically migrate your project from `maven_jar` to `maven_install` provided by `rules_jvm_external`. | ||
|
||
These PRs were generated using this tool: | ||
|
||
* https://github.com/google/copybara/pull/96 | ||
* https://github.com/kythe/kythe/pull/4180 | ||
* https://github.com/bazelbuild/rules_k8s/pull/463 | ||
|
||
## Prerequisites | ||
|
||
* [Buildozer](https://github.com/bazelbuild/buildtools/releases). Ensure that the `buildozer` is available in your `PATH`. | ||
|
||
## Usage | ||
|
||
First, add the latest version of `rules_jvm_external` to your WORKSPACE by | ||
following the instructions on the | ||
[releases](https://github.com/bazelbuild/rules_jvm_external/releases) page. | ||
|
||
Then, add the following to your WORKSPACE to load the migrator's | ||
dependencies: | ||
|
||
```python | ||
load("@rules_jvm_external//:defs.bzl", "maven_install") | ||
load("@rules_jvm_external//migration:maven_jar_migrator_deps.bzl", "maven_jar_migrator_repositories") | ||
maven_jar_migrator_repositories() | ||
``` | ||
|
||
Next, run this command in root of project workspace to generate the | ||
`maven_install` WORKSPACE snippet: | ||
|
||
``` | ||
$ bazel run @rules_jvm_external//migration:maven_jar | ||
``` | ||
|
||
This command will also run the buildozer commands to migrate your project to | ||
use the new `maven_install` labels. | ||
|
||
If the snippet looks good, concatenate it to the end of your WORKSPACE file: | ||
|
||
``` | ||
$ bazel run @rules_jvm_external//migration:maven_jar >> WORKSPACE | ||
``` | ||
|
||
Finally, if the build continues to succeed, you can remove | ||
`maven_jar_migrator_repositories` from your WORKSPACE file. |
137 changes: 137 additions & 0 deletions
137
migration/java/rules/jvm/external/MavenJarMigrator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package rules.jvm.external; | ||
|
||
import com.google.common.base.Joiner; | ||
import com.google.common.collect.ImmutableList; | ||
import com.google.common.io.ByteStreams; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.File; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.InputStreamReader; | ||
import java.util.Iterator; | ||
import java.util.function.Function; | ||
import java.util.stream.Collectors; | ||
|
||
import static java.nio.charset.StandardCharsets.UTF_8; | ||
|
||
/** A migration tool from native.maven_jar to rules_jvm_external's maven_install. */ | ||
public class MavenJarMigrator { | ||
|
||
// Defined by Bazel during a `bazel run`. | ||
private static final String BUILD_WORKING_DIRECTORY = System.getenv("BUILD_WORKING_DIRECTORY"); | ||
// Converts a Maven coordinate to a valid maven_install target label. | ||
// e.g. com.google.guava:guava:28.0-jre -> @maven//:com_google_guava_guava | ||
private static final Function<String, String> convertCoordinateToNewLabel = | ||
(String coordinate) -> { | ||
coordinate = coordinate.replace("-", "_").replace(".", "_"); | ||
String[] parts = coordinate.split(":"); | ||
return "@maven//:" + Joiner.on("_").join(parts[0], parts[1]); | ||
}; | ||
|
||
public static void main(String[] args) throws IOException, InterruptedException { | ||
checkPrerequisites(); | ||
|
||
ImmutableList<String> coordinates = collectMavenJarAttributeValues("artifact"); | ||
// Phase 1: Run buildozer to convert old maven_jar labels to new maven_install labels. | ||
convertLabels(coordinates); | ||
// Phase 2: Print maven_install WORKSPACE snippet on stdout. | ||
System.out.println(generateWorkspaceSnippet(coordinates)); | ||
} | ||
|
||
private static void checkPrerequisites() throws InterruptedException, IOException { | ||
// Assert that buildozer exists on PATH. | ||
if (getProcessBuilder("buildozer", "-version").start().waitFor() != 0) { | ||
throw new AssertionError("buildozer is not found on your PATH. Download " | ||
+ "buildozer for your platform from https://github.com/bazelbuild/buildtools/releases " | ||
+ "and put the executable in your PATH."); | ||
} | ||
} | ||
|
||
/** | ||
* Converts the old style maven_jar labels to the new style maven_install labels. | ||
* | ||
* <p>This implementation assumes that the sortedness output of bazel query --output=build is | ||
* deterministic. | ||
* | ||
* @param coordinates A list of coordinates to derive the old and new labels. | ||
* @throws IOException | ||
* @throws InterruptedException | ||
*/ | ||
private static void convertLabels(ImmutableList<String> coordinates) | ||
throws IOException, InterruptedException { | ||
ImmutableList<String> oldLabels = | ||
collectMavenJarAttributeValues("name").stream() | ||
.map((String name) -> String.format("@%s//jar", name)) | ||
.collect(ImmutableList.toImmutableList()); | ||
ImmutableList<String> newLabels = | ||
coordinates.stream() | ||
.map(convertCoordinateToNewLabel) | ||
.collect(ImmutableList.toImmutableList()); | ||
|
||
assert (newLabels.size() == oldLabels.size()); | ||
Iterator<String> oldLabelIterator = oldLabels.iterator(); | ||
Iterator<String> newLabelIterator = newLabels.iterator(); | ||
while (oldLabelIterator.hasNext()) { | ||
getProcessBuilder( | ||
"buildozer", | ||
"substitute * " + oldLabelIterator.next() + " " + newLabelIterator.next(), | ||
"//...:*") | ||
.start() | ||
.waitFor(); | ||
} | ||
} | ||
|
||
private static String generateWorkspaceSnippet(ImmutableList<String> coordinates) | ||
throws IOException { | ||
InputStream stream = | ||
MavenJarMigrator.class.getResourceAsStream("resources/workspace_template.txt"); | ||
String workspaceTemplate = new String(ByteStreams.toByteArray(stream), UTF_8); | ||
return workspaceTemplate.replace( | ||
"%maven_artifact_list%", | ||
coordinates.stream() | ||
.sorted() | ||
.map((String line) -> " \"" + line + "\",") | ||
.collect(Collectors.joining("\n"))); | ||
} | ||
|
||
/** | ||
* Aggregate information about an attribute on all maven_jar targets using bazel query. | ||
* | ||
* <p>The maven_jar declaration does not need to be in the local WORKSPACE. It can be a maven_jar | ||
* declaration loaded from a remote repository's deps.bzl. | ||
* | ||
* @return A list of Maven artifact coordinates used by this workspace. | ||
* @throws IOException | ||
* @throws InterruptedException | ||
*/ | ||
private static ImmutableList<String> collectMavenJarAttributeValues(String attribute) | ||
throws IOException, InterruptedException { | ||
ProcessBuilder processBuilder = | ||
getProcessBuilder( | ||
"bazel", | ||
"query", | ||
"kind(maven_jar, //external:all)", | ||
"--output=build", | ||
"--noshow_progress"); | ||
|
||
return readOutput(processBuilder.start()).stream() | ||
.filter((String line) -> line.trim().startsWith(attribute)) | ||
.map((String line) -> line.split("\"")[1]) // get the value in a string attribute | ||
.collect(ImmutableList.toImmutableList()); | ||
} | ||
|
||
private static ProcessBuilder getProcessBuilder(String... args) { | ||
ProcessBuilder processBuilder = new ProcessBuilder(); | ||
processBuilder.directory(new File(BUILD_WORKING_DIRECTORY)); | ||
processBuilder.command(args); | ||
return processBuilder; | ||
} | ||
|
||
private static ImmutableList<String> readOutput(Process p) throws InterruptedException { | ||
// ensure that the process is completed before reading the standard output. | ||
p.waitFor(); | ||
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); | ||
return br.lines().collect(ImmutableList.toImmutableList()); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
migration/java/rules/jvm/external/resources/workspace_template.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
load("@rules_jvm_external//:defs.bzl", "maven_install") | ||
|
||
maven_install( | ||
name = "maven", | ||
artifacts = [ | ||
%maven_artifact_list% | ||
], | ||
repositories = [ | ||
"https://jcenter.bintray.com", | ||
"https://maven.google.com", | ||
"https://repo1.maven.org/maven2", | ||
], | ||
fetch_sources = True, | ||
version_conflict_policy = "pinned", | ||
# See https://github.com/bazelbuild/rules_jvm_external/#repository-aliases | ||
# This can be removed if none of your external dependencies uses `maven_jar`. | ||
generate_compat_repositories = True, | ||
) | ||
load("@maven//:compat.bzl", "compat_repositories") | ||
compat_repositories() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
load("@rules_jvm_external//:defs.bzl", "maven_install") | ||
|
||
def maven_jar_migrator_repositories(): | ||
maven_install( | ||
name = "maven_jar_migrator", | ||
artifacts = [ | ||
"com.google.guava:guava:28.0-jre", | ||
], | ||
repositories = [ | ||
"https://repo1.maven.org/maven2", | ||
"https://jcenter.bintray.com", | ||
], | ||
) |