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

Committing not to ever use a description field / maybe reserving some other fields for future use #86

Open
bakkot opened this issue Mar 20, 2022 · 3 comments

Comments

@bakkot
Copy link
Collaborator

bakkot commented Mar 20, 2022

Right now, parseArgs is not going to generate usage text for you. I think that's sensible. But it's an obvious thing to want, so I imagine someone's going to make a library which takes the options specification and generates help text. The way I imagine that working is that it would take exactly the same options config, but each option would additionally have a description field, and possibly others. That is:

let { makeUsage } = require('some-userland-library');
let { parseArgs } = require('util');

let options = {
  foo: {
    type: 'string',
    description: 'A metavariable.',
  },
  bar: {
    type: 'string',
    description: 'A measure of music.',
  },
  help: {
    type: 'boolean',
    description: 'Display this message.',
  },
};

let parsed = parseArgs({ options });

if (parsed.values.help) {
  console.log(makeUsage({ options }));
  process.exit(0);
}

// etc

The thing to note here is that I expect such usage-generating libraries to be passed the same object as parseArgs, because that's by far the most convenient thing for script authors. But it would (in my imagining) also look at some additional keys currently ignored by parseArgs, at the very least description.

If and when such libraries exist and are in common use, that means parseArgs is never going to be able to use any such additional keys for its own purposes - that would be a breaking change, because the script author did not intend parseArgs to read the descriptions. A particularly cautious library author might want to refrain from using extra fields for that reason, though I am sure not everyone will be that cautious, so such libraries will almost certainly exist regardless.

As such, I think it makes sense to decide now if there are any fields like this which parseArgs wants to commit to not using, so that such userland libraries can use those fields without worrying about that breaking parseArgs later.

And, conversely, if there are fields (possibly default?) which parseArgs might want to make use of later, but which a library built on top of parseArgs might start using for their own purposes, it might make sense to reserve those fields somehow - either just in the description of parseArgs, or (more aggressively) by actively throwing if those fields exist.

@shadowspawn
Copy link
Collaborator

The property conflict issue is also true of every class that gets offered by Node.js and used for subclassing, such as Error. Are there some patterns already in use there? (I have not noticed any.) Is it just be aware that every addition of a property is a potentially breaking change and can only occur in a major version?

I wondered about reserving a property or prefix for third-party additions, which I have seen used in some APIs. A little clunky but offers safety. And library writers are not compelled to follow the convention. (But I don't think it is the best pattern here.)

Say "extra" was reserved for third-party use:

  foo: {
    type: 'string',
    extra: { description: 'A metavariable.' },
  },

The tradeoffs of properties reserved for future parseArgs use vs reserved for library authors depend somewhat on which is more active. In particular, I am uncertain whether there will be much development in parseArgs itself after a base version is available in Node.js! So leaving it free-for-all for library authors might be the most pragmatic.

@shadowspawn
Copy link
Collaborator

Are there some patterns already in use there?

Ah, Stability Index.

https://nodejs.org/dist/latest-v17.x/docs/api/documentation.html#stability-index

@hildjj
Copy link

hildjj commented Jun 16, 2022

If the people building the usage-generating library export a Symbol for their extension properties, they're guaranteed not to cause issues in the future. Yes, that's not as convenient for their users, but it's not that much more to type.

let { description, makeUsage } = require('some-userland-library');
let { parseArgs } = require('util');

let options = {
  foo: {
    type: 'string',
    [description]: 'A metavariable.',
  },
...
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants