Reputation: 8178
I'm trying to automate a process I go through every time I test my apps and sites on the server. I'm currently running on nodejitsu. When I've tested something and it works on my local machine, the next thing I do is...
jitsu deploy
After I'm done, and my apps ready to go I undo my changes in my package.json file. I'd like to automate this process. I had the idea of doing so with a tiny node.js file. Here it is so far...
/*
* Use this file to deploy an app to the staging server on nodejitsu
*/
var bash = require('child_process').spawn('bash');
var colors = require('colors');
var fs = require('fs');
// stdout setup
bash.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
bash.stdout.on('error', function (err) {
console.log('stdout error: '.red, err);
});
// on bash exit
bash.on('exit', function (code) {
console.log('Exiting... ', code);
});
// grab package.json
var package = '';
fs.readFile('package.json', {encoding: 'utf-8'}, function (err, data) { // grab the package.json file contents
if (err) throw err;
package = JSON.parse(data);
fs.rename('package.json', 'rename-me-before-deploying.json'); // rename the package.json file
package.name = 'stajing'; // alter json
package.subdomain = 'stajing'; // alter json
package.domains = []; // alter json
fs.writeFile('package.json', JSON.stringify(package, null, 2), function(err) { // write the new package to package.json
if (err) throw err;
bash.stdin.write('jitsu deploy\n'); // Deploy to staging app on nodejitsu.
setTimeout(function () { // this needs to be replaced
bash.stdin.write('yes\n');
}, 5000);
console.log("All done : )");
// bash.stdin.end(); // close out
});
});
I have a few issues here. I'm pretty sure all I need to know to complete it, is the event that fires when nodejitsu prompts me to increment the version number prompt: Is this ok?: (yes)
so that I can confirm, if that happens, and the event that fires when the whole process finishes so that I can revert the changes to my package.json file, leaving my app deployed to a staging environment and my files essentially untouched.
Upvotes: 3
Views: 3925
Reputation: 151380
I'm not setup here to run jitsu deploy
. However, here is some code that illustrates how you can deal with the prompts:
var command = require('child_process').spawn('./command.js');
require('colors');
var stdout = "";
var prompt_re = /Is it okay \(yes\)\?.*?$/m;
command.stdout.on('data', function (data) {
console.log("stdout data: ".green + data);
stdout += data;
if (prompt_re.test(stdout)) {
command.stdin.write("yes\n");
// Flush the current buffer.
stdout = "";
}
});
command.stdout.on('error', function (err) {
console.log('stdout error: '.red, err);
});
var exit_msg = 'Exited with code... ';
command.on('exit', function (code) {
if (code != 0) {
console.log(exit_msg.red, code);
process.exit(1); // Or whatever you want to handle errors.
}
console.log(exit_msg.green, code);
// The code you want to execute once your command is done goes here.
});
Some explanations:
The code above buffers the data it gets from command.stdout
into as string stored in the stdout
variable and tests against that because if there's a lot of output there's no guarantee that the prompt will arrive in a single data
event. (It could, for instance, come in one event that contains a bunch of data + the string Is it
and then the next data
event could contain the rest of the prompt.)
The regular expression prompt_re
contains '.*?$' because the command I use to simulate getting a prompt uses escape codes for colors and I could not be bothered to match against the exact codes that are output.
This code assumes that the command will stop right away after outputting a prompt and waits there. This seems to be a safe assumption.
It also assumes that the prompt text cannot appear as something which is not a prompt. Whether this is safe depends on your specific scenario.
The ./command.js
file I used to simulate the command being run is:
#!/usr/bin/env node
var prompt = require("prompt");
function ask(cb) {
prompt.get(["Is it okay (yes)?"], function (err, result) {
console.log("asked");
cb();
});
}
setTimeout(function () {
ask(function () {
setTimeout(function () {
ask(function () { process.exit(0); });
}, 1000);
});
}, 5000);
It waits 5s, prompts once, waits 1s, prompts a second time and exits.
Upvotes: 2