6 module.exports = exports = gyp
12 var fs = require('graceful-fs')
13 , path = require('path')
14 , nopt = require('nopt')
15 , log = require('npmlog')
16 , child_process = require('child_process')
17 , EE = require('events').EventEmitter
18 , inherits = require('util').inherits
20 // Module build commands
25 // Development Header File management commands
35 // differentiate node-gyp's logs from npm's
49 // set the dir where node-gyp dev files get installed
50 // TODO: make this *more* configurable?
51 // see: https://github.com/nodejs/node-gyp/issues/21
52 var homeDir = process.env.HOME || process.env.USERPROFILE
55 "node-gyp requires that the user's home directory is specified " +
56 "in either of the environmental variables HOME or USERPROFILE"
59 this.devDir = path.resolve(homeDir, '.node-gyp')
63 commands.forEach(function (command) {
64 self.commands[command] = function (argv, callback) {
65 log.verbose('command', command, argv)
66 return require('./' + command)(self, argv, callback)
72 var proto = Gyp.prototype
75 * Export the contents of the package.json.
78 proto.package = require('../package')
81 * nopt configuration definitions
85 help: Boolean // everywhere
86 , arch: String // 'configure'
87 , cafile: String // 'install'
88 , debug: Boolean // 'build'
89 , directory: String // bin
90 , make: String // 'build'
91 , msvs_version: String // 'configure'
92 , ensure: Boolean // 'install'
93 , solution: String // 'build' (windows only)
94 , proxy: String // 'install'
95 , nodedir: String // 'configure'
96 , loglevel: String // everywhere
97 , python: String // 'configure'
98 , 'dist-url': String // 'install'
99 , 'tarball': String // 'install'
100 , jobs: String // 'build'
101 , thin: String // 'configure'
109 release: '--no-debug'
113 , silly: '--loglevel=silly'
114 , verbose: '--loglevel=verbose'
115 , silent: '--loglevel=silent'
119 * expose the command aliases for the bin file to use.
122 proto.aliases = aliases
125 * Parses the given argv array and sets the 'opts',
126 * 'argv' and 'command' properties.
129 proto.parseArgv = function parseOpts (argv) {
130 this.opts = nopt(this.configDefs, this.shorthands, argv)
131 this.argv = this.opts.argv.remain.slice()
133 var commands = this.todo = []
135 // create a copy of the argv array with aliases mapped
136 argv = this.argv.map(function (arg) {
138 if (arg in this.aliases) {
139 arg = this.aliases[arg]
144 // process the mapped args into "command" objects ("name" and "args" props)
145 argv.slice().forEach(function (arg) {
146 if (arg in this.commands) {
147 var args = argv.splice(0, argv.indexOf(arg))
149 if (commands.length > 0) {
150 commands[commands.length - 1].args = args
152 commands.push({ name: arg, args: [] })
155 if (commands.length > 0) {
156 commands[commands.length - 1].args = argv.splice(0)
159 // support for inheriting config env variables from npm
160 var npm_config_prefix = 'npm_config_'
161 Object.keys(process.env).forEach(function (name) {
162 if (name.indexOf(npm_config_prefix) !== 0) return
163 var val = process.env[name]
164 if (name === npm_config_prefix + 'loglevel') {
167 // add the user-defined options to the config
168 name = name.substring(npm_config_prefix.length)
169 // gyp@741b7f1 enters an infinite loop when it encounters
170 // zero-length options so ensure those don't get through.
171 if (name) this.opts[name] = val
175 if (this.opts.loglevel) {
176 log.level = this.opts.loglevel
182 * Spawns a child process and emits a 'spawn' event.
185 proto.spawn = function spawn (command, args, opts) {
187 if (!opts.silent && !opts.stdio) {
188 opts.stdio = [ 0, 1, 2 ]
190 var cp = child_process.spawn(command, args, opts)
191 log.info('spawn', command)
192 log.info('spawn args', args)
197 * Returns the usage instructions for node-gyp.
200 proto.usage = function usage () {
203 , ' Usage: node-gyp <command> [options]'
205 , ' where <command> is one of:'
206 , commands.map(function (c) {
207 return ' - ' + c + ' - ' + require('./' + c).usage
210 , 'node-gyp@' + this.version + ' ' + path.resolve(__dirname, '..')
211 , 'node@' + process.versions.node
217 * Version number getter.
220 Object.defineProperty(proto, 'version', {
222 return this.package.version