Birden çok veritabanına bir değer eklemek için bir komisyon görevi var.
Bu değeri komut satırından veya başka bir komisyon görevinden komisyon görevine geçirmek istiyorum .
Bunu nasıl yapabilirim?
Birden çok veritabanına bir değer eklemek için bir komisyon görevi var.
Bu değeri komut satırından veya başka bir komisyon görevinden komisyon görevine geçirmek istiyorum .
Bunu nasıl yapabilirim?
Yanıtlar:
seçenekler ve bağımlılıklar dizilerin içinde olmalıdır:
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
Sonra
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"}
NOT: Değişken
task
görev nesnesidir, Rake içlerini bilmiyorsanız / önemsemediğiniz sürece çok yararlı değildir.
RAYLAR NOT:
Görevi raylardan çalıştırıyorsanız, bağımlı görevleri
=> [:environment]
kurmanın bir yolunu ekleyerek ortamı önceden yüklemek en iyisidir .
task :work, [:option, :foo, :bar] => [:environment] do |task, args|
puts "work", args
end
rake thing:work[1, 2, 3]
işe yaramaz ve bir hata alırsınızDon't know how to build task
rake thing:work'[1,2,3]'
rake thing:work\[1,2,3\]
veya burake 'thing:work[1,2,3]'
:environment
sembolü görevinizden çıkarabilirsiniz . raylar uygulamaları bir: çevre görevi var ...
t
araçlar task
, neden sadece kullanmayın task
param adı olarak?
Görev çağrısına sembol bağımsız değişkenleri ekleyerek komisyonda resmi bağımsız değişkenler belirleyebilirsiniz. Örneğin:
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
Ardından, komut satırından:
> komisyon my_task [1, false] Bağımsız değişkenler: Rake :: TaskArguments sınıfının {: arg1 => "1",: arg2 => "false"} arg1 oldu: '1' sınıf String arg2: Sınıf String'in 'false' değeri > komisyon "my_task [1, 2]" Bağımsız değişkenler: {: arg1 => "1",: arg2 => "2"} > rake Instagram Hesabındaki Resim ve Videoları invoke_my_task Bağımsız değişkenler: {: arg1 => "1",: arg2 => "2"} > komisyon invoke_my_task_2 Bağımsız değişkenler: {: arg1 => 3,: arg2 => 4} > ön koşullu komisyon [5,6] Bağımsız değişkenler: {: arg1 => "5",: arg2 => "6"} > de_defaults ile komisyon Varsayılanları olan bağımsız değişkenler şunlardı: {: arg1 =>: varsayılan_1,: arg2 =>: varsayılan_2} > ifla_defaults ['x', 'y'] Varsayılanları olan bağımsız değişkenler şunlardı: {: arg1 => "x",: arg2 => "y"}
İkinci örnekte gösterildiği gibi, boşluk kullanmak istiyorsanız, kabuğun boşluktaki bağımsız değişkenleri ayırmasını önlemek için hedef adının etrafındaki tırnak işaretleri gereklidir.
Rake.rb dosyasındaki koda bakıldığında , komisyonun önkoşullar için bağımsız değişkenler ayıklamak üzere görev dizelerini ayrıştırmadığı anlaşılamaz task :t1 => "dep[1,2]"
. Bir ön koşul olduğu gibi, bağımlı görev eylem içinde açıkça çağırmak olacaktır tek yolu farklı argüman belirtmek :invoke_my_task
ve :invoke_my_task_2
.
Bazı mermilerin (zsh gibi) parantezlerden kaçmanızı gerektirdiğini unutmayın: rake my_task\['arg1'\]
WARNING: 'task :t, arg, :needs => [deps]' is deprecated. Please use 'task :t, [args] => [deps]' instead.
zsh: no matches found: ...
parantez kaçmak gerekir, böylece): rake my_task\['arg1'\]
. Gönderen robots.thoughtbot.com/post/18129303042/...
Kch tarafından cevap vermenin yanı sıra (buna nasıl bir yorum bırakacağım, üzgünüm):
ENV
Komuttan önce değişkenleri değişken olarak belirtmeniz gerekmez rake
. Bunları normal komut satırı parametreleri olarak şu şekilde ayarlayabilirsiniz:
rake mytask var=foo
ve komisyon dosyanızdaki gibi ENV değişkenleri olarak bunlara erişin:
p ENV['var'] # => "foo"
p
demek?
Adlandırılmış bağımsız değişkenleri (örneğin standart ile OptionParser
) iletmek isterseniz, bunun gibi bir şey kullanabilirsiniz:
$ rake user:create -- --user test@example.com --pass 123
--
bunun standart Rake argümanlarını atlamak için gerekli olduğunu unutmayın . Komisyon 0.9.x , <= 10.3.x ile çalışmalıdır .
Yeni Komisyon ayrıştırmasını değiştirdi --
ve şimdi bunun OptionParser#parse
yönteme geçmediğinden emin olmalısınız , örneğinparser.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
sonunda ekstra argümanların Komisyon görevi olarak yorumlanmamasını sağlayacaktır.
Ayrıca argüman kısayolu da çalışmalıdır:
rake user:create -- -u test@example.com -p 123
Komisyon senaryoları bu şekilde göründüğünde, belki de bunun kutudan çıkmasına izin verecek başka bir araç aramanın zamanı gelmiştir.
--option-names
. Tek önerim kullanmak olacaktır exit
ziyade abort
olarak abort
kabuğun 1 ila dönüş kodunu size bırakacaktır. Komisyon görevi daha üst düzey bir komut dosyasının parçasıysa, sıfır dışında bir çıkışın bir tür hata olduğunu varsaymak daha yaygındır.
--
mu? rake
Asıl göreve veya başka bir şeye argüman iletmek gibi mi? Beğendim task :my_task, :*args do |t, args|
falan?
{username}
burada ne için olduğunu anlamıyorum . Nerede kullanılır? Neden orada değil -u {username}
? Şerefe
10.4.1
ve geri alındı 10.4.2
. github.com/ruby/rake/commit/…
Bu iki web sitesinden cevap buldum: Net Maniac ve Aimred .
Bu tekniği kullanmak için> 0.8 tırmık sürüme sahip olmanız gerekir
Normal komisyon görevi açıklaması şudur:
desc 'Task Description'
task :task_name => [:depends_on_taskA, :depends_on_taskB] do
#interesting things
end
Argümanları iletmek için üç şey yapın:
Koddaki bağımsız değişkenlere erişmek için args.arg_name komutunu kullanın
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
Bu görevi komut satırından çağırmak için [] s
rake task_name['Hello',4]
çıktı olacak
Hello
Hello
Hello
Hello
ve bu görevi başka bir görevden çağırıp bağımsız değişkenlerini iletmek istiyorsanız, invoke komutunu kullanın
task :caller do
puts 'In Caller'
Rake::Task[:task_name].invoke('hi',2)
end
sonra komut
rake caller
çıktı olacak
In Caller
hi
hi
Aşağıdaki kod kırıldığı gibi, bağımlılık bir parçası olarak bağımsız değişkenler geçmek için bir yol bulamadık:
task :caller => :task_name['hi',2]' do
puts 'In Caller'
end
'task :t, arg, :needs => [deps]' is deprecated. Please use 'task :t, [args] => [deps]' instead.
Yaygın olarak kullanılan bir başka seçenek de ortam değişkenlerini geçirmektir. Kodunuzda bunları okursunuz ENV['VAR']
ve rake
komuttan hemen önce geçirebilirsiniz , örneğin
$ VAR=foo rake mytask
rake blah -- --these --go --to --a-program
( --
tırmığın anahtarlarının bittiğini söylemek için not edin ), bkz. stackoverflow.com/questions/5086224/…
Ben bunu çözene kadar nasıl args ve ayrıca: çevre geçmek anlayamadık:
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
Sonra şöyle diyorum:
rake db:export['foo, /tmp/']
desc 'an updated version'
task :task_name, [:arg1, :arg2] => [:dependency1, :dependency2] do |t, args|
puts args[:arg1]
end
rake task_name[hello, world]
Sadece koşmak istedim:
$ rake some:task arg1 arg2
Basit, değil mi? (Hayır!)
Komisyon, yorum olarak arg1
ve arg2
görevler olarak çalışır ve bunları çalıştırmaya çalışır. Bu yüzden sadece iptal etmeden önce iptal ediyoruz.
namespace :some do
task task: :environment do
arg1, arg2 = ARGV
# your task...
exit
end
end
Al şunu, parantez!
Feragatname : Bunu oldukça küçük bir evcil hayvan projesinde yapmak istedim. Tırmık görevlerini zincirleme yeteneğinizi (yani rake task1 task2 task3
) kaybettiğiniz için "gerçek dünya" kullanımı için tasarlanmamıştır . IMO buna değmez. Sadece çirkin kullanın rake task[arg1,arg2]
.
_, arg1, arg2 = ARGV
ilk argüman olarak yapmak gerekiyordu, komisyon görevinin adı olarak görülüyordu. Ama bu exit
temiz bir numara.
rake task[arg1,arg2] && rake task2 && rake task3
Bundan daha çirkin olup olmadığından emin değilim rake task[arg1,arg2] task2 task3
. Muhtemelen daha az verimli.
_, *args = ARGV
sonraki tüm argümanları yakalamak için mükemmel! Teşekkürler yığınları!
Komisyon dosyasında düzenli bir yakut argümanı kullanıyorum:
DB = ARGV[1]
daha sonra dosyanın altındaki komisyon görevlerini sapladım (çünkü komisyon bu argüman adına dayalı bir görev arayacaktır).
task :database_name1
task :database_name2
Komut satırı:
rake mytask db_name
bu bana var = foo ENV var ve görev argümanlarından [blah, blah2] daha temiz geliyor.
saplama biraz cenky, ama sadece bir kerelik kurulum olan birkaç ortamınız varsa çok kötü değil
dup
için, sonunda kullanın : db = ARGV [1] .dup
db = ARGV[1].dup unless ARGV[1].nil?
Bir nil çoğaltma istisna önlemek için daha iyi olay .
Tartışmayı iletmenin yolları yukarıdaki cevapta doğrudur. Bununla birlikte, komisyon görevini argümanlarla çalıştırmak için, rayların daha yeni versiyonunda küçük bir teknik vardır
Komisyon "namespace: taskname ['argument1']" ile çalışır
Görevi komut satırından çalıştırırken Ters tırnaklara dikkat edin.
Varsayılan göreve argüman iletmek için böyle bir şey yapabilirsiniz. Örneğin, argümanınız "sürüm" deyin:
task :default, [:version] => [:build]
task :build, :version do |t,args|
version = args[:version]
puts version ? "version is #{version}" : "no version passed"
end
Sonra şöyle diyebilirsiniz:
$ rake
no version passed
veya
$ rake default[3.2.1]
version is 3.2.1
veya
$ rake build[3.2.1]
version is 3.2.1
Ancak, argümanlar iletirken görev adını (varsayılan veya derleme) belirtmekten kaçınmanın bir yolunu bulamadım. Herkes bir yol biliyorsa duymak isterim.
Özellikle geçirilecek argümanlar çok olduğunda, argüman geçen "querystring" sözdizimi gibi.
Misal:
rake "mytask[width=10&height=20]"
"Querystring" varlık:
width=10&height=20
Uyarı: sözdiziminin rake "mytask[foo=bar]"
ve NOT rake mytask["foo=bar"]
Kullanarak tırmıklama görevinin içinde ayrıştırıldığında Rack::Utils.parse_nested_query
şunları elde ederiz Hash
:
=> {"width"=>"10", "height"=>"20"}
(Harika olan şey, daha fazla karma ve dizileri geçebilmenizdir)
Bunu başarmak için:
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
İşte benim delayed_job_active_record_threaded gem Rails ile kullandığım daha genişletilmiş bir örnek :
bundle exec rake "dj:start[ebooks[workers_number]=16&ebooks[worker_timeout]=60&albums[workers_number]=32&albums[worker_timeout]=120]"
Ortam bağımlılığına sahip olarak yukarıdakiyle aynı şekilde ayrıştırılır (Rails ortamını yüklemek için)
namespace :dj do
task :start, [ :args_expr ] => :environment do |t, args|
# defaults here...
options = Rack::Utils.parse_nested_query(args[:args_expr])
end
end
Aşağıdakileri verir: options
=> {"ebooks"=>{"workers_number"=>"16", "worker_timeout"=>"60"}, "albums"=>{"workers_number"=>"32", "worker_timeout"=>"120"}}
Eğer ne için argüman pozisyonunun ne olduğunu hatırlamaktan rahatsız olamazsanız ve yakut argüman karması gibi bir şey yapmak istersiniz. Bir dizeyi iletmek için bir argüman kullanabilir ve ardından bu dizeyi bir seçenekler karmasına yeniden düzenleyebilirsiniz.
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
Ve komut satırında olsun.
$ 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
Yukarıda açıklanan yöntemlerin çoğu benim için işe yaramadı, belki de yeni sürümlerde kullanımdan kaldırıldı. Güncel kılavuzu şu adreste bulabilirsiniz: http://guides.rubyonrails.org/command_line.html#custom-rake-tasks
rehberden bir kopyala ve yapıştır ans burada:
task :task_name, [:arg_1] => [:pre_1, :pre_2] do |t, args|
# You can use args from here
end
Bu şekilde çağır
bin/rake "task_name[value 1]" # entire argument string should be quoted
Komisyon görevlerini geleneksel argümanlar stiliyle çalıştırmak için:
rake task arg1 arg2
Ve sonra kullanın:
task :task do |_, args|
puts "This is argument 1: #{args.first}"
end
Komisyon geminin aşağıdaki yamasını ekleyin:
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
Parametreleri iletirken, daha iyi bir seçenek bir giriş dosyasıdır, bu bir excel olabilir veya ihtiyacınız olan her şey olabilir ve oradan ihtiyaç duyduğunuz değişken adını da içeren veri yapısını ve değişkenleri okuyabilirsiniz. Bir dosyayı okumak için aşağıdaki yapıya sahip olabilir.
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
{
"name_task": "I'm a task",
"user_id": 389,
"users_assigned": [389,672,524],
"task_id": 3
}
rake :name_task