@atomist/sdm-core
Version:
Atomist Software Delivery Machine - Implementation
245 lines • 10.5 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.
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const configuration_1 = require("@atomist/automation-client/lib/configuration");
const camelcaseKeys = require("camelcase-keys");
const changeCase = require("change-case");
const fs = require("fs-extra");
const glob = require("glob");
const yaml = require("js-yaml");
const stringify = require("json-stringify-safe");
const _ = require("lodash");
const path = require("path");
const trace = require("stack-trace");
const util = require("util");
const github_1 = require("../../pack/github-goal-status/github");
const goalState_1 = require("../../pack/goal-state/goalState");
const array_1 = require("../../util/misc/array");
const configure_1 = require("../configure");
const mapGoals_1 = require("./mapGoals");
const mapRules_1 = require("./mapRules");
const util_1 = require("./util");
/**
* Load one or more yaml files to create goal sets
*
* When providing more than one yaml file, files are being loaded
* in provided order with later files overwriting earlier ones.
*/
function configureYaml(patterns, options = {}) {
return __awaiter(this, void 0, void 0, function* () {
// Get the caller of this function to determine the cwd for resolving glob patterns
const callerCallSite = trace.get().filter(t => t.getFileName() !== __filename)
.filter(t => !!t.getFileName())[0];
const cwd = options.cwd || path.dirname(callerCallSite.getFileName());
const cfg = yield createConfiguration(cwd, options);
return configure_1.configure((sdm) => __awaiter(this, void 0, void 0, function* () {
yield createExtensions(cwd, cfg, sdm);
return createGoalData(patterns, cwd, options, cfg, sdm);
}), options.options || {});
});
}
exports.configureYaml = configureYaml;
function createConfiguration(cwd, options) {
return __awaiter(this, void 0, void 0, function* () {
const cfg = {};
yield awaitIterable(yield requireConfiguration(cwd), (v) => __awaiter(this, void 0, void 0, function* () {
const c = yield v(cfg);
configuration_1.deepMergeConfigs(cfg, c);
}));
_.update(options, "options.preProcessors", old => !!old ? old : []);
options.options.preProcessors = [
(c) => __awaiter(this, void 0, void 0, function* () { return configuration_1.deepMergeConfigs(c, cfg); }),
...array_1.toArray(options.options.preProcessors),
];
return cfg;
});
}
function createExtensions(cwd, cfg, sdm) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
yield awaitIterable(yield requireCommands(cwd, _.get(cfg, "extensions.commands")), (c, k) => __awaiter(this, void 0, void 0, function* () {
let registration;
try {
const makerResult = yield c(sdm);
registration = { name: k, listener: makerResult };
}
catch (e) {
e.message = `Failed to make command using CommandMaker ${k}: ${e.message}`;
throw e;
}
try {
sdm.addCommand(registration);
}
catch (e) {
e.message = `Failed to add command ${k} '${stringify(registration)}': ${e.message}`;
throw e;
}
}));
yield awaitIterable(yield requireEvents(cwd, _.get(cfg, "extensions.events")), (e, k) => __awaiter(this, void 0, void 0, function* () {
let registration;
try {
const makerResult = yield e(sdm);
registration = Object.assign({ name: k }, makerResult);
}
catch (e) {
e.message = `Failed to make event using EventMaker ${k}: ${e.message}`;
throw e;
}
try {
sdm.addEvent(registration);
}
catch (e) {
e.message = `Failed to add event ${k} '${stringify(registration)}': ${e.message}`;
throw e;
}
}));
yield requireIngesters(cwd, _.get(cfg, "extensions.ingesters"));
sdm.addExtensionPacks(...(((_a = sdm.configuration.sdm) === null || _a === void 0 ? void 0 : _a.extensionPacks) || [
goalState_1.goalStateSupport({
cancellation: {
enabled: true,
},
}),
github_1.githubGoalStatusSupport(),
]));
});
}
// tslint:disable-next-line:cyclomatic-complexity
function createGoalData(patterns, cwd, options, cfg, sdm) {
return __awaiter(this, void 0, void 0, function* () {
const additionalGoals = options.goals ? yield sdm.createGoals(options.goals, options.configurers) : {};
const goalMakers = yield requireGoals(cwd, _.get(cfg, "extensions.goals"));
const testMakers = yield requireTests(cwd, _.get(cfg, "extensions.tests"));
const files = yield resolvePaths(cwd, patterns, true);
const goalData = {};
for (const file of files) {
const configs = yaml.safeLoadAll(yield fs.readFile(path.join(cwd, file), { encoding: "UTF-8" }));
for (const config of configs) {
if (!!config.name) {
sdm.name = config.name;
}
if (!!config.configuration) {
_.merge(sdm.configuration, camelcaseKeys(config.configuration, { deep: true }));
}
if (!!config.item) {
_.merge(sdm.configuration, camelcaseKeys(config.item, { deep: true }));
}
for (const k in config) {
if (config.hasOwnProperty(k)) {
const value = config[k];
// Ignore two special keys used to set up the SDM
if (k === "name" || k === "configuration" || k === "skill") {
continue;
}
// Just create goals and register with SDM
if (k === "goals") {
yield mapGoals_1.mapGoals(sdm, value, additionalGoals, goalMakers, options.tests || {}, testMakers);
}
if (k === "rules") {
yield mapRules_1.mapRules(value, goalData, sdm, options, additionalGoals, goalMakers, testMakers);
}
}
}
}
}
return goalData;
});
}
function requireExtensions(cwd, pattern, cb = () => {
}) {
return __awaiter(this, void 0, void 0, function* () {
const extensions = {};
const files = yield resolvePaths(cwd, pattern);
for (const file of files) {
const testJs = require(`${cwd}/${file}`);
_.forEach(testJs, (v, k) => {
if (!!cb) {
cb(v, k, extensions);
}
extensions[k] = v;
});
}
return extensions;
});
}
function requireTests(cwd, pattern = ["tests/**.js", "lib/tests/**.js"]) {
return __awaiter(this, void 0, void 0, function* () {
return requireExtensions(cwd, pattern, (v, k, e) => e[changeCase.snake(k)] = v);
});
}
function requireGoals(cwd, pattern = ["goals/**.js", "lib/goals/**.js"]) {
return __awaiter(this, void 0, void 0, function* () {
return requireExtensions(cwd, pattern, (v, k, e) => e[changeCase.snake(k)] = v);
});
}
function requireCommands(cwd, pattern = ["commands/**.js", "lib/commands/**.js"]) {
return __awaiter(this, void 0, void 0, function* () {
return requireExtensions(cwd, pattern);
});
}
function requireEvents(cwd, pattern = ["events/**.js", "lib/events/**.js"]) {
return __awaiter(this, void 0, void 0, function* () {
return requireExtensions(cwd, pattern);
});
}
function requireConfiguration(cwd, pattern = ["config.js", "lib/config.js"]) {
return __awaiter(this, void 0, void 0, function* () {
return requireExtensions(cwd, pattern);
});
}
function requireIngesters(cwd, pattern = ["ingesters/**.graphql", "lib/graphql/ingester/**.graphql"]) {
return __awaiter(this, void 0, void 0, function* () {
const ingesters = [];
const files = yield resolvePaths(cwd, pattern);
for (const file of files) {
ingesters.push((yield fs.readFile(file)).toString());
}
return ingesters;
});
}
function awaitIterable(elems, cb) {
return __awaiter(this, void 0, void 0, function* () {
for (const k in elems) {
if (elems.hasOwnProperty(k)) {
const v = elems[k];
yield cb(v, k);
}
}
});
}
function resolvePaths(cwd, patterns, watch = false) {
return __awaiter(this, void 0, void 0, function* () {
const paths = [];
for (const pattern of array_1.toArray(patterns)) {
paths.push(...yield util.promisify(glob)(pattern, { cwd }));
}
if (watch) {
util_1.watchPaths(paths);
}
return paths;
});
}
//# sourceMappingURL=configureYaml.js.map
;