From 8a152b28b2cc5150398a128924a05bae9351cb69 Mon Sep 17 00:00:00 2001 From: Stephanie Gawroriski Date: Sun, 4 Jun 2023 19:15:24 +0000 Subject: [PATCH] Commonize into PathUtils; On Linux/BSD try to use xdg-open/x-www-browser if Java's browser open does not work. --- .idea/compiler.xml | 2 +- .../plugin/general/DeveloperNoteTask.java | 34 ++++++- .../java/cc/squirreljme/plugin/util/FossilExe.java | 38 ++------ .../java/cc/squirreljme/plugin/util/PathUtils.java | 101 +++++++++++++++++++++ 4 files changed, 144 insertions(+), 31 deletions(-) create mode 100644 buildSrc/src/main/java/cc/squirreljme/plugin/util/PathUtils.java diff --git a/.idea/compiler.xml b/.idea/compiler.xml index bf71c453ea..3846720645 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -8,7 +8,7 @@ - + diff --git a/buildSrc/src/main/java/cc/squirreljme/plugin/general/DeveloperNoteTask.java b/buildSrc/src/main/java/cc/squirreljme/plugin/general/DeveloperNoteTask.java index 829c141af2..6bf3fe1cf6 100644 --- a/buildSrc/src/main/java/cc/squirreljme/plugin/general/DeveloperNoteTask.java +++ b/buildSrc/src/main/java/cc/squirreljme/plugin/general/DeveloperNoteTask.java @@ -11,6 +11,7 @@ package cc.squirreljme.plugin.general; import cc.squirreljme.plugin.multivm.AlwaysFalse; import cc.squirreljme.plugin.util.FossilExe; +import cc.squirreljme.plugin.util.PathUtils; import cc.squirreljme.plugin.util.SimpleHTTPRequest; import cc.squirreljme.plugin.util.SimpleHTTPResponse; import cc.squirreljme.plugin.util.SimpleHTTPResponseBuilder; @@ -24,12 +25,15 @@ import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; +import java.nio.file.Path; import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.Arrays; import java.util.Objects; import javax.inject.Inject; import org.gradle.api.DefaultTask; import org.gradle.api.Task; +import org.gradle.internal.os.OperatingSystem; /** * Edits the current day in developer notes. @@ -212,8 +216,36 @@ public class DeveloperNoteTask } // Do not fail on this, just try more - catch (IOException|HeadlessException ignored) + catch (Throwable ignored) { + ignored.printStackTrace(); + } + + // If we are on Linux, try to launch browser + if (OperatingSystem.current() == OperatingSystem.LINUX || + OperatingSystem.current() == OperatingSystem.FREE_BSD) + { + // Try different potential browsers + for (String attempt : Arrays.asList( + "xdg-open", // Standard XDG Open + "x-www-browser" // On Debian + )) + { + // Find executable + Path path = PathUtils.findPathExecutable(attempt); + if (path != null) + try + { + ProcessBuilder builder = new ProcessBuilder( + path.toAbsolutePath().toString(), __url); + + builder.start(); + return; + } + catch (IOException ignored) + { + } + } } // Open the browser using another means diff --git a/buildSrc/src/main/java/cc/squirreljme/plugin/util/FossilExe.java b/buildSrc/src/main/java/cc/squirreljme/plugin/util/FossilExe.java index 39640f8fc5..aa58e54ef6 100644 --- a/buildSrc/src/main/java/cc/squirreljme/plugin/util/FossilExe.java +++ b/buildSrc/src/main/java/cc/squirreljme/plugin/util/FossilExe.java @@ -467,36 +467,16 @@ public final class FossilExe if (rv != null) return rv; - // Path should exist, but it might not - String pathEnv = System.getenv("PATH"); - if (pathEnv == null) - throw new InvalidFossilExeException("No PATH variable is set."); + // Try to find it + Path maybe = PathUtils.findPathExecutable("fossil"); + if (maybe == null) + throw new InvalidFossilExeException( + "Could not find Fossil executable."); - // The executable we are looking for - Path exeName = Paths.get( - (OperatingSystem.current() == OperatingSystem.WINDOWS ? - "fossil.exe" : "fossil")); - - // Search each path piece for the given executable - for (String pathSegment : pathEnv.split( - Pattern.quote(System.getProperty("path.separator")))) - { - Path fullPath = Paths.get(pathSegment).resolve(exeName); - - // If we find it, cache it - if (Files.isRegularFile(fullPath) && Files.isExecutable(fullPath)) - { - rv = new FossilExe(fullPath); - - FossilExe._cached = rv; - - return rv; - } - } - - // Not found - throw new InvalidFossilExeException( - "Could not find Fossil executable."); + // Cache for later + rv = new FossilExe(maybe); + FossilExe._cached = rv; + return rv; } /** diff --git a/buildSrc/src/main/java/cc/squirreljme/plugin/util/PathUtils.java b/buildSrc/src/main/java/cc/squirreljme/plugin/util/PathUtils.java new file mode 100644 index 0000000000..dfbd3fdce9 --- /dev/null +++ b/buildSrc/src/main/java/cc/squirreljme/plugin/util/PathUtils.java @@ -0,0 +1,101 @@ +// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*- +// --------------------------------------------------------------------------- +// Multi-Phasic Applications: SquirrelJME +// Copyright (C) Stephanie Gawroriski +// --------------------------------------------------------------------------- +// SquirrelJME is under the GNU General Public License v3+, or later. +// See license.mkd for licensing and copyright information. +// --------------------------------------------------------------------------- + +package cc.squirreljme.plugin.util; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.regex.Pattern; +import org.gradle.internal.os.OperatingSystem; + +/** + * General path utilities. + * + * @since 2023/06/04 + */ +public class PathUtils +{ + /** + * Not used. + * + * @since 2023/06/04 + */ + private PathUtils() + { + } + + /** + * Finds a file that is in {@code $PATH}. + * + * @param __name The name of the file + * @return The path to the file of the given name or {@code null} + * if not found. + * @throws NullPointerException On arguments. + * @since 2023/06/04 + */ + public static Path findPath(String __name) + { + // Path should exist, but it might not + String pathEnv = System.getenv("PATH"); + if (pathEnv == null) + return null; + + // Search each path piece for the given executable + for (String pathSegment : pathEnv.split( + Pattern.quote(System.getProperty("path.separator")))) + { + Path fullPath = Paths.get(pathSegment).resolve(__name); + + // If we find it, cache it + if (Files.isRegularFile(fullPath) && Files.isExecutable(fullPath)) + return fullPath; + } + + // Not found + return null; + } + + /** + * Finds an executable that is in {@code $PATH}. + * + * @param __name The name of the executable + * @return The path to the executable of the given name or {@code null} + * if not found. + * @throws NullPointerException On arguments. + * @since 2023/06/04 + */ + public static Path findPathExecutable(String __name) + throws NullPointerException + { + if (__name == null) + throw new NullPointerException("NARG"); + + // If we are on Windows there are multiple potential path executables + // for actual executables + if (OperatingSystem.current() == OperatingSystem.WINDOWS) + { + // Get path extensions that exist + String pathExts = System.getenv("PathExt"); + if (pathExts == null) + pathExts = ".EXE"; + + // Go through each extension and try to find it + for (String pathExt : pathExts.split(Pattern.quote(";"))) + { + Path found = PathUtils.findPath(__name + pathExt); + if (found != null) + return found; + } + } + + // Otherwise just the exact name + return PathUtils.findPath(__name); + } +} -- 2.11.4.GIT