build(brocolli): move filename filtering into DiffingPluginWrapper
Closes #1719
This commit is contained in:
parent
6bba289a3c
commit
aaf3edd131
|
@ -30,6 +30,8 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {
|
|||
private tsServiceHost: ts.LanguageServiceHost;
|
||||
private tsService: ts.LanguageService;
|
||||
|
||||
static includeExtensions = ['.ts'];
|
||||
static excludeExtensions = ['.d.ts'];
|
||||
|
||||
constructor(public inputPath: string, public cachePath: string, public options) {
|
||||
this.tsOpts = Object.create(options);
|
||||
|
@ -46,8 +48,7 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {
|
|||
let pathsToEmit = [];
|
||||
let pathsWithErrors = [];
|
||||
|
||||
treeDiff.changedPaths.filter((changedPath) =>
|
||||
changedPath.match(/\.ts/) && !changedPath.match(/\.d\.ts/))
|
||||
treeDiff.changedPaths
|
||||
.forEach((tsFilePath) => {
|
||||
if (!this.fileRegistry[tsFilePath]) {
|
||||
this.fileRegistry[tsFilePath] = {version: 0};
|
||||
|
@ -59,8 +60,7 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {
|
|||
pathsToEmit.push(tsFilePath);
|
||||
});
|
||||
|
||||
treeDiff.removedPaths.filter((changedPath) =>
|
||||
changedPath.match(/\.ts/) && !changedPath.match(/\.d\.ts/))
|
||||
treeDiff.removedPaths
|
||||
.forEach((tsFilePath) => {
|
||||
console.log('removing outputs for', tsFilePath);
|
||||
|
||||
|
|
|
@ -49,7 +49,6 @@ class DiffingPluginWrapper implements BroccoliTree {
|
|||
cachePath = null;
|
||||
outputPath = null;
|
||||
|
||||
|
||||
constructor(private pluginClass, private wrappedPluginArguments) {
|
||||
if (Array.isArray(wrappedPluginArguments[0])) {
|
||||
this.inputTrees = wrappedPluginArguments[0];
|
||||
|
@ -92,8 +91,10 @@ class DiffingPluginWrapper implements BroccoliTree {
|
|||
|
||||
private init() {
|
||||
if (!this.initialized) {
|
||||
let includeExtensions = this.pluginClass.includeExtensions || [];
|
||||
let excludeExtensions = this.pluginClass.excludeExtensions || [];
|
||||
this.initialized = true;
|
||||
this.treeDiffer = new TreeDiffer(this.inputPath);
|
||||
this.treeDiffer = new TreeDiffer(this.inputPath, includeExtensions, excludeExtensions);
|
||||
this.wrappedPlugin =
|
||||
new this.pluginClass(this.inputPath, this.cachePath, this.wrappedPluginArguments[1]);
|
||||
}
|
||||
|
|
|
@ -13,43 +13,37 @@ let xtend = require('xtend');
|
|||
class DiffingTraceurCompiler implements DiffingBroccoliPlugin {
|
||||
constructor(public inputPath: string, public cachePath: string, public options) {}
|
||||
|
||||
static includeExtensions = ['.js', '.es6', '.cjs'];
|
||||
|
||||
rebuild(treeDiff: DiffResult) {
|
||||
treeDiff.changedPaths.forEach((changedFilePath) => {
|
||||
var extension = path.extname(changedFilePath).toLowerCase();
|
||||
if (extension === '.js' || extension === '.es6' || extension === '.cjs') {
|
||||
var traceurOpts = xtend({filename: changedFilePath}, this.options.traceurOptions);
|
||||
var traceurOpts = xtend({filename: changedFilePath}, this.options.traceurOptions);
|
||||
|
||||
var fsOpts = {encoding: 'utf-8'};
|
||||
var absoluteInputFilePath = path.join(this.inputPath, changedFilePath);
|
||||
var sourcecode = fs.readFileSync(absoluteInputFilePath, fsOpts);
|
||||
var fsOpts = {encoding: 'utf-8'};
|
||||
var absoluteInputFilePath = path.join(this.inputPath, changedFilePath);
|
||||
var sourcecode = fs.readFileSync(absoluteInputFilePath, fsOpts);
|
||||
|
||||
var result = traceur.compile(traceurOpts, changedFilePath, sourcecode);
|
||||
var result = traceur.compile(traceurOpts, changedFilePath, sourcecode);
|
||||
|
||||
// TODO: we should fix the sourceMappingURL written by Traceur instead of overriding
|
||||
// (but we might switch to typescript first)
|
||||
var mapFilepath =
|
||||
changedFilePath.replace(/\.\w+$/, '') + this.options.destSourceMapExtension;
|
||||
result.js = result.js + '\n//# sourceMappingURL=./' + path.basename(mapFilepath);
|
||||
// TODO: we should fix the sourceMappingURL written by Traceur instead of overriding
|
||||
// (but we might switch to typescript first)
|
||||
var mapFilepath = changedFilePath.replace(/\.\w+$/, '') + this.options.destSourceMapExtension;
|
||||
result.js = result.js + '\n//# sourceMappingURL=./' + path.basename(mapFilepath);
|
||||
|
||||
var destFilepath = changedFilePath.replace(/\.\w+$/, this.options.destExtension);
|
||||
var destFile = path.join(this.cachePath, destFilepath);
|
||||
fse.mkdirsSync(path.dirname(destFile));
|
||||
fs.writeFileSync(destFile, result.js, fsOpts);
|
||||
var destFilepath = changedFilePath.replace(/\.\w+$/, this.options.destExtension);
|
||||
var destFile = path.join(this.cachePath, destFilepath);
|
||||
fse.mkdirsSync(path.dirname(destFile));
|
||||
fs.writeFileSync(destFile, result.js, fsOpts);
|
||||
|
||||
var destMap = path.join(this.cachePath, mapFilepath);
|
||||
result.sourceMap.file = destFilepath;
|
||||
fs.writeFileSync(destMap, JSON.stringify(result.sourceMap), fsOpts);
|
||||
}
|
||||
var destMap = path.join(this.cachePath, mapFilepath);
|
||||
result.sourceMap.file = destFilepath;
|
||||
fs.writeFileSync(destMap, JSON.stringify(result.sourceMap), fsOpts);
|
||||
});
|
||||
|
||||
treeDiff.removedPaths.forEach((removedFilePath) => {
|
||||
var extension = path.extname(removedFilePath).toLowerCase();
|
||||
if (extension === '.js' || extension === '.es6' || extension === '.cjs') {
|
||||
var destFilepath = removedFilePath.replace(/\.\w+$/, this.options.destExtension);
|
||||
var absoluteOuputFilePath = path.join(this.cachePath, destFilepath);
|
||||
fs.unlinkSync(absoluteOuputFilePath);
|
||||
}
|
||||
var destFilepath = removedFilePath.replace(/\.\w+$/, this.options.destExtension);
|
||||
var absoluteOuputFilePath = path.join(this.cachePath, destFilepath);
|
||||
fs.unlinkSync(absoluteOuputFilePath);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,6 +102,95 @@ describe('TreeDiffer', () => {
|
|||
diffResult = differ.diffTree();
|
||||
expect(diffResult.changedPaths).toEqual(['file-1.txt']);
|
||||
});
|
||||
|
||||
|
||||
it('should ignore files with extensions not listed in includeExtensions', () => {
|
||||
let testDir = {
|
||||
'dir1': {
|
||||
'file-1.js': mockfs.file({content: 'file-1.js content', mtime: new Date(1000)}),
|
||||
'file-2.md': mockfs.file({content: 'file-2.md content', mtime: new Date(1000)}),
|
||||
'file-3.coffee': mockfs.file({content: 'file-3.coffee content', mtime: new Date(1000)}),
|
||||
'subdir-1': {
|
||||
'file-1.1.cc': mockfs.file({content: 'file-1.1.cc content', mtime: new Date(1000)})
|
||||
}
|
||||
}
|
||||
};
|
||||
mockfs(testDir);
|
||||
|
||||
let differ = new TreeDiffer('dir1', ['.js', '.coffee']);
|
||||
|
||||
let diffResult = differ.diffTree();
|
||||
|
||||
expect(diffResult.changedPaths).toEqual(['file-1.js', 'file-3.coffee']);
|
||||
|
||||
// change two files
|
||||
testDir['dir1']['file-1.js'] = mockfs.file({content: 'new content', mtime: new Date(1000)});
|
||||
testDir['dir1']['file-3.coffee'] =
|
||||
mockfs.file({content: 'new content', mtime: new Date(1000)});
|
||||
testDir['dir1']['subdir-1']['file-1.1.cc'] =
|
||||
mockfs.file({content: 'file-1.1.cc content', mtime: new Date(9999)});
|
||||
mockfs(testDir);
|
||||
|
||||
diffResult = differ.diffTree();
|
||||
|
||||
expect(diffResult.changedPaths).toEqual(['file-1.js', 'file-3.coffee']);
|
||||
|
||||
expect(diffResult.removedPaths).toEqual([]);
|
||||
|
||||
// change one file
|
||||
testDir['dir1']['file-1.js'] = mockfs.file({content: 'super new', mtime: new Date(1000)});
|
||||
mockfs(testDir);
|
||||
|
||||
diffResult = differ.diffTree();
|
||||
expect(diffResult.changedPaths).toEqual(['file-1.js']);
|
||||
});
|
||||
|
||||
|
||||
it('should ignore files with extensions listed in excludeExtensions', () => {
|
||||
let testDir = {
|
||||
'dir1': {
|
||||
'file-1.ts': mockfs.file({content: 'file-1.ts content', mtime: new Date(1000)}),
|
||||
'file-1.cs': mockfs.file({content: 'file-1.cs content', mtime: new Date(1000)}),
|
||||
'file-1.d.cs': mockfs.file({content: 'file-1.d.cs content', mtime: new Date(1000)}),
|
||||
'file-2.md': mockfs.file({content: 'file-2.md content', mtime: new Date(1000)}),
|
||||
'file-3.ts': mockfs.file({content: 'file-3.ts content', mtime: new Date(1000)}),
|
||||
'file-4.d.ts': mockfs.file({content: 'file-4.d.ts content', mtime: new Date(1000)}),
|
||||
'subdir-1': {
|
||||
'file-1.1.cc': mockfs.file({content: 'file-1.1.cc content', mtime: new Date(1000)})
|
||||
}
|
||||
}
|
||||
};
|
||||
mockfs(testDir);
|
||||
|
||||
let differ = new TreeDiffer('dir1', ['.ts', '.cs'], ['.d.ts', '.d.cs']);
|
||||
|
||||
let diffResult = differ.diffTree();
|
||||
|
||||
expect(diffResult.changedPaths).toEqual(['file-1.cs', 'file-1.ts', 'file-3.ts']);
|
||||
|
||||
// change two files
|
||||
testDir['dir1']['file-1.ts'] = mockfs.file({content: 'new content', mtime: new Date(1000)});
|
||||
testDir['dir1']['file-1.cs'] = mockfs.file({content: 'new content', mtime: new Date(1000)});
|
||||
testDir['dir1']['file-1.d.cs'] = mockfs.file({content: 'new content', mtime: new Date(1000)});
|
||||
testDir['dir1']['file-3.ts'] = mockfs.file({content: 'new content', mtime: new Date(1000)});
|
||||
testDir['dir1']['file-4.d.ts'] = mockfs.file({content: 'new content', mtime: new Date(1000)});
|
||||
testDir['dir1']['subdir-1']['file-1.1.cc'] =
|
||||
mockfs.file({content: 'file-1.1.cc content', mtime: new Date(9999)});
|
||||
mockfs(testDir);
|
||||
|
||||
diffResult = differ.diffTree();
|
||||
|
||||
expect(diffResult.changedPaths).toEqual(['file-1.cs', 'file-1.ts', 'file-3.ts']);
|
||||
|
||||
expect(diffResult.removedPaths).toEqual([]);
|
||||
|
||||
// change one file
|
||||
testDir['dir1']['file-4.d.ts'] = mockfs.file({content: 'super new', mtime: new Date(1000)});
|
||||
mockfs(testDir);
|
||||
|
||||
diffResult = differ.diffTree();
|
||||
expect(diffResult.changedPaths).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('diff of new files', () => {
|
||||
|
|
|
@ -8,8 +8,24 @@ export class TreeDiffer {
|
|||
private fingerprints: {[key: string]: string} = Object.create(null);
|
||||
private nextFingerprints: {[key: string]: string} = Object.create(null);
|
||||
private rootDirName: string;
|
||||
private include: RegExp = null;
|
||||
private exclude: RegExp = null;
|
||||
|
||||
constructor(private rootPath: string) { this.rootDirName = path.basename(rootPath); }
|
||||
constructor(private rootPath: string, includeExtensions?: string[],
|
||||
excludeExtensions?: string[]) {
|
||||
this.rootDirName = path.basename(rootPath);
|
||||
|
||||
let buildRegexp = (arr) => new RegExp(`(${arr.reduce(combine, "")})$`, "i");
|
||||
|
||||
this.include = (includeExtensions || []).length ? buildRegexp(includeExtensions) : null;
|
||||
this.exclude = (excludeExtensions || []).length ? buildRegexp(excludeExtensions) : null;
|
||||
|
||||
function combine(prev, curr) {
|
||||
if (curr.charAt(0) !== ".") throw new TypeError("Extension must begin with '.'");
|
||||
curr = '(' + curr + ')';
|
||||
return prev ? (prev + '|' + curr) : curr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public diffTree(): DiffResult {
|
||||
|
@ -30,9 +46,12 @@ export class TreeDiffer {
|
|||
result.directoriesChecked++;
|
||||
this.dirtyCheckPath(absolutePath, result);
|
||||
} else {
|
||||
result.filesChecked++;
|
||||
if (this.isFileDirty(absolutePath, pathStat)) {
|
||||
result.changedPaths.push(path.relative(this.rootPath, absolutePath));
|
||||
if (!(this.include && !absolutePath.match(this.include)) &&
|
||||
!(this.exclude && absolutePath.match(this.exclude))) {
|
||||
result.filesChecked++;
|
||||
if (this.isFileDirty(absolutePath, pathStat)) {
|
||||
result.changedPaths.push(path.relative(this.rootPath, absolutePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -62,9 +81,12 @@ export class TreeDiffer {
|
|||
|
||||
private detectDeletionsAndUpdateFingerprints(result: DiffResult) {
|
||||
for (let absolutePath in this.fingerprints) {
|
||||
if (this.fingerprints[absolutePath] !== null) {
|
||||
let relativePath = path.relative(this.rootPath, absolutePath);
|
||||
result.removedPaths.push(relativePath);
|
||||
if (!(this.include && !absolutePath.match(this.include)) &&
|
||||
!(this.exclude && absolutePath.match(this.exclude))) {
|
||||
if (this.fingerprints[absolutePath] !== null) {
|
||||
let relativePath = path.relative(this.rootPath, absolutePath);
|
||||
result.removedPaths.push(relativePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,8 +115,7 @@ class DirtyCheckingDiffResult {
|
|||
constructor(public name: string) {}
|
||||
|
||||
toString() {
|
||||
return `${pad(this.name, 40)}, ` +
|
||||
`duration: ${pad(this.endTime - this.startTime, 5)}ms, ` +
|
||||
return `${pad(this.name, 40)}, duration: ${pad(this.endTime - this.startTime, 5)}ms, ` +
|
||||
`${pad(this.changedPaths.length + this.removedPaths.length, 5)} changes detected ` +
|
||||
`(files: ${pad(this.filesChecked, 5)}, directories: ${pad(this.directoriesChecked, 4)})`;
|
||||
}
|
||||
|
@ -102,8 +123,9 @@ class DirtyCheckingDiffResult {
|
|||
log(verbose) {
|
||||
let prefixedPaths =
|
||||
this.changedPaths.map((p) => `* ${p}`).concat(this.removedPaths.map((p) => `- ${p}`));
|
||||
console.log(`Tree diff: ${this}` +
|
||||
((verbose && prefixedPaths.length) ? ` [\n ${prefixedPaths.join('\n ')}\n]` : ''));
|
||||
console.log(`Tree diff: ${this}` + ((verbose && prefixedPaths.length) ?
|
||||
` [\n ${prefixedPaths.join('\n ')}\n]` :
|
||||
''));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue