Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Devex: Wrapper for node:utils parseArgs #5606

Merged
merged 11 commits into from
Dec 6, 2024
Merged

Conversation

jimlerza
Copy link
Collaborator

@jimlerza jimlerza commented Nov 27, 2024

Argument Parser for Shell Scripts Written in TypeScript

We have several scripts now that use node:utils parseArgs to parse command-line arguments, and it works great! Unfortunately, however, the scripts that use it have to implement a ton of code, to the extent that in some cases the code to configure and utilize parseArgs ends up being longer than the rest of the script combined.

Here I've written a wrapper that we can call that does all of that work for us, and centralizes some of the text transformation stuff we were slapping on afterwards.

How to Use the Argument Parser in a Shell Script

Let's say you want the $1 (first positional) argument to be required and you want to optionally support two additional arguments. Now you can just put this at the top of your script:

const scriptConfig: ScriptConfig = {
  description: 'some-script.ts - works wonders',
  parameters: {
    eventCode: {
      position: 0,
      required: true,
      type: 'string',
    },
    fiscal: {
      default: false,
      short: 'f',
      type: 'boolean',
    },
    year: {
      default: '2024',
      short: 'y',
      transform: 'number',
      type: 'string',
    },
  },
};

And then elsewhere in the script you can get the values thusly:

const { eventCode, fiscal, year } = parseArguments(scriptConfig);

In Action

Given the configuration above, say you call your script like so:

npx ts-node --transpile-only scripts/some-script.ts NOA -f

The argument parser will return the following:

{
  eventCode: 'NOA',
  fiscal: true,
  year: 2024,
};

Self-Documenting

All scripts that utilize the argument parser will get a --help flag that, when provided, will output usage information automatically generated from the ScriptConfig configuration object.

Again, given the configuration above, say you call your script like so:

npx ts-node --transpile-only scripts/some-script.ts --help

The argument parser will print the following:

some-script.ts - works wonders

Usage: some-script.ts <eventCode> [ -f -y <year> ]

…here were non-required positionals...it turns out parseArgs can handle those just fine. Also added some documentation in the ScriptConfig and ScriptParameter type definitions where appropriate.
@jimlerza jimlerza marked this pull request as ready for review December 3, 2024 16:53
Copy link
Collaborator

@jtdevos jtdevos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Jim, this is great. In my mind it's a big improvement over the built-in parseArgs because it allows for more config info (e.g. description) and makes the process for accessing values similar regardless if they are named or positional arguments.

I guess my only comment is that your excellent write-up of this is relegated to this pull-request. I know that we are relatively anti jsdoc here, but might be nice to capture the descriptions & examples from your PR into the reportUtils.ts file.

@jimlerza
Copy link
Collaborator Author

jimlerza commented Dec 5, 2024

Hey Jim, this is great. In my mind it's a big improvement over the built-in parseArgs because it allows for more config info (e.g. description) and makes the process for accessing values similar regardless if they are named or positional arguments.

I guess my only comment is that your excellent write-up of this is relegated to this pull-request. I know that we are relatively anti jsdoc here, but might be nice to capture the descriptions & examples from your PR into the reportUtils.ts file.

Great points!

I have added more JSDoc to the types and I have also created a readme for the argument parser (which is basically just the content from this PR description, reworded to be less salesy).

Copy link
Contributor

@En-8 En-8 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😍

@jimlerza jimlerza merged commit 71ac1e6 into staging Dec 6, 2024
44 checks passed
@jimlerza jimlerza deleted the devex-argument-parser branch December 6, 2024 18:08
@jimlerza jimlerza mentioned this pull request Dec 6, 2024
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants