Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

reworked install of `sm` in PATH

  • Loading branch information...
commit abe457d1b592f19d772e8eeca2b22659d0bed16c 1 parent ec07a0a
@cadorn cadorn authored
View
2  bin/sm
@@ -1,3 +1,3 @@
#!/usr/bin/env node
-require("../lib/cli");
+require("../lib/cli").main();
View
14 lib/cli.js
@@ -13,14 +13,13 @@ var ARGS_PARSER = require("sourcemint-util-js/lib/args").Parser;
const NPM_MIN_VERSION = "1.1.63";
//TODO: Only enable this in debug mode.
-process.on("uncaughtException", function (err)
-{
+process.on("uncaughtException", function (err) {
// NOTE: `err.stack` seems to be useless here.
console.error("Uncaught exception: " + err);
});
-function main() {
+exports.main = function() {
var optParser = new ARGS_PARSER();
optParser.masthead([
@@ -39,7 +38,11 @@ function main() {
optParser.helpful();
FS.readdirSync(PATH.resolve(__dirname, "commands")).forEach(function(filename) {
- UTIL.every(require(PATH.resolve(__dirname, "commands", filename)), function(pair) {
+ var commandModule = require(PATH.resolve(__dirname, "commands", filename));
+ if (typeof commandModule.getCommand === "function") {
+ commandModule = commandModule.getCommand();
+ }
+ UTIL.every(commandModule, function(pair) {
optParser.command(pair[0], pair[1]);
});
});
@@ -123,6 +126,3 @@ exports.checkPackageProgramPathInArguments = function(args) {
return path;
}
-
-
-main();
View
109 lib/commands/install-command.js
@@ -0,0 +1,109 @@
+
+const PATH = require("path");
+const FS = require("fs");
+const EXEC = require("child_process").exec;
+const ARGS_PARSER = require("sourcemint-util-js/lib/args").Parser;
+const TERM = require("sourcemint-util-js/lib/term");
+const OS = require("sourcemint-util-js/lib/os");
+const CLI = require("../cli");
+
+const COMMAND_PATH = PATH.join(__dirname, "../../bin/sm");
+
+
+exports.getCommand = function() {
+
+ var command = new ARGS_PARSER();
+
+ command.help("Install `sm` command in PATH.");
+ command.helpful();
+
+ command.action(function (options) {
+
+ exports.install(function(err) {
+ if (err) {
+ TERM.stderr.writenl("\0red([sm] ERROR: Installing `sm` in your PATH! Try re-running with: \0bold(sudo " + COMMAND_PATH + " install-command\0)\0)");
+ return CLI.failAndExit(true);
+ }
+ TERM.stderr.writenl("\0green(`sm` has successfully been installed in your PATH!\0)");
+ process.exit(0);
+ });
+ });
+
+ return {
+ "install-command": command
+ };
+}
+
+
+exports.install = function(callback) {
+
+ function fail(err) {
+ TERM.stderr.writenl("\0red(" + err.stack + "\0)");
+ return callback(err, COMMAND_PATH);
+ }
+
+ function finalVerify() {
+ EXEC("which sm", function(error, stdout, stderr) {
+ if (error) {
+ return fail(new Error("`which sm` failed to foind `sm` on PATH."));
+ }
+ return callback(null);
+ });
+ }
+
+ try {
+
+ var binPath = getBinPath();
+
+ var commandPath = PATH.join(binPath, PATH.basename(COMMAND_PATH));
+
+ if (PATH.existsSync(commandPath)) {
+ if (FS.readlinkSync(commandPath) === COMMAND_PATH) {
+ return finalVerify();
+ }
+ FS.unlinkSync(commandPath);
+ }
+
+ FS.symlinkSync(COMMAND_PATH, commandPath);
+ FS.chmodSync(commandPath, 0755);
+ if (OS.isSudo()) {
+ FS.lchownSync(commandPath, parseInt(process.env.SUDO_UID), parseInt(process.env.SUDO_GID));
+ }
+
+ return finalVerify();
+
+ } catch(err) {
+ if (err.code === "EACCES") {
+ return fail(new Error("Permission denied! Could not install command at '" + commandPath + "'."));
+ } else {
+ return fail(err);
+ }
+ }
+}
+
+
+// @source npm
+function getBinPath() {
+ var prefixPath;
+ if (process.platform === "win32") {
+ // c:\node\node.exe --> prefix=c:\node\
+ prefixPath = PATH.join(process.execPath, "..");
+ } else {
+ // /usr/local/bin/node --> prefix=/usr/local
+ prefixPath = PATH.join(process.execPath, "..", "..");
+ }
+ var binPath = PATH.join(prefixPath, "bin");
+
+ // TODO: Fix this for windows.
+ var paths = process.env.PATH.split(":");
+
+ if (paths.indexOf(binPath) === -1) {
+ // don't assume node is on the user's path
+ var binPathDefault = "/usr/local/bin";
+ if (!PATH.existsSync(binPathDefault)) {
+ throw new Error("Did not find node-based bin path '" + binPath + "' nor default bin path '" + binPathDefault + "' on PATH '" + process.env.PATH + "'!");
+ }
+ binPath = binPathDefault;
+ }
+ return binPath;
+}
View
103 scripts/postinstall.js
@@ -1,87 +1,30 @@
-const PATH = require("path");
-const FS = require("fs");
const TERM = require("sourcemint-util-js/lib/term");
-const FS_RECURSIVE = require("sourcemint-util-js/lib/fs-recursive");
-const EXEC = require("child_process").exec;
-const ERROR = require("sourcemint-util-js/lib/error");
+const CLI = require("../lib/cli");
+const INSTALL_COMMAND = require("../lib/commands/install-command");
-TERM.stderr.writenl("\0yellow(Running as UID: " + process.getuid() + "\0)");
-TERM.stderr.writenl("\0yellow(Running as GID: " + process.getgid() + "\0)");
-
-EXEC("which sm", function(err, stdout, stderr) {
+INSTALL_COMMAND.install(function(err, commandPath) {
if (err) {
- TERM.stderr.writenl("\0red(ERROR: Could not find `sm` on your PATH (" + process.env.PATH + ")! NPM should have installed it.\0)");
- process.exit(1);
- return;
+ TERM.stderr.writenl([
+ "\0magenta(******************************************************************************************",
+ "",
+ "\0green( `sm` has been installed\0) \0red(\0bold(BUT not in your PATH!\0)\0)",
+ "",
+ "\0bold( Please add '" + commandPath + "' to your PATH.\0)",
+ "",
+ " Alternatively you can run the following:",
+ "",
+ " \0bold(sudo " + commandPath + " install-command\0)",
+ "",
+ "******************************************************************************************\0)"
+ ].join("\n"));
+ return CLI.failAndExit(true);
}
-
- var binPath = stdout.replace(/\n$/, "");
-
- EXEC(binPath + " --version", function(err, stdout, stderr) {
- if (err) {
- TERM.stderr.writenl("\0red(ERROR: '" + err + "' while running `" + binPath + " --version" + "`: " + stderr + "\0)");
- process.exit(1);
- return;
- }
-
- var installedVersion = stdout.replace(/\n$/, "");
-
- if (installedVersion !== process.env.npm_package_version) {
- TERM.stderr.writenl("\0red(ERROR: Installed `sm` at `which sm` (" + binPath + ") has version '" + installedVersion + "' which is NOT the version '" + process.env.npm_package_version + "' we just installed!\0)");
- process.exit(1);
- return;
- }
-
- var sourcePath = PATH.join(__dirname, "..");
-
- if (typeof process.env.SUDO_USER === "string" &&
- typeof process.env.SUDO_UID === "string" &&
- typeof process.env.SUDO_GID === "string") {
-
- if (process.getuid() !== 0 || process.getgid() !== 0 ) {
-
- TERM.stderr.writenl("\0magenta( !");
- TERM.stderr.writenl(" ! You are installing `sm` with `sudo` but NPM is configured to run post-install scripts (this script) as non-root!");
- TERM.stderr.writenl(" ! The way things are right now you need to use `sudo` to run `sm` commands which is not recommended.");
- TERM.stderr.writenl(" ! To fix this do one of:");
- TERM.stderr.writenl(" !");
- TERM.stderr.writenl(" ! 1) Re-configure NPM to run scripts as root: http://npmjs.org/doc/scripts.html#USER");
- TERM.stderr.writenl(" !");
- TERM.stderr.writenl(" ! sudo npm uninstall -g sm");
- TERM.stderr.writenl(" ! npm config set user 0");
- TERM.stderr.writenl(" ! npm config set unsafe-perm true");
- TERM.stderr.writenl(" ! sudo npm install -g sm");
- TERM.stderr.writenl(" !");
- TERM.stderr.writenl(" ! 2) Update ownership yourself:");
- TERM.stderr.writenl(" !");
- TERM.stderr.writenl(" ! sudo chown -Rf " + process.env.SUDO_UID + ":" + process.env.SUDO_GID + " " + sourcePath);
- TERM.stderr.writenl(" !");
- TERM.stderr.writenl(" Letting script exit with 0 even though setup is not ideal.\0)");
-
- process.exit(0);
- }
- else {
-
- TERM.stdout.writenl("\0cyan(`sm` was installed with sudo. Changing ownership of all files to user: " + process.env.SUDO_USER + " (" + process.env.SUDO_UID + ":" + process.env.SUDO_GID + ")\0)");
-
- TERM.stdout.writenl("\0cyan(chown " + process.env.SUDO_UID + ":" + process.env.SUDO_GID + " " + binPath + "\0)");
- FS.chownSync(binPath, parseInt(process.env.SUDO_UID), parseInt(process.env.SUDO_GID));
-
- TERM.stdout.writenl("\0cyan(chown -Rf " + process.env.SUDO_UID + ":" + process.env.SUDO_GID + " " + sourcePath + "\0)");
- EXEC("chown -R " + process.env.SUDO_UID + ":" + process.env.SUDO_GID + " " + sourcePath, function(err, stdout, stderr) {
- if (err) {
- TERM.stderr.writenl("\0red(ERROR: '" + err + "' while chowning files!\0)");
- process.exit(1);
- return;
- }
-
- TERM.stderr.writenl("\0magenta(You should now be able to run `sm` WITHOUT `sudo` for user '" + process.env.SUDO_USER + "'!\0)");
- process.exit(0);
- });
- }
- }
- });
+ TERM.stderr.writenl([
+ "",
+ "\0green(`sm` has successfully been installed in your PATH!\0)",
+ "\0green(To get started run: \0bold(sm -h\0)\0)",
+ ""
+ ].join("\n"));
});
-
Please sign in to comment.
Something went wrong with that request. Please try again.