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

Parser generator #4

Open
clo4 opened this issue Aug 21, 2022 · 2 comments
Open

Parser generator #4

clo4 opened this issue Aug 21, 2022 · 2 comments
Milestone

Comments

@clo4
Copy link
Owner

clo4 commented Aug 21, 2022

Fig specs are essentially a grammar definition as JSON. The parser isn't optimal for every CLI because it has to be general enough to run them all, but a parser generator can create the optimal parser for each CLI.

I want this to be seamless. It should feel like no effort at all to set it up for your project. Not sure exactly how this will look right now

@clo4 clo4 added this to the 0.2 milestone Aug 24, 2022
@clo4
Copy link
Owner Author

clo4 commented Aug 30, 2022

This is the current idea that I have... I don't love it. Too complicated.

.
|- deno.json      // defines the build task
|- main.ts        // defines actions for commands, imports _parser.js
|- cli
|  |- spec.ts     // the spec definition file, purely declarative
|  |- _parser.js  // generated parser

@clo4
Copy link
Owner Author

clo4 commented Jan 18, 2023

The main problem I have with this right now is that it separates the business logic from the CLI itself. This is probably okay but the possible DX is just worse imo.
The generated CLI either needs to be imported from the main file then have you hook into it so you can tell it what to run for each command, or have some kind of way to invoke an external function itself which feels too magical.

// cli_def.ts
import compile from "...";

compile("./cli_gen.ts", {
  name: "test",
  action: true,
  subcommands: [
    { name: "another", action: true },
  ],
});
// main.ts
import CLI from "./cli_gen.ts";

CLI.run({
  test: () => {},
  another: () => {},
});

I don't love this

What if instead main can also lazily define the CLI, so when called with a special command it'll compile instead of running

Keeps the definition and everything in one file, but introduces a bootstrapping problem

// main.ts
import CLI from "./cli_gen.ts";

CLI.spec("./cli_gen.ts", () => ({
  name: "something",
  subcommands: [
    { name: "wow" },
    { name: "non_idiomatic_name", run: "nonIdiomaticName" },
  ],
}));

CLI.run({
  something: () => {},
  wow: () => {},
  nonIdiomaticName: () => {},
});

This is maybe cleaner but it could get really bad for larger specs

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

No branches or pull requests

1 participant