Class: Shoes::UI::Picker

Inherits:
Object
  • Object
show all
Defined in:
shoes-core/lib/shoes/ui/picker.rb

Instance Method Summary collapse

Constructor Details

#initialize(input = STDIN, output = STDOUT) ⇒ Picker

Returns a new instance of Picker


20
21
22
23
# File 'shoes-core/lib/shoes/ui/picker.rb', line 20

def initialize(input = STDIN, output = STDOUT)
  @input  = input
  @output = output
end

Instance Method Details

#bundleObject

Only bundle if we find a local Gemfile. This allows us to work properly running from source without finding gem-installed backends.


36
37
38
39
40
41
42
43
# File 'shoes-core/lib/shoes/ui/picker.rb', line 36

def bundle
  return unless File.exist?("Gemfile")

  # Only need bundler/setup to get our paths right--we don't need to
  # actually require the gems, since we find the generate_backend.rb's
  # and just require them directly.
  require 'bundler/setup'
end

#find_candidates(desired_backend) ⇒ Object


61
62
63
64
65
# File 'shoes-core/lib/shoes/ui/picker.rb', line 61

def find_candidates(desired_backend)
  search_string = "shoes/**/#{desired_backend}/generate_backend.rb"
  search_string = search_string.gsub("//", "/")
  Gem.find_files(search_string)
end

#name_for_candidate(candidate) ⇒ Object


93
94
95
96
# File 'shoes-core/lib/shoes/ui/picker.rb', line 93

def name_for_candidate(candidate)
  match = %r{.*lib\/shoes\/(.*)\/generate_backend.rb}.match(candidate)[1]
  "shoes-#{match.tr('/', '-')}"
end

#output_candidates(candidates) ⇒ Object


67
68
69
70
71
72
73
74
75
76
# File 'shoes-core/lib/shoes/ui/picker.rb', line 67

def output_candidates(candidates)
  @output.puts
  @output.puts "Enter a number to select a Shoes backend (This is a one-time operation):"

  candidates.each_with_index do |candidate, index|
    @output.puts " #{index + 1}. #{name_for_candidate(candidate)}"
  end

  @output.print "> "
end

#prompt_for_candidate(candidates) ⇒ Object


78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'shoes-core/lib/shoes/ui/picker.rb', line 78

def prompt_for_candidate(candidates)
  candidate = nil

  until candidate
    entered_index = @input.readline.to_i
    if entered_index.positive?
      candidate = candidates[entered_index - 1]
      break if candidate
    end
    @output.puts "Invalid selection. Try again with a number from 1 to #{candidates.size}."
  end

  candidate
end

#require_generator(desired_backend) ⇒ Object


98
99
100
101
# File 'shoes-core/lib/shoes/ui/picker.rb', line 98

def require_generator(desired_backend)
  generator_file = select_generator(desired_backend)
  require generator_file
end

#run(bin_dir, desired_backend = nil) ⇒ Object


25
26
27
28
29
30
31
32
# File 'shoes-core/lib/shoes/ui/picker.rb', line 25

def run(bin_dir, desired_backend = nil)
  bundle

  require_generator(desired_backend)
  validate_generator

  write_backend(bin_dir)
end

#select_generator(desired_backend = nil) ⇒ Object

Raises:

  • (ArgumentError)

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'shoes-core/lib/shoes/ui/picker.rb', line 45

def select_generator(desired_backend = nil)
  candidates = find_candidates(desired_backend)

  raise ArgumentError, "No gems found matching '#{desired_backend}'" if candidates.empty?

  if candidates.one?
    candidate = candidates.first
    @output.puts "Selecting #{name_for_candidate(candidate)} backend to use. This is a one-time operation."
    candidate
  else
    candidates.sort!
    output_candidates(candidates)
    prompt_for_candidate(candidates)
  end
end

#validate_generatorObject


103
104
105
# File 'shoes-core/lib/shoes/ui/picker.rb', line 103

def validate_generator
  Shoes::SelectedBackend.validate
end

#write_backend(bin_dir) ⇒ Object


107
108
109
110
111
112
# File 'shoes-core/lib/shoes/ui/picker.rb', line 107

def write_backend(bin_dir)
  File.open(File.expand_path(File.join(bin_dir, "shoes-backend")), "w") do |file|
    dest_dir = ENV["SHOES_PICKER_BIN_DIR"] || bin_dir
    file.write(Shoes::SelectedBackend.generate(dest_dir))
  end
end