วิธีการส่งผ่านอาร์กิวเมนต์บรรทัดคำสั่งไปยังงาน rake


1096

ฉันมีงานเรคที่ต้องใส่ค่าลงในหลายฐานข้อมูล

ฉันต้องการส่งค่านี้ไปยังภารกิจเรคจากบรรทัดคำสั่งหรือจากงานเรคอื่น

ฉันจะทำสิ่งนี้ได้อย่างไร



3
เอกสารที่ได้รับการสะท้อน SeattleRb
Jonathan Allard

1
คุณช่วยเปลี่ยนคำตอบที่ยอมรับเป็นคำตอบจาก @BlairAnderson ได้ไหมเนื่องจากคำตอบที่ยอมรับนั้นล้าสมัยไปมาก คำถามนี้ปรากฏสูงใน Google สำหรับหัวข้อนี้!
rmcsharry

คำตอบ:


377

ตัวเลือกและการอ้างอิงจำเป็นต้องอยู่ภายในอาร์เรย์:

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เป็นอ็อบเจกต์งานซึ่งไม่ค่อยมีประโยชน์เว้นแต่คุณจะรู้ / ใส่ใจเกี่ยวกับเรคภายใน

RAILS NOTE:

หากการเรียกใช้งานจากรางเป็นสิ่งที่ดีที่สุดในการโหลดสภาพแวดล้อมล่วงหน้าโดยการเพิ่ม=> [:environment]ซึ่งเป็นวิธีการตั้งค่างานที่ต้องพึ่งพา

  task :work, [:option, :foo, :bar] => [:environment] do |task, args|
    puts "work", args
  end

28
นอกจากนี้ตรวจสอบให้แน่ใจว่าคุณไม่ใช้ช่องว่างระหว่างอาร์กิวเมนต์ เช่นไม่ทำเช่นนี้rake thing:work[1, 2, 3]เพราะมันจะไม่ทำงานและคุณจะได้รับข้อผิดพลาดDon't know how to build task
rpbaltazar

9
นอกจากนี้ตรวจสอบให้แน่ใจว่าคุณใส่อาร์กิวเมนต์ในสตริง เช่นจากบรรทัดคำสั่งของคุณให้ทำงานคราดเช่นนั้น rake thing:work'[1,2,3]'
theterminalguy

36
Unfortuanely, zsh ไม่สามารถแยกการโทรอย่างถูกต้องคุณจะต้องพิมพ์คำสั่งใน zsh เช่นนี้rake thing:work\[1,2,3\]หรือนี้rake 'thing:work[1,2,3]'
hutusi

1
@ Sakurashinken คุณสามารถลบ:environmentสัญลักษณ์ออกจากงานของคุณได้ รางการใช้งานที่มี: งานของสภาพแวดล้อม ...
แบลร์เดอร์สัน

3
แทนที่จะมีหมายเหตุเพื่ออธิบายนั่นtหมายความtaskว่าทำไมไม่เพียงใช้taskเป็นชื่อพารามิเตอร์?
Joshua Pinter

1132

คุณสามารถระบุอาร์กิวเมนต์ที่เป็นทางการในเรคโดยการเพิ่มอาร์กิวเมนต์สัญลักษณ์ไปที่การเรียกใช้งาน ตัวอย่างเช่น:

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

จากนั้นจากบรรทัดคำสั่ง:

> rake my_task [1, เท็จ]
Args คือ: {: arg1 => "1",: arg2 => "false"} ของคลาส Rake :: TaskArguments
arg1 คือ: '1' ของคลาส String
arg2 คือ: 'false' ของคลาส String

> rake "my_task [1, 2]"
Args คือ: {: arg1 => "1",: arg2 => "2"}

> rake invoke_my_task
Args คือ: {: arg1 => "1",: arg2 => "2"}

> rake invoke_my_task_2
Args คือ: {: arg1 => 3,: arg2 => 4}

> rake with_prerequisite [5,6]
Args คือ: {: arg1 => "5",: arg2 => "6"}

> rake with_defaults
Args ที่มีค่าเริ่มต้นคือ: {: arg1 =>: default_1,: arg2 =>: default_2}

> rake with_defaults ['x', 'y']
Args ที่มีค่าเริ่มต้นคือ: {: arg1 => "x",: arg2 => "y"}

ดังที่แสดงไว้ในตัวอย่างที่สองถ้าคุณต้องการใช้ช่องว่างเครื่องหมายคำพูดรอบชื่อเป้าหมายจำเป็นเพื่อป้องกันไม่ให้เชลล์แยกอาร์กิวเมนต์ที่ช่องว่าง

มองไปที่รหัสในrake.rbtask :t1 => "dep[1,2]"ก็จะปรากฏขึ้นที่จะเสาะหาสายงานไม่แจงข้อโต้แย้งสารสกัดเบื้องต้นดังนั้นคุณจึงไม่สามารถทำได้ วิธีเดียวที่จะระบุข้อโต้แย้งที่แตกต่างกันสำหรับสิ่งที่จำเป็นที่จะเรียกมันอย่างชัดเจนในการดำเนินงานที่ขึ้นอยู่ในขณะที่และ:invoke_my_task:invoke_my_task_2

โปรดทราบว่าบางเชลล์ (เช่น zsh) ต้องการให้คุณหลีกเลี่ยงวงเล็บ: rake my_task\['arg1'\]


5
ในการเรียกใช้งานภายในเนมสเปซ simpy ให้ทำ: Rake :: Task ['namespace: task']. เรียกใช้
gaqzi

1
นั่นเป็นคำถามที่แยกต่างหาก Igoru แต่เหตุผลที่การเรียกเพื่อให้เรียกใช้เพียงครั้งเดียวของคุณคือเรคนั้นมีการพึ่งพาอาศัยดังนั้นมันจะทำงานเฉพาะเมื่อจำเป็นเท่านั้น สำหรับงานทั่วไปซึ่งหมายความว่าหากยังไม่ได้ทำงาน ในการดำเนินงานอย่างชัดเจนโดยไม่คำนึงถึงการพึ่งพาหรือถ้าจำเป็นให้เรียกใช้งานรันแทนการเรียกใช้
Nick Desjardins

10
หมายเหตุ: ตามเรคไวยากรณ์นี้สำหรับการยอมรับตัวแปรในงานไม่ได้รับการสนับสนุน:WARNING: 'task :t, arg, :needs => [deps]' is deprecated. Please use 'task :t, [args] => [deps]' instead.
Ajedi32

57
โปรดทราบว่า zsh ล้มเหลวที่จะแยกอาร์กิวเมนต์บรรทัดคำสั่งให้ถูกต้อง ( zsh: no matches found: ...) rake my_task\['arg1'\]ดังนั้นคุณจำเป็นต้องหนีวงเล็บ: จากrobots
Seth Bro

2
@SethBro ใช่ หากความคิดเห็นของคุณไม่ได้ซ่อนอยู่หลังลิงก์ "ดูความคิดเห็นเพิ่มเติม" ฉันจะไม่เสียเวลา 10 นาทีในการทำงานนี้
GMA

342

นอกจากนี้เพื่อตอบโดย kch (ฉันไม่พบวิธีการออกความคิดเห็นที่ขออภัย):

คุณไม่จำเป็นต้องระบุตัวแปรเป็นENVตัวแปรก่อนrakeคำสั่ง คุณสามารถตั้งค่าพารามิเตอร์บรรทัดคำสั่งตามปกติดังนี้:

rake mytask var=foo

และเข้าถึงจากไฟล์ rake ของคุณเป็นตัวแปร ENV เช่น:

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

2
นี่คือคำตอบที่ง่ายที่สุดของ IMO มันทำงานได้ทันที สิ่งที่ว่าไม่pหมายถึง?
stevec

1
@ user5783745 กดไลค์ แต่แทนที่จะบันทึกค่าเป็น to_s มาตรฐานจะเรียกใช้ Obj.inspect และบันทึกข้อมูลนั้นเป็นมาตรฐาน ruby-doc.org/core-2.0.0/Kernel.html#method-ip
kqcef

และแทนที่ตัวแปรสภาพแวดล้อม? Fantastic!
ดาเมียนโรช

เรคเป็นระเบียบที่มีการใช้งานอย่างหนักและนี่เป็นวิธีเดียวที่ทำงานได้ และไม่ใช่เพียงฉันคำตอบนี้มีจำนวนคะแนนเท่ากันกับคำตอบ "ถูกต้อง"
lzap

108

หากคุณต้องการส่งอาร์กิวเมนต์ที่มีชื่อ (เช่นมาตรฐานOptionParser) คุณสามารถใช้สิ่งนี้:

$ rake user:create -- --user test@example.com --pass 123

สังเกต--ว่าจำเป็นสำหรับการข้ามอาร์กิวเมนต์ Rake มาตรฐาน ควรจะทำงานกับคราด0.9.x , <= 10.3.x

Rake ที่ใหม่กว่าได้เปลี่ยนการแยกวิเคราะห์--และตอนนี้คุณต้องแน่ใจว่ามันไม่ถูกส่งผ่านไปยัง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

เมื่อสคริปต์คราดมีลักษณะเช่นนี้อาจถึงเวลาที่ต้องมองหาเครื่องมืออื่นที่อนุญาตให้ใช้งานได้ทันที


13
จากมุมมองของฉันนี้จริงๆเป็นคำตอบที่ดีที่สุด สภาพแวดล้อมบายพาส kludges --option-namesตัวแปรไวยากรณ์แปลกที่มีการขัดแย้งงานได้รับประโยชน์เพิ่มเติมสำหรับมาตรฐาน ข้อเสนอแนะเดียวของฉันจะใช้exitมากกว่าabortที่abortจะทำให้คุณมีรหัสส่งคืน 1 ถึงเชลล์ หากภารกิจ rake เป็นส่วนหนึ่งของสคริปต์ระดับสูงกว่าปกติจะถือว่าการออกที่ไม่ใช่ศูนย์เป็นข้อผิดพลาดบางประเภท
Joe

1
ฉันเห็นด้วยกับโจนี่เป็นคำตอบที่ดีที่สุด สิ่งที่เป็นธรรมชาติคือการใช้อินเทอร์เฟซเดียวกันสำหรับการส่งผ่านตัวเลือกในการเสาะอย่างที่คุณต้องการเมื่อส่งตัวเลือกไปยังสคริปต์
Rik Smith-Unna

1
ฉันยอมรับว่านี่เป็นคำตอบที่ดีที่สุด ไม่มีวิธีที่จะหลีกเลี่ยงคนน่าเกลียด--ใช่ไหม? ชอบส่งผ่านrakeข้อโต้แย้งไปยังงานจริงหรืออะไร? ชอบtask :my_task, :*args do |t, args|หรืออะไร
Augustin Riedinger

1
นอกจากนี้ฉันไม่เข้าใจว่า{username}มันมาเพื่ออะไร มันใช้อยู่ที่ไหน ทำไมไม่ได้มีใน-u {username}? ไชโย
Augustin Riedinger

2
วิธีวิธีการแยกวิเคราะห์คราด ARGV ก็เปลี่ยนในและหวนกลับใน10.4.1 github.com/ruby/rake/commit/…10.4.2
Tombart

58

ฉันได้พบคำตอบจากทั้งสองเว็บไซต์: Maniac สุทธิและAimred

คุณต้องมีรุ่น> 0.8 ของเรคเพื่อใช้เทคนิคนี้

คำอธิบายภารกิจคราดปกติคือ:

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

ในการผ่านการโต้แย้งให้ทำสามสิ่ง:

  1. เพิ่มชื่ออาร์กิวเมนต์หลังชื่องานคั่นด้วยเครื่องหมายจุลภาค
  2. ใส่การอ้างอิงในตอนท้ายโดยใช้: needs => [... ]
  3. สถานที่ | t, args | หลังจากที่ทำ (t เป็นวัตถุสำหรับงานนี้)

ในการเข้าถึงข้อโต้แย้งในสคริปต์ 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

15
รูปแบบของฟังก์ชันนี้เปลี่ยนไปตามคำเตือนนี้: 'task :t, arg, :needs => [deps]' is deprecated. Please use 'task :t, [args] => [deps]' instead.
madh

29

อีกตัวเลือกที่ใช้กันทั่วไปคือการส่งตัวแปรสภาพแวดล้อม ในรหัสของคุณคุณอ่านพวกเขาผ่านENV['VAR']และสามารถผ่านพวกเขาก่อนrakeคำสั่งเช่น

$ VAR=foo rake mytask

ตรงไปตรงมาฉันหวังว่าจะมีงานคราด - ไป - ไป - ไป - โปรแกรมและงานของฉันสามารถรับพวกเขาจาก ARGV น่าเสียดายที่ฉันไม่แน่ใจว่าเป็นไปได้หรือไม่ขณะนี้ฉันกำลังใช้วิธีแก้ปัญหาของคุณอยู่: rake var1 = val1 var2 = val2
JasonSmith

3
@jhs: rake blah -- --these --go --to --a-program(หมายเหตุ--ที่จะบอกว่าการเสาะหาสวิทช์ได้จบ) ดูstackoverflow.com/questions/5086224/...
หมู่สั้นเกินไป

28

@Nick Desjardins ตอบกลับได้สมบูรณ์แบบ แต่เพียงเพื่อการศึกษา: คุณสามารถใช้วิธีการสกปรก: การใช้ENVอาร์กิวเมนต์

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

rake my_task myvar=10
#=> myvar: 10

27

ฉันไม่สามารถหาวิธีที่จะผ่าน args และ: สิ่งแวดล้อมจนกว่าฉันจะทำสิ่งนี้:

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

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

ในการเรียกสิ่งนี้ให้ไป:rake task_name[hello, world]
Dex

2
from rake.rubyforge.org/files/doc/rakefile_rdoc.html "คำเตือนเพียงไม่กี่คำชื่อ rake task และอาร์กิวเมนต์จำเป็นต้องเป็นอาร์กิวเมนต์บรรทัดคำสั่งเดียวในการเรคซึ่งโดยทั่วไปหมายถึงไม่มีช่องว่างหากจำเป็นต้องเว้นวรรค ดังนั้นควรอ้างสตริง rake + อาร์กิวเมนต์ทั้งหมดสิ่งนี้: rake "name [billy bob, smith]" "
Gayle

19

ฉันแค่อยากจะวิ่ง:

$ rake some:task arg1 arg2

ง่ายใช่มั้ย (Nope!)

เรคตีความ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]เพียงแค่ใช้น่าเกลียด


3
จำเป็นต้องทำให้สิ่งนี้_, arg1, arg2 = ARGVเป็น ARG แรกที่ถูกมองว่าเป็นชื่อของภารกิจคราด แต่นั่นexitเป็นเคล็ดลับที่เรียบร้อย
ไขมัน

rake task[arg1,arg2] && rake task2 && rake task3ไม่แน่ใจว่ามันน่าเกลียดน้อยกว่าrake task[arg1,arg2] task2 task3หรือเปล่า อาจมีประสิทธิภาพน้อยลง
Nuclearman

_, *args = ARGVเป็นที่สมบูรณ์แบบสำหรับการจับข้อโต้แย้งที่ตามมาทั้งหมด! ขอบคุณมาก!
XtraSimplicity

12

ฉันใช้อาร์กิวเมนต์ ruby ​​ปกติในไฟล์ rake:

DB = ARGV[1]

จากนั้นฉันเริ่มต้นงานเรคที่ด้านล่างของไฟล์ (เนื่องจากเรคจะค้นหางานตามชื่ออาร์กิวเมนต์นั้น)

task :database_name1
task :database_name2

บรรทัดคำสั่ง:

rake mytask db_name

สิ่งนี้ทำให้ฉันรู้สึกว่าสะอาดกว่า var = foo ENV var และภาระงานเป็นโซลูชัน [blah, blah2]
ต้นขั้วเป็น jenky เล็ก ๆ น้อย ๆ แต่ไม่เลวร้ายเกินไปถ้าคุณมีเพียงไม่กี่สภาพแวดล้อมที่มีการตั้งค่าแบบครั้งเดียว


2
เพื่อป้องกันปัญหาการตรึงสตริงให้ใช้dupที่ส่วนท้าย: db = ARGV [1] .dup
Juanda

เหตุการณ์ดีขึ้นdb = ARGV[1].dup unless ARGV[1].nil?เพื่อป้องกันข้อยกเว้นของการทำซ้ำศูนย์
Andre Figueiredo

5

วิธีการผ่านการโต้แย้งนั้นถูกต้องในคำตอบข้างต้น อย่างไรก็ตามในการรัน rake ด้วยอาร์กิวเมนต์มีความรู้ด้านเทคนิคเล็กน้อยใน Rails เวอร์ชั่นใหม่

มันจะทำงานกับ rake "namespace: taskname ['argument1']"

หมายเหตุอัญประกาศ Inverted ในการเรียกใช้งานจากบรรทัดคำสั่ง


3

ในการส่งผ่านข้อโต้แย้งไปยังงานเริ่มต้นคุณสามารถทำสิ่งนี้ ตัวอย่างเช่นสมมติว่า "version" เป็นอาร์กิวเมนต์ของคุณ:

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

อย่างไรก็ตามฉันไม่พบวิธีหลีกเลี่ยงการระบุชื่อภารกิจ (ค่าเริ่มต้นหรือบิลด์) ขณะที่ส่งผ่านอาร์กิวเมนต์ ชอบที่จะได้ยินถ้าใครรู้วิธี


3

ฉันชอบไวยากรณ์ "การสอบถาม" สำหรับการผ่านการโต้แย้งโดยเฉพาะอย่างยิ่งเมื่อมีข้อโต้แย้งมากมายที่ต้องผ่าน

ตัวอย่าง:

rake "mytask[width=10&height=20]"

"querystring" กำลัง:

width=10&height=20

คำเตือน:โปรดทราบว่าไวยากรณ์คือrake "mytask[foo=bar]"และไม่ rake mytask["foo=bar"]

เมื่อแยกวิเคราะห์โดยใช้ rake task 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

ต่อไปนี้เป็นตัวอย่างเพิ่มเติมที่ฉันใช้กับ Rails ในอัญมณีของฉันล่าช้า _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]"

แยกวิเคราะห์ด้วยวิธีเดียวกันกับข้างต้นโดยอ้างอิงสภาพแวดล้อม (เพื่อโหลดสภาพแวดล้อมของ Rails)

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

3

หากคุณไม่สามารถใส่ใจที่จะจำได้ว่าตำแหน่งการโต้เถียงนั้นเป็นอย่างไรและคุณต้องการทำอะไรเช่นแฮชการโต้เถียงแบบทับทิม คุณสามารถใช้หนึ่งอาร์กิวเมนต์เพื่อส่งผ่านสตริงและจากนั้น 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

1
รหัสของคุณต้องการบรรทัดว่างที่วางไว้อย่างดีสองสามบรรทัด ฉันไม่รู้ว่าคุณอ่านข้อความนั้นได้อย่างไร
Joshua Pinter

2

วิธีการส่วนใหญ่ที่อธิบายไว้ข้างต้นไม่ได้ผลสำหรับฉันบางทีพวกเขาอาจเลิกใช้แล้วในเวอร์ชันที่ใหม่กว่า คู่มือล่าสุดอยู่ที่นี่: 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

1

ในการรันภารกิจ rake ด้วยสไตล์อาร์กิวเมนต์ดั้งเดิม:

rake task arg1 arg2

จากนั้นใช้:

task :task do |_, args|
  puts "This is argument 1: #{args.first}"
end

เพิ่มแพทช์ rake gem ต่อไปนี้:

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

-5

ในขณะที่ผ่านพารามิเตอร์มันเป็นตัวเลือกที่ดีกว่าคือไฟล์อินพุตสามารถเป็น excel a json หรืออะไรก็ได้ที่คุณต้องการและจากที่นั่นอ่านโครงสร้างข้อมูลและตัวแปรที่คุณต้องการจากนั้นรวมถึงชื่อตัวแปรตามที่ต้องการ หากต้องการอ่านไฟล์สามารถมีโครงสร้างดังต่อไปนี้

  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

ตัวอย่าง json

{
  "name_task": "I'm a task",
  "user_id": 389,
  "users_assigned": [389,672,524],
  "task_id": 3
}

การกระทำ

rake :name_task 

4
หากคุณต้องการไฟล์คำสั่ง JSON สำหรับงาน Rake ของคุณคุณอาจทำหลายอย่างในงาน Rake ของคุณ
ZiggyTheHamster

นี่เป็นวิธีที่ซับซ้อนเกินกว่าจะทำสิ่งที่ง่ายอย่างไม่น่าเชื่อ
jeffdill2
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.