xref: /expo/packages/@expo/cli/src/utils/args.ts (revision d566f199)
1// Common utilities for interacting with `args` library.
2// These functions should be used by every command.
3import arg from 'arg';
4import { existsSync } from 'fs';
5import { resolve } from 'path';
6
7import * as Log from '../log';
8
9/**
10 * Parse the first argument as a project directory.
11 *
12 * @returns valid project directory.
13 */
14export function getProjectRoot(args: arg.Result<arg.Spec>) {
15  const projectRoot = resolve(args._[0] || '.');
16
17  if (!existsSync(projectRoot)) {
18    Log.exit(`Invalid project root: ${projectRoot}`);
19  }
20
21  return projectRoot;
22}
23
24/**
25 * Parse args and assert unknown options.
26 *
27 * @param schema the `args` schema for parsing the command line arguments.
28 * @param argv extra strings
29 * @returns processed args object.
30 */
31export function assertArgs(schema: arg.Spec, argv?: string[]): arg.Result<arg.Spec> {
32  return assertWithOptionsArgs(schema, { argv });
33}
34
35export function assertWithOptionsArgs(
36  schema: arg.Spec,
37  options: arg.Options
38): arg.Result<arg.Spec> {
39  try {
40    return arg(schema, options);
41  } catch (error: any) {
42    // Ensure unknown options are handled the same way.
43    if (error.code === 'ARG_UNKNOWN_OPTION') {
44      Log.exit(error.message, 1);
45    }
46    // Otherwise rethrow the error.
47    throw error;
48  }
49}
50