web-dev-qa-db-fra.com

Comment passer des arguments dans une tâche Rake avec un environnement dans Rails?

Je peux transmettre des arguments comme suit:

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

Je peux aussi charger l’environnement actuel pour une application Rails

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

Ce que j'aimerais faire, c'est pouvoir avoir des variables et un environnement

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

Mais ce n'est pas un appel de tâche valide. Est-ce que quelqu'un sait comment je peux y arriver?

207
Will

TLDR;

task :t, [args] => [deps] 

Réponse originale

Lorsque vous transmettez des arguments pour ratisser des tâches, vous pouvez exiger l'environnement à l'aide de l'option: needs. Par exemple:


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

Mis à jour le commentaire de @ Peiniau ci-dessous

Quant à Rails> 3.1

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

Veuillez utiliser

task :t, [args] => [deps] 
112
hgmnz

Juste pour faire un suivi sur ce vieux sujet; voici ce que je pense qu'un Rakefile actuel (depuis longtemps) devrait faire là-bas. C'est une version mise à jour et corrigée de la réponse gagnante actuelle (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

Voici comment vous l'appelez ( http://guides.rubyonrails.org/v4.2/command_line.html#rake ):

  rake "hello[World]" 

Pour plusieurs arguments, il suffit d’ajouter leurs mots-clés dans le tableau de la déclaration de tâche (task :hello, [:a,:b,:c]...), et passez-les séparés par une virgule:

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

Note: le nombre d'arguments n'est pas vérifié, donc la planète impaire est laissée dehors :)

368
inger

Juste pour être complet, voici l'exemple tiré du docs mentionné ci-dessus:

   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

Remarques:

  • Vous pouvez omettre le #with_defaults appel, évidemment.
  • Vous devez utiliser un Array pour vos arguments, même s'il n'y en a qu'un.
  • Les conditions préalables ne doivent pas nécessairement être un Array.
  • args est une instance de Rake::TaskArguments.
  • t est une instance de Rake::Task.
59
mikezter

Une autre façon de procéder consiste à utiliser des variables d’environnement de système d’exploitation. Avantages de cette approche:

  • Toutes les tâches de rake dépendantes obtiennent les options.
  • La syntaxe est beaucoup plus simple, elle ne dépend pas de la raie DSL, ce qui est difficile à comprendre et évolue dans le temps.

J'ai une tâche de rake qui nécessite trois options de ligne de commande. Voici comment je l'invoque:

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

C'est une syntaxe très propre, simple et juste bash, que j'aime bien. Voici ma tâche de rake. Aussi très propre et pas de magie:

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

Cet exemple particulier ne montre pas l'utilisation de dépendances. Mais si le :import La tâche dépendait des autres, ils auraient également accès à ces options. Mais en utilisant la méthode des options de rake normales, ils ne le feraient pas.

19
Dogweather

Bien que ces solutions fonctionnent, à mon avis, cela est trop compliqué.

De plus, si vous le faites de cette manière dans zsh, vous obtiendrez des erreurs si les crochets de votre tableau ne sont pas masqués avec '\'.

Je recommande d'utiliser le tableau ARGV, qui fonctionne bien, est beaucoup plus simple et moins sujet aux erreurs. Par exemple:

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

ensuite

rake my_example:my_task 1 2 3

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

La seule chose que vous devez garder à l'esprit est que ARGV [0] est le nom du processus, utilisez donc uniquement ARGV [1 ..- 1].

Je me rends compte que, à proprement parler, cela ne répond pas à la question, car il ne fait pas usage de: l'environnement comme partie intégrante de la solution. Mais OP n'a pas expliqué pourquoi il avait inclus cette stipulation, elle pourrait donc toujours s'appliquer à son cas d'utilisation.

10
Lonny Eachus