Giter Site home page Giter Site logo

clim's Introduction

clim's People

Contributors

aduzsardi avatar at-grandpa avatar gregpk avatar kalinon avatar kalvisbuls avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

clim's Issues

Defaults for boolean option ignored (always false)

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]>

Having a bit of an issue with the DSL

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"]

Question: How would you go about refactoring a clim app?

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.

Value requirement of bool option

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自体の構文の理解不足のような気もしますが、解決策をご存知でしたら教えていただけないでしょうか。

pass options from main command to sub_commands

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?

Handling and defining required args

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:

  1. We can get arguments by their name, and not by their place.
  2. We will not need to handle missing arguments on our own, as it will be handled by Clim.

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

Required options raise exception if not provided

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.

  • "Option that requires an argument" - this prints a friendly error
  • "Required options" - this raises an exception

Sample code

# 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)

Actual behavior

$ 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 ...

Expected behavior

$ crystal run src/bug1.cr
ERROR: required option: "--prefix"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.