문제

여러 데이터베이스에 값을 삽입해야 하는 rake 작업이 있습니다.

이 값을 명령줄에서 rake 작업으로 전달하고 싶습니다. 또 다른 갈퀴 작업.

어떻게 해야 하나요?

도움이 되었습니까?

해결책

옵션 및 종속성은 배열 내부에 있어야합니다.

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 레이크 내부에 대해 알고 있거나 신경 쓰지 않는 한 작업 객체입니다.

레일 참고 :

레일에서 작업을 실행하는 경우 추가하여 환경을 예압하는 것이 가장 좋습니다. => [:environment] 설정하는 방법입니다 매달린 작업.

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

다른 팁

작업 호출에 기호 인수를 추가하여 레이크에서 공식 인수를 지정할 수 있습니다. 예를 들어:

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

두 번째 예에서 알 수 있듯이 공백을 사용하려면 쉘이 공간에서 인수를 분할하는 것을 막기 위해 대상 이름 주변의 인용문이 필요합니다.

코드를보고 있습니다 Rake.rb, 레이크는 전제 조건에 대한 인수를 추출하기 위해 작업 문자열을 구문 분석하지 않으므로 할 수 없습니다. task :t1 => "dep[1,2]". 전제 조건에 대한 다른 인수를 지정하는 유일한 방법은 :invoke_my_task 그리고 :invoke_my_task_2.

ZSH와 같은 일부 껍질은 괄호를 피해야합니다. rake my_task\['arg1'\]

KCH의 답변 외에도 (죄송합니다. 죄송합니다) :

변수를 다음과 같이 지정할 필요가 없습니다 ENV 전 변수 rake 명령. 일반적인 명령 줄 매개 변수로 설정할 수 있습니다.

rake mytask var=foo

그리고 레이크 파일에서 나온 것과 같은 ENV 변수로 액세스하십시오.

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

지명 인수를 전달하려면 (예 : 표준으로 OptionParser) 다음과 같은 것을 사용할 수 있습니다.

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

참고 --, 그것은 표준 레이크 인수를 우회하는 데 필요합니다. 레이크와 함께 일해야합니다 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

레이크 스크립트가 이렇게 보일 때, 아마도 이것을 상자 밖에서 허용하는 다른 도구를 찾아야 할 때입니다.

이 두 웹 사이트에서 답을 찾았습니다. 순 미치광이 그리고 AIMRED.

이 기술을 사용하려면 Rake의 버전> 0.8이 필요합니다.

일반적인 레이크 작업 설명은 다음과 같습니다.

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

논증을 통과하려면 세 가지를 수행하십시오.

  1. 쉼표로 분리 된 작업 이름 뒤에 인수 이름을 추가하십시오.
  2. 다음을 사용하여 종속성을 끝에 두십시오. 니ors => [...
  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

이 작업을 다른 작업에서 호출하고 인수를 전달하려면 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

일반적으로 사용되는 또 다른 옵션은 환경 변수를 통과하는 것입니다. 코드에서 당신은 그것들을 통해 읽습니다 ENV['VAR'], 바로 앞에 전달할 수 있습니다 rake 명령

$ VAR=foo rake mytask

실제로 @nick desjardins는 완벽하게 대답했습니다. 그러나 교육을 위해서만 : 더러운 접근법을 사용할 수 있습니다 : 사용 ENV 논쟁

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

rake my_task myvar=10
#=> myvar: 10

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/']
desc 'an updated version'
task :task_name, [:arg1, :arg2] => [:dependency1, :dependency2] do |t, args|
    puts args[:arg1]
end

방금 달릴 수 있기를 원했습니다.

$ 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). IMO는 가치가 없습니다. 못생긴 것을 사용하십시오 rake task[arg1,arg2].

나는 rake 파일에 일반 Ruby 인수를 사용합니다.

DB = ARGV[1]

그런 다음 파일 하단에서 rake 작업을 제거합니다(rake는 해당 인수 이름을 기반으로 작업을 찾기 때문입니다).

task :database_name1
task :database_name2

명령줄:

rake mytask db_name

이것은 var=foo ENV var 및 작업 args[blah, blah2] 솔루션보다 더 깨끗하다고 ​​느껴집니다.
스텁은 약간 지저분하지만 일회성 설정인 몇 가지 환경만 있는 경우에는 그리 나쁘지 않습니다.

인수를 전달하는 방법은 위의 답변에서 정확합니다. 그러나 인수로 레이크 작업을 실행하려면 최신 버전의 Rails와 관련된 작은 기술이 있습니다.

레이크 "네임 스페이스 : taskName [ 'argument1']으로 작동합니다.

명령 줄에서 작업을 실행할 때 거꾸로 된 인용문에 유의하십시오.

나는 인수 통과에 대한 "querystring"구문을 좋아합니다. 특히 통과해야 할 논쟁이 많이있을 때.

예시:

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

"QueryString"존재 :

width=10&height=20

경고: 구문은입니다 rake "mytask[foo=bar]" 그리고 아니다 rake mytask["foo=bar"]

레이크 작업을 사용하여 구문 분석 할 때 Rack::Utils.parse_nested_query , 우리는 a 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

다음은 내에서 레일과 함께 사용하는 더 확장 된 예입니다. DINEDED_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"}}

기본 작업에 인수를 전달하려면 이와 같은 작업을 수행 할 수 있습니다. 예를 들어, "버전"이라고 말하십시오.

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

그러나 인수를 전달하는 동안 작업 이름 (기본 또는 빌드)을 지정하지 않는 방법을 찾지 못했습니다. 누군가가 방법을 알고 있다면 듣고 싶습니다.

위에서 설명한 대부분의 방법은 나에게 효과가 없었으며 아마도 최신 버전으로 더 이상 사용되지 않았을 것입니다. 최신 가이드는 여기에서 찾을 수 있습니다. 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

당신이 무엇을위한 논쟁의 위치가 무엇인지 기억하고 루비 논쟁 해시와 같은 일을하고 싶어한다면 귀찮게 할 수 없다면. 하나의 인수를 사용하여 문자열로 전달한 다음 해당 문자열을 옵션 해시로 다시 선택할 수 있습니다.

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

전통적인 인수 스타일로 레이크 작업을 실행하려면 :

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

매개 변수를 전달하는 반면 더 나은 옵션은 입력 파일입니다. 이는 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 
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top