Running a scopt option with no values - scala

I am writing a CLI in Scala using Scopt.
I would like to add in the ability to call a command with or without the values.
For example:
CliUtility -o <value> <value> <value>
Would send in a Seq[String] of the values.
I want to also be able to run -o
CliUtility -o
I want that to send an empty Seq[String] but I can't see how to handle this.
Thank you.

From the examples on github:
arg[File]("<file>...") unbounded() optional() action { (x, c) =>
c.copy(files = c.files :+ x) } text("optional unbounded args")
produces the following usage text:
<file>...
optional unbounded args
and corresponds to files: Seq[File] within the Config case class.
Note the two modifiers of unbounded and optional. These make it so it can produce as many as you like, and it is not required. As you can see in the example case class code, the default value of files is an empty Seq, as you want.
Last but not least, I should mention that you'll want to set the -o to be a flag, similar to how the github example uses --verbose.

Related

How to get one or none arguments with click?

Click allows for variadic arguments like this:
#click.command()
#click.argument('src', nargs=-1)
#click.argument('dst', nargs=1)
def copy(src, dst):
"""Move file SRC to DST."""
for fn in src:
click.echo(f"move {fn} to folder {dst}")
But how can I specify at most one argument? While it may be interesting to have a minimum and maximum number, I am looking for adding an optional argument.
I think nargs=-1 and checking if n<2 myself would work like this
#click.command()
#click.argument('some_argument')
#click.argument('optional_argument', nargs=-1)
def example(some_argument, optional_argument):
if len(option_argument) > 1:
print("Too many arguments")
return
# do something with or without the optional argument
but the automatically generated helptext then just should some_argument optional_argument... and it should indicate it by some_argument [optional_argument]. And of course it would be nice if click could handle the check itself instead of only checking for zero or more arguments.
I think that you may need a command option (Click docs) here, since the argument is really optional:
#click.command()
#click.argument('some_argument')
#click.option('optional_argument', default='some value')
def example(some_argument, optional_argument):
# do something with or without the optional argument
Because optional_argument is now an option, the command can be used without providing a value for optional_argument or providing a single value (that will override the default value).

python click passing multiple key values as options

I am using python-click and I would like to pass values with a format like this
myprogram mycommand --parameter param1=value1 --parameter param2=value2
I was looking at click option documentation but I can't find any construct that could help with this, the only solution I can find is invoking a callback function and check that the string is properly constructed <key>=<value>, then elaborate the values properly.
Nothing bad in that solution, but I was wondering if there is a more elegant way to handle this since the pattern looks to be common enough.
So, I've had a go at it. I've managed to do it the following ways.
Firstly, I've tried this, though it doesn't satisfy the --parameter criteria.
#click.command("test")
#click.argument("args", nargs=-1)
def test(args):
args = dict([arg.split("=") for arg in args])
print(args)
so when invoking like test param1=test1 param2=test the output is:
{'param1': 'test1', 'param2': 'test2' }
Secondly, I thought about a multiple option, combined with a variadic argument, which seems to be closer to your requirements:
test -p param1=test -p param2=test
#click.command("test")
#click.option('-p', '--parameter', multiple=True)
#click.argument("args", nargs=-1)
def test(*args, **kwargs):
param_args = kwargs['parameter']
param_args = dict([p.split('=') for p in param_args])
print(param_args)
if __name__ == '__main__':
test()
The output will be the same as the previous case.
If you were to print(kwargs['parameter']), you'd get
('param1=test', 'param2=test')
It sounds a bit more cleaner than using a callback, but not by much. Still, hope it helps.

Erlang mnesia equivalent of "select * from Tb"

I'm a total erlang noob and I just want to see what's in a particular table I have. I want to just "select *" from a particular table to start with. The examples I'm seeing, such as the official documentation, all have column restrictions which I don't really want. I don't really know how to form the MatchHead or Guard to match anything (aka "*").
A very simple primer on how to just get everything out of a table would be very appreciated!
For example, you can use qlc:
F = fun() ->
Q = qlc:q([R || R <- mnesia:table(foo)]),
qlc:e(Q)
end,
mnesia:transaction(F).
The simplest way to do it is probably mnesia:dirty_match_object:
mnesia:dirty_match_object(foo, #foo{_ = '_'}).
That is, match everything in the table foo that is a foo record, regardless of the values of the fields (every field is '_', i.e. wildcard). Note that since it uses record construction syntax, it will only work in a module where you have included the record definition, or in the shell after evaluating rr(my_module) to make the record definition available.
(I expected mnesia:dirty_match_object(foo, '_') to work, but that fails with a bad_type error.)
To do it with select, call it like this:
mnesia:dirty_select(foo, [{'_', [], ['$_']}]).
Here, MatchHead is _, i.e. match anything. The guards are [], an empty list, i.e. no extra limitations. The result spec is ['$_'], i.e. return the entire record. For more information about match specs, see the match specifications chapter of the ERTS user guide.
If an expression is too deep and gets printed with ... in the shell, you can ask the shell to print the entire thing by evaluating rp(EXPRESSION). EXPRESSION can either be the function call once again, or v(-1) for the value returned by the previous expression, or v(42) for the value returned by the expression preceded by the shell prompt 42>.

Parsing options that take more than one value with scopt in scala

I am using scopt to parse command line arguments in scala. I want it to be able to parse options with more than one value. For instance, the range option, if specified, should take exactly two values.
--range 25 45
Coming, from python background, I am basically looking for a way to do the following with scopt instead of python's argparse:
parser.add_argument("--range", default=None, nargs=2, type=float,
metavar=('start', 'end'),
help=(" Foo bar start and stop "))
I dont think minOccurs and maxOccurs solves my problem exactly, nor the key:value example in its help.
Looking at the source code, this is not possible. The Read type class used has a member tuplesToRead, but it doesn't seem to be working when you force it to 2 instead of 1. You will have to make a feature request, I guess, or work around this by using --min 25 --max 45, or --range '25 45' with a custom Read instance that splits this string into two parts. As #roterl noted, this is not a standard way of parsing.
It should be ok if only your values are delimited with something else than a space...
--range 25-45
... although you need to split them manually. Parse it with something like:
opt[String]('r', "range").action { (x, c) =>
val rx = "([0-9]+)\\-([0-9]+)".r
val rx(from, to) = x
c.copy(from = from.toInt, to = to.toInt)
}
// ...
println(s" Got range ${parsedArgs.from}..${parsedArgs.to}")

Macro name expanded from another macro in makefile

I have a makefile with the following format. First I define what my outputs are;
EXEFILES = myexe1.exe myexe2.exe
Then I define what the dependencies are for those outputs;
myexe1.exe : myobj1.obj
myexe2.exe : myobj2.obj
Then I have some macros that define extra dependencies for linking;
DEP_myexe1 = lib1.lib lib2.lib
DEP_myexe2 = lib3.lib lib4.lib
Then I have the target for transforming .obj to .exe;
$(EXEFILES):
$(LINK) -OUT:"Exe\$#" -ADDOBJ:"Obj\$<" -IMPLIB:$($($(DEP_$*)):%=Lib\\%)
What I want to happen is (example for myexe1.exe)
DEP_$* -> DEP_myexe1
$(DEP_myexe1) -> lib1.lib lib2.lib
$(lib1.lib lib2.lib:%=Lib\\%) -> Lib\lib1.lib Lib\lib2.lib
Unfortunately this is not working. When I run make --just-print, the -IMPLIB: arguments are empty. However, if I run $(warning DEP_$*) I get
DEP_myexe1
And when I run $(warning $(DEP_myexe1)) I get
lib1.lib lib2.lib
So for some reason, make does not like the combination of $(DEP_$*). Perhaps it cannot resolve macro names dynamically like this. What can I do to get this to work? Is there an alternative?
Where does $(warning DEP_$*) give you DEP_myexe1 as output exactly? Because given your makefile above it shouldn't.
$* is the stem of the target pattern that matched. In your case, because you have explicit target names, you have no patten match and so no stem and so $* is always empty.
Additionally, you are attempting a few too many expansions. You are expanding $* to get myexe1 directly (assuming for the moment that variable works the way you intended). You then prefix that with DEP_ and used $(DEP_$*) to get the lib1.lib lib2.lib. You then expand that result $($(DEP_$*)) and then expand that (empty) result again (to do your substitution) $($($(DEP_$*)):%=Lib\\%).
You want to either use $(#:.exe=) instead of $* in your rule body or use %.exe as your target and then use $* to get myexe1/myexe2.
You then want to drop two levels of expansion from $($($(DEP_$*)):%=Lib\\%) and use $(DEP_$*:%=Lib\\%) instead.
So (assuming you use the pattern rule) you end up with:
%.exe:
$(LINK) -OUT:"Exe\$#" -ADDOBJ:"Obj\$<" -IMPLIB:$(DEP_$*:%=Lib\\%)
I managed to get it working without needing to resolve macros in the way described above. I modified the linking dependencies like this;
myexe1.exe : myobj1.obj lib1.lib lib2.lib
myexe2.exe : myobj2.obj lib3.lib lib4.lib
Then I need to filter these files by extension in the target recipe;
$(EXEFILES):
$(LINK) -OUT:"$(EXE_PATH)\$#" -ADDOBJ:$(patsubst %, Obj\\%, $(filter %.obj, $^)) -IMPLIB:$(patsubst %, Lib\\%, $(filter %.lib, $^))
The $(pathsubst ...) is used to prepend the path that the relevant files are in.
In the case of myexe1.exe, the link command expands to;
slink -OUT:"Exe\myexe1.exe" -ADDOBJ: Obj\myexe1.obj -IMPLIB: Lib\lib1.lib Lib\lib2.lib
Out of interest's sake, I would still like to know if it is possible to resolve macro names like in the question.