forked from validator/validator
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvnu-java-downloader.js
More file actions
executable file
·153 lines (141 loc) · 5.03 KB
/
vnu-java-downloader.js
File metadata and controls
executable file
·153 lines (141 loc) · 5.03 KB
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
149
150
151
152
153
#!/usr/bin/env node
'use strict';
const { spawnSync, execSync } = require('child_process');
const { mkdirSync, existsSync, createWriteStream } = require('fs');
const { join, dirname, parse } = require('path');
const { Readable } = require('stream');
const fetch = globalThis.fetch || require('node-fetch');
function findNearestNodeModules(startDir) {
let dir = startDir;
const { root } = parse(startDir);
while (true) {
const candidate = join(dir, 'node_modules');
if (existsSync(candidate)) {
return candidate;
}
if (dir === root) {
throw new Error('Could not find a node_modules directory.');
}
dir = dirname(dir);
}
}
const NODE_MODULES_DIR = findNearestNodeModules(__dirname);
const CACHE_DIR = join(NODE_MODULES_DIR, '.cache', 'vnu-jar', 'java');
const TEMURIN_VERSION = '17.0.17+10';
const TEMURIN_BASE_URL = `https://github.com/adoptium/temurin17-binaries/releases/download/jdk-${TEMURIN_VERSION}/`;
function getJavaVersion(javaPath) {
try {
const result = spawnSync(javaPath, ['-version'], { encoding: 'utf8' });
const versionOutput = result.stderr || result.stdout || '';
const match = versionOutput.match(/version "(\d+)(?:\.(\d+))?/);
if (match) {
const majorVersion = parseInt(match[1], 10);
return majorVersion;
}
} catch (err) {
return null;
}
return null;
}
function findSystemJava() {
const whichCmd = process.platform === 'win32' ? 'where' : 'which';
const result = spawnSync(whichCmd, ['java'], { encoding: 'utf8' });
if (result.status === 0 && result.stdout) {
const javaPath = result.stdout.split(/\r?\n/)[0].trim();
const version = getJavaVersion(javaPath);
if (version !== null && version >= 11) {
return javaPath;
}
}
return null;
}
function getPlatformArchiveName() {
let arch = process.arch;
let plat = 'linux';
if (process.platform === 'win32') {
plat = 'windows';
} else if (process.platform === 'darwin') {
plat = 'mac';
}
if (plat === 'mac' && arch === 'arm64') {
arch = 'aarch64';
}
const ext = process.platform === 'win32' ? 'zip' : 'tar.gz';
const version = TEMURIN_VERSION.replace('+', '_');
return `OpenJDK17U-jre_${arch}_${plat}_hotspot_${version}.${ext}`;
}
async function downloadJava() {
mkdirSync(CACHE_DIR, { recursive: true });
const archiveName = getPlatformArchiveName();
const url = TEMURIN_BASE_URL + archiveName;
const archivePath = join(CACHE_DIR, archiveName);
console.log(`Downloading Java 17 runtime from ${url}...`);
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to download Java: ${res.status} ${res.statusText}`);
}
await new Promise((resolve, reject) => {
const file = createWriteStream(archivePath);
Readable.fromWeb(res.body)
.pipe(file)
.on('finish', resolve)
.on('error', reject);
});
if (process.platform === 'win32') {
console.log('Extracting ZIP archive...');
const extractRes = spawnSync('powershell', [
'-NoProfile',
'-NonInteractive',
'-Command',
'Expand-Archive',
'-Force',
archivePath,
CACHE_DIR
], { stdio: 'inherit' });
if (extractRes.status !== 0) {
throw new Error('Failed to extract Java archive.');
}
} else {
console.log('Extracting tar.gz archive...');
const extractRes = spawnSync('tar', ['-xzf', archivePath, '-C', CACHE_DIR], { stdio: 'inherit' });
if (extractRes.status !== 0) {
throw new Error('Failed to extract Java archive.');
}
}
console.log('Local Java runtime now installed.');
}
function resolveLocalJavaExecutable() {
let javaPath = join(CACHE_DIR, `jdk-${TEMURIN_VERSION}-jre`, 'bin', 'java');
if (process.platform === 'win32') {
javaPath = join(CACHE_DIR, `jdk-${TEMURIN_VERSION}-jre`, 'bin', 'java.exe');
} else if (process.platform === 'darwin') {
javaPath = join(CACHE_DIR, `jdk-${TEMURIN_VERSION}-jre`, 'Contents', 'Home', 'bin', 'java');
}
if (!existsSync(javaPath)) {
throw new Error('Local Java runtime not found after installation.');
}
return javaPath;
}
async function ensureLocalJava() {
if (!existsSync(CACHE_DIR)) {
await downloadJava();
}
return resolveLocalJavaExecutable();
}
async function resolveJava() {
const javaPath = findSystemJava();
if (javaPath) return javaPath;
try {
return resolveLocalJavaExecutable();
} catch (err) {
console.error('Failed to resolve local Java runtime, falling back to ensureLocalJava():', err);
}
return ensureLocalJava();
}
if (require.main === module) {
void resolveJava().catch((err) => {
console.error('Failed to resolve Java runtime:', err && err.stack ? err.stack : String(err));
process.exit(1);
});
}
module.exports = { resolveJava };