diff --git a/src/main/java/io/github/ascopes/protobufmavenplugin/dependency/ProtocResolver.java b/src/main/java/io/github/ascopes/protobufmavenplugin/dependency/ProtocResolver.java index e555bf76..286bccc0 100644 --- a/src/main/java/io/github/ascopes/protobufmavenplugin/dependency/ProtocResolver.java +++ b/src/main/java/io/github/ascopes/protobufmavenplugin/dependency/ProtocResolver.java @@ -16,11 +16,14 @@ package io.github.ascopes.protobufmavenplugin.dependency; import io.github.ascopes.protobufmavenplugin.system.FileUtils; +import io.github.ascopes.protobufmavenplugin.system.HostSystem; import java.io.IOException; import java.nio.file.Path; import javax.inject.Inject; import javax.inject.Named; import org.apache.maven.execution.MavenSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Resolver for the {@code protoc} executable. @@ -29,20 +32,26 @@ */ @Named public final class ProtocResolver { + private static final String EXECUTABLE_NAME = "protoc"; private static final String GROUP_ID = "com.google.protobuf"; private static final String ARTIFACT_ID = "protoc"; + private static final Logger log = LoggerFactory.getLogger(ProtocResolver.class); + + private final HostSystem hostSystem; private final MavenDependencyPathResolver mavenDependencyPathResolver; private final PlatformArtifactFactory platformArtifactFactory; private final SystemPathBinaryResolver systemPathResolver; @Inject public ProtocResolver( + HostSystem hostSystem, MavenDependencyPathResolver mavenDependencyPathResolver, PlatformArtifactFactory platformArtifactFactory, SystemPathBinaryResolver systemPathResolver ) { + this.hostSystem = hostSystem; this.mavenDependencyPathResolver = mavenDependencyPathResolver; this.platformArtifactFactory = platformArtifactFactory; this.systemPathResolver = systemPathResolver; @@ -57,6 +66,16 @@ public Path resolve( .orElseThrow(() -> new ResolutionException("No protoc executable was found")); } + if (hostSystem.isProbablyAndroidTermux()) { + log.warn( + "It looks like you are using Termux on Android. You may encounter issues " + + "running the detected protoc binary from Maven central. If this is " + + "an issue, install the protoc compiler manually from your package " + + "manager (apt update && apt install protobuf), and then invoke " + + "Maven with the -Dprotoc.version=PATH flag to avoid this." + ); + } + var coordinate = platformArtifactFactory.createArtifact( GROUP_ID, ARTIFACT_ID, diff --git a/src/main/java/io/github/ascopes/protobufmavenplugin/system/HostSystem.java b/src/main/java/io/github/ascopes/protobufmavenplugin/system/HostSystem.java index c5a16252..491952ef 100644 --- a/src/main/java/io/github/ascopes/protobufmavenplugin/system/HostSystem.java +++ b/src/main/java/io/github/ascopes/protobufmavenplugin/system/HostSystem.java @@ -94,6 +94,11 @@ public boolean isProbablyWindows() { return operatingSystem.toLowerCase(Locale.ROOT).startsWith("windows"); } + public boolean isProbablyAndroidTermux() { + return isProbablyLinux() + && getWorkingDirectory().toString().startsWith("/data/data/com.termux/"); + } + public Path getWorkingDirectory() { return workingDirectory; } diff --git a/src/test/java/io/github/ascopes/protobufmavenplugin/system/HostSystemTest.java b/src/test/java/io/github/ascopes/protobufmavenplugin/system/HostSystemTest.java index a1bf33c7..0bbab107 100644 --- a/src/test/java/io/github/ascopes/protobufmavenplugin/system/HostSystemTest.java +++ b/src/test/java/io/github/ascopes/protobufmavenplugin/system/HostSystemTest.java @@ -17,6 +17,9 @@ import static io.github.ascopes.protobufmavenplugin.fixtures.RandomFixtures.someText; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.withSettings; import java.io.File; import java.io.IOException; @@ -27,6 +30,8 @@ import java.util.Properties; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledOnOs; +import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -92,7 +97,7 @@ void getCpuArchitectureReturnsTheCpuArchitecture() { " Windows 11, false", "Windows Server 2019, false", }) - @ParameterizedTest(name = ".isProbablyLinux(\"{0}\") returns {1}") + @ParameterizedTest(name = "returns {1} on {0}") void isProbablyLinuxReturnsTrueIfTheOsIsProbablyLinux(String osName, boolean expectedResult) { // Given var properties = new Properties(); @@ -133,7 +138,7 @@ void isProbablyLinuxReturnsTrueIfTheOsIsProbablyLinux(String osName, boolean exp " Windows 11, false", "Windows Server 2019, false", }) - @ParameterizedTest(name = ".isProbablyMacOs(\"{0}\") returns {1}") + @ParameterizedTest(name = "returns {1} on {0}") void isProbablyMacOsReturnsTrueIfTheOsIsProbablyMacOs(String osName, boolean expectedResult) { // Given var properties = new Properties(); @@ -174,7 +179,7 @@ void isProbablyMacOsReturnsTrueIfTheOsIsProbablyMacOs(String osName, boolean exp " Windows 11, true", "Windows Server 2019, true", }) - @ParameterizedTest(name = ".isProbablyWindows(\"{0}\") returns {1}") + @ParameterizedTest(name = "returns {1} on {0}") void isProbablyWindowsReturnsTrueIfTheOsIsProbablyWindows(String osName, boolean expectedResult) { // Given var properties = new Properties(); @@ -189,6 +194,31 @@ void isProbablyWindowsReturnsTrueIfTheOsIsProbablyWindows(String osName, boolean assertThat(actualResult).isEqualTo(expectedResult); } + // Avoid non-UNIX path declarations as it messes up our test data. + @DisabledOnOs({OS.WINDOWS, OS.OTHER}) + @DisplayName(".isProbablyAndroidTermux() returns true if running in Termux") + @CsvSource({ + " true, /data/data/com.termux/home, true", + "false, /data/data/com.termux/home, false", + " true, /foo/bar/baz/bork, false", + }) + @ParameterizedTest(name = "expect {2} when isProbablyLinux is {0} and the directory is {1}") + void isProbablyAndroidTermuxReturnsTrueIfRunningInTermux( + boolean isProbablyLinux, + String workingDirectory, + boolean expectedResult + ) { + // Given + var hostSystemBean = mock(HostSystem.class); + when(hostSystemBean.isProbablyLinux()).thenReturn(isProbablyLinux); + when(hostSystemBean.getWorkingDirectory()).thenReturn(Path.of(workingDirectory)); + when(hostSystemBean.isProbablyAndroidTermux()).thenCallRealMethod(); + + // Then + assertThat(hostSystemBean.isProbablyAndroidTermux()) + .isEqualTo(expectedResult); + } + @DisplayName(".getWorkingDirectory() returns the working directory") @Test void getWorkingDirectoryReturnsTheWorkingDirectory() {