UNPKG

@atomist/sdm-core

Version:

Atomist Software Delivery Machine - Implementation

245 lines 10.5 kB
"use strict"; /* * 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