UNPKG

6 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3'use strict';
4var gutil = require('gulp-util');
5var prettyTime = require('pretty-hrtime');
6var chalk = require('chalk');
7var semver = require('semver');
8var archy = require('archy');
9var Liftoff = require('liftoff');
10var tildify = require('tildify');
11var v8flags = require('v8flags');
12var completion = require('../util/completion');
13var argv = require('minimist')(process.argv.slice(2));
14var taskTree = require('../util/task-tree');
15
16// Set env var for ORIGINAL cwd
17// before anything touches it
18process.env.INIT_CWD = process.cwd();
19
20var cli = new Liftoff({
21 name: 'pomy',
22 completions: completion,
23 v8flags: v8flags,
24 processTitle: 'pomy',
25 moduleName: 'pomy',
26 configName: 'pomy',
27 extensions: {
28 '.json': null
29 }
30});
31
32// Exit with 0 or 1
33var failed = false;
34process.once('exit', function(code) {
35 if (code === 0 && failed) {
36 process.exit(1);
37 }
38});
39
40// Parse those args m8
41var cliPackage = require('../package');
42var versionFlag = argv.v || argv.version;
43var tasksFlag = argv.T || argv.tasks;
44var tasks = argv._;
45var toRun = tasks.length ? tasks : ['default'];
46
47// This is a hold-over until we have a better logging system
48// with log levels
49var simpleTasksFlag = argv['tasks-simple'];
50var shouldLog = !argv.silent && !simpleTasksFlag;
51
52if (!shouldLog) {
53 gutil.log = function() {};
54}
55
56cli.on('require', function(name) {
57 gutil.log('Requiring external module', chalk.magenta(name));
58});
59
60cli.on('requireFail', function(name) {
61 gutil.log(chalk.red('Failed to load external module'), chalk.magenta(name));
62});
63
64cli.on('respawn', function(flags, child) {
65 var nodeFlags = chalk.magenta(flags.join(', '));
66 var pid = chalk.magenta(child.pid);
67 gutil.log('Node flags detected:', nodeFlags);
68 gutil.log('Respawned to PID:', pid);
69});
70
71cli.launch({
72 cwd: argv.cwd,
73 configPath: argv.configPath,
74 require: argv.require,
75 completion: argv.completion,
76}, handleArguments);
77
78// The actual logic
79function handleArguments(env) {
80
81 if (versionFlag && tasks.length === 0) {
82 gutil.log('CLI version', cliPackage.version);
83 if (env.modulePackage && typeof env.modulePackage.version !== 'undefined') {
84 gutil.log('Local version', env.modulePackage.version);
85 }
86 process.exit(0);
87 }
88
89 var archetype = false;
90 if (tasks.length === 1 && tasks[0].indexOf('archetype:') === 0) {
91 archetype = true;
92 }
93
94 if (!env.modulePath) {
95 gutil.log(
96 chalk.red('Local pomy not found in'),
97 chalk.magenta(tildify(env.cwd))
98 );
99 gutil.log(chalk.red('Try running: npm install pomy'));
100 process.exit(1);
101 }
102
103 if (!archetype && !env.configPath) {
104 gutil.log(chalk.red('No pomy.json found'));
105 process.exit(1);
106 }
107
108 // Check for semver difference between cli and local installation
109 if (semver.gt(cliPackage.version, env.modulePackage.version)) {
110 gutil.log(chalk.red('Warning: pomy version mismatch:'));
111 gutil.log(chalk.red('Global pomy is', cliPackage.version));
112 gutil.log(chalk.red('Local pomy is', env.modulePackage.version));
113 }
114
115 // Chdir before requiring pomy.json to make sure
116 // we let them chdir as needed
117 if (process.cwd() !== env.cwd) {
118 process.chdir(env.cwd);
119 gutil.log(
120 'Working directory changed to',
121 chalk.magenta(tildify(env.cwd))
122 );
123 }
124
125 // This is what actually loads up the pomy.json
126 // require(env.configPath);
127 if (!archetype) {
128 gutil.log('Using pomy.json', chalk.magenta(tildify(env.configPath)));
129 }
130
131 var pomyInst = require(env.modulePath);
132 logEvents(pomyInst);
133
134 process.nextTick(function() {
135 if (simpleTasksFlag) {
136 return logTasksSimple(env, pomyInst);
137 }
138 if (tasksFlag) {
139 return logTasks(env, pomyInst);
140 }
141
142 if (tasks.length > 1) {
143 switch (tasks[0]) {
144 case 'install':
145 case 'uninstall':
146 toRun = ['bower:' + tasks[0]];
147 break;
148 case 'bower:install':
149 case 'bower:uninstall':
150 toRun = [tasks[0]];
151 case 'update':
152 case 'bower:update':
153 toRun = tasks.slice(0, 1);
154 break;
155 default:
156 break;
157 }
158 }
159 pomyInst.start.apply(pomyInst, toRun);
160 });
161}
162
163function logTasks(env, localGulp) {
164 var tree = taskTree(localGulp.tasks);
165 tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath));
166 archy(tree)
167 .split('\n')
168 .forEach(function(v) {
169 if (v.trim().length === 0) {
170 return;
171 }
172 gutil.log(v);
173 });
174}
175
176function logTasksSimple(env, localGulp) {
177 console.log(Object.keys(localGulp.tasks)
178 .join('\n')
179 .trim());
180}
181
182// Format orchestrator errors
183function formatError(e) {
184 if (!e.err) {
185 return e.message;
186 }
187
188 // PluginError
189 if (typeof e.err.showStack === 'boolean') {
190 return e.err.toString();
191 }
192
193 // Normal error
194 if (e.err.stack) {
195 return e.err.stack;
196 }
197
198 // Unknown (string, number, etc.)
199 return new Error(String(e.err)).stack;
200}
201
202// Wire up logging events
203function logEvents(pomyInst) {
204
205 // Total hack due to poor error management in orchestrator
206 pomyInst.on('err', function() {
207 failed = true;
208 });
209
210 pomyInst.on('task_start', function(e) {
211 // TODO: batch these
212 // so when 5 tasks start at once it only logs one time with all 5
213 gutil.log('Starting', '\'' + chalk.cyan(e.task) + '\'...');
214 });
215
216 pomyInst.on('task_stop', function(e) {
217 var time = prettyTime(e.hrDuration);
218 gutil.log(
219 'Finished', '\'' + chalk.cyan(e.task) + '\'',
220 'after', chalk.magenta(time)
221 );
222 });
223
224 pomyInst.on('task_err', function(e) {
225 var msg = formatError(e);
226 var time = prettyTime(e.hrDuration);
227 gutil.log(
228 '\'' + chalk.cyan(e.task) + '\'',
229 chalk.red('errored after'),
230 chalk.magenta(time)
231 );
232 gutil.log(msg);
233 });
234
235 pomyInst.on('task_not_found', function(err) {
236 gutil.log(
237 chalk.red('Task \'' + err.task + '\' is not in your gulpfile')
238 );
239 gutil.log('Please check the documentation for proper gulpfile formatting');
240 process.exit(1);
241 });
242}
\No newline at end of file