From 111626f4da2dda2804151e2fd3856e0512998e7f Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Thu, 30 Nov 2023 02:37:53 -0800 Subject: [PATCH] Add javax.tools.Tool implementation for google-java-format. PiperOrigin-RevId: 586609341 --- .../java/GoogleJavaFormatTool.java | 53 +++++++++++++++ .../java/GoogleJavaFormatToolProvider.java | 5 +- .../google/googlejavaformat/java/Main.java | 23 +++++-- .../GoogleJavaFormatToolProviderTest.java | 2 +- .../java/GoogleJavaFormatToolTest.java | 65 +++++++++++++++++++ 5 files changed, 138 insertions(+), 10 deletions(-) create mode 100644 core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatTool.java create mode 100644 core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java diff --git a/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatTool.java b/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatTool.java new file mode 100644 index 000000000..3c315aaf1 --- /dev/null +++ b/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatTool.java @@ -0,0 +1,53 @@ +/* + * Copyright 2021 Google Inc. + * + * Licensed 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 com.google.googlejavaformat.java; + +import static com.google.common.collect.Sets.toImmutableEnumSet; + +import com.google.auto.service.AutoService; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.Arrays; +import java.util.Set; +import javax.lang.model.SourceVersion; +import javax.tools.Tool; + +/** Provide a way to be invoked without necessarily starting a new VM. */ +@AutoService(Tool.class) +public class GoogleJavaFormatTool implements Tool { + @Override + public String name() { + return "google-java-format"; + } + + @Override + public Set getSourceVersions() { + return Arrays.stream(SourceVersion.values()).collect(toImmutableEnumSet()); + } + + @Override + public int run(InputStream in, OutputStream out, OutputStream err, String... args) { + PrintStream outStream = new PrintStream(out); + PrintStream errStream = new PrintStream(err); + try { + return Main.main(in, outStream, errStream, args); + } catch (RuntimeException e) { + errStream.print(e.getMessage()); + errStream.flush(); + return 1; // pass non-zero value back indicating an error has happened + } + } +} diff --git a/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProvider.java b/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProvider.java index 7bcad4cc5..438eac596 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProvider.java +++ b/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProvider.java @@ -29,10 +29,11 @@ public String name() { @Override public int run(PrintWriter out, PrintWriter err, String... args) { try { - return Main.main(out, err, args); + return Main.main(System.in, out, err, args); } catch (RuntimeException e) { err.print(e.getMessage()); - return -1; // pass non-zero value back indicating an error has happened + err.flush(); + return 1; // pass non-zero value back indicating an error has happened } } } diff --git a/core/src/main/java/com/google/googlejavaformat/java/Main.java b/core/src/main/java/com/google/googlejavaformat/java/Main.java index 62423f226..0845e0ec2 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Main.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Main.java @@ -26,6 +26,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; +import java.io.PrintStream; import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; @@ -66,20 +67,28 @@ public Main(PrintWriter outWriter, PrintWriter errWriter, InputStream inStream) * * @param args the command-line arguments */ - public static void main(String[] args) { - PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out, UTF_8)); - PrintWriter err = new PrintWriter(new OutputStreamWriter(System.err, UTF_8)); - int result = main(out, err, args); + public static void main(String... args) { + int result = main(System.in, System.out, System.err, args); System.exit(result); } /** - * Package-private main entry point used this CLI program and the java.util.spi.ToolProvider + * Package-private main entry point used by the {@link javax.tools.Tool Tool} implementation in + * the same package as this Main class. + */ + static int main(InputStream in, PrintStream out, PrintStream err, String... args) { + PrintWriter outWriter = new PrintWriter(new OutputStreamWriter(out, UTF_8)); + PrintWriter errWriter = new PrintWriter(new OutputStreamWriter(err, UTF_8)); + return main(in, outWriter, errWriter, args); + } + + /** + * Package-private main entry point used by the {@link java.util.spi.ToolProvider ToolProvider} * implementation in the same package as this Main class. */ - static int main(PrintWriter out, PrintWriter err, String... args) { + static int main(InputStream in, PrintWriter out, PrintWriter err, String... args) { try { - Main formatter = new Main(out, err, System.in); + Main formatter = new Main(out, err, in); return formatter.format(args); } catch (UsageException e) { err.print(e.getMessage()); diff --git a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java index d060fef1f..3d41a0733 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java @@ -46,7 +46,7 @@ public void testUsageOutputAfterLoadingViaToolName() { int result = format.run(new PrintWriter(out, true), new PrintWriter(err, true), "--help"); - assertThat(result).isEqualTo(2); + assertThat(result).isNotEqualTo(0); String usage = err.toString(); diff --git a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java new file mode 100644 index 000000000..691bb2234 --- /dev/null +++ b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2021 Google Inc. + * + * Licensed 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 com.google.googlejavaformat.java; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.ServiceLoader; +import javax.tools.Tool; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link GoogleJavaFormatToolProvider}. */ +@RunWith(JUnit4.class) +public class GoogleJavaFormatToolTest { + + @Test + public void testUsageOutputAfterLoadingViaToolName() { + String name = "google-java-format"; + + assertThat( + ServiceLoader.load(Tool.class).stream() + .map(ServiceLoader.Provider::get) + .map(Tool::name)) + .contains(name); + + Tool format = + ServiceLoader.load(Tool.class).stream() + .filter(provider -> name.equals(provider.get().name())) + .findFirst() + .get() + .get(); + + InputStream in = new ByteArrayInputStream(new byte[0]); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayOutputStream err = new ByteArrayOutputStream(); + + int result = format.run(in, out, err, "--help"); + + assertThat(result).isNotEqualTo(0); + + String usage = new String(err.toByteArray(), UTF_8); + + // Check that doc links are included. + assertThat(usage).containsMatch("http.*/google-java-format"); + assertThat(usage).contains("Usage: google-java-format"); + } +}