Class: Cpflow::Cli

Inherits:
Thor
  • Object
show all
Defined in:
lib/cpflow.rb

Overview

rubocop:disable Metrics/ClassLength

Class Method Summary collapse

Methods inherited from Thor

basename

Class Method Details

.all_base_commandsObject



211
212
213
# File 'lib/cpflow.rb', line 211

def self.all_base_commands
  ::Command::Base.all_commands.merge(deprecated_commands)
end

.check_cpflow_versionObject

rubocop:disable Metrics/MethodLength



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/cpflow.rb', line 87

def self.check_cpflow_version # rubocop:disable Metrics/MethodLength
  return if @checked_cpflow_version

  @checked_cpflow_version = true

  result = ::Shell.cmd("gem", "search", "^cpflow$", "--remote", capture_stderr: true)
  return unless result[:success]

  matches = result[:output].match(/cpflow \((.+)\)/)
  return unless matches

  version = Cpflow::VERSION
  latest_version = matches[1]
  return unless Gem::Version.new(version) < Gem::Version.new(latest_version)

  ::Shell.warn("You are not using the latest 'cpflow' version. Please update it with 'gem update cpflow'.")
  $stderr.puts
end

.check_cpln_versionObject

rubocop:disable Metrics/MethodLength



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

def self.check_cpln_version # rubocop:disable Metrics/MethodLength
  return if @checked_cpln_version

  @checked_cpln_version = true

  result = ::Shell.cmd("cpln", "--version", capture_stderr: true)
  if result[:success]
    data = JSON.parse(result[:output])

    version = data["npm"]
    min_version = Cpflow::MIN_CPLN_VERSION
    if Gem::Version.new(version) < Gem::Version.new(min_version)
      ::Shell.abort("Current 'cpln' version: #{version}. Minimum supported version: #{min_version}. " \
                    "Please update it with 'npm update -g @controlplane/cli'.")
    end
  else
    ::Shell.abort("Can't find 'cpln' executable. Please install it with 'npm install -g @controlplane/cli'.")
  end
end

.deprecated_commandsObject



197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/cpflow.rb', line 197

def self.deprecated_commands
  @deprecated_commands ||= begin
    deprecated_commands_file_path = "#{__dir__}/deprecated_commands.json"
    deprecated_commands_data = File.binread(deprecated_commands_file_path)
    deprecated_commands = JSON.parse(deprecated_commands_data)
    deprecated_commands.to_h do |old_command_name, new_command_name|
      file_name = new_command_name.gsub(/[^A-Za-z]/, "_")
      class_name = file_name.split("_").map(&:capitalize).join

      [old_command_name, Object.const_get("::Command::#{class_name}")]
    end
  end
end

.exit_on_failure?Boolean

Needed to silence deprecation warning

Returns:

  • (Boolean)


186
187
188
# File 'lib/cpflow.rb', line 186

def self.exit_on_failure?
  true
end

.fix_help_optionObject

This is so that we’re able to run ‘cpflow COMMAND –help` to print the help (it basically changes it to `cpflow –help COMMAND`, which Thor recognizes) Based on stackoverflow.com/questions/49042591/how-to-add-help-h-flag-to-thor-command



109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/cpflow.rb', line 109

def self.fix_help_option
  help_mappings = Thor::HELP_MAPPINGS + ["help"]
  matches = help_mappings & ARGV

  # Help option works correctly for subcommands
  return if matches && subcommand?

  matches.each do |match|
    ARGV.delete(match)
    ARGV.unshift(match)
  end
end

.is_thor_reserved_word?(word, type) ⇒ Boolean

Needed to be able to use “run” as a command

Returns:

  • (Boolean)


191
192
193
194
195
# File 'lib/cpflow.rb', line 191

def self.is_thor_reserved_word?(word, type) # rubocop:disable Naming/PredicatePrefix
  return false if word == "run"

  super
end

.process_option_params(params) ⇒ Object



219
220
221
222
223
224
225
# File 'lib/cpflow.rb', line 219

def self.process_option_params(params)
  # Ensures that if no value is provided for a non-boolean option (e.g., `cpflow command --option`),
  # it defaults to an empty string instead of the option name (which is the default Thor behavior)
  params[:lazy_default] ||= "" if params[:type] != :boolean

  params
end

.show_info_header(config) ⇒ Object

rubocop:disable Metrics/MethodLength



356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
# File 'lib/cpflow.rb', line 356

def self.show_info_header(config) # rubocop:disable Metrics/MethodLength
  return if @showed_info_header

  rows = {}
  rows["ORG"] = config.org || "NOT PROVIDED!"
  rows["ORG"] += " (comes from CPLN_ORG env var)" if config.org_comes_from_env
  rows["APP"] = config.app || "NOT PROVIDED!"
  rows["APP"] += " (comes from CPLN_APP env var)" if config.app_comes_from_env

  rows.each do |key, value|
    puts "#{key}: #{value}"
  end

  @showed_info_header = true

  # Add a newline after the info header
  puts
end

.start(*args) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/cpflow.rb', line 52

def self.start(*args)
  ENV["CPLN_SKIP_UPDATE_CHECK"] = "true"
  ENV["NODE_NO_WARNINGS"] = "1"

  fix_help_option
  # Thor's `start(args = ARGV.dup, ...)` accepts an explicit argv as the first
  # positional argument. Use that when present so the startup-check decision matches
  # the command Thor is about to dispatch (and so test invocations don't pick up
  # rspec's ARGV by accident).
  argv = args.first.is_a?(Array) ? args.first : ARGV
  run_startup_checks if requires_startup_checks?(argv)

  super
end

.subcommand_namesObject



215
216
217
# File 'lib/cpflow.rb', line 215

def self.subcommand_names
  Dir["#{__dir__}/command/*"].filter_map { |name| File.basename(name) if File.directory?(name) }
end

.validate_options!(options) ⇒ Object

rubocop:disable Metrics/MethodLength



336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
# File 'lib/cpflow.rb', line 336

def self.validate_options!(options) # rubocop:disable Metrics/MethodLength
  options.each do |name, value|
    normalized_name = ::Helpers.normalize_option_name(name)
    raise "No value provided for option #{normalized_name}." if value.to_s.strip.empty?

    option = ::Command::Base.all_options.find { |current_option| current_option[:name].to_s == name }
    if option[:new_name]
      normalized_new_name = ::Helpers.normalize_option_name(option[:new_name])
      ::Shell.warn_deprecated("Option #{normalized_name} is deprecated, " \
                              "please use #{normalized_new_name} instead.")
      $stderr.puts
    end

    params = option[:params]
    next unless params[:valid_regex]

    raise "Invalid value provided for option #{normalized_name}." unless value.match?(params[:valid_regex])
  end
end