Ruby 如何使:默认Rake任务依赖于具有参数的任务?

Ruby 如何使:默认Rake任务依赖于具有参数的任务?,ruby,rake,Ruby,Rake,我一直在玩Rake和Albacore,看看是否可以用非XML的东西替换现有的部署软件的MSBuild脚本。我有一个任务,将web.config中的调试值更改为false。该任务将web.config的目录作为参数,但我无法完全理解在默认任务中提供此参数所需的语法 require 'albacore' require 'nokogiri' deployment_path = 'c:/test-mars-deploy' task :default => [ :build, :publish

我一直在玩Rake和Albacore,看看是否可以用非XML的东西替换现有的部署软件的MSBuild脚本。我有一个任务,将
web.config
中的调试值更改为
false
。该任务将
web.config
的目录作为参数,但我无法完全理解在默认任务中提供此参数所需的语法

require 'albacore'
require 'nokogiri'

deployment_path = 'c:/test-mars-deploy'

task :default => [ :build, :publish, :update_web_config['c:/test-mars-deploy'] ]

task :update_web_config, :deploy_path do |t, args|  
  deployment_path = #{args[:deploy_path]}
  web_config_path = File.join deployment_path, 'Web.config'

  File.open(web_config_path, 'r+') do |f|
    doc = Nokogiri::XML(f)
    puts 'finding attribute'
    attribute = doc.xpath('/configuration/system.web/compilation')
    attribute.attr('debug', 'false')
    puts attribute.to_xml
  end

  File.delete(web_config_path)

  File.new(web_config_path, 'w') do |f|
    f.write(doc.to_s)
  end
end

基本上,您可以在任务名称之后将arg命名为额外符号。args参数将被传递到响应args名称的块中,您可以调用在方括号中传递args的任务(
[]


我认为您可能必须使用老式的参数传递,例如:

nicholas@hal:/tmp$ cat Rakefile
task :default => :all

deploy_path = ENV['deploy_path'] || "c:/some_path"

task :all do |t, args|
    puts deploy_path.inspect
end
并以以下方式调用:

nicholas@hal:/tmp$ rake
(in /tmp)
"c:/some_path"
或者,要覆盖路径,请执行以下操作:

nicholas@hal:/tmp$ rake deploy_path=c:/other_path
(in /tmp)
"c:/other_path"

任务依赖关系表示法不支持传递参数。它只接受引用任务名称的名称或符号

task :default => [ :build, :publish, :update_web_config['c:/test-mars-deploy'] ]
你需要这样做

task :default => [ :build, :publish ] do
    Rake::Task[:update_web_config].invoke 'c:/test-mars-deploy'
end
但是请记住,
invoke
在每个任务中只工作一次,即使参数不同。这是真正的依赖链调用。但是,它将调用所有依赖任务。如果需要多次执行,可以使用
execute
,但这不会调用依赖任务

Rake::Task[:update_web_config].invoke 'c:/test-mars-deploy'
Rake::Task[:update_web_config].execute 'c:/test-mars-deploy2'
Rake::Task[:update_web_config].execute 'c:/test-mars-deploy3'
一般来说,我不推荐这两种方法中的任何一种。在我看来,调用
invoke
execute
似乎表明任务结构不良。如果不过早地参数化,就不会有这个问题

web_config = 'c:/test-mars-deploy/Web.config'

task :update_web_config do
  File.open(web_config, 'r+') do |file|
    # ...
  end
end
如果必须参数化,请提供一个数组或
文件列表
,并生成每个项目的任务

web_configs = FileList['c:/test-*/Web.config']

web_configs.each do |config|
  task config do
    File.open(config, 'r+') do |file|
      # ...
    end
  end
end

task :update_all_web_configs => web_configs
更好的是,我会为你做这一切!提供要更新的
文件列表
,以及xpath查询的哈希=>替换

appconfig :update_web_configs do |x|
  x.files = FileList['c:/test-*/Web.config']
  x.replacements = {
    "/configuration/system.web/compilation/@debug" => 'False' }
end

任务依赖关系表示法实际上支持传递参数。例如,说“版本”是你的论点:

task :default, [:version] => [:build]

task :build, :version do |t,args|
  version = args[:version]
  puts version ? "version is #{version}" : "no version passed"
end
那么你可以这样称呼它:

$ rake
no version passed


但是,我没有找到一种方法来避免在传递参数时指定任务名称(默认或构建)。如果有人知道一种方法,我很想听听。

是的,它使用上述命令行正确运行,但我想知道的是如何使用默认任务传递参数,这样我就可以只键入“rake”。我设法重构了代码,以便使用此方法在批处理文件中运行。@Dan:你能解释一下为什么需要批处理文件吗?我发布的代码片段实际上并不需要批处理文件,但在我的实际代码中,我的任务是在一个文件中构建两个不同的项目。我可能会将它们分离成不同的文件,但我在ruby学习方面还没有走那么远。
$ rake
no version passed
$ rake default[3.2.1]
version is 3.2.1
$ rake build[3.2.1]
version is 3.2.1