basho / clique Goto Github PK
View Code? Open in Web Editor NEWCLI Framework for Erlang
License: Apache License 2.0
CLI Framework for Erlang
License: Apache License 2.0
When using the set
command the registered callback will be called on local or remote nodes automatically depending upon the --node and --all flags. Right now however, command callbacks must do the cross node calls themselves instead of being told where to run. Make this more inline with set
and call the functions in the right locations automatically.
Clique doesn't yet allow returning exit codes or custom error messages.
{{clique:run/1}} will always return {{ok}}.
[Created in JIRA by Sean Cribbs]
src/clique_usage.erl:23: export_all flag enabled - all functions will be exported
Compiling src/clique_usage.erl failed:
DEBUG: Worker compilation failed: {{error,
{error,[],
[["src/clique_usage.erl:23: export_all flag enabled - all functions will be exported\n"]]}},
{source,"src/clique_usage.erl"}}
Fix for #85 was resolving problem of equal sign in the middle of value.
If one or more =
signs are at the end of the value - they are all removed.
Following test case in src/clique_parser.erl
will fail:
parse_valid_arg_value_with_trailing_equal_sign_test() ->
Spec = spec(),
ArgsAndFlags = ["client-id=anon-Base64v=="],
{Spec, Args, Flags} = parse({Spec, ArgsAndFlags}),
?assertEqual(Args, [{"client-id", "anon-Base64v=="}]),
?assertEqual(Flags, []).
The app dependencies in rebar.config and .app.src are not in sync with the actual usage in the clique application.
This is currently one of the blockers for using riak_core as a dependency in your own project - at least if you want to use relx and rely on proper OTP rules for releases.
clique problems:
'IN_called_IN_deps_NOT_appsrc': [cuttlefish]
'IN_called_NOT_deps_NOT_appsrc': [mochiweb]
The fix is to simply bring the files in sync with reality.
[Created in JIRA by Torben Hoffmann]
In 0.3.1, Wildcard support was added. However, it appears that it may have broken the ability to set/get cuttlefish config settings (see #61 for more information).
Because Clique is so easy to update in isolation, we need to make sure we've got a good test suite there to prevent seemingly simple changes from breaking Riak.
[Created in JIRA by Douglas Rohrer]
Table columns, when the console is too small, are resized in a very uneven/unfair way. For example, take the following code:
Table = [[{foo, "Foo"}, {bar, "Bar"}, {baz, "Another"}, {buzz, "Yup"}, {"Transfer Rate","127 kbp[[{foo,"Foo"},"1280 objs"}, {pid, "<14479.003>"}]].
clique:print([clique_status:table(Table)], fun clique_human_writer:write/1).
If you run this in a console window that's a normal size, you'll get
+---+---+-------+----+-------------+---------+-----------+
|foo|bar| baz |buzz|Transfer Rate| Size | pid |
+---+---+-------+----+-------------+---------+-----------+
|Foo|Bar|Another|Yup | 127 kbps |1280 objs|<14479.003>|
+---+---+-------+----+-------------+---------+-----------+
Now, shrink your console to be exactly wide enough to show that table, and run clique:print([clique_status:table(Table)], fun clique_human_writer:write/1).
again. This time, you get:
+-----------+--------+------------+---+------+--+--+
| foo | bar | baz |buz|Transf|Si|pi|
+-----------+--------+------------+---+------+--+--+
| Foo | Bar | Another |Yup|127 kb|12|<1|
+-----------+--------+------------+---+------+--+--+
Need to find a better method of resizing the columns.
If you use the set command and use the --node flag to point to a node that's down, we should print some kind of an error message. Right now nothing is printed to the console, which makes it appear as though the command succeeded.
clique_error
defines how to format all errors, but if I want to validate a flag is properly formed, I can't customize the output (actually I'll probably get function_clause
). Example typecasting function:
ip(String) ->
try
[Ip, PortStr] = string:tokens(String, ":"),
{ok, _} = inet_parse:address(Ip),
Port = list_to_integer(PortStr),
{Ip, Port}
catch
error:badarg ->
{error, port_is_not_integer};
error:badmatch ->
{error, invalid_address}
end.
I should be able to use symbolic errors in this case or handle them explicitly by running the command with flagged inputs. Currently I can do neither because clique_error
is called immediately upon encountering an error.
It looks like there has been an issue for a while where the --help flag doesn't work on all commands. More recently, the --format flag has been added, and that appears to suffer from the same problem.
For some of the commands, it's easy to see why would be the case (set/show/describe), but I'm also seeing the same issue with an application-defined command (riak-admin cluster status), so I suspect there might be more than one thing that needs to be fixed here.
Seeing the following using this branch: https://github.com/basho/riak_core/tree/feature/riak-cli-handoff-enable
Andrews-MacBook-Pro:riak_ee ajs$ dev/dev1/bin/riak-admin set handoff.disable_outbound=true
Invalid Configuration: {error,[{error,"Error transforming datatype for: handoff.disable_outbound"},
{error,"\"true\" is not a valid enum value, acceptable values are [\"on\",\"off\"]."}]}
We should display this information in a much nicer way.
Provide the following interface:
riak_cli_status:list(List)
riak_cli_status:list(List, Title)
https://github.com/basho/clique/blob/develop/src/clique_error.erl#L39
clique_usage:find
only returns one error tuple: https://github.com/basho/clique/blob/develop/src/clique_usage.erl#L73
clique_error
should output that string instead of the Invalid command line. Here's what I saw when experimenting:
13> clique:run(["riak-admin", "foo", "limit"]).
Invalid command 'riak-adminfoolimit'
I tried to use an empty value argument like the following:
$ my-cli command foo=
And results in the following error:
{'EXIT',
{function_clause,
[{clique_error,
format,
["my-cli",
{error,
{invalid_kv_arg,
"foo"}}],
[{file,
"/mycli/_build/default/lib/clique/src/clique_error.erl"},
{line,
29}]},
{clique,
print,
3,
[{file,
"/mycli/_build/default/lib/clique/src/clique.erl"},
{line,
109}]},
{clique,
print,
2,
[{file,
"/mycli/_build/default/lib/clique/src/clique.erl"},
{line,
92}]},
{rpc,
'-handle_call_call/6-fun-0-',
5,
[{file,
"rpc.erl"},
{line,
197}]}]}
}
IMHO, instead of raising an error clique should pass an empty string "" as the value or even better catch the error and show a clique message instead of the stack trace.
See this comment: basho/riak_core#659 (comment)
Due to the deprecation of erlang:get_stack_trace()
erlang/otp#1783
===> Compiling _build/default/lib/clique/src/clique_test_group_leader.erl failed
_build/default/lib/clique/src/clique_test_group_leader.erl:118: erlang:get_stacktrace/0: deprecated; use the new try/catch syntax for retrieving the stack backtrace
The simple fix is to update the catch
to the new try/catch syntax but that'll break older versions. Otherwise adding an ignore deprecations flag to the project should work.
try apply(M, F, A) of
Chars ->
io_request({put_chars, Chars}, State)
catch C:T:S ->
{{error, {C,T, S}}, State}
end;
When cuttlefish config uses transformations, and is not a direct 1:1 mapping from riak.conf key to appenv key, the automagically generated set/show commands do not work. This almost certainly requires a bit of work to cuttlefish as well.
Current:
$ ./riak-admin set
Config Operations require one or more arguments
$ ./riak-admin set foo
Not a Key/Value argument of format: "foo"=<Value>:
$ ./riak-admin set foo=bar
Conf file attempted to set unknown variable: foo
Suggested:
$ ./riak-admin set
Usage: riak-admin set <variable>=<value> [-n <node>|--all]
$ ./riak-admin set foo
Usage: riak-admin set <variable>=<value> [-n <node>|--all]
$ ./riak-admin set foo=bar
Unknown configuration variable: foo
I tried to use a equal sign (=
) as value but it fails with:
$ my-cli do-something url=example.com?q=dada
Too many equal signs in argument: "url=example.com?q=dada"
IMHO clique should pass down any additional equal sign as part of value. At least it should provide a way to escape them.
We want to allow the user to dictate at runtime the type of output of the system.
For instance, we want --help
to always show help for the given command, but we don't want to make the user check whether the help command was run for each and every command.
We also will want to set the writer so that the values are output in a different manner. For example, we can use --csv
to output in csv format instead of a human readable format for every command.
Having global flags will allow us to add different writers in the future.
The current logic for handling terminals that aren't wide enough for the specified table is complex and buggy. Andrew Thompson attempted to fix one bug with #49 but that patch results in a more serious bug.
Creating a branch with a new approach to proportionally shrink columns. Should be easier to follow/debug.
https://github.com/basho/clique/tree/jrd/proportional-shrink is the work in progress.
[Created in JIRA by John Daily]
Andrews-MacBook-Pro:riak_ee ajs$ dev/dev1/bin/riak-admin show transfer_limit -n [email protected]
RPC to '[email protected]' failed: {'EXIT',
{function_clause,
[{clique_status,parse,
[{badrpc,nodedown},
#Fun<clique_human_writer.0.113743305>,
{context,false,[]}],
[{file,"src/clique_status.erl"},
{line,37}]},
{clique_human_writer,write,1,
[{file,"src/clique_human_writer.erl"},
{line,36}]},
{clique,print,2,
[{file,"src/clique.erl"},{line,71}]},
{rpc,'-handle_call_call/6-fun-0-',5,
[{file,"rpc.erl"},{line,205}]}]}}
We currently have no way of showing usage for cuttlefish config. We probably want something like:
riak-admin config transfer_limit
or riak-admin usage transfer-limit
where it shows the usage information that is written in the cuttlefish schemas.
Don't make the user do this separately for each command. It's especially useful for --node
and --all
.
If terminal width is too small the some columns are made wider than normal.
Perhaps we should break into multiple outputs if insufficient width.
ubuntu@riak105:~$ sudo riak-admin handoff details
Type Key: O = Ownership, H = Hinted, Rz = Resize, Rp = Repair
+-------------+--+-------+----+---------------+---------------++
| Type |So|Target:|Size| Rate (KB/s) | % ||
+-------------+--+-------+----+---------------+---------------++
| O |ri|riak@ri|611.| 608.96 | 329.16 ||
| O |ri|riak@ri|686.| 603.99 | 287.46 ||
+-------------+--+-------+----+---------------+---------------++
ubuntu@riak105:~$
ubuntu@riak105:~$ sudo riak-admin handoff details
Type Key: O = Ownership, H = Hinted, Rz = Resize, Rp = Repair
+----+-------------------+-------------------+--------+-----------+------+------------------+
|Type| Source:ID | Target:ID | Size |Rate (KB/s)| % | Sender |
+----+-------------------+-------------------+--------+-----------+------+------------------+
| O |[email protected]:17|[email protected]:17|661.3 MB| 910.14 | 16.11|<25397.31465.1017>|
| O |[email protected]:42|[email protected]:42|704.4 MB| 846.67 | 22.39|<25398.4560.1436> |
+----+-------------------+-------------------+--------+-----------+------+------------------+
Would be useful to support numeric values as alternatives to textual values.
Currently:
-type text() :: {text, iolist()}.
-type column() :: {column, iolist(), [iolist()]}.
-type table() :: {table, [{iolist(), iolist()}]}.
Proposed:
-type text() :: {text, iolist()}.
-type column() :: {column, iolist(), [iolist()|number()]}.
-type table() :: {table, [{iolist(), iolist()|number()}]}.
Optionally: -type numeric() :: {numeric, number()}.
Used in riak, running riak-admin cluster status
spits this out on the console
failed: {'EXIT',
{function_clause,
[{lists,seq,
[1,-1],
[{file,"lists.erl"},
{line,228}]},
{clique_table,char_seq,
2,
[{file,
"src/clique_table.erl"},
{line,196}]},
{clique_table,
'-vertical_border/1-lc$^0/1-0-',
1,
[{file,
"src/clique_table.erl"},
{line,191}]},
{clique_table,
'-vertical_border/1-lc$^0/1-0-',
1,
[{file,
"src/clique_table.erl"},
{line,192}]},
{clique_table,
vertical_border,1,
[{file,
"src/clique_table.erl"},
{line,191}]},
{clique_table,
create_table,4,
[{file,
"src/clique_table.erl"},
{line,71}]},
{clique_human_writer,
write_table,1,
[{file,
"src/clique_human_writer.erl"},
{line,67}]},
{clique_human_writer,
write_status,2,
[{file,
"src/clique_human_writer.erl"},
{line,57}]}]}}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.