Is it possible to make an interactive Rake task?

后端 未结 4 1547
盖世英雄少女心
盖世英雄少女心 2021-01-31 14:21

I want to run a Rake task that asks the user for input.

I know that I can supply input on the command line, but I want to ask the user if they are sure they wa

相关标签:
4条回答
  • 2021-01-31 14:54

    A handy feature for user input is to put it in a do..while loop, to only continue when a user has supplied valid input. Ruby doesn't explicitly have this construct, but you can achieve the same thing with begin and until. That would add to the accepted answer as follows:

    task :action do
      STDOUT.puts "I'm acting!"
    end
    
    task :check do
      # Loop until the user supplies a valid option
      begin
        STDOUT.puts "Are you sure? (y/n)"
        input = STDIN.gets.strip.downcase
      end until %w(y n).include?(input)
    
      if input == 'y'
        Rake::Task["action"].reenable
        Rake::Task["action"].invoke
      else
        # We know at this point that they've explicitly said no, 
        # rather than fumble the keyboard
        STDOUT.puts "So sorry for the confusion"
      end
    end
    
    0 讨论(0)
  • 2021-01-31 14:58

    You could also wrap this up in a service class so it can be unit-tested and used across your rake tasks:

    # frozen_string_literal: true
    
    class RakeConfirmDialog
      def initialize(question)
        @question = "#{question} (y/n)"
        @answer = "".inquiry
      end
    
      def confirm!
        prompt until (proceed? || abort?)
    
        respond
    
        proceed?
      end
    
      private
    
      def prompt
        STDOUT.puts @question
    
        @answer = STDIN.gets.strip.downcase.inquiry
      end
    
      def respond
        STDOUT.puts proceed? ? "Proceeding." : "Aborting."
      end
    
      def proceed?
        @answer.y?
      end
    
      def abort?
        @answer.n?
      end
    end
    

    Then use it like so in your task:

    next unless RakeConfirmDialog.new(
      "About to close the Hellmouth forever. Are you sure you want 'Buffy the Vampire Slayer' to have a happy ending?"
    ).confirm!
    
    0 讨论(0)
  • 2021-01-31 15:05

    Here's an example without using another task.

    task :solve_earth_problems => :environment do    
      STDOUT.puts "This is risky. Are you sure? (y/n)"
    
      begin
        input = STDIN.gets.strip.downcase
      end until %w(y n).include?(input)
    
      if input != 'y'
        STDOUT.puts "So sorry for the confusion"
        return
      end
    
      # user accepted, carry on
      Humanity.wipe_out!
    end
    
    0 讨论(0)
  • 2021-01-31 15:14

    Something like this might work

    task :action do
      STDOUT.puts "I'm acting!"
    end
    
    task :check do
      STDOUT.puts "Are you sure? (y/n)"
      input = STDIN.gets.strip
      if input == 'y'
        Rake::Task["action"].reenable
        Rake::Task["action"].invoke
      else
        STDOUT.puts "So sorry for the confusion"
      end
    end
    

    Task reenabling and invoking from How to run Rake tasks from within Rake tasks?

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