UNPKG

4.37 kBPlain TextView Raw
1#!/usr/bin/env node
2
3/*
4 * Copyright © 2018 Atomist, Inc.
5 *
6 * See LICENSE file.
7 */
8
9// tslint:disable-next-line:no-import-side-effect
10import "source-map-support/register";
11
12import * as appRoot from "app-root-path";
13import * as _ from "lodash";
14import * as path from "path";
15import { printError } from "../lib/util/error";
16
17async function main(): Promise<void> {
18 try {
19 const logging = require("../lib/util/logger");
20 logging.configureLogging(logging.ClientLogging);
21
22 let cfg = await require("../lib/configuration").loadConfiguration();
23 cfg = require("../lib/scan").enableDefaultScanning(cfg);
24 cfg.logging.banner.contributors.push(
25 require("../lib/internal/transport/showStartupMessages").DevModeBannerContributor);
26
27 const automationClient = require("../lib/automationClient").automationClient(cfg);
28 await automationClient.run();
29 const registration = prepareRegistration(cfg);
30
31 const chokidar = require("chokidar");
32 const watcher = chokidar.watch(["index.js", "lib/*.js", "lib/**/*.js"], { ignored: "\.ts" });
33
34 const indexPath = path.join(appRoot.path, "index.js");
35 const libPath = path.join(appRoot.path, "lib");
36 const logger = logging.logger;
37
38 watcher.on("ready", () => {
39 watcher.on("all", async (e, filePath) => {
40 const start = Date.now();
41 logger.warn("Change to '%s' file detected. Attempting reload...", filePath);
42
43 Object.keys(require.cache).forEach(id => {
44 if (id.startsWith(indexPath) || id.startsWith(libPath)) {
45 delete require.cache[id];
46 }
47 });
48
49 try {
50 let newCfg = await require("../lib/configuration").loadConfiguration();
51 newCfg = require("../lib/scan").enableDefaultScanning(newCfg);
52
53 diffRegistration(prepareRegistration(newCfg), registration);
54
55 // Clean out previous handlers and install new ones
56 automationClient.automationServer.commandHandlers = [];
57 newCfg.commands.forEach(command => automationClient.withCommandHandler(command));
58 automationClient.automationServer.eventHandlers = [];
59 newCfg.events.forEach(event => automationClient.withEventHandler(event));
60 // Now drop reference to previous configuration
61 automationClient.configuration = newCfg;
62
63 // Clean out the startup banner listeners
64 if (automationClient.defaultListeners.length > 2) {
65 automationClient.defaultListeners.splice(2);
66 }
67 await automationClient.raiseStartupEvent();
68
69 logger.warn(`Reload successful in ${((Date.now() - start) / 1000).toFixed(2)}s`);
70 } catch (e) {
71 logger.error("Reload failed");
72 printError(e);
73 }
74 });
75 });
76
77 } catch (e) {
78 printError(e);
79 process.exit(5);
80 }
81}
82
83function prepareRegistration(configuration: any): any {
84 const automations = new (require("../lib/server/BuildableAutomationServer").BuildableAutomationServer)(configuration);
85 (configuration.commands || []).forEach(c => automations.registerCommandHandler(c));
86 (configuration.events || []).forEach(e => automations.registerEventHandler(e));
87 (configuration.ingesters || []).forEach(i => automations.registerIngester(i));
88 return require("../lib/internal/transport/websocket/payloads")
89 .prepareRegistration(automations.automations, {}, configuration.metadata);
90}
91
92function diffRegistration(newReg: any, oldReg: any): void {
93 if (!_.isEqual(newReg, oldReg)) {
94 const jsonDiff = require("json-diff");
95 const logging = require("../lib/util/logger");
96 logging.logger.error(
97 `Unable to reload. Incompatible changes to registration metadata detected:
98${jsonDiff.diffString(newReg, oldReg).trim()}`);
99 logging.logger.error("Exiting...");
100 process.exit(15);
101 }
102}
103
104/* tslint:disable:no-console */
105
106main()
107 .catch(e => {
108 console.error(`Unhandled exception: ${e.message}`);
109 process.exit(10);
110 });