Frage Wie übergeben Sie Befehlszeilenargumente an eine Rake-Aufgabe


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

Ich möchte diesen Wert von der Befehlszeile oder von der Rake-Aufgabe übergeben Ein weiterer Rechenaufgabe.

Wie kann ich das machen?


950
2018-05-05 16:27


Ursprung


Antworten:


Optionen und Abhängigkeiten müssen innerhalb von Arrays sein:

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

Dann

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"}

HINWEIS: Variable task ist das Objekt der Aufgabe, nicht sehr hilfreich, es sei denn, Sie wissen / kümmern sich über Rake Interna.

Schienen HINWEIS:

Wenn Sie die Aufgabe von Rails ausführen, laden Sie die Umgebung am besten vorab => [:environment] Das ist eine Möglichkeit zum Einrichten abhängig Aufgaben.

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

229
2018-04-07 21:56



Sie können formale Argumente in Rake angeben, indem Sie dem Taskaufruf Symbolargumente hinzufügen. Beispielsweise:

require 'rake'

task :my_task, [:arg1, :arg2] do |t, args|
  puts "Args were: #{args}"
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 von der Befehlszeile aus:

> rake my_task [1,2]
Argumente waren: {: arg1 => "1",: arg2 => "2"}

> harken "my_task [1, 2]"
Argumente waren: {: arg1 => "1",: arg2 => "2"}

> Rake invoke_my_task
Argumente waren: {: arg1 => "1",: arg2 => "2"}

> Rake invoke_my_task_2
Argumente waren: {: arg1 => 3,: arg2 => 4}

> Rake mit_vorraus [5,6]
Argumente waren: {: arg1 => "5",: arg2 => "6"}

> rake with_defaults
Argumente mit Standardwerten waren: {: arg1 =>: default_1,: arg2 =>: default_2}

> rake with_defaults ['x', 'y']
Argumente mit Standardwerten waren: {: arg1 => "x",: arg2 => "y"}

Wie im zweiten Beispiel gezeigt, sind die Anführungszeichen um den Zielnamen erforderlich, damit die Shell die Argumente im Bereich nicht aufteilt.

Blick auf den Code in rake.rbscheint es, dass Rake Task-Strings nicht analysiert, um Argumente für Voraussetzungen zu extrahieren, was Sie nicht tun können task :t1 => "dep[1,2]". Die einzige Möglichkeit, verschiedene Argumente für eine Voraussetzung anzugeben, besteht darin, sie explizit innerhalb der abhängigen Aufgabenaktion aufzurufen, wie in :invoke_my_task und :invoke_my_task_2.

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


1081
2018-05-05 16:45



Zusätzlich zu antworten von kch (Ich habe nicht gefunden, wie man einen Kommentar dazu, tut mir leid):

Sie müssen keine Variablen als angeben ENV Variablen vor dem rake Befehl. Sie können sie einfach als übliche Befehlszeilenparameter einstellen:

rake mytask var=foo

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

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

287
2018-02-19 11:05



Wenn Sie benannte Argumente übergeben möchten (z. B. mit Standard OptionParser) Sie könnten so etwas verwenden:

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

beachten Sie das --, das ist notwendig, um Standard-Rake-Argumente zu umgehen. Sollte mit Rake arbeiten 0.9.x, <= 10.3.x.

Neuere Rake hat sein Parsing geändert --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 wird sichergestellt, dass die zusätzlichen Argumente nicht als Rake-Task interpretiert werden.

Auch die Verknüpfung für Argumente sollte funktionieren:

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

Wenn Rake-Skripts so aussehen, ist es vielleicht an der Zeit, nach einem anderen Tool zu suchen, das dies sofort ermöglicht.


94
2017-10-19 13:09



Ich habe die Antwort von diesen beiden Websites gefunden: Net Maniac und Aimred.

Sie müssen eine Version> 0.8 Rake haben, 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, mache drei Dinge:

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

Verwenden Sie args.arg_name, um auf die Argumente im Skript zuzugreifen

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 Task über die Befehlszeile aufzurufen, übergeben Sie ihr die Argumente in [] s

rake task_name['Hello',4]

wird ausgegeben

Hello
Hello
Hello
Hello

Wenn Sie diese Aufgabe von einer anderen Aufgabe aufrufen und Argumente übergeben möchten, 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 weiterzugeben, da der folgende Code bricht:

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

56
2018-05-05 16:51



Eine andere häufig verwendete Option besteht darin, Umgebungsvariablen zu übergeben. In Ihrem Code lesen Sie sie über ENV['VAR']und kann sie direkt vor der rake Befehl, wie

$ VAR=foo rake mytask

30
2018-05-05 16:53



Eigentlich @Nick Desjardins antwortete perfekt. Aber nur für die Bildung: Sie können schmutzigen Ansatz verwenden: Verwenden ENV Streit

task :my_task do
  myvar = ENV['myvar']
  puts "myvar: #{myvar}"
end 

rake my_task myvar=10
#=> myvar: 10

30
2018-02-28 20:06



Ich konnte nicht herausfinden, wie man Args und auch die Umgebung übergibt, bis ich das herausgefunden habe:

namespace :db do
  desc 'Export product data'
  task :export, [:file_token, :file_path] => :environment do |t, args|
    args.with_defaults(:file_token => "products", :file_path => "./lib/data/")

       #do stuff [...]

  end
end

Und dann rufe ich so an:

rake db:export['foo, /tmp/']

24
2017-11-29 19:38



desc 'an updated version'
task :task_name, [:arg1, :arg2] => [:dependency1, :dependency2] do |t, args|
    puts args[:arg1]
end

23
2017-10-16 07:36



Ich verwende ein reguläres Ruby-Argument in der Rake-Datei:

DB = ARGV[1]

dann stemple ich die Rake-Aufgaben am Ende der Datei aus (da Rake nach einer Aufgabe sucht, die auf diesem Argumentnamen basiert).

task :database_name1
task :database_name2

Befehlszeile:

rake mytask db_name

das fühlt sich sauberer an als die var = foo ENV var und die Task args [blah, blah2] -Lösungen.
Der Stub ist ein wenig junky, aber nicht so schlecht, wenn Sie nur ein paar Umgebungen haben, die einmalig eingerichtet sind


13
2017-12-29 02:48



Ich wollte nur laufen können:

$ rake some:task arg1 arg2

Einfach, oder? (Nee!)

Rake interpretiert arg1 und arg2 als Aufgaben und versucht sie auszuführen. Also brechen wir einfach ab, bevor es geht.

namespace :some do
  task task: :environment do
    arg1, arg2 = ARGV

    # your task...

    exit
  end
end

Nimm das, Klammern!

Haftungsausschluss: Ich wollte das in einem hübschen kleinen Haustierprojekt machen können. Nicht für die "echte" Verwendung gedacht, da Sie die Fähigkeit verlieren, Rake-Aufgaben zu ketten (d. H. rake task1 task2 task3). IMO ist es nicht wert. Benutze einfach das Hässliche rake task[arg1,arg2].


12
2018-04-29 03:29