ruby - variable - zsh rake task arguments




Como passar argumentos de linha de comando para uma tarefa de rake (12)

A maioria dos métodos descritos acima não funcionou para mim, talvez eles estejam obsoletos nas versões mais recentes. O guia atualizado pode ser encontrado aqui: http://guides.rubyonrails.org/command_line.html#custom-rake-tasks

um ans de copiar e colar do guia está aqui:

task :task_name, [:arg_1] => [:pre_1, :pre_2] do |t, args|
  # You can use args from here
end

Invoque-o assim

bin/rake "task_name[value 1]" # entire argument string should be quoted

Eu tenho uma tarefa de ancinho que precisa inserir um valor em vários bancos de dados.

Eu gostaria de passar este valor para a tarefa rake a partir da linha de comando, ou de outra tarefa rake.

Como posso fazer isso?


Além de responder por kch (não achei como deixar um comentário para isso, desculpe):

Você não precisa especificar variáveis ​​como variáveis ENV antes do comando rake . Você pode apenas configurá-los como parâmetros de linha de comando normais, como:

rake mytask var=foo

e acessar aqueles do seu arquivo rake como variáveis ​​ENV como:

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

As maneiras de passar o argumento estão corretas na resposta acima. No entanto, para executar a tarefa de rake com argumentos, há um pequeno detalhe técnico envolvido na versão mais recente dos trilhos

Ele funcionará com rake "namespace: taskname ['argument1']"

Observe as aspas invertidas na execução da tarefa a partir da linha de comando.


Eu encontrei a resposta destes dois sites: Net Maniac e Aimred .

Você precisa ter versão> 0.8 de rake para usar esta técnica

A descrição normal da tarefa de rake é esta:

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

Para passar argumentos, faça três coisas:

  1. Adicione os nomes dos argumentos após o nome da tarefa, separados por vírgulas.
  2. Coloque as dependências no final usando: needs => [...]
  3. Coloque | t, args | depois do fazer. (t é o objeto para esta tarefa)

Para acessar os argumentos no script, use 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

Para chamar esta tarefa a partir da linha de comando, passe os argumentos em [] s

rake task_name['Hello',4]

vai sair

Hello
Hello
Hello
Hello

e se você quiser chamar essa tarefa de outra tarefa e passar argumentos, use invoke

task :caller do
  puts 'In Caller'
  Rake::Task[:task_name].invoke('hi',2)
end

então o comando

rake caller

vai sair

In Caller
hi
hi

Eu não encontrei uma maneira de passar argumentos como parte de uma dependência, como o seguinte código quebra:

task :caller => :task_name['hi',2]' do
   puts 'In Caller'
end

Eu não conseguia descobrir como passar args e também o: ambiente até que eu trabalhei isso:

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

E então eu chamo assim:

rake db:export['foo, /tmp/']

Eu só queria poder correr:

$ rake some:task arg1 arg2

Simples, certo? (Não!)

O Rake interpreta arg1 e arg2 como tarefas e tenta executá-las. Então, nós apenas abortamos antes disso.

namespace :some do
  task task: :environment do
    arg1, arg2 = ARGV

    # your task...

    exit
  end
end

Tome isso, colchetes!

Disclaimer : Eu queria ser capaz de fazer isso em um projeto de estimação muito pequeno. Não se destina ao uso do "mundo real", já que você perde a capacidade de executar tarefas de rake (isto é, rake task1 task2 task3 ). IMO não vale a pena. Basta usar a feia rake task[arg1,arg2] .


Na verdade, @Nick Desjardins respondeu perfeito. Mas apenas para educação: você pode usar abordagem suja: usando o argumento ENV

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

rake my_task myvar=10
#=> myvar: 10

Outra opção comumente usada é passar variáveis ​​de ambiente. No seu código você os lê via ENV['VAR'] , e pode passá-los logo antes do comando rake , como

$ VAR=foo rake mytask

Se você não pode se incomodar em lembrar qual posição de argumento é para o que e você quer fazer algo como um hash de argumento de rubi. Você pode usar um argumento para passar uma string e depois regexar essa string em um hash de opções.

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

E na linha de comando você pega.

$ 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

Se você quiser passar argumentos nomeados (por exemplo, com OptionParser padrão) você poderia usar algo como isto:

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

observe o -- , isso é necessário para ignorar os argumentos padrão do Rake. Deve funcionar com o Rake 0.9.x , <= 10.3.x.

O novo Rake mudou sua análise de -- , e agora você precisa garantir que ele não seja passado para o método OptionParser#parse , por exemplo, com 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 no final garantirá que os argumentos extras não sejam interpretados como tarefa Rake.

Além disso, o atalho para argumentos deve funcionar:

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

Quando os scripts do rake se parecem com isso, talvez seja hora de procurar por outra ferramenta que permita isso apenas fora da caixa.


opções e dependências precisam estar dentro de matrizes:

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

Então

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

NOTA: task variável é o objeto da tarefa, não é muito útil a menos que você saiba / se importe com os internos do Rake.

NOTA DOS TRILHOS:

Se executar a tarefa a partir de trilhos, é melhor pré-carregar o ambiente adicionando => [:environment] que é uma maneira de configurar tarefas dependentes .

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

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




command-line-arguments