From 4c9caa420b3b1bc69432fd276370e03347052600 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Wed, 30 Nov 2016 20:14:20 -0800 Subject: [PATCH 01/17] initial `now.json` support --- bin/now-alias.js | 5 ++--- bin/now-deploy.js | 4 ++-- lib/index.js | 8 +++----- lib/read-metadata.js | 21 ++++++++++++++++++++- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/bin/now-alias.js b/bin/now-alias.js index a66a7c9..671d31f 100755 --- a/bin/now-alias.js +++ b/bin/now-alias.js @@ -296,13 +296,12 @@ function findAlias(alias, list) { async function realias(alias) { const path = process.cwd() - const {pkg, name} = await readMetaData(path, { + const {nowConfig, name} = await readMetaData(path, { deploymentType: 'npm', // hard coding settingsā€¦ quiet: true // `quiet` }) - const pkgConfig = pkg ? pkg.now || {} : {} - const target = pkgConfig.alias + const target = nowConfig.alias // the user never intended to support aliases from the package if (!target) { diff --git a/bin/now-deploy.js b/bin/now-deploy.js index 540b832..c65427f 100755 --- a/bin/now-deploy.js +++ b/bin/now-deploy.js @@ -363,7 +363,7 @@ async function sync(token) { } } - const {pkg: {now: pkgConfig = {}} = {}} = await readMetaData(path, { + const {nowConfig} = await readMetaData(path, { deploymentType, deploymentName, isStatic, @@ -373,7 +373,7 @@ async function sync(token) { const now = new Now(apiUrl, token, {debug}) // Merge `now.env` from package.json with `-e` arguments. - const pkgEnv = pkgConfig.env + const pkgEnv = nowConfig.env const envs = [ ...Object.keys(pkgEnv || {}).map(k => `${k}=${pkgEnv[k]}`), ...[].concat(argv.env || []) diff --git a/lib/index.js b/lib/index.js index 4cd6e99..2976753 100644 --- a/lib/index.js +++ b/lib/index.js @@ -53,7 +53,7 @@ module.exports = class Now extends EventEmitter { let files - const {pkg, name, description} = await readMetaData(path, { + const {pkg, name, description, nowConfig} = await readMetaData(path, { deploymentType, deploymentName, quiet, @@ -74,9 +74,7 @@ module.exports = class Now extends EventEmitter { console.timeEnd('> [debug] Getting files') } - const nowProperties = pkg ? pkg.now || {} : {} - - forwardNpm = forwardNpm || nowProperties.forwardNpm + forwardNpm = forwardNpm || nowConfig.forwardNpm // Read .npmrc let npmrc = {} @@ -118,7 +116,7 @@ module.exports = class Now extends EventEmitter { this._files = hashes - const engines = nowProperties.engines || pkg.engines + const engines = nowConfig.engines || pkg.engines const deployment = await this.retry(async bail => { if (this._debug) { diff --git a/lib/read-metadata.js b/lib/read-metadata.js index 4b9f626..ca6974f 100644 --- a/lib/read-metadata.js +++ b/lib/read-metadata.js @@ -19,10 +19,23 @@ module.exports = async function (path, { isStatic = false }) { let pkg = {} + let nowConfig = {} let name let description + try { + nowConfig = await readFile(resolvePath(path, 'now.json')) + nowConfig = JSON.parse(nowConfig) + } catch (err) { + // if the file doesn't exist then that's fine; any other error bubbles up + if (err.code !== 'ENOENT') { + const e = Error(`Failed to read JSON in "${path}/now.json"`) + e.userError = true + throw e + } + } + if (deploymentType === 'npm') { if (isStatic) { pkg = listPackage @@ -113,9 +126,15 @@ module.exports = async function (path, { name = deploymentName } + // merge in `package.now` if present, but have `now.json` take precedence + if (pkg.now) { + nowConfig = extend({}, pkg.now, nowConfig) + } + return { name, description, - pkg + pkg, + nowConfig } } From cee788d3e11c6c17475c4987c100d9ea289d71fb Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Thu, 1 Dec 2016 10:22:17 -0800 Subject: [PATCH 02/17] add a `strict` mode to readMetadata() Test cases will set this to `false`, because they're missing `scripts.start` and other required properties in this function --- lib/read-metadata.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/read-metadata.js b/lib/read-metadata.js index ca6974f..21ba172 100644 --- a/lib/read-metadata.js +++ b/lib/read-metadata.js @@ -16,6 +16,7 @@ module.exports = async function (path, { deploymentType = 'npm', deploymentName, quiet = false, + strict = true, isStatic = false }) { let pkg = {} @@ -50,7 +51,7 @@ module.exports = async function (path, { } } - if (!pkg.scripts || (!pkg.scripts.start && !pkg.scripts['now-start'])) { + if (strict && (!pkg.scripts || (!pkg.scripts.start && !pkg.scripts['now-start']))) { const e = Error('Missing `start` (or `now-start`) script in `package.json`. ' + 'See: https://docs.npmjs.com/cli/start.') e.userError = true @@ -81,7 +82,7 @@ module.exports = async function (path, { throw e } - if (docker.length <= 0) { + if (strict && docker.length <= 0) { const e = Error('No commands found in `Dockerfile`') e.userError = true throw e From 76e4ab503707e43ea7a715fda91d2aa2f10b0b52 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Thu, 1 Dec 2016 10:23:59 -0800 Subject: [PATCH 03/17] support `now.files` in now.json Needs a test case still... --- lib/get-files.js | 17 ++++++++++++----- lib/index.js | 4 ++-- lib/read-metadata.js | 8 +++----- test/index.js | 14 +++++--------- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/lib/get-files.js b/lib/get-files.js index a225344..cf93a8e 100644 --- a/lib/get-files.js +++ b/lib/get-files.js @@ -24,11 +24,14 @@ const IGNORED = require('./ignored') * @return {Array} comprehensive list of paths to sync */ -async function npm(path, pkg, { +async function npm(path, pkg, nowConfig = {}, { limit = null, debug = false } = {}) { - const whitelist = pkg.now && pkg.now.files ? pkg.now.files : pkg.files + const whitelist = nowConfig.files || pkg.files + + // the package.json `files` whitelist still + // honors ignores: https://docs.npmjs.com/files/package.json#files const search_ = whitelist || ['.'] // convert all filenames into absolute paths const search = Array.prototype.concat.apply([], (await Promise.all(search_.map(file => glob(file, {cwd: path, absolute: true, dot: true}))))) @@ -125,12 +128,16 @@ const asAbsolute = function (path, parent) { * @return {Array} comprehensive list of paths to sync */ -async function docker(path, { +async function docker(path, nowConfig = {}, { limit = null, debug = false } = {}) { + const whitelist = nowConfig.files + // base search path - const search_ = ['.'] + // the now.json `files` whitelist still + // honors ignores: https://docs.npmjs.com/files/package.json#files + const search_ = whitelist || ['.'] // convert all filenames into absolute paths const search = search_.map(file => asAbsolute(file, path)) @@ -262,7 +269,7 @@ const explode = async function (paths, {accepts, debug}) { const maybeRead = async function (path, default_ = '') { try { - return (await readFile(path, 'utf8')) + return await readFile(path, 'utf8') } catch (err) { return default_ } diff --git a/lib/index.js b/lib/index.js index 2976753..4caf982 100644 --- a/lib/index.js +++ b/lib/index.js @@ -65,9 +65,9 @@ module.exports = class Now extends EventEmitter { } if (deploymentType === 'npm') { - files = await getNpmFiles(path, pkg, {debug: this._debug}) + files = await getNpmFiles(path, pkg, nowConfig, {debug: this._debug}) } else { - files = await getDockerFiles(path, {debug: this._debug}) + files = await getDockerFiles(path, nowConfig, {debug: this._debug}) } if (this._debug) { diff --git a/lib/read-metadata.js b/lib/read-metadata.js index 21ba172..21d6275 100644 --- a/lib/read-metadata.js +++ b/lib/read-metadata.js @@ -12,7 +12,7 @@ const listPackage = { } } -module.exports = async function (path, { +module.exports = async function getMetadata (path, { deploymentType = 'npm', deploymentName, quiet = false, @@ -26,8 +26,7 @@ module.exports = async function (path, { let description try { - nowConfig = await readFile(resolvePath(path, 'now.json')) - nowConfig = JSON.parse(nowConfig) + nowConfig = JSON.parse(await readFile(resolvePath(path, 'now.json'))) } catch (err) { // if the file doesn't exist then that's fine; any other error bubbles up if (err.code !== 'ENOENT') { @@ -42,8 +41,7 @@ module.exports = async function (path, { pkg = listPackage } else { try { - pkg = await readFile(resolvePath(path, 'package.json')) - pkg = JSON.parse(pkg) + pkg = JSON.parse(await readFile(resolvePath(path, 'package.json'))) } catch (err) { const e = Error(`Failed to read JSON in "${path}/package.json"`) e.userError = true diff --git a/test/index.js b/test/index.js index 33ea08f..8c6faa7 100644 --- a/test/index.js +++ b/test/index.js @@ -7,22 +7,18 @@ const {asc: alpha} = require('alpha-sort') const {readFile} = require('fs-promise') // Ours -const {npm: getNpmFiles_, docker: getDockerFiles} = require('../lib/get-files') const hash = require('../lib/hash') +const readMetadata = require('../lib/read-metadata') +const {npm: getNpmFiles_, docker: getDockerFiles} = require('../lib/get-files') const prefix = join(__dirname, '_fixtures') + '/' const base = path => path.replace(prefix, '') const fixture = name => resolve(`./test/_fixtures/${name}`) -const readJSON = async file => { - const data = await readFile(file) - return JSON.parse(data) -} - // overload to force debugging -const getNpmFiles = async dir => { - const pkg = await readJSON(resolve(dir, 'package.json')) - return getNpmFiles_(dir, pkg) +const getNpmFiles = async (dir) => { + const { pkg, nowConfig } = await readMetadata(dir, { quiet: true, strict: false }) + return getNpmFiles_(dir, pkg, nowConfig) } test('`files`', async t => { From c11131310c5f23ec05714e3f11561d0cf0f101d9 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Thu, 1 Dec 2016 10:40:44 -0800 Subject: [PATCH 04/17] fix lint --- lib/read-metadata.js | 2 +- test/index.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/read-metadata.js b/lib/read-metadata.js index 21d6275..fddba12 100644 --- a/lib/read-metadata.js +++ b/lib/read-metadata.js @@ -12,7 +12,7 @@ const listPackage = { } } -module.exports = async function getMetadata (path, { +module.exports = async function getMetadata(path, { deploymentType = 'npm', deploymentName, quiet = false, diff --git a/test/index.js b/test/index.js index 8c6faa7..2e30793 100644 --- a/test/index.js +++ b/test/index.js @@ -16,8 +16,8 @@ const base = path => path.replace(prefix, '') const fixture = name => resolve(`./test/_fixtures/${name}`) // overload to force debugging -const getNpmFiles = async (dir) => { - const { pkg, nowConfig } = await readMetadata(dir, { quiet: true, strict: false }) +const getNpmFiles = async dir => { + const {pkg, nowConfig} = await readMetadata(dir, {quiet: true, strict: false}) return getNpmFiles_(dir, pkg, nowConfig) } From c44284b0b31f0479c7881bc167f566d0259a874f Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Tue, 24 Jan 2017 14:31:39 -0800 Subject: [PATCH 05/17] remove unused require call --- test/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/index.js b/test/index.js index 2e30793..d4c49d1 100644 --- a/test/index.js +++ b/test/index.js @@ -4,7 +4,6 @@ const {join, resolve} = require('path') // Packages const test = require('ava') const {asc: alpha} = require('alpha-sort') -const {readFile} = require('fs-promise') // Ours const hash = require('../lib/hash') From f6c0e65b7f06a8793e2ee8a585aeec814c74c4f1 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Tue, 24 Jan 2017 14:31:53 -0800 Subject: [PATCH 06/17] fail hard when both a `now.json` and `package.json` file with "now" are present As discussed in the GH issue. --- lib/read-metadata.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/read-metadata.js b/lib/read-metadata.js index fddba12..089120c 100644 --- a/lib/read-metadata.js +++ b/lib/read-metadata.js @@ -125,9 +125,11 @@ module.exports = async function getMetadata(path, { name = deploymentName } - // merge in `package.now` if present, but have `now.json` take precedence + // if the project has both a `now.json` and `now` Object in the `package.json` + // file, then fail hard and let the user know that they need to pick one or the + // other if (pkg.now) { - nowConfig = extend({}, pkg.now, nowConfig) + throw new Error('Refusing to proceed with multiple Now configurations (`now.json` and `package.json`). Please pick only one, then try again!') } return { From d9b5c4d4faa1aababc9c8dacd8fbd69c717b4713 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Tue, 24 Jan 2017 14:32:19 -0800 Subject: [PATCH 07/17] fix lint --- lib/read-metadata.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/read-metadata.js b/lib/read-metadata.js index 089120c..d307142 100644 --- a/lib/read-metadata.js +++ b/lib/read-metadata.js @@ -12,7 +12,9 @@ const listPackage = { } } -module.exports = async function getMetadata(path, { +module.exports = getMetadata + +async function getMetadata(path, { deploymentType = 'npm', deploymentName, quiet = false, From 4ad921e958d3fbf63b3f699056b1aad4fce7dfe8 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Wed, 25 Jan 2017 10:34:37 -0800 Subject: [PATCH 08/17] add first `now.json` test case Passing. --- test/_fixtures/now-json/a.js | 1 + test/_fixtures/now-json/b.js | 1 + test/_fixtures/now-json/now.json | 5 +++++ test/_fixtures/now-json/package.json | 9 +++++++++ test/index.js | 8 ++++++++ 5 files changed, 24 insertions(+) create mode 100644 test/_fixtures/now-json/a.js create mode 100644 test/_fixtures/now-json/b.js create mode 100644 test/_fixtures/now-json/now.json create mode 100644 test/_fixtures/now-json/package.json diff --git a/test/_fixtures/now-json/a.js b/test/_fixtures/now-json/a.js new file mode 100644 index 0000000..95c1988 --- /dev/null +++ b/test/_fixtures/now-json/a.js @@ -0,0 +1 @@ +// should not be included diff --git a/test/_fixtures/now-json/b.js b/test/_fixtures/now-json/b.js new file mode 100644 index 0000000..dcdb2da --- /dev/null +++ b/test/_fixtures/now-json/b.js @@ -0,0 +1 @@ +// should be included diff --git a/test/_fixtures/now-json/now.json b/test/_fixtures/now-json/now.json new file mode 100644 index 0000000..5acf2cb --- /dev/null +++ b/test/_fixtures/now-json/now.json @@ -0,0 +1,5 @@ +{ + "files": [ + "b.js" + ] +} diff --git a/test/_fixtures/now-json/package.json b/test/_fixtures/now-json/package.json new file mode 100644 index 0000000..c679e7f --- /dev/null +++ b/test/_fixtures/now-json/package.json @@ -0,0 +1,9 @@ +{ + "name": "woot", + "version": "0.0.1", + "description": "", + "dependencies": {}, + "files": [ + "a.js" + ] +} diff --git a/test/index.js b/test/index.js index d4c49d1..4df2279 100644 --- a/test/index.js +++ b/test/index.js @@ -165,3 +165,11 @@ test('prefix regression', async t => { t.is(base(files[0]), 'prefix-regression/package.json') t.is(base(files[1]), 'prefix-regression/woot.js') }) + +test.only('support `now.json` files', async t => { + let files = await getNpmFiles(fixture('now-json')) + files = files.sort(alpha) + t.is(files.length, 2) + t.is(base(files[0]), 'now-json/b.js') + t.is(base(files[1]), 'now-json/package.json') +}) From 38fe08ad97160bdfca7ec9753eb6aa301f5f27f9 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Wed, 25 Jan 2017 10:38:13 -0800 Subject: [PATCH 09/17] rename getMetadata() to readMetaData() Matches what it's called elsewhere in the codebase --- lib/read-metadata.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/read-metadata.js b/lib/read-metadata.js index d307142..529221f 100644 --- a/lib/read-metadata.js +++ b/lib/read-metadata.js @@ -12,9 +12,9 @@ const listPackage = { } } -module.exports = getMetadata +module.exports = readMetaData -async function getMetadata(path, { +async function readMetaData(path, { deploymentType = 'npm', deploymentName, quiet = false, From 7daf1e4c492d3cd29de45106f19a3f190a05852b Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Wed, 25 Jan 2017 10:42:45 -0800 Subject: [PATCH 10/17] Only throw when both `pkg.now` and `now.json` are present Fixes failing test case. --- lib/read-metadata.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/read-metadata.js b/lib/read-metadata.js index 529221f..8b19b60 100644 --- a/lib/read-metadata.js +++ b/lib/read-metadata.js @@ -23,12 +23,14 @@ async function readMetaData(path, { }) { let pkg = {} let nowConfig = {} + let hasNowJson = false let name let description try { nowConfig = JSON.parse(await readFile(resolvePath(path, 'now.json'))) + hasNowJson = true } catch (err) { // if the file doesn't exist then that's fine; any other error bubbles up if (err.code !== 'ENOENT') { @@ -127,11 +129,15 @@ async function readMetaData(path, { name = deploymentName } - // if the project has both a `now.json` and `now` Object in the `package.json` - // file, then fail hard and let the user know that they need to pick one or the - // other if (pkg.now) { - throw new Error('Refusing to proceed with multiple Now configurations (`now.json` and `package.json`). Please pick only one, then try again!') + // if the project has both a `now.json` and `now` Object in the `package.json` + // file, then fail hard and let the user know that they need to pick one or the + // other + if (hasNowJson) { + throw new Error('Refusing to proceed with multiple Now configurations (`now.json` and `package.json`). Please pick only one, then try again!') + } else { + nowConfig = pkg.now + } } return { From 1151830af6604e651676a518e7be2e1c157f819b Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Wed, 25 Jan 2017 12:09:28 -0800 Subject: [PATCH 11/17] a couple more test cases and fixes for them --- lib/get-files.js | 20 +++++++++--- lib/index.js | 13 +++++--- lib/read-metadata.js | 18 +++++++++-- test/_fixtures/now-json-docker/Dockerfile | 1 + test/_fixtures/now-json-docker/a.js | 1 + test/_fixtures/now-json-docker/b.js | 1 + test/_fixtures/now-json-docker/now.json | 6 ++++ test/_fixtures/now-json-throws/now.json | 3 ++ test/_fixtures/now-json-throws/package.json | 9 ++++++ test/index.js | 35 ++++++++++++++++++--- 10 files changed, 89 insertions(+), 18 deletions(-) create mode 100644 test/_fixtures/now-json-docker/Dockerfile create mode 100644 test/_fixtures/now-json-docker/a.js create mode 100644 test/_fixtures/now-json-docker/b.js create mode 100644 test/_fixtures/now-json-docker/now.json create mode 100644 test/_fixtures/now-json-throws/now.json create mode 100644 test/_fixtures/now-json-throws/package.json diff --git a/lib/get-files.js b/lib/get-files.js index cf93a8e..b61da19 100644 --- a/lib/get-files.js +++ b/lib/get-files.js @@ -24,11 +24,12 @@ const IGNORED = require('./ignored') * @return {Array} comprehensive list of paths to sync */ -async function npm(path, pkg, nowConfig = {}, { +async function npm(path, pkg, nowConfig = null, { limit = null, + hasNowJson = false, debug = false } = {}) { - const whitelist = nowConfig.files || pkg.files + const whitelist = (nowConfig && nowConfig.files) || pkg.files // the package.json `files` whitelist still // honors ignores: https://docs.npmjs.com/files/package.json#files @@ -95,6 +96,10 @@ async function npm(path, pkg, nowConfig = {}, { // source: https://docs.npmjs.com/files/package.json#files files.push(asAbsolute('package.json', path)) + if (hasNowJson) { + files.push(asAbsolute('now.json', path)) + } + // get files return unique(files) } @@ -128,11 +133,12 @@ const asAbsolute = function (path, parent) { * @return {Array} comprehensive list of paths to sync */ -async function docker(path, nowConfig = {}, { +async function docker(path, nowConfig = null, { limit = null, + hasNowJson = false, debug = false } = {}) { - const whitelist = nowConfig.files + const whitelist = nowConfig && nowConfig.files // base search path // the now.json `files` whitelist still @@ -183,6 +189,10 @@ async function docker(path, nowConfig = {}, { // source: https://docs.npmjs.com/files/package.json#files files.push(asAbsolute('Dockerfile', path)) + if (hasNowJson) { + files.push(asAbsolute('now.json', path)) + } + // get files return unique(files) } @@ -213,7 +223,7 @@ const glob = async function (pattern, options) { * @return {Array} of {String}s of full paths */ -const explode = async function (paths, {accepts, debug}) { +async function explode (paths, {accepts, debug}) { const list = async file => { let path = file let s diff --git a/lib/index.js b/lib/index.js index 4caf982..9359eee 100644 --- a/lib/index.js +++ b/lib/index.js @@ -53,28 +53,31 @@ module.exports = class Now extends EventEmitter { let files - const {pkg, name, description, nowConfig} = await readMetaData(path, { + const meta = await readMetaData(path, { deploymentType, deploymentName, quiet, isStatic }) + const {pkg, name, description, nowConfig, hasNowJson} = meta + deploymentType = meta.deploymentType if (this._debug) { console.time('> [debug] Getting files') } + const opts = {debug: this._debug, hasNowJson} if (deploymentType === 'npm') { - files = await getNpmFiles(path, pkg, nowConfig, {debug: this._debug}) + files = await getNpmFiles(path, pkg, nowConfig, opts) } else { - files = await getDockerFiles(path, nowConfig, {debug: this._debug}) + files = await getDockerFiles(path, nowConfig, opts) } if (this._debug) { console.timeEnd('> [debug] Getting files') } - forwardNpm = forwardNpm || nowConfig.forwardNpm + forwardNpm = forwardNpm || (nowConfig && nowConfig.forwardNpm) // Read .npmrc let npmrc = {} @@ -116,7 +119,7 @@ module.exports = class Now extends EventEmitter { this._files = hashes - const engines = nowConfig.engines || pkg.engines + const engines = (nowConfig && nowConfig.engines) || pkg.engines const deployment = await this.retry(async bail => { if (this._debug) { diff --git a/lib/read-metadata.js b/lib/read-metadata.js index 8b19b60..bc6f43d 100644 --- a/lib/read-metadata.js +++ b/lib/read-metadata.js @@ -22,7 +22,7 @@ async function readMetaData(path, { isStatic = false }) { let pkg = {} - let nowConfig = {} + let nowConfig = null let hasNowJson = false let name @@ -40,6 +40,12 @@ async function readMetaData(path, { } } + // user can specify the type of deployment explicitly in the `now.json` file + // when both a package.json and Dockerfile exist + if (hasNowJson && nowConfig.type) { + deploymentType = nowConfig.type + } + if (deploymentType === 'npm') { if (isStatic) { pkg = listPackage @@ -123,6 +129,8 @@ async function readMetaData(path, { } description = labels.description + } else { + throw new TypeError(`Unsupported "deploymentType": ${deploymentType}`) } if (deploymentName) { @@ -134,7 +142,9 @@ async function readMetaData(path, { // file, then fail hard and let the user know that they need to pick one or the // other if (hasNowJson) { - throw new Error('Refusing to proceed with multiple Now configurations (`now.json` and `package.json`). Please pick only one, then try again!') + const e = new Error('Refusing to proceed with multiple Now configurations (`now.json` and `package.json`). Please pick only one, then try again!') + e.userError = true + throw e } else { nowConfig = pkg.now } @@ -143,7 +153,9 @@ async function readMetaData(path, { return { name, description, + deploymentType, pkg, - nowConfig + nowConfig, + hasNowJson } } diff --git a/test/_fixtures/now-json-docker/Dockerfile b/test/_fixtures/now-json-docker/Dockerfile new file mode 100644 index 0000000..a86da2e --- /dev/null +++ b/test/_fixtures/now-json-docker/Dockerfile @@ -0,0 +1 @@ +CMD echo 'world' diff --git a/test/_fixtures/now-json-docker/a.js b/test/_fixtures/now-json-docker/a.js new file mode 100644 index 0000000..95c1988 --- /dev/null +++ b/test/_fixtures/now-json-docker/a.js @@ -0,0 +1 @@ +// should not be included diff --git a/test/_fixtures/now-json-docker/b.js b/test/_fixtures/now-json-docker/b.js new file mode 100644 index 0000000..dcdb2da --- /dev/null +++ b/test/_fixtures/now-json-docker/b.js @@ -0,0 +1 @@ +// should be included diff --git a/test/_fixtures/now-json-docker/now.json b/test/_fixtures/now-json-docker/now.json new file mode 100644 index 0000000..88faec5 --- /dev/null +++ b/test/_fixtures/now-json-docker/now.json @@ -0,0 +1,6 @@ +{ + "type": "docker", + "files": [ + "b.js" + ] +} diff --git a/test/_fixtures/now-json-throws/now.json b/test/_fixtures/now-json-throws/now.json new file mode 100644 index 0000000..087ce94 --- /dev/null +++ b/test/_fixtures/now-json-throws/now.json @@ -0,0 +1,3 @@ +{ + "alias": "bar.com" +} diff --git a/test/_fixtures/now-json-throws/package.json b/test/_fixtures/now-json-throws/package.json new file mode 100644 index 0000000..350ad6c --- /dev/null +++ b/test/_fixtures/now-json-throws/package.json @@ -0,0 +1,9 @@ +{ + "name": "woot", + "version": "0.0.1", + "description": "", + "dependencies": {}, + "now": { + "alias": "foo.com" + } +} diff --git a/test/index.js b/test/index.js index 4df2279..df80ad6 100644 --- a/test/index.js +++ b/test/index.js @@ -16,8 +16,8 @@ const fixture = name => resolve(`./test/_fixtures/${name}`) // overload to force debugging const getNpmFiles = async dir => { - const {pkg, nowConfig} = await readMetadata(dir, {quiet: true, strict: false}) - return getNpmFiles_(dir, pkg, nowConfig) + const {pkg, nowConfig, hasNowJson} = await readMetadata(dir, {quiet: true, strict: false}) + return getNpmFiles_(dir, pkg, nowConfig, {hasNowJson}) } test('`files`', async t => { @@ -166,10 +166,35 @@ test('prefix regression', async t => { t.is(base(files[1]), 'prefix-regression/woot.js') }) -test.only('support `now.json` files', async t => { +test('support `now.json` files with package.json', async t => { let files = await getNpmFiles(fixture('now-json')) files = files.sort(alpha) - t.is(files.length, 2) + t.is(files.length, 3) t.is(base(files[0]), 'now-json/b.js') - t.is(base(files[1]), 'now-json/package.json') + t.is(base(files[1]), 'now-json/now.json') + t.is(base(files[2]), 'now-json/package.json') +}) + +test('support `now.json` files with Dockerfile', async t => { + const f = fixture('now-json-docker') + const {deploymentType, nowConfig, hasNowJson} = await readMetadata(f, {quiet: true, strict: false}) + t.is(deploymentType, 'docker') + + let files = await getDockerFiles(f, nowConfig, {hasNowJson}) + files = files.sort(alpha) + t.is(files.length, 3) + t.is(base(files[0]), 'now-json-docker/Dockerfile') + t.is(base(files[1]), 'now-json-docker/b.js') + t.is(base(files[2]), 'now-json-docker/now.json') +}) + +test('throws when both `now.json` and `package.json:now` exist', async t => { + let err + try { + await readMetadata(fixture('now-json-throws'), {quiet: true, strict: false}) + } catch (e) { + err = e + } + t.is(err.name, 'Error') + t.pass(/refusing to proceed/i.test(err.message)) }) From 0b2b39222c132c4e46090bf603877390ed2c15c6 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Wed, 25 Jan 2017 12:12:58 -0800 Subject: [PATCH 12/17] lint --- lib/get-files.js | 2 +- test/index.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/get-files.js b/lib/get-files.js index b61da19..f797b6e 100644 --- a/lib/get-files.js +++ b/lib/get-files.js @@ -223,7 +223,7 @@ const glob = async function (pattern, options) { * @return {Array} of {String}s of full paths */ -async function explode (paths, {accepts, debug}) { +async function explode(paths, {accepts, debug}) { const list = async file => { let path = file let s diff --git a/test/index.js b/test/index.js index df80ad6..5bfcd73 100644 --- a/test/index.js +++ b/test/index.js @@ -189,12 +189,12 @@ test('support `now.json` files with Dockerfile', async t => { }) test('throws when both `now.json` and `package.json:now` exist', async t => { - let err + let e try { await readMetadata(fixture('now-json-throws'), {quiet: true, strict: false}) - } catch (e) { - err = e + } catch (err) { + e = err } - t.is(err.name, 'Error') - t.pass(/refusing to proceed/i.test(err.message)) + t.is(e.name, 'Error') + t.pass(/refusing to proceed/i.test(e.message)) }) From 540caa4db7de68b389f8cf5b4b2930ac14e556d8 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Wed, 25 Jan 2017 12:15:02 -0800 Subject: [PATCH 13/17] fixes for when `nowConfig` is null --- bin/now-alias.js | 2 +- bin/now-deploy.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/now-alias.js b/bin/now-alias.js index 671d31f..4814f5f 100755 --- a/bin/now-alias.js +++ b/bin/now-alias.js @@ -301,7 +301,7 @@ async function realias(alias) { quiet: true // `quiet` }) - const target = nowConfig.alias + const target = nowConfig && nowConfig.alias // the user never intended to support aliases from the package if (!target) { diff --git a/bin/now-deploy.js b/bin/now-deploy.js index c65427f..08ecc53 100755 --- a/bin/now-deploy.js +++ b/bin/now-deploy.js @@ -373,7 +373,7 @@ async function sync(token) { const now = new Now(apiUrl, token, {debug}) // Merge `now.env` from package.json with `-e` arguments. - const pkgEnv = nowConfig.env + const pkgEnv = nowConfig && nowConfig.env const envs = [ ...Object.keys(pkgEnv || {}).map(k => `${k}=${pkgEnv[k]}`), ...[].concat(argv.env || []) From 73f22bb68e91cfbf44749f80b29c52f7d5714492 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Wed, 25 Jan 2017 13:00:01 -0800 Subject: [PATCH 14/17] use G's wording for error message --- lib/read-metadata.js | 2 +- test/index.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/read-metadata.js b/lib/read-metadata.js index bc6f43d..cbb9cf9 100644 --- a/lib/read-metadata.js +++ b/lib/read-metadata.js @@ -142,7 +142,7 @@ async function readMetaData(path, { // file, then fail hard and let the user know that they need to pick one or the // other if (hasNowJson) { - const e = new Error('Refusing to proceed with multiple Now configurations (`now.json` and `package.json`). Please pick only one, then try again!') + const e = new Error('You have a `now` configuration field inside `package.json`, but configuration is also present in `now.json`! Please ensure there\'s a single source of configuration by removing one') e.userError = true throw e } else { diff --git a/test/index.js b/test/index.js index 5bfcd73..47ebda4 100644 --- a/test/index.js +++ b/test/index.js @@ -196,5 +196,6 @@ test('throws when both `now.json` and `package.json:now` exist', async t => { e = err } t.is(e.name, 'Error') - t.pass(/refusing to proceed/i.test(e.message)) + t.is(e.userError, true) + t.pass(/please ensure there\'s a single source of configuration/i.test(e.message)) }) From 7f92455b2e2a3f097defd93394b5a055de13c9f4 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Wed, 25 Jan 2017 13:03:28 -0800 Subject: [PATCH 15/17] lint *again* --- test/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/index.js b/test/index.js index 47ebda4..11b1f99 100644 --- a/test/index.js +++ b/test/index.js @@ -197,5 +197,5 @@ test('throws when both `now.json` and `package.json:now` exist', async t => { } t.is(e.name, 'Error') t.is(e.userError, true) - t.pass(/please ensure there\'s a single source of configuration/i.test(e.message)) + t.pass(/please ensure there's a single source of configuration/i.test(e.message)) }) From 957744e3a581eb7a5cc47ddf53a74e6fd7490ab3 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Wed, 25 Jan 2017 16:00:49 -0800 Subject: [PATCH 16/17] add `now.json:name` field support --- lib/read-metadata.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/read-metadata.js b/lib/read-metadata.js index cbb9cf9..c5636c5 100644 --- a/lib/read-metadata.js +++ b/lib/read-metadata.js @@ -40,10 +40,15 @@ async function readMetaData(path, { } } - // user can specify the type of deployment explicitly in the `now.json` file - // when both a package.json and Dockerfile exist - if (hasNowJson && nowConfig.type) { - deploymentType = nowConfig.type + if (hasNowJson) { + // user can specify the type of deployment explicitly in the `now.json` file + // when both a package.json and Dockerfile exist + if (nowConfig.type) { + deploymentType = nowConfig.type + } + if (nowConfig.name) { + deploymentName = nowConfig.name + } } if (deploymentType === 'npm') { @@ -123,7 +128,11 @@ async function readMetaData(path, { name = basename(path) if (!quiet) { - console.log(`> No \`name\` LABEL in \`Dockerfile\`, using ${chalk.bold(name)}`) + if (hasNowJson) { + console.log(`> No \`name\` LABEL in \`Dockerfile\` or \`name\` field in `\now.json\`, using ${chalk.bold(name)}`) + } else { + console.log(`> No \`name\` LABEL in \`Dockerfile\`, using ${chalk.bold(name)}`) + } } } } From 9540863c0e8cc90a846a3f1f086373c6ea4f123f Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Wed, 25 Jan 2017 16:04:39 -0800 Subject: [PATCH 17/17] fix typo --- lib/read-metadata.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/read-metadata.js b/lib/read-metadata.js index c5636c5..011eee9 100644 --- a/lib/read-metadata.js +++ b/lib/read-metadata.js @@ -129,7 +129,7 @@ async function readMetaData(path, { if (!quiet) { if (hasNowJson) { - console.log(`> No \`name\` LABEL in \`Dockerfile\` or \`name\` field in `\now.json\`, using ${chalk.bold(name)}`) + console.log(`> No \`name\` LABEL in \`Dockerfile\` or \`name\` field in \`now.json\`, using ${chalk.bold(name)}`) } else { console.log(`> No \`name\` LABEL in \`Dockerfile\`, using ${chalk.bold(name)}`) }