-
Notifications
You must be signed in to change notification settings - Fork 63
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
Options Parser #118
Comments
Well the pocoo guys recently released a pretty awesome CLI API in Python. I think it's one of the cleanest APIs I've seen, but it makes heavy usage of annotations which are not available in JavaScript. One attempt at function annotation I've seen (in JavaScript) was in Angular.js. You can annotate using one of the following methods, array wrapper: var annotated = [annotation1, annotation2, annotation3, funcToAnnotate] and properties on function: funcToAnnotate.annotation1 = "..."
funcToAnnotate.annotation2 = "..."
// etc
function funcToAnnotate() {
} I think the second approach might be able to produce pretty clean results. /**
* ex: ls -l Folder/
* options: { l: true }
* text: "Folder/"
*/
function cmd(options, text) {
}
cmd.help = 'List stuff in a folder.'
cmd.options = {
'-l': {
help: 'Give more details.'
}
}
// call the cli API with the args and the annotated function.
cli(args, cmd); It could also be done with jQuery style chaining around a method, like so: var cmd = command(function (options, text) {
})
.help('List stuff in a folder.')
.option('-l', 'Gives more details', { extra: information })
// or
var cmd = command()
.help('List stuff in a folder.')
.option('-l', 'Gives more details', { extra: information })
.exec(function (options, text) {
})
// or
var cmd = command()
.help('List stuff in a folder.')
.option('-l', 'Gives more details', { extra: information })
{options,text} = cmd.exec(args) |
Nice, some good ideas, thanks @sbstp (^_^). I think to start with we want something pretty simple; we can always build it up or have another lib later. So, I prefer the latter style over trying to decorate function objects for now. I don't think we need to handle subcommands and stuff either yet,we can just let the user do it. So to expand on this with a more concrete example, maybe something like this: function main(args, opts)
{
// args is an object
var op = args.op;
var numbers = args.numbers;
var initValue = 0;
var fun;
// user has to do some validation
if (op === "plus")
fun = function(a, b){ return a + b};
else if (op === "minus")
fun = function(a, b){ return a - b};
else
throw "Expected \'plus\' or \'minus\'";
// opts is an object
if ("initValue" in opts)
initValue = Number(opts.initValue);
// numbers is an array
var result = numbers.reduce(fun, initValue);
print(result);
}
optParser()
.desc("A program to do something with numbers")
.arg("op", {
required : true,
desc : "The operation to apply."
})
// note the use of ... to consume the rest of the args
.arg("numbers...", {
required : true,
desc : "A list of numbers to operate on."
})
.opt("initValue", {
desc : "an initial value."
})
.exec(global.arguments, main); Later we could add more advanced features like being able to provide a validation function or list of good values for arguments, figuring out valid subcommand combos, checking/converting types for arguments. Whoever wants to tackle this can make the final call on how fancy they want to make it and what names they want to give everything, but it should provide a simple api for simple cases and only get more complex if needed. |
Not sure that I love the chaining notation, but that's not really relevant. You can support that notation without forcing people to use it. Having desc strings seems like a good idea. I'd suggest naming the library "options", not just "opt". |
@maximecb yea, should be easy to have it support just passing in an object that describes all the options and everything |
i think higgs itself should not include an option parser, as this sounds too "high level" to me.. i'd rather see higgs with a js core with just barebone functionalities and an officially supported separate package providing higher-level abstractions (akin to ruby's or go's stdlib) :) |
The options parser is going to be in a library. |
I'd like to maybe add "shebang" mode to Higgs as well as command-line mode. I'm guessing this might affect the options parser a bit. |
I added the shebang mode support a little while back: 165b3f8 |
Since @sbstp contributed an options parser, should we close this issue for now, reopen it later? |
There were still a few questions about the API (the error was fixed, but not the API). I could fix that before we close this issue. |
Which questions do you feel still need to be resolved? |
I created the singleton, but the way I created it conflicted with the way module are imported. Every time you'd |
Why modify the exports variable? The way modules work now, the library will only be loaded/initialized once. |
It was designed to be a constructor, so using it to instantiate an object and assigning it to |
Do eet |
Higgs allows users to pass arguments to scripts by including them after "--", like so:
However, this just provides an array of strings (in this case ["foo", "bar"]). Higgs should include a library that makes it easy for scripts to declare what arguments and options they take, which ones are required, etc. The library should then take an argument array like:
and produce an array of the arguments like:
as well as an opts object like
If all required args/options are not present an error should be thrown and/or a message displayed and the program exited.
A possible enhancement would be to take an optional description of what each option does, and use this to construct a "usage" message to display when no/incorrect args/opts are passed or the "-help" option is encountered.
Another possible enhancement would be to take an optional type for each arg/opt and then convert the argument/opt value to that type before passing it along to the library user, or an optional "converter function" to be applied to the opt/arg before passing it on to the library user.
Feedback for possible extra features, ideas for what the API should look like, and any other general thoughts are very welcome (^_^).
The text was updated successfully, but these errors were encountered: