ruby - एक रेक कार्य के लिए कमांड लाइन तर्क कैसे पास करें
command-line rake (12)
आप कार्य कॉल में प्रतीक तर्क जोड़कर रेक में औपचारिक तर्क निर्दिष्ट कर सकते हैं। उदाहरण के लिए:
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
फिर, कमांड लाइन से:
> 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"}
जैसा कि दूसरे उदाहरण में दिखाया गया है, यदि आप रिक्त स्थान का उपयोग करना चाहते हैं, तो शैल को अंतरिक्ष पर तर्कों को विभाजित करने के लिए लक्ष्य नाम के चारों ओर उद्धरण आवश्यक हैं।
रेक.आरबी में कोड को देखते हुए , ऐसा प्रतीत होता है कि रेक किसी भी चीज के लिए तर्क निकालने के लिए कार्य स्ट्रिंग को पार्स नहीं करता है, इसलिए आप task :t1 => "dep[1,2]"
नहीं कर सकते task :t1 => "dep[1,2]"
। किसी पूर्व शर्त के लिए अलग-अलग तर्क निर्दिष्ट करने का एकमात्र तरीका यह है कि इसे आश्रित कार्य कार्रवाई के भीतर स्पष्ट रूप से आमंत्रित करना होगा, जैसे :invoke_my_task
और :invoke_my_task_2
।
ध्यान दें कि कुछ गोले (जैसे zsh) आपको ब्रैकेट से बचने की आवश्यकता होती है: rake my_task\['arg1'\]
मेरे पास एक रेक कार्य है जिसे एकाधिक डेटाबेस में एक मूल्य डालने की आवश्यकता है।
मैं इस मान को कमांड लाइन से, या किसी अन्य रेक कार्य से रेक कार्य में पास करना चाहता हूं।
मैं यह कैसे कर सकता हूँ?
ऊपर वर्णित अधिकांश विधियों ने मेरे लिए काम नहीं किया है, शायद वे नए संस्करणों में बहिष्कृत हैं। अद्यतित गाइड यहां पाया जा सकता है: http://guides.rubyonrails.org/command_line.html#custom-rake-tasks
मार्गदर्शिका से एक कॉपी-एंड-पेस्ट उत्तर यहां है:
task :task_name, [:arg_1] => [:pre_1, :pre_2] do |t, args|
# You can use args from here
end
इसे इस तरह से आमंत्रित करें
bin/rake "task_name[value 1]" # entire argument string should be quoted
केएच द्वारा जवाब देने के अलावा (मुझे यह नहीं मिला कि उस पर टिप्पणी कैसे छोड़ें, क्षमा करें):
rake
आदेश से पहले आपको ENV
चर के रूप में चर निर्दिष्ट करने की आवश्यकता नहीं है। आप उन्हें सामान्य कमांड लाइन पैरामीटर के रूप में सेट कर सकते हैं जैसे कि:
rake mytask var=foo
और एनएनवी चर के रूप में अपनी रेक फ़ाइल से उन तक पहुंचें जैसे:
p ENV['var'] # => "foo"
डिफ़ॉल्ट कार्य में तर्क पारित करने के लिए, आप ऐसा कुछ कर सकते हैं। उदाहरण के लिए, "संस्करण" कहें आपका तर्क है:
task :default, [:version] => [:build]
task :build, :version do |t,args|
version = args[:version]
puts version ? "version is #{version}" : "no version passed"
end
फिर आप इसे इस तरह से कॉल कर सकते हैं:
$ rake
no version passed
या
$ rake default[3.2.1]
version is 3.2.1
या
$ rake build[3.2.1]
version is 3.2.1
हालांकि, मुझे तर्कों में गुजरते समय कार्य नाम (डिफ़ॉल्ट या निर्माण) निर्दिष्ट करने से बचने का कोई तरीका नहीं मिला है। अगर कोई किसी तरह से जानता है तो सुनना अच्छा लगेगा।
दरअसल @ निक Desjardins सही जवाब दिया। लेकिन सिर्फ शिक्षा के लिए: आप गंदे दृष्टिकोण का उपयोग कर सकते हैं: ENV
तर्क का उपयोग कर
task :my_task do
myvar = ENV['myvar']
puts "myvar: #{myvar}"
end
rake my_task myvar=10
#=> myvar: 10
मापदंडों को पार करते समय, यह एक बेहतर विकल्प है, एक इनपुट फ़ाइल है, क्या यह एक जेएसएल या जो कुछ भी आपको चाहिए उसे एक्सेल हो सकता है और वहां से डेटा स्ट्रक्चर और वैरिएबल को पढ़ सकते हैं, जिसमें आपको वैरिएबल नाम की ज़रूरत है। फ़ाइल को पढ़ने के लिए निम्न संरचना हो सकती है।
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
मुझे बहस के लिए "क्वेरीस्ट्रिंग" वाक्यविन्यास पसंद है, खासकर जब पास होने के लिए बहुत से तर्क हैं।
उदाहरण:
rake "mytask[width=10&height=20]"
"क्वेरीस्ट्रिंग" होने जा रहा है:
width=10&height=20
चेतावनी: ध्यान दें कि वाक्यविन्यास rake "mytask[foo=bar]"
rake mytask["foo=bar"]
और rake mytask["foo=bar"]
नहीं है rake mytask["foo=bar"]
Rack::Utils.parse_nested_query
का उपयोग करते हुए रेक कार्य के अंदर पार्स किया गया, हमें एक Hash
मिलता है:
=> {"width"=>"10", "height"=>"20"}
(अच्छी बात यह है कि आप हैश और सरणी पास कर सकते हैं, नीचे और अधिक)
यह कैसे प्राप्त करें:
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
यहां एक और विस्तारित उदाहरण दिया गया है कि मैं अपने delayed_job_active_record_threaded मणि में रेल के साथ उपयोग कर रहा हूं:
bundle exec rake "dj:start[ebooks[workers_number]=16&ebooks[worker_timeout]=60&albums[workers_number]=32&albums[worker_timeout]=120]"
एक पर्यावरण निर्भरता के साथ उपरोक्त जैसा ही विश्लेषण किया गया है (क्रम में रेल पर्यावरण को लोड करें)
namespace :dj do
task :start, [ :args_expr ] => :environment do |t, args|
# defaults here...
options = Rack::Utils.parse_nested_query(args[:args_expr])
end
end
options
में निम्नलिखित देता है
=> {"ebooks"=>{"workers_number"=>"16", "worker_timeout"=>"60"}, "albums"=>{"workers_number"=>"32", "worker_timeout"=>"120"}}
मैं यह नहीं समझ सका कि तर्क कैसे पारित किया जाए और पर्यावरण: जब तक मैंने इसे काम नहीं किया:
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
और फिर मैं इस तरह फोन करता हूं:
rake db:export['foo, /tmp/']
मैं सिर्फ दौड़ने में सक्षम होना चाहता था:
$ rake some:task arg1 arg2
सरल, सही? (नहीं!)
रेक ने arg1
और arg2
को कार्यों के रूप में व्याख्या किया है, और उन्हें चलाने की कोशिश करता है। तो हम इसे करने से पहले ही गर्भपात करते हैं।
namespace :some do
task task: :environment do
arg1, arg2 = ARGV
# your task...
exit
end
end
वह लो, ब्रैकेट्स!
अस्वीकरण : मैं इसे एक सुंदर छोटी पालतू परियोजना में करने में सक्षम होना चाहता था। "असली दुनिया" उपयोग के लिए इरादा नहीं है क्योंकि आप श्रृंखला रेक कार्यों (यानी rake task1 task2 task3
कार्य 1 rake task1 task2 task3
) की क्षमता खो देते हैं। आईएमओ इसके लायक नहीं है। बस बदसूरत rake task[arg1,arg2]
।
यदि आप नामांकित तर्क (उदाहरण के लिए मानक विकल्प OptionParser
साथ) पास करना चाहते हैं तो आप इस तरह कुछ उपयोग कर सकते हैं:
$ rake user:create -- --user [email protected] --pass 123
ध्यान दें --
मानक राक तर्कों को छोड़ने के लिए यह आवश्यक है। रेक 0.9.x , <= 10.3.x के साथ काम करना चाहिए।
न्यूर रेक ने इसके OptionParser#parse
को बदल दिया है --
और अब आपको यह सुनिश्चित करना होगा कि यह OptionParser#parse
विधि को पास नहीं किया गया है, उदाहरण के लिए 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
से यह सुनिश्चित होगा कि अतिरिक्त तर्कों को रेक कार्य के रूप में व्याख्या नहीं किया जाएगा।
तर्कों के लिए शॉर्टकट भी काम करना चाहिए:
rake user:create -- -u [email protected] -p 123
जब रेक स्क्रिप्ट इस तरह दिखती हैं, तो शायद यह एक और टूल देखने का समय है जो इसे बॉक्स से बाहर करने की अनुमति देगा।
विकल्पों और निर्भरताओं को सरणी के अंदर होना चाहिए:
namespace :thing do
desc "it does a thing"
task :work, [:option, :foo, :bar] => [:environment] do |t, args|
puts "work", args
end
task :another, [:option, :foo, :bar] => [:environment] do |t, 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
फिर
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"}
नोट: चर के लिए परिवर्तनीय
t
छोटा है। यह कार्य वस्तु है, बहुत उपयोगी नहीं है जबतक कि आप यह नहीं जानते कि आप क्या कर रहे हैं।
desc 'an updated version'
task :task_name, [:arg1, :arg2] => [:dependency1, :dependency2] do |t, args|
puts args[:arg1]
end