Module: Hippo::Util

Defined in:
lib/hippo/util.rb

Class Method Summary collapse

Class Method Details

.action(message) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/hippo/util.rb', line 128

def action(message)
  $stdout.print message
  complete_state = 'done'
  color = '32'
  passed_proc = proc do |value|
    complete_state = value
    color = '33'
  end
  return_value = yield(passed_proc)
  puts " \e[#{color}m#{complete_state}\e[0m"
  return_value
rescue StandardError => e
  puts " \e[31merror\e[0m"
  raise
end

.ask(question, default: nil) ⇒ Object



112
113
114
115
116
117
# File 'lib/hippo/util.rb', line 112

def ask(question, default: nil)
  puts "\e[35m#{question}\e[0m" + (default ? " [#{default}]" : '')
  response = STDIN.gets
  response = response.to_s.strip
  response.empty? ? default : response
end

.confirm(question) ⇒ Object



85
86
87
88
89
90
91
92
93
# File 'lib/hippo/util.rb', line 85

def confirm(question)
  response = ask(question)
  if %w[yes y].include?(response.downcase)
    puts
    true
  else
    false
  end
end

.create_object_definitions(hash, stage, required_kinds: nil, clean: false) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/hippo/util.rb', line 42

def create_object_definitions(hash, stage, required_kinds: nil, clean: false)
  index = 0
  hash.each_with_object([]) do |(path, objects), array|
    objects.each_with_index do |object, inner_index|
      od = ObjectDefinition.new(object, stage, clean: clean)

      if od.name.nil?
        raise Error, "All object defintions must have a name. Missing metadata.name for object in #{path} at index #{inner_index}"
      end

      if od.kind.nil?
        raise Error, "All object definitions must have a kind defined. Check #{path} at index #{inner_index}"
      end

      if required_kinds && !required_kinds.include?(od.kind)
        raise Error, "Kind '#{od.kind}' cannot be defined in #{path} at index #{inner_index}. Only kinds #{required_kinds} are permitted."
      end

      array << od
      index += 1
    end
  end
end

.load_objects_from_path(path, decorator: nil) ⇒ Object



34
35
36
37
38
39
40
# File 'lib/hippo/util.rb', line 34

def load_objects_from_path(path, decorator: nil)
  files = Dir[path]
  files.each_with_object({}) do |path, objects|
    file = load_yaml_from_file(path, decorator: decorator)
    objects[path] = file
  end
end

.load_yaml_from_data(data, path: nil, decorator: nil) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/hippo/util.rb', line 18

def load_yaml_from_data(data, path: nil, decorator: nil)
  data = decorator.call(data) if decorator

  parts = data.split(/^\-\-\-\s*$/)
  parts.each_with_index.each_with_object([]) do |(p, i), array|
    begin
      yaml = YAML.safe_load(p)
      next unless yaml.is_a?(Hash)

      array << yaml
    rescue Psych::SyntaxError => e
      raise Error, e.message.sub('(<unknown>): ', "(#{path}[#{i}]): ")
    end
  end
end

.load_yaml_from_file(path, decorator: nil) ⇒ Object

Raises:



11
12
13
14
15
16
# File 'lib/hippo/util.rb', line 11

def load_yaml_from_file(path, decorator: nil)
  raise Error, "No file found at #{path} to load" unless File.file?(path)

  file = File.read(path)
  load_yaml_from_data(file, path: path, decorator: decorator)
end

.open_in_editor(name, contents) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/hippo/util.rb', line 66

def open_in_editor(name, contents)
  if ENV['EDITOR'].nil?
    raise Error, 'No EDITOR environment variable has been defined'
  end

  tmp_root = File.join(ENV['HOME'], '.hippo')
  FileUtils.mkdir_p(tmp_root)
  begin
    tmpfile = Tempfile.new([name, '.yaml'], tmp_root)
    tmpfile.write(contents)
    tmpfile.close
    Kernel.system("#{ENV['EDITOR']} #{tmpfile.path}")
    tmpfile.open
    tmpfile.read
  ensure
    tmpfile.unlink
  end
end

.parse_kubectl_apply_lines(stdout) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/hippo/util.rb', line 145

def self.parse_kubectl_apply_lines(stdout)
  stdout.split("\n").each_with_object({}) do |line, hash|
    if line =~ %r{\A([\w\/\-\.]+) (\w+)\z}
      object = Regexp.last_match(1)
      status = Regexp.last_match(2)
    elsif line =~ %r{\A[\w\.\/\-]+ \"([\w\-]+)\" (\w+)\z}
      object = Regexp.last_match(1)
      status = Regexp.last_match(2)
    else
      next
    end
    hash[object] = status

    color = '32'
    color = '31' if status == 'deleted'
    color = '33' if status == 'configured'

    status = "\e[#{color}m#{status}\e[0m" unless status == 'unchanged'
    puts "\e[37m====> #{object} #{status}\e[0m"
  end
end

.select(question, items) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/hippo/util.rb', line 95

def select(question, items)
  items.each_with_index do |item, index|
    puts "#{index + 1}) #{item}"
  end
  selected_item = nil

  until selected_item
    response = ask(question)
    selected_item = items[response.to_i - 1]
    if selected_item.nil?
      puts "\e[31mThat is not a valid option. Try again.\e[0m"
    end
  end

  selected_item
end

.system(command, stdin_data: nil) ⇒ Object



119
120
121
122
123
124
125
126
# File 'lib/hippo/util.rb', line 119

def system(command, stdin_data: nil)
  stdout, stderr, status = Open3.capture3(command, stdin_data: stdin_data)
  unless status.success?
    raise Error, "Command failed to execute: #{stderr}"
  end

  stdout
end