2009-11-06 6 views
18

Je suis nouveau sur Rake et je l'utilise pour construire des projets .net. Ce qui m'intéresse est d'avoir une tâche récapitulative qui imprime un résumé de ce qui a été fait. Je veux que cette tâche soit toujours appelée, peu importe les tâches auxquelles rake a été invoqué.Comment exécuter une tâche Rake Task après toutes les autres tâches? (c'est-à-dire une tâche Rake AfterBuild)

Existe-t-il un moyen facile d'accomplir ceci?

Merci


mise à jour sur la question, en réponse à Patrick's answer ce que je veux est l'après tâche à exécuter une fois après toutes les autres tâches, de sorte que la sortie que je veux est:

task :test1 do 
    puts 'test1' 
end 

task :test2 do 
    puts 'test2' 
end 

Rake::Task.tasks.each do |t| 
    <Insert rake magic here> 
# t.enhance do 
# puts 'after' 
# end 
end 

$ rake test1 
test1 
after 

$rake test2 
test2 
after 

$rake test1 test2 
test1 
test2 
after 

et si

task :test3 =>[:test1, :test2] 
    puts 'test3' 
end 

    $rake test3 
test1 
test2 
test3 
after 

Même si la générosité a disparu, toute aide supplémentaire très appréciée. (Sadily Je ne pense pas que je peux offrir une autre prime.)

Répondre

10

Publier cela comme nouvelle réponse pour garder l'autre disponible. C'est beaucoup moins élégant car je dois entrer dans les tripes de Rake et mettre à jour manuellement la liste des tâches, mais cela fonctionne.

task :test1 do 
    puts 'test1' 
end 

task :test2 do 
    puts 'test2' 
end 

task :after do 
    puts 'after' 
end 

# top_level_tasks is't writable so we need to do this ugly 
# instance_variable_set hack... 
current_tasks = Rake.application.top_level_tasks 
current_tasks << :after 
Rake.application.instance_variable_set(:@top_level_tasks, current_tasks) 

Sorties:

$ rake test1 
test1 
after 

$ rake test1 test2 
test1 
test2 
after 
+0

GREAT! C'est exactement ce que je veux. J'aimerais savoir ce qu'est la magie ici. Pouvez-vous me donner plus d'explications sur ce qui se passe? En attendant, je verrai ce que je peux trouver sur google. – Chasler

+0

OK. Je comprends ce qui se passe. Bon travail. Merci. – Chasler

+2

Bien sûr. En aparté, je suis à une conférence et j'ai retrouvé Jim Weirich (l'auteur de rake) pour voir si c'était la meilleure façon de résoudre le problème. Sa réponse a été que Rake n'a pas de façon intégrée de le faire, mais il est ouvert à un correctif si quelqu'un peut trouver une méthode généralisée pour le faire. Donc le code: L'application Rake a un lecteur pour garder une trace des tâches à exécuter appelées 'top_level_tasks'. Parce qu'il est en lecture seule, nous devons le lire, le mettre à jour, puis utiliser instance_variable_set pour repasser le changement dans l'application. Si c'était écrit, nous pourrions le faire en une seule ligne. –

1

Je ne sais pas si c'est la meilleure façon, mais il est le plus simple:

faire tous vos Résumé « tâches publiques » ceux qui appellent réel les tâches.

task :compile => :realcompile do 
    summary stuff 
end 
35

Vous devriez être en mesure de le faire avec 'améliorer':

Rake::Task["my_task"].enhance do 
    Rake::Task["my_after_task"].invoke 
end 

Cela entraînera 'my_after_task' à être invoquée après 'my_task'.

Si vous voulez appliquer à toutes les tâches, juste boucle sur toutes les tâches et appeler améliorer pour chaque:

Rake::Task.tasks.each do |t| 
    t.enhance do 
    Rake::Task["my_after_task"].invoke 
    end 
end 

fichier Test complet:

task :test1 do 
    puts 'test1' 
end 

task :test2 do 
    puts 'test2' 
end 

Rake::Task.tasks.each do |t| 
    t.enhance do 
    puts 'after' 
    end 
end 

Et la sortie:

$ rake test1 
test1 
after 

$ rake test2 
test2 
after 
+0

Merci. J'ai peur de ne pas avoir clairement posé ma question. Je souhaite que la tâche après s'exécute une fois, une fois que les autres tâches sont terminées. donc: test1 râteau $ test2 génèrerait test1 test2 après test1 râteau de $ test1 après $ rake test2 test2 après Toute idée comment y arriver? – Chasler

+0

Ah ok, j'ai trouvé une solution pour vous. Moins élégant mais ça marche. Si vous êtes intéressé, je peux expliquer en détail ce que je fais pour que cela fonctionne ... –

4

Outre le laid Rake.application.instance_variable_set, vous pouvez améliorer la dernière tâche sur la ligne de commande comme ceci:

last_task = Rake.application.top_level_tasks.last 
    Rake::Task[last_task].enhance do 
    puts 'after' 
    end 

Cela devrait faire exactement ce dont vous avez besoin faire!

+0

Vous avez une 'fin' à la fin qui ne devrait pas être là, je suppose. –

+0

Merci, Konstantin! Je l'ai corrigé. – awendt

+0

Intéressant. La solution acceptée ci-dessous fonctionne, et je n'ai pas eu à modifier le script depuis des lustres, mais la prochaine fois que je le ferai, je regarderai en utilisant cette méthode. C'est définitivement plus élégant. – Chasler

4

Vous pouvez utiliser l'appel Kernel.trap et le joindre au signal "Exit". Il tirera sur la sortie normale et anormale.

Mettre cela au début de votre rakefile:

Kernel.trap("EXIT") do 
    Rake::Task[:final].invoke 
end 

Maintenant, chaque fois que vous faire une tâche « finale » il sera exécuté à la fin du programme. peu importe ce que.

task :final do 
    puts "Hit return to continue..." 
    STDIN.getc 
end 
+0

Cool. Merci. Je vais essayer la prochaine fois que j'en ai besoin. – Chasler

10

cette réponse simple trouvé élégante here qui utilise la méthode Ruby at_exit.

Il est à noter que la méthode définie après at_exit s'exécutera chaque fois que le script rake est appelé quelle que soit l'exécution de la tâche, ou si une tâche est exécutée. Cela inclut lors de l'exécution rake -T (pour répertorier les tâches disponibles). Assurez-vous que at_exit ne fait rien si une tâche précédente lui a dit de le faire.

rakefile.rb

desc "Lovely task a" 
task :a do 
    puts "a" 
end 

desc "Lovely task b" 
task :b do 
    puts "b" 
end 

task :cleanup do 
    puts "cleanup" 
end 

at_exit { Rake::Task[:cleanup].invoke if $!.nil? } 

shell

$ rake a b 
a 
b 
cleanup 
$ rake -T 
rake a # Lovely task a 
rake b # Lovely task b 
cleanup 

Vous n'avez pas besoin de le faire exécuter une tâche si vous ne voulez pas.

at_exit do 
    puts "cleanup" 
end 

Ou faire exécuter une méthode

def on_exit_do_cleanup 
    puts "cleanup" 
end 

at_exit { on_exit_do_cleanup } 

Et vous voudrez peut-être vous assurer que vous faites seulement le nettoyage si une tâche a été exécutée en fait de sorte que rake -T ne sera pas aussi faire un nettoyage.

rakefile.rb

do_cleanup = false 

desc "Lovely task a" 
task :a do 
    puts "a" 
    do_cleanup = true 
end 

desc "Lovely task b" 
task :b do 
    puts "b" 
    do_cleanup = true 
end 

task :cleanup do 
    return unless $!.nil? # No cleanup on error 
    return unless do_cleanup # No cleanup if flag is false 
    puts "cleanup" 
end 

at_exit { Rake::Task[:cleanup].invoke } 
+0

qu'est ce que $ !. nil? dénote ..? –

+0

'$!' Contient la dernière erreur surélevée et 'x.nil?' Renvoie vrai si le 'x' est' nil' alors, '... si $ !. nil?' S'assure que la tâche de nettoyage ne s'exécute que si il n'y avait pas d'erreurs dans cette exécution du script. (Réponse éditée pour clarification) – Nate

0

Si quelqu'un est venu ici pour trouver la façon d'exécuter une tâche avant toutes les autres tâches (par exemple, une tâche de chargement env spécial), vous pouvez toujours utiliser la même améliorer la méthode, sauf que le premier argument:

task :environment do 
    env = (ENV['RACK_ENV'] || 'production').downcase 
    # do things before other tasks 
end 

# run environment task before all tasks for setup 
Rake::Task.tasks.each do |t| 
    next if t.name == 'environment' 
    t.enhance [:environment] 
end 
Questions connexes