diff --git a/HISTORY.md b/HISTORY.md index ebdbf7b..f7792bb 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,4 +1,12 @@ +0.19.0 / 2016-07-22 +=================== + + * alias: handle `ESERVFAIL` [@rauchg] + * add cmd line flag to forward NPM auth token [@rase-] + * make a binary of `now` using enclosejs [@igorklopov] + * bunch of misc improvements to build process [@leo] + 0.18.1 / 2016-06-23 =================== diff --git a/bin/now b/bin/now index e723245..f160437 100755 --- a/bin/now +++ b/bin/now @@ -39,7 +39,12 @@ if (commands.has(cmd)) { args = args.concat(process.argv.slice(2)); } -const bin = resolve(__dirname, 'now-' + cmd); +let bin = resolve(__dirname, 'now-' + cmd); +if (process.enclose) { + args.unshift("--entrypoint", bin); + bin = process.execPath; +} + const proc = spawn(bin, args, { stdio: 'inherit', customFds: [0, 1, 2] }); proc.on('close', (code) => exit(code)); proc.on('error', () => exit(1)); diff --git a/bin/now-deploy b/bin/now-deploy index 9b63ed5..70168fc 100755 --- a/bin/now-deploy +++ b/bin/now-deploy @@ -14,7 +14,7 @@ import ms from 'ms'; import { handleError, error } from '../lib/error'; const argv = minimist(process.argv.slice(2), { - boolean: ['help', 'version', 'debug', 'force', 'login', 'no-clipboard'], + boolean: ['help', 'version', 'debug', 'force', 'login', 'no-clipboard', 'forward-npm'], alias: { help: 'h', debug: 'd', @@ -22,7 +22,8 @@ const argv = minimist(process.argv.slice(2), { force: 'f', forceSync: 'F', login: 'L', - 'no-clipboard': 'C' + 'no-clipboard': 'C', + 'forward-npm': 'N' } }); @@ -47,6 +48,7 @@ const help = () => { -f, --force force a new deployment even if nothing has changed -L, --login configure login -C, --no-clipboard do not attempt to copy URL to clipboard + -N, --forward-npm Forward login information to install private NPM modules ${chalk.dim('Examples:')} @@ -93,7 +95,8 @@ const exit = (code) => { // options const debug = argv.debug; const clipboard = !argv['no-clipboard']; -const force = argv.force; +const forwardNpm = argv['forward-npm']; +const forceNew = argv.force; const forceSync = argv.forceSync; const shouldLogin = argv.login; const apiUrl = argv.url || 'https://api.zeit.co'; @@ -141,8 +144,9 @@ async function sync (token) { try { await now.create(path, { - forceNew: force, - forceSync: forceSync, + forceNew, + forceSync, + forwardNpm, quiet: !isTTY }); } catch (err) { diff --git a/enclose.js b/enclose.js new file mode 100644 index 0000000..13bfb8f --- /dev/null +++ b/enclose.js @@ -0,0 +1,5 @@ +module.exports = { + scripts: [ + "build/bin/now-*" + ] +}; diff --git a/gulpfile.babel.js b/gulpfile.babel.js index d39cb28..bb3e7f8 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js @@ -3,6 +3,7 @@ import del from 'del'; import babel from 'gulp-babel'; import uglify from 'gulp-uglify'; import help from 'gulp-task-listing'; +import { exec as enclose } from 'enclose'; gulp.task('help', help); @@ -23,6 +24,14 @@ gulp.task('compile-bin', () => .pipe(uglify()) .pipe(gulp.dest('build/bin'))); +gulp.task('enclose', ['compile'], (cb) => { + enclose([ + 'build/bin/now', + '-c', 'enclose.js', + '-o', 'build/now' + ], cb); +}); + gulp.task('watch-lib', () => gulp.watch('lib/*.js', ['compile-lib'])); gulp.task('watch-bin', () => gulp.watch('bin/*', ['compile-bin'])); gulp.task('clean', () => del(['build'])); diff --git a/lib/alias.js b/lib/alias.js index c58bdf9..cedfdc1 100644 --- a/lib/alias.js +++ b/lib/alias.js @@ -282,7 +282,7 @@ export default class Alias extends Now { try { ips = await resolve4(domain); } catch (err) { - if ('ENODATA' === err.code || 'ENOTFOUND' === err.code) { + if ('ENODATA' === err.code || 'ESERVFAIL' === err.code || 'ENOTFOUND' === err.code) { // not errors per se, just absence of records if (this._debug) console.log(`> [debug] No records found for "${domain}"`); } else { diff --git a/lib/index.js b/lib/index.js index 3131409..071d93a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -7,6 +7,8 @@ import retry from 'async-retry'; import Agent from './agent'; import EventEmitter from 'events'; import { basename, resolve as resolvePath } from 'path'; +import { homedir } from 'os'; +import { parse as parseIni } from 'ini'; import { stat, readFile } from 'fs-promise'; import resumer from 'resumer'; import splitArray from 'split-array'; @@ -28,7 +30,7 @@ export default class Now extends EventEmitter { this._onRetry = this._onRetry.bind(this); } - async create (path, { forceNew, forceSync, quiet = false }) { + async create (path, { forceNew, forceSync, forwardNpm, quiet = false }) { this._path = path; try { @@ -61,6 +63,33 @@ export default class Now extends EventEmitter { throw e; } + const nowProperties = pkg.now || {}; + + forwardNpm = forwardNpm || nowProperties['forward-npm']; + + // Read .npmrc + let npmrc = {}; + let authToken; + if (forwardNpm) { + try { + npmrc = await readFile(resolvePath(path, '.npmrc'), 'utf8'); + npmrc = parseIni(npmrc); + authToken = npmrc['//registry.npmjs.org/:_authToken']; + } catch (err) { + // Do nothing + } + + if (!authToken) { + try { + npmrc = await readFile(resolvePath(homedir(), '.npmrc'), 'utf8'); + npmrc = parseIni(npmrc); + authToken = npmrc['//registry.npmjs.org/:_authToken']; + } catch (err) { + // Do nothing + } + } + } + if (this._debug) console.time('> [debug] Getting files'); const files = await getFiles(path, pkg, { debug: this._debug }); if (this._debug) console.timeEnd('> [debug] Getting files'); @@ -71,7 +100,6 @@ export default class Now extends EventEmitter { this._files = hashes; - const nowProperties = pkg.now || {}; const engines = nowProperties.engines || pkg.engines; const deployment = await this.retry(async (bail) => { @@ -83,6 +111,7 @@ export default class Now extends EventEmitter { forceSync, name: pkg.name || basename(path), description: pkg.description, + registryAuthToken: authToken, // Flatten the array to contain files to sync where each nested input // array has a group of files with the same sha but different path files: Array.prototype.concat.apply([], Array.from(this._files).map(([sha, { data, names }]) => { diff --git a/package.json b/package.json index 179073f..0e2e281 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "now", - "version": "0.18.1", + "version": "0.19.0", "description": "realtime instant node.js deployment with one command", "readme": "", "main": "./build/lib/index", @@ -62,6 +62,7 @@ "email-validator": "1.0.4", "fs-promise": "0.5.0", "graceful-fs": "4.1.4", + "ini": "1.3.4", "minimatch": "3.0.0", "minimist": "1.2.0", "ms": "0.7.1", @@ -83,6 +84,7 @@ "babel-preset-es2015": "6.9.0", "babel-register": "6.9.0", "del": "2.2.0", + "enclose": "2.1.0", "eslint": "2.12.0", "eslint-config-standard": "5.3.1", "eslint-plugin-promise": "1.3.2", @@ -97,7 +99,8 @@ "scripts": { "start": "gulp", "test": "ava", - "prepublish": "gulp compile" + "prepublish": "gulp compile", + "enclose": "gulp enclose" }, "ava": { "failFast": true,