@atomist/sdm
Version:
Atomist Software Delivery Machine SDK
114 lines • 4.18 kB
JavaScript
;
/*
* Copyright © 2019 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.any = exports.all = exports.whenNot = void 0;
const logger_1 = require("@atomist/automation-client/lib/util/logger");
const PredicateMapping_1 = require("../PredicateMapping");
const defaultPredicateMappingCostAnalyzer_1 = require("./defaultPredicateMappingCostAnalyzer");
const PredicateMappingCostAnalyzer_1 = require("./PredicateMappingCostAnalyzer");
/**
* Return the opposite of this predicate mapping
*/
function whenNot(t) {
return {
name: `not (${t.name})`,
mapping: async (pi) => !(await t.mapping(pi)),
structure: {
components: [t],
compositionStyle: PredicateMapping_1.PredicateMappingCompositionStyle.Not,
},
};
}
exports.whenNot = whenNot;
/**
* Wrap all these predicates in a single predicate
* AND: Return true if all are satisfied
* @param {PredicateMapping} predicates
* @param analyzer analyzer to use for performance optimization
* @return {PredicateMapping}
*/
function all(predicates, analyzer = defaultPredicateMappingCostAnalyzer_1.DefaultPredicateMappingCostAnalyzer) {
return {
name: predicates.map(g => g.name).join(" && "),
mapping: async (pci) => optimizedAndEvaluation(predicates, analyzer)(pci),
structure: {
components: predicates,
compositionStyle: PredicateMapping_1.PredicateMappingCompositionStyle.And,
},
};
}
exports.all = all;
/**
* Wrap all these predicates in a single predicate
* OR: Return true if any is satisfied
* @param {PredicateMapping} predicates
* @param analyzer analyzer to use for performance optimization
* @return {PredicateMapping}
*/
function any(predicates, analyzer = defaultPredicateMappingCostAnalyzer_1.DefaultPredicateMappingCostAnalyzer) {
return {
name: predicates.map(g => g.name).join(" || "),
mapping: async (pci) => {
// Cannot short-circuit this
const allResults = await gatherResults(predicates)(pci);
return allResults.includes(true);
},
structure: {
components: predicates,
compositionStyle: PredicateMapping_1.PredicateMappingCompositionStyle.Or,
},
};
}
exports.any = any;
/**
* Evaluate predicates for an AND, running non-expensive ones first
* @param {Array<PredicateMapping<F>>} predicates
* @param {PredicateMappingCostAnalyzer<F>} analyzer
* @return {(f: F) => Promise<boolean>}
*/
function optimizedAndEvaluation(predicates, analyzer) {
const cheap = [];
const remaining = [];
for (const p of predicates) {
const cost = analyzer(p);
if (cost !== PredicateMappingCostAnalyzer_1.ExpectedPredicateMappingCost.expensive) {
cheap.push(p);
}
else {
remaining.push(p);
}
}
logger_1.logger.debug("Cheap: [%j], remaining: [%j]", cheap, remaining);
return async (pci) => {
const cheapResults = await gatherResults(cheap)(pci);
if (cheapResults.includes(false)) {
return false;
}
const remainingResults = await gatherResults(remaining)(pci);
return !remainingResults.includes(false);
};
}
function gatherResults(predicates) {
return pci => {
return Promise.all(predicates.map(async (pt) => {
const result = await pt.mapping(pci);
logger_1.logger.debug(`Result of PushTest '${pt.name}' was ${result}`);
return result;
}));
};
}
//# sourceMappingURL=predicateUtils.js.map