appcelerator
Advanced tools
Comparing version 4.2.15 to 4.3.0-1
@@ -14,3 +14,2 @@ // jscs:disable jsDoc | ||
errorlib = require('./error'), | ||
urllib = require('url'), | ||
fs = require('fs'), | ||
@@ -26,4 +25,8 @@ os = require('os'), | ||
debug('download called with arguments: %o', arguments); | ||
if (!nobanner && !wantVersion) { util.waitMessage('Finding latest version '); } | ||
if (!nobanner && wantVersion) { util.waitMessage('Finding version ' + wantVersion + ' '); } | ||
if (!nobanner && !wantVersion) { | ||
util.waitMessage('Finding latest version '); | ||
} | ||
if (!nobanner && wantVersion) { | ||
util.waitMessage('Finding version ' + wantVersion + ' '); | ||
} | ||
@@ -34,3 +37,3 @@ retryAttempts = retryAttempts || 1; | ||
var bar; | ||
pendingRequest = util.request(location, function (err, res, req) { | ||
pendingRequest = util.request(location, function (err, res, _req) { | ||
if (err) { | ||
@@ -80,4 +83,8 @@ debug('error from download was: %o', err); | ||
if (!nobanner && !wantVersion) { util.okMessage(chalk.green(version)); } | ||
if (!nobanner && wantVersion) { util.okMessage(); } | ||
if (!nobanner && !wantVersion) { | ||
util.okMessage(chalk.green(version)); | ||
} | ||
if (!nobanner && wantVersion) { | ||
util.okMessage(); | ||
} | ||
@@ -99,4 +106,4 @@ // check to see if we have it already installed and if we do, just continue | ||
bar = (!nobanner && process.stdout.isTTY && !process.env.TRAVIS) && | ||
new ProgressBar('Downloading [:bar] :percent :etas', { | ||
bar = (!nobanner && process.stdout.isTTY && !process.env.TRAVIS) | ||
&& new ProgressBar('Downloading [:bar] :percent :etas', { | ||
complete: util.isWindows() ? '█' : chalk.green('▤'), | ||
@@ -138,5 +145,5 @@ incomplete: ' ', | ||
stream.end(); | ||
} catch (E) { | ||
// ignore | ||
} | ||
catch (E) { | ||
} | ||
pendingRequest = null; | ||
@@ -148,3 +155,5 @@ callback(errorlib.createError('com.appcelerator.install.download.server.stream.error', err.message)); | ||
debug('download end'); | ||
if (bar) { bar.tick(tickCount); } | ||
if (bar) { | ||
bar.tick(tickCount); | ||
} | ||
stream.end(); | ||
@@ -178,6 +187,4 @@ pendingRequest = null; | ||
return callback(errorlib.createError('com.appcelerator.install.download.failed.checksum', shasum, checkshasum)); | ||
} else { | ||
if (!quiet) { | ||
util.infoMessage('Validating security checksum ' + chalk.green(util.isWindows() ? 'OK' : '✓')); | ||
} | ||
} else if (!quiet) { | ||
util.infoMessage('Validating security checksum ' + chalk.green(util.isWindows() ? 'OK' : '✓')); | ||
} | ||
@@ -195,3 +202,5 @@ process.nextTick(function () { | ||
stream.end(); | ||
if (bar) { util.resetLine(); } | ||
if (bar) { | ||
util.resetLine(); | ||
} | ||
pendingRequest = null; | ||
@@ -211,3 +220,5 @@ if (retryAttempts >= MAX_RETRIES) { | ||
stream.end(); | ||
if (bar) { util.resetLine(); } | ||
if (bar) { | ||
util.resetLine(); | ||
} | ||
pendingRequest = null; | ||
@@ -224,37 +235,37 @@ return callback(errorlib.createError('com.appcelerator.install.download.server.response.unexpected', res.statusCode)); | ||
sigintFn, | ||
pendingAbort, | ||
createCleanup = function createCleanup(name) { | ||
return function (exit) { | ||
if (pendingRequest) { | ||
try { | ||
// abort the pending HTTP request so it will | ||
// close the server socket | ||
pendingRequest.abort(); | ||
} | ||
catch (E) { | ||
} | ||
pendingRequest = null; | ||
} | ||
pendingAbort; | ||
function createCleanup(name) { | ||
return function (exit) { | ||
if (pendingRequest) { | ||
try { | ||
if (fs.existSync(tmpfile)) { | ||
fs.unlinkSync(tmpfile); | ||
} | ||
// abort the pending HTTP request so it will | ||
// close the server socket | ||
pendingRequest.abort(); | ||
} catch (E) { | ||
// ignore | ||
} | ||
catch (E) { | ||
pendingRequest = null; | ||
} | ||
try { | ||
if (fs.existSync(tmpfile)) { | ||
fs.unlinkSync(tmpfile); | ||
} | ||
if (name === 'SIGINT') { | ||
pendingAbort = true; | ||
process.removeListener('SIGINT', sigintFn); | ||
util.abortMessage('Download'); | ||
} else if (name === 'exit') { | ||
process.removeListener('exit', exitFn); | ||
if (!pendingAbort) { | ||
process.exit(exit); | ||
} | ||
} else { | ||
process.removeListener('exit', exitFn); | ||
process.removeListener('SIGINT', sigintFn); | ||
} catch (E) { | ||
// ignore | ||
} | ||
if (name === 'SIGINT') { | ||
pendingAbort = true; | ||
process.removeListener('SIGINT', sigintFn); | ||
util.abortMessage('Download'); | ||
} else if (name === 'exit') { | ||
process.removeListener('exit', exitFn); | ||
if (!pendingAbort) { | ||
process.exit(exit); | ||
} | ||
}; | ||
} else { | ||
process.removeListener('exit', exitFn); | ||
process.removeListener('SIGINT', sigintFn); | ||
} | ||
}; | ||
} | ||
@@ -261,0 +272,0 @@ // make sure we remove the file on shutdown |
@@ -9,3 +9,3 @@ /** | ||
*/ | ||
/*jshint esnext: true */ | ||
/* jshint esnext: true */ | ||
var util = require('util'), | ||
@@ -18,2 +18,4 @@ u = require('./util'), | ||
* create a custom error so we can get proper error code | ||
* @param {string} message - The error message. | ||
* @param {string} id - The ID for the error. | ||
*/ | ||
@@ -39,4 +41,4 @@ function AppCError(message, id) { | ||
'com.appcelerator.install.binary.missing': { | ||
message: 'Cannot find expected binary at %s. ' + | ||
'This likely means the install package at %s is invalid for version %s', | ||
message: 'Cannot find expected binary at %s. ' | ||
+ 'This likely means the install package at %s is invalid for version %s', | ||
argcount: 3 | ||
@@ -49,9 +51,9 @@ }, | ||
'com.appcelerator.install.download.server.response.error': { | ||
message: 'Server responded with unexpected error: %s. Please re-try your install again. ' + | ||
'If you continue to have this problem, please contact Appcelerator Support at support@appcelerator.com.', | ||
message: 'Server responded with unexpected error: %s. Please re-try your install again. ' | ||
+ 'If you continue to have this problem, please contact Appcelerator Support at support@appcelerator.com.', | ||
argcount: 1 | ||
}, | ||
'com.appcelerator.install.download.server.stream.error': { | ||
message: 'Unexpected error received during download. %s. Please re-try your install again. ' + | ||
'If you continue to have this problem, please contact Appcelerator Support at support@appcelerator.com.', | ||
message: 'Unexpected error received during download. %s. Please re-try your install again. ' | ||
+ 'If you continue to have this problem, please contact Appcelerator Support at support@appcelerator.com.', | ||
argcount: 1 | ||
@@ -64,23 +66,23 @@ }, | ||
'com.appcelerator.install.download.invalid.content.length': { | ||
message: 'Received invalid response from download server (content-length was not set). ' + | ||
'Please re-try your install again.' | ||
message: 'Received invalid response from download server (content-length was not set). ' | ||
+ 'Please re-try your install again.' | ||
}, | ||
'com.appcelerator.install.download.failed.retries.max': { | ||
message: 'Download failed after %d failed re-attempts. ' + | ||
'Please re-try your install again in a few moments. If you continue to have this problem, please contact Appcelerator Support at support@appcelerator.com.', | ||
message: 'Download failed after %d failed re-attempts. ' | ||
+ 'Please re-try your install again in a few moments. If you continue to have this problem, please contact Appcelerator Support at support@appcelerator.com.', | ||
argcount: 1 | ||
}, | ||
'com.appcelerator.install.download.failed.checksum': { | ||
message: 'Invalid file download checksum. ' + | ||
'This could be a result of the file being modified in transit or it could be because the download was interrupted or had an error. Expected: %s, was: %s. Please re-try this install again.', | ||
message: 'Invalid file download checksum. ' | ||
+ 'This could be a result of the file being modified in transit or it could be because the download was interrupted or had an error. Expected: %s, was: %s. Please re-try this install again.', | ||
argcount: 2 | ||
}, | ||
'com.appcelerator.install.download.server.unavailable': { | ||
message: 'Download server is not currently available. ' + | ||
'Please re-try your install again in a few moments. ' + | ||
'If you continue to have this problem, please contact Appcelerator Support at support@appcelerator.com.' | ||
message: 'Download server is not currently available. ' | ||
+ 'Please re-try your install again in a few moments. ' | ||
+ 'If you continue to have this problem, please contact Appcelerator Support at support@appcelerator.com.' | ||
}, | ||
'com.appcelerator.install.download.server.response.unexpected': { | ||
message: 'Unexpected response returned from server (%d). ' + | ||
'Please re-try your install again.', | ||
message: 'Unexpected response returned from server (%d). ' | ||
+ 'Please re-try your install again.', | ||
argcount: 1 | ||
@@ -96,9 +98,9 @@ }, | ||
'com.appcelerator.install.installer.user.sudo.user': { | ||
message: 'Ooops! You cannot run using sudo as another user. ' + | ||
'Please re-run using the %s account.', | ||
message: 'Ooops! You cannot run using sudo as another user. ' | ||
+ 'Please re-run using the %s account.', | ||
argcount: 1 | ||
}, | ||
'com.appcelerator.install.installer.missing.homedir': { | ||
message: 'Ooops! Your home directory (%s) cannot be found. ' + | ||
'Please make sure that the environment variable %s is set correctly to the correct directory and that it is writable.', | ||
message: 'Ooops! Your home directory (%s) cannot be found. ' | ||
+ 'Please make sure that the environment variable %s is set correctly to the correct directory and that it is writable.', | ||
argcount: 2 | ||
@@ -118,9 +120,9 @@ }, | ||
'com.appcelerator.install.preflight.missing.xcode.clitools': { | ||
message: 'Xcode command line developers tools are required. ' + | ||
'Choose an option in the dialog to download the command line developer tools. ' + | ||
'Once you have completed the installation, please re-run this command.' | ||
message: 'Xcode command line developers tools are required. ' | ||
+ 'Choose an option in the dialog to download the command line developer tools. ' | ||
+ 'Once you have completed the installation, please re-run this command.' | ||
}, | ||
'com.appcelerator.install.use.download.error': { | ||
message: 'Unexpected error received fetching latest version details. %s Please re-try your request again. ' + | ||
'If you continue to have this problem, please contact Appcelerator Support at support@appcelerator.com.', | ||
message: 'Unexpected error received fetching latest version details. %s Please re-try your request again. ' | ||
+ 'If you continue to have this problem, please contact Appcelerator Support at support@appcelerator.com.', | ||
argcount: 1 | ||
@@ -132,2 +134,4 @@ } | ||
* construct the proper error message | ||
* @param {string} errorcode - The errorcode for the error. | ||
* @returns {string} | ||
*/ | ||
@@ -139,9 +143,9 @@ function createErrorMessage(errorcode) { | ||
if (entry.argcount && entry.argcount !== args.length) { | ||
u.fail('Internal failure. Unexpected usage of internal command. Please report error code: ' + errorcode + '(invalid args) ' + | ||
'to Appcelerator Support with the following stack trace:' + new Error().stack); | ||
u.fail('Internal failure. Unexpected usage of internal command. Please report error code: ' + errorcode + '(invalid args) ' | ||
+ 'to Appcelerator Support with the following stack trace:' + new Error().stack); | ||
} | ||
return args.length ? util.format.apply(util.format, [entry.message].concat(args)) : entry.message; | ||
return args.length ? util.format.apply(util.format, [ entry.message ].concat(args)) : entry.message; | ||
} else { | ||
u.fail('Internal failure. Unexpected usage of internal command. Please report error code: ' + errorcode + '(invalid error code) ' + | ||
'to Appcelerator Support with the following stack trace:' + new Error().stack); | ||
u.fail('Internal failure. Unexpected usage of internal command. Please report error code: ' + errorcode + '(invalid error code) ' | ||
+ 'to Appcelerator Support with the following stack trace:' + new Error().stack); | ||
} | ||
@@ -152,2 +156,3 @@ } | ||
* fail with an error (console.error + exitcode 1) | ||
* @param {string} errorcode - The errorcode for the error. | ||
*/ | ||
@@ -163,2 +168,4 @@ exports.failWithError = function (errorcode) { | ||
* create an AppCError error class and return an instance | ||
* @param {string} errorcode - The errorcode for the error. | ||
* @returns {AppCError} | ||
*/ | ||
@@ -165,0 +172,0 @@ exports.createError = function (errorcode) { |
@@ -12,4 +12,3 @@ /** | ||
module.exports = require('./' + process.platform); | ||
} | ||
catch (e) { | ||
} catch (e) { | ||
// this is OK, no platform to load | ||
@@ -16,0 +15,0 @@ } |
@@ -21,3 +21,3 @@ // jscs:disable jsDoc | ||
debug = require('debug')('appc:install'), | ||
exec = require('child_process').exec, | ||
exec = require('child_process').exec, // eslint-disable-line security/detect-child-process | ||
semver = require('semver'), | ||
@@ -28,2 +28,5 @@ checkPlatform = require('npm-install-checks').checkPlatform; | ||
* tar gunzip | ||
* @param {string} sourceFile - The source tar.gz file to extract | ||
* @param {string} destination - The destination to extract to | ||
* @param {function} callback - Function to call one complete | ||
*/ | ||
@@ -42,2 +45,5 @@ function targz(sourceFile, destination, callback) { | ||
* run the pre-flight check to check env for specific things we need | ||
* @param {object} opts - Various options | ||
* @param {function} callback - Function to call when complete | ||
* @returns {undefined} | ||
*/ | ||
@@ -97,3 +103,3 @@ function preflight(opts, callback) { | ||
// must have Xcode tools to compile so let's check that | ||
return exec('xcode-select -p', function (err, stdout) { | ||
return exec('xcode-select -p', function (err, _stdout) { | ||
var exitCode = err && err.code; | ||
@@ -104,3 +110,3 @@ if (exitCode === 2) { | ||
// you do this by trying to invoke gcc which will automatically install | ||
exec('gcc', function (err, stdout) { | ||
exec('gcc', function (_err, _stdout) { | ||
return callback(errorlib.createError('com.appcelerator.install.preflight.missing.xcode.clitools')); | ||
@@ -119,2 +125,8 @@ }); | ||
* tar gunzip our package into dir | ||
* @param {boolean} quiet - Whether to output logs during extraction | ||
* @param {string} filename - Path to file to extract | ||
* @param {string} dir - Location to extract to | ||
* @param {function} callback - Function to call when complete | ||
* @param {number} attempts - Number of attempts to make to extract | ||
* @returns {undefined} | ||
*/ | ||
@@ -124,3 +136,5 @@ function extract(quiet, filename, dir, callback, attempts) { | ||
attempts = attempts || 0; | ||
if (!quiet) { util.waitMessage('Installing '); } | ||
if (!quiet) { | ||
util.waitMessage('Installing '); | ||
} | ||
util.ensureDir(dir); | ||
@@ -132,3 +146,3 @@ var error = util.checkDirectory(dir, 'install'); | ||
} | ||
targz(filename, dir, function (err) { | ||
targz(filename, dir, function (_err) { | ||
// let errors fail through and attempt to do it again. we seem to have | ||
@@ -147,3 +161,3 @@ // failures ocassionally on extraction | ||
util.rmdirSyncRecursive(dir); | ||
//console.log('extraction failed, attempting again',attempts+1); | ||
// console.log('extraction failed, attempting again',attempts+1); | ||
extract(quiet, filename, dir, callback, attempts + 1); | ||
@@ -163,2 +177,5 @@ } else { | ||
* on the target platform during install. | ||
* @param {string} dir - Directory to search | ||
* @param {string[]} check - Array of directories that have been checked already | ||
* @returns {string[]} | ||
*/ | ||
@@ -178,4 +195,3 @@ function findAllNativeModules(dir, check) { | ||
} | ||
} | ||
catch (e) { | ||
} catch (e) { | ||
// ignore this. just means we're trying to follow a | ||
@@ -193,2 +209,5 @@ // bad symlink | ||
* correctly compiled for the installed platform (vs. the platform we used to upload) | ||
* @param {string} dir - Directory to run npm install in | ||
* @param {string} cliVersion - Version of the CLI we're installing in | ||
* @param {function} callback - Function to call when done | ||
*/ | ||
@@ -205,3 +224,3 @@ function compileNativeModules(dir, cliVersion, callback) { | ||
debug('exec: %s in dir %s', cmd, dir); | ||
exec(cmd, {cwd: dir}, function (err, stdout, stderr) { | ||
exec(cmd, { cwd: dir }, function (err, stdout, stderr) { | ||
if (err) { | ||
@@ -225,3 +244,3 @@ util.infoMessage('Failed to rebuild native modules. Please contact Appcelerator Support at support@appcelerator.com.'); | ||
// run them serially so we don't run into npm lock issues | ||
var doNext = function doNext() { | ||
function doNext() { | ||
var dir = dirs[finished++]; | ||
@@ -235,3 +254,3 @@ if (dir) { | ||
version; | ||
/*jshint -W083 */ | ||
/* jshint -W083 */ | ||
if (fs.existsSync(dir)) { | ||
@@ -259,3 +278,3 @@ var pkg = path.join(dir, 'package.json'); | ||
util.waitMessage('└ ' + chalk.cyan(todirname + '/' + name) + ' '); | ||
exec(cmd, {cwd: installdir}, function (err, stdout, stderr) { | ||
exec(cmd, { cwd: installdir }, function (err, stdout, stderr) { | ||
if (err) { | ||
@@ -278,3 +297,3 @@ util.infoMessage('Failed to install ' + name + version + '; it may not support your current OS.'); | ||
} | ||
}; | ||
} | ||
doNext(); | ||
@@ -291,2 +310,4 @@ } else { | ||
* start the install process | ||
* @param {object} opts - configuration options | ||
* @param {function} callback - Function to call when done | ||
*/ | ||
@@ -315,4 +336,7 @@ function start(opts, callback) { | ||
* run setup | ||
* @param {string} installBin - Path to the installation binary | ||
* @param {object} opts - Configuration options | ||
* @param {function} cb - Function to call when doe | ||
*/ | ||
function runSetup(installBin, opts, cb) { | ||
function runSetup(installBin, opts, _cb) { | ||
var run = require('./index').run, | ||
@@ -330,7 +354,7 @@ found = util.parseArgs(opts); | ||
debug('calling run with %s', installBin); | ||
run(installBin, util.mergeOptsToArgs(['--no-banner'], opts)); | ||
run(installBin, util.mergeOptsToArgs([ '--no-banner' ], opts)); | ||
} else { | ||
// otherwise, we've called a different command and we should just run | ||
// it instead and skip the setup | ||
run(installBin, util.mergeOptsToArgs(['--no-banner'], opts)); | ||
run(installBin, util.mergeOptsToArgs([ '--no-banner' ], opts)); | ||
} | ||
@@ -341,9 +365,14 @@ } | ||
* run the install | ||
* @param {string} installDir - Path to the installation directory | ||
* @param {object} opts - Configuration options | ||
* @param {function} cb - Function to call when doe | ||
*/ | ||
function install(installDir, opts, cb) { | ||
start(opts, function (err, result) { | ||
start(opts, function (_err, result) { | ||
if (!result) { | ||
util.stopSpinner(); | ||
if (!opts.quiet) { console.log('Cancelled!'); } | ||
if (!opts.quiet) { | ||
console.log('Cancelled!'); | ||
} | ||
process.exit(1); | ||
@@ -362,3 +391,5 @@ } | ||
debug('bin is setup and not force'); | ||
if (!opts.quiet) { util.infoMessage('Version ' + chalk.green(wantVersion) + ' already installed.'); } | ||
if (!opts.quiet) { | ||
util.infoMessage('Version ' + chalk.green(wantVersion) + ' already installed.'); | ||
} | ||
return cb && cb(null, installDir, wantVersion, bin); | ||
@@ -378,3 +409,5 @@ } | ||
download.start(opts.quiet, opts.banner, !!opts.force, url, wantVersion, function (err, filename, version, installBin) { | ||
if (err) { util.fail(err); } | ||
if (err) { | ||
util.fail(err); | ||
} | ||
@@ -395,3 +428,5 @@ // we mark it as failed in case it gets interuppted before finishing | ||
var pkg = path.join(installationDir, 'package', 'package.json'); | ||
if (fs.existsSync(pkg)) { fs.unlinkSync(pkg); } | ||
if (fs.existsSync(pkg)) { | ||
fs.unlinkSync(pkg); | ||
} | ||
} | ||
@@ -402,4 +437,3 @@ // if exit, go ahead and exit with exitcode | ||
process.removeListener('exit', exitFn); | ||
} | ||
catch (e) { | ||
} catch (e) { | ||
// this is OK | ||
@@ -417,4 +451,3 @@ } | ||
process.removeListener('SIGINT', sigIntFn); | ||
} | ||
catch (e) { | ||
} catch (e) { | ||
// this is OK | ||
@@ -440,3 +473,5 @@ } | ||
createCleanup()(); | ||
if (!opts.quiet) { util.infoMessage('Version ' + chalk.green(version) + ' already installed.'); } | ||
if (!opts.quiet) { | ||
util.infoMessage('Version ' + chalk.green(version) + ' already installed.'); | ||
} | ||
if (opts.setup) { | ||
@@ -512,3 +547,3 @@ util.writeVersion(version); | ||
// run it | ||
require('./index').run(installBin, ['--no-banner']); | ||
require('./index').run(installBin, [ '--no-banner' ]); | ||
}); | ||
@@ -515,0 +550,0 @@ }); |
@@ -13,2 +13,6 @@ /** | ||
* and then delegate directly (via a spawn) to the real appc binary in our package | ||
* @param {string} installBin - Installation binary to run | ||
* @param {string[]} additionalArgs - Array of additional args to pass along | ||
* @param {function} cb - Function to call when complete | ||
* @param {boolean} dontexit - Do not exit after process has finished | ||
*/ | ||
@@ -18,5 +22,5 @@ function run(installBin, additionalArgs, cb, dontexit) { | ||
chalk = require('chalk'), | ||
exec = require('child_process').exec, | ||
spawn = require('child_process').spawn, | ||
spawn = require('child_process').spawn, // eslint-disable-line security/detect-child-process | ||
path = require('path'), | ||
fs = require('fs'), | ||
util = require('./util'), | ||
@@ -26,3 +30,3 @@ isWin = /^win/.test(process.platform); | ||
// append any incoming program args | ||
var args = [installBin].concat(process.argv.splice(2)); | ||
var args = [ installBin ].concat(process.argv.splice(2)); | ||
@@ -38,7 +42,7 @@ // add any additional args | ||
// setup our node environment by first appending our appc node_modules | ||
env.NODE_PATH = path.resolve(path.join(path.dirname(installBin), '..', 'node_modules')) + path.delimiter + | ||
// and then our global cache directory | ||
path.join(util.getCacheDir(), 'node_modules') + path.delimiter + | ||
// then pickup any paths already setup in our env | ||
(env.NODE_PATH || ''); | ||
env.NODE_PATH = path.resolve(path.join(path.dirname(installBin), '..', 'node_modules')) + path.delimiter | ||
// and then our global cache directory | ||
+ path.join(util.getCacheDir(), 'node_modules') + path.delimiter | ||
// then pickup any paths already setup in our env | ||
+ (env.NODE_PATH || ''); | ||
@@ -50,4 +54,4 @@ debug('run with env=%j, args=%o', env, args); | ||
var packageDir = path.join(installBin, '..', '..'), | ||
isJSON = args.indexOf('json') === -1 ? false : true, | ||
rebuildOpts = {stdio: 'ignore', cwd: packageDir}, | ||
isJSON = args.indexOf('json') !== -1, | ||
rebuildOpts = { stdio: 'ignore', cwd: packageDir }, | ||
child; | ||
@@ -57,14 +61,14 @@ | ||
if (installBin && util.isModuleVersionChanged(installBin)) { | ||
util.outputInfo(chalk.yellow('\nYou are attempting to run appc ' + | ||
util.getActiveVersion() + | ||
' which was compiled for node ' + | ||
util.getPackageNodeVersion(installBin) + | ||
' but you are now running node ' + process.version + '\n'), isJSON); | ||
util.outputInfo(chalk.yellow('Rebuilding package modules ...' + '\n'), isJSON); | ||
util.outputInfo(chalk.yellow('\nYou are attempting to run appc ' | ||
+ util.getActiveVersion() | ||
+ ' which was compiled for node ' | ||
+ util.getPackageNodeVersion(installBin) | ||
+ ' but you are now running node ' + process.version + '\n'), isJSON); | ||
util.outputInfo(chalk.yellow('Rebuilding package modules ...\n'), isJSON); | ||
debug('exec: npm rebuild in dir %s', packageDir); | ||
if (/^win/.test(process.platform)) { | ||
child = spawn(process.env.comspec, ['/c', 'npm'].concat(['rebuild']), rebuildOpts); | ||
child = spawn(process.env.comspec, [ '/c', 'npm' ].concat([ 'rebuild' ]), rebuildOpts); | ||
} else { | ||
child = spawn('npm', ['rebuild'], rebuildOpts); | ||
child = spawn('npm', [ 'rebuild' ], rebuildOpts); | ||
} | ||
@@ -88,4 +92,23 @@ | ||
function (next) { | ||
// check that this version of the cli supports the currently selected node version | ||
const packageJsonLocation = path.join(installBin, '..', '..', 'package.json'); | ||
if (!fs.existsSync(packageJsonLocation)) { | ||
next(); | ||
} | ||
try { | ||
const packageJson = require(packageJsonLocation); | ||
if (!packageJson.engines || !packageJson.engines.node) { | ||
return next(); | ||
} | ||
util.checkNodeVersion(packageJson.engines.node); | ||
} catch (e) { /* squash */ } | ||
next(); | ||
}, | ||
function (next) { | ||
// create our child process which simply inherits this process stdio | ||
var child = spawn(process.execPath, args, {env: env, stdio: 'inherit'}); | ||
var child = spawn(process.execPath, args, { env: env, stdio: 'inherit' }); | ||
@@ -98,3 +121,3 @@ // on exit of child, exit ourselves with same exit code | ||
// propagate signals to child process | ||
['SIGTERM', 'SIGUSR1', 'SIGUSR2', 'SIGINT', 'SIGHUP', 'SIGQUIT', 'SIGABRT', 'exit'].forEach(function (name) { | ||
[ 'SIGTERM', 'SIGUSR1', 'SIGUSR2', 'SIGINT', 'SIGHUP', 'SIGQUIT', 'SIGABRT', 'exit' ].forEach(function (name) { | ||
process.on(name, function (code) { | ||
@@ -117,4 +140,8 @@ // Windows does not support sending signals | ||
], function (error, results) { | ||
if (cb) { cb(results); } | ||
if (!dontexit) { process.exit(Array.isArray(results) ? results[results.length - 1] : results); } | ||
if (cb) { | ||
cb(results); | ||
} | ||
if (!dontexit) { | ||
process.exit(Array.isArray(results) ? results[results.length - 1] : results); | ||
} | ||
}); | ||
@@ -121,0 +148,0 @@ } |
@@ -40,3 +40,3 @@ // jscs:disable jsDoc | ||
var latestUrl = util.makeURL(opts, '/api/appc/latest'); | ||
util.requestJSON({url: latestUrl}, function (err, latestVersion) { | ||
util.requestJSON({ url: latestUrl }, function (err, latestVersion) { | ||
if (err) { | ||
@@ -55,3 +55,3 @@ if (err.name === 'AppCError') { | ||
var url = util.makeURL(opts, apiPath); | ||
util.requestJSON({url: url}, function (err, result) { | ||
util.requestJSON({ url: url }, function (err, result) { | ||
util.stopSpinner(); | ||
@@ -82,3 +82,3 @@ if (err) { | ||
// Is this JSON output ? | ||
if ('json' === opts.output) { | ||
if (opts.output === 'json') { | ||
obj = util.getVersionJson(opts, result); | ||
@@ -112,3 +112,3 @@ console.log(JSON.stringify(obj, null, '\t')); | ||
// json output | ||
} else if ('json' === util.parseOpts(opts).o) { | ||
} else if (util.parseOpts(opts).o === 'json') { | ||
var obj = util.getVersionJson(versions); | ||
@@ -115,0 +115,0 @@ console.log(JSON.stringify(obj, null, '\t')); |
198
lib/util.js
@@ -22,3 +22,3 @@ // jscs:disable jsDoc | ||
sprite = '/-\\|', | ||
execSync = require('child_process').execSync; | ||
execSync = require('child_process').execSync; // eslint-disable-line security/detect-child-process | ||
@@ -28,4 +28,4 @@ var MAX_RETRIES = exports.MAX_RETRIES = 5; | ||
//NOTE: not using char-spinner because i don't want it to reset to beginning | ||
//of line each time it starts/stops. i want to spin in place at point of cursor | ||
// NOTE: not using char-spinner because i don't want it to reset to beginning | ||
// of line each time it starts/stops. i want to spin in place at point of cursor | ||
@@ -55,3 +55,3 @@ /* | ||
// go back one column | ||
exports.stdout.write('\033[1D'); | ||
exports.stdout.write('\0o33[1D'); | ||
} | ||
@@ -72,3 +72,3 @@ var s = ++spriteIndex % sprite.length; | ||
// go back on column | ||
exports.stdout.write('\033[1D'); | ||
exports.stdout.write('\0o33[1D'); | ||
spinner = null; | ||
@@ -80,2 +80,3 @@ } | ||
* write a wait message and start spinner | ||
* @param {string} msg - message to output | ||
*/ | ||
@@ -89,2 +90,3 @@ function waitMessage(msg) { | ||
* write OK mark and stop spinner | ||
* @param {string} msg - message to output | ||
*/ | ||
@@ -100,2 +102,3 @@ function okMessage(msg) { | ||
* write message and stop spinner | ||
* @param {string} msg - message to output | ||
*/ | ||
@@ -109,2 +112,3 @@ function infoMessage(msg) { | ||
* return the platform specific HOME directory | ||
* @returns {string} | ||
*/ | ||
@@ -117,2 +121,3 @@ function getHomeDir() { | ||
* return our AppC directory | ||
* @returns {string} | ||
*/ | ||
@@ -125,2 +130,3 @@ function getAppcDir() { | ||
* return the AppC install tag file | ||
* @returns {string} | ||
*/ | ||
@@ -133,2 +139,3 @@ function getInstallTag() { | ||
* return the global cache directory in the users home folder | ||
* @returns {string} | ||
*/ | ||
@@ -141,2 +148,3 @@ function getCacheDir() { | ||
* return the platform specific install directory | ||
* @returns {string} | ||
*/ | ||
@@ -149,2 +157,3 @@ function getInstallDir() { | ||
* return the version file | ||
* @returns {string} | ||
*/ | ||
@@ -157,2 +166,3 @@ function getVersionFile() { | ||
* return the config file | ||
* @returns {string} | ||
*/ | ||
@@ -165,2 +175,3 @@ function getConfigFile() { | ||
* return the private npm cache directory | ||
* @returns {string} | ||
*/ | ||
@@ -173,2 +184,3 @@ function getNpmCacheDirectory() { | ||
* write out the current version file | ||
* @param {string} version - Version to write | ||
*/ | ||
@@ -186,2 +198,3 @@ function writeVersion(version) { | ||
* return the active version (if specified) or undefined | ||
* @returns {string|undefined} | ||
*/ | ||
@@ -208,2 +221,5 @@ function getActiveVersion() { | ||
* list versions installed | ||
* @param {object} opts - Options | ||
* @param {object} versions - Versions of the CLI | ||
* @returns {undefined} | ||
*/ | ||
@@ -245,2 +261,5 @@ function listVersions(opts, versions) { | ||
* return json object of versions | ||
* @param {object} opts - Options | ||
* @param {object} versions - CLI versions | ||
* @return {object} | ||
*/ | ||
@@ -257,3 +276,5 @@ function getVersionJson(opts, versions) { | ||
if (versions[0] && versions[0].version) { | ||
obj.versions = Object.keys(versions).map(function (value, index) { return versions[index].version; }); | ||
obj.versions = Object.keys(versions).map(function (value, index) { | ||
return versions[index].version; | ||
}); | ||
} else { | ||
@@ -268,4 +289,5 @@ obj.versions = versions; | ||
* return the current versions installed | ||
* @returns {string[]} | ||
*/ | ||
function getInstalledVersions(callback) { | ||
function getInstalledVersions() { | ||
var installDir = getInstallDir(); | ||
@@ -279,7 +301,11 @@ if (fs.existsSync(installDir)) { | ||
// attempt to sort by latest version | ||
dirs = dirs.filter(function (e) { return e[0] !== '.'; }).sort(function (a, b) { | ||
var av = parseInt(a.replace(/\./g, '')), | ||
bv = parseInt(b.replace(/\./g, '')); | ||
return bv - av; | ||
}); | ||
dirs = dirs | ||
.filter(function (e) { | ||
return e[0] !== '.'; | ||
}) | ||
.sort(function (a, b) { | ||
var av = parseInt(a.replace(/\./g, '')), | ||
bv = parseInt(b.replace(/\./g, '')); | ||
return bv - av; | ||
}); | ||
} | ||
@@ -289,4 +315,3 @@ debug('found the following version directories: %j', dirs); | ||
} | ||
} | ||
catch (E) { | ||
} catch (E) { | ||
debug('error reading install directory %o', E); | ||
@@ -308,2 +333,5 @@ if (E.code === 'EACCES') { | ||
* return the platform specific install binary path | ||
* @param {object} opts - Options | ||
* @param {string} theversion - version to lookup the install binary for | ||
* @returns {string|null} | ||
*/ | ||
@@ -361,2 +389,4 @@ function getInstallBinary(opts, theversion) { | ||
* given a full path, makes sure that the directory exists | ||
* @param {string} dir - Directory to ensure exists | ||
* @return {string} | ||
*/ | ||
@@ -390,2 +420,4 @@ function ensureDir(dir) { | ||
* expand ~ in fn | ||
* @param {string} fn - Path to expand | ||
* @returns {string} | ||
*/ | ||
@@ -405,2 +437,3 @@ function expandPath(fn) { | ||
* fail and properly exit | ||
* @param {string} msg - Message to output | ||
*/ | ||
@@ -422,2 +455,3 @@ function fail(msg) { | ||
* very loose parsing of options | ||
* @returns {object} | ||
*/ | ||
@@ -447,2 +481,4 @@ function parseOpts() { | ||
* loose parse none options | ||
* @param {object} opts - Options | ||
* @returns {string[]} | ||
*/ | ||
@@ -479,5 +515,8 @@ function parseArgs(opts) { | ||
* make a registry url | ||
* @param {object} opts - Options | ||
* @param {string} urlpath - Path to add to the the baseUrl | ||
* @returns {string} | ||
*/ | ||
function makeURL(opts, urlpath) { | ||
if (typeof(opts) === 'string') { | ||
if (typeof (opts) === 'string') { | ||
urlpath = opts; | ||
@@ -531,2 +570,3 @@ opts = {}; | ||
* return the request library | ||
* @return {object} | ||
*/ | ||
@@ -539,6 +579,9 @@ function getRequest() { | ||
* make a request to location url | ||
* @param {string|object} location - url to request or request object | ||
* @param {function} callback - function to call when done | ||
* @returns {request} | ||
*/ | ||
function request(location, callback) { | ||
var options; | ||
if (typeof(location) === 'object') { | ||
if (typeof (location) === 'object') { | ||
options = location; | ||
@@ -614,2 +657,6 @@ location = options.url; | ||
* make a request a return JSON | ||
* @param {string} location - URL to request | ||
* @param {function} callback - Function to call when done | ||
* @param {number} attempts - Number or attempts to make | ||
* @return {request} | ||
*/ | ||
@@ -619,3 +666,3 @@ function requestJSON(location, callback, attempts) { | ||
attempts = attempts || 1; | ||
if (typeof(location) === 'object') { | ||
if (typeof (location) === 'object') { | ||
location.attempts = attempts + 1; | ||
@@ -679,2 +726,5 @@ } | ||
* right pad a string to a specific length | ||
* @param {string} str - string to pad | ||
* @param {number} len - number of spaces to pad | ||
* @returns {string} | ||
*/ | ||
@@ -693,2 +743,4 @@ function pad(str, len) { | ||
* returns true if directory is writable by user | ||
* @param {string} dir - Directory to check | ||
* @returns {boolean} | ||
*/ | ||
@@ -712,4 +764,3 @@ function canWriteDir(dir) { | ||
} | ||
} | ||
catch (E) { | ||
} catch (E) { | ||
if (E.code === 'EACCES') { | ||
@@ -719,9 +770,16 @@ return false; | ||
console.log(E.stack, E.code); | ||
} | ||
finally { | ||
} finally { | ||
if (fs.existsSync(fn)) { | ||
try { fs.unlinkSync(fn); } catch (ig) {} | ||
try { | ||
fs.unlinkSync(fn); | ||
} catch (ig) { | ||
// ignore | ||
} | ||
} | ||
if (del) { | ||
try { fs.unlinkSync(path); } catch (ig) {} | ||
try { | ||
fs.unlinkSync(path); | ||
} catch (ig) { | ||
// ignore | ||
} | ||
} | ||
@@ -733,2 +791,5 @@ } | ||
* if not writable, returns a message otherwise undefined | ||
* @param {string} dir - Directory to check | ||
* @param {string} name - Error name | ||
* @returns {undefined|AppcError} | ||
*/ | ||
@@ -745,10 +806,8 @@ function checkDirectory(dir, name) { | ||
return errorlib.createError('com.appcelerator.install.preflight.directory.unwritable', name, dir, message); | ||
} else { | ||
} else if (process.platform !== 'win32') { | ||
// check the ownership of the directory too | ||
if (process.platform !== 'win32') { | ||
var stat = fs.statSync(dir); | ||
if (stat.uid !== process.getuid()) { | ||
message = 'Please make sure you change the permissions using these commands:\n\n\t' + chalk.yellow('sudo chown -R ' + process.env.USER + ' ' + dir + '\n\tchmod -R 0700 ' + dir) + '\n'; | ||
return errorlib.createError('com.appcelerator.install.preflight.directory.ownership', name, dir, process.env.USER, message); | ||
} | ||
var stat = fs.statSync(dir); | ||
if (stat.uid !== process.getuid()) { | ||
message = 'Please make sure you change the permissions using these commands:\n\n\t' + chalk.yellow('sudo chown -R ' + process.env.USER + ' ' + dir + '\n\tchmod -R 0700 ' + dir) + '\n'; | ||
return errorlib.createError('com.appcelerator.install.preflight.directory.ownership', name, dir, process.env.USER, message); | ||
} | ||
@@ -770,3 +829,5 @@ } | ||
function readConfig() { | ||
if (cachedConfig) { return cachedConfig; } | ||
if (cachedConfig) { | ||
return cachedConfig; | ||
} | ||
var cf = getConfigFile(); | ||
@@ -797,6 +858,11 @@ if (!fs.existsSync(cf)) { | ||
* | ||
* @param {object} opts - Options | ||
* @param {function} callback - Function to call when done | ||
* @returns {undefined} | ||
*/ | ||
function updateCheck(opts, callback) { | ||
// we are specifying a version or we want quiet output, skip | ||
if (opts.version || opts.quiet || opts.output === 'json') { return callback(); } | ||
if (opts.version || opts.quiet || opts.output === 'json') { | ||
return callback(); | ||
} | ||
@@ -823,4 +889,3 @@ // check to see if we have a config file and if we don't that's OK, return | ||
} | ||
} | ||
catch (E) { | ||
} catch (E) { | ||
// ignore errors, they will be dealt with otherwise | ||
@@ -854,5 +919,5 @@ return callback(); | ||
} | ||
} catch (E) { | ||
// ignore | ||
} | ||
catch (E) { | ||
} | ||
} | ||
@@ -902,2 +967,6 @@ callback(); | ||
* THE SOFTWARE. | ||
* | ||
* @param {string} _path - filepath | ||
* @param {boolean} failSilent - Fail silently | ||
* @returns {undefined} | ||
*/ | ||
@@ -949,4 +1018,7 @@ function rmdirSyncRecursive(_path, failSilent) { | ||
* return an array of arguments appending any subsequent process args | ||
* @param {string} args - arguments | ||
* @param {object} opts - options | ||
* @returns {array[]} | ||
*/ | ||
function mergeOptsToArgs(args, opts) { | ||
function mergeOptsToArgs(args, _opts) { | ||
var argv = [].concat(process.__argv.slice(3)); | ||
@@ -969,2 +1041,5 @@ if (argv.length) { | ||
* appc config set proxyServer '[proxy url]' | ||
* | ||
* @param {object} config - config object | ||
* @returns {string} | ||
*/ | ||
@@ -977,3 +1052,3 @@ function getProxyServer(config) { | ||
parsed = urllib.parse(config.proxyServer); | ||
if (/^https?\:$/.test(parsed.protocol) && parsed.hostname && parsed.hostname !== 'null') { | ||
if (/^https?:$/.test(parsed.protocol) && parsed.hostname && parsed.hostname !== 'null') { | ||
proxy = config.proxyServer; | ||
@@ -983,7 +1058,8 @@ } | ||
return proxy || | ||
process.env.HTTP_PROXY || | ||
process.env.http_proxy || | ||
process.env.HTTPS_PROXY || | ||
process.env.https_proxy || ''; | ||
return proxy | ||
|| process.env.HTTP_PROXY | ||
|| process.env.http_proxy | ||
|| process.env.HTTPS_PROXY | ||
|| process.env.https_proxy | ||
|| ''; | ||
} | ||
@@ -996,2 +1072,5 @@ | ||
* appc config set strictSSL [false/true] | ||
* | ||
* @param {object} config - config object | ||
* @return {boolean|null} | ||
*/ | ||
@@ -1007,2 +1086,5 @@ function getStrictSSL(config) { | ||
* appc config set cafile '[file path, in PEM format]' | ||
* | ||
* @param {object} config - config object | ||
* @return {string|null} | ||
*/ | ||
@@ -1019,2 +1101,4 @@ function getCAfile(config) { | ||
* write out the process.versions info stored when installing package | ||
* | ||
* @param {string} pkgDir - package directory | ||
*/ | ||
@@ -1041,2 +1125,5 @@ function writeVersions(pkgDir) { | ||
* return the process.versions info when install the package | ||
* | ||
* @param {string} installBin - install binary location | ||
* @returns {object} | ||
*/ | ||
@@ -1059,2 +1146,5 @@ function readVersions(installBin) { | ||
* check if the minor/major NodeJS version changed since the package was installed | ||
* | ||
* @param {string} installBin - path to install binary | ||
* @return {boolean} | ||
*/ | ||
@@ -1077,2 +1167,5 @@ function isNodeVersionChanged(installBin) { | ||
* check if the modules version changed since the package was installed | ||
* | ||
* @param {string} installBin - path to install binary | ||
* @return {boolean} | ||
*/ | ||
@@ -1097,2 +1190,5 @@ function isModuleVersionChanged(installBin) { | ||
* return the NodeJS version used to install the package | ||
* | ||
* @param {string} installBin - path to install binary | ||
* @return {string} | ||
*/ | ||
@@ -1130,3 +1226,3 @@ function getPackageNodeVersion(installBin) { | ||
try { | ||
execSync(installBin + ' appcd stop'); | ||
execSync(installBin + ' appcd restart'); | ||
} catch (error) { | ||
@@ -1140,2 +1236,16 @@ // ignore | ||
function checkNodeVersion (supportedNodeRange) { | ||
if (!semver.satisfies(process.version, supportedNodeRange)) { | ||
console.log(chalk.cyan('Appcelerator Command-Line Interface')); | ||
console.log('Copyright (c) 2014-' + (new Date().getFullYear()) + ', Appcelerator, Inc. All Rights Reserved.'); | ||
console.log(''); | ||
console.log(chalk.red('ERROR: appc requires Node.js ' + semver.validRange(supportedNodeRange))); | ||
console.log('Visit ' + chalk.cyan('http://nodejs.org/') + ' to download a newer version.'); | ||
console.log(''); | ||
exports.exit(1); | ||
} | ||
} | ||
exports.checkNodeVersion = checkNodeVersion; | ||
exports.getAppcDir = getAppcDir; | ||
@@ -1142,0 +1252,0 @@ exports.getHomeDir = getHomeDir; |
{ | ||
"name": "appcelerator", | ||
"version": "4.2.15", | ||
"version": "4.3.0-1", | ||
"description": "Appcelerator Platform Software installer", | ||
@@ -14,3 +14,4 @@ "main": "index.js", | ||
"scripts": { | ||
"test": "JUNIT_REPORT_PATH=junit_report.xml grunt" | ||
"test": "cross-env APPC_TEST=1 JUNIT_REPORT_PATH=junit_report.xml nyc mocha test/**/*_test.js", | ||
"lint": "eslint ." | ||
}, | ||
@@ -31,12 +32,10 @@ "repository": { | ||
"devDependencies": { | ||
"grunt": "^1.0.3", | ||
"grunt-appc-js": "^1.0.19", | ||
"grunt-cli": "^1.2.0", | ||
"grunt-contrib-clean": "^1.0.0", | ||
"grunt-env": "0.4.4", | ||
"grunt-mocha-istanbul": "^5.0.2", | ||
"istanbul": "^0.4.1", | ||
"lodash": "^4.17.10", | ||
"cross-env": "^5.2.0", | ||
"eslint": "^6.2.1", | ||
"eslint-config-axway": "^4.3.0", | ||
"eslint-plugin-mocha": "^6.1.0", | ||
"lodash": "^4.17.15", | ||
"mocha": "^5.2.0", | ||
"mocha-jenkins-reporter": "^0.3.7", | ||
"mocha-jenkins-reporter": "^0.4.1", | ||
"nyc": "^14.1.1", | ||
"should": "^8.0.2" | ||
@@ -58,3 +57,6 @@ }, | ||
"node": ">=8.0.0" | ||
}, | ||
"publishConfig": { | ||
"tag": "next" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
9
3
216651
22
2345
2
45