【问题标题】:Namespacing thor commands in a standalone ruby executable在独立的 ruby​​ 可执行文件中命名空间 thor 命令
【发布时间】:2011-04-14 12:52:39
【问题描述】:

在命令行上调用 thor 命令时,方法按其模块/类结构命名空间,例如

class App < Thor
  desc 'hello', 'prints hello'
  def hello
    puts 'hello'
  end
end

将使用命令运行

thor app:hello

但是,如果您通过放置来使该自我可执行

App.start

在底部你可以运行如下命令:

app hello

有没有办法给这些命令命名?这样你就可以打电话了,例如

app say:hello
app say:goodbye

【问题讨论】:

    标签: ruby thor


    【解决方案1】:

    另一种方法是使用寄存器:

    class CLI < Thor
      register(SubTask, 'sub', 'sub <command>', 'Description.')
    end
    
    class SubTask < Thor
      desc "bar", "..."
      def bar()
        # ...
      end
    end
    
    CLI.start
    

    现在 - 假设您的可执行文件名为 foo - 您可以调用:

    $ foo sub bar
    

    在当前的雷神版本(0.15.0.rc2)中,虽然有一个错误,导致帮助文本跳过子命令的命名空间:

    $ foo sub
    Tasks:
       foo help [COMMAND]  # Describe subcommands or one specific subcommand
       foo bar             #
    

    您可以通过覆盖 self.banner 并显式设置命名空间来解决此问题。

    class SubTask < Thor
      namespace :sub
    
      def bar ...
    
      def self.banner(task, namespace = true, subcommand = false)
        "#{basename} #{task.formatted_usage(self, true, subcommand)}"
      end
    end
    

    formatted_usage 的第二个参数是唯一与原始实现banner 不同的地方。您也可以这样做一次,然后让其他子命令类从 SubTask 继承。现在你得到:

    $ foo sub
    Tasks:
       foo sub help [COMMAND]  # Describe subcommands or one specific subcommand
       foo sub bar             #
    

    希望对您有所帮助。

    【讨论】:

    【解决方案2】:

    这是将 App 作为默认命名空间的一种方式(虽然很 hacky):

    #!/usr/bin/env ruby
    require "rubygems"
    require "thor"
    
    class Say < Thor
      # ./app say:hello
      desc 'hello', 'prints hello'
      def hello
        puts 'hello'
      end
    end
    
    class App < Thor
      # ./app nothing
      desc 'nothing', 'does nothing'
      def nothing
        puts 'doing nothing'
      end
    end
    
    begin
      parts = ARGV[0].split(':')
      namespace = Kernel.const_get(parts[0].capitalize)
      parts.shift
      ARGV[0] = parts.join
      namespace.start
    rescue
      App.start
    end
    

    或者,也不理想:

    define_method 'say:hello'
    

    【讨论】:

    • 所以没有干净的方法可以做到这一点?只是不支持?
    • 我不能肯定。我试图找到一种干净的方法但失败了。我认为命名空间方法仅在使用 thor 命令而不是独立可执行文件时才有效。
    猜你喜欢
    • 2011-09-27
    • 2016-03-03
    • 2022-07-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    相关资源
    最近更新 更多