-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow specifying Java with --java-bin-dirs or PATH
Most of the action happens in: * The new `SAWScript.JavaTools` module, which exports functionality for locating a Java executable and finding its system properties. * `SAWScript.Options`, which now exposes a new `--java-bin-dirs` flag. (Alternatively, one can use the `PATH`.) The `processEnv` function now performs additional post-processing based on whether `--java-bin-dirs`/`PATH` are set. Fixes #1022, and paves the way to a better user experience for #861. Other things: * I ended up cargo-culting some `process`-related code from `SAWScript.Builtins` for use in `SAWScript.JavaTools`. To avoid blatant code duplication (and because I end up needing the exact same code later in another patch), I factored out this code into the new `SAWScript.ProcessUtils` module. I considered putting it in the existing `SAWScript.Utils` module, but that would have led to import cycles. Sigh.
- Loading branch information
1 parent
81664fc
commit 685e8ae
Showing
13 changed files
with
219 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
{- | | ||
Module : SAWScript.JavaTools | ||
Description : Functionality for finding a Java executable and its properties. | ||
License : BSD3 | ||
Maintainer : atomb | ||
Stability : provisional | ||
-} | ||
|
||
module SAWScript.JavaTools | ||
( findJavaIn | ||
, findJavaProperty | ||
, findJavaMajorVersion | ||
) where | ||
|
||
import Data.List.Extra (dropPrefix, firstJust, stripInfix) | ||
import Data.Maybe | ||
import System.Directory | ||
|
||
import SAWScript.ProcessUtils | ||
|
||
-- | @'findJavaIn' javaBinDirs@ searches for an executable named @java@ in the | ||
-- directories in @javaBinDirs@. If @javaBinDirs@ is empty, then the @PATH@ is | ||
-- searched. | ||
-- | ||
-- If the search finds at least one executable, then @Just@ the first result is | ||
-- returned. If no executables are found, then @Nothing@ is returned. | ||
findJavaIn :: [FilePath] -> IO (Maybe FilePath) | ||
findJavaIn javaBinDirs | ||
| null javaBinDirs = findExecutable "java" | ||
| otherwise = listToMaybe <$> findExecutablesInDirectories javaBinDirs "java" | ||
|
||
-- | @'findJavaProperty' javaPath prop@ invokes @javaPath@ to dump its system | ||
-- properties (see <https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html>) | ||
-- and attempts to find the value associated with the property named @prop@. | ||
-- If such a value is found, then @Just@ that value is returned. | ||
-- If no property named @prop@ exists, then @Nothing@ is returned. | ||
-- | ||
-- This will throw an exception if @javaPath@'s system properties cannot be | ||
-- determined. | ||
findJavaProperty :: FilePath -> String -> IO (Maybe String) | ||
findJavaProperty javaPath propertyNeedle = do | ||
(_stdOut, stdErr) <- readProcessExitIfFailure javaPath ["-XshowSettings:properties", "-version"] | ||
let propertyHaystacks = lines stdErr | ||
pure $ firstJust getProperty_maybe propertyHaystacks | ||
where | ||
-- Each Java system property, as reported by | ||
-- @java -XshowSettings:properties@, adheres to this template: | ||
-- | ||
-- " <prop> = <value>" | ||
-- | ||
-- Note the leading whitespace. As a result, stripInfix is used to detect | ||
-- "<prop> = " in the middle of the string and obtain the <value> after it. | ||
getProperty_maybe :: String -> Maybe String | ||
getProperty_maybe propertyHaystack = | ||
snd <$> stripInfix (propertyNeedle ++ " = ") propertyHaystack | ||
|
||
-- | @'findJavaMajorVersion' javaPath@ will consult @javaPath@ to find the | ||
-- major version number corresponding to that Java release. | ||
findJavaMajorVersion :: FilePath -> IO Int | ||
findJavaMajorVersion javaPath = do | ||
mbVersionStr <- findJavaProperty javaPath "java.version" | ||
case mbVersionStr of | ||
Nothing -> fail $ "Could not detect the version of Java at " ++ javaPath | ||
Just versionStr -> pure $ read $ takeMajorVersionStr $ dropOldJavaVersionPrefix versionStr | ||
where | ||
-- e.g., if the version number is "11.0.9.1", then just take the "11" part. | ||
takeMajorVersionStr :: String -> String | ||
takeMajorVersionStr = takeWhile (/= '.') | ||
|
||
-- Prior to Java 9, the leading version number was always 1. For example, | ||
-- Java 8 would use 1.8.<...>. We only care about the 8 part, so drop the | ||
-- leading 1. bit. | ||
dropOldJavaVersionPrefix :: String -> String | ||
dropOldJavaVersionPrefix = dropPrefix "1." |
Oops, something went wrong.