@bluealba/carryall
Advanced tools
Comparing version 1.0.4 to 1.0.5
16
index.js
@@ -6,4 +6,18 @@ #!/usr/bin/env node | ||
const fs = require("fs"); | ||
const program = require("commander"); | ||
const ownVersion = require("./package.json"); | ||
const config = JSON.parse(fs.readFileSync("./carryall.json", { "encoding": "UTF-8" })); | ||
program | ||
.version(ownVersion.version) | ||
.option("-c", "--config <path>", "Change the configuration file. Defaults to carryall.json") | ||
.option("-s, --silent", "Silent mode, will not prompt for any action") | ||
.option("-R, --no-restart", "Do not perform a service restart") | ||
.parse(process.argv); | ||
const config = JSON.parse(fs.readFileSync(program.config || "./carryall.json", { "encoding": "UTF-8" })); | ||
config.control = { | ||
silent: program.silent, | ||
noRestart: !program.restart, | ||
} | ||
new Carryall().deploy(config) |
@@ -5,11 +5,12 @@ "use strict"; | ||
const { defaultReporter } = require("./Reporter"); | ||
const { interactiveConsole } = require("./Control"); | ||
const { interactive } = require("./Control"); | ||
const { git } = require("./Descriptor"); | ||
const installPackages = require("./installPackages"); | ||
const restartServices = require("./restartServices"); | ||
class Carryall { | ||
constructor({ reporterFactory = defaultReporter, control = interactiveConsole, descriptorFactory = git } = {}) { | ||
constructor({ reporterFactory = defaultReporter, controlFactory = interactive, descriptorFactory = git } = {}) { | ||
this.reporterFactory = reporterFactory; | ||
this.control = control; | ||
this.controlFactory = controlFactory; | ||
this.descriptorFactory = descriptorFactory; | ||
@@ -21,6 +22,7 @@ | ||
* deploy(config) { | ||
const control = this.controlFactory(config); | ||
const reporter = this.reporterFactory(config); | ||
reporter.greet(); | ||
// Calculate required actions | ||
const descriptor = yield this.descriptorFactory(config); | ||
@@ -30,7 +32,8 @@ const necessaryUpgrades = yield descriptor.requiredActions(); | ||
// Confirm and proceeed | ||
if (! necessaryUpgrades.length) return; //noop | ||
const proceed = yield this.control.confirmInstall(); | ||
const proceed = yield control.confirmInstall(); | ||
if (! proceed) return; | ||
// Install upgrades | ||
reporter.reportInstallStart(); | ||
@@ -40,5 +43,13 @@ yield installPackages(necessaryUpgrades); | ||
// Reports new state | ||
const newState = yield descriptor.inspectEnvironment(); | ||
const pendingActions = yield descriptor.requiredActions(); //should be empty | ||
reporter.reportActionsDone(newState, necessaryUpgrades, pendingActions); | ||
// Restart PM2s | ||
const necessaryRestarts = descriptor.requiredRestarts(necessaryUpgrades); | ||
const proceedRestart = yield control.confirmRestart(necessaryRestarts); | ||
if (! proceedRestart) return; | ||
yield restartServices(necessaryRestarts); | ||
} | ||
@@ -45,0 +56,0 @@ } |
@@ -8,6 +8,16 @@ "use strict"; | ||
confirmInstall() {} | ||
confirmRestart(services) {} | ||
} | ||
class InteractiveConsole extends Control { | ||
constructor(config) { | ||
super(); | ||
this.config = config; | ||
} | ||
confirm(message) { | ||
if (this.config.control.silent) { | ||
return Promise.resolve(true); | ||
} | ||
return inquirer | ||
@@ -18,2 +28,9 @@ .prompt([{ name: "prompt", type: "confirm", default: false, message }]) | ||
confirmRestart(services) { | ||
if (this.config.control.noRestart) { | ||
return Promise.resolve(false); | ||
} | ||
return this.confirm(`Restart PM2 for ${services.length} services?`) | ||
} | ||
confirmInstall() { | ||
@@ -25,4 +42,3 @@ return this.confirm("Proceed?") | ||
module.exports = { | ||
Control, | ||
interactiveConsole: new InteractiveConsole(), | ||
interactive: config => new InteractiveConsole(config), | ||
} |
@@ -7,3 +7,3 @@ "use strict"; | ||
const inspectEnvironment = require("./util/inspectEnvironment"); | ||
const { keys } = require("ramda"); | ||
const { keys, prop } = require("ramda"); | ||
const git = require("./util/git-wrapper"); | ||
@@ -45,2 +45,9 @@ | ||
/** | ||
* Which ones of the following aftifacts are PM2 based? | ||
*/ | ||
requiredRestarts(upgradedServices) { | ||
return upgradedServices.map(prop("artifact")).filter(artifact => fs.existsSync(`${artifact}.pm2.json`)); | ||
} | ||
inspectEnvironment() { | ||
@@ -52,4 +59,2 @@ return inspectEnvironment(this.artifacts); | ||
module.exports = { | ||
Descriptor: Descriptor, | ||
git: co.wrap(function* (config) { | ||
@@ -56,0 +61,0 @@ const target = path.join(config.workdir, "" + Date.now()); |
@@ -5,3 +5,2 @@ "use strict"; | ||
const emoji = require("node-emoji"); | ||
const own = require("../package.json"); | ||
const ora = require("ora"); | ||
@@ -18,3 +17,3 @@ const Slack = require("slack"); | ||
greet() { | ||
this.print(`${this.format.bold("Carryall")} ${emoji.get("truck")} - version ${own.version}`); | ||
this.print(`${this.format.bold("Carryall")} ${emoji.get("truck")}`); | ||
} | ||
@@ -44,7 +43,15 @@ | ||
reportActionsDone(currentEnvironment, actionsDone, actionsNeeded) { | ||
this.print(`Deploy finished on ${this.format.bold(this.environment)}. New state:`) | ||
this.print(`Deploy finished on ${this.format.bold(this.environment)}. ${this.onlyUpgrades ? "Actions" : "Current state"}:`) | ||
toPairs(currentEnvironment).forEach(([artifact, current]) => { | ||
const actionDone = actionsDone.find(propEq("artifact", artifact)) | ||
const actionPending = actionsNeeded.find(propEq("artifact", artifact)) | ||
this.printPackageState({ artifact, current, pending: !!actionPending, updated: !!actionDone}) | ||
if (!this.onlyUpgrades || actionPending || actionDone) { | ||
this.printPackageState({ | ||
artifact, | ||
before: actionDone && actionDone.current, | ||
current, | ||
pending: !!actionPending, | ||
updated: !!actionDone | ||
}) | ||
} | ||
}); | ||
@@ -58,7 +65,8 @@ this.print() | ||
printPackageState({artifact, current, pending, updated}) { | ||
const pack = `${emoji.get("package")} ${this.format.bold(artifact)}: ${current || "missing"}` | ||
printPackageState({artifact, before, current, pending, updated}) { | ||
const action = updated ? `${before || "missing"} -> ${current || "missing"}` : `${current || "missing"}`; | ||
const pack = `${emoji.get("package")} ${this.format.bold(artifact)}`; | ||
const updatedFlag = updated ? this.format.green(" (updated)") : ""; | ||
const errorFlag = pending ? this.format.red(" (different version requested!)") : ""; | ||
this.print(`${pack}${updatedFlag}${errorFlag}`); | ||
this.print(`${pack}: ${action}${updatedFlag}${errorFlag}`); | ||
} | ||
@@ -95,2 +103,3 @@ } | ||
this.channel = config.reporter.slack.channel; | ||
this.onlyUpgrades = !!config.reporter.slack.onlyUpgrades; | ||
this.format = { | ||
@@ -114,5 +123,15 @@ bold: x => `*${x}*`, | ||
flush() { | ||
this.slack.chat.postMessage({ channel: "@cf", text: this.buffer, }) | ||
this.slack.chat.postMessage({ | ||
channel: this.channel, | ||
text: this.buffer, | ||
username: `Carryall - ${this.environment}`, | ||
}) | ||
} | ||
reportInstallStart() { | ||
this.clear(); | ||
this.print(`${this.format.bold("Carryall")} ${emoji.get("truck")} - starting deploy`); | ||
this.flush(); | ||
} | ||
reportActionsDone(currentEnvironment, actionsDone, actionsNeeded) { | ||
@@ -143,3 +162,2 @@ this.clear(); | ||
module.exports = { | ||
Reporter, | ||
consoleReporter: config => new ConsoleReporter(config), | ||
@@ -146,0 +164,0 @@ slackReporter: config => new SlackReporter(config), |
{ | ||
"name": "@bluealba/carryall", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"description": "An easy way to keep your environments in sync", | ||
@@ -22,2 +22,3 @@ "main": "index.js", | ||
"co": "^4.6.0", | ||
"commander": "^2.19.0", | ||
"inquirer": "^6.2.0", | ||
@@ -24,0 +25,0 @@ "node-emoji": "^1.8.1", |
Sorry, the diff of this file is not supported yet
255730
21
432
11
3
+ Addedcommander@^2.19.0
+ Addedcommander@2.20.3(transitive)