-
Notifications
You must be signed in to change notification settings - Fork 2
/
java.js
148 lines (124 loc) · 5.89 KB
/
java.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import fs from "fs"
import path from "path"
import process from "process"
import core from "@actions/core"
import SdkmanTool from "./sdkmantool.js"
export default class Java extends SdkmanTool {
static tool = "java"
static toolVersion = "java -version"
constructor() {
super(Java.tool)
}
// desiredVersion : The identifier for the specific desired version of java as
// known to sdkman such as "11.0.2-open" for version 11.0.2 from java.net.
// assumes sdkman is already installed on the self-hosted runner, is a failure
// condition otherwise.
async setup(desiredVersion) {
const [checkVersion, isVersionOverridden] =
this.getJavaVersion(desiredVersion)
if (!(await this.haveVersion(checkVersion))) {
return checkVersion
}
// Make sure that sdkman is installed
await this.findInstaller()
// This doesn't fail hard, but it probably should
this.checkSdkmanSettings(
path.join(`${await this.findRoot()}`, "etc/config"),
)
// Set downstream environment variable for future steps in this Job
if (isVersionOverridden) {
core.exportVariable("JAVA_VERSION", checkVersion)
}
// If sdkman is requested to install the same version of java more than once,
// all subsequent attempts will be a no-op and sdkman will report a message of the
// form "java 11.0.2-open is already installed". sdk install does not pick up the
// environment variable JAVA_VERSION unlike tfenv, so we specify it here as an
// argument explicitly, if it's set
await this.subprocessShell(`sdk install java ${checkVersion}`).catch(
this.logAndExit(`failed to install: ${checkVersion}`),
)
// Set the "current" default Java version to the desired version
await this.subprocessShell(`sdk default java ${checkVersion}`).catch(
this.logAndExit(`failed to set default: ${checkVersion}`),
)
// export JAVA_HOME to force using the correct version of java
const javaHome = `${process.env[this.envVar]}/candidates/java/current`
core.exportVariable("JAVA_HOME", javaHome)
// Augment path so that the current version of java according to sdkman will be
// the version found.
core.addPath(`${javaHome}/bin`)
// Remove the trailing -blah from the Java version string
const expectedVersion = checkVersion.replace(/[-_][^-_]+$/, "")
// Sanity check that the java command works and its reported version matches what we have
// requested to be in place.
await this.validateVersion(expectedVersion)
// If we got this far, we have successfully configured java.
core.setOutput(Java.tool, checkVersion)
this.info("java success!")
return checkVersion
}
// determines the desired version of java that is being requested. if the desired version
// presented to the action is present, that version is honored rather than the version
// presented in the .sdkmanrc file that can be optionally present in the checked out repo itself.
// Second value returned indicates whether or not the version returned has overridden
// the version from the .sdkmanrc file.
getJavaVersion(actionDesiredVersion) {
// Check if we have any version passed in to the action (can be null/empty string)
if (actionDesiredVersion) return [actionDesiredVersion, true]
const readJavaVersion = this.parseSdkmanrc()
if (readJavaVersion) {
this.debug(`Found java version ${readJavaVersion} in .sdkmanrc`)
return [readJavaVersion, false]
}
// No version has been specified
return [null, null]
}
parseSdkmanrc(filename) {
filename = filename || ".sdkmanrc"
filename = path.resolve(path.join(process.cwd(), filename))
// No file? We're done
if (!fs.existsSync(filename)) {
this.debug(`No .sdkmanrc file found: ${filename}`)
return
}
// Read our file and split it linewise
let data = fs.readFileSync(filename, { encoding: "utf8", flag: "r" })
if (!data) return
data = data.split("\n")
// Iterate over each line and match against the regex
const find = new RegExp("^([^#=]+)=([^# ]+)$")
let found = {}
for (let line of data) {
const match = find.exec(line)
if (!match) continue
found[match[1]] = match[2]
}
this.debug(`Found .sdkmanrc entries ${JSON.stringify(found)}`)
return found["java"]
}
// versionParser specially handles version string extraction
// because we have to map strings like 1.8.0_282 to 8.0.282 for the actual
// SemVer comparison
versionParser(text) {
// Default case for 11.x or 17.x it should match and we're ok
let versions = super.versionParser(text)
this.debug(`versionParser: ${versions}`)
if (!versions.length) return versions
// Fast check for 1.x versions that don't parse right
const v = /^\d+\.\d+\.\d+/ // Check against X.Y.Z
const v1x = /^1\.\d+\.\d+/ // Check against 1.Y.Z
if (v.test(versions[0]) && !v1x.test(versions[0])) return versions
// This parsing is to match the version string for 1.8.0_282 (or
// similar) which is what the java binary puts out, however `sdkman`
// uses the updated naming of `8.0.282` which is what we want to check
// against, so we're going to hard parse against X.Y.Z_W to rewrite it
// to Y.Z.W
const parser = /1\.([0-9]+\.[0-9]+_[0-9]+)/
const matched = parser.exec(text)
this.debug(`versionParser: matched 1.x version: ${matched}`)
if (!matched) return versions
return [matched[1].replace("_", ".")]
}
}
// Register the subclass in our tool list
Java.register()