Wie erfolgt die Befehlszeilenargumente an eine Rake Aufgabe übergeben
-
05-07-2019 - |
Frage
Ich habe eine Harke Aufgabe, die einen Wert in mehrere Datenbanken einfügen muss.
Ich mag diesen Wert in die Rake-Aufgabe von der Kommandozeile zu übergeben, oder von andere Rake Aufgabe.
Wie kann ich das tun?
Lösung
Optionen und Abhängigkeiten müssen innerhalb 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 die Aufgabe Objekt, nicht sehr hilfreich, wenn Sie / Pflege über Rake Interna kennen.
SCHIENEN HINWEIS:
, um die Aufgabe von Schienen Wenn ausgeführt wird, seine besten die Umwelt vorzuladen durch
=> [:environment]
Zugabe, die eine Möglichkeit zur Einrichtung ist abhängig Aufgaben.
task :work, [:option, :foo, :bar] => [:environment] do |task, args|
puts "work", args
end
Andere Tipps
Sie können die formalen Argumente in Rake angeben, indem Symbol Argumente, um die Aufgabe Gespräch hinzugefügt. Zum Beispiel:
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 wird aus der Befehlszeile ein:
> rake my_task[1,2] Args were: {:arg1=>"1", :arg2=>"2"} > 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, wenn Sie möchten, Räume nutzen, die Anführungszeichen um die Zielnamen sind notwendig, um die Schale zu verhindern, die Argumente in dem Raum Aufspaltung.
auf den Code der Suche in rake.rb , scheint es, dass Rake nicht Aufgabe Strings analysieren Argumente für die erforderlichen Komponenten zu extrahieren, so dass Sie nicht task :t1 => "dep[1,2]"
tun können. Die einzige Möglichkeit, verschiedene Argumente angeben, für eine Voraussetzung innerhalb der abhängigen Aufgabe Aktion explizit aufrufen würde, wie in :invoke_my_task
und :invoke_my_task_2
.
Beachten Sie, dass einige Shells (wie zsh) benötigen Sie die Klammern zu entkommen: rake my_task\['arg1'\]
Zusätzlich von KCH zu beantworten (ich habe nicht gefunden, wie um einen Kommentar zu bewenden lassen, sorry):
Sie müssen keine Variablen wie ENV
Variablen vor dem rake
Befehl angeben. Sie können einstellen, sie wie gewohnt Kommandozeilenparameter wie folgt aus:
rake mytask var=foo
und Zugriff auf diejenigen aus dem Rake-Datei als ENV Variablen wie so:
p ENV['var'] # => "foo"
Wenn Sie benannte Argumente zu übergeben (zum Beispiel mit Standard OptionParser
) Sie so etwas wie diese verwenden:
$ rake user:create -- --user test@example.com --pass 123
beachten Sie die --
, dass zur Umgehung Standard Rake Argumente notwendig ist. Sollte die Arbeit mit Rechen 0.9.x , <= 10.3.x .
Neuere Rake hat seine Parsen von --
geändert, und jetzt haben Sie es nicht auf die OptionParser#parse
Methode übergeben stellen Sie sicher, 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 dafür sorgen, dass die zusätzlichen Argumente werden nicht als Rake Aufgabe interpretiert werden.
Auch sollte die Abkürzung für Argumente arbeiten:
rake user:create -- -u test@example.com -p 123
Wenn Rake-Skripte so aussehen, vielleicht ist es Zeit für ein anderes Werkzeug zu suchen, die diese gerade aus der Box erlauben würden.
Ich habe die Antwort aus diesen beiden Websites gefunden: Net Maniac und Aimred .
Sie müssen Version haben> 0,8 Rake diese Technik zu verwenden
Die normale Rake Aufgabenbeschreibung ist dies:
desc 'Task Description'
task :task_name => [:depends_on_taskA, :depends_on_taskB] do
#interesting things
end
Argumente zu übergeben, drei Dinge tun:
- Fügen Sie die Argumentnamen nach dem Task-Namen durch Kommas getrennt.
- Legen Sie die Abhängigkeiten am Ende mit: needs => [...]
- Platz | t, args | nach dem do. (T ist die Aufgabe für diese Aufgabe)
Um die Argumente im Skript zuzugreifen, verwenden 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 rufen Sie von der Kommandozeile, übergeben Sie die Argumente in [] s
rake task_name['Hello',4]
Wille Ausgang
Hello
Hello
Hello
Hello
und wenn Sie möchten, aus einer anderen Aufgabe, diese Aufgabe rufen, und übergibt es Argumente, die Verwendung invoke
task :caller do
puts 'In Caller'
Rake::Task[:task_name].invoke('hi',2)
end
dann der Befehl
rake caller
Wille Ausgang
In Caller
hi
hi
Ich habe einen Weg gefunden Argumente als Teil einer Abhängigkeit zu übergeben, wie die folgenden Code Pausen:
task :caller => :task_name['hi',2]' do
puts 'In Caller'
end
Eine andere häufig verwendete Option ist Umgebungsvariablen zu übergeben. In Ihrem Code lesen Sie sie über ENV['VAR']
, und kann sie direkt vor dem rake
Befehl übergeben, wie
$ VAR=foo rake mytask
Eigentlich beantwortet @ Nick Desjardins perfekt. Aber nur für die Ausbildung: Sie schmutzig Ansatz verwenden: using ENV
Argument
task :my_task do
myvar = ENV['myvar']
puts "myvar: #{myvar}"
end
rake my_task myvar=10
#=> myvar: 10
Ich kann nicht herausfinden, wie args passieren und auch die: Umgebung, bis ich das herausgearbeitet:
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 wie folgt aus:
rake db:export['foo, /tmp/']
desc 'an updated version'
task :task_name, [:arg1, :arg2] => [:dependency1, :dependency2] do |t, args|
puts args[:arg1]
end
Ich wollte nur in der Lage sein zu laufen:
$ rake some:task arg1 arg2
Einfach, nicht wahr? (Nein!)
Rake interpretiert arg1
und arg2
als Aufgaben und versucht, sie laufen zu lassen. Also haben wir einfach abbrechen, bevor es der Fall ist.
namespace :some do
task task: :environment do
arg1, arg2 = ARGV
# your task...
exit
end
end
Nehmen Sie das, Klammern!
Hinweis : Ich wollte diese in einem ziemlich kleines Haustier Projekt in der Lage sein zu tun. Nicht für „reale Welt“ Nutzung, da Sie die Möglichkeit, Ketten Rake Aufgaben (das heißt rake task1 task2 task3
) verlieren. IMO nicht wert. Verwenden Sie einfach das hässliche rake task[arg1,arg2]
.
Ich verwende ein regelmäßigen rubin Argument in der Rake-Datei:
DB = ARGV[1]
I Stub dann die Rake-Aufgaben am Ende der Datei (seit Rechen für eine Aufgabe auf diesem Argument Namen basierte aussehen werden).
task :database_name1
task :database_name2
Befehlszeile:
rake mytask db_name
das fühlt sich sauberer mir als die var = foo ENV var und die Aufgabe args [blah, blah2] Lösungen.
der Stub ist ein wenig jenky, aber nicht so schlimm, wenn man nur ein paar Umgebungen, die eine einmalige Setup
Die Wege Argument übergeben sind richtig in oben Antwort. Allerdings Rake Aufgabe mit Argumenten zu laufen, gibt es eine kleine Technisierung in neuerer Version von Schienen beteiligt
Es wird mit Harke arbeiten "Namespace: Taskname [ 'argument1']"
Beachten Sie die Inverted Anführungszeichen in die Aufgabe von der Kommandozeile ausgeführt werden.
Ich mag die „Abfragezeichen“ Syntax für Argumentübergabe, vor allem, wenn es viele Argumente übergeben werden.
Beispiel:
rake "mytask[width=10&height=20]"
Die "Abfragezeichenfolgeflag" Wesen:
width=10&height=20
Achtung: Beachten Sie, dass die Syntax rake "mytask[foo=bar]"
und nicht rake mytask["foo=bar"]
Wenn innerhalb der Rake Aufgabe mit Rack::Utils.parse_nested_query
analysiert, erhalten wir eine Hash
:
=> {"width"=>"10", "height"=>"20"}
(Die kühle Sache ist, dass man Hashes und Arrays passieren kann, mehr unten)
Dies ist, wie dies zu erreichen:
require 'rack/utils'
task :mytask, :args_expr do |t,args|
args.with_defaults(:args_expr => "width=10&height=10")
options = Rack::Utils.parse_nested_query(args[:args_expr])
end
Hier ist ein ausgedehntere Beispiel, dass ich mit Rails bin in meinem delayed_job_active_record_threaded gem:
bundle exec rake "dj:start[ebooks[workers_number]=16&ebooks[worker_timeout]=60&albums[workers_number]=32&albums[worker_timeout]=120]"
Analysierte die gleiche Art und Weise wie oben, mit einer Umgebung Abhängigkeit (um die Rails-Umgebung laden)
namespace :dj do
task :start, [ :args_expr ] => :environment do |t, args|
# defaults here...
options = Rack::Utils.parse_nested_query(args[:args_expr])
end
end
Gibt die folgende in options
=> {"ebooks"=>{"workers_number"=>"16", "worker_timeout"=>"60"}, "albums"=>{"workers_number"=>"32", "worker_timeout"=>"120"}}
Um Argumente an das Default-Task übergeben, können Sie etwas tun. Zum Beispiel, sagen "Version" ist Ihr Argument:
task :default, [:version] => [:build]
task :build, :version do |t,args|
version = args[:version]
puts version ? "version is #{version}" : "no version passed"
end
Dann können Sie es wie so nennen:
$ rake
no version passed
oder
$ rake default[3.2.1]
version is 3.2.1
oder
$ rake build[3.2.1]
version is 3.2.1
Allerdings habe ich keine Möglichkeit zu vermeiden, unter Angabe der Vorgangsnamen (default oder Build) beim Durchgang in Argumente gefunden. Würde gerne hören, wenn jemand einen Weg kennt.
Die meisten der oben beschriebenen Methoden nicht für mich arbeiten, vielleicht sind sie in den neueren Versionen veraltet. Das up-to-date Guide finden Sie hier: http: //guides.rubyonrails .org / command_line.html # custom-Rake-Aufgaben
a copy-and-paste am aus der Führung ist hier:
task :task_name, [:arg_1] => [:pre_1, :pre_2] do |t, args|
# You can use args from here
end
Rufen Sie es wie folgt
bin/rake "task_name[value 1]" # entire argument string should be quoted
Wenn Sie nicht gestört werden, können sich daran zu erinnern, was Argument Position für das, was ist, und Sie wollen etwas tun, wie ein Rubin Argument Hash. Sie können ein Argument in einer Zeichenfolge zu übergeben und dann diese Zeichenfolge in eine Hash-Optionen regex.
namespace :dummy_data do
desc "Tests options hash like arguments"
task :test, [:options] => :environment do |t, args|
arg_options = args[:options] || '' # nil catch incase no options are provided
two_d_array = arg_options.scan(/\W*(\w*): (\w*)\W*/)
puts two_d_array.to_s + ' # options are regexed into a 2d array'
string_key_hash = two_d_array.to_h
puts string_key_hash.to_s + ' # options are in a hash with keys as strings'
options = two_d_array.map {|p| [p[0].to_sym, p[1]]}.to_h
puts options.to_s + ' # options are in a hash with symbols'
default_options = {users: '50', friends: '25', colour: 'red', name: 'tom'}
options = default_options.merge(options)
puts options.to_s + ' # default option values are merged into options'
end
end
Und auf der Kommandozeile Sie erhalten.
$ rake dummy_data:test["users: 100 friends: 50 colour: red"]
[["users", "100"], ["friends", "50"], ["colour", "red"]] # options are regexed into a 2d array
{"users"=>"100", "friends"=>"50", "colour"=>"red"} # options are in a hash with keys as strings
{:users=>"100", :friends=>"50", :colour=>"red"} # options are in a hash with symbols
{:users=>"100", :friends=>"50", :colour=>"red", :name=>"tom"} # default option values are merged into options
Um Rake Aufgaben mit traditionellen Argumenten Stil ausführen:
rake task arg1 arg2
Und dann verwenden:
task :task do |_, args|
puts "This is argument 1: #{args.first}"
end
In der Harke gem folgende Patch:
Rake::Application.class_eval do
alias origin_top_level top_level
def top_level
@top_level_tasks = [top_level_tasks.join(' ')]
origin_top_level
end
def parse_task_string(string) # :nodoc:
parts = string.split ' '
return parts.shift, parts
end
end
Rake::Task.class_eval do
def invoke(*args)
invoke_with_call_chain(args, Rake::InvocationChain::EMPTY)
end
end
Parameter Während vorbei, ist es bessere Option ist, eine Eingabedatei, kann dies eine Excel sein ein json oder was auch immer Sie brauchen, und von dort aus der Datenstruktur zu lesen und Variablen, die Sie von diesen einschließlich der Variablennamen müssen wie die Notwendigkeit. Um eine Datei zu lesen, die folgende Struktur hat.
namespace :name_sapace_task do
desc "Description task...."
task :name_task => :environment do
data = ActiveSupport::JSON.decode(File.read(Rails.root+"public/file.json")) if defined?(data)
# and work whit yoour data, example is data["user_id"]
end
end
Beispiel json
{
"name_task": "I'm a task",
"user_id": 389,
"users_assigned": [389,672,524],
"task_id": 3
}
Ausführung
rake :name_task