arcanis / clipanion

Type-safe CLI library / framework with no runtime dependencies
https://mael.dev/clipanion/
1.12k stars 65 forks source link

RFC: What if we didn't use decorators? #50

Closed arcanis closed 4 years ago

arcanis commented 4 years ago

My idea is, what if we were to replace:

class MyCommand extends Command {
  @Command.Boolean(`-v,--verbose`)
  verbose: boolean = false;

  @Command.String(`--email`)
  email?: string;

  @Command.String()
  name!: string;

  async execute() {
    console.log(this.verbose);
    console.log(this.email);
    console.log(this.name);
  }
}

By the following:

class MyCommand extends Command {
  verbose = Command.Boolean(`-v,--verbose`, false);
  email = Command.String(`--email`);
  name = Command.String();

  async execute() {
    console.log(this.verbose.value);
    console.log(this.email.value);
    console.log(this.name.value);
  }
}

Presumably, the Command.Boolean function would be implemented kinda like this:

function Boolean(name: string): OptionProperty<boolean> {
  return {
    value: undefined as any as boolean,
    definition(...) {
      ...
    }
    transformer(state, command) {
      command[propertyName].value = true;
    }
  };
}

And on setup, instead of instantiating one command, the runner would first instantiate them all (in order to call the install property from each option), but would only call the execute method on the one that would end up being used (it would probably create a fresh one, since instantiation should be fairly cheap anyway).

Benefits I can see:

Of course, this would be a change worth of a major bump.

yoannmoinet commented 4 years ago

I loved using decorators where possible, because it was highly readable and the proximity of it was on point. But, I feel like it is a fairly obscure feature of the language still, and only possible in a specific context. So it was possibly inaccessible for some users, and the documentation had to be divergent in some places.

I'm all for the new design, it checks all the boxes IMHO.

Good idea 👍

arcanis commented 4 years ago

Implemented in #53

kevinkhill commented 4 years ago

I like how I landed on this, when the docs are describing how to use v3 but the library is still on v2!

A little bewildering when the exmaples throw all sorts of TS errors.

I switched back to the decorators for now and patiently await :smile:

arcanis commented 4 years ago

Good point, I'll add a note about this in the readme 😅

kevinkhill commented 4 years ago

BTW, I like the new syntax and have been using this for some time now. Great library!