是否可以进行交互式Rake任务?

时间:2011-03-25 02:14:27

标签: rake

我想运行一个Rake任务,要求用户输入。

我知道我可以在命令行上提供输入,但是我想询问用户是否确定他们想要继续执行特定操作,以防他们错误输入其中一个值到Rake任务。

4 个答案:

答案 0 :(得分:78)

这样的事情可能会起作用

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

How to run Rake tasks from within Rake tasks?

重新启用和调用任务

答案 1 :(得分:5)

用户输入的一个便利功能是将其置于do..while循环中,仅在用户提供有效输入时才继续。 Ruby没有明确地拥有这个构造,但是你可以用beginuntil来实现相同的功能。这将增加接受的答案如下:

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

答案 2 :(得分:4)

这是一个不使用其他任务的示例。

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

答案 3 :(得分:0)

您还可以将其包装在服务类中,以便可以对其进行单元测试并在您的所有rake任务中使用:

# 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

然后像在任务中那样使用它:

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!