How do I have the :default Rake task depend on a task with arguments?

拥有回忆 提交于 2019-12-24 12:11:18

问题


I have been playing around with Rake and Albacore, to see if I can replace our existing MSBuild script that deploys software with something that isn't XML. I have a task that will change the debug value inside a web.config to false. The task takes the directory of the web.config as an argument, but I can't quite figure out the syntax needed to supply this argument in the default task.

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

回答1:


I think you might have to use the old style parameter passing, eg:

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

And invoke with:

nicholas@hal:/tmp$ rake
(in /tmp)
"c:/some_path"

Or, to override the path:

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



回答2:


The task dependency notation doesn't support passing arguments. It only takes names or symbols referring to task names.

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

You'd need to do something like this.

task :default => [ :build, :publish ] do
    Rake::Task[:update_web_config].invoke 'c:/test-mars-deploy'
end

Remember, though, invoke will only work once per task, even with different arguments. It's the real dependency chain invoke. But, it will call all dependent tasks. You can use execute if you need multiple executions, but that won't call dependent tasks.

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'

In general, I don't recommend either of these approaches. Calling invoke or execute seems to me to indicate a poorly structured task. You simply don't have this problem if you don't prematurely parameterize.

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

task :update_web_config do
  File.open(web_config, 'r+') do |file|
    # ...
  end
end

If you must parameterize, provide an array or FileList and generate the tasks per item.

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

Better yet, I published a config update task that does all of this mess for you! Provide a FileList to update and a hash of xpath queries => replacements.

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



回答3:


basically, you name your args as extra symbols after the name of the task. an args param will get passed into the block that responds to the name of your args, and you can invoke the task passing the args in square brackets ([])

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



回答4:


The task dependency notation does in fact support passing arguments. For example, say "version" is your argument:

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

task :build, :version do |t,args|
  version = args[:version]
  puts version ? "version is #{version}" : "no version passed"
end

Then you can call it like so:

$ rake
no version passed

or

$ rake default[3.2.1]
version is 3.2.1

or

$ rake build[3.2.1]
version is 3.2.1

However, I have not found a way to avoid specifying the task name (default or build) while passing in arguments. Would love to hear if anyone knows of a way.



来源:https://stackoverflow.com/questions/3467347/how-do-i-have-the-default-rake-task-depend-on-a-task-with-arguments

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!