Domanda

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...

  1. Open my package.json file
  2. Delete the domains field and change the name and subdomain to staging. (It might also make sense to change the version number)
  3. Then I jitsu deploy
  4. Confirm any prompts (like approve an increment of the version number)
  5. Once the app starts I check out how my apps working on the server, make changes and so on

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.

È stato utile?

Soluzione

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:

  1. 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.)

  2. 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.

  3. This code assumes that the command will stop right away after outputting a prompt and waits there. This seems to be a safe assumption.

  4. 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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top