मेरे पास एक रेक कार्य है जो कई डेटाबेस में एक मूल्य सम्मिलित करने की आवश्यकता है।
मैं कमांड लाइन से या किसी अन्य रेक कार्य से रेक कार्य में इस मान को पास करना चाहूंगा ।
मैं यह कैसे कर सकता हूँ?
मेरे पास एक रेक कार्य है जो कई डेटाबेस में एक मूल्य सम्मिलित करने की आवश्यकता है।
मैं कमांड लाइन से या किसी अन्य रेक कार्य से रेक कार्य में इस मान को पास करना चाहूंगा ।
मैं यह कैसे कर सकता हूँ?
जवाबों:
विकल्प और निर्भरता सरणियों के अंदर होना चाहिए:
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
फिर
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"}
नोट: चर
task
कार्य ऑब्जेक्ट है, बहुत उपयोगी नहीं है जब तक आप रेक इंटर्नल के बारे में जानते / परवाह नहीं करते हैं।
नोट नोट:
यदि रेल को टास्क से चलाया जाए, तो पर्यावरण को जोड़ने के लिए सबसे अच्छा है
=> [:environment]
जो कि आश्रित कार्यों को सेटअप करने का एक तरीका है।
task :work, [:option, :foo, :bar] => [:environment] do |task, args|
puts "work", args
end
rake thing:work[1, 2, 3]
क्योंकि यह काम नहीं करेगा और आपको एक त्रुटि Don't know how to build task
rake thing:work'[1,2,3]'
rake thing:work\[1,2,3\]
या यहrake 'thing:work[1,2,3]'
:environment
अपने कार्य से प्रतीक को हटा सकते हैं । रेल अनुप्रयोगों में एक है: पर्यावरण कार्य ...
t
इसका मतलब यह है कि task
सिर्फ task
परम नाम के रूप में उपयोग क्यों करें?
आप कार्य कॉल में प्रतीक तर्क जोड़कर रेक में औपचारिक तर्क निर्दिष्ट कर सकते हैं। उदाहरण के लिए:
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
फिर, कमांड लाइन से:
> रेक my_task [1, गलत] आर्ग्स थे: {: arg1 => "1",: arg2 => "असत्य"} वर्ग रेक का :: टास्कआर्गुमेंट्स arg1 था: कक्षा स्ट्रिंग का '1' arg2 था: क्लास स्ट्रिंग का 'झूठा' > रेक "my_task [1, 2]" आर्ग्स थे: {: arg1 => "1",: arg2 => "2"} > रेक इनवोक_मी_टस्क आर्ग्स थे: {: arg1 => "1",: arg2 => "2"} > रेक इनवोक_मी_टस्क २ आर्ग्स थे: {: arg1 => 3,: arg2 => 4} > rake with_prerequisite [5,6] आर्ग्स थे: {: arg1 => "5",: arg2 => "6"} > rake with_defaults डिफॉल्ट वाले आर्ग्स थे: {: arg1 =>: default_1,: arg2 =>: default_2} > rake with_defaults ['x', 'y'] चूक वाले आर्ग थे: {: arg1 => "x":: arg2 => "y"}
जैसा कि दूसरे उदाहरण में दर्शाया गया है, यदि आप रिक्त स्थान का उपयोग करना चाहते हैं, तो लक्ष्य नाम के आसपास के उद्धरणों को अंतरिक्ष में तर्कों को विभाजित करने से खोल को रखना आवश्यक है।
Rake.rb में कोड को देखते हुए , ऐसा प्रतीत होता है कि रेक कार्य स्ट्रिंग को पार्स करने के लिए तर्क निकालने के लिए पार्स नहीं करता है, इसलिए आप ऐसा नहीं कर सकते task :t1 => "dep[1,2]"
। एक ही रास्ता अलग तर्क के लिए एक शर्त, निर्भर कार्य कार्रवाई के भीतर यह स्पष्ट रूप से आह्वान करने के लिए के रूप में किया जाएगा निर्दिष्ट करने के लिए :invoke_my_task
और :invoke_my_task_2
।
ध्यान दें कि कुछ गोले (जैसे zsh) के लिए आपको कोष्ठक से बचने की आवश्यकता होती है: rake my_task\['arg1'\]
WARNING: 'task :t, arg, :needs => [deps]' is deprecated. Please use 'task :t, [args] => [deps]' instead.
zsh: no matches found: ...
इसलिए, आपको कोष्ठक से बचने की आवश्यकता है rake my_task\['arg1'\]
:। से robots.thoughtbot.com/post/18129303042/...
Kch द्वारा जवाब देने के अलावा (मुझे नहीं लगा कि मुझे उस पर टिप्पणी कैसे छोड़नी है, क्षमा करें):
आपको आदेश ENV
से पहले चर को चर के रूप में निर्दिष्ट करने की आवश्यकता नहीं है rake
। आप उन्हें सामान्य कमांड लाइन पैरामीटर की तरह सेट कर सकते हैं:
rake mytask var=foo
और अपनी रेक फ़ाइल से ENV वैरिएबल की तरह एक्सेस करें:
p ENV['var'] # => "foo"
p
मतलब है?
यदि आप नामित तर्क (जैसे मानक के साथ OptionParser
) पास करना चाहते हैं, तो आप कुछ इस तरह का उपयोग कर सकते हैं:
$ rake user:create -- --user test@example.com --pass 123
ध्यान दें --
, यह मानक रेक तर्कों को दरकिनार करने के लिए आवश्यक है। Rake 0.9.x , <= 10.3.x के साथ काम करना चाहिए ।
नए रेक ने इसकी पार्सिंग को बदल दिया है --
, और अब आपको यह सुनिश्चित करना होगा कि यह 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 test@example.com -p 123
जब रेक स्क्रिप्ट इस तरह दिखती हैं, तो शायद यह एक और टूल की तलाश में है जो इसे सिर्फ आउट ऑफ बॉक्स की अनुमति देगा।
--option-names
। मेरी केवल सुझाव उपयोग करने के लिए किया जाएगा exit
के बजाय abort
के रूप में abort
आप खोल करने के लिए 1 की वापसी कोड के साथ छोड़ देंगे। यदि रेक कार्य उच्च-स्तरीय स्क्रिप्ट का एक हिस्सा है, तो यह गैर-शून्य निकास मानने के लिए अधिक सामान्य है कुछ प्रकार की त्रुटि है।
--
? rake
वास्तविक कार्य या कुछ करने के लिए तर्क पारित करने की तरह ? जैसे task :my_task, :*args do |t, args|
या कुछ और?
{username}
यहाँ क्या है। इसका उपयोग कहां किया जाता है? इसमें क्यों नहीं है -u {username}
? चीयर्स
10.4.1
और में वापस लाया 10.4.2
। github.com/ruby/rake/commit/…
मुझे इन दो वेबसाइटों से जवाब मिला है: नेट मनिक और मनिक आइम्रेड ।
इस तकनीक का उपयोग करने के लिए आपके पास संस्करण> 0.8 का होना आवश्यक है
सामान्य रेक कार्य विवरण यह है:
desc 'Task Description'
task :task_name => [:depends_on_taskA, :depends_on_taskB] do
#interesting things
end
तर्क पारित करने के लिए, तीन काम करें:
स्क्रिप्ट में तर्कों को एक्सेस करने के लिए, 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
कमांड लाइन से इस कार्य को कॉल करने के लिए, इसे तर्क में पास करें
rake task_name['Hello',4]
उत्पादन होगा
Hello
Hello
Hello
Hello
और यदि आप इस कार्य को किसी अन्य कार्य से कॉल करना चाहते हैं, और इसे पास करना चाहते हैं, तो इनवोक का उपयोग करें
task :caller do
puts 'In Caller'
Rake::Task[:task_name].invoke('hi',2)
end
उसके बाद कमान
rake caller
उत्पादन होगा
In Caller
hi
hi
मुझे एक निर्भरता के हिस्से के रूप में तर्कों को पारित करने का एक तरीका नहीं मिला, जैसा कि निम्नलिखित कोड टूटता है:
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.
एक और आमतौर पर इस्तेमाल किया जाने वाला विकल्प है पर्यावरण चर। आपके कोड में आप उन्हें पढ़ते हैं ENV['VAR']
, और उन्हें rake
कमांड से ठीक पहले पास कर सकते हैं , जैसे
$ VAR=foo rake mytask
rake blah -- --these --go --to --a-program
(ध्यान दें --
कि रेक अपने स्विच समाप्त हो गया है), stackoverflow.com/questions/5086224/…
जब तक मैंने यह काम नहीं किया तब तक मैं यह पता नहीं लगा सकता था कि आर्ग्स को कैसे पारित किया जाए: पर्यावरण
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/']
desc 'an updated version'
task :task_name, [:arg1, :arg2] => [:dependency1, :dependency2] do |t, args|
puts args[:arg1]
end
rake task_name[hello, world]
मैं बस चलाने में सक्षम होना चाहता था:
$ 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
) की क्षमता खो देते हैं । IMO इसके लायक नहीं है। बस बदसूरत का उपयोग करेंrake task[arg1,arg2]
।
_, arg1, arg2 = ARGV
इसे पहला अर्ग बनाने की आवश्यकता थी, जिसे रेक कार्य के नाम के रूप में देखा गया था। लेकिन exit
यह एक साफ-सुथरी चाल है।
rake task[arg1,arg2] && rake task2 && rake task3
यकीन नहीं होता कि अगर इससे कम बदसूरत है rake task[arg1,arg2] task2 task3
। शायद कम कुशल हालांकि।
_, *args = ARGV
बाद के सभी तर्कों को कैप्चर करने के लिए एकदम सही है! बहुत बहुत धन्यवाद!
मैं रेक फ़ाइल में एक नियमित रूप से रूबी तर्क का उपयोग करता हूं:
DB = ARGV[1]
तब मैं फ़ाइल के निचले भाग में रेक कार्य को रोक देता हूं (क्योंकि रेक उस तर्क नाम के आधार पर किसी कार्य की तलाश करेगा)।
task :database_name1
task :database_name2
कमांड लाइन:
rake mytask db_name
यह मुझे var = foo ENV var की तुलना में क्लीनर लगता है और कार्य args [blah, blah2] समाधान करता है।
ठूंठ थोड़ा झेंपता है, लेकिन बहुत बुरा नहीं है अगर आपके पास बस कुछ वातावरण है जो एक बार का सेटअप है
dup
अंत में उपयोग करें : db = ARGV [1] .dup
db = ARGV[1].dup unless ARGV[1].nil?
को रोकने के लिए बेहतर है कि एक शून्य को धोखा दिया जाए।
उपरोक्त उत्तर में तर्क पारित करने के तरीके सही हैं। हालांकि, तर्क के साथ रेक कार्य चलाने के लिए, रेल के नए संस्करण में एक छोटी सी तकनीकी शामिल है
यह रेक के साथ काम करेगा "नेमस्पेस: टास्कनेम ['आर्ग्यू 1']"
कमांड लाइन से टास्क को चलाने में उल्टे उद्धरणों पर ध्यान दें।
डिफ़ॉल्ट कार्य के लिए तर्क पारित करने के लिए, आप ऐसा कुछ कर सकते हैं। उदाहरण के लिए, मान लें कि "संस्करण" आपका तर्क है:
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
हालाँकि, मुझे तर्कों में पास होने के दौरान कार्य नाम (डिफ़ॉल्ट या बिल्ड) निर्दिष्ट करने से बचने का कोई तरीका नहीं मिला है। अगर किसी को कोई रास्ता पता हो तो सुनना अच्छा लगेगा।
मुझे तर्क पारित करने के लिए "क्वेरिस्ट्रिंग" वाक्यविन्यास पसंद है, खासकर जब तर्क देने के लिए बहुत सारे तर्क हैं।
उदाहरण:
rake "mytask[width=10&height=20]"
"क्वेरिस्ट्रिंग" किया जा रहा है:
width=10&height=20
चेतावनी: ध्यान दें कि वाक्य रचना 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
यहां एक और विस्तारित उदाहरण दिया गया है, जिसका उपयोग मैं अपने विलंबित_जॉब_ऐक्टिव_क्रैड_थ्रेडेड रत्न में रेल के साथ कर रहा हूं :
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"}}
यदि आपको यह याद रखने के लिए परेशान नहीं किया जा सकता है कि तर्क की स्थिति क्या है और आप एक रूबी तर्क हैश की तरह कुछ करना चाहते हैं। आप एक स्ट्रिंग में पास होने के लिए एक तर्क का उपयोग कर सकते हैं और फिर उस स्ट्रिंग को एक विकल्प हैश में 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
और कमांड लाइन पर आपको मिलता है।
$ 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
ऊपर वर्णित अधिकांश विधियां मेरे लिए काम नहीं करती हैं, शायद वे नए संस्करणों में पदावनत हैं। अप-टू-डेट गाइड यहां पाया जा सकता है: http://guides.rubyonrails.org/command_line.html#custom-rake-tasks
गाइड से एक कॉपी और पेस्ट ans यहाँ है:
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 task arg1 arg2
और फिर उपयोग करें:
task :task do |_, args|
puts "This is argument 1: #{args.first}"
end
रेक रत्न के निम्नलिखित पैच जोड़ें:
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
मापदंडों को पारित करते समय, यह बेहतर विकल्प है एक इनपुट फ़ाइल, क्या यह एक एक्सेल हो सकता है या जो कुछ भी आपको ज़रूरत है और वहां से डेटा संरचना और चर को पढ़ सकते हैं जो आपको आवश्यक है जैसे कि चर नाम भी शामिल है। किसी फ़ाइल को पढ़ने के लिए निम्न संरचना हो सकती है।
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