spoom 1.0.4 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
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