Soru Komut satırı argümanlarını bir komisyon görevine nasıl geçirilir


Birden çok veritabanına bir değer eklemesi gereken bir komisyon görevim var.

Bu değeri komut satırından komisyon görevine geçirmek isterim veya bir diğeri komisyon görevi.

Bunu nasıl yapabilirim?


952
2018-05-05 16:27


Menşei


rakefile rdoc - Brian Maltzan
Dokümanlar SeattleRb tarafından yansıtılmıştır. - Jonathan Allard
Kabul edilen cevabı şu an çok güncel değil diye, kabul edilen cevabı @BlairAnderson'dan değiştirebilir misiniz? Bu konu için Google'da bu soru yüksek görünüyor! - rmcsharry


Cevaplar:


seçenekler ve bağımlılıkların diziler içinde olması gerekir:

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

Sonra

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

NOT: değişken task Rake internals hakkında bilmedikçe / umursamadığınız sürece, görev nesnesi çok yararlı değil.

RAYLAR NOT:

Eğer görevi raylardan çalıştırıyorsanız, ekleyerek çevreyi önceden yüklemek en iyisidir. => [:environment] kurulumun bir yolu bağımlı görevler.

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

230
2018-04-07 21:56



Bu Ağustos 2016 yılında m için çalıştı ... güncellenmiş bir cevabın bence bu güncellenmelidir! - rmcsharry
Bunu istek üzerine cevap olarak kabul etmek için güncelledim. Bununla birlikte, bir görevin kendisinden başka bir komisyon görevine nasıl argüman gönderileceğini göstermemektedir. - Tilendor
Ayrıca, bağımsız değişkenler arasındaki boşlukları kullanmadığınızdan emin olun. E.G bunu yapma: rake thing:work[1, 2, 3] işe yaramayacak ve bir hata alacaksınız Don't know how to build task - rpbaltazar
Ayrıca, argümanı dizeye eklediğinizden emin olun. örneğin komut satırından, komisyon görevini çalıştır rake thing:work'[1,2,3]' - Damian Simon Peter
Maalesef, zsh çağrıyı doğru şekilde ayrıştırılamaz, zsh komutunu şu şekilde yazmanız gerekir: rake thing:work\[1,2,3\], veya bu rake 'thing:work[1,2,3]' - hutusi


Görev çağrısına sembol argümanları ekleyerek resmi argümanları rake olarak belirtebilirsiniz. Örneğin:

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

Sonra, komut satırından:

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

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

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

> rake Instagram Hesabındaki Resim ve Videoları invoke_my_task_2
Args'ler: {: arg1 => 3,: arg2 => 4}

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

> rake with_defaults
Varsayılanları olan kodlar: {: arg1 =>: default_1,: arg2 =>: default_2}

> rake with_defaults ['x', 'y']
Varsayılanları olan kodlar: {: arg1 => "x",: arg2 => "y"}

İkinci örnekte gösterildiği gibi, boşluk kullanmak isterseniz, kabuğun boşluktaki argümanları bölmesini engellemek için hedef ismin etrafındaki alıntılar gereklidir.

İçine kod bakmak rake.rb, komisyonun önkoşullar için argümanları ayıklamak için görev dizelerini ayrıştırmadığı anlaşılıyor, bu yüzden yapamazsınız task :t1 => "dep[1,2]". Bir önkoşul için farklı argümanlar belirlemenin tek yolu, bağımlı görev eylemi içinde açıkça olduğu gibi :invoke_my_task ve :invoke_my_task_2.

Bazı kabukların (zsh gibi) parantezlerden kaçmanızı gerektirdiğini unutmayın: rake my_task\['arg1'\]


1081
2018-05-05 16:45



Bir isim içinde bir görevi çağırmak için simpy yapmak: Rake :: Task ['namespace: task']. - gaqzi
Bu ayrı bir soru, Igoru, ama çağırma çağrınızın sadece bir kez çalıştırılmasının sebebi, bu komisyonun bağımlılık yönelimli olması, yani eğer gerekliyse sadece bir görevi yürütmesidir. Genel görevleri için, daha önce çalışmadıysa. Bağımlılıklarından bağımsız olarak bir işi açık bir şekilde yürütmek için veya gerekirse, çağırma yerine çağrıyı çağırın. - Nick Desjardins
Not: Komisyona göre, değişkenlerdeki görevleri kabul etmek için kullanılan bu sözdizimi kullanımdan kaldırılmıştır: WARNING: 'task :t, arg, :needs => [deps]' is deprecated. Please use 'task :t, [args] => [deps]' instead. - Ajedi32
Zsh komut satırı argümanlarını doğru şekilde ayrıştırılamayacağını unutmayın (zsh: no matches found: ...), böylece parantezlerden kaçmanız gerekiyor: rake my_task\['arg1'\]. itibaren robots.thoughtbot.com/post/18129303042/... - Seth Bro
@SethBro YES. Sadece yorumunuz "Daha fazla yorum gör" bağlantısının arkasına gizlenmemiş olsaydı, bu işi yapamayan 10 dakika israf olmazdım. - GMA


Kch ile yanıtlamaya ek olarak (buna nasıl yorumda bulunacağımı bulamadım, üzgünüm):

Değişkenleri belirtmeniz gerekmez. ENV önce değişkenler rake Komut. Onları her zamanki gibi komut satırı parametreleri gibi ayarlayabilirsiniz:

rake mytask var=foo

ve aşağıdaki gibi ENV değişkenleri olarak rake dosyanızdan olanlara erişebilirsiniz:

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

287
2018-02-19 11:05



Bu gerçekten uygun. Teşekkürler! - Hoang Le
Ah Bu yüzden bu Rails böyle yapar. Mantıklı... - Ajedi32


Adlandırılmış bağımsız değişkenleri (örneğin standart) geçmek istiyorsanız OptionParser) Böyle bir şey kullanabilirsiniz:

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

not etmek --Standart Rake argümanlarını atlamak için gereklidir. Rake ile çalışmalı 0.9.x, <= 10.3.x.

Daha yeni Rake ayrışmasını değiştirdi --ve şimdi ona geçmediğinden emin olmalısın OptionParser#parse yöntemle, örneğin 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 Sonunda, ekstra argümanların Rake görevi olarak yorumlanmayacağından emin olun.

Ayrıca argümanlar için kısayol çalışmalıdır:

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

Komisyon komut dosyaları böyle göründüğünde, belki de bu kutudan çıkmasına izin veren başka bir araç aramanın zamanı gelmiştir.


94
2017-10-19 13:09



Benim bakış açımdan bu gerçekten en iyi cevaptır. Bypass ortam değişken kludges, görev argümanları ile garip sözdizimi, standart için ek yarar --option-names. Tek önerim kullanmak olurdu exit ziyade abort gibi abort sizi 1'e geri dönüş kodu ile bırakacaktır. Komisyon görevi üst düzey bir komut dosyasının bir parçasıysa, sıfır olmayan bir çıkışın bir tür hata olduğunu varsaymak daha yaygındır. - Joe
Joe'ya katılıyorum, bu en iyi cevap. Doğal olan, seçenekleri bir komut dosyasına geçirirken olduğu gibi geçiş yapmak için seçenekleri aktarmak için aynı arabirimi kullanmaktır. - Rik Smith-Unna
Bunun en iyi cevap olduğuna katılıyorum. Çirkinliği atlamanın bir yolu yok. --? Geçmek gibi rake asıl görev ya da bir şey için argümanlar? Sevmek task :my_task, :*args do |t, args| ya da başka birşey? - Augustin Riedinger
Ayrıca ne olduğunu anlamıyorum {username} için burada. Nerede kullanılır? Neden orada değil -u {username}? Şerefe - Augustin Riedinger
Rake’in ARGV’yi nasıl değiştirdiği 10.4.1 ve geri döndü 10.4.2. github.com/ruby/rake/commit/... - Tombart


Bu iki web sitesinden cevabı buldum: Net Maniac ve Aimred.

Bu tekniği kullanabilmek için sürüm> 0.8'inin olması gerekir.

Normal tırmık görevi açıklaması şu şekildedir:

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

Argümanları geçmek için üç şey yapın:

  1. Bağımsız değişken adlarını görev adından sonra virgülle ayırarak ekleyin.
  2. Bağımlılıkları aşağıdakileri kullanarak sonlandırın: needs => [...]
  3. Yer | t, args | yaptıktan sonra. (t bu görev için nesnedir)

Komut dosyasındaki bağımsız değişkenlere erişmek için args.arg_name adresini kullanın.

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

Bu görevi komut satırından aramak için, [] s içindeki argümanları iletin

rake task_name['Hello',4]

çıktı olacak

Hello
Hello
Hello
Hello

ve bu görevi başka bir görevden çağırmak ve argümanları iletmek istiyorsanız,

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

sonra komut

rake caller

çıktı olacak

In Caller
hi
hi

Aşağıdaki kod kırılırken, bağımsız değişkenin bir parçası olarak bağımsız değişkenleri iletmenin bir yolunu bulamadım:

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

56
2018-05-05 16:51



Bu işlevin formatı, bu uyarı durumu olarak değişti: 'task :t, arg, :needs => [deps]' is deprecated. Please use 'task :t, [args] => [deps]' instead. - madh


Yaygın olarak kullanılan başka bir seçenek de çevre değişkenlerini geçmek. Kodunuzda bunları okuyorsunuz ENV['VAR']ve hemen önce bunları geçebilir rake komut gibi

$ VAR=foo rake mytask

30
2018-05-05 16:53



Açıkçası ben komisyon görevi - bu --go - to-bir program umuyordum ve görevim onları ARGV'den alabilir. Ne yazık ki mümkün değil mi emin değilim ancak şu anda çözümünüzü kullanıyorum: rake var1 = val1 var2 = val2 - JasonSmith
@jhs: rake blah -- --these --go --to --a-program (not -- anahtarlarının sona erdiğini söylemek için), bkz. stackoverflow.com/questions/5086224/... - mu is too short


Aslında @Nick Desjardins mükemmel cevap verdi. Fakat sadece eğitim için: kirli yaklaşımı kullanabilirsiniz: ENV tartışma

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

rake my_task myvar=10
#=> myvar: 10

30
2018-02-28 20:06





Ben bunları çalıştı kadar args nasıl geçeceğini ve: çevre ne olduğunu anlayamadım:

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

Ve sonra şöyle diyoruz:

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



Bunu söylemek için gidin: rake task_name[hello, world] - Dex
itibaren rake.rubyforge.org/files/doc/rakefile_rdoc.html   "Sadece bir kaç uyarı söz konusu. Komisyon görevi adı ve argümanları, rake için tek bir komut satırı argümanı olmalıdır. Bu genellikle boşluklar anlamına gelir. Boşluklar gerekliyse, tüm rake + argüman dizgisi alıntılanmalıdır. bu: rake "adı [billy bob, smith]" " - Gayle


Komisyon dosyasında normal bir Ruby argümanı kullanıyorum:

DB = ARGV[1]

sonra dosyanın altındaki komisyon görevlerini koyarım (rake o argüman adına dayalı bir görev arar).

task :database_name1
task :database_name2

Komut satırı:

rake mytask db_name

Bu benim için daha iyi hissettirir var = foo ENV var ve görev [blah, blah2] çözümleri.
Bir kerelik bir kurulum olan birkaç ortamınız varsa, saplama biraz jenky, fakat çok da kötü değil


13
2017-12-29 02:48



Donmuş dizeleri önlemek için dup sonunda: db = ARGV [1] .dup - Juanda
Etkinlik daha iyi db = ARGV[1].dup unless ARGV[1].nil? bir nil duping istisnasını önlemek için. - Andre Figueiredo


Sadece koşabilmek istedim:

$ rake some:task arg1 arg2

Basit, değil mi? (Hayır!)

Rake interprets arg1 ve arg2 görevleri olarak çalıştırmayı dener. Yani biz bunu yapmadan önce iptal ediyoruz.

namespace :some do
  task task: :environment do
    arg1, arg2 = ARGV

    # your task...

    exit
  end
end

Bunu al, parantez!

feragat: Bunu oldukça küçük bir evcil hayvan projesinde yapmak istedim. "Gerçek dünya" kullanımı için tasarlanmamıştır, çünkü komisyon görevlerini yerine getirme yeteneğini kaybedersiniz (örn. rake task1 task2 task3). IMO buna değmez. Sadece çirkin kullan rake task[arg1,arg2].


12
2018-04-29 03:29



Bunu yapmak için gerekli _, arg1, arg2 = ARGV İlk arg olarak komisyon görevi olarak görülüyordu. Ama bu exit temiz bir numaradır. - fatty
rake task[arg1,arg2] && rake task2 && rake task3 Bundan daha az çirkin olup olmadığından emin değilsiniz. rake task[arg1,arg2] task2 task3. Muhtemelen daha az verimli olsa da. - Nuclearman