1216 Stimmen

Übergabe von Kommandozeilenargumenten an einen Rake-Task

Ich habe eine Rake-Aufgabe, die einen Wert in mehrere Datenbanken einfügen muss.

Ich möchte diesen Wert an die Rake-Aufgabe von der Kommandozeile aus übergeben, oder von eine andere Rake-Aufgabe.

Wie kann ich das tun?

3voto

hexinpeter Punkte 1350

Die meisten der oben beschriebenen Methoden haben bei mir nicht funktioniert, vielleicht sind sie in den neueren Versionen veraltet. Der aktuelle Leitfaden ist hier zu finden: http://guides.rubyonrails.org/command_line.html#custom-rake-tasks

eine Kopie des Leitfadens finden Sie hier:

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

Rufen Sie es wie folgt auf

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

3voto

Abdo Punkte 12769

Ich mag die "querystring"-Syntax für die Übergabe von Argumenten, vor allem, wenn es viele Argumente zu übergeben sind.

Exemple :

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

Der "Querystring" ist:

width=10&height=20

Warnung: Beachten Sie, dass die Syntax lautet rake "mytask[foo=bar]" y NICHT rake mytask["foo=bar"]

Beim Parsen innerhalb der Rake-Aufgabe mit Rack::Utils.parse_nested_query erhalten wir eine Hash :

=> {"width"=>"10", "height"=>"20"}

(Der Clou ist, dass man Hashes und Arrays übergeben kann, mehr dazu weiter unten)

So können Sie dies erreichen:

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

Hier ist ein ausführlicheres Beispiel, das ich mit Rails in meinem 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]"

Parsed die gleiche Weise wie oben, mit einer Umgebung Abhängigkeit (um die Rails-Umgebung zu laden)

namespace :dj do
  task :start, [ :args_expr ] => :environment do |t, args|
    # defaults here...
    options = Rack::Utils.parse_nested_query(args[:args_expr])  
  end
end

Gibt das Folgende an options

=> {"ebooks"=>{"workers_number"=>"16", "worker_timeout"=>"60"}, "albums"=>{"workers_number"=>"32", "worker_timeout"=>"120"}}

3voto

Gal Punkte 4649

Um der Standardaufgabe Argumente zu übergeben, können Sie etwa so vorgehen. Zum Beispiel, sagen Sie "Version" ist Ihr Argument:

task :default, [:version] => [:build]

task :build, :version do |t,args|
  version = args[:version]
  puts version ? "version is #{version}" : "no version passed"
end

Dann können Sie es so nennen:

$ rake
no version passed

o

$ rake default[3.2.1]
version is 3.2.1

o

$ rake build[3.2.1]
version is 3.2.1

Ich habe jedoch keine Möglichkeit gefunden, bei der Übergabe von Argumenten die Angabe des Aufgabennamens (Standard oder Build) zu vermeiden. Ich würde mich freuen zu hören, wenn jemand einen Weg kennt.

3voto

xander-miller Punkte 509

Wenn Sie sich nicht die Mühe machen können, sich zu merken, welche Argumentposition für was steht, und Sie etwas wie einen Ruby-Argument-Hash verwenden möchten. Sie können ein Argument verwenden, um eine Zeichenkette zu übergeben und diese Zeichenkette dann mit einem Regex in einen Options-Hash umwandeln.

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

Und in der Befehlszeile erhalten Sie.

$ 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

-5voto

tundervirld Punkte 1

Bei der Übergabe von Parametern ist es besser, eine Eingabedatei zu verwenden, z. B. eine Excel- oder Json-Datei, und von dort die Datenstruktur und Variablen zu lesen, die Sie benötigen, einschließlich des Variablennamens, je nach Bedarf. Das Lesen einer Datei kann die folgende Struktur haben.

  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

Beispiel json

{
  "name_task": "I'm a task",
  "user_id": 389,
  "users_assigned": [389,672,524],
  "task_id": 3
}

Ausführung

rake :name_task

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X