Как передать аргументы в задачу Rake со средой в Rails? [Дубликат]

173

Я могу передать аргументы следующим образом:

desc "Testing args"
task: :hello, :user, :message do |t, args|
  args.with_defaults(:message => "Thanks for logging on")
  puts "Hello #{args[:user]}. #{:message}"
end

Я также могу загрузить текущую среду для приложения Rails

desc "Testing environment"
task: :hello => :environment do 
  puts "Hello #{User.first.name}."
end

То, что я хотел бы сделать, это иметь переменные и среду

desc "Testing environment and variables"
task: :hello => :environment, :message do |t, args|
  args.with_defaults(:message => "Thanks for logging on")
  puts "Hello #{User.first.name}. #{:message}"
end

Но это недействительный вызов задачи. Кто-нибудь знает, как я могу это достичь?

  • 14
    Не могли бы вы обновить, чтобы принять более новый ответ inger.
Теги:
rake

5 ответов

94
Лучший ответ

Когда вы передаете аргументы для задач rake, вы можете потребовать среду, используя опцию: needs. Например:


desc "Testing environment and variables"
task :hello, :message, :needs => :environment do |t, args|
  args.with_defaults(:message => "Thanks for logging on")
  puts "Hello #{User.first.name}. #{args.message}"
end

Обновлено на комментарий @Peiniau ниже

Что касается Rails > 3.1

task :t, arg, :needs => [deps] # deprecated

Пожалуйста, используйте

task :t, [args] => [deps] 
  • 13
    Обратите внимание, что самые последние документы описывают метод :needs следующим образом: «Этот формат все еще поддерживается для совместимости, но не рекомендуется для использования». (Я упоминаю об этом только для будущих браузеров, поскольку он предполагает, что в конечном итоге :needs больше не будут поддерживаться. Раздел называется «Формат устаревших параметров задачи» ...)
  • 6
    Ошибка в этом коде: помещает «Hello # {User.first.name}. # {: Message}» ... это не печатает «Спасибо за вход», просто «сообщение». Исправлено: # {args.message} для последней замены.
Показать ещё 3 комментария
358

Просто следить за этой старой темой; вот что я думаю, что текущий Rakefile (с давних времен) должен там делать. Это обновленная и исправленная версия текущего выигрышного ответа (hgimenez):

desc "Testing environment and variables"
task :hello, [:message]  => :environment  do |t, args|
  args.with_defaults(:message => "Thanks for logging on")
  puts "Hello #{User.first.name}. #{args.message}"   # Q&A above had a typo here : #{:message}
end

Вот как вы его вызываете (http://guides.rubyonrails.org/v4.2/command_line.html#rake):

  rake "hello[World]" 

Для нескольких аргументов просто добавьте их ключевые слова в массив объявления задачи (task :hello, [:a,:b,:c]...) и разделите их запятыми:

  rake "hello[Earth,Mars,Sun,Pluto]" 

Примечание: количество аргументов не проверяется, поэтому нечетная планета не учитывается:)

  • 37
    Этот ответ должен быть принятым.
  • 26
    Чувак ... грабли всегда кажутся мне такими безобидными. Большинство вещей в ruby, ваша первая догадка, как это на самом деле работает. Этот синтаксис просто причудливый. </ Декламация>
Показать ещё 11 комментариев
52

Просто для полноты, вот пример из docs, упомянутый выше:

   task :name, [:first_name, :last_name] => [:pre_name] do |t, args|
     args.with_defaults(:first_name => "John", :last_name => "Dough")
     puts "First name is #{args.first_name}"
     puts "Last  name is #{args.last_name}"
   end

Примечания:

  • Вы можете опустить вызов #with_defaults, очевидно.
  • Вы должны использовать Array для своих аргументов, даже если есть только один.
  • Предварительные требования не обязательно должны быть Array.
  • args - это экземпляр Rake::TaskArguments.
  • t является экземпляром Rake::Task.
  • 3
    Это объясняет, почему args.empty? дал мне странные результаты. args выглядит как хеш, но это Rake::TaskArguments . Поэтому, если вам нужно особое поведение при отсутствии аргументов, вызовите #to_hash или #to_s прежде чем проверять, является ли args пустым.
16

Альтернативный способ сделать это: использовать переменные среды ОС. Преимущества такого подхода:

  • Все зависимые задачи грабли получают параметры.
  • Синтаксис намного проще, не зависящий от грабли DSL, который трудно понять и со временем меняет.

У меня есть задача rake, которая требует трех параметров командной строки. Вот как я его вызываю:

$ rake eaternet:import country=us region=or agency=multco

Это очень чистый, простой и просто синтаксис bash, который мне нравится. Вот моя рейк-задача. Также очень чисто и без магии:

task import: [:environment] do
  agency = agency_to_import
  puts "Importing data for #{agency}..."
  agency.import_businesses
end

def agency_to_import
  country_code = ENV['country'] or raise "No country specified"
  region_slug  = ENV['region']  or raise "No region specified"
  agency_slug  = ENV['agency']  or raise "No agency specified"
  Agency.from_slugs(country_code, region_slug, agency_slug)
end

Этот конкретный пример не показывает использование зависимостей. Но если задача :import зависела от других, они также имели бы доступ к этим параметрам. Но, используя обычный метод опций rake, они бы этого не сделали.

  • 1
    Это определенно не переменные окружения! Это разгребать аргументы , даже если рейка показывает, как переменные окружения. Существует огромная концептуальная (и практическая) разница! Обратите внимание, что country=us ruby -e "puts ENV['country']" не то же самое, что ruby -e "puts ENV['country']" country=us (переменная окружения в первом против аргумента во втором).
5

Хотя эти решения работают, на мой взгляд, это слишком сложно.

Кроме того, если вы сделаете это так в zsh, вы получите ошибки, если скобки в вашем массиве не экранированы с помощью '\'.

Я рекомендую использовать массив ARGV, который отлично работает, намного проще и менее подвержен ошибкам. Например:

namespace :my_example do
  desc "Something"
  task :my_task => :environment do
    puts ARGV.inspect
  end
end

затем

rake my_example:my_task 1 2 3

#=>  ["my_example:my_task", "1", "2", "3"]

Единственное, что вам нужно иметь в виду, это то, что ARGV [0] - это имя процесса, поэтому используйте только ARGV [1..- 1].

Я понимаю, что, строго говоря, это не отвечает на вопрос, так как он не использует: среду как часть решения. Но ОП не указал, почему он включил это условие, чтобы он мог по-прежнему применяться к его прецеденту.

  • 2
    :environment необходима для загрузки кода приложения Rails. И, пробуя его в приложении Rails, я получаю: ["my_example:my_task", "1", "2", "3"] rake aborted! Don't know how to build task '1' (see --tasks)
  • 0
    это именно то, что я искал

Ещё вопросы

Сообщество Overcoder
Наверх
Меню