Skip to content

Commit

Permalink
[bazel] Automatically generate java 9 modules for java_export
Browse files Browse the repository at this point in the history
  • Loading branch information
shs96c committed Aug 24, 2019
1 parent 753dcb8 commit f6f9c87
Show file tree
Hide file tree
Showing 42 changed files with 963 additions and 60 deletions.
2 changes: 1 addition & 1 deletion java/client/src/org/openqa/selenium/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
load("//java:version.bzl", "SE_VERSION")
load("//java:maven.bzl", "java_export")
load("//java:defs.bzl", "java_export")

filegroup(
name = "template-pom",
Expand Down
2 changes: 1 addition & 1 deletion java/client/src/org/openqa/selenium/chrome/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//java:maven.bzl", "java_export")
load("//java:defs.bzl", "java_export")
load("//java:version.bzl", "SE_VERSION")

java_export(
Expand Down
2 changes: 1 addition & 1 deletion java/client/src/org/openqa/selenium/chromium/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//java:maven.bzl", "java_export")
load("//java:defs.bzl", "java_export")
load("//java:version.bzl", "SE_VERSION")

java_export(
Expand Down
2 changes: 1 addition & 1 deletion java/client/src/org/openqa/selenium/devtools/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//java:maven.bzl", "java_export")
load("//java:defs.bzl", "java_export")
load("//java:version.bzl", "SE_VERSION")

java_export(
Expand Down
2 changes: 1 addition & 1 deletion java/client/src/org/openqa/selenium/edge/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//java:maven.bzl", "java_export")
load("//java:defs.bzl", "java_export")
load("//java:version.bzl", "SE_VERSION")

java_library(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//java:maven.bzl", "java_export")
load("//java:defs.bzl", "java_export")
load("//java:version.bzl", "SE_VERSION")

java_export(
Expand Down
2 changes: 1 addition & 1 deletion java/client/src/org/openqa/selenium/firefox/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//java:maven.bzl", "java_export")
load("//java:defs.bzl", "java_export")
load("//java:version.bzl", "SE_VERSION")
load("//:copy_file.bzl", "copy_file")

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//java:maven.bzl", "java_export")
load("//java:defs.bzl", "java_export")
load("//java:version.bzl", "SE_VERSION")
load("//:copy_file.bzl", "copy_file")

Expand Down
2 changes: 1 addition & 1 deletion java/client/src/org/openqa/selenium/ie/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//java:maven.bzl", "java_export")
load("//java:defs.bzl", "java_export")
load("//java:version.bzl", "SE_VERSION")

java_export(
Expand Down
2 changes: 1 addition & 1 deletion java/client/src/org/openqa/selenium/json/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//java:maven.bzl", "java_export")
load("//java:defs.bzl", "java_export")
load("//java:version.bzl", "SE_VERSION")

java_export(
Expand Down
2 changes: 1 addition & 1 deletion java/client/src/org/openqa/selenium/lift/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//java:maven.bzl", "java_export")
load("//java:defs.bzl", "java_export")
load("//java:version.bzl", "SE_VERSION")

java_export(
Expand Down
2 changes: 1 addition & 1 deletion java/client/src/org/openqa/selenium/opera/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//java:maven.bzl", "java_export")
load("//java:defs.bzl", "java_export")
load("//java:version.bzl", "SE_VERSION")

java_export(
Expand Down
2 changes: 1 addition & 1 deletion java/client/src/org/openqa/selenium/remote/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
load("//java:defs.bzl", "java_export")
load("//java:version.bzl", "SE_VERSION")
load("//java:maven.bzl", "java_export")

java_library(
name = "api",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//java:maven.bzl", "java_export")
load("//java:defs.bzl", "java_export")
load("//java:version.bzl", "SE_VERSION")

java_export(
Expand Down
2 changes: 1 addition & 1 deletion java/client/src/org/openqa/selenium/safari/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//java:maven.bzl", "java_export")
load("//java:defs.bzl", "java_export")
load("//java:version.bzl", "SE_VERSION")

java_export(
Expand Down
2 changes: 1 addition & 1 deletion java/client/src/org/openqa/selenium/support/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//java:maven.bzl", "java_export")
load("//java:defs.bzl", "java_export")
load("//java:version.bzl", "SE_VERSION")

java_export(
Expand Down
13 changes: 13 additions & 0 deletions java/client/src/org/openqa/selenium/tools/jar/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
java_binary(
name = "MergeJars",
srcs = glob(["*.java"]),
javacopts = [
"-source", "11",
"-target", "11",
],
deps = [
],
visibility = [
"//visibility:public",
]
)
217 changes: 217 additions & 0 deletions java/client/src/org/openqa/selenium/tools/jar/MergeJars.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package org.openqa.selenium.tools.jar;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileTime;
import java.time.Instant;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import static java.util.zip.Deflater.BEST_COMPRESSION;
import static java.util.zip.ZipOutputStream.DEFLATED;

public class MergeJars {

// File time is taken from the epoch (1970-01-01T00:00:00Z), but zip files
// have a different epoch. Oof. Make something sensible up.
private static final FileTime DOS_EPOCH = FileTime.from(Instant.parse("1985-02-01T00:00:00.00Z"));

public static void main(String[] args) throws IOException {
Path out = null;
SortedSet<Path> sources = new TreeSet<>();

for (int i = 0; i < args.length; i++) {
switch (args[i]) {
case "--compression":
case "--normalize":
// ignore
break;

case "--output":
out = Paths.get(args[++i]);
break;

case "--sources":
Path path = Paths.get(args[++i]);
if (!Files.exists(path) || !Files.isReadable(path)) {
throw new IllegalArgumentException("Source must a readable file: " + path);
}
sources.add(path);
break;

default:
throw new IllegalArgumentException("Unable to parse command line: " + Arrays.toString(args));
}
}

Objects.requireNonNull(out, "Output path must be set.");
if (sources.isEmpty()) {
// Just write an empty jar and leave
try (OutputStream fos = Files.newOutputStream(out);
JarOutputStream jos = new JarOutputStream(fos)) {
}
return;
}

// To keep things simple, we expand all the inputs jars into a single directory,
// merge the manifests, and then create our own zip.
Path temp = Files.createTempDirectory("mergejars");

Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");

SortedMap<Path, SortedMap<Path, Path>> allPaths = new TreeMap<>();

for (Path source : sources) {
try (InputStream fis = Files.newInputStream(source);
ZipInputStream zis = new ZipInputStream(fis)) {

ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
if ("META-INF/MANIFEST.MF".equals(entry.getName())) {
Manifest other = new Manifest(zis);
manifest = merge(manifest, other);
continue;
}

if (entry.isDirectory()) {
// Skip it.
zis.readAllBytes();
continue;
}

// TODO: merge services files

Path outPath = temp.resolve(entry.getName()).normalize();
if (!outPath.startsWith(temp)) {
throw new IllegalStateException("Attempt to write jar entry somewhere weird: " + outPath);
}
if (!Files.exists(outPath.getParent())) {
Files.createDirectories(outPath.getParent());
}
try (OutputStream os = Files.newOutputStream(outPath)) {
zis.transferTo(os);
}

SortedMap<Path, Path> dirPaths = allPaths.computeIfAbsent(
temp.relativize(outPath.getParent()),
path -> new TreeMap<>());
dirPaths.put(temp.relativize(outPath), outPath);
}
}
}

manifest.getMainAttributes().put(new Attributes.Name("Created-By"), "mergejars");

Set<String> seen = new HashSet<>(Set.of("META-INF/", "META-INF/MANIFEST.MF"));

// Now create the output jar
try (OutputStream os = Files.newOutputStream(out);
JarOutputStream jos = new JarOutputStream(os)) {
jos.setMethod(DEFLATED);
jos.setLevel(BEST_COMPRESSION);

// Write the manifest by hand to ensure the date is good
JarEntry entry = new JarEntry("META-INF/");
entry = resetTime(entry);
jos.putNextEntry(entry);
jos.closeEntry();

entry = new JarEntry("META-INF/MANIFEST.MF");
entry = resetTime(entry);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
manifest.write(bos);
entry.setSize(bos.size());
jos.putNextEntry(entry);
jos.write(bos.toByteArray());
jos.closeEntry();

allPaths.forEach((dir, entries) -> {
try {
String name = dir.toString() + "/";
if (seen.add(name)) {
JarEntry je = new JarEntry(name);
je = resetTime(je);
jos.putNextEntry(je);
jos.closeEntry();
}

for (Map.Entry<Path, Path> me : entries.entrySet()) {
name = me.getKey().toString();

if (seen.add(name)) {
JarEntry je = new JarEntry(name);
je = resetTime(je);
jos.putNextEntry(je);
try (InputStream fis = Files.newInputStream(me.getValue())) {
fis.transferTo(jos);
}
jos.closeEntry();
}
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
}
}

private static JarEntry resetTime(JarEntry entry) {
entry.setTime(DOS_EPOCH.toMillis());
return entry;
}

private static Manifest merge(Manifest into, Manifest from) {
Attributes attributes = from.getMainAttributes();
if (attributes != null) {
attributes.forEach((key, value) -> into.getMainAttributes().put(key, value));
}

from.getEntries().forEach((key, value) -> {
Attributes attrs = into.getAttributes(key);
if (attrs == null) {
attrs = new Attributes();
into.getEntries().put(key, attrs);
}
attrs.putAll(value);
});

return into;
}
}
15 changes: 15 additions & 0 deletions java/client/src/org/openqa/selenium/tools/modules/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
java_binary(
name = "ModuleGenerator",
srcs = glob(["*.java"]),
main_class = "org.openqa.selenium.tools.modules.ModuleGenerator",
javacopts = [
"-source", "11",
"-target", "11",
],
deps = [
"//third_party/java/bytebuddy:byte-buddy",
"//third_party/java/javaparser:javaparser-core",
],
visibility = ["//visibility:public"],
)

0 comments on commit f6f9c87

Please sign in to comment.