UNPKG

bestikk-jdk-ea

Version:

A simple tool to download and install JDK Early Access Releases

205 lines (186 loc) 6.11 kB
const child_process = require('child_process'); const fs = require('fs'); const path = require('path'); const https = require('https'); const http = require('http'); const os = require('os'); const zlib = require('zlib'); const tar = require('tar-fs'); const log = require('bestikk-log'); const deleteFolderRecursive = (path) => { let files = []; if (fs.existsSync(path)) { files = fs.readdirSync(path); files.forEach(function (file) { const curPath = path + "/" + file; if (fs.lstatSync(curPath).isDirectory()) { // recurse deleteFolderRecursive(curPath); } else { // delete file fs.unlinkSync(curPath); } }); fs.rmdirSync(path); } }; // https://github.com/jprichardson/node-fs-extra/blob/master/lib/mkdirs/mkdirs-sync.js const mkdirsSync = (p, made) => { p = path.resolve(p); try { fs.mkdirSync(p); made = made || p; } catch (err0) { switch (err0.code) { case 'ENOENT' : made = mkdirsSync(path.dirname(p), made); mkdirsSync(p, made); break; // In the case of any other error, just see if there's a dir // there already. If so, then hooray! If not, then something // is borked. default: let stat; try { stat = fs.statSync(p); } catch (err1) { throw err0; } if (!stat.isDirectory()) throw err0; break; } } return made; }; const execSync = (command) => { log.debug(command); if (!process.env.DRY_RUN) { stdout = child_process.execSync(command); process.stdout.write(stdout); } }; const getContentFromURL = (source, target) => new Promise((resolve) => { log.transform('get', source, target); const targetStream = fs.createWriteStream(target); let downloadModule; // startWith alternative if (source.lastIndexOf('https', 0) === 0) { downloadModule = https; } else { downloadModule = http; } downloadModule.get(source, function (response) { response.pipe(targetStream); targetStream.on('finish', function () { targetStream.close(); resolve(); }); }); }); const untar = (source, baseDirName, destinationDir) => new Promise((resolve) => { log.transform('untar', source, destinationDir + '/' + baseDirName); const stream = fs.createReadStream(source).pipe(zlib.createGunzip()).pipe(tar.extract(destinationDir, { map: function (header) { // REMIND Do NOT user path.sep! // In this case, even on Windows, the separator is '/'. const paths = header.name.split('/'); // replace base directory with 'baseDirName' paths.shift(); paths.unshift(baseDirName); header.name = paths.join('/'); return header; } })); stream.on('finish', function () { resolve(); }); }); const isWin = () => /^win/.test(process.platform); const jdk8DownloadURL = () => new Promise((resolve, reject) => { const jdkId = isWin() ? 'winOffline64JDK' : 'lin64JDKrpm'; http.get('http://jdk.java.net/8/', (result) => { const data = []; result.setEncoding('utf8'); result.on('data', (chunk) => { data.push(chunk); }); result.on('end', () => { const html = data.join(''); const jdkURLRegexp = new RegExp('document\\.getElementById\\(\\"' + jdkId + '\\"\\)\\.href = "(.*)";'); const jdkURL = jdkURLRegexp.exec(html)[1]; resolve(jdkURL); }); }).on('error', (e) => { console.error(e); reject(e); }); }); const jdk9DownloadURL = () => new Promise((resolve, reject) => { http.get('http://jdk.java.net/9/', (result) => { const data = []; result.setEncoding('utf8'); result.on('data', function (chunk) { data.push(chunk); }); result.on('end', function () { const html = data.join(''); let jdkURLRegexp; if (isWin()) { jdkURLRegexp = new RegExp('href="(https:\/\/download.java.net\/java.*_windows-x64.*)"'); } else { jdkURLRegexp = new RegExp('href="(https:\/\/download.java.net\/java.*_linux-x64.*)"'); } const jdkURL = jdkURLRegexp.exec(html)[1]; resolve(jdkURL); }); }).on('error', function (e) { console.error(e); reject(e); }); }); const download = (url, destination) => { log.task('download ' + url); if (fs.existsSync(destination)) { log.info('File ' + destination + ' already exists, skipping download'); return Promise.resolve(); } log.info('Starting download...'); return getContentFromURL(url, destination); }; const install = (installDir, jdkName, jdkURL) => { const suffix = jdkURL.endsWith('.exe') ? '.exe' : '.tar.gz'; const jdkEADownloadDestination = os.tmpdir() + path.sep + jdkName + suffix; const waitWindowsInstallCompletion = (jdkInstallDir) => { if (!fs.existsSync(jdkInstallDir + path.sep + 'bin' + path.sep + 'jjs.exe') || !fs.existsSync(jdkInstallDir + path.sep + 'bin' + path.sep + 'javac.exe') || !fs.existsSync(jdkInstallDir + path.sep + 'bin' + path.sep + 'java.exe')) { setTimeout(waitWindowsInstallCompletion(jdkInstallDir), 1000); } }; deleteFolderRecursive(installDir); mkdirsSync(installDir); return download(jdkURL, jdkEADownloadDestination) .then(() => { if (jdkURL.endsWith(".exe")) { const winInstallDir = installDir.replace(/\\\//, '\\\\').replace(/\//, '\\\\'); execSync(jdkEADownloadDestination + ' /s INSTALLDIR="%CD%\\' + winInstallDir + '"'); waitWindowsInstallCompletion(installDir); return Promise.resolve(); } log.task('uncompress ' + jdkName); return untar(jdkEADownloadDestination, '', installDir); }); }; class JDKEA { constructor () { this.jdk8EAName = 'jdk1.8.0-ea'; this.jdk9EAName = 'jdk1.9.0-ea'; }; installJDK8EA (installDir) { return jdk8DownloadURL() .then((jdkDownloadURL) => install(installDir, this.jdk8EAName, jdkDownloadURL)); }; installJDK9EA (installDir) { return jdk9DownloadURL() .then((jdkDownloadURL) => install(installDir, this.jdk9EAName, jdkDownloadURL)); }; } module.exports = new JDKEA();