Guillermo Rauch 9 years ago
parent
commit
39a4435e4b
  1. 8
      bin/now-deploy
  2. 113
      lib/get-files.js
  3. 2
      lib/index.js
  4. 1
      test/_fixtures/always-include-main/a.js
  5. 1
      test/_fixtures/always-include-main/b.js
  6. 10
      test/_fixtures/always-include-main/package.json
  7. 1
      test/_fixtures/always-include-main/woot.js
  8. 1
      test/_fixtures/dockerfile/Dockerfile
  9. 1
      test/_fixtures/dockerfile/a.js
  10. 1
      test/_fixtures/negation/a.js
  11. 1
      test/_fixtures/nested-node_modules/.npmignore
  12. 1
      test/_fixtures/nested-node_modules/index.js
  13. 3
      test/_fixtures/nested-node_modules/package.json
  14. 2
      test/_fixtures/no-node_modules/package.json
  15. 1
      test/_fixtures/now-files/a.js
  16. 1
      test/_fixtures/now-files/b.js
  17. 14
      test/_fixtures/now-files/package.json
  18. 79
      test/index.js

8
bin/now-deploy

@ -79,10 +79,10 @@ const help = () => {
let path = argv._[0];
if (path) {
if ('/' !== path[0]) {
path = resolve(process.cwd(), path);
}
if (null != path) {
// if path is relative: resolve
// if path is absolute: clear up strange `/` etc
path = resolve(process.cwd(), path);
} else {
path = process.cwd();
}

113
lib/get-files.js

@ -22,53 +22,115 @@ import parser from 'gitignore-parser';
export async function npm (path, pkg, {
limit = null,
debug = false
}) {
} = {}) {
const whitelist = pkg.now && pkg.now.files
? pkg.now.files
: pkg.files;
// the package.json `files` whitelist still
// honors ignores: https://docs.npmjs.com/files/package.json#files
let search = (whitelist || ['.']).push('package.json');
const search_ = whitelist || ['.'];
// always include the "main" file
if (pkg.main) {
search.push(pkg.main);
search_.push(pkg.main);
}
// always include binary files
if (pkg.bin) {
for (const script in pkg.bin) {
search.push(pkg.bin[script]);
// convert all filenames into absolute paths
const search = search_.map((file) => asAbsolute(file, path));
// locate files
if (debug) console.time('> [debug] locating files');
const files_ = await explode(search, { limit, debug });
if (debug) console.timeEnd('> [debug] locating files');
// compile list of ignored patterns and files
const npmIgnore = await maybeRead(resolve(path, '.npmignore'), null);
const ignored = parser.compile(
IGNORED +
'\n' +
clearRelative(null != npmIgnore
? npmIgnore
: await maybeRead(resolve(path, '.gitignore')))
);
// if debugging is turned on, describe which files
// are being ignored
const prefixLength = path.length + 1;
const accepts = function (file) {
const accepted = ignored.accepts(file.substr(prefixLength));
if (!accepted && debug) {
console.log('> [debug] ignoring "%s"', file);
}
}
return accepted;
};
// filter files
const files = files_.filter(accepts);
// always include manifest as npm does not allow ignoring it
// source: https://docs.npmjs.com/files/package.json#files
files.push(asAbsolute('package.json', path));
// get files
return unique(files);
}
/**
* Returns a list of files in the given
* directory that are subject to be
* sent to docker as build context.
*
* @param {String} full path to directory
* @param {String} contents of `Dockerfile`
* @param {Object} options:
* - `limit` {Number|null} byte limit
* - `debug` {Boolean} warn upon ignore
* @return {Array} comprehensive list of paths to sync
*/
export async function docker (path, {
limit = null,
debug = false
} = {}) {
// base search path
const search_ = ['.'];
// convert all filenames into absolute paths
search = search.map((file) => asAbsolute(file, path));
const search = search_.map((file) => asAbsolute(file, path));
// locate files
if (debug) console.time('> [debug] locating files');
const files = await explode(search, { limit, debug });
const files_ = await explode(search, { limit, debug });
if (debug) console.timeEnd('> [debug] locating files');
// compile list of ignored patterns and files
const npmIgnore = await maybeRead(resolve(path, '.npmignore'));
const ignored = parser.compile(
IGNORED +
'\n' +
npmIgnore
? npmIgnore
: await maybeRead(resolve(path, '.gitignore'))
await maybeRead(resolve(path, '.dockerignore'))
);
// if debugging is turned on, describe which files
// are being ignored
const accepts = debug ? function (file) {
const accepted = ignored.accepts(file);
if (!accepted) {
const prefixLength = path.length + 1;
const accepts = function (file) {
const accepted = ignored.accepts(file.substr(prefixLength));
if (!accepted && debug) {
console.log('> [debug] ignoring "%s"', file);
}
return accepted;
} : ignored.accepts;
};
// filter files
const files = files_.filter(accepts);
// always include manifest as npm does not allow ignoring it
// source: https://docs.npmjs.com/files/package.json#files
files.push(asAbsolute('Dockerfile', path));
// get files
return unique(files.filter(accepts));
return unique(files);
}
/**
@ -140,10 +202,19 @@ const explode = async function (paths, { limit, debug }) {
* @return {String} results or `''`
*/
const maybeRead = async function (path) {
const maybeRead = async function (path, default_ = '') {
try {
return (await readFile(path, 'utf8'));
} catch (e) {
return '';
return default_;
}
};
/**
* Remove leading `./` from the beginning of ignores
* because our parser doesn't like them :|
*/
const clearRelative = function (str) {
return str.replace(/(\n|^)\.\//g, '$1');
}

2
lib/index.js

@ -3,7 +3,7 @@ import chalk from 'chalk';
import {
npm as getNpmFiles,
docker as getDockerFiles
} from './get-npm-files';
} from './get-files';
import ua from './ua';
import hash from './hash';
import retry from 'async-retry';

1
test/_fixtures/always-include-main/a.js

@ -0,0 +1 @@
// should be included

1
test/_fixtures/always-include-main/b.js

@ -0,0 +1 @@
// should NOT be included

10
test/_fixtures/always-include-main/package.json

@ -0,0 +1,10 @@
{
"name": "should-include-main",
"version": "0.0.1",
"description": "",
"main": "a.js",
"files": [
"woot.js"
],
"dependencies": {}
}

1
test/_fixtures/always-include-main/woot.js

@ -0,0 +1 @@
// should be included

1
test/_fixtures/dockerfile/Dockerfile

@ -0,0 +1 @@
CMD echo 'world'

1
test/_fixtures/dockerfile/a.js

@ -0,0 +1 @@
// this should be included

1
test/_fixtures/negation/a.js

@ -0,0 +1 @@
// should include it

1
test/_fixtures/nested-node_modules/.npmignore

@ -0,0 +1 @@
**/node_modules

1
test/_fixtures/nested-node_modules/index.js

@ -0,0 +1 @@
// this should be included

3
test/_fixtures/nested-node_modules/package.json

@ -0,0 +1,3 @@
{
"name": "nested-node_modules"
}

2
test/_fixtures/no-node_modules/package.json

@ -1,5 +1,5 @@
{
"name": "",
"name": "no-node_modules",
"version": "0.0.1",
"description": "",
"dependencies": {}

1
test/_fixtures/now-files/a.js

@ -0,0 +1 @@
// should not be included

1
test/_fixtures/now-files/b.js

@ -0,0 +1 @@
// should be included

14
test/_fixtures/now-files/package.json

@ -0,0 +1,14 @@
{
"name": "woot",
"version": "0.0.1",
"description": "",
"dependencies": {},
"files": [
"a.js"
],
"now": {
"files": [
"b.js"
]
}
}

79
test/index.js

@ -1,18 +1,30 @@
import test from 'ava';
import { join, resolve } from 'path';
import _getFiles from '../lib/get-files';
import {
npm as getNpmFiles_,
docker as getDockerFiles
} from '../lib/get-files';
import hash from '../lib/hash';
import { asc as alpha } from 'alpha-sort';
import { readFile } from 'fs-promise';
const prefix = join(__dirname, '_fixtures') + '/';
const base = (path) => path.replace(prefix, '');
const fixture = (name) => resolve(`./_fixtures/${name}`);
// overload to force debugging
const getFiles = (dir) => _getFiles(dir, null, true);
const getNpmFiles = async (dir) => {
const pkg = await readJSON(resolve(dir, 'package.json'));
return getNpmFiles_(dir, pkg);
};
test('`files` + README', async t => {
let files = await getFiles(fixture('files-in-package'));
const readJSON = async (file) => {
const data = await readFile(file);
return JSON.parse(data);
};
test('`files`', async t => {
let files = await getNpmFiles(fixture('files-in-package'));
t.is(files.length, 3);
files = files.sort(alpha);
t.is(base(files[0]), 'files-in-package/build/a/b/c/d.js');
@ -20,19 +32,19 @@ test('`files` + README', async t => {
t.is(base(files[2]), 'files-in-package/package.json');
});
test('`files` + README + `.*.swp` + `.npmignore`', async t => {
let files = await getFiles(fixture('files-in-package-ignore'));
t.is(files.length, 3);
test('`files` + `.*.swp` + `.npmignore`', async t => {
let files = await getNpmFiles(fixture('files-in-package-ignore'));
files = files.sort(alpha);
t.is(files.length, 3);
t.is(base(files[0]), 'files-in-package-ignore/build/a/b/c/d.js');
t.is(base(files[1]), 'files-in-package-ignore/build/a/e.js');
t.is(base(files[2]), 'files-in-package-ignore/package.json');
});
test('simple', async t => {
let files = await getFiles(fixture('simple'));
t.is(files.length, 5);
let files = await getNpmFiles(fixture('simple'));
files = files.sort(alpha);
t.is(files.length, 5);
t.is(base(files[0]), 'simple/bin/test');
t.is(base(files[1]), 'simple/index.js');
t.is(base(files[2]), 'simple/lib/woot');
@ -41,16 +53,17 @@ test('simple', async t => {
});
test('simple with main', async t => {
let files = await getFiles(fixture('simple-main'));
let files = await getNpmFiles(fixture('simple-main'));
t.is(files.length, 3);
files = files.sort(alpha);
t.is(files.length, 3);
t.is(base(files[0]), 'simple-main/build/a.js');
t.is(base(files[1]), 'simple-main/index.js');
t.is(base(files[2]), 'simple-main/package.json');
});
test('hashes', async t => {
const files = await getFiles(fixture('hashes'));
const files = await getNpmFiles(fixture('hashes'));
const hashes = await hash(files);
t.is(hashes.size, 3);
t.is(hashes.get('277c55a2042910b9fe706ad00859e008c1b7d172').names[0], prefix + 'hashes/dei.png');
@ -60,8 +73,50 @@ test('hashes', async t => {
});
test('ignore node_modules', async t => {
let files = await getFiles(fixture('no-node_modules'));
let files = await getNpmFiles(fixture('no-node_modules'));
files = files.sort(alpha);
t.is(files.length, 2);
t.is(base(files[0]), 'no-node_modules/index.js');
t.is(base(files[1]), 'no-node_modules/package.json');
});
test('ignore nested `node_modules` with .npmignore **', async t => {
let files = await getNpmFiles(fixture('nested-node_modules'));
files = files.sort(alpha);
t.is(files.length, 2);
t.is(base(files[0]), 'nested-node_modules/index.js');
t.is(base(files[1]), 'nested-node_modules/package.json');
});
test('include `main` even if not in files', async t => {
let files = await getNpmFiles(fixture('always-include-main'));
files = files.sort(alpha);
t.is(files.length, 3);
t.is(base(files[0]), 'always-include-main/a.js');
t.is(base(files[1]), 'always-include-main/package.json');
t.is(base(files[2]), 'always-include-main/woot.js');
});
test('support whitelisting with .npmignore and !', async t => {
let files = await getNpmFiles(fixture('negation'));
files = files.sort(alpha);
t.is(files.length, 2);
t.is(base(files[0]), 'negation/a.js');
t.is(base(files[1]), 'negation/package.json');
});
test('support `now.files`', async t => {
let files = await getNpmFiles(fixture('now-files'));
files = files.sort(alpha);
t.is(files.length, 2);
t.is(base(files[0]), 'now-files/b.js');
t.is(base(files[1]), 'now-files/package.json');
});
test('support docker', async t => {
let files = await getDockerFiles(fixture('dockerfile'));
files = files.sort(alpha);
t.is(files.length, 2);
t.is(base(files[0]), 'dockerfile/Dockerfile');
t.is(base(files[1]), 'dockerfile/a.js');
});

Loading…
Cancel
Save