spoom 1.0.3 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f6a3db37efef69beb451a63043e45e10e8c49cb6c86c774fdc8e01a18aee858
4
- data.tar.gz: de6e4f8e97f5802b3843ccde507510d4de081a98f4fdd3b7bf6da62d1b177dcb
3
+ metadata.gz: 866446fc75971d51c7a71d7ed713cf256f682ffbd0fabfaf97c95b601638876b
4
+ data.tar.gz: a38dd3b7859929349c2d84b4119e5f8d8d374c0cf5062adbb3904065a1d6f0f2
5
5
  SHA512:
6
- metadata.gz: 74189496b4e9a126ba649fa529f3061c03e334f01c715b571dc12920f97219ea79e6d7f25811d073fc6daa2fa6db04aeb12030fa119fefe94cb822964710e658
7
- data.tar.gz: bcefd877fc949636d850a660e389bd0f395ef3fb38b6eed178f2b09b0bc63685202dff5628ac6f39a54597471e4ea8004356971db9d578a0e07fdde986d05a8e
6
+ metadata.gz: 257a78cbdf439ee83e23a823ed39918ada7a1b66786967a77604e5dca2bb825aeb8af2f5fcda6c497686f29f9d0c7dba1d051060d984694f22c0064dcbd8c1a9
7
+ data.tar.gz: 4a66b832da23c6237d1dedc16735cce058306ce66327fd2e074d72a481d55412aa7dc8047f0fa25957e1369747478347b77ccf8cd7c85cdb286fcff6a564a412
data/Gemfile CHANGED
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  source "https://rubygems.org"
@@ -6,4 +7,7 @@ gemspec
6
7
 
7
8
  group(:development) do
8
9
  gem('rubocop-shopify', require: false)
10
+ gem('rubocop-sorbet', require: false)
11
+ gem('byebug')
12
+ gem('pry-byebug')
9
13
  end
data/README.md CHANGED
@@ -20,7 +20,261 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- ### Parsing Sorbet config
23
+ `spoom` provides both a CLI and an API to interact with Sorbet.
24
+
25
+ ### Generate a typing coverage report
26
+
27
+ Spoom can create a typing coverage report from Sorbet and Git data:
28
+
29
+ ![Coverage Report](docs/report.png)
30
+
31
+ After installing the `spoom` gem, run the `timeline` command to collect the history data:
32
+
33
+ ```
34
+ $ spoom coverage timeline --save
35
+ ```
36
+
37
+ Then create the HTML page with `report`:
38
+
39
+ ```
40
+ $ spoom coverage report
41
+ ```
42
+
43
+ Your report will be generated under `spoom_report.html`.
44
+
45
+ See all the [Typing Coverage](#typing-coverage) CLI commands for more details.
46
+
47
+ ### Command Line Interface
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
+ #### Errors sorting and filtering
68
+
69
+ List all typechecking errors sorted by location:
70
+
71
+ ```
72
+ $ spoom tc -s loc
73
+ ```
74
+
75
+ List all typechecking errors sorted by error code first:
76
+
77
+ ```
78
+ $ spoom tc -s code
79
+ ```
80
+
81
+ List only typechecking errors from a specific error code:
82
+
83
+ ```
84
+ $ spoom tc -c 7004
85
+ ```
86
+
87
+ List only the first 10 typechecking errors
88
+
89
+ ```
90
+ $ spoom tc -l 10
91
+ ```
92
+
93
+ These options can be combined:
94
+
95
+ ```
96
+ $ spoom tc -s -c 7004 -l 10
97
+ ```
98
+
99
+ Remove duplicated error lines:
100
+
101
+ ```
102
+ $ spoom tc -u
103
+ ```
104
+
105
+ Format each error line:
106
+
107
+ ```
108
+ $ spoom tc -f '%C - %F:%L: %M'
109
+ ```
110
+
111
+ Where:
112
+
113
+ * `%C` is the error code
114
+ * `%F` is the file the error is from
115
+ * `%L` is the line the error is from
116
+ * `%M` is the error message
117
+
118
+ Hide the `Errors: X` at the end of the list:
119
+
120
+ ```
121
+ $ spoom tc --no-count
122
+ ```
123
+
124
+ #### Typing coverage
125
+
126
+ Show metrics about the project contents and the typing coverage:
127
+
128
+ ```
129
+ $ spoom coverage
130
+ ```
131
+
132
+ Save coverage data under `spoom_data/`:
133
+
134
+ ```
135
+ $ spoom coverage --save
136
+ ```
137
+
138
+ Save coverage data under a specific directory:
139
+
140
+ ```
141
+ $ spoom coverage --save my_data/
142
+ ```
143
+
144
+ Show typing coverage evolution based on the commits history:
145
+
146
+ ```
147
+ $ spoom coverage timeline
148
+ ```
149
+
150
+ Show typing coverage evolution based on the commits history between specific dates:
151
+
152
+ ```
153
+ $ spoom coverage timeline --from YYYY-MM-DD --to YYYY-MM-DD
154
+ ```
155
+
156
+ Save the typing coverage evolution as JSON under `spoom_data/`:
157
+
158
+ ```
159
+ $ spoom coverage timeline --save
160
+ ```
161
+
162
+ Save the typing coverage evolution as JSON in a specific directory:
163
+
164
+ ```
165
+ $ spoom coverage timeline --save my_data/
166
+ ```
167
+
168
+ Run `bundle install` for each commit of the timeline (may solve errors due to different Sorbet versions):
169
+
170
+ ```
171
+ $ spoom coverage timeline --bundle-install
172
+ ```
173
+
174
+ Generate an HTML typing coverage report:
175
+
176
+ ```
177
+ $ spoom coverage report
178
+ ```
179
+
180
+ Change the colors used for strictnesses (useful for colorblind folks):
181
+
182
+ ```
183
+ $ spoom coverage report \
184
+ --color-true "#648ffe" \
185
+ --color-false "#fe6002" \
186
+ --color-ignore "#feb000" \
187
+ --color-strict "#795ef0" \
188
+ --color-strong "#6444f1"
189
+ ```
190
+
191
+ Open the HTML typing coverage report:
192
+
193
+ ```
194
+ $ spoom coverage open
195
+ ```
196
+
197
+ #### Change the sigil used in files
198
+
199
+ Bump the strictness from all files currently at `typed: false` to `typed: true` where it does not create typechecking errors:
200
+
201
+ ```
202
+ $ spoom bump --from false --to true
203
+ ```
204
+
205
+ Bump the strictness from all files currently at `typed: false` to `typed: true` even if it creates typechecking errors:
206
+
207
+ ```
208
+ $ spoom bump --from false --to true -f
209
+ ```
210
+
211
+ Bump the strictness from a list of files (one file by line):
212
+
213
+ ```
214
+ $ spoom bump --from false --to true -o list.txt
215
+ ```
216
+
217
+ Check if files can be bumped without applying any change:
218
+
219
+ ```
220
+ $ spoom bump --from false --to true --dry
221
+ ```
222
+
223
+ Bump files using a custom instance of Sorbet:
224
+
225
+ ```
226
+ $ spoom bump --from false --to true --sorbet /path/to/sorbet/bin
227
+ ```
228
+
229
+ #### Interact with Sorbet LSP mode
230
+
231
+ **Experimental**
232
+
233
+ Find all definitions for `Foo`:
234
+
235
+ ```
236
+ $ spoom lsp find Foo
237
+ ```
238
+
239
+ List all symbols in a file:
240
+
241
+ ```
242
+ $ spoom lsp symbols <file.rb>
243
+ ```
244
+
245
+ List all definitions for a specific code location:
246
+
247
+ ```
248
+ $ spoom lsp defs <file.rb> <line> <column>
249
+ ```
250
+
251
+ List all references for a specific code location:
252
+
253
+ ```
254
+ $ spoom lsp refs <file.rb> <line> <column>
255
+ ```
256
+
257
+ Show hover information for a specific code location:
258
+
259
+ ```
260
+ $ spoom lsp hover <file.rb> <line> <column>
261
+ ```
262
+
263
+ Show signature information for a specific code location:
264
+
265
+ ```
266
+ $ spoom lsp sig <file.rb> <line> <column>
267
+ ```
268
+
269
+ Show type information for a specific code location:
270
+
271
+ ```
272
+ $ spoom lsp sig <file.rb> <line> <column>
273
+ ```
274
+
275
+ ### API
276
+
277
+ #### Parsing Sorbet config
24
278
 
25
279
  Parses a Sorbet config file:
26
280
 
@@ -41,6 +295,47 @@ puts config.paths # "a", "b"
41
295
  puts config.ignore # "c"
42
296
  ```
43
297
 
298
+ List all files typchecked by Sorbet:
299
+
300
+ ```ruby
301
+ config = Spoom::Sorbet::Config.parse_file("sorbet/config")
302
+ puts Spoom::Sorbet.srb_files(config)
303
+ ```
304
+
305
+ #### Parsing Sorbet metrics
306
+
307
+ Display metrics collected during typechecking:
308
+
309
+ ```ruby
310
+ puts Spoom::Sorbet.srb_metrics(capture_err: false)
311
+ ```
312
+
313
+ #### Interacting with LSP
314
+
315
+ Create an LSP client:
316
+
317
+ ```rb
318
+ client = Spoom::LSP::Client.new(
319
+ Spoom::Sorbet::BIN_PATH,
320
+ "--lsp",
321
+ "--enable-all-experimental-lsp-features",
322
+ "--disable-watchman",
323
+ )
324
+ client.open(".")
325
+ ```
326
+
327
+ Find all the symbols matching a string:
328
+
329
+ ```rb
330
+ puts client.symbols("Foo")
331
+ ```
332
+
333
+ Find all the symbols for a file:
334
+
335
+ ```rb
336
+ puts client.document_symbols("file://path/to/my/file.rb")
337
+ ```
338
+
44
339
  ## Development
45
340
 
46
341
  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.
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
  require "bundler/gem_tasks"
3
4
  require "rake/testtask"
@@ -5,6 +6,7 @@ require "rake/testtask"
5
6
  Rake::TestTask.new(:test) do |t|
6
7
  t.libs << "test"
7
8
  t.libs << "lib"
9
+ t.warning = false
8
10
  t.test_files = FileList["test/**/*_test.rb"]
9
11
  end
10
12
 
data/exe/spoom CHANGED
@@ -0,0 +1,7 @@
1
+ #! /usr/bin/env ruby
2
+ # typed: true
3
+ # frozen_string_literal: true
4
+
5
+ require_relative "../lib/spoom"
6
+
7
+ Spoom::Cli::Main.start(ARGV)
@@ -1,6 +1,31 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require "sorbet-runtime"
4
5
 
6
+ module Spoom
7
+ extend T::Sig
8
+
9
+ SPOOM_PATH = (Pathname.new(__FILE__) / ".." / "..").to_s
10
+
11
+ class Error < StandardError; end
12
+
13
+ sig do
14
+ params(
15
+ cmd: String,
16
+ arg: String,
17
+ path: String,
18
+ capture_err: T::Boolean
19
+ ).returns([String, T::Boolean])
20
+ end
21
+ def self.exec(cmd, *arg, path: '.', capture_err: false)
22
+ method = capture_err ? "popen2e" : "popen2"
23
+ Open3.send(method, [cmd, *arg].join(" "), chdir: path) do |_, o, t|
24
+ [o.read, T.cast(t.value, Process::Status).success?]
25
+ end
26
+ end
27
+ end
28
+
29
+ require "spoom/sorbet"
30
+ require "spoom/cli"
5
31
  require "spoom/version"
6
- require "spoom/sorbet/config"
@@ -0,0 +1,69 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require "thor"
5
+
6
+ require_relative 'cli/helper'
7
+
8
+ require_relative "cli/bump"
9
+ require_relative "cli/config"
10
+ require_relative "cli/lsp"
11
+ require_relative "cli/coverage"
12
+ require_relative "cli/run"
13
+
14
+ module Spoom
15
+ module Cli
16
+ class Main < Thor
17
+ extend T::Sig
18
+ include Helper
19
+
20
+ class_option :color, type: :boolean, default: true, desc: "Use colors"
21
+ class_option :path, type: :string, default: ".", aliases: :p, desc: "Run spoom in a specific path"
22
+
23
+ map T.unsafe(%w[--version -v] => :__print_version)
24
+
25
+ desc "bump", "Bump Sorbet sigils from `false` to `true` when no errors"
26
+ subcommand "bump", Spoom::Cli::Bump
27
+
28
+ desc "config", "Manage Sorbet config"
29
+ subcommand "config", Spoom::Cli::Config
30
+
31
+ desc "coverage", "Collect metrics related to Sorbet coverage"
32
+ subcommand "coverage", Spoom::Cli::Coverage
33
+
34
+ desc "lsp", "Send LSP requests to Sorbet"
35
+ subcommand "lsp", Spoom::Cli::LSP
36
+
37
+ desc "tc", "Run Sorbet and parses its output"
38
+ subcommand "tc", Spoom::Cli::Run
39
+
40
+ desc "files", "List all the files typechecked by Sorbet"
41
+ def files
42
+ in_sorbet_project!
43
+
44
+ path = exec_path
45
+ config = Spoom::Sorbet::Config.parse_file(sorbet_config)
46
+ files = Spoom::Sorbet.srb_files(config, path: path)
47
+
48
+ say("Files matching `#{sorbet_config}`:")
49
+ if files.empty?
50
+ say(" NONE")
51
+ else
52
+ tree = FileTree.new(files, strip_prefix: path)
53
+ tree.print(colors: options[:color], indent_level: 2)
54
+ end
55
+ end
56
+
57
+ desc "--version", "Show version"
58
+ def __print_version
59
+ puts "Spoom v#{Spoom::VERSION}"
60
+ end
61
+
62
+ # Utils
63
+
64
+ def self.exit_on_failure?
65
+ true
66
+ end
67
+ end
68
+ end
69
+ end