2010-08-12 52 views
1

我一直在玩弄Rake和Albacore,看看我能否替換我們現有的MSBuild腳本,它部署的軟件不是XML。我有一個任務會將web.config中的調試值更改爲false。該任務將web.config的目錄作爲參數,但我無法完全弄清楚在默認任務中提供此參數所需的語法。我如何擁有:default rake任務取決於具有參數的任務?

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 

回答

0

參數傳遞,例如:

[email protected]:/tmp$ cat Rakefile 
task :default => :all 

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

task :all do |t, args| 
    puts deploy_path.inspect 
end 

並調用具有:

[email protected]:/tmp$ rake 
(in /tmp) 
"c:/some_path" 

或者重寫路徑:

[email protected]:/tmp$ rake deploy_path=c:/other_path 
(in /tmp) 
"c:/other_path" 
+0

我設法重構我的代碼,所以它使用這種方法通過批處理文件運行。 – 2010-08-12 14:42:58

+0

@丹:你可以評論你爲什麼需要一個批處理文件? – ngoozeff 2010-08-12 16:47:45

+0

我發佈的代碼片段並不是真的需要它,但是在我的實際代碼中,我有一些任務在一個文件中構建了幾個不同的項目。我大概可以將它們分成單獨的文件,但是在我的紅寶石學習中我還沒有那麼深入。 – 2010-08-13 07:51:43

0

基本上,您將參數命名爲任務名稱後的額外符號。 args中,該PARAM將得到傳遞到了響應您的args來命名塊,你可以調用傳遞ARGS在方括號我想你可能必須使用舊式的任務([]

[email protected] [email protected]:~/setup$ cat lib/tasks/blah.rake 
task :blah, :n do |t, args| 
    puts args.n 
end 
[email protected] [email protected]:~/setup$ rake blah[20] 
(in /home/matt/setup) 
20 
+0

是的,它使用上面的命令行可以正確運行,但是我正在尋找的是如何使用默認任務傳遞參數,以便我可以輸入'rake'。 – 2010-08-12 12:18:25

+0

對不起,真的沒有足夠好的閱讀這個問題 – 2010-08-12 12:25:31

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 queries =>替換的散列。

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

任務依賴標記事實上確實支持傳遞參數。例如,說 「版本」 是你的論點:

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 

然而,我還沒有找到避免指定th的方法e傳遞參數時的任務名稱(默認或構建)。如果有人知道某種方式,會很樂意聽到。