Merge branch 'full-npm-dep-ignore' of https://github.com/SrTobi/vscode-vsce into SrTobi-full-npm-dep-ignore

This commit is contained in:
Joao Moreno 2016-01-28 17:03:53 +01:00
commit e5f21a782d
6 changed files with 57 additions and 10 deletions

44
src/npmdeps.ts Normal file
View file

@ -0,0 +1,44 @@
import * as pth from 'path';
import * as _glob from 'glob';
import * as denodeify from 'denodeify';
import * as child_process from 'child_process';
const glob = denodeify<string, _glob.IOptions, string[]>(_glob);
function flatten<T>(arr: T[][]): T[] {
return [].concat.apply([], arr) as T[];
}
function globFiles(cwd: string, moduleDirs: string[]): Promise<string[]> {
return Promise.all(moduleDirs.map(dir => glob('**', { cwd: dir, nodir: true, dot: true, ignore: "node_modules/**" })
.then(filepaths => {
return filepaths.map(filepath => pth.relative(cwd, pth.join(dir, filepath)))
.map(filepath => filepath.replace(/\\/g, '/'))
})))
.then(moduleFiles => flatten(moduleFiles));
}
function npmProdDeps(cwd: string): Promise<string[]> {
return new Promise<string[]>((resolve, reject) => {
child_process.exec("npm list --production --parseable --depth", {cwd: cwd},
(error, stdout, stderr) => {
if (error) {
reject(error);
}
let moduleDirs = stdout.toString()
.split("\n")
.filter(dir => pth.isAbsolute(dir));
resolve(moduleDirs);
}
)
});
}
export function getDependencyFiles(cwd: string): Promise<string[]> {
return npmProdDeps(cwd)
.then(ps => globFiles(cwd, ps));
}

View file

@ -11,6 +11,7 @@ import * as denodeify from 'denodeify';
import * as mime from 'mime';
import * as urljoin from 'url-join';
import { validatePublisher, validateExtensionName, validateVersion } from './validation';
import {getDependencyFiles} from './npmdeps';
interface IReadFile {
(filePath: string): Promise<Buffer>;
@ -304,17 +305,12 @@ const defaultIgnore = [
'**/*.vsixmanifest'
];
function devDependenciesIgnore(manifest: Manifest): string[] {
const devDependencies = Object.keys(manifest.devDependencies || {});
return devDependencies.map(d => `node_modules/${ d }/**`);
}
function collectFiles(cwd: string, manifest: Manifest): Promise<string[]> {
return glob('**', { cwd, nodir: true, dot: true }).then(files => {
return getDependencyFiles(cwd)
.then(files => {
return readFile(path.join(cwd, '.vscodeignore'), 'utf8')
.catch<string>(err => err.code !== 'ENOENT' ? Promise.reject(err) : Promise.resolve(''))
.then(rawIgnore => rawIgnore.split(/[\n\r]/).map(s => s.trim()).filter(s => !!s))
.then(ignore => devDependenciesIgnore(manifest).concat(ignore))
.then(ignore => defaultIgnore.concat(ignore))
.then(ignore => ignore.filter(i => !/^\s*#/.test(i)))
.then<{ ignore: string[]; negate: string[]; }>(ignore => <any> _.indexBy(_.partition(ignore, i => !/^\s*!/.test(i)), (o, i) => i ? 'negate' : 'ignore'))

View file

@ -0,0 +1,4 @@
{
"name": "fake",
"version": "1.0.0"
}

View file

@ -0,0 +1,4 @@
{
"name": "real",
"version": "1.0.0"
}

View file

@ -1,5 +1,5 @@
{
"name": "uuid",
"name": "root-test-package",
"publisher": "joaomoreno",
"version": "1.0.0",
"engines": { "vscode": "*" },

View file

@ -58,11 +58,10 @@ describe('collect', () => {
it('should ignore devDependencies', () => {
const cwd = fixture('devDependencies');
return readManifest(cwd)
.then(manifest => collect(manifest, { cwd }))
.then(files => {
assert.equal(files.length, 4);
assert.equal(files.length, 5);
assert.ok(files.some(f => /real\/dependency\.js/.test(f.path)));
assert.ok(!files.some(f => /fake\/dependency\.js/.test(f.path)));
});