Pertanyaan Cara meneruskan argumen baris perintah ke tugas garu


Saya memiliki tugas penggaruk yang perlu memasukkan nilai ke dalam beberapa basis data.

Saya ingin menyampaikan nilai ini ke dalam tugas penggaruk dari baris perintah, atau dari lain tugas rake.

Bagaimana saya bisa melakukan ini?


950
2018-05-05 16:27


asal


Jawaban:


pilihan dan dependensi harus berada di dalam array:

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

Kemudian

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

CATATAN: variabel task adalah objek tugas, tidak terlalu membantu kecuali Anda tahu / peduli tentang internal Rake.

CATATAN PERKERETAAPIAN:

Jika menjalankan tugas dari rel, yang terbaik untuk preload lingkungan dengan menambahkan => [:environment] yang merupakan cara untuk mengatur tergantung tugas.

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

229
2018-04-07 21:56



Anda dapat menentukan argumen formal dalam penggaruk dengan menambahkan argumen simbol ke panggilan tugas. Sebagai contoh:

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

Kemudian, dari baris perintah:

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

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

> rake invoke_my_task
Args adalah: {: arg1 => "1",: arg2 => "2"}

> rake invoke_my_task_2
Args adalah: {: arg1 => 3,: arg2 => 4}

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

> garap dengan_defaults
Args dengan default adalah: {: arg1 =>: default_1,: arg2 =>: default_2}

> rake with_defaults ['x', 'y']
Args dengan default adalah: {: arg1 => "x",: arg2 => "y"}

Seperti yang ditunjukkan pada contoh kedua, jika Anda ingin menggunakan spasi, tanda kutip di sekitar nama target diperlukan untuk menjaga agar shell tidak membelah argumen di ruang tersebut.

Melihat kode di rake.rb, tampak bahwa penggarukan tidak mengurai string tugas untuk mengekstrak argumen untuk prasyarat, sehingga Anda tidak bisa melakukannya task :t1 => "dep[1,2]". Satu-satunya cara untuk menentukan argumen yang berbeda untuk prasyarat adalah untuk memanggilnya secara eksplisit dalam aksi tugas tergantung, seperti dalam :invoke_my_task dan :invoke_my_task_2.

Perhatikan bahwa beberapa shell (seperti zsh) mengharuskan Anda untuk menghindari tanda kurung: rake my_task\['arg1'\]


1081
2018-05-05 16:45



Selain menjawab dengan kch (saya tidak menemukan cara meninggalkan komentar untuk itu, maaf):

Anda tidak harus menetapkan variabel sebagai ENV variabel sebelum rake perintah. Anda dapat mengaturnya sebagai parameter baris perintah biasa seperti itu:

rake mytask var=foo

dan akses mereka dari file rake Anda sebagai variabel ENV seperti itu:

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

287
2018-02-19 11:05



Jika Anda ingin meneruskan argumen bernama (misalnya dengan standar OptionParser) Anda bisa menggunakan sesuatu seperti ini:

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

perhatikan --, itu diperlukan untuk melewati argumen Rake standar. Harus bekerja dengan Rake 0.9.x, <= 10.3.x.

Newer Rake telah mengubah parsingnya --, dan sekarang Anda harus memastikan itu tidak diteruskan ke OptionParser#parse metode, misalnya dengan 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 pada akhirnya akan memastikan bahwa argumen tambahan tidak akan ditafsirkan sebagai tugas Rake.

Juga cara pintas untuk argumen seharusnya bekerja:

 rake user:create -- -u test@example.com -p 123

Ketika skrip rake terlihat seperti ini, mungkin sudah waktunya untuk mencari alat lain yang akan memungkinkan ini keluar dari kotak.


94
2017-10-19 13:09



Saya telah menemukan jawaban dari dua situs web ini: Maniak Bersih dan Aimred.

Anda harus memiliki versi> 0,8 rake untuk menggunakan teknik ini

Deskripsi tugas rake normal adalah ini:

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

Untuk menyampaikan argumen, lakukan tiga hal:

  1. Tambahkan nama argumen setelah nama tugas, dipisahkan dengan koma.
  2. Taruh dependensi di bagian akhir menggunakan: needs => [...]
  3. Tempat | t, args | setelah melakukannya. (t adalah objek untuk tugas ini)

Untuk mengakses argumen dalam skrip, gunakan 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

Untuk memanggil tugas ini dari baris perintah, berikan argumen pada [] s

rake task_name['Hello',4]

akan menghasilkan

Hello
Hello
Hello
Hello

dan jika Anda ingin memanggil tugas ini dari tugas lain, dan memberikan argumennya, gunakan invoke

task :caller do
  puts 'In Caller'
  Rake::Task[:task_name].invoke('hi',2)
end

maka perintahnya

rake caller

akan menghasilkan

In Caller
hi
hi

Saya belum menemukan cara untuk menyampaikan argumen sebagai bagian dari ketergantungan, karena kode berikut ini pecah:

task :caller => :task_name['hi',2]' do
   puts 'In Caller'
end

56
2018-05-05 16:51



Pilihan lain yang biasa digunakan adalah untuk melewatkan variabel lingkungan. Dalam kode Anda, Anda membacanya melalui ENV['VAR'], dan dapat melewati mereka tepat sebelum rake perintah, suka

$ VAR=foo rake mytask

30
2018-05-05 16:53



Sebenarnya jawaban @Nick Desjardins sempurna. Tetapi hanya untuk pendidikan: Anda dapat menggunakan pendekatan kotor: menggunakan ENV argumen

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

rake my_task myvar=10
#=> myvar: 10

30
2018-02-28 20:06



Saya tidak tahu bagaimana cara melewati argumen dan juga lingkungan: sampai saya menyelesaikan ini:

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

Dan kemudian saya memanggilnya seperti ini:

rake db:export['foo, /tmp/']

24
2017-11-29 19:38



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

23
2017-10-16 07:36



Saya menggunakan argumen ruby ​​biasa dalam file penggaruk:

DB = ARGV[1]

kemudian saya menghentikan tugas penggaruk di bagian bawah file (karena rake akan mencari tugas berdasarkan nama argumen itu).

task :database_name1
task :database_name2

garis komando:

rake mytask db_name

ini terasa lebih bersih bagi saya daripada var = foo ENV var dan tugasnya berargumentasi [blah, blah2].
rintisannya agak jenky, tapi tidak terlalu buruk jika Anda hanya memiliki beberapa lingkungan yang merupakan pengaturan satu kali


13
2017-12-29 02:48