2012-03-24 147 views
12

我想使交互式应用,其中用户运行它,并可以通过创建交互式Ruby控制台应用程序

例如键入命令(某种壳)做各种任务:

./myapp.rb 
App says Hi 
Commands: 
    help - display help about command 
    open - open task 
    do - do action 
Start>help open 
    open <TaskName> 
    opens specified task 
Start>open Something 
Something>do SomeAction 
    Success! 
Something> (blinking cursor here) 

我搜查,但couldn没有找到任何宝石宝石,我可以专门用于控制台交互,所以我即将做出我自己的...

我看着Thor,但那不完全如我wa NT,也许我可以使用它,但不知道...

它可能看起来像:

class Tasks 
    attr_reader :opened_task 

    desc "open <TaskName>", "opens specified task" 
    def open(params) 
    end 

    desc "do <ActionName>", "do specified action" 
    def do(params) 
    end 
end 

tasks = Tasks.new 
# theoretical Console class 
console = Console.new 
console.addCommand("open",tasks.method(:open),"open task") 
console.addCommand("do",tasks.method(:do),"do action") 
console.start("%s>",[*tasks.opened_task]) 

所以我的问题是,什么宝石我可以用它来做出这样的控制台类?也许有人已经做出了类似的东西? 我计划使用HighLine进行输入/输出,但任何其他建议我可以使用什么?

+0

它应该是红宝石或你自己的语法? – Reactormonk 2012-03-24 19:02:49

+0

你是指红宝石还是自己的语法? :| 如果你的意思是使用IRB,那么这不是一个选项... – davispuh 2012-03-24 19:11:52

+1

为什么不呢?它为您免费提供图灵完整性。 – Reactormonk 2012-03-24 19:15:04

回答

17

你想要的是一个REPL - Read → Evaluate → Print Loop。例如,IRB为Ruby语言实现了REPL。

这里是一个非常简单的实现应用程序的REPL的:

loop do 
    Application::Console.prompt.display 
    input = gets.chomp 
    command, *params = input.split /\s/ 

    case command 
    when /\Ahelp\z/i 
    puts Application::Console.help_text 
    when /\Aopen\z/i 
    Application::Task.open params.first 
    when /\Ado\z/i 
    Application::Action.perform *params 
    else puts 'Invalid command' 
    end 
end 

\A\z匹配的字符串分别开始和字符串的结尾。

+0

好吧谢谢显示的方式之一,我可以如何实现控制台类的方法“开始”:) – davispuh 2012-03-24 20:08:58

+0

@davispuh我忘了提示 - 更新答案改进实施。你的'start'方法应该只包含循环。 – 2012-03-24 20:28:55

+2

我接受了这个答案,因为它建议通过展示部分实现来自己制作它,所以我将制作自​​己的CLI,特别是为了我所有的需要... – davispuh 2012-03-26 22:19:20

1
class MyAPI 
    def self.__is__(text) 
    @__is__ = text 
    end 

    def self.method_added(method) 
    @__help__ ||= {} 
    @__help__[method.to_s] = @__is__ 
    @__is__ = nil 
    end 

    def self.help(of) 
    @__help__[of] 
    end 

    __is__ "open file <file>" 
    def open(file) 
    #... 
    end 

    __is__ "do X" 
    def do(*params) 
    #... 
    end 

    __is__ "calls help, use help <command>" 
    def help(*args, &block) 
    self.class.help(*args, &block) 
    end 
end 

MyAPI.new(...).pry 

或者你可以使用撬命令,但击败 图灵完备。可能使用命令来实现帮助,因为我不知道我的方法效果如何。这些方法需要编码为 防御性。我不记得如何使用类变量: -/

+0

它需要大量的更改/配置才能让它工作,因为我需要...我也会用它来完成任务,而这个任务并不适用于它,它具有“功能”,我甚至不需要... – davispuh 2012-03-26 21:10:42

+0

@davispuh,你给了'cliqr'(上面)一个镜头吗?它不需要太多的配置,几乎可以直接使用。 – nuaavee 2018-02-09 02:25:41

+0

@nuaavee当我写下这个问题时,它现在还没有存在,但它看起来与我所需要的非常相似,然后比创建它早了3年:D – davispuh 2018-02-09 18:37:42

4

您也可以尝试ripl。 (从文件):

require 'ripl' 
# Define plugins, load files, etc... 
Ripl.start 

有插件RIPL的完整列表以及使用项目网站上RIPL控制台应用程序列表: 创建和启动自定义外壳的就是这么简单。

+0

这看起来更有希望,但仍需要做一些配置,并且它有相同的“功能”,我不需要作为pry/irb,我也认为需要非常多的变化/配置... – davispuh 2012-03-26 22:15:45

+2

说实话,迄今为止我没有使用'ripl' - 但是写入从头开始你自己的解决方案似乎不是最好的主意。只要考虑用箭头键移动 - 没有readline支持用户会发誓。 – 2012-03-26 22:24:35

+0

在Windows中,命令历史正在工作(向上/向下箭头),我只需要使用选项卡自动完成,但在开始时我甚至可能没有这样的生活...... – davispuh 2012-03-27 01:21:05

4

好的,所以我创建了这个库,用于在ruby中创建控制台应用程序。实际上它是前一阵子,但只是决定释放它。如果与HighLine和Readline一起使用,它支持自动完成。

当我写它没有任何文档和测试/规格,但现在我做了一些。仍然不多,但开始应该没问题。

所以宝石cli-console和 代码是在GitHub上,这里的usage example

3

看看cliqr红宝石的宝石。它看起来正是你所需要的。以下是描述性自述文件的github链接:https://github.com/anshulverma/cliqr

它可以直接或在内置shell中执行命令。

下面是它的混帐回购测试用例:

it 'can execute a sub action from shell' do 
     cli = Cliqr.interface do 
     name 'my-command' 
     handler do 
      puts 'base command executed' 
     end 

     action :foo do 
      handler do 
      puts 'foo executed' 
      end 

      action :bar do 
      handler do 
       puts 'bar executed' 
      end 
      end 
     end 
     end 

     with_input(['', 'my-command', 'foo', 'foo bar', 'foo bar help']) do 
     result = cli.execute %w(my-command shell), output: :buffer 
     expect(result[:stdout]).to eq <<-EOS 
Starting shell for command "my-command" 
my-command > . 
base command executed 
my-command > my-command. 
base command executed 
my-command > foo. 
foo executed 
my-command > foo bar. 
bar executed 
my-command > foo bar help. 
my-command foo bar 

USAGE: 
    my-command foo bar [actions] [options] [arguments] 

Available options: 

    --help, -h : Get helpful information for action "my-command foo bar" along with its usage information. 

Available actions: 
[ Type "my-command foo bar help [action-name]" to get more information about that action ] 

    help -- The help action for command "my-command foo bar" which provides details and usage information on how to use the command. 
my-command > exit. 
shell exited with code 0 
     EOS 
     end 
    end 
3

TTY是很容易做这样的事情一个很好的宝石。你有足够的工具可以单独使用或者使用完整的toolkit。您可以使用颜色,提示,执行shell本机,与屏幕交互,打印表格,进度条和其他许多有用的命令行元素,以及简单的goop api。

特别是tty-prompt对询问用户输入非常有用。

你提出的情况下,一个简单的例子:

require 'tty-prompt' 
require 'pastel' 

prompt = TTY::Prompt.new 
loop do 
    cmd, parms* = prompt.ask('[email protected]$ ').split /\s/ 
    case cmd 
    when "hola" 
     puts "Hola amigo " parms 
    when "exit" 
     break if prompt.yes?('Do you really want to exit?') 
    end 
end 
+0

感谢您的评论。我正要增加这个例子。 – 2017-09-25 15:21:18

+0

这不是我正在寻找的东西,这是一个可以用来实现这种控制台的库,如你所示。当我问这个问题的时候,它也不存在:D我使用https://github.com/JEG2/highline实现了我的CLI控制台,它的功能非常类似。 – davispuh 2017-10-01 17:56:10

相关问题