c9-core/plugins/c9.cli.open/open.js

258 wiersze
9.0 KiB
JavaScript
Executable File

define(function(require, exports, module) {
main.consumes = ["Plugin", "cli_commands", "proc", "bridge.client"];
main.provides = ["open"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var cmd = imports.cli_commands;
var proc = imports.proc;
var bridge = imports["bridge.client"];
var fs = require("fs");
var PATH = require("path");
/***** Initialization *****/
var plugin = new Plugin("Ajax.org", main.consumes);
// var emit = plugin.getEmitter();
var loaded;
function load() {
if (loaded) return;
loaded = true;
cmd.addCommand({
name: "open",
info: " Opens a file or directory.",
usage: "[--wait] [--pipe] <path>",
options: {
"wait": {
description: "Wait until the file(s) are closed",
"default": false,
"boolean": true
},
"pipe": {
description: "Pipe data from a command into c9",
"default": false,
"boolean": true
}
},
check: function(argv) {
if (argv._.length < 2 && !argv["path"] && !argv.pipe)
throw new Error("Missing path");
},
exec: function(argv) {
if (argv.pipe) {
openWithPipe(function() {});
return;
}
open(
argv._.slice(1), // Remove "open" from the paths
argv.wait,
function() {});
}
});
}
/***** Methods *****/
function open(paths, wait, callback) {
try {
paths = paths.map(function(path) {
path = String(path);
var isDir = fs.existsSync(path) && fs.statSync(path).isDirectory();
path = PATH.resolve(path);
if (path.substr(0, process.env.HOME.length) == process.env.HOME)
path = "~" + path.substr(process.env.HOME.length);
return {
path: path,
type: isDir ? "directory" : "file"
};
});
} catch (e) {
return console.error(e);
}
var last;
paths.forEach(function(info) {
var path = info.type == "directory"
? info.path : PATH.dirname(info.path);
if (!last) {
last = path;
}
else {
var one = last.split(PATH.sep);
var two = path.split(PATH.sep);
for (var i = 0; i < one.length; i++) {
if (one[i] != two[i]) {
last = one.slice(0, i).join(PATH.sep);
return;
}
}
}
});
var message = {
type: "open",
workspace: "local",
wait: wait,
paths: paths
};
bridge.send(message, function cb(err, response) {
if (err) {
if (err.code == "ECONNREFUSED") {
// Seems Cloud9 is not running, lets start it up
startCloud9Local({}, function(success) {
if (success)
bridge.send(message, cb);
else {
console.log("Could not start Cloud9. "
+ "Please check your configuration.");
callback(err);
process.exit(40); // This appears to be needed; let's return something useful
}
});
return;
}
else
console.log(err.message);
}
if (response !== true)
console.log("Could not open ", paths);
process.exit(); // I don't get why this is needed
});
}
function openWithPipe(callback) {
bridge.send({
type: "pipe",
path: process.cwd() + "/" + "Pipe " + (new Date()).toLocaleString().replace(/:/g, "."),
}, function cb(err, response) {
if (err) {
if (err.code == "ECONNREFUSED") {
// Seems Cloud9 is not running, lets start it up
startCloud9Local({}, function(success) {
if (success)
bridge.send({ type: "pipe" }, cb);
else {
console.log("Could not start Cloud9. "
+ "Please check your configuration.");
callback(err);
process.exit(40); // This appears to be needed; let's return something useful
}
});
return;
}
else {
console.log(err.message);
return;
}
}
var stdin = process.openStdin();
stdin.setEncoding("utf8");
var finished = 0;
stdin.on("data", function(chunk) {
finished++;
bridge.send({
type: "pipeData",
data: chunk,
tab: response
}, function(err, message) {
// Dunno why, but this always returns No Response...
// Escaping that error so end users aren't confused...
if (err && err.message !== "No Response")
console.log(err.message);
finished--;
});
});
stdin.on("end", function() {
(function retry() {
if (finished === 0)
process.exit();
setTimeout(retry, 100);
})();
});
});
}
function startCloud9Local(opts, callback) {
if (options.platform == "darwin") {
proc.spawn("open", {
args: ["-b", "io.c9.desktop"],
detached: true
}, function(err, process) {
if (err)
return callback(false);
// required so the parent can exit
process.unref();
var timed = Date.now();
(function retry() {
bridge.send({ type: "ping" }, function(err, message) {
if (!err)
return callback(true);
if (Date.now() - timed > 10000)
return callback(false);
if (message !== true)
return callback(false);
setTimeout(retry, 100);
});
})();
});
}
else if (options.platform == "linux") {
}
else if (options.platform == "windows") {
}
else {
callback(false);
}
}
/***** Lifecycle *****/
plugin.on("load", function() {
load();
});
plugin.on("enable", function() {
});
plugin.on("disable", function() {
});
plugin.on("unload", function() {
loaded = false;
});
/***** Register and define API *****/
/**
* Finds or lists files and/or lines based on their filename or contents
**/
plugin.freezePublicAPI({
/**
*
*/
open: open
});
register(null, {
open: plugin
});
}
});