ruby - 레이크 작업에 명령 줄 인수를 전달하는 방법




command-line rake command-line-arguments (15)

나는이 두 웹 사이트에서 답을 찾았습니다 : Net ManiacAimred .

이 기법을 사용하려면 레이크 버전이 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

명령 줄에서이 작업을 호출하려면 [] 안에 인수를 전달하십시오.

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

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

이 값을 명령 줄이나 다른 레이크 작업에서 rake 작업으로 전달하고 싶습니다.

어떻게해야합니까?


나는 지금 막 달릴 수 있고 싶었다 :

$ rake some:task arg1 arg2

간단 하죠? (아니!)

Rake는 arg1arg2 를 태스크로 해석하고 실행하려고 시도합니다. 그래서 우리는 단지 그것을하기 전에 중단합니다.

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 "mytask[width=10&height=20]"

"querystring"존재 :

width=10&height=20

경고 : 구문은 rake "mytask[foo=bar]" 이고 rake mytask["foo=bar"] 아닙니다 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]"

위와 같은 방식으로 환경 의존성을 파싱했다 (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"}}

레이크 파일에서 일반적인 루비 인수를 사용합니다.

DB = ARGV[1]

파일의 맨 아래에있는 레이크 작업을 스텁 아웃합니다 (레이크가 해당 인수 이름을 기반으로 작업을 찾을 것이기 때문에).

task :database_name1
task :database_name2

명령 줄 :

rake mytask db_name

이것은 var = foo ENV var 및 task args [blah, blah2] 솔루션보다 나에게 더 깔끔하게 느껴집니다.
그루터기는 조금 천천히 지내지 만 한 번 설정하는 몇 가지 환경 만 있다면 너무 나쁘지 않습니다.


기본 작업에 인수를 전달하려면 다음과 같이하면됩니다. 예를 들어, "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

그러나 인수를 전달하는 동안 작업 이름 (기본 또는 빌드)을 지정하지 않도록하는 방법을 찾지 못했습니다. 아무도 모른다면 듣고 싶습니다.


매개 변수를 전달하는 동안 더 나은 옵션은 입력 파일입니다.이 옵션은 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 

타스크 인수에 기호 인수를 추가하여 레이크에서 형식 인수를 지정할 수 있습니다. 예 :

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 의 코드를 보면 rake가 선행 조건에 대한 인수를 추출하기 위해 작업 문자열을 구문 분석하지 않으므로 작업을 수행 할 수 없습니다 task :t1 => "dep[1,2]" . 제반 사항에 대해 다른 인수를 지정하는 유일한 f}은 :invoke_my_task W :invoke_my_task_2 와 같이 종속 타스크 조치에서 명시 적으로 호출하는 것입니다.

일부 쉘 (zsh과 같은)은 대괄호를 이스케이프해야합니다. rake my_task\['arg1'\]


인수를 전달하는 방법은 위의 대답에서 정확합니다. 그러나 인수를 사용하여 레이크 작업을 실행하려면 새로운 버전의 레일에 관련된 작은 기술적 인 문제가 있습니다.

rake "네임 스페이스와 함께 작동합니다 : taskname [ 'argument1']"

명령 행에서 태스크를 실행할 때 거꾸로 된 따옴표를 주목하십시오.


실제로 @Nick Desjardins는 완벽하다고 대답했습니다. 하지만 그냥 교육 : 당신은 더러운 접근 방식을 사용할 수 있습니다 : ENV 인수 사용

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

rake my_task myvar=10
#=> myvar: 10

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

만약 당신이 어떤 인수 위치가 무엇인지를 기억하지 못한다면, 루비 인자 해쉬와 같은 일을하고 싶을 것입니다. 하나의 인수를 사용하여 문자열을 전달한 다음 해당 문자열을 옵션 해시로 정규 표현할 수 있습니다.

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

나는이 문제를 해결할 때까지 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/']

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

$ VAR=foo rake mytask

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

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 내부 정보를 알고 있거나 신경 쓰지 않는 한별로 도움이되지 않습니다.

RAILS NOTE :

작업을 레일에서 실행하는 경우 종속 작업을 설정하는 방법 인 => [:environment] 을 추가하여 환경을 미리로드하는 것이 가장 좋습니다.

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

나는 이것을 사용 해왔다.

cat myfile.txt | wc -l

나는 그것이 파일 이름을 출력하지 않기 때문에 받아 들여진 대답보다 선호한다. 그리고 awk 를 사용하여 그것을 고칠 필요가 없다. 수락 된 답변 :

wc -l myfile.txt

그러나 나는 최고의 것이 GGB667의 대답이라고 생각한다.

wc -l < myfile.txt

아마 지금부터 사용할 것입니다. 제 길보다 약간 짧습니다. 나는 누구든지 그것을 선호한다면 그것을하기 위해 나의 오래된 방식을 버리고있다. 출력은 두 가지 방법과 동일합니다.





ruby command-line rake command-line-arguments