Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
charphi committed Jun 25, 2024
2 parents a7078e0 + bd8a64a commit a3a225b
Show file tree
Hide file tree
Showing 20 changed files with 139 additions and 55 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.0.30] - 2024-06-25

### Fixed

- Fix UTF8 encoding in PowerShellWrapper

## [0.0.29] - 2024-06-21

### Fixed
Expand Down Expand Up @@ -262,7 +268,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

- Initial release

[Unreleased]: https://github.com/nbbrd/java-io-util/compare/v0.0.29...HEAD
[Unreleased]: https://github.com/nbbrd/java-io-util/compare/v0.0.30...HEAD
[0.0.30]: https://github.com/nbbrd/java-io-util/compare/v0.0.29...v0.0.30
[0.0.29]: https://github.com/nbbrd/java-io-util/compare/v0.0.28...v0.0.29
[0.0.28]: https://github.com/nbbrd/java-io-util/compare/v0.0.27...v0.0.28
[0.0.27]: https://github.com/nbbrd/java-io-util/compare/v0.0.26...v0.0.27
Expand Down
2 changes: 1 addition & 1 deletion java-io-base/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.github.nbbrd.java-io-util</groupId>
<artifactId>java-io-parent</artifactId>
<version>0.0.29</version>
<version>0.0.30</version>
</parent>

<artifactId>java-io-base</artifactId>
Expand Down
32 changes: 28 additions & 4 deletions java-io-base/src/main/java/nbbrd/io/sys/ProcessReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,48 @@
@lombok.experimental.UtilityClass
public class ProcessReader {

@Deprecated
public static @NonNull BufferedReader newReader(@NonNull String... args) throws IOException {
return newReader(new ProcessBuilder(args).start());
return newReader(getSystemCharset(), args);
}

@Deprecated
public static @NonNull BufferedReader newReader(@NonNull Process process) {
return TextResource.newBufferedReader(new ProcessInputStream(process), Charset.defaultCharset());
return newReader(getSystemCharset(), process);
}

@Deprecated
public static @NonNull String readToString(@NonNull String... args) throws IOException {
return readToString(new ProcessBuilder(args).start());
return readToString(getSystemCharset(), args);
}

@Deprecated
public static @NonNull String readToString(@NonNull Process process) throws IOException {
try (BufferedReader reader = newReader(process)) {
return readToString(getSystemCharset(), process);
}

public static @NonNull BufferedReader newReader(@NonNull Charset charset, @NonNull String... args) throws IOException {
return newReader(charset, new ProcessBuilder(args).start());
}

public static @NonNull BufferedReader newReader(@NonNull Charset charset, @NonNull Process process) {
return TextResource.newBufferedReader(new ProcessInputStream(process), charset);
}

public static @NonNull String readToString(@NonNull Charset charset, @NonNull String... args) throws IOException {
return readToString(charset, new ProcessBuilder(args).start());
}

public static @NonNull String readToString(@NonNull Charset charset, @NonNull Process process) throws IOException {
try (BufferedReader reader = newReader(charset, process)) {
return InternalTextResource.copyByLineToString(reader, System.lineSeparator());
}
}

private static Charset getSystemCharset() {
return Charset.defaultCharset();
}

private static final class ProcessInputStream extends InputStream {

@lombok.experimental.Delegate(excludes = Closeable.class)
Expand Down
33 changes: 18 additions & 15 deletions java-io-base/src/test/java/nbbrd/io/sys/ProcessReaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,40 @@

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.UUID;

import static java.nio.charset.StandardCharsets.UTF_8;
import static nbbrd.io.sys.ProcessReader.newReader;
import static nbbrd.io.sys.ProcessReader.readToString;
import static org.assertj.core.api.Assertions.*;

public class ProcessReaderTest {

@SuppressWarnings({"resource", "DataFlowIssue", "deprecation"})
@Test
public void testFactories() {
assertThatNullPointerException()
.isThrownBy(() -> ProcessReader.newReader((String[]) null));
assertThatNullPointerException().isThrownBy(() -> newReader((String[]) null));
assertThatNullPointerException().isThrownBy(() -> newReader((Process) null));
assertThatNullPointerException().isThrownBy(() -> readToString((String[]) null));
assertThatNullPointerException().isThrownBy(() -> readToString((Process) null));

assertThatNullPointerException()
.isThrownBy(() -> ProcessReader.newReader((Process) null));

assertThatNullPointerException()
.isThrownBy(() -> ProcessReader.readToString((String[]) null));

assertThatNullPointerException()
.isThrownBy(() -> ProcessReader.readToString((Process) null));
assertThatNullPointerException().isThrownBy(() -> newReader(UTF_8, (String[]) null));
assertThatNullPointerException().isThrownBy(() -> newReader(UTF_8, (Process) null));
assertThatNullPointerException().isThrownBy(() -> readToString(UTF_8, (String[]) null));
assertThatNullPointerException().isThrownBy(() -> readToString(UTF_8, (Process) null));
}

@Test
public void testContent() throws IOException {
switch (OS.NAME) {
case WINDOWS:
assertThat(new File(ProcessReader.readToString("where", "where"))).exists();
assertThat(new File(readToString(Charset.defaultCharset(), "where", "where"))).exists();
break;
case LINUX:
case MACOS:
case SOLARIS:
assertThat(new File(ProcessReader.readToString("which", "which"))).exists();
assertThat(new File(readToString(Charset.defaultCharset(), "which", "which"))).exists();
break;
}
}
Expand All @@ -44,14 +47,14 @@ public void testExitCode() {
switch (OS.NAME) {
case WINDOWS:
assertThatExceptionOfType(EndOfProcessException.class)
.isThrownBy(() -> ProcessReader.readToString("where", UUID.randomUUID().toString()))
.isThrownBy(() -> readToString(Charset.defaultCharset(), "where", UUID.randomUUID().toString()))
.withMessageStartingWith("Invalid exit value")
.withNoCause()
.matches(ex -> ex.getExitValue() != 0)
.matches(ex -> !ex.getErrorMessage().isEmpty());

assertThatExceptionOfType(EndOfProcessException.class)
.isThrownBy(() -> ProcessReader.readToString("where", "/Q", UUID.randomUUID().toString()))
.isThrownBy(() -> readToString(Charset.defaultCharset(), "where", "/Q", UUID.randomUUID().toString()))
.withMessageStartingWith("Invalid exit value")
.withNoCause()
.matches(ex -> ex.getExitValue() != 0)
Expand All @@ -61,7 +64,7 @@ public void testExitCode() {
case MACOS:
case SOLARIS:
assertThatExceptionOfType(EndOfProcessException.class)
.isThrownBy(() -> ProcessReader.readToString("which", UUID.randomUUID().toString()))
.isThrownBy(() -> readToString(Charset.defaultCharset(), "which", UUID.randomUUID().toString()))
.withMessageStartingWith("Invalid exit value")
.withNoCause()
.matches(ex -> ex.getExitValue() != 0);
Expand Down
2 changes: 1 addition & 1 deletion java-io-bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<artifactId>java-io-parent</artifactId>
<groupId>com.github.nbbrd.java-io-util</groupId>
<version>0.0.29</version>
<version>0.0.30</version>
</parent>

<artifactId>java-io-bom</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion java-io-curl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>com.github.nbbrd.java-io-util</groupId>
<artifactId>java-io-parent</artifactId>
<version>0.0.29</version>
<version>0.0.30</version>
</parent>

<artifactId>java-io-curl</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import java.io.*;
import java.net.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.*;
import java.util.function.BiConsumer;
Expand Down Expand Up @@ -183,7 +184,7 @@ String[] createCurlCommand() {
}

private Curl.Head executeCurlCommand(String[] command) throws IOException {
try (BufferedReader reader = ProcessReader.newReader(command)) {
try (BufferedReader reader = ProcessReader.newReader(Charset.defaultCharset(), command)) {
LinkedList<Curl.Head> curlHeads = Curl.Head.parseResponse(reader);
return curlHeads.isEmpty() ? NO_HEAD : curlHeads.getLast();
} catch (EndOfProcessException ex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.*;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.Locale;
import java.util.UUID;
Expand Down Expand Up @@ -157,7 +158,7 @@ public void testCurlHead(@TempDir Path temp) throws IOException {
.insecure(selfSignedCertificate)
.build();

ProcessReader.readToString(command);
ProcessReader.readToString(Charset.defaultCharset(), command);

String content = org.assertj.core.util.Files.contentOf(dumpHeader.toFile(), UTF_8);

Expand Down
3 changes: 2 additions & 1 deletion java-io-curl/src/test/java/nbbrd/io/curl/CurlTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.List;
import java.util.TreeMap;

Expand Down Expand Up @@ -144,7 +145,7 @@ public void testHead() throws IOException {
@Test
public void testVersion() throws IOException {
String[] versionCommand = new Curl.CommandBuilder().version().build();
try (BufferedReader reader = ProcessReader.newReader(versionCommand)) {
try (BufferedReader reader = ProcessReader.newReader(Charset.defaultCharset(), versionCommand)) {
Curl.Version.parseText(reader).getLines().forEach(System.out::println);
}
}
Expand Down
2 changes: 1 addition & 1 deletion java-io-http/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>com.github.nbbrd.java-io-util</groupId>
<artifactId>java-io-parent</artifactId>
<version>0.0.29</version>
<version>0.0.30</version>
</parent>

<artifactId>java-io-http</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion java-io-picocsv/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<artifactId>java-io-parent</artifactId>
<groupId>com.github.nbbrd.java-io-util</groupId>
<version>0.0.29</version>
<version>0.0.30</version>
</parent>

<artifactId>java-io-picocsv</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion java-io-win/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>com.github.nbbrd.java-io-util</groupId>
<artifactId>java-io-parent</artifactId>
<version>0.0.29</version>
<version>0.0.30</version>
</parent>

<artifactId>java-io-win</artifactId>
Expand Down
6 changes: 4 additions & 2 deletions java-io-win/src/main/java/nbbrd/io/win/CScriptWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ public Process exec(@NonNull File script, short timeoutInSeconds, @NonNull Strin
// http://technet.microsoft.com/en-us/library/ff920171.aspx
List<String> result = new ArrayList<>();
result.add(COMMAND);
result.add("\"" + script.getAbsolutePath() + "\"");
result.add(script.getName());
result.add("//NoLogo");
if (timeoutInSeconds > 0) {
result.add("//T:" + timeoutInSeconds);
}
result.addAll(Arrays.asList(args));
return new ProcessBuilder(result).start();
return new ProcessBuilder(result)
.directory(script.getParentFile())
.start();
}
}
13 changes: 11 additions & 2 deletions java-io-win/src/main/java/nbbrd/io/win/PowerShellWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,20 @@ public class PowerShellWrapper {
@NonNull
public Process exec(@NonNull File script, @NonNull String... args) throws IOException {
List<String> result = new ArrayList<>();
result.add("cmd");
result.add("/c");
result.add("chcp 65001 > NUL"); // UTF-8
result.add("&");
result.add(COMMAND);
result.add("-NoProfile");
result.add("-ExecutionPolicy");
result.add("Bypass");
result.add("-NoLogo");
result.add("-File");
result.add(script.getAbsolutePath());
result.add(script.getName());
result.addAll(Arrays.asList(args));
return new ProcessBuilder(result).start();
return new ProcessBuilder(result)
.directory(script.getParentFile())
.start();
}
}
3 changes: 2 additions & 1 deletion java-io-win/src/main/java/nbbrd/io/win/RegWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand All @@ -37,7 +38,7 @@ public class RegWrapper {
public static final String COMMAND = "reg";

public @NonNull Map<String, List<RegValue>> query(@NonNull String keyName, boolean recursive) throws IOException {
try (BufferedReader reader = ProcessReader.newReader(getArgs(keyName, recursive))) {
try (BufferedReader reader = ProcessReader.newReader(Charset.defaultCharset(), getArgs(keyName, recursive))) {
return parse(reader);
} catch (EndOfProcessException ex) {
if (ex.getExitValue() == 1) {
Expand Down
26 changes: 21 additions & 5 deletions java-io-win/src/test/java/nbbrd/io/win/CScriptWrapperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,23 @@
*/
package nbbrd.io.win;

import nbbrd.io.sys.ProcessReader;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.junit.jupiter.api.io.TempDir;

import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.Files.createTempDirectory;
import static java.nio.file.Files.createTempFile;
import static java.util.Arrays.asList;
import static nbbrd.io.sys.ProcessReader.readToString;
import static nbbrd.io.win.CScriptWrapper.NO_TIMEOUT;
import static nbbrd.io.win.CScriptWrapper.exec;
import static org.assertj.core.api.Assertions.*;
Expand Down Expand Up @@ -70,13 +73,14 @@ public void testTimeOut(@TempDir Path temp) throws IOException, InterruptedExcep
assertThat(exec(infiniteLoop, (short) 2).waitFor())
.isEqualTo(0);

assertThat(ProcessReader.readToString(exec(infiniteLoop, (short) 2)))
assertThat(readToString(Charset.defaultCharset(), exec(infiniteLoop, (short) 2)))
.contains(infiniteLoop.toString());
}

@Test
@EnabledOnOs(OS.WINDOWS)
public void testOutput(@TempDir Path temp) throws IOException, InterruptedException {
String emoji = "\uD83D\uDCA1"; // 💡
File scriptWithArgs = vbs(temp,
"For Each strArg in Wscript.Arguments",
" WScript.Echo strArg",
Expand All @@ -86,12 +90,24 @@ public void testOutput(@TempDir Path temp) throws IOException, InterruptedExcept
assertThat(exec(scriptWithArgs, NO_TIMEOUT, "a", "b", "c").waitFor())
.isEqualTo(0);

assertThat(ProcessReader.readToString(exec(scriptWithArgs, NO_TIMEOUT, "a", "b", "c")))
assertThat(exec(scriptWithArgs, NO_TIMEOUT, "a", "b", "c"))
.extracting(CScriptWrapperTest::readToSystemString, STRING)
.isEqualTo("a" + System.lineSeparator() + "b" + System.lineSeparator() + "c");

String emoji = "\uD83D\uDCA1"; // 💡
assertThatCode(() -> ProcessReader.readToString(exec(vbs(temp, "WScript.Echo \"" + emoji + "\""), NO_TIMEOUT)))
assertThatCode(() -> readToSystemString(exec(vbs(temp, "WScript.Echo \"" + emoji + "\""), NO_TIMEOUT)))
.doesNotThrowAnyException();

assertThat(exec(vbs(createTempDirectory(temp, "folder with spaces"), "WScript.Echo \"hello\""), NO_TIMEOUT))
.extracting(CScriptWrapperTest::readToSystemString, STRING)
.isEqualTo("hello");
}

private static String readToSystemString(Process process) {
try {
return readToString(Charset.defaultCharset(), process);
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}

private static File vbs(Path temp, String... content) throws IOException {
Expand Down
Loading

0 comments on commit a3a225b

Please sign in to comment.