diff --git a/index.js b/index.js index 811c4b3..dd7706a 100644 --- a/index.js +++ b/index.js @@ -51,6 +51,9 @@ const defaultRules = [ 'core.+([0-9])', ] +// There may be others, but :?|<> are handled by node-tar +const nameIsBadForWindows = file => /\*/.test(file) + // a decorator that applies our custom rules to an ignore walker const npmWalker = Class => class Walker extends Class { constructor (opt) { @@ -191,6 +194,16 @@ const npmWalker = Class => class Walker extends Class { then() } + // override parent stat function to completely skip any filenames + // that will break windows entirely. + // XXX(isaacs) Next major version should make this an error instead. + stat (entry, file, dir, then) { + if (nameIsBadForWindows(entry)) + then() + else + super.stat(entry, file, dir, then) + } + // override parent onstat function to nix all symlinks onstat (st, entry, file, dir, then) { if (st.isSymbolicLink()) diff --git a/tap-snapshots/test-star-names.js-TAP.test.js b/tap-snapshots/test-star-names.js-TAP.test.js deleted file mode 100644 index 7254245..0000000 --- a/tap-snapshots/test-star-names.js-TAP.test.js +++ /dev/null @@ -1,22 +0,0 @@ -/* IMPORTANT - * This snapshot file is auto-generated, but designed for humans. - * It should be checked into source control and tracked carefully. - * Re-generate by setting TAP_SNAPSHOT=1 and running tests. - * Make sure to inspect the output below. Do not ignore changes! - */ -'use strict' -exports[`test/star-names.js TAP follows npm package ignoring rules async > must match snapshot 1`] = ` -Array [ - "deps/foo/config/config.gypi", - "elf.js", - "package.json", -] -` - -exports[`test/star-names.js TAP follows npm package ignoring rules sync > must match snapshot 1`] = ` -Array [ - "deps/foo/config/config.gypi", - "elf.js", - "package.json", -] -` diff --git a/test/star-names.js b/test/star-names.js new file mode 100644 index 0000000..26270f1 --- /dev/null +++ b/test/star-names.js @@ -0,0 +1,122 @@ +'use strict' +const fs = require('fs') + +const readdir = fs.readdir +fs.readdir = (path, cb) => { + readdir(path, (er, entries) => { + if (er) + cb(er) + else + cb(null, entries.concat('made*of*stars')) + }) +} + +const readdirSync = fs.readdirSync +fs.readdirSync = path => readdirSync(path).concat('made*of*stars') + +const path = require('path') + +const mkdirp = require('mkdirp') +const rimraf = require('rimraf') +const t = require('tap') + +const pack = require('../') + +const pkg = path.join(__dirname, path.basename(__filename, '.js')) +t.teardown(_ => rimraf.sync(pkg)) + +const elfJS = ` +module.exports = elf => + console.log("i'm a elf") +` + +const json = { + 'name': 'test-package', + 'version': '3.1.4', + 'main': 'elf.js' +} + +const expect = [ + 'deps/foo/config/config.gypi', + 'elf.js', + 'package.json', +] + +t.test('setup', t => { + rimraf.sync(pkg) + mkdirp.sync(pkg) + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(json, null, 2) + ) + + fs.writeFileSync( + path.join(pkg, 'elf.js'), + elfJS + ) + + fs.writeFileSync( + path.join(pkg, '.npmrc'), + 'packaged=false' + ) + + fs.writeFileSync( + path.join(pkg, '.npmignore'), + '.npmignore\ndummy\npackage.json' + ) + + fs.writeFileSync( + path.join(pkg, 'dummy'), + 'foo' + ) + + // empty dir should be ignored + mkdirp.sync(pkg + '/this/dir/is/empty/and/ignored') + + const buildDir = path.join(pkg, 'build') + mkdirp.sync(buildDir) + fs.writeFileSync( + path.join(buildDir, 'config.gypi'), + "i_wont_be_included='with any luck'" + ) + + const depscfg = path.join(pkg, 'deps/foo/config') + mkdirp.sync(depscfg) + fs.writeFileSync( + path.join(depscfg, 'config.gypi'), + "i_will_be_included='with any luck'" + ) + + fs.writeFileSync( + path.join(buildDir, 'npm-debug.log'), + '0 lol\n' + ) + + const gitDir = path.join(pkg, '.git') + mkdirp.sync(gitDir) + fs.writeFileSync( + path.join(gitDir, 'gitstub'), + "won't fool git, also won't be included" + ) + + const historyDir = path.join(pkg, 'node_modules/history') + mkdirp.sync(historyDir) + fs.writeFileSync( + path.join(historyDir, 'README.md'), + "please don't include me" + ) + + t.end() +}) + +t.test('follows npm package ignoring rules', function (t) { + const check = (files, t) => { + t.same(files, expect) + t.end() + } + + t.test('sync', t => check(pack.sync({ path: pkg }), t)) + t.test('async', t => pack({ path: pkg }).then(files => check(files, t))) + + t.end() +})