diff --git a/configs/cli.js b/configs/cli.js index fef801e9..ba843516 100644 --- a/configs/cli.js +++ b/configs/cli.js @@ -36,6 +36,16 @@ return [ projectId: PID, apiHost: APIHOST }, + { + packagePath: "./c9.cli.publish/install", + projectId: PID, + apiHost: APIHOST + }, + { + packagePath: "./c9.cli.publish/list", + projectId: PID, + apiHost: APIHOST + }, { packagePath: "./c9.ide.auth/auth", accessToken: "token", @@ -65,11 +75,34 @@ return [ packagePath: "./c9.cli.open/restart", platform: process.platform }, + "./c9.automate/automate", + "./c9.ide.installer/commands/centos", + "./c9.ide.installer/commands/darwin", + "./c9.ide.installer/commands/bash", + "./c9.ide.installer/commands/npm", + "./c9.ide.installer/commands/pip", + "./c9.ide.installer/commands/gem", + "./c9.ide.installer/commands/zip", + "./c9.ide.installer/commands/symlink", + "./c9.ide.installer/commands/message", + { + packagePath: "./c9.ide.installer/commands/tar.gz", + bashBin: "bash" + }, + "./c9.ide.installer/commands/ubuntu", + "./c9.ide.installer/cli", + { + packagePath: "./c9.ide.installer/installer", + homeDir: process.env.HOME, + installSelfCheck: false, + installPath: process.env.HOME + "/.c9", + cli: true + }, // "./c9.cli.sync/sync", //"./c9.ide.keys/commands", { consumes: [], - provides: ["settings", "workspace", "cli_commands", "c9"], + provides: ["settings", "workspace", "cli_commands", "c9", "error_handler"], setup: function(options, imports, register) { register(null, { // @todo share with ace min @@ -78,8 +111,12 @@ return [ debug: true, hosted: false, local: true, + home: process.env.HOME, setStatus: function(){} }, + error_handler: { + log: function(){} + }, workspace: (function(){ var ws = new EventEmitter(); ws.connect = function(name, callback) { diff --git a/configs/client-default.js b/configs/client-default.js index 39874673..0e403b4e 100644 --- a/configs/client-default.js +++ b/configs/client-default.js @@ -523,9 +523,14 @@ module.exports = function(options) { }, "plugins/c9.automate/automate", "plugins/c9.ide.installer/commands/centos", + "plugins/c9.ide.installer/commands/darwin", "plugins/c9.ide.installer/commands/bash", "plugins/c9.ide.installer/commands/npm", + "plugins/c9.ide.installer/commands/pip", + "plugins/c9.ide.installer/commands/gem", + "plugins/c9.ide.installer/commands/zip", "plugins/c9.ide.installer/commands/symlink", + "plugins/c9.ide.installer/commands/message", { packagePath: "plugins/c9.ide.installer/commands/tar.gz", bashBin: options.bashBin diff --git a/package.json b/package.json index 6fe0f4ba..fa35e43b 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "c9.ide.find.infiles": "#72582de3cd", "c9.ide.find.replace": "#e4daf722b8", "c9.ide.run.debug": "#638e6b00b3", - "c9.automate": "#b1b0cca13a", + "c9.automate": "#47e2c429c9", "c9.ide.ace.emmet": "#e5f1a92ac3", "c9.ide.ace.gotoline": "#4d1a93172c", "c9.ide.ace.keymaps": "#43445d6306", @@ -77,13 +77,13 @@ "c9.ide.behaviors": "#6aad7006a0", "c9.ide.closeconfirmation": "#a28bfd8272", "c9.ide.configuration": "#adf50fdaa2", - "c9.ide.dialog.wizard": "#ea640aa5a1", + "c9.ide.dialog.wizard": "#5df4f14bb8", "c9.ide.fontawesome": "#781602c5d8", "c9.ide.format": "#f51451ac57", "c9.ide.help.support": "#60e88f5680", "c9.ide.imgeditor": "#08bbc53578", "c9.ide.immediate": "#6845a93705", - "c9.ide.installer": "#f8f0d11bff", + "c9.ide.installer": "#02e7018bf6", "c9.ide.mount": "#32e79866ee", "c9.ide.navigate": "#64156c7f4a", "c9.ide.newresource": "#f1f0624768", diff --git a/plugins/c9.cli.publish/install.js b/plugins/c9.cli.publish/install.js new file mode 100644 index 00000000..eb14b7b2 --- /dev/null +++ b/plugins/c9.cli.publish/install.js @@ -0,0 +1,579 @@ +define(function(require, exports, module) { + main.consumes = [ + "Plugin", "cli_commands", "proc", "api", "auth", "installer", + "installer.cli" + ]; + main.provides = ["cli.install"]; + return main; + + function main(options, imports, register) { + var Plugin = imports.Plugin; + var cmd = imports.cli_commands; + var proc = imports.proc; + var auth = imports.auth; + var api = imports.api; + var installer = imports.installer; + var installerCLI = imports["installer.cli"]; + + var TEST_MODE = !!process.env.C9_TEST_MODE; + var SHELLSCRIPT = TEST_MODE ? "" : require("text!./publish.git.sh").toString("utf8"); + var TAR = "tar"; + var APIHOST = options.apiHost; + var BASICAUTH = process.env.C9_TEST_AUTH; + var SCM = { + "git": { + binary: "git", + clone: "clone" + }, + "mercurial": { + binary: "hg", + clone: "clone" + }, + "hg": { + binary: "hg", + clone: "clone" + } + }; + + var fs = require("fs"); + var join = require("path").join; + var os = require("os"); + var http = require(APIHOST.indexOf("localhost") > -1 ? "http" : "https"); + + var verbose = false; + var force = false; + + // Set up basic auth for api if needed + if (BASICAUTH) api.basicAuth = BASICAUTH; + + /***** 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: "install", + info: " Installs a cloud9 package.", + usage: "[--verbose] [--force] [--global] [--local] [--debug] [--dry-run] [@]", + options: { + "local": { + description: "", + "default": false, + "boolean": true + }, + "global": { + description: "", + "default": false, + "boolean": true + }, + "debug": { + description: "", + "default": false, + "boolean": true + }, + "package" : { + description: "", + "default": false + }, + "verbose" : { + "description": "Output more information", + "alias": "v", + "default": false, + "boolean": true + }, + "dry-run" : { + "description": "Installs current directory as a package", + "default": false, + "boolean": true + }, + "force" : { + "description": "Ignore warnings", + "alias": "f", + "default": false, + "boolean": true + } + }, + check: function(argv) { + if (argv._.length < 2 && !argv["package"]) + throw new Error("package"); + }, + exec: function(argv) { + verbose = argv["verbose"]; + force = argv["force"]; + + if (argv.accessToken) + auth.accessToken = argv.accessToken; + + if (!argv.local && !argv.debug) { + if (!process.env.C9_PID) { + console.warn("It looks like you are not running on c9.io. Will default to local installation of the package"); + argv.local = true; + } + } + + var name = argv._[1]; + install( + name, + { + global: argv.global, + local: argv.local, + debug: argv.debug, + dryRun: argv["dry-run"] + }, + function(err, data){ + if (err) { + console.error(err.message || "Terminated."); + process.exit(1); + } + else { + console.log("Succesfully installed", name + (argv.debug ? "" : "@" + data.version)); + process.exit(0); + } + }); + } + }); + + cmd.addCommand({ + name: "remove", + info: " Removes a cloud9 package.", + usage: "[--verbose] [--global] [--local] ", // @TODO --global + options: { + "local": { + description: "", + "default": false, + "boolean": true + }, + "global": { + description: "", + "default": false, + "boolean": true + }, + "package" : { + description: "" + }, + "verbose" : { + "description": "Output more information", + "alias": "v", + "default": false, + "boolean": true + } + }, + check: function(argv) { + if (argv._.length < 2 && !argv["package"]) + throw new Error("package"); + }, + exec: function(argv) { + verbose = argv["verbose"]; + + if (argv.accessToken) + auth.accessToken = argv.accessToken; + + var name = argv._[1]; + uninstall( + name, + { + global: argv.global, + local: argv.local + }, + function(err, data){ + if (err) { + console.error(err.message || "Terminated."); + process.exit(1); + } + else { + console.log("Succesfully removed", name); + process.exit(0); + } + }); + } + }); + } + + /***** Methods *****/ + + function install(packageName, options, callback){ + // Call install url + var parts = packageName.split("@"); + var name = parts[0]; + var version = parts[1]; + var repository; + + if ((!version || options.debug) && !options.dryRun) { + if (verbose) + console.log("Retrieving package info"); + + api.packages.get(name, function (err, info) { + if (err) return callback(err); + + if (verbose) + console.log("Found:", info); + + version = info.latest; + repository = info.repository; + + installPackage(); + }); + } + else { + installPackage(); + } + + function prepareDirectory(callback){ + // Create package dir + var packagePath = process.env.HOME + "/.c9/plugins/" + name; + var exists = fs.existsSync(packagePath) ; + if (exists) { + if (!force) + return callback(new Error("WARNING: Directory not empty: " + packagePath + + ". Use --force to overwrite.")); + + proc.execFile("rm", { + args: ["-Rf", packagePath] + }, function(){ + mkdirP(packagePath); + callback(null, packagePath); + }); + } + else { + mkdirP(packagePath); + callback(null, packagePath); + } + } + + function installPackage(){ + if (!version && !options.dryRun) + return callback(new Error("No version found for this package")); + + if (options.local) { + installLocal(); + } + else if (options.debug) { + installDebug(); + } + else { + installFull(); + } + } + + function installLocal(){ + if (verbose) + console.log("Installing package locally"); + + prepareDirectory(function(err, packagePath){ + if (err) return callback(err); + + function installNPM(){ + proc.spawn(join(process.env.HOME, ".c9/node/bin/npm"), { + args: ["install"], + cwd: packagePath + }, function(err, p){ + if (err) return callback(err); + + if (verbose) { + p.stdout.on("data", function(c){ + process.stdout.write(c.toString("utf8")); + }); + p.stderr.on("data", function(c){ + process.stderr.write(c.toString("utf8")); + }); + } + + p.on("exit", function(code){ + // Done + callback(err, { + version: version + }); + }); + }); + } + + if (options.dryRun) { + try { + var json = JSON.parse(fs.readFileSync(join(process.cwd(), "package.json"))); + if (json.private) + return callback(new Error("ERROR: Private flag in package.json prevents from installing")); + } + catch(e) { + return callback(new Error("ERROR: Invalid package")); + } + + proc.execFile("bash", { args: ["-c", "cp -a " + join(process.cwd(), "/*") + " " + packagePath] }, function(err){ + if (err) return callback(err); + + installNPM(); + }); + + return; + } + + // Download package + var gzPath = join(os.tmpDir(), name + "@" + version + ".tar.gz"); + var file = fs.createWriteStream(gzPath); + + var path = "/packages/" + name + "/versions/" + version + + "/download?access_token=" + + encodeURIComponent(auth.accessToken); + var host = APIHOST.split(":")[0]; + var port = parseInt(APIHOST.split(":")[1]) || null; + + var request = http.get({ + agent: false, + method: "get", + host: host, + port: port, + auth: BASICAUTH, + path: path + }, function(response){ + response.pipe(file); + }); + + if (verbose) + console.log("Downloading package to", gzPath); + + request.on('response', function(res) { + if (res.statusCode != 200) + return callback(new Error("Unknown Error:" + res.statusCode)); + }); + + file.on('finish', function() { + if (verbose) + console.log("Unpacking", gzPath, "to", packagePath); + + // Untargz package + proc.spawn(TAR, { + args: ["-C", normalizePath(packagePath), "-zxvf", normalizePath(gzPath)] + }, function(err, p){ + if (err) return callback(err); + + if (verbose) { + p.stdout.on("data", function(c){ + process.stdout.write(c.toString("utf8")); + }); + p.stderr.on("data", function(c){ + process.stderr.write(c.toString("utf8")); + }); + } + + p.on("exit", function(code){ + var err = code !== 0 + ? new Error("Failed to unpack package") + : null; + if (err) return callback(err); + + installNPM(); + }); + }); + }); + }); + } + + function installDebug(){ + if (verbose) + console.log("Installing debug version of package"); + + if (!options.dryRun) + return callback(new Error("Dry run is not supported for debug installations")); + + prepareDirectory(function(err, packagePath){ + if (err) return callback(err); + + if (verbose) + console.log("Cloning repository: ", repository); + + // Git clone repository + var scm = SCM[repository.type]; + proc.spawn(scm.binary, { + args: [scm.clone, repository.url, packagePath] + }, function(err, p){ + if (err) return callback(err); + + if (verbose) { + p.stdout.on("data", function(c){ + process.stdout.write(c.toString("utf8")); + }); + p.stderr.on("data", function(c){ + process.stderr.write(c.toString("utf8")); + }); + } + + p.on("exit", function(code){ + var err = code !== 0 + ? new Error("Failed to clone package from repository. Do you have access?") + : null; + + // Done + callback(err); + }); + }); + }); + } + + function installFull(){ + if (verbose) + console.log("Notifying c9.io that packages needs to be installed"); + + // Install Locally + options.local = true; + install(name + "@" + version, options, function(err){ + if (err) return callback(err); + + var path = process.env.HOME + "/.c9/plugins/" + name; + fs.readFile(path + "/package.json", "utf8", function(err, data){ + if (err) return callback(new Error("Package.json not found in " + path)); + + var installPath; + try { installPath = JSON.parse(data).installer; } + catch(e){ + return callback(new Error("Could not parse package.json in " + path)); + } + + if (installPath) { + installerCLI.verbose = verbose; + installer.createSession(name, version, require(path + "/" + installPath), function(err){ + if (err) return callback(new Error("Error Installing Package " + name + "@" + version)); + installToDatabase(); + }); + } + else + installToDatabase(); + }); + + + function installToDatabase(){ + if (options.dryRun) + return callback(null, { version: "dry-run" }); + + var endpoint = options.global ? api.user : api.project; + var url = "install/" + packageName + "/" + version + "?mode=silent"; + + endpoint.post(url, function(err, info){ + callback(err, info); + }); + } + }); + } + } + + function uninstall(packageName, options, callback){ + // Call uninstall url + var parts = packageName.split("@"); + var name = parts[0]; + var version = parts[1]; + + if (!version) { + api.packages.get(name, function (err, info) { + if (err) return callback(err); + version = info.latest; + + uninstallPackage(); + }); + } + else { + uninstallPackage(); + } + + function uninstallPackage(){ + if (options.local || options.debug) { + // rm -Rf + var packagePath = process.env.HOME + "/.c9/plugins/" + name; + proc.spawn("rm", { + args: ["-rf", packagePath] + }, function(err, p){ + if (err) return callback(err); + + if (verbose) { + p.stdout.on("data", function(c){ + process.stdout.write(c.toString("utf8")); + }); + p.stderr.on("data", function(c){ + process.stderr.write(c.toString("utf8")); + }); + } + + p.on("exit", function(code){ + var err = code !== 0 + ? new Error("Failed to remove package.") + : null; + + // if debug > see if should be installed and put back original + // @TODO + + // Done + callback(err); + }); + }); + } + else { + var endpoint = options.global ? api.user : api.project; + var url = "uninstall/" + packageName; + + endpoint.post(url, function(err, info){ + callback(err, info); + }); + } + } + } + + function mkdirP(path){ + var dirs = path.split('/'); + var prevDir = dirs.splice(0,1) + "/"; + while (dirs.length > 0) { + var curDir = prevDir + dirs.splice(0,1); + if (! fs.existsSync(curDir) ) { + fs.mkdirSync(curDir); + } + prevDir = curDir + '/'; + } + } + + function normalizePath(p) { + if (process.platform == "win32") + p = p.replace(/\\/g, "/").replace(/^(\w):/, "/$1"); + return p; + } + + /***** Lifecycle *****/ + + plugin.on("load", function(){ + load(); + }); + plugin.on("enable", function(){ + + }); + plugin.on("disable", function(){ + + }); + plugin.on("unload", function(){ + loaded = false; + verbose = false; + force = false; + }); + + /***** Register and definfe API *****/ + + /** + * + **/ + plugin.freezePublicAPI({ + /** + * + */ + install: install, + + /** + * + */ + uninstall: uninstall + }); + + register(null, { + "cli.install": plugin + }); + } + +}); \ No newline at end of file diff --git a/plugins/c9.cli.publish/list.js b/plugins/c9.cli.publish/list.js new file mode 100644 index 00000000..a937e903 --- /dev/null +++ b/plugins/c9.cli.publish/list.js @@ -0,0 +1,130 @@ +define(function(require, exports, module) { + main.consumes = ["Plugin", "cli_commands", "api"]; + main.provides = ["cli.list"]; + return main; + + function main(options, imports, register) { + var Plugin = imports.Plugin; + var cmd = imports.cli_commands; + var api = imports.api; + + var BASICAUTH = process.env.C9_TEST_AUTH; + var verbose = false; + + var LIGHTBlUE = "\x1b[01;94m"; + var RESETCOLOR = "\x1b[0m"; + var PADDING = 2; + + // Set up basic auth for api if needed + if (BASICAUTH) api.basicAuth = BASICAUTH; + + /***** 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: "list", + info: " Lists all available packages.", + usage: "[--json]", + options: { + "json": { + description: "", + "default": false, + "boolean": true + }, + }, + check: function(argv) {}, + exec: function(argv) { + verbose = argv["verbose"]; + + list(argv.json, function(err){ + if (err) + console.error(err.message || err); + process.exit(err ? 1 : 0); + }); + } + }); + } + + /***** Methods *****/ + + function stringifyError(err){ + return (verbose ? JSON.stringify(err, 4, " ") : (typeof err == "string" ? err : err.message)); + } + + function pad(str, nr){ + return str + Array(nr - str.length).join(" "); + } + + function list(asJson, callback){ + callback = callback || function(){}; + api.packages.get("", function(err, list){ + if (err) { + console.error("ERROR: Could not get list: ", stringifyError(err)); + return callback(err); + } + + if (asJson) { + console.log(JSON.stringify(list, 4, " ")); + return callback(null, list); + } + else { + var max = [0, 0, 0, 0]; + list.forEach(function(item){ + max[0] = Math.max(max[0], item.name.length); + max[1] = Math.max(max[1], Math.min(50, item.description.split(".")[0].length)); + max[2] = Math.max(max[2], item.name.length + 33); + max[3] = Math.max(max[3], (item.website || item.repository.url).length); + }); + list.forEach(function(item){ + console.log( + pad(item.name, max[0] + PADDING), + pad(item.description.split(".")[0], max[1] + PADDING), + LIGHTBlUE + pad("https://c9.io/profile/packages/" + item.name, max[2] + PADDING) + RESETCOLOR, + pad(item.website || item.repository.url, max[3])); + }); + return callback(null, list); + } + }); + } + + /***** Lifecycle *****/ + + plugin.on("load", function(){ + load(); + }); + plugin.on("enable", function(){ + + }); + plugin.on("disable", function(){ + + }); + plugin.on("unload", function(){ + loaded = false; + verbose = false; + }); + + /***** Register and definfe API *****/ + + /** + * + **/ + plugin.freezePublicAPI({ + /** + * + */ + list: list + }); + + register(null, { + "cli.list": plugin + }); + } + +}); diff --git a/plugins/c9.cli.publish/publish.js b/plugins/c9.cli.publish/publish.js index 7f76ab70..37ae956c 100644 --- a/plugins/c9.cli.publish/publish.js +++ b/plugins/c9.cli.publish/publish.js @@ -118,7 +118,7 @@ define(function(require, exports, module) { cmd.addCommand({ name: "build", - info: " Builds development version of package to load in non-debug mode.", + info: " Builds development version of package to load in non-debug mode.", usage: "[--devel]", options: { "devel" : { @@ -156,12 +156,12 @@ define(function(require, exports, module) { .trim() .replace(/PACKAGE_NAME/g, packageName); - fs.writeFileSync(cwd + "/__installed__.js", code, "utf8") - } else { - dryRun = true - publish({local: true}, function(err, data){}); + fs.writeFileSync(cwd + "/__installed__.js", code, "utf8"); + } + else { + dryRun = true; + publish({local: true}, function(){}); } - } }); @@ -194,156 +194,6 @@ define(function(require, exports, module) { }); } }); - - cmd.addCommand({ - name: "install", - info: " Installs a cloud9 package.", - usage: "[--verbose] [--force] [--global] [--local] [--debug] [@]", // @TODO --global, --debug, --local - options: { - "local": { - description: "", - "default": false, - "boolean": true - }, - "global": { - description: "", - "default": false, - "boolean": true - }, - "debug": { - description: "", - "default": false, - "boolean": true - }, - "package" : { - description: "", - "default": false - }, - "verbose" : { - "description": "Output more information", - "alias": "v", - "default": false, - "boolean": true - }, - "force" : { - "description": "Ignore warnings", - "alias": "f", - "default": false, - "boolean": true - } - }, - check: function(argv) { - if (argv._.length < 2 && !argv["package"]) - throw new Error("package"); - }, - exec: function(argv) { - verbose = argv["verbose"]; - force = argv["force"]; - - if (argv.accessToken) - auth.accessToken = argv.accessToken; - - if (!argv.local && !argv.debug) { - if (!process.env.C9_PID) { - console.warn("It looks like you are not running on c9.io. Will default to local installation of the package"); - argv.local = true; - } - } - - var name = argv._[1]; - install( - name, - { - global: argv.global, - local: argv.local, - debug: argv.debug - }, - function(err, data){ - if (err) { - console.error(err.message || "Terminated."); - process.exit(1); - } - else { - console.log("Succesfully installed", name + (argv.debug ? "" : "@" + data.version)); - process.exit(0); - } - }); - } - }); - - cmd.addCommand({ - name: "remove", - info: " Removes a cloud9 package.", - usage: "[--verbose] [--global] [--local] ", // @TODO --global - options: { - "local": { - description: "", - "default": false, - "boolean": true - }, - "global": { - description: "", - "default": false, - "boolean": true - }, - "package" : { - description: "" - }, - "verbose" : { - "description": "Output more information", - "alias": "v", - "default": false, - "boolean": true - } - }, - check: function(argv) { - if (argv._.length < 2 && !argv["package"]) - throw new Error("package"); - }, - exec: function(argv) { - verbose = argv["verbose"]; - - if (argv.accessToken) - auth.accessToken = argv.accessToken; - - var name = argv._[1]; - uninstall( - name, - { - global: argv.global, - local: argv.local - }, - function(err, data){ - if (err) { - console.error(err.message || "Terminated."); - process.exit(1); - } - else { - console.log("Succesfully removed", name); - process.exit(0); - } - }); - } - }); - - cmd.addCommand({ - name: "list", - info: " Lists all available packages.", - usage: "[--json]", - options: { - "json": { - description: "", - "default": false, - "boolean": true - }, - }, - check: function(argv) {}, - exec: function(argv) { - verbose = argv["verbose"]; - - list(argv.json); - } - }); } /***** Methods *****/ @@ -352,27 +202,6 @@ define(function(require, exports, module) { return (verbose ? JSON.stringify(err, 4, " ") : (typeof err == "string" ? err : err.message)); } - function list(asJson, callback){ - callback = callback || function(){}; - api.packages.get("", function(err, list){ - if (err) { - console.error("ERROR: Could not get list: ", stringifyError(err)); - return callback(err); - } - - if (asJson) { - console.log(JSON.stringify(list, 4, " ")); - return callback(null, list); - } - else { - list.forEach(function(item){ - console.log(item.name, "https://c9.io/packages/" + item.name); - }); - return callback(null, list); - } - }); - } - function publish(options, callback) { if (typeof options != "object") options = {version: options}; @@ -390,6 +219,8 @@ define(function(require, exports, module) { } // Basic Validation + if (json.private) + return callback(new Error("ERROR: Private flag in package.json prevents from publishing")); if (!json.name) return callback(new Error("ERROR: Missing name property in package.json")); if (basename(cwd) != json.name) { @@ -397,10 +228,10 @@ define(function(require, exports, module) { if (!force) return callback(new Error("Use --force to ignore this warning.")); } - if (!json.description) - return callback(new Error("ERROR: Missing description property in package.json")); if (!json.repository) return callback(new Error("ERROR: Missing repository property in package.json")); + if (!json.repository.url) + return callback(new Error("ERROR: Missing repository.url property in package.json")); if (!json.categories || json.categories.length == 0) return callback(new Error("ERROR: At least one category is required in package.json")); @@ -411,6 +242,12 @@ define(function(require, exports, module) { return callback(new Error("Use --force to ignore these warnings.")); } + if (json.description) + console.warn("WARNING: Description property in package.json will be ignored. README.md will be used."); + + var originalDesc = json.description; + json.description = fs.readFileSync(join(cwd, "README.md"), "utf8"); + // Validate plugins var plugins = {}; fs.readdirSync(cwd).forEach(function(filename) { @@ -472,10 +309,14 @@ define(function(require, exports, module) { if (!version) return next(); + // Reset description + var pkgJson = Object.create(json); + pkgJson.description = originalDesc; + // Write the package.json file var indent = data.match(/{\n\r?^ {4}"/) ? 4 : 2; - var newData = JSON.stringify(json, null, indent); - fs.writeFile(cwd + "/.c9/.build/pacage.json", newData, function(err){ + var newData = JSON.stringify(pkgJson, null, indent); + fs.writeFile(cwd + "/.c9/.build/pacage.json", newData, function(){ if (dryRun) return next(); // if dry-run is passed only update path in .build fs.writeFile(packagePath, newData, function(err){ @@ -948,258 +789,6 @@ define(function(require, exports, module) { }); } - function install(packageName, options, callback){ - // Call install url - var parts = packageName.split("@"); - var name = parts[0]; - var version = parts[1]; - var repository; - - if (!version || options.debug) { - if (verbose) - console.log("Retrieving package info"); - - api.packages.get(name, function (err, info) { - if (err) return callback(err); - - if (verbose) - console.log("Found:", info); - - version = info.latest; - repository = info.repository; - - installPackage(); - }); - } - else { - installPackage(); - } - - function prepareDirectory(callback){ - // Create package dir - var packagePath = process.env.HOME + "/.c9/plugins/" + name; - var exists = fs.existsSync(packagePath) ; - if (exists) { - if (!force) - return callback(new Error("WARNING: Directory not empty: " + packagePath - + ". Use --force to overwrite.")); - - proc.execFile("rm", { - args: ["-Rf", packagePath] - }, function(){ - mkdirP(packagePath); - callback(null, packagePath); - }); - } - else { - mkdirP(packagePath); - callback(null, packagePath); - } - } - - function installPackage(){ - if (!version) - return callback(new Error("No version found for this package")); - - if (options.local) { - if (verbose) - console.log("Installing package locally"); - - prepareDirectory(function(err, packagePath){ - if (err) return callback(err); - - // Download package - var gzPath = join(os.tmpDir(), name + "@" + version + ".tar.gz"); - var file = fs.createWriteStream(gzPath); - - var path = "/packages/" + name + "/versions/" + version - + "/download?access_token=" - + encodeURIComponent(auth.accessToken); - var host = APIHOST.split(":")[0]; - var port = parseInt(APIHOST.split(":")[1]) || null; - - var request = http.get({ - agent: false, - method: "get", - host: host, - port: port, - auth: BASICAUTH, - path: path - }, function(response){ - response.pipe(file); - }); - - if (verbose) - console.log("Downloading package to", gzPath); - - request.on('response', function(res) { - if (res.statusCode != 200) - return callback(new Error("Unknown Error:" + res.statusCode)); - }); - - file.on('finish', function(err) { - if (verbose) - console.log("Unpacking", gzPath, "to", packagePath); - - // Untargz package - proc.spawn(TAR, { - args: ["-C", normalizePath(packagePath), "-zxvf", normalizePath(gzPath)] - }, function(err, p){ - if (err) return callback(err); - - if (verbose) { - p.stdout.on("data", function(c){ - process.stdout.write(c.toString("utf8")); - }); - p.stderr.on("data", function(c){ - process.stderr.write(c.toString("utf8")); - }); - } - - p.on("exit", function(code){ - var err = code !== 0 - ? new Error("Failed to unpack package") - : null; - if (err) return callback(err); - - proc.spawn(join(process.env.HOME, ".c9/node/bin/npm"), { - args: ["install"], - cwd: packagePath - }, function(err, p){ - if (err) return callback(err); - - if (verbose) { - p.stdout.on("data", function(c){ - process.stdout.write(c.toString("utf8")); - }); - p.stderr.on("data", function(c){ - process.stderr.write(c.toString("utf8")); - }); - } - - p.on("exit", function(code){ - // Done - callback(err, { - version: version - }); - }); - }); - }); - }); - }); - }); - } - else if (options.debug) { - if (verbose) - console.log("Installing debug version of package"); - - prepareDirectory(function(err, packagePath){ - if (err) return callback(err); - - if (verbose) - console.log("Cloning repository: ", repository); - - // Git clone repository - var scm = SCM[repository.type]; - proc.spawn(scm.binary, { - args: [scm.clone, repository.url, packagePath] - }, function(err, p){ - if (err) return callback(err); - - if (verbose) { - p.stdout.on("data", function(c){ - process.stdout.write(c.toString("utf8")); - }); - p.stderr.on("data", function(c){ - process.stderr.write(c.toString("utf8")); - }); - } - - p.on("exit", function(code){ - var err = code !== 0 - ? new Error("Failed to clone package from repository. Do you have access?") - : null; - - // Done - callback(err); - }); - }); - }); - } - else { - if (verbose) - console.log("Notifying c9.io that packages needs to be installed"); - - var endpoint = options.global ? api.user : api.project; - var url = "install/" + packageName + "/" + version; - - endpoint.post(url, function(err, info){ - callback(err, info); - }); - } - } - } - - function uninstall(packageName, options, callback){ - // Call uninstall url - var parts = packageName.split("@"); - var name = parts[0]; - var version = parts[1]; - - if (!version) { - api.packages.get(name, function (err, info) { - if (err) return callback(err); - version = info.latest; - - uninstallPackage(); - }); - } - else { - uninstallPackage(); - } - - function uninstallPackage(){ - if (options.local || options.debug) { - // rm -Rf - var packagePath = process.env.HOME + "/.c9/plugins/" + name; - proc.spawn("rm", { - args: ["-rf", packagePath] - }, function(err, p){ - if (err) return callback(err); - - if (verbose) { - p.stdout.on("data", function(c){ - process.stdout.write(c.toString("utf8")); - }); - p.stderr.on("data", function(c){ - process.stderr.write(c.toString("utf8")); - }); - } - - p.on("exit", function(code){ - var err = code !== 0 - ? new Error("Failed to remove package.") - : null; - - // if debug > see if should be installed and put back original - // @TODO - - // Done - callback(err); - }); - }); - } - else { - var endpoint = options.global ? api.user : api.project; - var url = "uninstall/" + packageName; - - endpoint.post(url, function(err, info){ - callback(err, info); - }); - } - } - } - function mkdirP(path){ var dirs = path.split('/'); var prevDir = dirs.splice(0,1) + "/"; @@ -1249,22 +838,7 @@ define(function(require, exports, module) { /** * */ - unpublish: unpublish, - - /** - * - */ - install: install, - - /** - * - */ - uninstall: uninstall, - - /** - * - */ - list: list + unpublish: unpublish }); register(null, { diff --git a/plugins/c9.fs/proc2pty.js b/plugins/c9.fs/proc2pty.js index 249cda20..d9b9d562 100644 --- a/plugins/c9.fs/proc2pty.js +++ b/plugins/c9.fs/proc2pty.js @@ -4,7 +4,7 @@ define(function(require, exports, module) { module.exports = function(process){ var pty = new EventEmitter(); pty.write = function(data){ - process.stdin.write(data); + process.stdin.write(data.replace(/\r/g, "\n")); }; pty.resize = function(){}; pty.destroy = @@ -23,5 +23,5 @@ define(function(require, exports, module) { }); return pty; - } + }; }); \ No newline at end of file diff --git a/plugins/c9.ide.errorhandler/raygun_error_handler.js b/plugins/c9.ide.errorhandler/raygun_error_handler.js index 12be8f71..3c3dcca8 100644 --- a/plugins/c9.ide.errorhandler/raygun_error_handler.js +++ b/plugins/c9.ide.errorhandler/raygun_error_handler.js @@ -62,7 +62,9 @@ define(function(require, exports, module) { exception = new Error(exception); if (!exception) exception = new Error("Unspecified error"); - console.error(exception.stack); + console.error(exception); + if (customData) + console.log(customData); Raygun.send(exception, customData, tags); } diff --git a/plugins/c9.ide.plugins/loader.js b/plugins/c9.ide.plugins/loader.js index 93ad2aea..7b21a959 100644 --- a/plugins/c9.ide.plugins/loader.js +++ b/plugins/c9.ide.plugins/loader.js @@ -57,8 +57,11 @@ define(function(require, exports, module) { if (loadFromDisk) { fs.readdir("~/.c9/plugins", function handle(err, files){ if (err) { - if (err.code == "EDISCONNECT") - fs.readdir("~/.c9/plugins", handle); + if (err.code == "EDISCONNECT") { + c9.once("connect", function(){ + fs.readdir("~/.c9/plugins", handle); + }); + } console.error(err); return; } diff --git a/plugins/c9.vfs.client/vfs.cli.js b/plugins/c9.vfs.client/vfs.cli.js index 915200fe..92d339e8 100644 --- a/plugins/c9.vfs.client/vfs.cli.js +++ b/plugins/c9.vfs.client/vfs.cli.js @@ -9,7 +9,7 @@ define(function(require, module, exports) { var vfs = new localFs({ root: "/", - nopty: true, + // nopty: true, defaultEnv: { CUSTOM: 43 } });