1216 Stimmen

Übergabe von Kommandozeilenargumenten an einen Rake-Task

Ich habe eine Rake-Aufgabe, die einen Wert in mehrere Datenbanken einfügen muss.

Ich möchte diesen Wert an die Rake-Aufgabe von der Kommandozeile aus übergeben, oder von eine andere Rake-Aufgabe.

Wie kann ich das tun?

1194voto

Nick Desjardins Punkte 12576

Sie können in Rake formale Argumente angeben, indem Sie dem Aufgabenaufruf Symbolargumente hinzufügen. Zum Beispiel:

require 'rake'

task :my_task, [:arg1, :arg2] do |t, args|
  puts "Args were: #{args} of class #{args.class}"
  puts "arg1 was: '#{args[:arg1]}' of class #{args[:arg1].class}"
  puts "arg2 was: '#{args[:arg2]}' of class #{args[:arg2].class}"
end

task :invoke_my_task do
  Rake.application.invoke_task("my_task[1, 2]")
end

# or if you prefer this syntax...
task :invoke_my_task_2 do
  Rake::Task[:my_task].invoke(3, 4)
end

# a task with prerequisites passes its 
# arguments to it prerequisites
task :with_prerequisite, [:arg1, :arg2] => :my_task #<- name of prerequisite task

# to specify default values, 
# we take advantage of args being a Rake::TaskArguments object
task :with_defaults, :arg1, :arg2 do |t, args|
  args.with_defaults(:arg1 => :default_1, :arg2 => :default_2)
  puts "Args with defaults were: #{args}"
end

Dann geben Sie in der Befehlszeile ein:

\> rake my\_task\[1,false\]
Args were: {:arg1=>"1", :arg2=>"false"} of class Rake::TaskArguments
arg1 was: '1' of class String
arg2 was: 'false' of class String

> rake "my\_task\[1, 2\]"
Args were: {:arg1=>"1", :arg2=>"2"}

> rake invoke\_my\_task
Args were: {:arg1=>"1", :arg2=>"2"}

> rake invoke\_my\_task\_2
Args were: {:arg1=>3, :arg2=>4}

> rake with\_prerequisite\[5,6\]
Args were: {:arg1=>"5", :arg2=>"6"}

> rake with\_defaults
Args with defaults were: {:arg1=>:default\_1, :arg2=>:default\_2}

> rake with\_defaults\['x','y'\]
Args with defaults were: {:arg1=>"x", :arg2=>"y"}

Wie im zweiten Beispiel gezeigt, sind die Anführungszeichen um den Zielnamen notwendig, um die Shell daran zu hindern, die Argumente am Leerzeichen aufzuteilen, wenn Sie Leerzeichen verwenden wollen.

Ein Blick auf den Code in rake.rb Es scheint, dass Rake keine Task-Strings analysiert, um Argumente für Voraussetzungen zu extrahieren, also können Sie nicht task :t1 => "dep[1,2]" . Die einzige Möglichkeit, unterschiedliche Argumente für eine Voraussetzung anzugeben, besteht darin, sie explizit innerhalb der Aktion der abhängigen Aufgabe aufzurufen, wie in :invoke_my_task y :invoke_my_task_2 .

Beachten Sie, dass einige Shells (wie zsh) verlangen, dass Sie die Klammern entwerten: rake my_task\['arg1'\]

477voto

Blair Anderson Punkte 18077

Optionen und Abhängigkeiten müssen sich in Arrays befinden:

namespace :thing do
  desc "it does a thing"
  task :work, [:option, :foo, :bar] do |task, args|
    puts "work", args
  end

  task :another, [:option, :foo, :bar] do |task, args|
    puts "another #{args}"
    Rake::Task["thing:work"].invoke(args[:option], args[:foo], args[:bar])
    # or splat the args
    # Rake::Task["thing:work"].invoke(*args)
  end

end

Entonces

rake thing:work[1,2,3]
=> work: {:option=>"1", :foo=>"2", :bar=>"3"}

rake thing:another[1,2,3]
=> another {:option=>"1", :foo=>"2", :bar=>"3"}
=> work: {:option=>"1", :foo=>"2", :bar=>"3"}

ANMERKUNG: variabel task ist das Task-Objekt, nicht sehr hilfreich, es sei denn, Sie kennen sich mit den Interna von Rake aus.

RAILS NOTE:

Wenn Sie die Aufgabe von Rails aus starten, ist es am besten, die Umgebung vorzuladen, indem Sie => [:environment] was eine Möglichkeit ist, die abhängig Aufgaben.

  task :work, [:option, :foo, :bar] => [:environment] do |task, args|
    puts "work", args
  end

385voto

timurb Punkte 5174

In Ergänzung zur Antwort von kch (ich habe nicht gefunden, wie ich einen Kommentar dazu hinterlassen kann, sorry):

Sie müssen die Variablen nicht als ENV Variablen, bevor die rake Befehl. Sie können sie einfach als gewöhnliche Befehlszeilenparameter einstellen:

rake mytask var=foo

und greifen Sie auf diese von Ihrer Rake-Datei aus als ENV-Variablen zu:

p ENV['var'] # => "foo"

120voto

Tombart Punkte 27954

Wenn Sie benannte Argumente übergeben wollen (z. B. mit Standard OptionParser ) könnten Sie etwas wie dieses verwenden:

$ rake user:create -- --user test@example.com --pass 123

beachten Sie die -- die notwendig ist, um die Standardargumente von Rake zu umgehen. Sollte mit Rake funktionieren 0.9.x , <= 10.3.x .

Das neuere Rake hat sein Parsing von -- und jetzt müssen Sie sicherstellen, dass es nicht an die OptionParser#parse Methode, zum Beispiel mit parser.parse!(ARGV[2..-1])

require 'rake'
require 'optparse'
# Rake task for creating an account

namespace :user do |args|
  desc 'Creates user account with given credentials: rake user:create'
  # environment is required to have access to Rails models
  task :create do
    options = {}
    OptionParser.new(args) do |opts|
      opts.banner = "Usage: rake user:create [options]"
      opts.on("-u", "--user {username}","User's email address", String) do |user|
        options[:user] = user
      end
      opts.on("-p", "--pass {password}","User's password", String) do |pass|
        options[:pass] = pass
      end
    end.parse!

    puts "creating user account..."
    u = Hash.new
    u[:email] = options[:user]
    u[:password] = options[:pass]
    # with some DB layer like ActiveRecord:
    # user = User.new(u); user.save!
    puts "user: " + u.to_s
    puts "account created."
    exit 0
  end
end

exit am Ende stellt sicher, dass die zusätzlichen Argumente nicht als Rake-Aufgabe interpretiert werden.

Auch die Abkürzung für Argumente sollte funktionieren:

 rake user:create -- -u test@example.com -p 123

Wenn Rake-Skripte so aussehen, ist es vielleicht an der Zeit, sich nach einem anderen Tool umzusehen, das so etwas ohne Weiteres ermöglicht.

59voto

Tilendor Punkte 46817

Ich habe die Antwort auf diesen beiden Websites gefunden: Netz-Wahnsinniger y Aimred .

Sie benötigen eine Version > 0.8 von Rake, um diese Technik zu verwenden

Die normale Rake-Aufgabenbeschreibung lautet wie folgt:

desc 'Task Description'
task :task_name => [:depends_on_taskA, :depends_on_taskB] do
  #interesting things
end

Um Argumente zu übergeben, müssen Sie drei Dinge tun:

  1. Fügen Sie die Namen der Argumente nach dem Aufgabennamen ein, getrennt durch Kommata.
  2. Fügen Sie die Abhängigkeiten am Ende mit :needs => [...]
  3. Setzen Sie |t, args| nach dem do. (t ist das Objekt für diese Aufgabe)

Um auf die Argumente im Skript zuzugreifen, verwenden Sie args.arg_name

desc 'Takes arguments task'
task :task_name, :display_value, :display_times, :needs => [:depends_on_taskA, :depends_on_taskB] do |t, args|
  args.display_times.to_i.times do
    puts args.display_value
  end
end

Um diese Aufgabe von der Befehlszeile aus aufzurufen, übergeben Sie ihr die Argumente in []s

rake task_name['Hello',4]

wird ausgegeben

Hello
Hello
Hello
Hello

und wenn Sie diese Aufgabe von einer anderen Aufgabe aus aufrufen und ihr Argumente übergeben wollen, verwenden Sie invoke

task :caller do
  puts 'In Caller'
  Rake::Task[:task_name].invoke('hi',2)
end

dann der Befehl

rake caller

wird ausgegeben

In Caller
hi
hi

Ich habe keine Möglichkeit gefunden, Argumente als Teil einer Abhängigkeit zu übergeben, da der folgende Code nicht funktioniert:

task :caller => :task_name['hi',2]' do
   puts 'In Caller'
end

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X