@atomist/sdm
Version:
Atomist Software Delivery Machine SDK
93 lines • 3.23 kB
JavaScript
;
/*
* Copyright © 2020 Atomist, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.filteredView = void 0;
const stream = require("stream");
/**
* Create a filtered view of the given project.
* Changes to the filtered view will affect the source project.
* @param {LocalProject} p
* @param filter function to filter file paths. Return true to eliminate a file
* @return {Promise<LocalProject>}
*/
function filteredView(p, filter) {
// Use an ES6 proxy to bring back memories of Spring AOP
const handler = {
get: (target, prop) => {
const decorator = new FilteredProject(target, filter);
if (prop.endsWith("Sync")) {
throw new Error("Don't use sync methods: had " + prop);
}
const origMethod = target[prop];
if (typeof origMethod !== "function") {
return origMethod;
}
const decoratedMethod = decorator[prop];
return function (...args) {
return !!decoratedMethod ?
decoratedMethod.apply(decorator, args) :
origMethod.apply(this, args);
};
},
};
return new Proxy(p, handler);
}
exports.filteredView = filteredView;
/**
* This relies on the implementation of AbstractProject,
* where overriding streamFilesRaw does most of what we need
*/
class FilteredProject {
constructor(project, filter) {
this.project = project;
this.filter = filter;
}
getFile(path) {
return this.filter(path) ?
this.project.getFile(path) :
undefined;
}
findFile(path) {
if (this.filter(path)) {
return this.project.findFile(path);
}
throw new Error(`No file at ${path}`);
}
async getFiles(globPatterns = []) {
const files = await this.project.getFiles(globPatterns);
return files.filter(f => this.filter(f.path));
}
/**
* This method is used by most of the others, such as totalFileCount
* @param {string[]} globPatterns
* @param {{}} opts
* @return {FileStream}
*/
streamFilesRaw(globPatterns, opts) {
const filter = this.filter;
const onlyIncludedFilters = new stream.Transform({ objectMode: true });
onlyIncludedFilters._transform = function (f, encoding, done) {
if (filter(f.path)) {
this.push(f);
}
done();
};
return this.project.streamFilesRaw(globPatterns, opts)
.pipe(onlyIncludedFilters);
}
}
//# sourceMappingURL=filteredView.js.map