Initial commit
[yaffs-website] / node_modules / node-gyp / lib / node-gyp.js
1
2 /**
3  * Module exports.
4  */
5
6 module.exports = exports = gyp
7
8 /**
9  * Module dependencies.
10  */
11
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
19   , commands = [
20       // Module build commands
21         'build'
22       , 'clean'
23       , 'configure'
24       , 'rebuild'
25       // Development Header File management commands
26       , 'install'
27       , 'list'
28       , 'remove'
29     ]
30   , aliases = {
31         'ls': 'list'
32       , 'rm': 'remove'
33     }
34
35 // differentiate node-gyp's logs from npm's
36 log.heading = 'gyp'
37
38 /**
39  * The `gyp` function.
40  */
41
42 function gyp () {
43   return new Gyp()
44 }
45
46 function Gyp () {
47   var self = this
48
49   this.devDir = ''
50   this.commands = {}
51
52   commands.forEach(function (command) {
53     self.commands[command] = function (argv, callback) {
54       log.verbose('command', command, argv)
55       return require('./' + command)(self, argv, callback)
56     }
57   })
58 }
59 inherits(Gyp, EE)
60 exports.Gyp = Gyp
61 var proto = Gyp.prototype
62
63 /**
64  * Export the contents of the package.json.
65  */
66
67 proto.package = require('../package')
68
69 /**
70  * nopt configuration definitions
71  */
72
73 proto.configDefs = {
74     help: Boolean     // everywhere
75   , arch: String      // 'configure'
76   , cafile: String    // 'install'
77   , debug: Boolean    // 'build'
78   , directory: String // bin
79   , make: String      // 'build'
80   , msvs_version: String // 'configure'
81   , ensure: Boolean   // 'install'
82   , solution: String  // 'build' (windows only)
83   , proxy: String     // 'install'
84   , devdir: String   // everywhere
85   , nodedir: String   // 'configure'
86   , loglevel: String  // everywhere
87   , python: String    // 'configure'
88   , 'dist-url': String // 'install'
89   , 'tarball': String // 'install'
90   , jobs: String      // 'build'
91   , thin: String      // 'configure'
92 }
93
94 /**
95  * nopt shorthands
96  */
97
98 proto.shorthands = {
99     release: '--no-debug'
100   , C: '--directory'
101   , debug: '--debug'
102   , j: '--jobs'
103   , silly: '--loglevel=silly'
104   , verbose: '--loglevel=verbose'
105   , silent: '--loglevel=silent'
106 }
107
108 /**
109  * expose the command aliases for the bin file to use.
110  */
111
112 proto.aliases = aliases
113
114 /**
115  * Parses the given argv array and sets the 'opts',
116  * 'argv' and 'command' properties.
117  */
118
119 proto.parseArgv = function parseOpts (argv) {
120   this.opts = nopt(this.configDefs, this.shorthands, argv)
121   this.argv = this.opts.argv.remain.slice()
122
123   var commands = this.todo = []
124
125   // create a copy of the argv array with aliases mapped
126   argv = this.argv.map(function (arg) {
127     // is this an alias?
128     if (arg in this.aliases) {
129       arg = this.aliases[arg]
130     }
131     return arg
132   }, this)
133
134   // process the mapped args into "command" objects ("name" and "args" props)
135   argv.slice().forEach(function (arg) {
136     if (arg in this.commands) {
137       var args = argv.splice(0, argv.indexOf(arg))
138       argv.shift()
139       if (commands.length > 0) {
140         commands[commands.length - 1].args = args
141       }
142       commands.push({ name: arg, args: [] })
143     }
144   }, this)
145   if (commands.length > 0) {
146     commands[commands.length - 1].args = argv.splice(0)
147   }
148
149   // support for inheriting config env variables from npm
150   var npm_config_prefix = 'npm_config_'
151   Object.keys(process.env).forEach(function (name) {
152     if (name.indexOf(npm_config_prefix) !== 0) return
153     var val = process.env[name]
154     if (name === npm_config_prefix + 'loglevel') {
155       log.level = val
156     } else {
157       // add the user-defined options to the config
158       name = name.substring(npm_config_prefix.length)
159       // gyp@741b7f1 enters an infinite loop when it encounters
160       // zero-length options so ensure those don't get through.
161       if (name) this.opts[name] = val
162     }
163   }, this)
164
165   if (this.opts.loglevel) {
166     log.level = this.opts.loglevel
167   }
168   log.resume()
169 }
170
171 /**
172  * Spawns a child process and emits a 'spawn' event.
173  */
174
175 proto.spawn = function spawn (command, args, opts) {
176   if (!opts) opts = {}
177   if (!opts.silent && !opts.stdio) {
178     opts.stdio = [ 0, 1, 2 ]
179   }
180   var cp = child_process.spawn(command, args, opts)
181   log.info('spawn', command)
182   log.info('spawn args', args)
183   return cp
184 }
185
186 /**
187  * Returns the usage instructions for node-gyp.
188  */
189
190 proto.usage = function usage () {
191   var str = [
192       ''
193     , '  Usage: node-gyp <command> [options]'
194     , ''
195     , '  where <command> is one of:'
196     , commands.map(function (c) {
197         return '    - ' + c + ' - ' + require('./' + c).usage
198       }).join('\n')
199     , ''
200     , 'node-gyp@' + this.version + '  ' + path.resolve(__dirname, '..')
201     , 'node@' + process.versions.node
202   ].join('\n')
203   return str
204 }
205
206 /**
207  * Version number getter.
208  */
209
210 Object.defineProperty(proto, 'version', {
211     get: function () {
212       return this.package.version
213     }
214   , enumerable: true
215 })
216