- Most favorite language => https://crystal-lang.org/
- Twitter => https://twitter.com/at_grandpa
- GitHub account name => at
-
grandpa (hyphen) - Twitter account name => at
_
grandpa (underscore)
Slim command line interface builder for Crystal.
License: MIT License
-
grandpa (hyphen)_
grandpa (underscore)Code:
class A < Clim
main do
option "-a", type: Bool, desc: "nope.", default: true
run do |opts, args|
pp opts.a
pp opts
end
end
end
A.start(ARGV)
Output:
false
#<A::Command_Main_command_of_clim_library::Options_Main_command_of_clim_library:0x7f493b602ea0
@a_instance=
#<A::Command_Main_command_of_clim_library::Options_Main_command_of_clim_library::Option_a:0x7f493b602e70
@array_set_flag=false,
@default=false,
@desc="nope.",
@long=nil,
@required=false,
@set_value=false,
@short="-a",
@value=false>,
@help_instance=
#<A::Command_Main_command_of_clim_library::Options_Main_command_of_clim_library::Option_help:0x7f493b602e40 [SNIP]>
I'd like to reorganize my tasks in multiple files. Is this possible. What method would you suggest?
The Crystal community has somewhat decided to use crystal
as the language's topic.
To avoid fragmentation in the community, please drop the crystal-language
topic, that only has ~28 repositories at the moment. We're sticking to crystal
, instead.
Any contributor can change it from the repo's homepage.
See crystal-lang/crystal#4241 for more context.
Thank you very much :)
So, I configured this:
class CLI < Clim
main_command do
desc "NexPloit CLI utility for automation and testing"
usage "./nexploit_cli [sub_command] [arguments]"
run do |options, arguments|
puts options.help
end
sub_command "info" do
desc "Get info from the engine instance"
usage "./nexploit_cli info [arguments]"
option "--uuids", type: Bool, desc: "Get all UUIDs of running scans", default: false
option "--url", type: String, desc: "URL of the engine API", required: true
run do |options, arguments|
raise "No URL given in options! #{options}" unless options.url
api = API.new(options.url.to_s)
api.get_uuids(options.url.to_s) if options.uuids
end
end
sub_command "scan" do
desc "Initiate Scan of a new target"
usage "./nexploit_cli scan [arguments]"
run do |options, arguments|
puts "Fake Crystal tool!!"
end
end
end
end
Now, I would expect 2 things.
First, options.url
to always be String not String? because it's required
else it should raise.
Second, not sure why but the options.url
is empty (Nil) even though the argument clearly shows the var populated ["http://1.1.1.1"]
I am building an application and it will have several sub-commands; with each sub-command having it's own sub-commands and so on.
I'd like to have, say:
src/
├── sitr
│ ├── cli
│ │ ├── business.cr
│ │ ├── nginx.cr
│ │ └── website.cr
│ ├── cli.cr
│ └── db.cr
└── sitr.cr
For now, `src/sitr.cr' contains only:
require "./sitr/*"
# TODO: Write documentation for `Sitr`
module Sitr
NAME = "sitr"
VER = "0.1.0"
end
Sitr::Cli.start(ARGV)
My problem starts in src/sitr/cli.cr
. How can I refactor stuff that should go within main do
? I'd like to put all the business
sub-commands in one file and the nginx
sub-commands in another, etc.
I think if an option's type is boolean, we shouldn't get an error to give a value as a parameter. Current workflow:
option "-ws", "--with-something", type: Bool, desc: "Integrates something"
run do |opts, args|
puts opts.with_something
end
$ app --with-something
ERROR: Bool arguments accept only "true" or "false". Input: [g]
Please see the `--help`.
Desired behavior:
$ ./app --with-something
true
$ ./app
false
とても初歩的な質問ですいません。
サブコマンド同士で、処理を使いまわしたく、クラスメソッドを作成したのですがコンパイルすることができません。
サンプルとして https://github.com/takanotume24/FakeCrystalCommand を作成しました。
例えばsrc/FakeCrystalCommand.cr
にて、それぞれのサブコマンドでクラス変数やクラスメソッドを使用する場合、どのようにすればよいのでしょうか?
https://github.com/takanotume24/FakeCrystalCommand/blob/1f21e041afb622bbf1e418f4d915a71578e8b736/src/FakeCrystalCommand.cr#L5
のようにクラス変数@@num
,クラスメソッドincrement
を定義し、サブコマンド"format"
内で呼びだそうとすると、コンパイル時に
ubuntu:~/environment/FakeCrystalCommand (master) $ crystal build src/FakeCrystalCommand.cr
Showing last frame. Use --error-trace for full trace.
Unhandled exception: Negative argument (ArgumentError)
from ???
from ???
from ???
from ???
from ???
from ???
from ???
from ???
となりコンパイルに失敗してしまいます。
やりたいこととしては、異なるサブコマンドで同一の処理が発生するため、その処理を関数として分けて、それを呼び出して使用した、という感じです。crystal自体の構文の理解不足のような気もしますが、解決策をご存知でしたら教えていただけないでしょうか。
Lets say my main command configured a URL param, that needs to be used no matter what sub command I branch out to
my_cli --url "123" sub_command --other-params 123123
How can I do that?
Hi,
I am not sure if this is currently possible - I haven't seen anything in the README.
Right now, it seems like required option flags are handled by Clim, while required arguments are not.
Is there a DSL command similar to option
to define required args? I believe that having such a command would be beneficial in two ways:
Example to demonstrate. Consider this code:
require "clim"
module Hello
class Cli < Clim
main do
usage "hello <name>"
run do |opts, args|
if args.empty?
puts opts.help_string
else
puts "hello #{args.first}"
end
end
end
end
end
Hello::Cli.start(ARGV)
Would be much nicer if it can be written like this:
main do
usage "hello <name>"
argument "name", type: String, required: true
run do |opts, args|
# We will not be in this block unless <name> is given
puts "hello #{args.name}" # <- using args.name instead of args.first
end
end
Hello,
I am not sure if this is a design choice or not.
It seems like in some cases, Clim handles exceptions on its own, and shows a friendly error to the user, and in other cases, it does not.
# src/bug1.cr
require "clim"
module Hello
class Cli < Clim
main do
usage "hello <name>"
option "--prefix <text>", type: String, desc: "Prefix.", required: true
run do |opts, args|
puts "ok"
end
end
end
end
Hello::Cli.start(ARGV)
$ crystal run src/bug1.cr -- --prefix
ERROR: Option that requires an argument. "--prefix"
Please see the `--help`.
$ crystal run src/bug1.cr -- --prefix a
ok
$ crystal run src/bug1.cr
Unhandled exception: Required options. "--prefix <text>" (Exception)
from lib/clim/src/clim/command/parser.cr:31:11 in 'required_validate!'
from lib/clim/src/clim/command.cr:79:7 in 'parse_by_parser'
from lib/clim/src/clim/command.cr:72:14 in 'recursive_parse'
from lib/clim/src/clim/command.cr:62:7 in 'parse'
... snip ...
$ crystal run src/bug1.cr
ERROR: required option: "--prefix"
It would be really cool if you could provide -h
as well; in addition to --help
.
When running ./cli --version
and have another option that is marked as required , the cli errors out with
ERROR: Required options. "-p"
Please see the
--help
.
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.