Giter Club home page Giter Club logo

Comments (4)

arcanis avatar arcanis commented on August 23, 2024

When using proxies, non-proxy arguments must be specified before the last path component (and thus require at least one path component). This is because we otherwise have no way to know whether -C was intended for the command or whatever it proxies (while it's perhaps not an issue for options like -C, it starts being a bit weird when you have things like --version, --verbose, or --help).

from clipanion.

lordofthelake avatar lordofthelake commented on August 23, 2024

I see. It makes sense, although it was not obvious from the docs.

What I was trying to achieve here is to have a modular CLI where plugins that defined more commands could be loaded at runtime from a configuration file.

So my attempt so far looked something like this simplified version:

import { Command, Option, Cli } from "clipanion";
import path from "path";

class ConfigLoaderCommand extends Command {
  static paths = [Command.Default];

  configPath = Option.String("-C,--config", {
    description: "configuration to load",
  });

  args = Option.Proxy();

  async execute(): Promise<void> {
    // load the configuration from the current folder
    const config = require(path.resolve(this.configPath ?? "mycommand.config.js"))
    
    // build a CLI instance with all the plugins loaded
    const innerCli = new Cli()
    for(const command of config.plugins) {
    	cli.register(command);
    }
    
    // pass everything down to the built instance
    await innerCli.runExit(args, { ...this.context});
  }
}

const [, , ...args] = process.argv;

const cli = new Cli();
cli.register(ConfigLoaderCommand);
cli.runExit(args, Cli.defaultContext);

This did the job, except for the inability of reading -C (unless you want to parse it manually before handing over the other args to Clipanion).

I had made a version that uses Option.Rest(), which didn't have this problem, but has trouble with --help and other built-in flags.

Do you have any suggestions about what could be a better way of achieving this with Clipanion? Really loved the library so far, but hit a bit of a wall here. If there was an option of stopping the automatic handling of --help and similar from the outer CLI command, I guess Rest() would have worked here..? (Is there a way to disable that?)

from clipanion.

arcanis avatar arcanis commented on August 23, 2024

You have a few options, but with their own drawbacks:

  • You can add a path; so instead of my-cli -C config arg1 arg2 ... you require my-cli -C config run arg1 arg2 ...
  • You can parse the -C option yourself (but it's not super pretty, of course)
  • You can use Option.Rest, and require your users to explicitly pass -- if they wish to proxy option arguments

Generally though, there's no way to keep parsing options once we may be inside a proxy, especially since we don't know for sure how the nested arguments will be parsed (for instance, if I write --foo -C config, perhaps the nested CLI would interpret it as --foo=-C config rather than --foo -C=config).

from clipanion.

lordofthelake avatar lordofthelake commented on August 23, 2024

Thanks for taking the time for the detailed response.

I ended up adding a light layer pre-parsing using arg and I'm doing some work to augment the help command so that my "global options" are shown there as well. It's not super pretty, but I think that it's probably the most transparent option for the end-user.

I'm going to close this issue because as it is it's not actionable. Thanks for the help!

from clipanion.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.