16

在命令行上调用 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
4

2 回答 2

24

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

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

在当前的 thor 版本(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             #

希望有帮助。

于 2011-08-31T12:28:07.843 回答
5

这是将 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'
于 2011-05-09T02:55:26.063 回答