Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add npm-exec(1) as command for executing dependency executables #3375

Closed
wants to merge 2 commits into from

3 participants

@samshull

There is always the chance that this functionality already exists in npm, if so, just close this and point me to it, thanks. This is intended to reproduce the basic functionality of bundle exec in npm.

There is a very good chance this is incomplete or incorrect in some way or another, but it works for the specific use case that it was written for: npm exec mocha -- --colors test/file.test.js.

There is also the question of how this should be handled from an API perspective. Should npm.exec use the directory of the package that it is referenced from or the package that it is referenced in? i.e.: I use npm.exec to execute an executable in my node_modules directory and the executable that is being executed wants to use npm.exec to execute an executable in it's own node_modules folder.

Hopefully, this commit will get the ball rolling on this discussion.

references #1543

@nathan7
Collaborator

First, awesome that someone's taking this on.

A few issues.
Using synchronous functions - not in line with the npm style guide.
We don't just use ./node_modules/.bin - we traverse all the way up, just like require does.

You should probably see #2460.

Sam Shull Be more npm-ish
- Use the path specified by npm.bin as the executable directory
- Don't use sync function
- Remove unecessary changes to child process environment and cwd
14401ba
@samshull

This should address most of the concerns raised by @isaacs in #2460, except:

For example, if you depend on grunt, and it's provided by a parent package's dependencies, then you won't be able to access the grunt binaries.
which is an issue that I referred to earlier in the pull request that I think should be discussed further.

It does change the behavior from #2460 slightly by only running if the referenced executable is in the package's own bin directory.

I also chose not to implement the completion for now.

@nathan7
Collaborator

This brings it exactly as far as #2460, which we aren't merging for the same reason.
Your code looks clean, so I might try sorting this based on your code.

@isaacs
Owner

The issue to target for this is #3313.

I'd like to make sure that npm exec scripts run exactly the same as lifecycle scripts (prepublish and test and such). Then, this would be the backing for npm run-script.

@isaacs isaacs closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 25, 2013
  1. Add npm-exec(1) as command for executing dependency executables

    Sam Shull authored
    references #1543
Commits on Apr 26, 2013
  1. Be more npm-ish

    Sam Shull authored
    - Use the path specified by npm.bin as the executable directory
    - Don't use sync function
    - Remove unecessary changes to child process environment and cwd
This page is out of date. Refresh to see the latest.
Showing with 64 additions and 0 deletions.
  1. +13 −0 doc/api/exec.md
  2. +15 −0 doc/cli/exec.md
  3. +35 −0 lib/exec.js
  4. +1 −0  lib/npm.js
View
13 doc/api/exec.md
@@ -0,0 +1,13 @@
+npm-exec(1) -- Execute a dependency supplied binary
+==================================================
+
+## SYNOPSIS
+
+ npm.exec(executable [, arguments])
+
+## DESCRIPTION
+
+This command will execute a executable from the executables made available by
+your package.json dependencies in the current working directory.
+Zero or more arguments to the executable may be supplied after the
+executable name.
View
15 doc/cli/exec.md
@@ -0,0 +1,15 @@
+npm-exec(1) -- Execute a dependency supplied executable
+=======================================================
+
+## SYNOPSIS
+
+ npm exec <executable>
+ npm exec <executable> -- <executable_arguments>
+
+## DESCRIPTION
+
+This command will execute an executable from the executables made available by
+your package.json dependencies in the current working directory.
+Arguments to the executable may be supplied after "--".
+
+
View
35 lib/exec.js
@@ -0,0 +1,35 @@
+module.exports = exec
+
+var child_process = require("child_process")
+ , fs = require("fs")
+ , path = require("path")
+ , npm = require("./npm.js")
+
+exec.usage = "npm exec <executable>"
+ + "\nnpm exec <executable> -- <executable_arguments>"
+
+function exec(args, cb) {
+ if (!args.length) return cb(exec.usage);
+
+ var executable_dir = npm.bin
+ , executable = path.basename(args[0])
+ , fullpath = path.join(executable_dir, executable)
+ , executable_args = args.slice(1)
+ , child
+
+ fs.exists(fullpath, function(exists) {
+ if (exists) {
+ child = child_process.spawn(fullpath, executable_args, { stdio: [0,1,2] })
+
+ child.on('error', function(error) {
+ cb(error)
+ })
+
+ child.on('exit', function() {
+ cb(null)
+ })
+ } else {
+ cb("Unable to find: " + executable + " in " + executable_dir)
+ }
+ })
+}
View
1  lib/npm.js
@@ -121,6 +121,7 @@ var commandCache = {}
, "submodule"
, "pack"
, "dedupe"
+ , "exec"
, "rebuild"
, "link"
Something went wrong with that request. Please try again.