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