Как сделать так, чтобы задача Rake :default зависела от задачи с аргументами?

Я экспериментировал с 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

person Dan Scott    schedule 12.08.2010    source источник


Ответы (4)


Я думаю, вам, возможно, придется использовать передачу параметров старого стиля, например:

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"
person ngoozeff    schedule 12.08.2010
comment
Мне удалось реорганизовать свой код, чтобы он запускался через пакетный файл с использованием этого метода. - person Dan Scott; 12.08.2010
comment
@Dan: не могли бы вы прокомментировать, зачем вам нужен пакетный файл? - person ngoozeff; 12.08.2010
comment
Фрагмент, который я разместил, на самом деле не нуждается в нем, но в моем реальном коде у меня есть задачи, которые создают пару разных проектов внутри одного файла. Я мог бы, вероятно, разделить их на отдельные файлы, но я не продвинулся так далеко в своем изучении ruby. - person Dan Scott; 13.08.2010

Нотация зависимости задачи не поддерживает передачу аргументов. Он принимает только имена или символы, относящиеся к именам задач.

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'

В общем, я не рекомендую ни один из этих подходов. Мне кажется, что вызов invoke или execute указывает на плохо структурированную задачу. У вас просто не будет этой проблемы, если вы не будете преждевременно параметризовать.

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 => замены.

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

в основном, вы называете свои аргументы дополнительными символами после имени задачи. параметр 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
person Matt Briggs    schedule 12.08.2010
comment
Да, он работает правильно из командной строки, используя приведенное выше, но я ищу, как передать аргумент, используя задачу по умолчанию, чтобы я мог просто ввести «грабли». - person Dan Scott; 12.08.2010

Нотация зависимости задачи фактически поддерживает передачу аргументов. Например, скажите, что «версия» — это ваш аргумент:

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

or

$ rake default[3.2.1]
version is 3.2.1

or

$ rake build[3.2.1]
version is 3.2.1

Однако я не нашел способа избежать указания имени задачи (по умолчанию или сборки) при передаче аргументов. Хотелось бы услышать, если кто знает способ.

person Gal    schedule 20.10.2013