Module: RspecStarter

Defined in:
lib/rspec_starter.rb,
lib/rspec_starter/help.rb,
lib/rspec_starter/option.rb,
lib/rspec_starter/runner.rb,
lib/rspec_starter/command.rb,
lib/rspec_starter/helpers.rb,
lib/rspec_starter/options.rb,
lib/rspec_starter/version.rb,
lib/rspec_starter/environment.rb,
lib/rspec_starter/step_context.rb,
lib/rspec_starter/step_options.rb,
lib/rspec_starter/task_context.rb,
lib/rspec_starter/helpers/which.rb,
lib/rspec_starter/command_context.rb,
lib/rspec_starter/errors/step_error.rb,
lib/rspec_starter/errors/step_stopper.rb

Overview

A helper method for figuring out if a command exists on the file system.

Defined Under Namespace

Classes: Command, CommandContext, Environment, Helpers, Option, Options, Runner, StepContext, StepError, StepOptions, StepStopper, TaskContext

Constant Summary collapse

VERSION =
"3.0.0".freeze

Class Method Summary collapse

Class Method Details

.helpersObject



3
4
5
# File 'lib/rspec_starter/helpers.rb', line 3

def self.helpers
  @helpers ||= Helpers.new
end

.should_show_help?Boolean

Returns:

  • (Boolean)


3
4
5
# File 'lib/rspec_starter/help.rb', line 3

def self.should_show_help?
  ARGV.any? { |option| option.include?("--help") || option.include?("-h") }
end

.show_helpObject



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/rspec_starter/help.rb', line 7

def self.show_help
  # Figure out the file name that invoked the rspec_starter helper and treat it as the name of the
  # script.  We install a bin/rspec_starter file, but the user could call it anything.
  script_name = helpers.starter_script_file_name
  colored_script_name = script_name.colorize(:light_blue)

  write_help_usage_section(script_name, colored_script_name)
  write_help_command_line_options_section(colored_script_name)
  write_help_examples_section(colored_script_name)
  write_available_tasks
  write_task_info(colored_script_name)

  puts ""

  exit(0)
end

.show_missing_start_block_error_and_exitObject



74
75
76
77
78
79
80
81
82
83
# File 'lib/rspec_starter.rb', line 74

def self.show_missing_start_block_error_and_exit
  msg = "Error: RspecStarter.start was called without a block. It should be called like this: \n\n" \
        "       RspecStarter.start do\n" \
        "         command \"echo 'something'\"\n" \
        "         task :some_task_name\n" \
        "         #     ... more tasks and commands ...\n" \
        "       end".colorize(:red)
  puts msg
  exit 1
end

.start(&block) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/rspec_starter.rb', line 45

def self.start(&block)
  show_missing_start_block_error_and_exit unless block

  # Loads the information from the bin/start_rspec file and loads/parses the options. Provides info to the @runner.
  @environment = Environment.new(ARGV, &block)

  # Holds the step objects and executes them.
  @runner = Runner.new(@environment)

  # The bin/start_rspec file in the host application sets the APP_ROOT to the root folder of the host application.
  Dir.chdir APP_ROOT do
    # If we show help, exit and don't do anything else. We need to run the help in the context of the app root
    # so the help output can show file paths relative to where the user is running (and not relative to this gem).
    return show_help if should_show_help?

    begin
      @runner.run
    rescue StepError
      # The runner executes steps (which are tasks and commands). If a step reports a problem and the 'stop_on_problem' option
      # is set to 'true' (for a given step), the step will raise a StepError error. That is the signal that execution should
      # terminate immediately.
      exit(@runner.largest_exit_status)
    end

    # If we get here RSpec has been started and the rspec_starter's job is done.
    exit 0
  end
end

.which(cmd) ⇒ Object



3
4
5
6
7
8
9
10
11
12
# File 'lib/rspec_starter/helpers/which.rb', line 3

def self.which(cmd)
  exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
  ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
    exts.each do |ext|
      exe = File.join(path, "#{cmd}#{ext}")
      return exe if File.executable?(exe) && !File.directory?(exe)
    end
  end
  false
end

.write_available_tasksObject



54
55
56
57
58
59
60
61
62
# File 'lib/rspec_starter/help.rb', line 54

def self.write_available_tasks
  subclasses = ObjectSpace.each_object(Class).select { |klass| klass < RspecStarterTask }.sort_by(&:name)

  puts "\nAvailable Tasks:"
  subclasses.each do |klass|
    task_name = RspecStarterTask.name_for_class(klass).to_s
    puts "       #{task_name.colorize(:light_blue)} - #{klass.description}"
  end
end

.write_help_command_line_options_section(colored_script_name) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/rspec_starter/help.rb', line 29

def self.write_help_command_line_options_section(colored_script_name)
  puts "\nCommand Line Options: (run #{'rspec --help'.colorize(:light_blue)} to see RSpec's options)"
  puts "       This list is computed dynamically based on the tasks that are enabled in the #{colored_script_name} file."

  max_length = @environment.options.all_task_switches.max_by(&:length).size

  @environment.options.all_task_options.each do |option|
    next unless option.switch

    length = option.switch.length
    padding = max_length - length + 5 # 5 is the number of spaces past the longest swtich to start the description column
    puts "       #{option.switch.colorize(:light_blue)}#{' ' * padding}#{option.switch_description}"
  end
end

.write_help_examples_section(colored_script_name) ⇒ Object



44
45
46
47
48
49
50
51
52
# File 'lib/rspec_starter/help.rb', line 44

def self.write_help_examples_section(colored_script_name)
  puts "\nExamples:"
  puts "       #{colored_script_name} #{'spec/features'.colorize(:light_blue)} (only run specs in the specs/features folder)"
  # rubocop:disable Layout/LineLength
  puts "       #{colored_script_name} #{'spec/features/some_spec:53'.colorize(:light_blue)} (run the spec on line 53 of the spec/features_some_spec.rb file)"
  puts "       #{colored_script_name} #{'--skip-display-server'.colorize(:light_blue)} #{'spec/requests/some_spec'.colorize(:light_blue)} (don't start XVFB since it's not needed for request specs)"
  # rubocop:enable Layout/LineLength
  puts "       #{'SIMPLECOV_FORMATTER=rcov'.colorize(:light_blue)} #{colored_script_name} (use with environment variables)\n"
end

.write_help_usage_section(script_name, colored_script_name) ⇒ Object



24
25
26
27
# File 'lib/rspec_starter/help.rb', line 24

def self.write_help_usage_section(script_name, colored_script_name)
  puts "Usage: #{colored_script_name} #{'[options] [options for RSpec]'.colorize(:light_blue)}\n"
  puts "       #{script_name} will look for its own options first then pass any remaining options to RSpec."
end

.write_task_info(colored_script_name) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/rspec_starter/help.rb', line 64

def self.write_task_info(colored_script_name)
  write_task_info_header(colored_script_name)

  sorted_task_options = @environment.options.registered_task_options.sort_by do |klass, _options|
    RspecStarterTask.name_for_class(klass)
  end

  sorted_task_options.to_h.each do |klass, options|
    dsl_options = options.select(&:is_dsl_option?).sort_by(&:name)
    next if dsl_options.empty?

    puts "       :#{RspecStarterTask.name_for_class(klass).to_s.colorize(:light_blue)}"
    dsl_options.each do |option|
      puts "          #{option.name.colorize(:light_blue)} (#{option.description})"
    end
  end
end

.write_task_info_header(colored_script_name) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
# File 'lib/rspec_starter/help.rb', line 82

def self.write_task_info_header(colored_script_name)
  puts "\nTask Options:"
  puts "       These options can be used inside the #{colored_script_name} file on #{'task'.colorize(:light_blue)} lines."
  puts "       This list is computed dynamically based on the tasks that are enabled in the #{colored_script_name} file."
  puts "       Every task accepts the following options:"
  # rubocop:disable Layout/LineLength
  puts "          #{'quiet'.colorize(:light_blue)} (true/false - Tell the task to be verbose. Some tasks may disregard at times.)"
  puts "          #{'stop_on_problem'.colorize(:light_blue)} (true/false - Tell the task to stop startup if it encounters a problem.)"
  # rubocop:enable Layout/LineLength
  puts ""
end