web-dev-qa-db-de.com

Wie übergebe ich Argumente in eine Rake-Task mit einer Umgebung in Rails?

Ich kann folgende Argumente vorbringen:

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

Ich kann auch die aktuelle Umgebung für eine Rails Anwendung laden

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

Was ich tun möchte, ist in der Lage zu sein, Variablen und Umgebung zu haben

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

Dies ist jedoch kein gültiger Taskaufruf. Weiß jemand, wie ich das erreichen kann?

207
Will

TLDR;

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

Ursprüngliche Antwort

Wenn Sie Argumente an Rake-Tasks übergeben, können Sie die Umgebung mit der Option: needs anfordern. Beispielsweise:


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

Aktualisiert per @ Peiniau Kommentar unten

Wie für Rails> 3.1

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

Benutzen Sie bitte

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

Nur um diesem alten Thema nachzugehen; Hier ist, was ich denke, ein aktuelles Rakefile (seit langer Zeit) dort tun sollte. Es ist eine aktualisierte und fehlerbehebte Version der aktuellen Gewinnerantwort (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

So rufen Sie es auf ( http://guides.rubyonrails.org/v4.2/command_line.html#rake ):

  rake "hello[World]" 

Für mehrere Argumente fügen Sie einfach ihre Schlüsselwörter in das Array der Task-Deklaration ein (task :hello, [:a,:b,:c]...), und übergeben Sie sie durch Kommas getrennt:

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

Hinweis: Die Anzahl der Argumente wird nicht überprüft, sodass der ungerade Planet weggelassen wird :)

368
inger

Der Vollständigkeit halber hier das oben erwähnte Beispiel aus 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

Anmerkungen:

  • Sie können den #with_defaults - Aufruf natürlich weglassen.
  • Sie müssen ein Array für Ihre Argumente verwenden, auch wenn es nur eines gibt.
  • Die Voraussetzungen müssen kein Array sein.
  • args ist eine Instanz von Rake::TaskArguments.
  • t ist eine Instanz von Rake::Task.
59
mikezter

Eine andere Möglichkeit, dies zu tun: Verwenden Sie Umgebungsvariablen des Betriebssystems. Vorteile dieses Ansatzes:

  • Alle abhängigen Rechenaufgaben erhalten die Optionen.
  • Die Syntax ist viel einfacher, unabhängig von der Rake-DSL, die schwer herauszufinden ist und sich im Laufe der Zeit ändert.

Ich habe eine Rechenaufgabe, die drei Befehlszeilenoptionen erfordert. So rufe ich es auf:

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

Das ist sehr sauber, einfach und nur bash-Syntax, die ich mag. Hier ist meine Rechenaufgabe. Auch sehr sauber und keine 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

In diesem speziellen Beispiel wird die Verwendung von Abhängigkeiten nicht gezeigt. Aber wenn das :import Die Aufgabe war von anderen abhängig, sie hatten auch Zugriff auf diese Optionen. Bei Verwendung der normalen Rake-Optionsmethode würde dies jedoch nicht der Fall sein.

19
Dogweather

Während diese Lösungen funktionieren, ist dies meiner Meinung nach zu kompliziert.

Wenn Sie dies in zsh auf diese Weise tun, werden Fehler angezeigt, wenn die Klammern in Ihrem Array nicht mit '\' maskiert sind.

Ich empfehle die Verwendung des ARGV-Arrays, das gut funktioniert, viel einfacher und weniger fehleranfällig ist. Z.B:

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

dann

rake my_example:my_task 1 2 3

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

Das einzige, was Sie beachten müssen, ist, dass ARGV [0] der Prozessname ist. Verwenden Sie daher nur ARGV [1 ..- 1].

Mir ist klar, dass genau genommen die Frage nicht beantwortet wird, da Umwelt als Teil der Lösung nicht verwendet wird. OP gab jedoch nicht an, warum er diese Bestimmung aufgenommen hatte, sodass sie möglicherweise immer noch für seinen Anwendungsfall gilt.

10
Lonny Eachus