1 // On windows, create a .cmd file.
2 // Read the #! in the file to see what it uses. The vast majority
3 // of the time, this will be either:
4 // "#!/usr/bin/env <prog> <args...>"
6 // "#!<prog> <args...>"
8 // Write a binroot/pkg.bin + ".cmd" file that has this line in it:
9 // @<prog> <args...> %~dp0<target> %*
11 module.exports = cmdShim
12 cmdShim.ifExists = cmdShimIfExists
14 var fs = require("graceful-fs")
16 var mkdir = require("mkdirp")
17 , path = require("path")
18 , shebangExpr = /^#\!\s*(?:\/usr\/bin\/env)?\s*([^ \t]+)(.*)$/
20 function cmdShimIfExists (from, to, cb) {
21 fs.stat(from, function (er) {
27 // Try to unlink, but ignore errors.
28 // Any problems will surface later.
29 function rm (path, cb) {
30 fs.unlink(path, function(er) {
35 function cmdShim (from, to, cb) {
36 fs.stat(from, function (er, stat) {
40 cmdShim_(from, to, cb)
44 function cmdShim_ (from, to, cb) {
45 var then = times(2, next, cb)
50 writeShim(from, to, cb)
54 function writeShim (from, to, cb) {
55 // make a cmd file and a sh script
56 // First, check if the bin is a #! of some sort.
57 // If not, then assume it's something that'll be compiled, or some other
58 // sort of script, and just call it directly.
59 mkdir(path.dirname(to), function (er) {
62 fs.readFile(from, "utf8", function (er, data) {
63 if (er) return writeShim_(from, to, null, null, cb)
64 var firstLine = data.trim().split(/\r*\n/)[0]
65 , shebang = firstLine.match(shebangExpr)
66 if (!shebang) return writeShim_(from, to, null, null, cb)
68 , args = shebang[2] || ""
69 return writeShim_(from, to, prog, args, cb)
74 function writeShim_ (from, to, prog, args, cb) {
75 var shTarget = path.relative(path.dirname(to), from)
76 , target = shTarget.split("/").join("\\")
78 , shProg = prog && prog.split("\\").join("/")
80 shTarget = shTarget.split("\\").join("/")
83 prog = "\"%~dp0\\" + target + "\""
84 shProg = "\"$basedir/" + shTarget + "\""
89 longProg = "\"%~dp0\\" + prog + ".exe\""
90 shLongProg = "\"$basedir/" + prog + "\""
91 target = "\"%~dp0\\" + target + "\""
92 shTarget = "\"$basedir/" + shTarget + "\""
95 // @IF EXIST "%~dp0\node.exe" (
96 // "%~dp0\node.exe" "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*
99 // SET PATHEXT=%PATHEXT:;.JS;=;%
100 // node "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*
104 cmd = "@IF EXIST " + longProg + " (\r\n"
105 + " " + longProg + " " + args + " " + target + " %*\r\n"
108 + " @SET PATHEXT=%PATHEXT:;.JS;=;%\r\n"
109 + " " + prog + " " + args + " " + target + " %*\r\n"
112 cmd = "@" + prog + " " + args + " " + target + " %*\r\n"
116 // basedir=`dirname "$0"`
119 // *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
122 // if [ -x "$basedir/node.exe" ]; then
123 // "$basedir/node.exe" "$basedir/node_modules/npm/bin/npm-cli.js" "$@"
126 // node "$basedir/node_modules/npm/bin/npm-cli.js" "$@"
131 var sh = "#!/bin/sh\n"
135 + "basedir=$(dirname \"$(echo \"$0\" | sed -e 's,\\\\,/,g')\")\n"
137 + "case `uname` in\n"
138 + " *CYGWIN*) basedir=`cygpath -w \"$basedir\"`;;\n"
143 + "if [ -x "+shLongProg+" ]; then\n"
144 + " " + shLongProg + " " + args + " " + shTarget + " \"$@\"\n"
147 + " " + shProg + " " + args + " " + shTarget + " \"$@\"\n"
152 sh = shProg + " " + args + " " + shTarget + " \"$@\"\n"
156 var then = times(2, next, cb)
157 fs.writeFile(to + ".cmd", cmd, "utf8", then)
158 fs.writeFile(to, sh, "utf8", then)
164 function chmodShim (to, cb) {
165 var then = times(2, cb, cb)
166 fs.chmod(to, 0755, then)
167 fs.chmod(to + ".cmd", 0755, then)
170 function times(n, ok, cb) {
172 return function(er) {