export function parseCliArgs()

in packages/@aws-cdk/integ-runner/lib/cli.ts [18:99]


export function parseCliArgs(args: string[] = []) {
  const argv = yargs
    .usage('Usage: integ-runner [TEST...]')
    .option('config', {
      config: true,
      configParser: configFromFile,
      default: 'integ.config.json',
      desc: 'Load options from a JSON config file. Options provided as CLI arguments take precedent.',
    })
    .option('watch', { type: 'boolean', default: false, desc: 'Perform integ tests in watch mode' })
    .option('list', { type: 'boolean', default: false, desc: 'List tests instead of running them' })
    .option('clean', { type: 'boolean', default: true, desc: 'Skips stack clean up after test is completed (use --no-clean to negate)' })
    .option('verbose', { type: 'boolean', default: false, alias: 'v', count: true, desc: 'Verbose logs and metrics on integration tests durations (specify multiple times to increase verbosity)' })
    .option('dry-run', { type: 'boolean', default: false, desc: 'do not actually deploy the stack. just update the snapshot (not recommended!)' })
    .option('update-on-failed', { type: 'boolean', default: false, desc: 'rerun integration tests and update snapshots for failed tests.' })
    .option('force', { type: 'boolean', default: false, desc: 'Rerun all integration tests even if tests are passing' })
    .option('parallel-regions', { type: 'array', desc: 'Tests are run in parallel across these regions. To prevent tests from running in parallel, provide only a single region', default: [] })
    .options('directory', { type: 'string', default: 'test', desc: 'starting directory to discover integration tests. Tests will be discovered recursively from this directory' })
    .options('profiles', { type: 'array', desc: 'list of AWS profiles to use. Tests will be run in parallel across each profile+regions', default: [] })
    .options('max-workers', { type: 'number', desc: 'The max number of workerpool workers to use when running integration tests in parallel', default: 16 })
    .options('exclude', { type: 'boolean', desc: 'Run all tests in the directory, except the specified TESTs', default: false })
    .options('from-file', { type: 'string', desc: 'Read TEST names from a file (one TEST per line)' })
    .option('inspect-failures', { type: 'boolean', desc: 'Keep the integ test cloud assembly if a failure occurs for inspection', default: false })
    .option('disable-update-workflow', { type: 'boolean', default: false, desc: 'If this is "true" then the stack update workflow will be disabled' })
    .option('language', {
      alias: 'l',
      default: ['javascript', 'typescript', 'python', 'go'],
      choices: ['javascript', 'typescript', 'python', 'go'],
      type: 'array',
      nargs: 1,
      desc: 'Use these presets to run integration tests for the selected languages',
    })
    .option('app', { type: 'string', default: undefined, desc: 'The custom CLI command that will be used to run the test files. You can include {filePath} to specify where in the command the test file path should be inserted. Example: --app="python3.8 {filePath}".' })
    .option('test-regex', { type: 'array', desc: 'Detect integration test files matching this JavaScript regex pattern. If used multiple times, all files matching any one of the patterns are detected.', default: [] })
    .strict()
    .parse(args);

  const tests: string[] = argv._;
  const parallelRegions = arrayFromYargs(argv['parallel-regions']);
  const testRegions: string[] = parallelRegions ?? ['us-east-1', 'us-east-2', 'us-west-2'];
  const profiles = arrayFromYargs(argv.profiles);
  const fromFile: string | undefined = argv['from-file'];
  const maxWorkers: number = argv['max-workers'];
  const verbosity: number = argv.verbose;
  const verbose: boolean = verbosity >= 1;

  const numTests = testRegions.length * (profiles ?? [1]).length;
  if (maxWorkers < numTests) {
    logger.warning('You are attempting to run %s tests in parallel, but only have %s workers. Not all of your profiles+regions will be utilized', numTests, maxWorkers);
  }

  if (tests.length > 0 && fromFile) {
    throw new Error('A list of tests cannot be provided if "--from-file" is provided');
  }
  const requestedTests = fromFile
    ? (fs.readFileSync(fromFile, { encoding: 'utf8' })).split('\n').filter(x => x)
    : (tests.length > 0 ? tests : undefined); // 'undefined' means no request

  return {
    tests: requestedTests,
    app: argv.app as (string | undefined),
    testRegex: arrayFromYargs(argv['test-regex']),
    testRegions,
    originalRegions: parallelRegions,
    profiles,
    runUpdateOnFailed: (argv['update-on-failed'] ?? false) as boolean,
    fromFile,
    exclude: argv.exclude as boolean,
    maxWorkers,
    list: argv.list as boolean,
    directory: argv.directory as string,
    inspectFailures: argv['inspect-failures'] as boolean,
    verbosity,
    verbose,
    clean: argv.clean as boolean,
    force: argv.force as boolean,
    dryRun: argv['dry-run'] as boolean,
    disableUpdateWorkflow: argv['disable-update-workflow'] as boolean,
    language: arrayFromYargs(argv.language),
    watch: argv.watch as boolean,
  };
}