Skip to content

Commit 4e17b60

Browse files
Add SysInfo class
1 parent 906e3cf commit 4e17b60

File tree

3 files changed

+153
-0
lines changed

3 files changed

+153
-0
lines changed

lib/declarations.d.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Describes process properties.
3+
*/
4+
interface IProcessInfo {
5+
/**
6+
* The stdout of the process.
7+
*/
8+
stdout: string;
9+
10+
/**
11+
* The stderr of the process.
12+
*/
13+
stderr: string;
14+
15+
/**
16+
* The exit code of the process.
17+
*/
18+
exitCode?: number;
19+
}

lib/sys-info.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { ChildProcess } from "./wrappers/child-process";
2+
import * as Promise from "bluebird";
3+
import * as path from "path";
4+
5+
export class SysInfo {
6+
// Different java has different format for `java -version` command.
7+
private static JAVA_VERSION_REGEXP = /(?:openjdk|java) version \"((?:\d+\.)+(?:\d+))/i;
8+
9+
// For other versions of java javac version output is not on first line.
10+
// Thus can't use ^ for starts with in regex.
11+
private static JAVA_COMPILER_VERSION_REGEXP = /javac (.*)/i;
12+
13+
private javaVerCache: string;
14+
private javaCompilerVerCache: string;
15+
16+
constructor(private childProcess: ChildProcess) { }
17+
18+
public getJavaVersion(): Promise<string> {
19+
if (!this.javaVerCache) {
20+
return new Promise<string>((resolve, reject) => {
21+
this.childProcess.spawnFromEvent("java", ["-version"], "exit")
22+
.then((spawnResult) => {
23+
this.javaVerCache = SysInfo.JAVA_VERSION_REGEXP.exec(spawnResult.stderr)[1];
24+
resolve(this.javaVerCache);
25+
})
26+
.catch((err) => {
27+
this.javaVerCache = null;
28+
resolve(this.javaVerCache);
29+
});
30+
});
31+
}
32+
33+
return Promise.resolve(this.javaVerCache);
34+
}
35+
36+
public getJavaCompilerVersion(): Promise<string> {
37+
if (!this.javaCompilerVerCache) {
38+
return new Promise<string>((resolve, reject) => {
39+
let javaCompileExecutableName = "javac";
40+
let javaHome = process.env.JAVA_HOME;
41+
let pathToJavaCompilerExecutable = javaHome ? path.join(javaHome, "bin", javaCompileExecutableName) : javaCompileExecutableName;
42+
this.childProcess.exec(`"${pathToJavaCompilerExecutable}" -version`)
43+
.then((output) => {
44+
this.javaCompilerVerCache = output ? SysInfo.JAVA_COMPILER_VERSION_REGEXP.exec(output.stderr)[1] : null;
45+
resolve(this.javaCompilerVerCache);
46+
})
47+
.catch((err) => {
48+
this.javaCompilerVerCache = null;
49+
resolve(this.javaCompilerVerCache);
50+
});
51+
});
52+
}
53+
54+
return Promise.resolve(this.javaCompilerVerCache);
55+
}
56+
}

lib/wrappers/child-process.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import * as childProcess from "child_process";
2+
import * as Promise from "bluebird";
3+
4+
export class ChildProcess {
5+
public spawnFromEvent(command: string, args: string[], event: string, options?: childProcess.SpawnOptions, ignoreError: boolean = false): Promise<IProcessInfo> {
6+
return new Promise<IProcessInfo>((resolve, reject) => {
7+
let commandChildProcess = childProcess.spawn(command, args, options);
8+
let capturedOut = "";
9+
let capturedErr = "";
10+
11+
if (commandChildProcess.stdout) {
12+
commandChildProcess.stdout.on("data", (data: string) => {
13+
capturedOut += data;
14+
});
15+
}
16+
17+
if (commandChildProcess.stderr) {
18+
commandChildProcess.stderr.on("data", (data: string) => {
19+
capturedErr += data;
20+
});
21+
}
22+
23+
commandChildProcess.on(event, (arg: any) => {
24+
let exitCode = typeof arg === "number" ? arg : arg && arg.code;
25+
let result = {
26+
stdout: capturedOut,
27+
stderr: capturedErr,
28+
exitCode: exitCode
29+
};
30+
31+
if (ignoreError) {
32+
resolve(result);
33+
} else {
34+
if (exitCode === 0) {
35+
resolve(result);
36+
} else {
37+
let errorMessage = `Command ${command} failed with exit code ${exitCode}`;
38+
if (capturedErr) {
39+
errorMessage += ` Error output: \n ${capturedErr}`;
40+
}
41+
42+
throw new Error(errorMessage);
43+
}
44+
}
45+
});
46+
47+
commandChildProcess.once("error", (err: Error) => {
48+
if (ignoreError) {
49+
let result = {
50+
stdout: capturedOut,
51+
stderr: err.message,
52+
exitCode: (<any>err).code
53+
};
54+
resolve(result);
55+
} else {
56+
throw err;
57+
}
58+
});
59+
});
60+
}
61+
62+
public exec(command: string, options?: childProcess.ExecOptions): Promise<IProcessInfo> {
63+
return new Promise<IProcessInfo>((resolve, reject) => {
64+
childProcess.exec(command, options, (err, stdout, stderr) => {
65+
if (err) {
66+
throw err;
67+
}
68+
69+
let result: IProcessInfo = {
70+
stdout,
71+
stderr
72+
};
73+
74+
resolve(result);
75+
});
76+
});
77+
}
78+
}

0 commit comments

Comments
 (0)