限制名称空间内定义的规则范围

时间:2019-01-04 21:08:53

标签: ruby rake

我有以下Rakefile(这是一个简化的示例):

namespace :green do
  rule(/^build:/) do |t|
    puts "[green] #{t}"
  end

  task :start do
    puts '[green] start'
  end

  task run: ['build:app', :start]
end

namespace :blue do
  rule(/^build:/) do |t|
    puts "[blue] #{t}"
  end

  task :start do
    puts '[blue] start'
  end

  task run: ['build:app', :start]
end

我希望每个“构建”规则仅适用于定义它的名称空间。换句话说,这就是我想要发生的事情:

$ rake blue:run
[blue] build:app
[blue] start

但是实际上是什么(使用Rake 12.3.1):

$ rake blue:run
[green] build:app
[blue] start

是否有一种方法可以限制“构建”规则的范围,以使“绿色”命名空间中定义的规则无法从“蓝色”命名空间访问?

2 个答案:

答案 0 :(得分:0)

Rake似乎不支持此功能。任务的作用域是定义它们的名称空间(通过将作用域路径添加为前缀),但是规则没有这样的前缀。

我可以通过修补猴子的Rake来使它起作用,这并不理想:

# Monkey-patch rake
module Rake
  module TaskManager
    # Copied from rake 12.3.1 and enhanced for scoped rules
    def lookup_in_scope(name, scope)
      loop do
        tn = scope.path_with_task_name(name)
        task = @tasks[tn]
        return task if task
        break if scope.empty?
        # BEGIN ADDED LINES
        task = enhance_with_matching_rule(tn)
        return task if task
        # END ADDED LINES
        scope = scope.tail
      end
      nil
    end
  end

  module DSL
    # Create a rule inside a namespace scope
    def scoped_rule(name, &block)
      pattern = "^#{Rake.application.current_scope.path}:#{name}:"
      Rake.application.create_rule(Regexp.new(pattern), &block)
    end
  end
end

namespace :green do
  scoped_rule :build do |t|
    puts t
  end

  task :start do |t|
    puts t
  end

  task run: ['build:app', :start]
end

namespace :blue do
  scoped_rule :build do |t|
    puts t
  end

  task :start do |t|
    puts t
  end

  task run: ['build:app', :start]
end

输出:

$ rake green:run
green:build:app
green:start
$ rake blue:run
blue:build:app
blue:start

答案 1 :(得分:0)

我知道这不是最好的解决方案,但我认为它可能会为您提供帮助。

rule(/^build*/) do |t|
  Rake::Task["green:build"].invoke if ARGV[0].start_with? "green"
  Rake::Task["blue:build"].invoke if ARGV[0].start_with? "blue"
end

namespace :green do
  task :build do
    puts '[green] build'
  end

  task :start do
    puts '[green] start'
  end

  task run: ['build.app', :start]
end

namespace :blue do
  task :build do
    puts '[blue] build'
  end

  task :start do
    puts '[blue] start'
  end

  task run: ['build.app', :start]
end

测试它有

rake green:run # [green] build
               # [green] start

rake blue:run # [blue] build
              # [blue] start