Как передать аргументы командной строки в задачу rake

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

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

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


person Tilendor    schedule 05.05.2009    source источник
comment
rakefile rdoc   -  person Brian Maltzan    schedule 19.05.2011
comment
Документы были скопированы SeattleRb.   -  person Jonathan Allard    schedule 02.11.2014


Ответы (19)


Параметры и зависимости должны быть внутри массивов:

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 лучше всего предварительно загрузить среду, добавив => [:environment], который является способом настройки зависимых задач.

  task :work, [:option, :foo, :bar] => [:environment] do |task, args|
    puts "work", args
  end
person Blair Anderson    schedule 07.04.2015
comment
Также убедитесь, что вы не используете пробелы между аргументами. Например, не делайте этого: rake thing:work[1, 2, 3], так как это не сработает, и вы получите сообщение об ошибке Don't know how to build task - person rpbaltazar; 29.09.2016
comment
Также убедитесь, что вы заключили аргумент в строку. например, из командной строки запустите задачу rake следующим образом rake thing:work'[1,2,3]' - person theterminalguy; 14.01.2017
comment
@DamianSimonPeter вам не нужно использовать строки. можно просто сделать rake thing:workd[true,false,cheese] значения будут строками! - person Blair Anderson; 11.02.2017
comment
К сожалению, zsh не может правильно разобрать вызов, вам нужно ввести команду на zsh, например: rake thing:work\[1,2,3\], или это rake 'thing:work[1,2,3]' - person hutusi; 27.07.2017
comment
Это не удалось для меня с ошибкой Don't know how to build task 'environment' (see --tasks) Ответ Ника Дежардена сработал отлично. - person sakurashinken; 16.04.2018
comment
@sakurashinken, вы можете убрать символ :environment из своей задачи. В приложениях rails есть задача: environment ... - person Blair Anderson; 16.04.2018
comment
Вместо пояснения, что t означает task, почему бы просто не использовать task в качестве имени параметра? - person Joshua Pinter; 05.05.2018
comment
@BlairAnderson Явность. Я люблю это! :-) - person Joshua Pinter; 11.05.2018
comment
Задачи Rake, похоже, имеют почти бессмысленную структуру для имени, зависимостей и аргументов. Вывод - пока он работает - это не то, к чему вы могли бы прийти интуитивно. - person user2490003; 15.04.2019
comment
Вот такая вот счетчик интуитивно понятная настройка для бегуна / системы задач. Это ни легко читается, ни легко записывается - person user2490003; 03.09.2019

Вы можете указать формальные аргументы в rake, добавив аргументы символа к вызову задачи. Например:

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

Затем из командной строки:

> rake my_task[1,false]
Args were: {:arg1=>"1", :arg2=>"false"} of class Rake::TaskArguments
arg1 was: '1' of class String
arg2 was: 'false' of class String

> 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]". Единственный способ указать разные аргументы для предварительного требования - это явно вызвать его внутри действия зависимой задачи, как в :invoke_my_task и :invoke_my_task_2.

Обратите внимание, что некоторые оболочки (например, zsh) требуют, чтобы вы избегали скобок: rake my_task\['arg1'\]

person Nick Desjardins    schedule 05.05.2009
comment
Это не говорит мне, как запустить задачу rake с аргументами из другой задачи. Он охватывает только использование командной строки - person Tilendor; 06.05.2009
comment
Чтобы вызвать задачу в пространстве имен, просто выполните: Rake :: Task ['namespace: task']. Invoke - person gaqzi; 07.08.2009
comment
На самом деле удивлен, я столько раз искал ответ на этот вопрос, и это всегда была задача rake arg1 = 2 arg2 = 3. Это намного проще, когда аргументы идут последовательно. - person opsb; 21.10.2010
comment
Спасибо, мне особенно нужно было передать аргументы в предварительную задачу, ваши примеры работают отлично. - person Rob; 13.01.2011
comment
@Rob, @Nick: особенно необходимо для передачи аргументов в предварительную задачу. Я не вижу примера явной передачи параметров в предварительную задачу .. Я что-то пропустил? Есть ли способ сделать это вместо вызова? - person inger; 22.03.2011
comment
Есть ли способ вызвать задачу более одного раза подряд? Я попробовал 5.times { Rake::Task[:my_task].invoke }, и это сработало только в первый раз. - person igorsantos07; 18.08.2011
comment
Это отдельный вопрос, Игорю, но причина того, что ваш вызов invoke выполняется только один раз, заключается в том, что rake ориентирован на зависимости, поэтому он будет выполнять задачу только в том случае, если она необходима. Для общих задач это означает, что он еще не был запущен. Чтобы явно выполнить задачу независимо от ее зависимостей или, если это необходимо, вызовите execute вместо invoke. - person Nick Desjardins; 18.08.2011
comment
Примечание. Согласно rake, этот синтаксис для приема переменных в задачах устарел: WARNING: 'task :t, arg, :needs => [deps]' is deprecated. Please use 'task :t, [args] => [deps]' instead. - person Ajedi32; 16.08.2012
comment
Обратите внимание, что zsh не может правильно проанализировать аргументы командной строки (zsh: no matches found: ...), поэтому вам нужно избегать скобок: rake my_task\['arg1'\]. Из robots.oughttbot.com/post / 18129303042 / - person Seth Bro; 17.07.2013
comment
@SethBro ДА. Если бы только ваш комментарий не был спрятан за ссылкой «Посмотреть больше комментариев», я бы не потратил 10 минут на то, чтобы сделать эту работу. - person GMA; 08.01.2014
comment
Добавьте alias rake='noglob rake' в свой .zshrc и забудьте о скобках. - person Roberto; 24.02.2016
comment
допустимый синтаксис для текущих рельсов (5): task :task_name, [:var1, :var2] => :environment do |t, vars|. Внутренние вары задач выглядят так: {:var1 => val, :var2 => val} - person res; 07.09.2016
comment
Для полноты: задача не может явно указать (или переопределить) значения для аргументов зависимой задачи. - person William Entriken; 16.03.2017
comment
ПРИМЕЧАНИЕ. Не добавляйте пробел между аргументами. Используйте rake my_task[1,2] вместо rake my_task[1, 2]. В противном случае вы получите ужасную Don't know how to build task 'my_task[1,' ошибку и будете чесать затылок дольше, чем хотели бы признать. - person Joshua Pinter; 08.05.2018
comment
в вашем последнем примере со значениями по умолчанию: это рекурсивный вызов with_defaults или имя задачи и имя метода просто совпадают? - person vlsd; 28.05.2021
comment
Какой смысл убегать от x и y в rake with_defaults['x','y']? В любом случае rake получает with_defaults[x,y]. - person x-yuri; 05.07.2021

В дополнение к ответу kch (я не нашел, как оставить комментарий к этому, извините):

Вам не нужно указывать переменные как ENV переменные перед командой rake. Вы можете просто установить их как обычные параметры командной строки, например:

rake mytask var=foo

и получить доступ к ним из вашего rake-файла как переменные ENV, например:

p ENV['var'] # => "foo"
person timurb    schedule 19.02.2011
comment
Это лучший самый простой ответ ИМО. Это сработало сразу. Что именно означает p? - person stevec; 02.06.2019
comment
@ user5783745 То же, что и put, но вместо того, чтобы регистрировать value.to_s в стандарте, он вызывает Obj.inspect и записывает его в стандартный вывод. ruby-doc.org/core-2.0.0/Kernel. html # method-ip - person kqcef; 03.06.2019
comment
И переопределить переменные среды? Фантастика! - person Damien Roche; 13.11.2019
comment
Рейк - это полностью замысловатый беспорядок, и это единственный способ, который сработал. И не только я, этот ответ набрал столько же голосов, что и правильный. - person lzap; 21.01.2020

Если вы хотите передать именованные аргументы (например, со стандартным OptionParser), вы можете использовать что-то вроде этого:

$ rake user:create -- --user [email protected] --pass 123

обратите внимание на --, который необходим для обхода стандартных аргументов Rake. Должен работать с Rake 0.9.x, ‹= 10.3.x.

В новой версии Rake изменился синтаксический анализ --, и теперь вы должны убедиться, что он не передан методу 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.

Также должен работать ярлык для аргументов:

 rake user:create -- -u [email protected] -p 123

Когда скрипты rake выглядят так, возможно, пришло время поискать другой инструмент, который позволил бы это прямо из коробки.

person Tombart    schedule 19.10.2013
comment
С моей точки зрения, это действительно лучший ответ. Обход клуджей переменных окружения, странный синтаксис с аргументами задачи, дополнительное преимущество для стандартного --option-names. Мое единственное предложение - использовать exit, а не abort, поскольку abort оставит вам код возврата 1 для оболочки. Если задача rake является частью сценария более высокого уровня, чаще предполагается, что ненулевой выход - это какой-то тип ошибки. - person Joe; 01.12.2013
comment
Я согласен с Джо, это лучший ответ. Естественно использовать тот же интерфейс для передачи параметров в грабли, что и при передаче параметров в скрипт. - person Rik Smith-Unna; 14.01.2014
comment
Я согласен, это лучший ответ. Разве нет способа обойти уродливое --? Например, передать rake аргумента реальной задаче или что-то в этом роде? Типа task :my_task, :*args do |t, args| или что-то в этом роде? - person Augustin Riedinger; 02.04.2014
comment
Кроме того, я не понимаю, для чего здесь {username}. Где это используется? Почему его нет в -u {username}? Ваше здоровье - person Augustin Riedinger; 03.04.2014
comment
Насколько я знаю, нет способа обойти уродливый -- (просто не используя грабли). {username} следует заменить на свое настоящее имя пользователя. Это просто обозначение переменной, оно не интерпретируется рубином. - person Tombart; 03.04.2014
comment
exit("account created.") вызывает ошибку rake aborted! не будет ли puts "account created"; exit(0) лучший подход? - person Justin Tanner; 20.11.2014
comment
У меня это сработало после того, как я дважды ARGV.shift удалил create:user и -- из ARGV. Я уверен, что так не следует делать. Буду признателен, если кто-нибудь покажет, как это исправить. - person pawel7318; 23.01.2015
comment
@ pawel7318 Какую версию Rake вы используете? Похоже, что Rake не следует семантическим соглашениям об управлении версиями, есть нарушение совместимости с 10.4.0 - person Tombart; 25.01.2015
comment
Способ, которым Rake анализирует ARGV, был изменен в 10.4.1 и возвращен в 10.4.2. github.com/ruby/rake/commit/ - person Tombart; 25.01.2015
comment
Я использую 10.4.2. Я создал новый вопрос здесь. - person pawel7318; 25.01.2015
comment
А как насчет использования пакета exec rake? - person valheru; 16.02.2017
comment
побочным эффектом использования exit 0 является то, что эта задача выходит из Rake по завершении. Итак, если у вас есть задача, которая вызывает 2 задачи, и она сначала вызывает вышеуказанное, вторая задача не будет запущена. - person karatedog; 23.07.2021

Я нашел ответ на этих двух веб-сайтах: Net Maniac и Нацеленный.

Для использования этой техники у вас должна быть версия rake> 0.8.

Обычное описание рейк-задачи таково:

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

Чтобы передать аргументы, сделайте три вещи:

  1. Добавьте имена аргументов после имени задачи, разделенные запятыми.
  2. Поместите зависимости в конце, используя: needs => [...]
  3. Место | t, аргументы | после делать. (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
person Tilendor    schedule 05.05.2009
comment
Формат этой функции был изменен, поскольку в этом предупреждении указано: 'task :t, arg, :needs => [deps]' is deprecated. Please use 'task :t, [args] => [deps]' instead. - person madh; 15.01.2012

На самом деле @Nick Desjardins ответил идеально. Но только для образования: вы можете использовать грязный подход: использовать аргумент ENV

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

rake my_task myvar=10
#=> myvar: 10
person fl00r    schedule 28.02.2011

Другой часто используемый вариант - передать переменные среды. В вашем коде вы читаете их через ENV['VAR'] и можете передавать их прямо перед командой rake, например

$ VAR=foo rake mytask
person kch    schedule 05.05.2009
comment
Откровенно говоря, я надеялся на задачу с граблями - эти --go --to -a программы, и моя задача могла получить их от ARGV. К сожалению, я не уверен, возможно ли это, но в настоящее время я использую ваше решение: rake var1 = val1 var2 = val2 - person JasonSmith; 03.08.2010
comment
@jhs: rake blah -- --these --go --to --a-program (обратите внимание на --, чтобы сообщить граблям, что его переключатели закончились), см. stackoverflow.com/questions/5086224/ - person mu is too short; 27.02.2011
comment
@muistooshort, к сожалению (не зная, как это работало в '11), он попытается запустить все переданные аргументы, как если бы они были задачами. Одно из наполовину уродливых решений - создать пустые задачи на основе ARGV, content, чтобы эти задачи действительно запускались, они просто ничего не будут делать, второе - exit в конце задачи. Выйти проще, но это сломает любую сложную задачу, которая пытается запустить существующую задачу вместе с другими, поскольку exit остановит выполнение задачи и выйдет из Rake. - person karatedog; 22.07.2021
comment
@karatedog Вы в этом уверены? Я просто попробовал, чтобы убедиться, и вроде все в порядке, я что-то упустил? - person mu is too short; 23.07.2021
comment
@muistooshort Верно, передача аргументов с двойным тире работает. Я не могу исправить предыдущий комментарий, ошибка заключалась в передаче аргументов командной строки в стиле Linux, например: --switch1 value1 --switch2 value2. - person karatedog; 23.07.2021

Я не мог понять, как передавать аргументы, а также среду:, пока не разобрался с этим:

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/']
person Nate Flink    schedule 29.11.2014
comment
Спасибо за это, отличное решение при сохранении: окружающей среды - person Olivier JM; 07.06.2020

Я просто хотел уметь бегать:

$ 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). ИМО не стоит. Просто используйте уродливый rake task[arg1,arg2].

person jassa    schedule 29.04.2016
comment
Это необходимо сделать _, arg1, arg2 = ARGV, поскольку первый аргумент был виден как имя задачи с граблями. Но это exit - изящный трюк. - person fatty; 13.09.2016
comment
rake task[arg1,arg2] && rake task2 && rake task3 Не уверен, что это менее уродливо, чем rake task[arg1,arg2] task2 task3. Хотя, вероятно, менее эффективен. - person Nuclearman; 11.11.2016
comment
_, *args = ARGV идеально подходит для сбора всех последующих аргументов! Большое спасибо! - person XtraSimplicity; 18.11.2018

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

DB = ARGV[1]

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

task :database_name1
task :database_name2

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

rake mytask db_name

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

person djburdick    schedule 29.12.2012
comment
Чтобы предотвратить проблемы с замороженными строками, используйте dup в конце: db = ARGV [1] .dup - person Juanda; 18.01.2013
comment
Событие лучше db = ARGV[1].dup unless ARGV[1].nil?, чтобы предотвратить исключение дублирования нуля. - person Andre Figueiredo; 30.06.2016

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

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

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

person Asim Mushtaq    schedule 24.04.2014

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

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

or

$ rake default[3.2.1]
version is 3.2.1

or

$ rake build[3.2.1]
version is 3.2.1

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

person Gal    schedule 20.10.2013

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

Пример:

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

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

width=10&height=20

Предупреждение: обратите внимание, что синтаксис - rake "mytask[foo=bar]", а НЕ 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:

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"}}
person Abdo    schedule 16.02.2014

Большинство описанных выше методов у меня не работали, возможно, они устарели в более новых версиях. Актуальное руководство можно найти здесь: 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
person hexinpeter    schedule 03.02.2015

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

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
person xander-miller    schedule 12.05.2017
comment
Вашему коду нужно несколько хорошо размещенных пустых строк. Я не знаю, как вы читаете эту стену с текстом. - person Joshua Pinter; 05.05.2018

Чтобы запустить rake-задачи с традиционным стилем аргументов:

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
person Daniel Garmoshka    schedule 13.02.2019

Я не вижу здесь как обрабатывать произвольные аргументы. Если вы передаете аргументы, которые не указаны в определении задачи, они по-прежнему доступны в args.extras:

task :thing, [:foo] do |task, args|
  puts args[:foo]     # named argument
  puts args.extras    # any additional arguments that were passed
end
person lobati    schedule 07.11.2020

При передаче параметров лучшим вариантом является входной файл, может ли это быть excel 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 
person tundervirld    schedule 27.02.2014
comment
Если вам нужен файл инструкций JSON для вашей задачи Rake, вы, вероятно, делаете слишком много вещей в своей задаче Rake. - person ZiggyTheHamster; 20.08.2015
comment
Это способ чрезмерного усложнения чего-то невероятно простого. - person jeffdill2; 31.12.2015
comment
Мы использовали задачу с граблями для выполнения многих сложных вещей, например, задачи. Один из них должен был быть входом в процесс ETL, и для этого вам могло понадобиться много полей ввода. Мы использовали задачу rake для выполнения многих сложных вещей, таких как задача. Один из них должен был быть входом в процесс ETL, и для этого вам могло понадобиться много полей ввода. Если вы думаете, что Rake Task предназначен только для самых простых вещей, возможно, вы не используете его в другом сложном контексте. Спасибо за комментарий. - person tundervirld; 24.11.2020

person    schedule
comment
Чтобы вызвать это, идите: rake task_name[hello, world] - person Dex; 27.04.2014
comment
из rake.rubyforge.org/files/doc/rakefile_rdoc.html Просто несколько слов предостережения. Имя задачи rake и ее аргументы должны быть одним аргументом командной строки для rake. Обычно это означает отсутствие пробелов. Если необходимы пробелы, следует заключить в кавычки всю строку аргумента rake +. Примерно так: имя грабли [билли боб, смит] - person Gayle; 13.05.2014