| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- module FontStylePatch
- RESET_COLOR = "\e[0m" #重置所有颜色和样式
- COLORS = {
- black: "\e[30m", #黑色文本
- red: "\e[31m", #红色文本
- green: "\e[32m", #绿色文本
- yellow: "\e[33m", #黄色文本
- blue: "\e[34m", #蓝色文本
- carmine: "\e[35m", #洋红色文本
- cyan: "\e[36m", #青色文本
- white: "\e[37m" #白色文本
- }
- COLORS.keys.each do |color_name|
- define_method(color_name) do
- return "#{COLORS[color_name]}#{self}#{RESET_COLOR}"
- end
- end
- end
- module StringPatch
- def nature_case
- self.gsub(/(.)([A-Z])/, '\1 \2').downcase.capitalize
- end
- end
- class String
- include FontStylePatch
- include StringPatch
- end
- module RimeDeploy
- class RimeDeployError < StandardError
- end
- class ChooseSession
- def initialize(items)
- @items = items #[[intro, method]] auto index
- end
- def call
- message = nil
- choose = nil
- while true
- puts @title
- puts "Choose mode:"
- @items.each_with_index do |item, index|
- puts "[#{index + 1}] " + item[0]
- end
- puts "Tips: input the index. e.g: 1; Ctrl-C exit."
- puts "Message: #{message}".red if message
- print ">>".green
- choose_mode = gets
- choose_index = choose_mode.strip
- if choose_index =~ /\d+/ && choose_index.to_i <= @items.length
- choose = @items[choose_index.to_i - 1]
- break
- else
- message = "Wrong Index, try again."
- end
- end
- choose[1].call
- end
- end
- class Job
- attr_accessor :status, :intro
- def initialize
- @status = :waiting # :waiting, :processing, :done, :fail
- klass_name = self.class.to_s.split("::").last.sub(/Job$/, "")
- @intro = klass_name.nature_case
- end
- def call
- end
- def rollback
- end
- end
- class JobGroup
- @jobs = []
- @after_jobs = []
- @before_jobs = []
- def self.jobs
- @jobs
- end
- def self.jobs=(value)
- @jobs = value
- end
- def self.after_jobs
- @after_jobs
- end
- def self.after_jobs=(value)
- @after_jobs = value
- end
- def self.before_jobs
- @before_jobs
- end
- def self.before_jobs=(value)
- @before_jobs = value
- end
- def initialize()
- @title = "=== Rime Deploy ====".green
- @before_jobs = []
- if self.class.before_jobs
- self.class.before_jobs.each { |job| @before_jobs << job.new }
- end
- @queue = []
- self.class.jobs.each { |job| @queue << job.new } if self.class.jobs.each
- @after_jobs = []
- self.class.after_jobs.each { |job| @after_jobs << job.new }
- @current_index = 0
- end
- def print_progress
- system("clear")
- puts @title
- @queue.each_with_index do |job, index|
- job_id = "[%02d]" % (index + 1)
- job_intro = job.intro.to_s.ljust(20).green
- job_status = job.status
- case job_status
- when :waiting
- job_status = job_status.to_s.white
- when :processing
- job_status = job_status.to_s.yellow
- when :done
- job_status = job_status.to_s.green
- end
- job_status = job_status.rjust(15)
- puts "#{job_id} #{job_intro}\t#{job_status}"
- end
- if @current_index < @queue.length
- puts "Total: #{@queue.length}".ljust(10)
- puts "Detail " + "-" * 20
- end
- end
- def run_job_with_info_wrapper(current_job)
- print_progress
- begin
- result = current_job.call
- if result == :next
- current_job.status = :done
- @current_index += 1
- else
- # 失败处理
- current_job.rollback if current_job.respond_to? :rollback
- raise RimeDeployError
- end
- print_progress
- rescue RimeDeployError
- what_next
- end
- end
- def guidance
- puts @title
- puts "welcome to use Rime installer."
- ChooseSession.new(
- [
- [
- "Auto mode: Suitable for first-time operation.",
- -> { run_jobs_auto }
- ],
- [
- "Handle mode: Decide to execute on your own.",
- -> { run_jobs_handle }
- ]
- ]
- ).call
- end
- def run_jobs_handle
- halt_flag =
- catch :halt do
- system("clear")
- puts "[Handle Mode]".yellow
- handle_jobs = []
- @queue.each_with_index do |job, index|
- job_intro = job.intro.to_s.ljust(20).green
- handle_jobs.push(
- ["#{job_intro}", -> { run_job_with_info_wrapper(job) }]
- )
- end
- begin
- ChooseSession.new(handle_jobs).call
- rescue RimeDeployError
- what_next
- end
- end
- run_jobs_handle if halt_flag == :handle_mode
- end
- def run_jobs_auto
- system("clear")
- puts "[Auto Mode]".green
- print_progress
- halt_flag =
- catch :halt do
- while @current_index < @queue.length
- current_job = @queue[@current_index]
- current_job.status = :processing
- print_progress
- begin
- result = current_job.call
- if result == :next
- current_job.status = :done
- @current_index += 1
- else
- # 失败处理
- raise RimeDeployError
- end
- print_progress
- rescue RimeDeployError
- what_next
- end
- end
- end
- run_jobs_handle if halt_flag == :handle_mode
- end
- def reset_status
- @queue.each { |q| q.status = :waiting }
- end
- def what_next
- puts ""
- puts "Raise an error. Next, you want to...".red
- ChooseSession.new(
- [
- ["Retry", -> {}],
- ["Change to: Handle mode", -> { throw :halt, :handle_mode }],
- ["Exit", -> { exit 0 }]
- ]
- ).call
- end
- def call
- @before_jobs.length > 0 && @before_jobs.each { |job| job.call }
- guidance
- @after_jobs.length > 0 && @after_jobs.each { |job| job.call }
- end
- end
- end
|