spoom 1.0.3 → 1.0.8

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: 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