Unitech/pm2 — pull request #186 by bretcope (2013-11-22 01:10:59+00:00)
Title: Consistent JSON structure for God and CLI

I should reiterate how much I like PM2. It's feature set is impressive, significantly better than any of the node process management tools I've used before, and I've started to use it for a new project here at Stack Exchange/Stack Overflow. Besides the [socket connection keeping my scripts alive](https://github.com/Unitech/pm2-interface/pull/2) problem, I found one major pain point while trying to use [pm2-interface](https://github.com/Unitech/pm2-interface).

Looking at the README in pm2-interface, there is very little documentation about what format it expects for arguments. In particular, it came as a surprise that `prepare()`

_description from the README:_

> `ipm2.rpc.prepare(json, fn)` send a JSON configuration to start app(s)

uses a JSON structure different from the command line interface `pm2 start processes.json`. This does not appear to be documented anywhere and it took some digging in the code to first figure out that I needed to be looking in the pm2 project, not pm2-interface, and second, to discover that there is a separate internal JSON structure used (for example, instead of `script`, it uses `pm_exec_path`.

Adding to my frustration was discovering that, while the `processes.json` format allowed some properties to be omitted so that default values may be assumed, `prepare()` would fail if I did not supply explicit values for `pm_out_log_path`, `pm_err_log_path`, and `pm_pid_path`.

So I set out to fix this.

#### Solution

The CLI was using a `reslovePaths` method to convert the `processes.json` app structure into the internal app structure, supplying default values along the way where explicit properties were missing. This method was local to the CLI module, and therefore not accessible elsewhere.

My solution was to refactor this out into a `Common.js` module which could be loaded by both CLI and God. Since the CLI and God need to handle errors a little differently, there are slight changes, but the code is mostly a cut and paste.

In God, I added a `prepareJson()` method which is essentially a wrapper for `prepare()` which first calls `Common.resolveAppPaths()` to convert the app structure, then, if successful, passes it on to prepare.

It's usage works like this:

```javascript
var ipm2 = require('pm2-interface')();
var processes = require('./processes.json');
ipm2.on('ready', function () {
for (var i in processes) {
ipm2.rpc.prepareJson(processes[i], process.cwd(), function (err, procs) {
console.log(err || procs);
});
}
});
```

The middle `cwd` parameter is optional, and discussed here.

#### Testing

No existing functionality was changed, and all existing tests still pass. If you would like tests written for this addition, I would be happy to work with you on that.

#### PM2-Interface Updates

If this pull-request is accepted, this pull request should also be accepted into pm2-interface otherwise users won't be able to utilize the optional `cwd` parameter of prepareJson.

Also, at that time, the pm2-interface README should be updated to reflect the addition of prepareJson.

#### Thoughts?

This was a very necessary change in order for PM2 to be usable for us, but if you have any problems with the way I implemented it, please let me know so we can try to come up with a solution which works for everyone. Let me know if this is something you would consider merging.