Passing arguments to Node.js program - node.js

I'm trying to pass 2 mandatory arguments for a Node.js program I'm creating.
I'm using Yargs to do it like this:
const yarg = require("yargs")
.usage("hi")
.options("m", {demandOption: true})
.options("m2", {demandOption: true})
.argv;
This works fine with a slight issue. I want to activate the script like this:
node index.js -m val -m2 val2
It doesn't work and I get an error saying m2 is missing. Only when I add another - before m2 it works, meaning I have to do it like this:
node index.js -m val1 --m2 val2
Is there a way to make it accept the args like I wanted to in the first place?

You can't do what you're asking for with yargs, and arguably you shouldn't. It's easy to see why you can't by looking at what yargs-parser (the module yargs uses to parse your arguments) returns for the different argument styles you mentioned:
console.log(yargsParser(['-m', 'A']));
console.log(yargsParser(['-m2', 'B']));
console.log(yargsParser(['--m2', 'C']));
<script src="https://bundle.run/yargs-parser#11.1.1"></script>
As you can see:
-m A is parsed as option m with value A.
-m2 B is parsed as option m with value 2 and, separately, array parameter B.
--m2 C is parsed as option m2 with value C.
There is not a way to make the parser behave differently. This is with good reason: Most command line tools (Windows notwithstanding) behave this way.
By decades-old convention, "long" options use two dashes followed by a human-readable name, like --max-count. "Short" options, which are often aliases for long ones, use a single dash followed by a single character, like -m, and—this is the crucial bit—if the option takes a value, the space between the option and the value can be omitted. This is why when yargs sees -m2, it assumes 2 is the value for the m option.
If you want to use yargs (and not confuse command line-savvy users) you'll you need to change your options to either 1. --m and --m2 or, 2. -m and (for example) -n.

Related

Why is this branch always true using clap 4?

I would like to have a command line in Rust using clap 4 which allows this:
app --wait
If --wait is present start a function. If is NOT present do nothing.
I'm trying the below code with no luck: the if command.contains_id("wait") is always true! With or without --wait as argument, why?
let command = Command::new("")
.arg(
Arg::new("wait")
.long("wait")
.required(false)
.num_args(0)
.help("Wait..."),
)
.get_matches();
if command.contains_id("wait") {
do_wait().await;
}
From the clap4 documentation for default_value:
Value for the argument when not present.
NOTE: If the user does not use this argument at runtime ArgMatches::contains_id will still return true. If you wish to determine whether the argument was used at runtime or not, consider ArgMatches::value_source.
So it would seem that default_value is taking affect. Why?
I'm not completely certain but it would seem that Arg::new uses defaults from Arg::default. This defaults default_vals to an empty vec, which wouldn't work on anything other than num_args(0), but does work in your case b/c you have no args.
So it looks like your solution is to use value_source instead of contains_id, however you should not use num_args like this.
Instead use .action(ArgAction::SetTrue) like so:
Arg::new("wait")
.long("wait")
.action(ArgAction::SetTrue)
.help("Wait ...")
See the flags section here for more details.

What are valid characters and how to escape in clap.rs arguments?

I want to pass in some shape or form a dictionary/map/object into my clap app. I can preprocess the dict to turn it into some csv or whatever. My problem is that I cannot find in clap docs which characters are valid for the argument values and how to escape them. Is this unrelated to clap and instead shell specific?
Can I pass something like
myApp --dicty="a=1,b=3,qwe=yxc"
?
Is this unrelated to clap and instead shell specific?
Mostly, yes. clap is going to get whatever arguments the shell has determined and will parse that.
However clap has built-in support for value sets, from the readme:
Supports multiple values (i.e. -o <val1> -o <val2> or -o <val1> <val2>)
Supports delimited values (i.e. -o=val1,val2,val3, can also change the delimiter)
If that's not sufficient, then you'll have to define dicty as a String, you will receive the string a=1,b=3,qwe=yxc (I don't think you'll receive the quotes) then you'll have to parse that yourself, either by hand (regex/split/...) or with something more advanced (e.g. the csv crate though that's likely overkill).
That seems like a somewhat odd option value though.
FWIW structopt (which builds upon clap to provide a more declarative UI, and should be part of Clap 3) doesn't exactly have support for that sort of things but can be coerced into it relatively easily: https://github.com/TeXitoi/structopt/blob/master/examples/keyvalue.rs
With some modifications would allow something like
myApp -D a=1 -D b=3 -D que=yxc
or (though see comments in linked snippet for limitations)
myApp -D a=1 b=3 que=yxc
to be collected as a vec![("a", "1"), ("b", "3"), ("que", "yxc")] from which creating a hashmap is trivial.

NodeJS: how disable auto output after every line in console?

As u can see on the image, after every line, an automatic output appears. I want do disable this. I do not intend to use it as a workaround editor, the problem is that on some functions this output is more than some screens big and is hard to look at the expected result.
The default CLI, IIRC, uses the standard Node REPL, but does not provide a trivial way to customize it.
You could start your own REPL and provide options as described in the REPL docs, specifically focusing on:
eval
ignoreUndefined
The easiest solution is to append something to whatever is returning the long value, e.g., if there's a function called foo that returns an object that spans pages, like:
> foo()
// countless lines of output
Tack on something to the command, like:
> foo(); null
null

How to to pass a string to function arguments in python3

I'm building a command-line interface using the argparse library to parse user input. At one stage, I'd like to take user input such as "'test', x=False" and use it in a function such as func('test', x=False).
I've tried using ast.literal_eval to do this but it encounters a syntax error at the equals sign. (I did ast.literal_eval("("+args+")") where args was above example)
Does anyone know of a safe way to parse the user input like that? Preferably without eval although worst-case scenario I could use eval as, well, it's a CLI tool.
Edit (to people that have said to use input manually(): I need the tool to parse input from when the command is run (it's a python module that I want to be able to be called like python3 -m hmcli.raw --args "'test', x=False" where the args can be flexible as the function used can differ.

python argparse add_argument_group required

In this question
argparse: require either of two arguments
I find a reference to the solution I want, but it isn't right.
I need at least 1 of 2 options to be present, option1, option2 or both...
The add_argument_group function doesn't have a required argument.
The add_mutually_exclusive function has it, but it forces me to choose between the 2 options, which is not what I want.
rds,
argument_group just controls the help display. It does not affect the parsing or check for errors. mutually_exclusive_group affects usage display and tests for occurrence, but as you note, its logic is not what you want.
There is a Python bug issue requesting some form of nested 'inclusive' group. But a general form that allows nesting and all versions of and/or/xor logic is not a trivial addition.
I think your simplest solution is to test the args after parsing. If there is a wrong mix of defaults, then raise an error.
Assuming the default for both arguments is None:
if args.option1 is None and args.option2 is None:
parser.error('at least one of option1 and option2 is required')
What would be meaningful usage line? required mutually exclusive' uses(opt1 | opt2).(opt1 & opt2)might indicate that both are required. Your case is anon-exclusive or`
usage: PROG [-h] (--opt1 OPT1 ? --opt2 OPT2)

Resources