我如何拥有:默认Rake任务取决于带参数的任务?

我一直在玩Rake和Albacore,看看我是否可以替换现有的MSBuild脚本,该脚本使用非XML的软件来部署软件。 我有一个任务,将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 

我想你可能不得不使用旧的样式参数传递,例如:

 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' 

一般来说,我不推荐这些方法中的任何一种。 在我看来,调用invokeexecute表示结构不合理的任务。 如果不过早参数化,则根本没有此问题。

 web_config = 'c:/test-mars-deploy/Web.config' task :update_web_config do File.open(web_config, 'r+') do |file| # ... end end 

如果必须参数化,请提供数组或FileList并为每个项生成任务。

 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 

更好的是,我发布了一个配置更新任务 ,为您完成所有这些混乱! 提供要更新的FileList和xpath queries => replacement的哈希。

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

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

 ree-1.8.7-2010.02@rails3 matt@Zion:~/setup$ cat lib/tasks/blah.rake task :blah, :n do |t, args| puts args.n end ree-1.8.7-2010.02@rails3 matt@Zion:~/setup$ rake blah[20] (in /home/matt/setup) 20 

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

 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 default[3.2.1] version is 3.2.1 

要么

 $ rake build[3.2.1] version is 3.2.1 

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