spoom 1.2.4 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +54 -55
- data/lib/spoom/cli/deadcode.rb +172 -0
- data/lib/spoom/cli/helper.rb +20 -0
- data/lib/spoom/cli/srb/bump.rb +200 -0
- data/lib/spoom/cli/srb/coverage.rb +224 -0
- data/lib/spoom/cli/srb/lsp.rb +159 -0
- data/lib/spoom/cli/srb/tc.rb +150 -0
- data/lib/spoom/cli/srb.rb +27 -0
- data/lib/spoom/cli.rb +72 -32
- data/lib/spoom/context/git.rb +2 -2
- data/lib/spoom/context/sorbet.rb +2 -2
- data/lib/spoom/deadcode/definition.rb +11 -0
- data/lib/spoom/deadcode/indexer.rb +222 -224
- data/lib/spoom/deadcode/location.rb +2 -2
- data/lib/spoom/deadcode/plugins/action_mailer.rb +2 -2
- data/lib/spoom/deadcode/plugins/action_mailer_preview.rb +19 -0
- data/lib/spoom/deadcode/plugins/actionpack.rb +4 -6
- data/lib/spoom/deadcode/plugins/active_model.rb +8 -8
- data/lib/spoom/deadcode/plugins/active_record.rb +9 -12
- data/lib/spoom/deadcode/plugins/active_support.rb +11 -0
- data/lib/spoom/deadcode/plugins/base.rb +1 -1
- data/lib/spoom/deadcode/plugins/graphql.rb +4 -4
- data/lib/spoom/deadcode/plugins/namespaces.rb +2 -4
- data/lib/spoom/deadcode/plugins/ruby.rb +8 -17
- data/lib/spoom/deadcode/plugins/sorbet.rb +4 -10
- data/lib/spoom/deadcode/plugins.rb +1 -0
- data/lib/spoom/deadcode/remover.rb +209 -174
- data/lib/spoom/deadcode/send.rb +9 -10
- data/lib/spoom/deadcode/visitor.rb +755 -0
- data/lib/spoom/deadcode.rb +40 -10
- data/lib/spoom/file_tree.rb +0 -16
- data/lib/spoom/sorbet/errors.rb +1 -1
- data/lib/spoom/sorbet/lsp/structures.rb +2 -2
- data/lib/spoom/version.rb +1 -1
- metadata +19 -15
- data/lib/spoom/cli/bump.rb +0 -198
- data/lib/spoom/cli/coverage.rb +0 -222
- data/lib/spoom/cli/lsp.rb +0 -168
- data/lib/spoom/cli/run.rb +0 -148
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1993e4b43cf1c9d97475b654c049e8b14a27189561471b2bfb4bb077ac2f7b9e
|
4
|
+
data.tar.gz: ad6a269fe90e77df95564a13e222d58e9993c7ffef389c2be3a0e2fc7a1aed9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8eab661cb5d9aa290bea6dba5ab3808ad4df7847213229616c4eb912faf012208da053bcb4019700e390f57ce156ff7852a9ef4b01ab48c819acc1453a62b8eb
|
7
|
+
data.tar.gz: 7f74c0655f781be1c9832d33dcc9a1cb088705f201998f431dae80a90dae259fe09a85cb0ffec1bd53369694b842c5bfe10a3b32ff25a9b1c61ee712fd934900
|
data/README.md
CHANGED
@@ -31,13 +31,13 @@ Spoom can create a typing coverage report from Sorbet and Git data:
|
|
31
31
|
After installing the `spoom` gem, run the `timeline` command to collect the history data:
|
32
32
|
|
33
33
|
```
|
34
|
-
$ spoom coverage timeline --save
|
34
|
+
$ spoom srb coverage timeline --save
|
35
35
|
```
|
36
36
|
|
37
37
|
Then create the HTML page with `report`:
|
38
38
|
|
39
39
|
```
|
40
|
-
$ spoom coverage report
|
40
|
+
$ spoom srb coverage report
|
41
41
|
```
|
42
42
|
|
43
43
|
Your report will be generated under `spoom_report.html`.
|
@@ -46,66 +46,48 @@ See all the [Typing Coverage](#typing-coverage) CLI commands for more details.
|
|
46
46
|
|
47
47
|
### Command Line Interface
|
48
48
|
|
49
|
-
#### Sorbet configuration commands
|
50
|
-
|
51
|
-
Spoom works with your `sorbet/config` file. No additional configuration is needed.
|
52
|
-
|
53
|
-
Show Sorbet config options:
|
54
|
-
|
55
|
-
```
|
56
|
-
$ spoom config
|
57
|
-
```
|
58
|
-
|
59
|
-
#### Listing files
|
60
|
-
|
61
|
-
List the files (and related strictness) that will be typchecked with the current Sorbet config options:
|
62
|
-
|
63
|
-
```
|
64
|
-
$ spoom files
|
65
|
-
```
|
66
|
-
|
67
49
|
#### Errors sorting and filtering
|
68
50
|
|
69
51
|
List all typechecking errors sorted by location:
|
70
52
|
|
71
53
|
```
|
72
|
-
$ spoom tc -s loc
|
54
|
+
$ spoom srb tc -s loc
|
73
55
|
```
|
74
56
|
|
75
57
|
List all typechecking errors sorted by error code first:
|
76
58
|
|
77
59
|
```
|
78
|
-
$ spoom tc -s code
|
60
|
+
$ spoom srb tc -s code
|
79
61
|
```
|
80
62
|
|
81
63
|
List only typechecking errors from a specific error code:
|
82
64
|
|
83
65
|
```
|
84
|
-
$ spoom tc -c 7004
|
66
|
+
$ spoom srb tc -c 7004
|
85
67
|
```
|
86
68
|
|
87
69
|
List only the first 10 typechecking errors
|
88
70
|
|
89
71
|
```
|
90
|
-
$ spoom tc -l 10
|
72
|
+
$ spoom srb tc -l 10
|
91
73
|
```
|
92
74
|
|
93
75
|
These options can be combined:
|
94
76
|
|
95
77
|
```
|
96
|
-
$ spoom tc -s -c 7004 -l 10
|
78
|
+
$ spoom srb tc -s -c 7004 -l 10
|
97
79
|
```
|
98
80
|
|
99
81
|
Remove duplicated error lines:
|
100
82
|
|
101
83
|
```
|
102
|
-
$ spoom tc -u
|
84
|
+
$ spoom srb tc -u
|
103
85
|
```
|
104
86
|
|
105
87
|
Format each error line:
|
106
88
|
|
107
89
|
```
|
108
|
-
$ spoom tc -f '%C - %F:%L: %M'
|
90
|
+
$ spoom srb tc -f '%C - %F:%L: %M'
|
109
91
|
```
|
110
92
|
|
111
93
|
Where:
|
@@ -118,13 +100,13 @@ Where:
|
|
118
100
|
Hide the `Errors: X` at the end of the list:
|
119
101
|
|
120
102
|
```
|
121
|
-
$ spoom tc --no-count
|
103
|
+
$ spoom srb tc --no-count
|
122
104
|
```
|
123
105
|
|
124
|
-
List only the errors
|
106
|
+
List only the errors coming from specific directories or files:
|
125
107
|
|
126
108
|
```
|
127
|
-
$ spoom tc file1.rb path1/ path2/
|
109
|
+
$ spoom srb tc file1.rb path1/ path2/
|
128
110
|
```
|
129
111
|
|
130
112
|
#### Typing coverage
|
@@ -132,61 +114,61 @@ $ spoom tc file1.rb path1/ path2/
|
|
132
114
|
Show metrics about the project contents and the typing coverage:
|
133
115
|
|
134
116
|
```
|
135
|
-
$ spoom coverage
|
117
|
+
$ spoom srb coverage
|
136
118
|
```
|
137
119
|
|
138
120
|
Save coverage data under `spoom_data/`:
|
139
121
|
|
140
122
|
```
|
141
|
-
$ spoom coverage --save
|
123
|
+
$ spoom srb coverage --save
|
142
124
|
```
|
143
125
|
|
144
126
|
Save coverage data under a specific directory:
|
145
127
|
|
146
128
|
```
|
147
|
-
$ spoom coverage --save my_data/
|
129
|
+
$ spoom srb coverage --save my_data/
|
148
130
|
```
|
149
131
|
|
150
132
|
Show typing coverage evolution based on the commits history:
|
151
133
|
|
152
134
|
```
|
153
|
-
$ spoom coverage timeline
|
135
|
+
$ spoom srb coverage timeline
|
154
136
|
```
|
155
137
|
|
156
138
|
Show typing coverage evolution based on the commits history between specific dates:
|
157
139
|
|
158
140
|
```
|
159
|
-
$ spoom coverage timeline --from YYYY-MM-DD --to YYYY-MM-DD
|
141
|
+
$ spoom srb coverage timeline --from YYYY-MM-DD --to YYYY-MM-DD
|
160
142
|
```
|
161
143
|
|
162
144
|
Save the typing coverage evolution as JSON under `spoom_data/`:
|
163
145
|
|
164
146
|
```
|
165
|
-
$ spoom coverage timeline --save
|
147
|
+
$ spoom srb coverage timeline --save
|
166
148
|
```
|
167
149
|
|
168
150
|
Save the typing coverage evolution as JSON in a specific directory:
|
169
151
|
|
170
152
|
```
|
171
|
-
$ spoom coverage timeline --save my_data/
|
153
|
+
$ spoom srb coverage timeline --save my_data/
|
172
154
|
```
|
173
155
|
|
174
156
|
Run `bundle install` for each commit of the timeline (may solve errors due to different Sorbet versions):
|
175
157
|
|
176
158
|
```
|
177
|
-
$ spoom coverage timeline --bundle-install
|
159
|
+
$ spoom srb coverage timeline --bundle-install
|
178
160
|
```
|
179
161
|
|
180
162
|
Generate an HTML typing coverage report:
|
181
163
|
|
182
164
|
```
|
183
|
-
$ spoom coverage report
|
165
|
+
$ spoom srb coverage report
|
184
166
|
```
|
185
167
|
|
186
168
|
Change the colors used for strictnesses (useful for colorblind folks):
|
187
169
|
|
188
170
|
```
|
189
|
-
$ spoom coverage report \
|
171
|
+
$ spoom srb coverage report \
|
190
172
|
--color-true "#648ffe" \
|
191
173
|
--color-false "#fe6002" \
|
192
174
|
--color-ignore "#feb000" \
|
@@ -197,7 +179,7 @@ $ spoom coverage report \
|
|
197
179
|
Open the HTML typing coverage report:
|
198
180
|
|
199
181
|
```
|
200
|
-
$ spoom coverage open
|
182
|
+
$ spoom srb coverage open
|
201
183
|
```
|
202
184
|
|
203
185
|
#### Change the sigil used in files
|
@@ -205,37 +187,38 @@ $ spoom coverage open
|
|
205
187
|
Bump the strictness from all files currently at `typed: false` to `typed: true` where it does not create typechecking errors:
|
206
188
|
|
207
189
|
```
|
208
|
-
$ spoom bump --from false --to true
|
190
|
+
$ spoom srb bump --from false --to true
|
209
191
|
```
|
210
192
|
|
211
193
|
Bump the strictness from all files currently at `typed: false` to `typed: true` even if it creates typechecking errors:
|
212
194
|
|
213
195
|
```
|
214
|
-
$ spoom bump --from false --to true -f
|
196
|
+
$ spoom srb bump --from false --to true -f
|
215
197
|
```
|
216
198
|
|
217
199
|
Bump the strictness from a list of files (one file by line):
|
218
200
|
|
219
201
|
```
|
220
|
-
$ spoom bump --from false --to true -o list.txt
|
202
|
+
$ spoom srb bump --from false --to true -o list.txt
|
221
203
|
```
|
222
204
|
|
223
|
-
Check if files can be bumped without applying any change
|
205
|
+
Check if files can be bumped without applying any change and show the list of files that can be bumped without errors.
|
206
|
+
Will exit with a non-zero status if some files can be bumped without errors (useful to check for bumpable files on CI for example):
|
224
207
|
|
225
208
|
```
|
226
|
-
$ spoom bump --from false --to true --dry
|
209
|
+
$ spoom srb bump --from false --to true --dry
|
227
210
|
```
|
228
211
|
|
229
212
|
Bump files using a custom instance of Sorbet:
|
230
213
|
|
231
214
|
```
|
232
|
-
$ spoom bump --from false --to true --sorbet /path/to/sorbet/bin
|
215
|
+
$ spoom srb bump --from false --to true --sorbet /path/to/sorbet/bin
|
233
216
|
```
|
234
217
|
|
235
218
|
Count the number of type-checking errors if all files were bumped to true:
|
236
219
|
|
237
220
|
```
|
238
|
-
$ spoom bump --count-errors --dry
|
221
|
+
$ spoom srb bump --count-errors --dry
|
239
222
|
```
|
240
223
|
|
241
224
|
#### Interact with Sorbet LSP mode
|
@@ -245,43 +228,43 @@ $ spoom bump --count-errors --dry
|
|
245
228
|
Find all definitions for `Foo`:
|
246
229
|
|
247
230
|
```
|
248
|
-
$ spoom lsp find Foo
|
231
|
+
$ spoom srb lsp find Foo
|
249
232
|
```
|
250
233
|
|
251
234
|
List all symbols in a file:
|
252
235
|
|
253
236
|
```
|
254
|
-
$ spoom lsp symbols <file.rb>
|
237
|
+
$ spoom srb lsp symbols <file.rb>
|
255
238
|
```
|
256
239
|
|
257
240
|
List all definitions for a specific code location:
|
258
241
|
|
259
242
|
```
|
260
|
-
$ spoom lsp defs <file.rb> <line> <column>
|
243
|
+
$ spoom srb lsp defs <file.rb> <line> <column>
|
261
244
|
```
|
262
245
|
|
263
246
|
List all references for a specific code location:
|
264
247
|
|
265
248
|
```
|
266
|
-
$ spoom lsp refs <file.rb> <line> <column>
|
249
|
+
$ spoom srb lsp refs <file.rb> <line> <column>
|
267
250
|
```
|
268
251
|
|
269
252
|
Show hover information for a specific code location:
|
270
253
|
|
271
254
|
```
|
272
|
-
$ spoom lsp hover <file.rb> <line> <column>
|
255
|
+
$ spoom srb lsp hover <file.rb> <line> <column>
|
273
256
|
```
|
274
257
|
|
275
258
|
Show signature information for a specific code location:
|
276
259
|
|
277
260
|
```
|
278
|
-
$ spoom lsp sig <file.rb> <line> <column>
|
261
|
+
$ spoom srb lsp sig <file.rb> <line> <column>
|
279
262
|
```
|
280
263
|
|
281
264
|
Show type information for a specific code location:
|
282
265
|
|
283
266
|
```
|
284
|
-
$ spoom lsp sig <file.rb> <line> <column>
|
267
|
+
$ spoom srb lsp sig <file.rb> <line> <column>
|
285
268
|
```
|
286
269
|
|
287
270
|
### API
|
@@ -358,6 +341,22 @@ require "spoom/backtrace_filter/minitest"
|
|
358
341
|
Minitest.backtrace_filter = Spoom::BacktraceFilter::Minitest.new
|
359
342
|
```
|
360
343
|
|
344
|
+
### Dead code removal
|
345
|
+
|
346
|
+
Run dead code detection in your project with:
|
347
|
+
|
348
|
+
```
|
349
|
+
$ spoom deadcode
|
350
|
+
```
|
351
|
+
|
352
|
+
This will list all the methods and constants that do not appear to be used in your project.
|
353
|
+
|
354
|
+
You can remove them with Spoom:
|
355
|
+
|
356
|
+
```
|
357
|
+
$ spoom deadcode remove path/to/file.rb:42:18-47:23
|
358
|
+
```
|
359
|
+
|
361
360
|
## Development
|
362
361
|
|
363
362
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. Don't forget to run `bin/sanity` before pushing your changes.
|
@@ -0,0 +1,172 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative "../deadcode"
|
5
|
+
|
6
|
+
module Spoom
|
7
|
+
module Cli
|
8
|
+
class Deadcode < Thor
|
9
|
+
extend T::Sig
|
10
|
+
include Helper
|
11
|
+
|
12
|
+
default_task :deadcode
|
13
|
+
|
14
|
+
desc "deadcode PATH...", "Analyze PATHS to find dead code"
|
15
|
+
option :allowed_extensions,
|
16
|
+
type: :array,
|
17
|
+
default: [".rb", ".erb", ".gemspec"],
|
18
|
+
aliases: :e,
|
19
|
+
desc: "Allowed extensions"
|
20
|
+
option :allowed_mime_types,
|
21
|
+
type: :array,
|
22
|
+
default: ["text/x-ruby", "text/x-ruby-script"],
|
23
|
+
aliases: :m,
|
24
|
+
desc: "Allowed mime types"
|
25
|
+
option :exclude,
|
26
|
+
type: :array,
|
27
|
+
default: ["vendor/", "sorbet/"],
|
28
|
+
aliases: :x,
|
29
|
+
desc: "Exclude paths"
|
30
|
+
option :show_files,
|
31
|
+
type: :boolean,
|
32
|
+
default: false,
|
33
|
+
desc: "Show the files that will be analyzed"
|
34
|
+
option :show_plugins,
|
35
|
+
type: :boolean,
|
36
|
+
default: false,
|
37
|
+
desc: "Show the loaded plugins"
|
38
|
+
option :show_defs,
|
39
|
+
type: :boolean,
|
40
|
+
default: false,
|
41
|
+
desc: "Show the indexed definitions"
|
42
|
+
option :show_refs,
|
43
|
+
type: :boolean,
|
44
|
+
default: false,
|
45
|
+
desc: "Show the indexed references"
|
46
|
+
option :sort,
|
47
|
+
type: :string,
|
48
|
+
default: "name",
|
49
|
+
enum: ["name", "location"],
|
50
|
+
desc: "Sort the output by name or location"
|
51
|
+
sig { params(paths: String).void }
|
52
|
+
def deadcode(*paths)
|
53
|
+
context = self.context
|
54
|
+
|
55
|
+
paths << exec_path if paths.empty?
|
56
|
+
|
57
|
+
$stderr.puts "Collecting files..."
|
58
|
+
collector = FileCollector.new(
|
59
|
+
allow_extensions: options[:allowed_extensions],
|
60
|
+
allow_mime_types: options[:allowed_mime_types],
|
61
|
+
exclude_patterns: options[:exclude].map { |p| Pathname.new(File.join(exec_path, p, "**")).cleanpath.to_s },
|
62
|
+
)
|
63
|
+
collector.visit_paths(paths)
|
64
|
+
files = collector.files.sort
|
65
|
+
|
66
|
+
if options[:show_files]
|
67
|
+
$stderr.puts "\nCollected #{blue(files.size.to_s)} files for analysis\n"
|
68
|
+
files.each do |file|
|
69
|
+
$stderr.puts " #{gray(file)}"
|
70
|
+
end
|
71
|
+
$stderr.puts
|
72
|
+
end
|
73
|
+
|
74
|
+
plugins = Spoom::Deadcode.plugins_from_gemfile_lock(context)
|
75
|
+
if options[:show_plugins]
|
76
|
+
$stderr.puts "\nLoaded #{blue(plugins.size.to_s)} plugins\n"
|
77
|
+
plugins.each do |plugin|
|
78
|
+
$stderr.puts " #{gray(plugin.class.to_s)}"
|
79
|
+
end
|
80
|
+
$stderr.puts
|
81
|
+
end
|
82
|
+
|
83
|
+
index = Spoom::Deadcode::Index.new
|
84
|
+
|
85
|
+
$stderr.puts "Indexing #{blue(files.size.to_s)} files..."
|
86
|
+
files.each do |file|
|
87
|
+
content = File.read(file)
|
88
|
+
content = ERB.new(content).src if file.end_with?(".erb")
|
89
|
+
|
90
|
+
tree = Spoom::Deadcode.parse_ruby(content, file: file)
|
91
|
+
Spoom::Deadcode.index_node(index, tree, content, file: file, plugins: plugins)
|
92
|
+
rescue Spoom::Deadcode::ParserError => e
|
93
|
+
say_error("Error parsing #{file}: #{e.message}")
|
94
|
+
next
|
95
|
+
rescue Spoom::Deadcode::IndexerError => e
|
96
|
+
say_error("Error indexing #{file}: #{e.message}")
|
97
|
+
next
|
98
|
+
end
|
99
|
+
|
100
|
+
if options[:show_defs]
|
101
|
+
$stderr.puts "\nDefinitions:"
|
102
|
+
index.definitions.each do |name, definitions|
|
103
|
+
$stderr.puts " #{blue(name)}"
|
104
|
+
definitions.each do |definition|
|
105
|
+
$stderr.puts " #{yellow(definition.kind.serialize)} #{gray(definition.location.to_s)}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
$stderr.puts
|
109
|
+
end
|
110
|
+
|
111
|
+
if options[:show_refs]
|
112
|
+
$stderr.puts "\nReferences:"
|
113
|
+
index.references.values.flatten.sort_by(&:name).each do |references|
|
114
|
+
name = references.name
|
115
|
+
kind = references.kind.serialize
|
116
|
+
loc = references.location.to_s
|
117
|
+
$stderr.puts " #{blue(name)} #{yellow(kind)} #{gray(loc)}"
|
118
|
+
end
|
119
|
+
$stderr.puts
|
120
|
+
end
|
121
|
+
|
122
|
+
definitions_count = index.definitions.size.to_s
|
123
|
+
references_count = index.references.size.to_s
|
124
|
+
$stderr.puts "Analyzing #{blue(definitions_count)} definitions against #{blue(references_count)} references..."
|
125
|
+
|
126
|
+
index.finalize!
|
127
|
+
dead = index.definitions.values.flatten.select(&:dead?)
|
128
|
+
|
129
|
+
if options[:sort] == "name"
|
130
|
+
dead.sort_by!(&:name)
|
131
|
+
else
|
132
|
+
dead.sort_by!(&:location)
|
133
|
+
end
|
134
|
+
|
135
|
+
if dead.empty?
|
136
|
+
$stderr.puts "\n#{green("No dead code found!")}"
|
137
|
+
else
|
138
|
+
$stderr.puts "\nCandidates:"
|
139
|
+
dead.each do |definition|
|
140
|
+
$stderr.puts " #{red(definition.full_name)} #{gray(definition.location.to_s)}"
|
141
|
+
end
|
142
|
+
$stderr.puts "\n"
|
143
|
+
$stderr.puts red(" Found #{dead.size} dead candidates")
|
144
|
+
|
145
|
+
exit(1)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
desc "remove LOCATION", "Remove dead code at LOCATION"
|
150
|
+
def remove(location_string)
|
151
|
+
location = Spoom::Deadcode::Location.from_string(location_string)
|
152
|
+
context = self.context
|
153
|
+
remover = Spoom::Deadcode::Remover.new(context)
|
154
|
+
|
155
|
+
new_source = remover.remove_location(nil, location)
|
156
|
+
context.write!("PATCH", new_source)
|
157
|
+
|
158
|
+
diff = context.exec("diff -u #{location.file} PATCH")
|
159
|
+
$stderr.puts T.must(diff.out.lines[2..-1]).join
|
160
|
+
context.remove!("PATCH")
|
161
|
+
|
162
|
+
context.write!(location.file, new_source)
|
163
|
+
rescue Spoom::Deadcode::Remover::Error => e
|
164
|
+
say_error("Can't remove code at #{location_string}: #{e.message}")
|
165
|
+
exit(1)
|
166
|
+
rescue Spoom::Deadcode::Location::LocationError => e
|
167
|
+
say_error(e.message)
|
168
|
+
exit(1)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
data/lib/spoom/cli/helper.rb
CHANGED
@@ -46,6 +46,26 @@ module Spoom
|
|
46
46
|
$stderr.flush
|
47
47
|
end
|
48
48
|
|
49
|
+
# Print `message` on `$stderr`
|
50
|
+
#
|
51
|
+
# The message is prefixed by a status (default: `Warning`).
|
52
|
+
sig do
|
53
|
+
params(
|
54
|
+
message: String,
|
55
|
+
status: T.nilable(String),
|
56
|
+
nl: T::Boolean,
|
57
|
+
).void
|
58
|
+
end
|
59
|
+
def say_warning(message, status: "Warning", nl: true)
|
60
|
+
buffer = StringIO.new
|
61
|
+
buffer << "#{yellow(status)}: " if status
|
62
|
+
buffer << highlight(message)
|
63
|
+
buffer << "\n" if nl && !message.end_with?("\n")
|
64
|
+
|
65
|
+
$stderr.print(buffer.string)
|
66
|
+
$stderr.flush
|
67
|
+
end
|
68
|
+
|
49
69
|
# Returns the context at `--path` (by default the current working directory)
|
50
70
|
sig { returns(Context) }
|
51
71
|
def context
|