text: "use strict";
  
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  
  exports.__esModule = true;
  exports.createCli = void 0;
  
  var _path = _interopRequireDefault(require("path"));
  
  var _resolveCwd = _interopRequireDefault(require("resolve-cwd"));
  
  var _yargs = _interopRequireDefault(require("yargs"));
  
  var _reporter = _interopRequireDefault(require("./reporter"));
  
  var _redux = require("./reporter/redux");
  
  var _version = require("./util/version");
  
  var _envinfo = _interopRequireDefault(require("envinfo"));
  
  var _fsExistsCached = require("fs-exists-cached");
  
  var _clipboardy = _interopRequireDefault(require("clipboardy"));
  
  var _gatsbyTelemetry = require("gatsby-telemetry");
  
  var _initStarter = require("./init-starter");
  
  var _recipes = require("./recipes");
  
  const handlerP = fn => (...args) => {
    Promise.resolve(fn(...args)).then(() => process.exit(0), err => _reporter.default.panic(err));
  };
  
  function buildLocalCommands(cli, isLocalSite) {
    const defaultHost = `localhost`;
    const defaultPort = `8000`;
  
    const directory = _path.default.resolve(`.`); // 'not dead' query not available in browserslist used in Gatsby v1
  
  
    const DEFAULT_BROWSERS = getLocalGatsbyMajorVersion() === 1 ? [`> 1%`, `last 2 versions`, `IE >= 9`] : [`>0.25%`, `not dead`];
    const siteInfo = {
      directory,
      browserslist: DEFAULT_BROWSERS,
      sitePackageJson: undefined
    };
    const useYarn = (0, _fsExistsCached.sync)(_path.default.join(directory, `yarn.lock`));
  
    if (isLocalSite) {
      const json = require(_path.default.join(directory, `package.json`));
  
      siteInfo.sitePackageJson = json;
      siteInfo.browserslist = json.browserslist || siteInfo.browserslist;
    }
  
    function getLocalGatsbyMajorVersion() {
      const version = (0, _version.getLocalGatsbyVersion)();
  
      if (version) {
        return Number(version.split(`.`)[0]);
      }
  
      return undefined;
    }
  
    function resolveLocalCommand(command) {
      if (!isLocalSite) {
        cli.showHelp();
  
        _reporter.default.verbose(`current directory: ${directory}`);
  
        return _reporter.default.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`);
      }
  
      try {
        const cmdPath = _resolveCwd.default.silent(`gatsby/dist/commands/${command}`) || // Old location of commands
        _resolveCwd.default.silent(`gatsby/dist/utils/${command}`);
  
        if (!cmdPath) return _reporter.default.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.`);
  
        _reporter.default.verbose(`loading local command from: ${cmdPath}`);
  
        const cmd = require(cmdPath);
  
        if (cmd instanceof Function) {
          return cmd;
        }
  
        return _reporter.default.panic(`Handler for command "${command}" is not a function. Your Gatsby package might be corrupted, try reinstalling it and running the command again.`);
      } catch (err) {
        cli.showHelp();
        return _reporter.default.panic(`There was a problem loading the local ${command} command. Gatsby may not be installed. Perhaps you need to run "npm install"?`, err);
      }
    }
  
    function getCommandHandler(command, handler) {
      return argv => {
        _reporter.default.setVerbose(!!argv.verbose);
  
        _reporter.default.setNoColor(!!(argv.noColor || process.env.NO_COLOR));
  
        process.env.gatsby_log_level = argv.verbose ? `verbose` : `normal`;
  
        _reporter.default.verbose(`set gatsby_log_level: "${process.env.gatsby_log_level}"`);
  
        process.env.gatsby_executing_command = command;
  
        _reporter.default.verbose(`set gatsby_executing_command: "${command}"`);
  
        const localCmd = resolveLocalCommand(command);
        const args = { ...argv,
          ...siteInfo,
          report: _reporter.default,
          useYarn,
          setStore: _redux.setStore
        };
  
        _reporter.default.verbose(`running command: ${command}`);
  
        return handler ? handler(args, localCmd) : localCmd(args);
      };
    }
  
    cli.command({
      command: `develop`,
      describe: `Start development server. Watches files, rebuilds, and hot reloads ` + `if something changes`,
      builder: _ => _.option(`H`, {
        alias: `host`,
        type: `string`,
        default: defaultHost,
        describe: `Set host. Defaults to ${defaultHost}`
      }).option(`p`, {
        alias: `port`,
        type: `string`,
        default: process.env.PORT || defaultPort,
        describe: process.env.PORT ? `Set port. Defaults to ${process.env.PORT} (set by env.PORT) (otherwise defaults ${defaultPort})` : `Set port. Defaults to ${defaultPort}`
      }).option(`o`, {
        alias: `open`,
        type: `boolean`,
        describe: `Open the site in your (default) browser for you.`
      }).option(`S`, {
        alias: `https`,
        type: `boolean`,
        describe: `Use HTTPS. See https://www.gatsbyjs.org/docs/local-https/ as a guide`
      }).option(`c`, {
        alias: `cert-file`,
        type: `string`,
        default: ``,
        describe: `Custom HTTPS cert file (also required: --https, --key-file). See https://www.gatsbyjs.org/docs/local-https/`
      }).option(`k`, {
        alias: `key-file`,
        type: `string`,
        default: ``,
        describe: `Custom HTTPS key file (also required: --https, --cert-file). See https://www.gatsbyjs.org/docs/local-https/`
      }).option(`ca-file`, {
        type: `string`,
        default: ``,
        describe: `Custom HTTPS CA certificate file (also required: --https, --cert-file, --key-file).  See https://www.gatsbyjs.org/docs/local-https/`
      }).option(`graphql-tracing`, {
        type: `boolean`,
        describe: `Trace every graphql resolver, may have performance implications`,
        default: false
      }).option(`open-tracing-config-file`, {
        type: `string`,
        describe: `Tracer configuration file (OpenTracing compatible). See https://gatsby.dev/tracing`
      }),
      handler: handlerP(getCommandHandler(`develop`, (args, cmd) => {
        process.env.NODE_ENV = process.env.NODE_ENV || `development`;
        cmd(args); // Return an empty promise to prevent handlerP from exiting early.
        // The development server shouldn't ever exit until the user directly
        // kills it so this is fine.
  
        return new Promise(() => {});
      }))
    });
    cli.command({
      command: `build`,
      describe: `Build a Gatsby project.`,
      builder: _ => _.option(`prefix-paths`, {
        type: `boolean`,
        default: process.env.PREFIX_PATHS === `true` || process.env.PREFIX_PATHS === `1`,
        describe: `Build site with link paths prefixed with the pathPrefix value in gatsby-config.js. Default is env.PREFIX_PATHS or false.`
      }).option(`no-uglify`, {
        type: `boolean`,
        default: false,
        describe: `Build site without uglifying JS bundles (for debugging).`
      }).option(`profile`, {
        type: `boolean`,
        default: false,
        describe: `Build site with react profiling (this can add some additional overhead). See https://reactjs.org/docs/profiler`
      }).option(`graphql-tracing`, {
        type: `boolean`,
        describe: `Trace every graphql resolver, may have performance implications`,
        default: false
      }).option(`open-tracing-config-file`, {
        type: `string`,
        describe: `Tracer configuration file (OpenTracing compatible). See https://gatsby.dev/tracing`
      }) // log-pages and write-to-file are specific to experimental GATSBY_EXPERIMENTAL_PAGE_BUILD_ON_DATA_CHANGES feature
      // because of that they are hidden from `--help` but still defined so `yargs` know about them
      .option(`log-pages`, {
        type: `boolean`,
        default: false,
        describe: `Log the pages that changes since last build (only available when using GATSBY_EXPERIMENTAL_PAGE_BUILD_ON_DATA_CHANGES).`,
        hidden: true
      }).option(`write-to-file`, {
        type: `boolean`,
        default: false,
        describe: `Save the log of changed pages for future comparison (only available when using GATSBY_EXPERIMENTAL_PAGE_BUILD_ON_DATA_CHANGES).`,
        hidden: true
      }),
      handler: handlerP(getCommandHandler(`build`, (args, cmd) => {
        process.env.NODE_ENV = `production`;
        return cmd(args);
      }))
    });
    cli.command({
      command: `serve`,
      describe: `Serve previously built Gatsby site.`,
      builder: _ => _.option(`H`, {
        alias: `host`,
        type: `string`,
        default: defaultHost,
        describe: `Set host. Defaults to ${defaultHost}`
      }).option(`p`, {
        alias: `port`,
        type: `string`,
        default: `9000`,
        describe: `Set port. Defaults to 9000`
      }).option(`o`, {
        alias: `open`,
        type: `boolean`,
        describe: `Open the site in your (default) browser for you.`
      }).option(`prefix-paths`, {
        type: `boolean`,
        default: process.env.PREFIX_PATHS === `true` || process.env.PREFIX_PATHS === `1`,
        describe: `Serve site with link paths prefixed with the pathPrefix value in gatsby-config.js.Default is env.PREFIX_PATHS or false.`
      }),
      handler: getCommandHandler(`serve`)
    });
    cli.command({
      command: `info`,
      describe: `Get environment information for debugging and issue reporting`,
      builder: _ => _.option(`C`, {
        alias: `clipboard`,
        type: `boolean`,
        default: false,
        describe: `Automagically copy environment information to clipboard`
      }),
      handler: args => {
        try {
          const copyToClipboard = // Clipboard is not accessible when on a linux tty
          process.platform === `linux` && !process.env.DISPLAY ? false : args.clipboard;
  
          _envinfo.default.run({
            System: [`OS`, `CPU`, `Shell`],
            Binaries: [`Node`, `npm`, `Yarn`],
            Browsers: [`Chrome`, `Edge`, `Firefox`, `Safari`],
            Languages: [`Python`],
            npmPackages: `gatsby*`,
            npmGlobalPackages: `gatsby*`
          }).then(envinfoOutput => {
            console.log(envinfoOutput);
  
            if (copyToClipboard) {
              _clipboardy.default.writeSync(envinfoOutput);
            }
          });
        } catch (err) {
          console.log(`Error: Unable to print environment info`);
          console.log(err);
        }
      }
    });
    cli.command({
      command: `feedback`,
      builder: _ => _.option(`disable`, {
        type: `boolean`,
        describe: `Opt out of future feedback requests`
      }).option(`enable`, {
        type: `boolean`,
        describe: `Opt into future feedback requests`
      }),
      handler: getCommandHandler(`feedback`)
    });
    cli.command({
      command: `clean`,
      describe: `Wipe the local gatsby environment including built assets and cache`,
      handler: getCommandHandler(`clean`)
    });
    cli.command({
      command: `repl`,
      describe: `Get a node repl with context of Gatsby environment, see (https://www.gatsbyjs.org/docs/gatsby-repl/)`,
      handler: getCommandHandler(`repl`, (args, cmd) => {
        process.env.NODE_ENV = process.env.NODE_ENV || `development`;
        return cmd(args);
      })
    });
    cli.command({
      command: `recipes [recipe]`,
      describe: `[EXPERIMENTAL] Run a recipe`,
      handler: handlerP(async ({
        recipe
      }) => {
        await (0, _recipes.recipesHandler)(recipe);
      })
    });
  }
  
  function isLocalGatsbySite() {
    let inGatsbySite = false;
  
    try {
      const {
        dependencies,
        devDependencies
      } = require(_path.default.resolve(`./package.json`));
  
      inGatsbySite = dependencies && dependencies.gatsby || devDependencies && devDependencies.gatsby;
    } catch (err) {
      /* ignore */
    }
  
    return !!inGatsbySite;
  }
  
  function getVersionInfo() {
    const {
      version
    } = require(`../package.json`);
  
    const isGatsbySite = isLocalGatsbySite();
  
    if (isGatsbySite) {
      // we need to get the version from node_modules
      let gatsbyVersion = (0, _version.getLocalGatsbyVersion)();
  
      if (!gatsbyVersion) {
        gatsbyVersion = `unknown`;
      }
  
      return `Gatsby CLI version: ${version}
  Gatsby version: ${gatsbyVersion}
    Note: this is the Gatsby version for the site at: ${process.cwd()}`;
    } else {
      return `Gatsby CLI version: ${version}`;
    }
  }
  
  const createCli = argv => {
    const cli = (0, _yargs.default)(argv).parserConfiguration({
      "boolean-negation": false
    });
    const isLocalSite = isLocalGatsbySite();
    cli.scriptName(`gatsby`).usage(`Usage: $0 <command> [options]`).alias(`h`, `help`).alias(`v`, `version`).option(`verbose`, {
      default: false,
      type: `boolean`,
      describe: `Turn on verbose output`,
      global: true
    }).option(`no-color`, {
      alias: `no-colors`,
      default: false,
      type: `boolean`,
      describe: `Turn off the color in output`,
      global: true
    }).option(`json`, {
      describe: `Turn on the JSON logger`,
      default: false,
      type: `boolean`,
      global: true
    });
    buildLocalCommands(cli, isLocalSite);
  
    try {
      const {
        version
      } = require(`../package.json`);
  
      cli.version(`version`, `Show the version of the Gatsby CLI and the Gatsby package in the current project`, getVersionInfo());
      (0, _gatsbyTelemetry.setDefaultTags)({
        gatsbyCliVersion: version
      });
    } catch (e) {// ignore
    }
  
    (0, _gatsbyTelemetry.trackCli)(argv);
    return cli.command({
      command: `new [rootPath] [starter]`,
      describe: `Create new Gatsby project.`,
      handler: handlerP(async ({
        rootPath,
        starter
      }) => {
        const starterStr = starter ? String(starter) : undefined;
        const rootPathStr = rootPath ? String(rootPath) : undefined;
        await (0, _initStarter.initStarter)(starterStr, rootPathStr);
      })
    }).command(`plugin`, `Useful commands relating to Gatsby plugins`, yargs => yargs.command({
      command: `docs`,
      describe: `Helpful info about using and creating plugins`,
      handler: handlerP(() => console.log(`
  Using a plugin:
  - What is a Plugin? (https://www.gatsbyjs.org/docs/what-is-a-plugin/)
  - Using a Plugin in Your Site (https://www.gatsbyjs.org/docs/using-a-plugin-in-your-site/)
  - What You Don't Need Plugins For (https://www.gatsbyjs.org/docs/what-you-dont-need-plugins-for/)
  - Loading Plugins from Your Local Plugins Folder (https://www.gatsbyjs.org/docs/loading-plugins-from-your-local-plugins-folder/)
  - Plugin Library (https://www.gatsbyjs.org/plugins/)
  
  Creating a plugin:
  - Naming a Plugin (https://www.gatsbyjs.org/docs/naming-a-plugin/)
  - Files Gatsby Looks for in a Plugin (https://www.gatsbyjs.org/docs/files-gatsby-looks-for-in-a-plugin/)
  - Creating a Generic Plugin (https://www.gatsbyjs.org/docs/creating-a-generic-plugin/)
  - Creating a Local Plugin (https://www.gatsbyjs.org/docs/creating-a-local-plugin/)
  - Creating a Source Plugin (https://www.gatsbyjs.org/docs/creating-a-source-plugin/)
  - Creating a Transformer Plugin (https://www.gatsbyjs.org/docs/creating-a-transformer-plugin/)
  - Submit to Plugin Library (https://www.gatsbyjs.org/contributing/submit-to-plugin-library/)
  - Source Plugin Tutorial (https://www.gatsbyjs.org/tutorial/source-plugin-tutorial/)
  - Maintaining a Plugin (https://www.gatsbyjs.org/docs/maintaining-a-plugin/)
  - Join Discord #plugin-authoring channel to ask questions! (https://gatsby.dev/discord/)
            `))
    }).demandCommand(1, `Pass --help to see all available commands and options.`)).command({
      command: `telemetry`,
      describe: `Enable or disable Gatsby anonymous analytics collection.`,
      builder: yargs => yargs.option(`enable`, {
        type: `boolean`,
        description: `Enable telemetry (default)`
      }).option(`disable`, {
        type: `boolean`,
        description: `Disable telemetry`
      }),
      handler: handlerP(({
        enable,
        disable
      }) => {
        const enabled = enable || !disable;
        (0, _gatsbyTelemetry.setTelemetryEnabled)(enabled);
  
        _reporter.default.log(`Telemetry collection ${enabled ? `enabled` : `disabled`}`);
      })
    }).wrap(cli.terminalWidth()).demandCommand(1, `Pass --help to see all available commands and options.`).strict().recommendCommands().parse(argv.slice(2));
  };
  
  exports.createCli = createCli;