Class: TLDR::ArgvParser

Inherits:
Object
  • Object
show all
Defined in:
lib/tldr/argv_parser.rb

Constant Summary collapse

PATTERN_FRIENDLY_SPLITTER =
/,(?=(?:[^\/]*\/[^\/]*\/)*[^\/]*$)/

Instance Method Summary collapse

Instance Method Details

#parse(args, options = {cli_defaults: true}) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/tldr/argv_parser.rb', line 7

def parse args, options = {cli_defaults: true}
  og_args = args.dup
  OptionParser.new do |opts|
    opts.banner = "Usage: tldr [options] some_tests/**/*.rb some/path.rb:13 ..."

    opts.on "-t", "--[no-]timeout [TIMEOUT]", "Timeout (in seconds) before timer aborts the run (Default: #{Config::DEFAULT_TIMEOUT})" do |timeout|
      options[:timeout] = if timeout == false
        # --no-timeout
        -1
      elsif timeout.nil?
        # --timeout
        Config::DEFAULT_TIMEOUT
      else
        # --timeout 42.3
        handle_unparsable_optional_value(og_args, "timeout", timeout) do
          Float(timeout)
        end
      end
    end

    opts.on CONFLAGS[:watch], "Run your tests continuously on file save (requires 'fswatch' to be installed)" do
      options[:watch] = true
    end

    opts.on CONFLAGS[:fail_fast], "Stop running tests as soon as one fails" do |fail_fast|
      options[:fail_fast] = fail_fast
    end

    opts.on CONFLAGS[:parallel], "Parallelize tests (Default: true)" do |parallel|
      options[:parallel] = parallel
    end

    opts.on "-s", "#{CONFLAGS[:seed]} SEED", Integer, "Random seed for test order (setting --seed disables parallelization by default)" do |seed|
      options[:seed] = seed
    end

    opts.on "-n", "#{CONFLAGS[:names]} PATTERN", "One or more names or /patterns/ of tests to run (like: foo_test, /test_foo.*/, Foo#foo_test)" do |name|
      options[:names] ||= []
      options[:names] += name.split(PATTERN_FRIENDLY_SPLITTER)
    end

    opts.on "#{CONFLAGS[:exclude_names]} PATTERN", "One or more names or /patterns/ NOT to run" do |exclude_name|
      options[:exclude_names] ||= []
      options[:exclude_names] += exclude_name.split(PATTERN_FRIENDLY_SPLITTER)
    end

    opts.on "#{CONFLAGS[:exclude_paths]} PATH", Array, "One or more paths NOT to run (like: foo.rb, \"test/bar/**\", baz.rb:3)" do |path|
      options[:exclude_paths] ||= []
      options[:exclude_paths] += path
    end

    opts.on "#{CONFLAGS[:helper_paths]} PATH", Array, "One or more paths to a helper that is required before any tests (Default: \"test/helper.rb\")" do |path|
      options[:helper_paths] ||= []
      options[:helper_paths] += path
    end

    opts.on CONFLAGS[:no_helper], "Don't require any test helpers" do
      options[:no_helper] = true
    end

    opts.on "#{CONFLAGS[:prepend_paths]} PATH", Array, "Prepend one or more paths to run before the rest (Default: most recently modified test)" do |prepend|
      options[:prepend_paths] ||= []
      options[:prepend_paths] += prepend
    end

    opts.on CONFLAGS[:no_prepend], "Don't prepend any tests before the rest of the suite" do
      options[:no_prepend] = true
    end

    opts.on "-l", "#{CONFLAGS[:load_paths]} PATH", Array, "Add one or more paths to the $LOAD_PATH (Default: [\"lib\", \"test\"])" do |load_path|
      options[:load_paths] ||= []
      options[:load_paths] += load_path
    end

    opts.on "#{CONFLAGS[:base_path]} PATH", String, "Change the working directory for all relative paths (Default: current working directory)" do |path|
      options[:base_path] = path
    end

    opts.on "-c", "#{CONFLAGS[:config_path]} PATH", String, "The YAML configuration file to load (Default: '.tldr.yml')" do |config_path|
      options[:config_path] = config_path
    end

    opts.on "-r", "#{CONFLAGS[:reporter]} REPORTER", String, "Set a custom reporter class (Default: \"TLDR::Reporters::Default\")" do |reporter|
      options[:reporter] = reporter
    end

    opts.on CONFLAGS[:emoji], "Enable emoji output for the default reporter (Default: false)" do |emoji|
      options[:emoji] = emoji
    end

    opts.on CONFLAGS[:warnings], "Print Ruby warnings (Default: true)" do |warnings|
      options[:warnings] = warnings
    end

    opts.on "-v", CONFLAGS[:verbose], "Print stack traces for errors" do |verbose|
      options[:verbose] = verbose
    end

    opts.on CONFLAGS[:yes_i_know], "Suppress TLDR report when suite runs beyond any configured --timeout" do
      options[:yes_i_know] = true
    end

    opts.on CONFLAGS[:exit_0_on_timeout], "Exit with status code 0 when suite times out instead of 3" do
      options[:exit_0_on_timeout] = true
    end

    opts.on CONFLAGS[:exit_2_on_failure], "Exit with status code 2 (normally for errors) for both failures and errors" do
      options[:exit_2_on_failure] = true
    end

    opts.on CONFLAGS[:print_interrupted_test_backtraces], "Print stack traces of tests interrupted after a timeout" do |print_interrupted_test_backtraces|
      options[:print_interrupted_test_backtraces] = print_interrupted_test_backtraces
    end

    unless ARGV.include?("--help") || ARGV.include?("--h")
      opts.on CONFLAGS[:i_am_being_watched], "[INTERNAL] Signals to tldr it is being invoked under --watch mode" do
        options[:i_am_being_watched] = true
      end

      opts.on "--comment COMMENT", String, "[INTERNAL] No-op; used for multi-line execution instructions" do
        # See "--comment" in lib/tldr/reporters/default.rb for an example of how this is used internally
      end
    end
  end.parse!(args)

  options[:paths] = args if args.any?
  options[:config_path] = case options[:config_path]
  when nil then Config::DEFAULT_YAML_PATH
  when false then nil
  else options[:config_path]
  end

  Config.new(**options)
end