ruby एक रेक कार्य के लिए कमांड लाइन तर्क कैसे पास करें




command-line rake (14)

ऊपर वर्णित अधिकांश विधियों ने मेरे लिए काम नहीं किया है, शायद वे नए संस्करणों में बहिष्कृत हैं। अद्यतित गाइड यहां पाया जा सकता है: 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

मेरे पास एक रेक कार्य है जिसे एकाधिक डेटाबेस में एक मूल्य डालने की आवश्यकता है।

मैं इस मान को कमांड लाइन से, या किसी अन्य रेक कार्य से रेक कार्य में पास करना चाहता हूं।

मैं यह कैसे कर सकता हूँ?


यदि आप नामांकित तर्क (उदाहरण के लिए मानक विकल्प 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 छोटा है। यह कार्य वस्तु है, बहुत उपयोगी नहीं है जबतक कि आप यह नहीं जानते कि आप क्या कर रहे हैं।


आप कार्य कॉल में प्रतीक तर्क जोड़कर रेक में औपचारिक तर्क निर्दिष्ट कर सकते हैं। उदाहरण के लिए:

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'\]


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

मुझे इन दो वेबसाइटों का उत्तर मिला है: नेट पागल और Aimred

इस तकनीक का उपयोग करने के लिए आपको संस्करण> 0.8 रेक की आवश्यकता है

सामान्य रेक कार्य विवरण यह है:

desc 'Task Description'
task :task_name => [:depends_on_taskA, :depends_on_taskB] do
  #interesting things
end

तर्क पारित करने के लिए, तीन चीजें करें:

  1. कार्य नाम के बाद तर्क नाम जोड़ें, अल्पविराम से अलग।
  2. निर्भरता को अंत में उपयोग करके रखें: ज़रूरत => [...]
  3. प्लेस | टी, तर्क | करने के बाद। (टी इस कार्य के लिए वस्तु है)

स्क्रिप्ट में तर्कों तक पहुंचने के लिए, 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

इस कार्य को कमांड लाइन से कॉल करने के लिए, इसे [] s में तर्क दें

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

मुझे बहस के लिए "क्वेरीस्ट्रिंग" वाक्यविन्यास पसंद है, खासकर जब पास होने के लिए बहुत से तर्क हैं।

उदाहरण:

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

केएच द्वारा जवाब देने के अलावा (मुझे यह नहीं मिला कि उस पर टिप्पणी कैसे छोड़ें, क्षमा करें):

rake आदेश से पहले आपको ENV चर के रूप में चर निर्दिष्ट करने की आवश्यकता नहीं है। आप उन्हें सामान्य कमांड लाइन पैरामीटर के रूप में सेट कर सकते हैं जैसे कि:

rake mytask var=foo

और एनएनवी चर के रूप में अपनी रेक फ़ाइल से उन तक पहुंचें जैसे:

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

मैं सिर्फ दौड़ने में सक्षम होना चाहता था:

$ 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]


तर्क पारित करने के तरीके उपरोक्त उत्तर में सही हैं। हालांकि तर्कों के साथ रेक कार्य चलाने के लिए, रेल के नए संस्करण में शामिल एक छोटी तकनीकीता है

यह रेक "नेमस्पेस: कार्यनाम ['argument1'] के साथ काम करेगा"

कमांड लाइन से कार्य चलाने में उलटा उद्धरण नोट करें।


दरअसल @ निक Desjardins सही जवाब दिया। लेकिन सिर्फ शिक्षा के लिए: आप गंदे दृष्टिकोण का उपयोग कर सकते हैं: ENV तर्क का उपयोग कर

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

rake my_task myvar=10
#=> myvar: 10

डिफ़ॉल्ट कार्य में तर्क पारित करने के लिए, आप ऐसा कुछ कर सकते हैं। उदाहरण के लिए, "संस्करण" कहें आपका तर्क है:

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

हालांकि, मुझे तर्कों में गुजरते समय कार्य नाम (डिफ़ॉल्ट या निर्माण) निर्दिष्ट करने से बचने का कोई तरीका नहीं मिला है। अगर कोई किसी तरह से जानता है तो सुनना अच्छा लगेगा।


मापदंडों को पार करते समय, यह एक बेहतर विकल्प है, एक इनपुट फ़ाइल है, क्या यह एक जेएसएल या जो कुछ भी आपको चाहिए उसे एक्सेल हो सकता है और वहां से डेटा स्ट्रक्चर और वैरिएबल को पढ़ सकते हैं, जिसमें आपको वैरिएबल नाम की ज़रूरत है। फ़ाइल को पढ़ने के लिए निम्न संरचना हो सकती है।

  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 

यदि आपको याद रखने के लिए परेशान नहीं किया जा सकता है कि तर्क और स्थिति क्या है और आप रूबी तर्क हैश की तरह कुछ करना चाहते हैं। आप एक स्ट्रिंग में पास करने के लिए एक तर्क का उपयोग कर सकते हैं और उसके बाद विकल्प को हैश में स्ट्रिंग कर सकते हैं।

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




command-line-arguments