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

时间:2010-08-12 11:58:32

标签: ruby 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

4 个答案:

答案 0 :(得分:2)

任务依赖性表示法不支持传递参数。它只需要引用任务名称的名称或符号。

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

更好的是,我published一个config update task为你做了所有这些混乱!提供FileList更新和xpath查询的哈希=>替代品。

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

答案 1 :(得分:0)

基本上,您将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

答案 2 :(得分:0)

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

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"

答案 3 :(得分:0)

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

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

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