【问题标题】:Is it possible to make an interactive Rake task?是否可以进行交互式 Rake 任务?
【发布时间】:2011-07-22 14:53:07
【问题描述】:

我想运行一个请求用户输入的 Rake 任务。

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

【问题讨论】:

  • 查看Thor 来代替交互式任务。它比 Rake 优越得多,而且它带有 Rails,所以你已经拥有它而无需安装任何东西。
  • @meagar 今天刚遇到这个问题,我被卡住了,你有没有想过?我在带有 zsh 的 Mac 上。 . .
  • 刚刚想通了——它显然与 Rails zsh 插件有关。当我删除该插件时,重新启动 zsh,然后重新添加它,问题就消失了。 . .

标签: rake


【解决方案1】:

这样的事情可能会奏效

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?重新启用和调用任务

【讨论】:

  • 知道在输入“no”后按下回车键时此代码何时会显示“^M”吗??
【解决方案2】:

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

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】:

    用户输入的一个方便功能是将其放入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
    

    【讨论】:

      【解决方案4】:

      您也可以将其包装在一个服务类中,以便对其进行单元测试并在您的 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!
      

      【讨论】:

        猜你喜欢
        • 2011-08-22
        • 2017-06-03
        • 2012-08-23
        • 2011-04-16
        • 1970-01-01
        • 2019-05-23
        • 1970-01-01
        • 1970-01-01
        • 2012-06-26
        相关资源
        最近更新 更多