@atomist/sdm
Version:
Atomist Software Delivery Machine SDK
81 lines (72 loc) • 2.86 kB
text/typescript
/*
* 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.
*/
import { logger } from "@atomist/automation-client/lib/util/logger";
import { PushListenerInvocation } from "../../listener/PushListener";
import {
GoalSettingCompositionStyle,
GoalSettingStructure,
} from "../GoalSetter";
import { PushMapping } from "../PushMapping";
/**
* Use to execute a rule set for any push to resolve to an object.
* The value from the first matching rule will be used.
*/
export class PushRules<V> implements PushMapping<V>, GoalSettingStructure<PushListenerInvocation, V> {
public choices: Array<PushMapping<V>> = [];
get structure(): { components: Array<PushMapping<V>>, compositionStyle: GoalSettingCompositionStyle } {
return {
components: this.rules,
compositionStyle: GoalSettingCompositionStyle.FirstMatch,
};
}
/**
* Return all possible values
* @param {string} name
* @param {Array<PushMapping<V>>} rules Array of rules.
* Passing an empty array will result in an instance that always maps to undefined,
* and is not an error.
*/
constructor(public readonly name: string, private readonly rules: Array<PushMapping<V>> = []) {
if (!name) {
throw new Error("PushRule name must be specified");
}
this.add(rules);
}
/**
* Return a PushRules with a subset of the rules of this one
* @param {(p: PushMapping<V>) => boolean} predicate
* @return {PushRules<V>}
*/
public filter(predicate: (p: PushMapping<V>) => boolean): PushRules<V> {
return new PushRules("name-", this.choices.filter(predicate));
}
public add(rules: Array<PushMapping<V>>): void {
this.choices = this.choices.concat(rules);
}
public async mapping(pi: PushListenerInvocation): Promise<V> {
for (const pc of this.choices) {
const found = await pc.mapping(pi);
logger.debug("Eligible PushRule named %s returned choice %j", pc.name, found);
if (found) {
logger.debug("PushRules '%s': Value for push on %j is %j", this.name, pi.id, found);
return found;
} else if (found === null) {
return undefined;
}
}
return undefined;
}
}