greenhat 0.6.1 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4787b5c739b568b8f6f5d22bab609f685ed4e4ed725085c432809102174e9dd5
4
- data.tar.gz: 7fcedca5675835ae177c58418dc2ddcaf25bae27333aeea9430e5a36d92a0b01
3
+ metadata.gz: 2bdaa3adc8b035c2b528472f1176e8104e75e369c0191926f2277a69170759b5
4
+ data.tar.gz: 9d5d1811e7efe201a93a2385ec08bb5f280adbf0e00b3e02dc70eab4d6fafe47
5
5
  SHA512:
6
- metadata.gz: c54a1054bd1c38b8514d4cd4c2b38f1c851a463134399c6c5c1af4c81ae9ffe6dbde083856b4dcabd1f09b9b68c5632240fdce5f135b5f8c763d5c72dc7047b0
7
- data.tar.gz: 894307efe02d22b50a4a6ca8674700409611e24cf8b46b9653b7f4b24f242b65a0f1649f4fd881bc636c92afea4d42085043b4a8cf3c4662b4535127f9e70b85
6
+ metadata.gz: 4bd0b3e175659ff78f984dea7cae51fcd3b5cce01171db9a74e6e77c0c3fd2b5bad48a2e52a8a0941674ed39858893a8035fe7f2582279752d07f25c0db06821
7
+ data.tar.gz: 35a342acfbea1e1dbcd70285f458cbed15822668fc06ae77a05ef8658667768be25560a1676bd3536bb2a80945bb9ea87d5b179aefc81c049ba4d951617b6f4f
@@ -11,7 +11,7 @@ module GreenHat
11
11
  x.slice(key)
12
12
  end
13
13
 
14
- list.map(&:values).flatten.max_by(&:size).size + 4
14
+ list.map(&:values).flatten.max_by(&:size).size + 5
15
15
  end
16
16
 
17
17
  def self.padding(disks, keys = %i[mounted_on size used avail])
@@ -29,6 +29,44 @@ module GreenHat
29
29
  things
30
30
  end
31
31
 
32
+ def self.report_output(data, filter = %w[tmpfs loop])
33
+ output = []
34
+
35
+ disks = data.sort_by { |x| x.use.to_i }.reverse
36
+ disks.reject! { |x| filter.any? { |y| x.filesystem.include? y } }
37
+ pad_mount, pad_size, pad_used, pad_avail = GreenHat::Disk.padding(disks)
38
+
39
+ output << [
40
+ 'Mount'.ljust(pad_mount).pastel(:blue),
41
+ 'Size'.ljust(pad_size).pastel(:magenta),
42
+ 'Used'.ljust(pad_used).pastel(:cyan),
43
+ 'Avail'.ljust(pad_avail).pastel(:white),
44
+ '% Use'.ljust(pad_avail).pastel(:green)
45
+ ].join
46
+
47
+ disks.map do |disk|
48
+ # Pretty Disk Use
49
+ use = [
50
+ disk.use.rjust(5).ljust(5).pastel(:green),
51
+ ' ['.pastel(:blue),
52
+ ('=' * (disk.use.to_i / 2)).pastel(:green),
53
+ ' ' * (50 - (disk.use.to_i / 2)),
54
+ ']'.pastel(:blue)
55
+ ].join
56
+
57
+ # Whole Thing
58
+ output << [
59
+ disk.mounted_on.ljust(pad_mount).pastel(:blue),
60
+ disk[:size].to_s.ljust(pad_size).pastel(:magenta),
61
+ disk.used.to_s.ljust(pad_used).pastel(:cyan),
62
+ disk.avail.to_s.ljust(pad_avail).pastel(:white),
63
+ use
64
+ ].join
65
+ end
66
+
67
+ output.join("\n ")
68
+ end
69
+
32
70
  # Unified Output Handler
33
71
  def self.format_output(file, name = false, limit = nil, filter = %w[tmpfs loop])
34
72
  output = []
@@ -79,13 +117,11 @@ module GreenHat
79
117
  end
80
118
 
81
119
  # Unified Output Handler
82
- def self.markdown_format(file, name = false, limit = nil, filter = %w[tmpfs loop])
120
+ def self.markdown_format(data, _name = false, limit = nil, filter = %w[tmpfs loop])
83
121
  output = []
84
122
 
85
- output << file.friendly_name if name
86
-
87
123
  # Reject TMPFS
88
- disks = file.data.sort_by { |x| x.use.to_i }.reverse
124
+ disks = data.sort_by { |x| x.use.to_i }.reverse
89
125
 
90
126
  # Filter
91
127
  disks.reject! { |x| filter.any? { |y| x.filesystem.include? y } }
@@ -115,7 +151,7 @@ module GreenHat
115
151
  ].join
116
152
  end
117
153
 
118
- output
154
+ output.join("\n")
119
155
  end
120
156
  # =
121
157
  end
@@ -26,7 +26,7 @@ module GreenHat
26
26
 
27
27
  def self.identify_node(archive)
28
28
  gitlab_status = archive.things.find { |x| x.name == 'gitlab_status' }&.data&.keys
29
- hostname = archive.things.find { |x| x.type == 'hostname' }.data.first
29
+ hostname = archive.things.find { |x| x.type == 'hostname' }.data.first.chomp
30
30
 
31
31
  {
32
32
  host: hostname,
data/lib/greenhat/cli.rb CHANGED
@@ -169,8 +169,6 @@ module GreenHat
169
169
  def self.did_you_mean
170
170
  dictionary = current_methods + current_submodules + cmd_list
171
171
 
172
- # all.select! { |x| x.include? cmd }
173
-
174
172
  all = DidYouMean::SpellChecker.new(dictionary: dictionary).correct(cmd)
175
173
 
176
174
  if all.empty?
@@ -6,12 +6,13 @@ module GreenHat
6
6
  class Builder
7
7
  include GreenHat::Reports::Shared
8
8
 
9
- attr_accessor :store, :flags, :args
9
+ attr_accessor :store, :flags, :args, :raw_args
10
10
 
11
- def initialize(file:, flags:, args:)
11
+ def initialize(file:, flags:, args:, raw_args:)
12
12
  self.store = []
13
13
  self.flags = flags
14
14
  self.args = args
15
+ self.raw_args = raw_args
15
16
  instance_eval File.read(file)
16
17
  rescue StandardError => e
17
18
  print "#{e.message}\n"
@@ -88,6 +89,10 @@ module GreenHat
88
89
  add(:query_format, query, show_output, block)
89
90
  end
90
91
 
92
+ def query_if_exists(query, show_output = true, &block)
93
+ add(:query_if_exists, query, show_output, block)
94
+ end
95
+
91
96
  # FastStats Helper
92
97
  def faststats(query, subcmd = '')
93
98
  add(:faststats, query, subcmd)
@@ -52,6 +52,10 @@ def query(query, show_output = true, &block)
52
52
  add(:query, query, show_output, block)
53
53
  end
54
54
 
55
+ def query_if_exists(query, show_output = true, &block)
56
+ add(:query_if_exists, query, show_output, block)
57
+ end
58
+
55
59
  # Log Query / Assume Format
56
60
  def query_format(query, show_output = true, &block)
57
61
  add(:query_format, query, show_output, block)
@@ -37,9 +37,32 @@ module GreenHat
37
37
  instance_exec(&block)
38
38
  end
39
39
 
40
+ # Log Query Ignore if no Files
41
+ def query_if_exists(query, show_output, block)
42
+ files, query_flags, query_args = GreenHat::Args.parse(Shellwords.split(query))
43
+
44
+ query_flags[:archive] = [archive.name] # Limit query to archive
45
+ query_flags[:combine] = true
46
+
47
+ # Default to everything
48
+ files = archive.things if files.empty?
49
+
50
+ # Ignore if no files are found
51
+ return unless ShellHelper.any_things?(files, query_flags)
52
+
53
+ results = Query.start(files, query_flags, query_args)
54
+
55
+ # Print and Exit of No Block / Show
56
+ return show(results) if block.nil? && show_output
57
+
58
+ output = instance_exec(results, &block)
59
+ show output if show_output
60
+ end
61
+
40
62
  # Log Query
41
63
  def query(query, show_output, block)
42
64
  files, query_flags, query_args = GreenHat::Args.parse(Shellwords.split(query))
65
+
43
66
  query_flags[:archive] = [archive.name] # Limit query to archive
44
67
  query_flags[:combine] = true
45
68
 
@@ -23,11 +23,13 @@ entries = [
23
23
  { header: 'Workhorse', base: 'gitlab-workhorse/current --level=error', stats: 'error' },
24
24
  { header: 'Sidekiq', base: 'sidekiq/current --severity=error', stats: 'message' },
25
25
  { header: 'API', base: 'gitlab-rails/api_json.log --severity=error',
26
- stats: 'exception.class,exception.message,status' }
26
+ stats: 'exception.class,exception.message,status' },
27
+ { header: 'Gitaly', base: 'gitaly/current --level=error --truncate=99', stats: 'error' }
27
28
  ]
28
29
 
29
30
  # Filter Logic
30
31
  filters = args_select(:filter)
32
+
31
33
  unless filters.empty?
32
34
  entries.select! do |entry|
33
35
  filters.any? do |filter|
@@ -36,11 +38,23 @@ unless filters.empty?
36
38
  end
37
39
  end
38
40
 
41
+ # Fuzzy Filter Match
42
+ unless raw_args.empty?
43
+ entries.select! do |entry|
44
+ # Create a pattern with the file and title
45
+ globby = [entry.header.downcase, entry.base.split(' ', 2).first].join(' ')
46
+
47
+ # Check any Matches
48
+ raw_args.any? { |x| globby.include? x }
49
+ end
50
+ end
51
+
39
52
  # Return output
40
53
  entries.each do |entry|
41
- query_string = flags.verbose ? entry.base : entry.base + " --stats=#{entry.stats}"
54
+ query_string = flags[:verbose] ? entry.base : entry.base + " --stats=#{entry.stats}"
42
55
  query(query_string, false) do |results|
43
- next if results.map(&:values).map(&:first).sum.zero?
56
+ next if results.empty?
57
+ next if !flags[:verbose] && results.map(&:values).map(&:first).sum.zero?
44
58
 
45
59
  header entry.header
46
60
 
@@ -94,6 +94,13 @@ info('free_m', false) do |data|
94
94
  end
95
95
  end
96
96
 
97
+ br
98
+ header 'Disk'
99
+
100
+ info 'df_hT' do |data|
101
+ indent GreenHat::Disk.report_output(data)
102
+ end
103
+
97
104
  br
98
105
  header 'GitLab'
99
106
  info 'gitlab/version-manifest.json' do |data|
@@ -107,37 +114,43 @@ end
107
114
  br
108
115
  puts indent('Errors'.pastel(:cyan))
109
116
 
110
- query 'gitlab-rails/production_json.log --status=500' do |data|
117
+ query_if_exists 'gitlab-rails/production_json.log --status=500' do |data|
111
118
  color = data.count.zero? ? :green : :red
112
119
  indent("#{ljust('Production:', 14, :magenta)} #{data.count.to_s.pastel(color)}", 4)
113
120
  end
114
121
 
115
- query 'gitlab-rails/application_json.log --message!="Cannot obtain an exclusive lease" --severity=error' do |data|
122
+ app_query = 'gitlab-rails/application_json.log --message!="Cannot obtain an exclusive lease" --severity=error'
123
+ query_if_exists app_query do |data|
116
124
  color = data.count.zero? ? :green : :red
117
125
  indent("#{ljust('Application:', 14, :magenta)} #{data.count.to_s.pastel(color)}", 4)
118
126
  end
119
127
 
120
- query 'sidekiq/current --severity=error' do |data|
128
+ query_if_exists 'sidekiq/current --severity=error' do |data|
121
129
  color = data.count.zero? ? :green : :red
122
130
  indent("#{ljust('Sidekiq:', 14, :magenta)} #{data.count.to_s.pastel(color)}", 4)
123
131
  end
124
132
 
125
- query 'gitlab-rails/api_json.log --status=500' do |data|
133
+ query_if_exists 'gitlab-rails/api_json.log --status=500' do |data|
126
134
  color = data.count.zero? ? :green : :red
127
135
  indent("#{ljust('API:', 14, :magenta)} #{data.count.to_s.pastel(color)}", 4)
128
136
  end
129
137
 
130
- query 'gitaly/current --level=error' do |data|
138
+ query_if_exists 'gitaly/current --level=error' do |data|
131
139
  color = data.count.zero? ? :green : :red
132
140
  indent("#{ljust('Gitaly:', 14, :magenta)} #{data.count.to_s.pastel(color)}", 4)
133
141
  end
134
142
 
135
- query 'gitlab-workhorse/current --level=error' do |data|
143
+ query_if_exists 'gitlab-workhorse/current --level=error' do |data|
136
144
  color = data.count.zero? ? :green : :red
137
145
  indent("#{ljust('Workhorse:', 14, :magenta)} #{data.count.to_s.pastel(color)}", 4)
138
146
  end
139
147
 
140
- query 'gitlab-rails/exceptions_json.log' do |data|
148
+ query_if_exists 'gitlab-rails/exceptions_json.log' do |data|
141
149
  color = data.count.zero? ? :green : :red
142
150
  indent("#{ljust('Exceptions:', 14, :magenta)} #{data.count.to_s.pastel(color)}", 4)
143
151
  end
152
+
153
+ query_if_exists('praefect/current --level=error') do |data|
154
+ color = data.count.zero? ? :green : :red
155
+ indent("#{ljust('Praefect:', 14, :magenta)} #{data.count.to_s.pastel(color)}", 4)
156
+ end
@@ -0,0 +1,140 @@
1
+ quiet!
2
+
3
+ puts '**OS**'
4
+ br
5
+
6
+ puts '```'
7
+ cat 'hostname' do |data|
8
+ "Hostname: #{data.join}"
9
+ end
10
+
11
+ info 'etc/os-release' do |data|
12
+ ident = "[#{data.ID}] "
13
+ pretty_name = data.PRETTY_NAME
14
+ " Distro: #{ident} #{pretty_name}"
15
+ end
16
+
17
+ cat 'uname' do |data|
18
+ value, build = data.first.split[2].split('-')
19
+ build = "(#{build})"
20
+ " Kernel: #{value} #{build}"
21
+ end
22
+
23
+ cat 'uptime' do |data|
24
+ init = data.join.split(', load average').first.strip.split('up ', 2).last
25
+ " Uptime: #{init}"
26
+ end
27
+
28
+ # Load Average
29
+ info 'lscpu' do |data|
30
+ uptime = archive.thing? 'uptime'
31
+ return unless uptime
32
+
33
+ cpu_count = data['CPU(s)'].to_i
34
+ intervals = uptime.data.first.split('load average: ', 2).last.split(', ').map(&:to_f)
35
+
36
+ intervals_text = intervals.map do |interval|
37
+ value = percent(interval, cpu_count)
38
+ [
39
+ interval,
40
+ ' (',
41
+ "#{value}%",
42
+ ')'
43
+ ].join
44
+ end
45
+
46
+ " LoadAvg: [CPU #{cpu_count}] #{intervals_text.join(', ')}"
47
+ end
48
+ puts '```'
49
+
50
+ br
51
+ puts '**Memory**'
52
+ br
53
+
54
+ puts '```'
55
+ info('free_m', false) do |data|
56
+ free = data.first
57
+
58
+ unless free.total.blank?
59
+ size = number_to_human_size(free.total.to_i * (1024**2))
60
+ puts " #{ljust('Total', 12)} #{size}"
61
+ end
62
+
63
+ unless free.used.blank?
64
+ size = number_to_human_size(free.used.to_i * (1024**2))
65
+
66
+ puts " #{ljust('Used', 12)} #{size}"
67
+ end
68
+
69
+ unless free.free.blank?
70
+ size = number_to_human_size(free.free.to_i * (1024**2))
71
+ puts " #{ljust('Free', 12)} #{size}"
72
+ end
73
+
74
+ unless free.available.blank?
75
+ size = number_to_human_size(free.available.to_i * (1024**2))
76
+ puts " #{ljust('Available', 12)} #{size}"
77
+ end
78
+
79
+ # br
80
+ # data.map { |x| GreenHat::Memory.memory_row x }.each do |row|
81
+ # puts row
82
+ # end
83
+ end
84
+ puts '```'
85
+
86
+ br
87
+ puts '**Disks**'
88
+ br
89
+
90
+ puts '```'
91
+ info 'df_hT' do |data|
92
+ GreenHat::Disk.markdown_format(data, false, 3)
93
+ end
94
+ puts '```'
95
+
96
+ br
97
+ puts '**GitLab**'
98
+ info 'gitlab/version-manifest.json' do |data|
99
+ "Version: #{data.build_version}"
100
+ end
101
+
102
+ br
103
+
104
+ info 'gitlab_status' do
105
+ GreenHat::GitLab.services_markdown(archive)
106
+ end
107
+
108
+ br
109
+ puts '**Errors**'
110
+ br
111
+
112
+ puts '```'
113
+ query 'gitlab-rails/production_json.log --status=500' do |data|
114
+ ljust('Production', 14) + data.count.to_s
115
+ end
116
+
117
+ query 'gitlab-rails/application_json.log --message!="Cannot obtain an exclusive lease" --severity=error' do |data|
118
+ ljust('Application', 14) + data.count.to_s
119
+ end
120
+
121
+ query 'sidekiq/current --severity=error' do |data|
122
+ ljust('Sidekiq', 14) + data.count.to_s
123
+ end
124
+
125
+ query 'gitlab-rails/api_json.log --status=500' do |data|
126
+ ljust('API', 14) + data.count.to_s
127
+ end
128
+
129
+ query 'gitaly/current --level=error' do |data|
130
+ ljust('Gitaly', 14) + data.count.to_s
131
+ end
132
+
133
+ query 'gitlab-workhorse/current --level=error' do |data|
134
+ ljust('Workhorse', 14) + data.count.to_s
135
+ end
136
+
137
+ query 'gitlab-rails/exceptions_json.log' do |data|
138
+ ljust('Exceptions', 14) + data.count.to_s
139
+ end
140
+ puts '```'
@@ -9,18 +9,19 @@ module GreenHat
9
9
 
10
10
  include InternalMethods
11
11
  include Shared
12
- attr_accessor :store, :archive, :flags, :args, :output
12
+ attr_accessor :store, :archive, :flags, :args, :raw_args, :output
13
13
 
14
14
  # Make Pry Easier
15
15
  def inspect
16
16
  "#<Runner archive: '#{archive}'>"
17
17
  end
18
18
 
19
- def initialize(archive:, store:, flags:, args:)
19
+ def initialize(archive:, store:, flags:, args:, raw_args:)
20
20
  self.store = store
21
21
  self.archive = archive
22
22
  self.flags = flags
23
23
  self.args = args
24
+ self.raw_args = raw_args
24
25
  self.output = []
25
26
 
26
27
  # Don't render paper new lines
@@ -31,6 +31,7 @@ module GreenHat
31
31
  def args_select(field)
32
32
  args.select { |x| x.field == field.to_sym }
33
33
  end
34
+
34
35
  # -=-=-=-=-=-
35
36
  end
36
37
  end
@@ -3,14 +3,15 @@ module GreenHat
3
3
  # Log Helpers
4
4
  module Reports
5
5
  # Make Running more consistent
6
- def self.run(file:, args:, flags:)
7
- report = GreenHat::Reports::Builder.new(file: file, args: args, flags: flags)
6
+ def self.run(file:, args:, flags:, raw_args:)
7
+ report = GreenHat::Reports::Builder.new(file: file, args: args, flags: flags, raw_args: raw_args)
8
8
  output = Archive.all.map do |archive|
9
9
  runner = GreenHat::Reports::Runner.new(
10
10
  archive: archive,
11
11
  store: report.store.clone,
12
12
  flags: flags,
13
- args: args
13
+ args: args,
14
+ raw_args: raw_args
14
15
  )
15
16
 
16
17
  runner.run!
@@ -29,6 +30,17 @@ module GreenHat
29
30
  path = "#{File.dirname(__FILE__)}/reports"
30
31
  Dir["#{path}/*.rb"] + Dir["#{GreenHat::Settings.reports_dir}/*.rb"]
31
32
  end
33
+
34
+ # Collect everything from Built-in and local reports
35
+ def self.auto_complete_list
36
+ path = "#{File.dirname(__FILE__)}/reports"
37
+ list = Dir["#{path}/*.rb"] + Dir["#{GreenHat::Settings.reports_dir}/*.rb"]
38
+
39
+ list.map do |entry|
40
+ File.basename(entry, '.rb')
41
+ end
42
+ end
43
+ # --
32
44
  end
33
45
  end
34
46
  end
@@ -82,8 +82,8 @@ module GreenHat
82
82
  # rubocop:enable Style/GuardClause
83
83
 
84
84
  def self.start
85
- Dir.mkdir dir unless Dir.exist? dir
86
- Dir.mkdir reports_dir unless Dir.exist? reports_dir
85
+ FileUtils.mkdir_p dir
86
+ FileUtils.mkdir_p reports_dir
87
87
 
88
88
  # Load User Settings
89
89
  settings_load
@@ -35,7 +35,7 @@ module GreenHat
35
35
  results = Archive.all.map { |x| GitLab.identify_node(x) }
36
36
 
37
37
  GitLab.node_types.each do |entry|
38
- list = results.select { |x| (x.services & entry.pattern).any? }.map(&:host).join(', ')
38
+ list = results.select { |x| (x.services & entry.pattern).any? }.map(&:host).join("\n")
39
39
  next if list.blank?
40
40
 
41
41
  puts entry.name.pastel(:bright_green)
@@ -88,7 +88,6 @@ module GreenHat
88
88
  "#{service.status}:",
89
89
  service.name.ljust(pad).pastel(color),
90
90
  "#{service.pid_uptime};".ljust(pad)
91
-
92
91
  ]
93
92
  end
94
93
 
@@ -125,10 +125,18 @@ module GreenHat
125
125
  return false
126
126
  end
127
127
 
128
- Thing.new.query_save(results, name)
128
+ Thing.new.query_save(save_greenhat_query_info + results, name)
129
129
  puts "#{name.pastel(:green)} Saved!"
130
130
  end
131
131
 
132
+ def self.save_greenhat_query_info
133
+ [{
134
+ time: Time.now,
135
+ query: ShellHelper::Log.last,
136
+ msg: 'GreenHat Save/Write'
137
+ }]
138
+ end
139
+
132
140
  def self.write(raw = [])
133
141
  if ShellHelper::Log.last.nil?
134
142
  puts 'No previous query found'.pastel(:red)
@@ -158,7 +166,7 @@ module GreenHat
158
166
  return false
159
167
  end
160
168
 
161
- all = results.map { |row| Oj.dump(row) }
169
+ all = (save_greenhat_query_info + results).map { |row| Oj.dump(row) }
162
170
  File.write(name, all.join("\n"))
163
171
  puts "#{name.pastel(:green)} File Written!"
164
172
  end
@@ -12,12 +12,19 @@ module GreenHat
12
12
  end
13
13
 
14
14
  def self.open(url = 'http://localhost:4567/chart/time')
15
- cmd = if platform.linux? || platform.unix?
16
- 'xdg-open'
17
- elsif platform.mac?
15
+ cmd = if platform.mac?
18
16
  'open'
17
+ elsif platform.linux? || platform.unix?
18
+ 'xdg-open'
19
19
  end
20
20
 
21
+ # See if anything was detected -- ignore system call if nothing was
22
+ if cmd.nil?
23
+ puts "Unknown OS! #{RbConfig::CONFIG['arch']}"
24
+ puts url
25
+ return
26
+ end
27
+
21
28
  # platform.windows? # => false
22
29
  # platform.unix? # => true
23
30
  # platform.linux? # => false
@@ -215,7 +215,7 @@ module GreenHat
215
215
  results = filter_pluck(results, flags[:pluck]) if flags.key?(:pluck)
216
216
 
217
217
  # Total Counter
218
- return [ShellHelper.total_count(results, flags)] if flags.key?(:total)
218
+ results = ShellHelper.total_count(results, flags) if flags.key?(:total)
219
219
 
220
220
  results
221
221
  end
@@ -10,6 +10,20 @@ module GreenHat
10
10
  module Shell
11
11
  # Logs
12
12
  module Reports
13
+ def self.auto_complete(_list, word)
14
+ matches = GreenHat::ShellHelper::Reports.auto_complete_list.select do |x|
15
+ x.include? word
16
+ end
17
+
18
+ if matches.count > 1
19
+ puts "#{'Report Options:'.pastel(:bright_blue)} #{matches.join(' ').pastel(:bright_green)}"
20
+
21
+ Cli.common_substr(matches.map(&:to_s))
22
+ elsif matches.count == 1
23
+ matches.first
24
+ end
25
+ end
26
+
13
27
  # Easy Show All
14
28
  def self.ls(raw = [])
15
29
  filter, _flags, _args = Args.parse(raw)
@@ -33,7 +47,8 @@ module GreenHat
33
47
  run_list.uniq!
34
48
 
35
49
  run_list.each do |file|
36
- GreenHat::ShellHelper::Reports.run(file: file, args: args, flags: flags)
50
+ raw_args = list.reject { |x| file.include? x }
51
+ GreenHat::ShellHelper::Reports.run(file: file, args: args, flags: flags, raw_args: raw_args)
37
52
  end
38
53
  end
39
54
  end