spoom 1.0.4 → 1.0.9

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -1
  3. data/README.md +296 -1
  4. data/Rakefile +1 -0
  5. data/lib/spoom.rb +21 -2
  6. data/lib/spoom/cli.rb +56 -10
  7. data/lib/spoom/cli/bump.rb +138 -0
  8. data/lib/spoom/cli/config.rb +51 -0
  9. data/lib/spoom/cli/coverage.rb +206 -0
  10. data/lib/spoom/cli/helper.rb +149 -0
  11. data/lib/spoom/cli/lsp.rb +165 -0
  12. data/lib/spoom/cli/run.rb +109 -0
  13. data/lib/spoom/coverage.rb +89 -0
  14. data/lib/spoom/coverage/d3.rb +110 -0
  15. data/lib/spoom/coverage/d3/base.rb +50 -0
  16. data/lib/spoom/coverage/d3/circle_map.rb +195 -0
  17. data/lib/spoom/coverage/d3/pie.rb +175 -0
  18. data/lib/spoom/coverage/d3/timeline.rb +486 -0
  19. data/lib/spoom/coverage/report.rb +308 -0
  20. data/lib/spoom/coverage/snapshot.rb +132 -0
  21. data/lib/spoom/file_tree.rb +196 -0
  22. data/lib/spoom/git.rb +98 -0
  23. data/lib/spoom/printer.rb +80 -0
  24. data/lib/spoom/sorbet.rb +99 -47
  25. data/lib/spoom/sorbet/config.rb +30 -0
  26. data/lib/spoom/sorbet/errors.rb +33 -15
  27. data/lib/spoom/sorbet/lsp.rb +2 -4
  28. data/lib/spoom/sorbet/lsp/structures.rb +108 -14
  29. data/lib/spoom/sorbet/metrics.rb +10 -79
  30. data/lib/spoom/sorbet/sigils.rb +98 -0
  31. data/lib/spoom/test_helpers/project.rb +112 -0
  32. data/lib/spoom/timeline.rb +53 -0
  33. data/lib/spoom/version.rb +2 -2
  34. data/templates/card.erb +8 -0
  35. data/templates/card_snapshot.erb +22 -0
  36. data/templates/page.erb +50 -0
  37. metadata +28 -11
  38. data/lib/spoom/cli/commands/base.rb +0 -36
  39. data/lib/spoom/cli/commands/config.rb +0 -67
  40. data/lib/spoom/cli/commands/lsp.rb +0 -156
  41. data/lib/spoom/cli/commands/run.rb +0 -92
  42. data/lib/spoom/cli/symbol_printer.rb +0 -71
  43. data/lib/spoom/config.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d851bf66dbfb8e1d316b27466fde8ee205e55e68b9b489c3f8f234c03e1763d2
4
- data.tar.gz: '068972f0ebb9393400dcbf68837be0a58114cc55560438fd329be3b54acfcaaf'
3
+ metadata.gz: 55531f68ca5416d234dc35cff63a0213a0f27ba0cf6fa840e183b90896661c3b
4
+ data.tar.gz: 2963d8788e5914ac38e00d30720d44a83691ef8c9165918cd2b7270b71775a3b
5
5
  SHA512:
6
- metadata.gz: 8315d9c7de9beaf2aa9a5d6963cde78ec6e9e7949659bac85a0ff719080755808fb5a854c2a03f6dcab8134c17bc8d90d145d53d32a3f1632d83a2c6a21ebfaa
7
- data.tar.gz: 88fee999fa79caf40dd776ce5253a1337a5acc2507653a2c09adfb3e4723b6a8a06033d34c8f299b3a7a663ef01c2fa4a8243d98fd9f104e9c77ad69f9836ff7
6
+ metadata.gz: 3b243083cf4ecae47f51bbfa6283e3272099c35ea28a7c471f731237eba01d5ce1f3634b9326ff3c19b7c36c58d38f97065e021e41070fd583efde13acfa2588
7
+ data.tar.gz: f0f2b0c272f46214a8d7bc21a9efc1e74f7646515a023a234612c96aaeb26c917c79a2db80169b275879c8da28cc57e49adf6e2f2a57c2f5e77abf0a018a6955
data/Gemfile CHANGED
@@ -8,6 +8,5 @@ gemspec
8
8
  group(:development) do
9
9
  gem('rubocop-shopify', require: false)
10
10
  gem('rubocop-sorbet', require: false)
11
- gem('byebug')
12
11
  gem('pry-byebug')
13
12
  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
@@ -6,6 +6,7 @@ require "rake/testtask"
6
6
  Rake::TestTask.new(:test) do |t|
7
7
  t.libs << "test"
8
8
  t.libs << "lib"
9
+ t.warning = false
9
10
  t.test_files = FileList["test/**/*_test.rb"]
10
11
  end
11
12
 
data/lib/spoom.rb CHANGED
@@ -1,13 +1,32 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "colorize"
4
5
  require "sorbet-runtime"
5
6
 
6
7
  module Spoom
8
+ extend T::Sig
9
+
10
+ SPOOM_PATH = (Pathname.new(__FILE__) / ".." / "..").to_s
11
+
7
12
  class Error < StandardError; end
13
+
14
+ sig do
15
+ params(
16
+ cmd: String,
17
+ arg: String,
18
+ path: String,
19
+ capture_err: T::Boolean
20
+ ).returns([String, T::Boolean])
21
+ end
22
+ def self.exec(cmd, *arg, path: '.', capture_err: false)
23
+ method = capture_err ? "popen2e" : "popen2"
24
+ Open3.send(method, [cmd, *arg].join(" "), chdir: path) do |_, o, t|
25
+ [o.read, T.cast(t.value, Process::Status).success?]
26
+ end
27
+ end
8
28
  end
9
29
 
10
- require "spoom/cli"
11
- require "spoom/config"
12
30
  require "spoom/sorbet"
31
+ require "spoom/cli"
13
32
  require "spoom/version"
data/lib/spoom/cli.rb CHANGED
@@ -3,25 +3,71 @@
3
3
 
4
4
  require "thor"
5
5
 
6
- require_relative "cli/commands/config"
7
- require_relative "cli/commands/lsp"
8
- require_relative "cli/commands/run"
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"
9
13
 
10
14
  module Spoom
11
15
  module Cli
12
16
  class Main < Thor
13
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
14
33
 
15
- class_option :no_color, desc: "Don't use colors", type: :boolean
34
+ desc "lsp", "Send LSP requests to Sorbet"
35
+ subcommand "lsp", Spoom::Cli::LSP
16
36
 
17
- desc "config", "manage Sorbet config"
18
- subcommand "config", Spoom::Cli::Commands::Config
37
+ desc "tc", "Run Sorbet and parses its output"
38
+ subcommand "tc", Spoom::Cli::Run
19
39
 
20
- desc "lsp", "send LSP requests to Sorbet"
21
- subcommand "lsp", Spoom::Cli::Commands::LSP
40
+ desc "files", "List all the files typechecked by Sorbet"
41
+ option :tree, type: :boolean, default: true, desc: "Display list as an indented tree"
42
+ option :rbi, type: :boolean, default: true, desc: "Show RBI files"
43
+ def files
44
+ in_sorbet_project!
22
45
 
23
- desc "tc", "run Sorbet and parses its output"
24
- subcommand "tc", Spoom::Cli::Commands::Run
46
+ path = exec_path
47
+ config = sorbet_config
48
+ files = Spoom::Sorbet.srb_files(config, path: path)
49
+
50
+ unless options[:rbi]
51
+ files = files.reject { |file| file.end_with?(".rbi") }
52
+ end
53
+
54
+ if files.empty?
55
+ say_error("No file matching `#{sorbet_config_file}`")
56
+ exit(1)
57
+ end
58
+
59
+ if options[:tree]
60
+ tree = FileTree.new(files, strip_prefix: path)
61
+ tree.print(colors: options[:color], indent_level: 0)
62
+ else
63
+ puts files
64
+ end
65
+ end
66
+
67
+ desc "--version", "Show version"
68
+ def __print_version
69
+ puts "Spoom v#{Spoom::VERSION}"
70
+ end
25
71
 
26
72
  # Utils
27
73