Как передать аргументы командной строки в задачу rake - PullRequest
1028 голосов
/ 05 мая 2009

У меня есть задача rake, которая должна вставить значение в несколько баз данных.

Я бы хотел передать это значение в задачу rake из командной строки или из другой задачи rake.

Как я могу это сделать?

Ответы [ 18 ]

12 голосов
/ 29 декабря 2012

Я использую обычный аргумент ruby ​​в файле rake:

DB = ARGV[1]

затем я заглушаю задачи rake внизу файла (поскольку rake будет искать задачу по имени этого аргумента).

task :database_name1
task :database_name2

командная строка:

rake mytask db_name

для меня это чище, чем для var = foo ENV var и args [blah, blah2].
заглушка немного дрянная, но не так уж и плоха, если у вас всего несколько сред, которые являются одноразовыми

5 голосов
/ 24 апреля 2014

Способы передачи аргумента верны в ответе выше. Однако, чтобы запустить грабли с аргументами, в более новой версии rails есть небольшая сложность

Будет работать с граблями "namespace: taskname ['arguments1']"

Обратите внимание на кавычки при запуске задачи из командной строки.

4 голосов
/ 17 февраля 2014

Мне нравится синтаксис querystring для передачи аргументов, особенно когда нужно передать много аргументов.

Пример:

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

Строка запроса:

width=10&height=20

Предупреждение: обратите внимание, что синтаксис: rake "mytask[foo=bar]" и NOT rake mytask["foo=bar"]

При анализе внутри задачи rake с использованием 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

Вот более расширенный пример, который я использую с Rails в моем delayed_job_active_record_threaded gem:

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"}}
3 голосов
/ 20 октября 2013

Чтобы передать аргументы задаче по умолчанию, вы можете сделать что-то вроде этого. Например, скажем «версия» - ваш аргумент:

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

Однако я не нашел способа избежать указания имени задачи (по умолчанию или сборка) при передаче аргументов. Хотелось бы услышать, если кто-нибудь знает способ.

2 голосов
/ 12 мая 2017

Если вы не можете вспомнить, какая позиция аргумента для чего, и вы хотите сделать что-то вроде хеша рубинового аргумента. Вы можете использовать один аргумент, чтобы передать строку, а затем пересмотреть эту строку в хэш опций.

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
2 голосов
/ 03 февраля 2015

Большинство методов, описанных выше, у меня не сработали, возможно, они устарели в более новых версиях. Актуальное руководство можно найти здесь: http://guides.rubyonrails.org/command_line.html#custom-rake-tasks

Копия и вставка из руководства здесь:

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
1 голос
/ 13 февраля 2019

Для запуска граблей с традиционным стилем аргументов:

rake task arg1 arg2

А затем используйте:

task :task do |_, args|
  puts "This is argument 1: #{args.first}"
end

Добавить следующий патч rake gem:

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
0 голосов
/ 27 февраля 2014

При передаче параметров лучше выбрать входной файл, может ли это быть 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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...