How do I make a Rake Task run after all other tasks? (i.e. a Rake AfterBuild task)

前端 未结 7 977
感动是毒
感动是毒 2021-02-02 12:39

I\'m new to Rake and using it to build .net projects. What I\'m interested in is having a Summary task that prints out a summary of what has been done. I want this task to alw

相关标签:
7条回答
  • 2021-02-02 13:17

    Posting this as a new answer to keep the other one available. This is much less elegant as I have to get into the guts of Rake and manually update the task list, but it works.

    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)
    

    Outputs:

    $ rake test1
    test1
    after
    
    $ rake test1 test2
    test1
    test2
    after
    
    0 讨论(0)
  • 2021-02-02 13:19

    You could use the Kernel.trap call and attach to the "Exit" signal. It will fire upon both normal and abnormal exit.

    Put this early in your rakefile:

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

    Now any time you make a "final" task it will be executed at the very end of the program. no matter what.

    task :final do
      puts "Hit return to continue..."
      STDIN.getc
    end
    
    0 讨论(0)
  • 2021-02-02 13:20

    Found this simple elegant answer here that uses the Ruby method at_exit.

    It's worth noting that the method defined after at_exit will run every time the rake script is invoked regardless of the task run, or if any task is run. This includes when running rake -T (to list available tasks). Make sure that at_exit only does anything if a previous task told it to do so.

    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
    

    You also don't need to make it run a task if you don't want to.

    at_exit do
      puts "cleanup"
    end
    

    Or make it run an method

    def on_exit_do_cleanup
      puts "cleanup"
    end
    
    at_exit { on_exit_do_cleanup }
    

    And you may want to make sure you only do the cleanup if a task actually ran so that rake -T won't also do a cleanup.

    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 讨论(0)
  • 2021-02-02 13:20

    If anyone came here looking for how to run a task before all other tasks (eg, a special env loading task), you can still use the same enhance method, except only the first arguement:

    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
    
    0 讨论(0)
  • 2021-02-02 13:22

    You should be able to do this with 'enhance':

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

    This will cause 'my_after_task' to be invoked after 'my_task'.

    If you want to apply this to all tasks, just loop over all the tasks and call enhance for each:

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

    Full test file:

    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
    

    And the output:

    $ rake test1
    test1
    after
    
    $ rake test2
    test2
    after
    
    0 讨论(0)
  • 2021-02-02 13:22

    Apart from the ugly Rake.application.instance_variable_set, you can enhance the last task on the command-line like so:

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

    That should do exactly what you need to do!

    0 讨论(0)
提交回复
热议问题