여러 데이터베이스에 값을 삽입 해야하는 레이크 작업이 있습니다.
이 값을 명령 행 또는 다른 레이크 작업 에서 레이크 작업으로 전달하고 싶습니다 .
어떻게해야합니까?
여러 데이터베이스에 값을 삽입 해야하는 레이크 작업이 있습니다.
이 값을 명령 행 또는 다른 레이크 작업 에서 레이크 작업으로 전달하고 싶습니다 .
어떻게해야합니까?
답변:
옵션과 종속성은 배열 안에 있어야합니다.
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
는 작업 객체이므로 Rake 내부를 알거나 관리하지 않는 한 크게 도움이되지 않습니다.
레일 노트 :
레일에서 작업을 실행하는 경우 종속 작업
=> [: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, 거짓] Arke : 클래스 Rake :: TaskArguments의 {: arg1 => "1", : arg2 => "false"} arg1은 다음과 같습니다 : String 클래스의 '1' arg2는 다음과 같습니다 : String 클래스의 'false' > "my_task [1, 2]"갈퀴 인수는 {: arg1 => "1", : arg2 => "2"}입니다. > invoke_my_task 레이크 인수는 {: arg1 => "1", : arg2 => "2"}입니다. > invoke_my_task_2 갈퀴 인수 : {: arg1 => 3, : arg2 => 4} > with_prerequisite [5,6] 갈퀴 인수는 {: arg1 => "5", : arg2 => "6"}입니다. > 레이크 with_defaults 기본값이있는 Args는 {: arg1 => : default_1, : arg2 => : default_2}입니다. > with_defaults [ 'x', 'y'] 갈퀴 기본값이있는 Args는 {: arg1 => "x", : arg2 => "y"}입니다.
두 번째 예에서 설명했듯이 공백을 사용하려면 셸에서 공백을 인수로 나누지 않도록 대상 이름을 따옴표로 묶어야합니다.
rake.rb 의 코드를 보면 rake가 작업 문자열을 구문 분석하여 전제 조건의 인수를 추출하지 않으므로 수행 할 수없는 것으로 보입니다 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
뜻입니까?
명명 된 인수 (예 : standard 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의 리턴 코드로 당신을 떠날 것입니다. 레이크 작업이 상위 레벨 스크립트의 일부인 경우 0이 아닌 종료가 일종의 오류라고 가정하는 것이 더 일반적입니다.
--
없습니까? rake
실제 작업이나 다른 것에 인수를 전달하는 것처럼 ? 좋아하는 task :my_task, :*args do |t, args|
것?
{username}
여기에 무엇이 있는지 이해하지 못합니다 . 어디에 사용됩니까? 왜 거기에 -u {username}
없습니까? 건배
Net Maniac 과 Aimred라는 두 웹 사이트에서 답을 찾았 습니다 .
이 기술을 사용하려면 레이크> 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
명령 행에서이 태스크를 호출하려면 [] s의 인수를 전달하십시오.
rake task_name['Hello',4]
출력합니다
Hello
Hello
Hello
Hello
다른 작업 에서이 작업을 호출하고 인수를 전달하려면 invoke를 사용하십시오.
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/를
내가 이것을 해결할 때까지 args와 : environment를 전달하는 방법을 알 수 없었습니다.
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
간단 하죠? (아니!)
Rake 는 작업을 해석 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 및 task args [blah, blah2] 솔루션보다 깨끗하다고 느낍니다.
스텁은 약간 까다 롭지 만 일회성 설정 인 몇 가지 환경이있는 경우 너무 나쁘지 않습니다.
dup
끝에 사용 하십시오. db = ARGV [1] .dup
db = ARGV[1].dup unless ARGV[1].nil?
nil을 두는 예외를 방지하는 것이 좋습니다 .
기본 작업에 인수를 전달하려면 다음과 같이하십시오. 예를 들어, "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
그러나 인수를 전달하는 동안 작업 이름 (기본값 또는 빌드)을 지정하지 않는 방법을 찾지 못했습니다. 누군가 방법을 알고 있다면 듣고 싶습니다.
전달할 인수가 많을 때 인수 전달에 대한 "querystring"구문이 마음에 듭니다.
예:
rake "mytask[width=10&height=20]"
"querystring"은 다음과 같습니다.
width=10&height=20
경고 : 메모를 구문이되어 rake "mytask[foo=bar]"
및 NOT 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 gem 에서 Rails와 함께 사용하는 더 확장 된 예입니다 .
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"}}
어떤 인수 위치가 무엇인지 기억하고 귀찮은 경우 루비 인수 해시와 같은 것을 원합니다. 하나의 인수를 사용하여 문자열을 전달한 다음 해당 문자열을 옵션 해시로 정규화 할 수 있습니다.
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
매개 변수를 전달하는 동안 더 나은 옵션은 입력 파일입니다. 이는 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
{
"name_task": "I'm a task",
"user_id": 389,
"users_assigned": [389,672,524],
"task_id": 3
}
rake :name_task