diff --git a/lib/fetcher.js b/lib/fetcher.js index a0a1447a..c4e5852d 100644 --- a/lib/fetcher.js +++ b/lib/fetcher.js @@ -47,6 +47,8 @@ class FetcherBase { throw new TypeError('options object is required') this.spec = npa(spec, opts.where) + this.allowGitIgnore = !!opts.allowGitIgnore + // a bit redundant because presumably the caller already knows this, // but it makes it easier to not have to keep track of the requested // spec when we're dispatching thousands of these at once, and normalizing @@ -414,7 +416,7 @@ class FetcherBase { const base = basename(entry.path) if (base === '.npmignore') sawIgnores.add(entry.path) - else if (base === '.gitignore') { + else if (base === '.gitignore' && !this.allowGitIgnore) { // rename, but only if there's not already a .npmignore const ni = entry.path.replace(/\.gitignore$/, '.npmignore') if (sawIgnores.has(ni)) diff --git a/lib/git.js b/lib/git.js index 81f7ca25..b9665b5f 100644 --- a/lib/git.js +++ b/lib/git.js @@ -207,6 +207,7 @@ class GitFetcher extends Fetcher { const nameat = this.spec.name ? `${this.spec.name}@` : '' return new RemoteFetcher(h.tarball({ noCommittish: false }), { ...this.opts, + allowGitIgnore: true, pkgid: `git:${nameat}${this.resolved}`, resolved: this.resolved, integrity: null, // it'll always be different, if we have one diff --git a/test/fixtures/prepare-requires-gitignore-1.2.3.tgz b/test/fixtures/prepare-requires-gitignore-1.2.3.tgz new file mode 100644 index 00000000..c1f5be9a Binary files /dev/null and b/test/fixtures/prepare-requires-gitignore-1.2.3.tgz differ diff --git a/test/fixtures/prepare-requires-gitignore/.gitignore b/test/fixtures/prepare-requires-gitignore/.gitignore new file mode 100644 index 00000000..967a6410 --- /dev/null +++ b/test/fixtures/prepare-requires-gitignore/.gitignore @@ -0,0 +1 @@ +# just a file you can ignore diff --git a/test/fixtures/prepare-requires-gitignore/index.js b/test/fixtures/prepare-requires-gitignore/index.js new file mode 100644 index 00000000..33037e4e --- /dev/null +++ b/test/fixtures/prepare-requires-gitignore/index.js @@ -0,0 +1 @@ +console.log('this is fine') diff --git a/test/fixtures/prepare-requires-gitignore/package.json b/test/fixtures/prepare-requires-gitignore/package.json new file mode 100644 index 00000000..71043972 --- /dev/null +++ b/test/fixtures/prepare-requires-gitignore/package.json @@ -0,0 +1,11 @@ +{ + "name": "prepare-requires-gitignore", + "version": "1.2.3", + "files": [ + "index.js", + "prepare_ran_successfully" + ], + "scripts": { + "prepare": "node prepare.js" + } +} diff --git a/test/fixtures/prepare-requires-gitignore/prepare.js b/test/fixtures/prepare-requires-gitignore/prepare.js new file mode 100644 index 00000000..e4fa26d1 --- /dev/null +++ b/test/fixtures/prepare-requires-gitignore/prepare.js @@ -0,0 +1,4 @@ +const { statSync, writeFileSync } = require('fs') +statSync(`${__dirname}/.gitignore`) +writeFileSync(`${__dirname}/prepare_ran_successfully`, 'hello') +console.log('this is fine') diff --git a/test/git.js b/test/git.js index 00e6b53b..cde1fc28 100644 --- a/test/git.js +++ b/test/git.js @@ -45,7 +45,9 @@ const http = require('http') const {resolve} = require('path') const rimraf = require('rimraf') -const abbrev = resolve(__dirname, 'fixtures/abbrev-1.1.1.tgz') +const fixtures = resolve(__dirname, 'fixtures') +const abbrev = resolve(fixtures, 'abbrev-1.1.1.tgz') +const prepIgnore = resolve(fixtures, 'prepare-requires-gitignore-1.2.3.tgz') const npa = require('npm-package-arg') t.saveFixture = true @@ -250,6 +252,13 @@ t.test('setup', { bail: true }, t => { case '/not-tar.tgz': res.statusCode = 200 return res.end('this is not a gzipped tarball tho') + case '/prepare-requires-gitignore-1.2.3.tgz': try { + const data = fs.readFileSync(prepIgnore) + return res.end(data) + } catch (er) { + res.statusCode = 500 + return res.end(er.stack) + } default: res.statusCode = 404 return res.end('not found') @@ -389,6 +398,20 @@ t.test('extract from tarball from hosted git service', t => { })) }) +t.test('include .gitignore in hosted tarballs for preparation', async t => { + const spec = npa(`localhost:foo/y#${REPO_HEAD}`) + spec.hosted.tarball = () => + `http://localhost:${httpPort}/prepare-requires-gitignore-1.2.3.tgz` + const g = new GitFetcher(spec, {cache}) + const dir = t.testdir() + await g.extract(dir) + t.strictSame(fs.readdirSync(dir).sort((a,b) => a.localeCompare(b)), [ + 'index.js', + 'package.json', + 'prepare_ran_successfully', + ]) +}) + t.test('add git sha to hosted git shorthand', t => new GitFetcher('localhost:repo/x', {cache}) // it adds the git+ because it thinks it's https