Skip to content

Commit

Permalink
[java] Build tools should not spoil the temp dir
Browse files Browse the repository at this point in the history
  • Loading branch information
barancev committed Apr 15, 2020
1 parent aec3619 commit 729df65
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 81 deletions.
3 changes: 3 additions & 0 deletions java/client/src/org/openqa/selenium/io/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ java_library(
visibility = [
"//java/client/src/org/openqa/selenium/os:__pkg__",
"//java/client/src/org/openqa/selenium/remote:__pkg__",
"//java/client/src/org/openqa/selenium/tools/jar:__pkg__",
"//java/client/src/org/openqa/selenium/tools/javadoc:__pkg__",
"//java/client/src/org/openqa/selenium/tools/modules:__pkg__",
"//java/client/test/org/openqa/selenium/io:__pkg__",
],
deps = [
Expand Down
1 change: 1 addition & 0 deletions java/client/src/org/openqa/selenium/tools/jar/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ java_binary(
"//visibility:public",
],
deps = [
"//java/client/src/org/openqa/selenium/io",
],
)
8 changes: 7 additions & 1 deletion java/client/src/org/openqa/selenium/tools/jar/MergeJars.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.openqa.selenium.tools.jar;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
Expand Down Expand Up @@ -46,6 +47,8 @@
import static java.util.zip.Deflater.BEST_COMPRESSION;
import static java.util.zip.ZipOutputStream.DEFLATED;

import org.openqa.selenium.io.TemporaryFilesystem;

public class MergeJars {

// File time is taken from the epoch (1970-01-01T00:00:00Z), but zip files
Expand Down Expand Up @@ -91,7 +94,8 @@ public static void main(String[] args) throws IOException {

// 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");
File tempDir = TemporaryFilesystem.getDefaultTmpFS().createTempDir("mergejars", "");
Path temp = tempDir.toPath();

Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
Expand Down Expand Up @@ -215,6 +219,8 @@ public static void main(String[] args) throws IOException {
}
});
}

TemporaryFilesystem.getDefaultTmpFS().deleteTempDir(tempDir);
}

private static JarEntry resetTime(JarEntry entry) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ java_binary(
"-target", "11",
],
deps = [
"//java/client/src/org/openqa/selenium/io",
"//java/client/src/org/openqa/selenium/tools/zip",
],
visibility = [
Expand Down
147 changes: 70 additions & 77 deletions java/client/src/org/openqa/selenium/tools/javadoc/JavadocJarMaker.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.openqa.selenium.tools.javadoc;

import org.openqa.selenium.io.TemporaryFilesystem;
import org.openqa.selenium.tools.zip.StableZipEntry;

import javax.tools.DocumentationTool;
Expand Down Expand Up @@ -82,98 +83,90 @@ public static void main(String[] args) throws IOException {
throw new IllegalArgumentException("The output jar location must be specified via the --out flag");
}

Set<Path> tempDirs = new HashSet<>();
Path dir = Files.createTempDirectory("javadocs");
TemporaryFilesystem tmpFS = TemporaryFilesystem.getDefaultTmpFS();
Set<File> tempDirs = new HashSet<>();
File dir = tmpFS.createTempDir("javadocs", "");
tempDirs.add(dir);

try {
DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
try (StandardJavaFileManager fileManager = tool.getStandardFileManager(null, Locale.getDefault(), UTF_8)) {
fileManager.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, List.of(dir.toFile()));
fileManager.setLocation(StandardLocation.CLASS_PATH, classpath.stream().map(Path::toFile).collect(Collectors.toSet()));

Set<JavaFileObject> sources = new HashSet<>();
Set<String> topLevelPackages = new HashSet<>();

Path unpackTo = Files.createTempDirectory("unpacked-sources");
tempDirs.add(unpackTo);
Set<String> fileNames = new HashSet<>();
readSourceFiles(unpackTo, fileManager, sourceJars, sources, topLevelPackages, fileNames);

// True if we're just exporting a set of modules
if (sources.isEmpty()) {
try (OutputStream os = Files.newOutputStream(out);
ZipOutputStream zos = new ZipOutputStream(os)) {
// It's enough to just create the thing
}
return;
}
DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
try (StandardJavaFileManager fileManager = tool.getStandardFileManager(null, Locale.getDefault(), UTF_8)) {
fileManager.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, List.of(dir));
fileManager.setLocation(StandardLocation.CLASS_PATH, classpath.stream().map(Path::toFile).collect(Collectors.toSet()));

Set<JavaFileObject> sources = new HashSet<>();
Set<String> topLevelPackages = new HashSet<>();

File unpackTo = tmpFS.createTempDir("unpacked-sources", "");
tempDirs.add(unpackTo);
Set<String> fileNames = new HashSet<>();
readSourceFiles(unpackTo.toPath(), fileManager, sourceJars, sources, topLevelPackages, fileNames);

List<String> options = new ArrayList<>();
if (!classpath.isEmpty()) {
options.add("-cp");
options.add(classpath.stream().map(String::valueOf).collect(Collectors.joining(File.pathSeparator)));
// True if we're just exporting a set of modules
if (sources.isEmpty()) {
try (OutputStream os = Files.newOutputStream(out);
ZipOutputStream zos = new ZipOutputStream(os)) {
// It's enough to just create the thing
}
options.addAll(List.of("-html5", "--frames", "-notimestamp", "-use", "-quiet", "-Xdoclint:-missing", "-encoding", "UTF8"));
return;
}

List<String> options = new ArrayList<>();
if (!classpath.isEmpty()) {
options.add("-cp");
options.add(classpath.stream().map(String::valueOf).collect(Collectors.joining(File.pathSeparator)));
}
options.addAll(List.of("-html5", "--frames", "-notimestamp", "-use", "-quiet", "-Xdoclint:-missing", "-encoding", "UTF8"));

Path outputTo = Files.createTempDirectory("output-dir");
tempDirs.add(outputTo);

options.addAll(List.of("-d", outputTo.toAbsolutePath().toString()));
File outputTo = tmpFS.createTempDir("output-dir", "");
tempDirs.add(outputTo);
Path outputToPath = outputTo.toPath();

sources.forEach(obj -> options.add(obj.getName()));
options.addAll(List.of("-d", outputTo.getAbsolutePath()));

Writer writer = new StringWriter();
DocumentationTool.DocumentationTask task = tool.getTask(writer, fileManager, null, null, options, sources);
Boolean result = task.call();
if (result == null || !result) {
System.err.println("javadoc " + String.join(" ", options));
System.err.println(writer);
return;
}
sources.forEach(obj -> options.add(obj.getName()));

try (OutputStream os = Files.newOutputStream(out);
ZipOutputStream zos = new ZipOutputStream(os);
Stream<Path> walk = Files.walk(outputTo)) {
walk.sorted(Comparator.naturalOrder())
.forEachOrdered(path -> {
if (path.equals(outputTo)) {
return;
}
Writer writer = new StringWriter();
DocumentationTool.DocumentationTask task = tool.getTask(writer, fileManager, null, null, options, sources);
Boolean result = task.call();
if (result == null || !result) {
System.err.println("javadoc " + String.join(" ", options));
System.err.println(writer);
return;
}

try {
if (Files.isDirectory(path)) {
String name = outputTo.relativize(path) + "/";
ZipEntry entry = new StableZipEntry(name);
zos.putNextEntry(entry);
zos.closeEntry();
} else {
String name = outputTo.relativize(path).toString();
ZipEntry entry = new StableZipEntry(name);
zos.putNextEntry(entry);
try (InputStream is = Files.newInputStream(path)) {
is.transferTo(zos);
}
zos.closeEntry();
try (OutputStream os = Files.newOutputStream(out);
ZipOutputStream zos = new ZipOutputStream(os);
Stream<Path> walk = Files.walk(outputToPath)) {
walk.sorted(Comparator.naturalOrder())
.forEachOrdered(path -> {
if (path.equals(outputToPath)) {
return;
}

try {
if (Files.isDirectory(path)) {
String name = outputToPath.relativize(path) + "/";
ZipEntry entry = new StableZipEntry(name);
zos.putNextEntry(entry);
zos.closeEntry();
} else {
String name = outputToPath.relativize(path).toString();
ZipEntry entry = new StableZipEntry(name);
zos.putNextEntry(entry);
try (InputStream is = Files.newInputStream(path)) {
is.transferTo(zos);
}
} catch (IOException e) {
throw new UncheckedIOException(e);
zos.closeEntry();
}
});
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
}
} finally {
tempDirs.forEach(d -> {
try (Stream<Path> walk = Files.walk(d)) {
walk.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
} catch (IOException e) {
e.printStackTrace();
}
});
}

tempDirs.forEach(tmpFS::deleteTempDir);
}

private static void readSourceFiles(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ java_binary(
main_class = "org.openqa.selenium.tools.modules.ModuleGenerator",
visibility = ["//visibility:public"],
deps = [
"//java/client/src/org/openqa/selenium/io",
"//java/client/src/org/openqa/selenium/tools/zip",
artifact("net.bytebuddy:byte-buddy"),
artifact("com.github.javaparser:javaparser-core"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import net.bytebuddy.jar.asm.ClassWriter;
import net.bytebuddy.jar.asm.ModuleVisitor;

import org.openqa.selenium.io.TemporaryFilesystem;
import org.openqa.selenium.tools.zip.StableZipEntry;

import java.io.ByteArrayOutputStream;
Expand Down Expand Up @@ -149,7 +151,8 @@ public static void main(String[] args) throws IOException {
Objects.requireNonNull(inJar, "Input jar must be set.");

ToolProvider jdeps = ToolProvider.findFirst("jdeps").orElseThrow();
Path tempDir = Files.createTempDirectory("module-dir");
File tempDir = TemporaryFilesystem.getDefaultTmpFS().createTempDir("module-dir", "");
Path temp = tempDir.toPath();

// It doesn't matter what we use for writing to the stream: jdeps doesn't use it. *facepalm*
List<String> jdepsArgs = new LinkedList<>(
Expand All @@ -159,7 +162,7 @@ public static void main(String[] args) throws IOException {
if (!modulePath.isEmpty()) {
jdepsArgs.addAll(List.of("--module-path", modulePath.stream().map(Object::toString).collect(Collectors.joining(File.pathSeparator))));
}
jdepsArgs.addAll(List.of("--generate-module-info", tempDir.toAbsolutePath().toString()));
jdepsArgs.addAll(List.of("--generate-module-info", temp.toAbsolutePath().toString()));
jdepsArgs.add(inJar.toAbsolutePath().toString());

PrintStream origOut = System.out;
Expand All @@ -186,7 +189,7 @@ public static void main(String[] args) throws IOException {

AtomicReference<Path> moduleInfo = new AtomicReference<>();
// Fortunately, we know the directory where the output is written
Files.walkFileTree(tempDir, new SimpleFileVisitor<>() {
Files.walkFileTree(temp, new SimpleFileVisitor<>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if ("module-info.java".equals(file.getFileName().toString())) {
Expand Down Expand Up @@ -306,6 +309,8 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
jos.write(bytes);
jos.closeEntry();
}

TemporaryFilesystem.getDefaultTmpFS().deleteTempDir(tempDir);
}

private static Set<String> inferPackages(Path inJar) {
Expand Down

0 comments on commit 729df65

Please sign in to comment.