问题
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