UNPKG

13.2 kBJavaScriptView Raw
1"use strict";
2
3const path = require(`path`);
4
5const resolveCwd = require(`resolve-cwd`);
6
7const yargs = require(`yargs`);
8
9const report = require(`./reporter`);
10
11const _require = require(`./reporter/redux`),
12 setStore = _require.setStore;
13
14const didYouMean = require(`./did-you-mean`);
15
16const _require2 = require(`./util/version`),
17 getLocalGatsbyVersion = _require2.getLocalGatsbyVersion;
18
19const envinfo = require(`envinfo`);
20
21const existsSync = require(`fs-exists-cached`).sync;
22
23const clipboardy = require(`clipboardy`);
24
25const _require3 = require(`gatsby-telemetry`),
26 trackCli = _require3.trackCli,
27 setDefaultTags = _require3.setDefaultTags,
28 setTelemetryEnabled = _require3.setTelemetryEnabled;
29
30const handlerP = fn => (...args) => {
31 Promise.resolve(fn(...args)).then(() => process.exit(0), err => report.panic(err));
32};
33
34function buildLocalCommands(cli, isLocalSite) {
35 const defaultHost = `localhost`;
36 const directory = path.resolve(`.`); // 'not dead' query not available in browserslist used in Gatsby v1
37
38 const DEFAULT_BROWSERS = getLocalGatsbyMajorVersion() === 1 ? [`> 1%`, `last 2 versions`, `IE >= 9`] : [`>0.25%`, `not dead`];
39 let siteInfo = {
40 directory,
41 browserslist: DEFAULT_BROWSERS
42 };
43 const useYarn = existsSync(path.join(directory, `yarn.lock`));
44
45 if (isLocalSite) {
46 const json = require(path.join(directory, `package.json`));
47
48 siteInfo.sitePackageJson = json;
49 siteInfo.browserslist = json.browserslist || siteInfo.browserslist;
50 }
51
52 function getLocalGatsbyMajorVersion() {
53 let version = getLocalGatsbyVersion();
54
55 if (version) {
56 version = Number(version.split(`.`)[0]);
57 }
58
59 return version;
60 }
61
62 function resolveLocalCommand(command) {
63 if (!isLocalSite) {
64 cli.showHelp();
65 report.verbose(`current directory: ${directory}`);
66 return report.panic(`gatsby <${command}> can only be run for a gatsby site.\n` + `Either the current working directory does not contain a valid package.json or ` + `'gatsby' is not specified as a dependency`);
67 }
68
69 try {
70 const cmdPath = resolveCwd.silent(`gatsby/dist/commands/${command}`) || // Old location of commands
71 resolveCwd.silent(`gatsby/dist/utils/${command}`);
72 if (!cmdPath) return report.panic(`There was a problem loading the local ${command} command. Gatsby may not be installed in your site's "node_modules" directory. Perhaps you need to run "npm install"? You might need to delete your "package-lock.json" as well.`);
73 report.verbose(`loading local command from: ${cmdPath}`);
74 return require(cmdPath);
75 } catch (err) {
76 cli.showHelp();
77 return report.panic(`There was a problem loading the local ${command} command. Gatsby may not be installed. Perhaps you need to run "npm install"?`, err);
78 }
79 }
80
81 function getCommandHandler(command, handler) {
82 return argv => {
83 report.setVerbose(!!argv.verbose);
84 report.setNoColor(argv.noColor || process.env.NO_COLOR);
85 process.env.gatsby_log_level = argv.verbose ? `verbose` : `normal`;
86 report.verbose(`set gatsby_log_level: "${process.env.gatsby_log_level}"`);
87 process.env.gatsby_executing_command = command;
88 report.verbose(`set gatsby_executing_command: "${command}"`);
89 let localCmd = resolveLocalCommand(command);
90 let args = Object.assign({}, argv, {}, siteInfo, {
91 report,
92 useYarn,
93 setStore
94 });
95 report.verbose(`running command: ${command}`);
96 return handler ? handler(args, localCmd) : localCmd(args);
97 };
98 }
99
100 cli.command({
101 command: `develop`,
102 desc: `Start development server. Watches files, rebuilds, and hot reloads ` + `if something changes`,
103 builder: _ => _.option(`H`, {
104 alias: `host`,
105 type: `string`,
106 default: defaultHost,
107 describe: `Set host. Defaults to ${defaultHost}`
108 }).option(`p`, {
109 alias: `port`,
110 type: `string`,
111 default: `8000`,
112 describe: `Set port. Defaults to 8000`
113 }).option(`o`, {
114 alias: `open`,
115 type: `boolean`,
116 describe: `Open the site in your (default) browser for you.`
117 }).option(`S`, {
118 alias: `https`,
119 type: `boolean`,
120 describe: `Use HTTPS. See https://www.gatsbyjs.org/docs/local-https/ as a guide`
121 }).option(`c`, {
122 alias: `cert-file`,
123 type: `string`,
124 default: ``,
125 describe: `Custom HTTPS cert file (relative path; also required: --https, --key-file). See https://www.gatsbyjs.org/docs/local-https/`
126 }).option(`k`, {
127 alias: `key-file`,
128 type: `string`,
129 default: ``,
130 describe: `Custom HTTPS key file (relative path; also required: --https, --cert-file). See https://www.gatsbyjs.org/docs/local-https/`
131 }).option(`open-tracing-config-file`, {
132 type: `string`,
133 describe: `Tracer configuration file (OpenTracing compatible). See https://gatsby.dev/tracing`
134 }),
135 handler: handlerP(getCommandHandler(`develop`, (args, cmd) => {
136 process.env.NODE_ENV = process.env.NODE_ENV || `development`;
137 cmd(args); // Return an empty promise to prevent handlerP from exiting early.
138 // The development server shouldn't ever exit until the user directly
139 // kills it so this is fine.
140
141 return new Promise(resolve => {});
142 }))
143 });
144 cli.command({
145 command: `build`,
146 desc: `Build a Gatsby project.`,
147 builder: _ => _.option(`prefix-paths`, {
148 type: `boolean`,
149 default: false,
150 describe: `Build site with link paths prefixed (set pathPrefix in your gatsby-config.js).`
151 }).option(`no-uglify`, {
152 type: `boolean`,
153 default: false,
154 describe: `Build site without uglifying JS bundles (for debugging).`
155 }).option(`open-tracing-config-file`, {
156 type: `string`,
157 describe: `Tracer configuration file (OpenTracing compatible). See https://gatsby.dev/tracing`
158 }),
159 handler: handlerP(getCommandHandler(`build`, (args, cmd) => {
160 process.env.NODE_ENV = `production`;
161 return cmd(args);
162 }))
163 });
164 cli.command({
165 command: `serve`,
166 desc: `Serve previously built Gatsby site.`,
167 builder: _ => _.option(`H`, {
168 alias: `host`,
169 type: `string`,
170 default: defaultHost,
171 describe: `Set host. Defaults to ${defaultHost}`
172 }).option(`p`, {
173 alias: `port`,
174 type: `string`,
175 default: `9000`,
176 describe: `Set port. Defaults to 9000`
177 }).option(`o`, {
178 alias: `open`,
179 type: `boolean`,
180 describe: `Open the site in your (default) browser for you.`
181 }).option(`prefix-paths`, {
182 type: `boolean`,
183 default: false,
184 describe: `Serve site with link paths prefixed (if built with pathPrefix in your gatsby-config.js).`
185 }),
186 handler: getCommandHandler(`serve`)
187 });
188 cli.command({
189 command: `info`,
190 desc: `Get environment information for debugging and issue reporting`,
191 builder: _ => _.option(`C`, {
192 alias: `clipboard`,
193 type: `boolean`,
194 default: false,
195 describe: `Automagically copy environment information to clipboard`
196 }),
197 handler: args => {
198 try {
199 const copyToClipboard = // Clipboard is not accessible when on a linux tty
200 process.platform === `linux` && !process.env.DISPLAY ? false : args.clipboard;
201 envinfo.run({
202 System: [`OS`, `CPU`, `Shell`],
203 Binaries: [`Node`, `npm`, `Yarn`],
204 Browsers: [`Chrome`, `Edge`, `Firefox`, `Safari`],
205 Languages: [`Python`],
206 npmPackages: `gatsby*`,
207 npmGlobalPackages: `gatsby*`
208 }).then(envinfoOutput => {
209 console.log(envinfoOutput);
210
211 if (copyToClipboard) {
212 clipboardy.writeSync(envinfoOutput);
213 }
214 });
215 } catch (err) {
216 console.log(`Error: Unable to print environment info`);
217 console.log(err);
218 }
219 }
220 });
221 cli.command({
222 command: `clean`,
223 desc: `Wipe the local gatsby environment including built assets and cache`,
224 handler: getCommandHandler(`clean`)
225 });
226 cli.command({
227 command: `repl`,
228 desc: `Get a node repl with context of Gatsby environment, see (https://www.gatsbyjs.org/docs/gatsby-repl/)`,
229 handler: getCommandHandler(`repl`, (args, cmd) => {
230 process.env.NODE_ENV = process.env.NODE_ENV || `development`;
231 return cmd(args);
232 })
233 });
234}
235
236function isLocalGatsbySite() {
237 let inGatsbySite = false;
238
239 try {
240 let _require4 = require(path.resolve(`./package.json`)),
241 dependencies = _require4.dependencies,
242 devDependencies = _require4.devDependencies;
243
244 inGatsbySite = dependencies && dependencies.gatsby || devDependencies && devDependencies.gatsby;
245 } catch (err) {
246 /* ignore */
247 }
248
249 return !!inGatsbySite;
250}
251
252function getVersionInfo() {
253 const _require5 = require(`../package.json`),
254 version = _require5.version;
255
256 const isGatsbySite = isLocalGatsbySite();
257
258 if (isGatsbySite) {
259 // we need to get the version from node_modules
260 let gatsbyVersion = getLocalGatsbyVersion();
261
262 if (!gatsbyVersion) {
263 gatsbyVersion = `unknown`;
264 }
265
266 return `Gatsby CLI version: ${version}
267Gatsby version: ${gatsbyVersion}
268 Note: this is the Gatsby version for the site at: ${process.cwd()}`;
269 } else {
270 return `Gatsby CLI version: ${version}`;
271 }
272}
273
274module.exports = argv => {
275 let cli = yargs();
276 let isLocalSite = isLocalGatsbySite();
277 cli.scriptName(`gatsby`).usage(`Usage: $0 <command> [options]`).alias(`h`, `help`).alias(`v`, `version`).option(`verbose`, {
278 default: false,
279 type: `boolean`,
280 describe: `Turn on verbose output`,
281 global: true
282 }).option(`no-color`, {
283 alias: `no-colors`,
284 default: false,
285 type: `boolean`,
286 describe: `Turn off the color in output`,
287 global: true
288 }).option(`json`, {
289 describe: `Turn on the JSON logger`,
290 default: false,
291 type: `boolean`,
292 global: true
293 });
294 buildLocalCommands(cli, isLocalSite);
295
296 try {
297 const _require6 = require(`../package.json`),
298 version = _require6.version;
299
300 cli.version(`version`, `Show the version of the Gatsby CLI and the Gatsby package in the current project`, getVersionInfo());
301 setDefaultTags({
302 gatsbyCliVersion: version
303 });
304 } catch (e) {// ignore
305 }
306
307 trackCli(argv);
308 return cli.command({
309 command: `new [rootPath] [starter]`,
310 desc: `Create new Gatsby project.`,
311 handler: handlerP(({
312 rootPath,
313 starter
314 }) => {
315 const initStarter = require(`./init-starter`);
316
317 return initStarter(starter, {
318 rootPath
319 });
320 })
321 }).command(`plugin`, `Useful commands relating to Gatsby plugins`, yargs => yargs.command({
322 command: `docs`,
323 desc: `Helpful info about using and creating plugins`,
324 handler: handlerP(() => console.log(`
325Using a plugin:
326- What is a Plugin? (https://www.gatsbyjs.org/docs/what-is-a-plugin/)
327- Using a Plugin in Your Site (https://www.gatsbyjs.org/docs/using-a-plugin-in-your-site/)
328- What You Don't Need Plugins For (https://www.gatsbyjs.org/docs/what-you-dont-need-plugins-for/)
329- Loading Plugins from Your Local Plugins Folder (https://www.gatsbyjs.org/docs/loading-plugins-from-your-local-plugins-folder/)
330- Plugin Library (https://www.gatsbyjs.org/plugins/)
331
332Creating a plugin:
333- Naming a Plugin (https://www.gatsbyjs.org/docs/naming-a-plugin/)
334- Files Gatsby Looks for in a Plugin (https://www.gatsbyjs.org/docs/files-gatsby-looks-for-in-a-plugin/)
335- Creating a Local Plugin (https://www.gatsbyjs.org/docs/creating-a-local-plugin/)
336- Creating a Source Plugin (https://www.gatsbyjs.org/docs/creating-a-source-plugin/)
337- Creating a Transformer Plugin (https://www.gatsbyjs.org/docs/creating-a-transformer-plugin/)
338- Submit to Plugin Library (https://www.gatsbyjs.org/contributing/submit-to-plugin-library/)
339- Pixabay Source Plugin Tutorial (https://www.gatsbyjs.org/docs/pixabay-source-plugin-tutorial/)
340- Maintaining a Plugin (https://www.gatsbyjs.org/docs/maintaining-a-plugin/)
341- Join Discord #plugin-authoring channel to ask questions! (https://gatsby.dev/discord/)
342 `))
343 }).demandCommand(1, `Pass --help to see all available commands and options.`)).command({
344 command: `telemetry`,
345 desc: `Enable or disable Gatsby anonymous analytics collection.`,
346 builder: yargs => yargs.option(`enable`, {
347 type: `boolean`,
348 description: `Enable telemetry (default)`
349 }).option(`disable`, {
350 type: `boolean`,
351 description: `Disable telemetry`
352 }),
353 handler: handlerP(({
354 enable,
355 disable
356 }) => {
357 const enabled = enable || !disable;
358 setTelemetryEnabled(enabled);
359 report.log(`Telemetry collection ${enabled ? `enabled` : `disabled`}`);
360 })
361 }).wrap(cli.terminalWidth()).demandCommand(1, `Pass --help to see all available commands and options.`).strict().fail((msg, err, yargs) => {
362 const availableCommands = yargs.getCommands().map(commandDescription => {
363 const command = commandDescription[0];
364 return command.split(` `)[0];
365 });
366 const arg = argv.slice(2)[0];
367 const suggestion = arg ? didYouMean(arg, availableCommands) : ``;
368 cli.showHelp();
369 report.log(suggestion);
370 report.log(msg);
371 }).parse(argv.slice(2));
372};
\No newline at end of file