spoom 1.0.0 → 1.0.5

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: 120fef71dbc1eb301d6425be852e9bd96554114865f5350c0bb5553fe16fbdaf
4
- data.tar.gz: a50b10a8f28d7a96c9167ccf457116b61ef300f06d9dcce44801528355fc22cf
3
+ metadata.gz: 7a5f19185a1beba98f75c9c96b08c06400c9917c0d85734f1dbf9c9d77e3fa74
4
+ data.tar.gz: 53f4b8b10f81b19588f58d57c93349721230836e3b98524b52c46a78f4682365
5
5
  SHA512:
6
- metadata.gz: 4c306c8d3bbe04aa4874fc95d826989d226a5b20d3548048c0e485ae27678e32f79e63c0a7e98e3b743e116622a2161e75f04c0ca75214c1c78ece75977f6ce4
7
- data.tar.gz: d5745d54bfc4caf3daf584231647dc299ce572888555304c8f4334aac495fec0d61457e60281a2c0e4992c4ef19d1b923e17151f006a4f436c7cddbf366b733c
6
+ metadata.gz: aff5a2bc4b3bd01c815ad0d00e76fcc700728ec659135645dce259db72dc97cf8ea2d339827d979bf9f225637b7d23f2ea09d13dd02786229fe5c42caf88886e
7
+ data.tar.gz: b2760f8f58a7f3cbfd90d59e16f5bb9b76356f13fc3f38a606758652f53caf72004024128e4195451ca32f30c9d03c6bdb553a6a7aea2893c7f0e6a2e6ec2528
data/Gemfile CHANGED
@@ -1,7 +1,13 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  source "https://rubygems.org"
4
5
 
5
6
  gemspec
6
7
 
7
- gem 'rubocop-shopify', require: false
8
+ group(:development) do
9
+ gem('rubocop-shopify', require: false)
10
+ gem('rubocop-sorbet', require: false)
11
+ gem('byebug')
12
+ gem('pry-byebug')
13
+ end
data/README.md CHANGED
@@ -20,7 +20,218 @@ 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
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
+ #### Typing coverage
100
+
101
+ Show metrics about the project contents and the typing coverage:
102
+
103
+ ```
104
+ $ spoom coverage
105
+ ```
106
+
107
+ Save coverage data under `spoom_data/`:
108
+
109
+ ```
110
+ $ spoom coverage --save
111
+ ```
112
+
113
+ Save coverage data under a specific directory:
114
+
115
+ ```
116
+ $ spoom coverage --save my_data/
117
+ ```
118
+
119
+ Show typing coverage evolution based on the commits history:
120
+
121
+ ```
122
+ $ spoom coverage timeline
123
+ ```
124
+
125
+ Show typing coverage evolution based on the commits history between specific dates:
126
+
127
+ ```
128
+ $ spoom coverage timeline --from YYYY-MM-DD --to YYYY-MM-DD
129
+ ```
130
+
131
+ Save the typing coverage evolution as JSON under `spoom_data/`:
132
+
133
+ ```
134
+ $ spoom coverage timeline --save
135
+ ```
136
+
137
+ Save the typing coverage evolution as JSON in a specific directory:
138
+
139
+ ```
140
+ $ spoom coverage timeline --save my_data/
141
+ ```
142
+
143
+ Run `bundle install` for each commit of the timeline (may solve errors due to different Sorbet versions):
144
+
145
+ ```
146
+ $ spoom coverage timeline --bundle-install
147
+ ```
148
+
149
+ Generate an HTML typing coverage report:
150
+
151
+ ```
152
+ $ spoom coverage report
153
+ ```
154
+
155
+ Change the colors used for strictnesses (useful for colorblind folks):
156
+
157
+ ```
158
+ $ spoom coverage report \
159
+ --color-true "#648ffe" \
160
+ --color-false "#fe6002" \
161
+ --color-ignore "#feb000" \
162
+ --color-strict "#795ef0" \
163
+ --color-strong "#6444f1"
164
+ ```
165
+
166
+ Open the HTML typing coverage report:
167
+
168
+ ```
169
+ $ spoom coverage open
170
+ ```
171
+
172
+ #### Change the sigil used in files
173
+
174
+ Bump the strictness from all files currently at `typed: false` to `typed: true` where it does not create typechecking errors:
175
+
176
+ ```
177
+ $ spoom bump --from false --to true
178
+ ```
179
+
180
+ Bump the strictness from all files currently at `typed: false` to `typed: true` even if it creates typechecking errors:
181
+
182
+ ```
183
+ $ spoom bump --from false --to true -f
184
+ ```
185
+
186
+ #### Interact with Sorbet LSP mode
187
+
188
+ **Experimental**
189
+
190
+ Find all definitions for `Foo`:
191
+
192
+ ```
193
+ $ spoom lsp find Foo
194
+ ```
195
+
196
+ List all symbols in a file:
197
+
198
+ ```
199
+ $ spoom lsp symbols <file.rb>
200
+ ```
201
+
202
+ List all definitions for a specific code location:
203
+
204
+ ```
205
+ $ spoom lsp defs <file.rb> <line> <column>
206
+ ```
207
+
208
+ List all references for a specific code location:
209
+
210
+ ```
211
+ $ spoom lsp refs <file.rb> <line> <column>
212
+ ```
213
+
214
+ Show hover information for a specific code location:
215
+
216
+ ```
217
+ $ spoom lsp hover <file.rb> <line> <column>
218
+ ```
219
+
220
+ Show signature information for a specific code location:
221
+
222
+ ```
223
+ $ spoom lsp sig <file.rb> <line> <column>
224
+ ```
225
+
226
+ Show type information for a specific code location:
227
+
228
+ ```
229
+ $ spoom lsp sig <file.rb> <line> <column>
230
+ ```
231
+
232
+ ### API
233
+
234
+ #### Parsing Sorbet config
24
235
 
25
236
  Parses a Sorbet config file:
26
237
 
@@ -41,6 +252,47 @@ puts config.paths # "a", "b"
41
252
  puts config.ignore # "c"
42
253
  ```
43
254
 
255
+ List all files typchecked by Sorbet:
256
+
257
+ ```ruby
258
+ config = Spoom::Sorbet::Config.parse_file("sorbet/config")
259
+ puts Spoom::Sorbet.srb_files(config)
260
+ ```
261
+
262
+ #### Parsing Sorbet metrics
263
+
264
+ Display metrics collected during typechecking:
265
+
266
+ ```ruby
267
+ puts Spoom::Sorbet.srb_metrics(capture_err: false)
268
+ ```
269
+
270
+ #### Interacting with LSP
271
+
272
+ Create an LSP client:
273
+
274
+ ```rb
275
+ client = Spoom::LSP::Client.new(
276
+ Spoom::Config::SORBET_PATH,
277
+ "--lsp",
278
+ "--enable-all-experimental-lsp-features",
279
+ "--disable-watchman",
280
+ )
281
+ client.open(".")
282
+ ```
283
+
284
+ Find all the symbols matching a string:
285
+
286
+ ```rb
287
+ puts client.symbols("Foo")
288
+ ```
289
+
290
+ Find all the symbols for a file:
291
+
292
+ ```rb
293
+ puts client.document_symbols("file://path/to/my/file.rb")
294
+ ```
295
+
44
296
  ## Development
45
297
 
46
298
  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,14 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require "sorbet-runtime"
4
5
 
6
+ module Spoom
7
+ class Error < StandardError; end
8
+ end
9
+
10
+ require "spoom/config"
11
+
12
+ require "spoom/sorbet"
13
+ require "spoom/cli"
5
14
  require "spoom/version"
6
- require "spoom/sorbet/config"
@@ -0,0 +1,68 @@
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, desc: "Use colors", type: :boolean, default: true
21
+ class_option :path, desc: "Run spoom in a specific path", type: :string, default: ".", aliases: :p
22
+ map T.unsafe(%w[--version -v] => :__print_version)
23
+
24
+ desc "bump", "bump Sorbet sigils from `false` to `true` when no errors"
25
+ subcommand "bump", Spoom::Cli::Bump
26
+
27
+ desc "config", "manage Sorbet config"
28
+ subcommand "config", Spoom::Cli::Config
29
+
30
+ desc "coverage", "collect metrics related to Sorbet coverage"
31
+ subcommand "coverage", Spoom::Cli::Coverage
32
+
33
+ desc "lsp", "send LSP requests to Sorbet"
34
+ subcommand "lsp", Spoom::Cli::LSP
35
+
36
+ desc "tc", "run Sorbet and parses its output"
37
+ subcommand "tc", Spoom::Cli::Run
38
+
39
+ desc "files", "list all the files typechecked by Sorbet"
40
+ def files
41
+ in_sorbet_project!
42
+
43
+ path = exec_path
44
+ config = Spoom::Sorbet::Config.parse_file(sorbet_config)
45
+ files = Spoom::Sorbet.srb_files(config, path: path)
46
+
47
+ say("Files matching `#{sorbet_config}`:")
48
+ if files.empty?
49
+ say(" NONE")
50
+ else
51
+ tree = FileTree.new(files, strip_prefix: path)
52
+ tree.print(colors: options[:color], indent_level: 2)
53
+ end
54
+ end
55
+
56
+ desc "--version", "show version"
57
+ def __print_version
58
+ puts "Spoom v#{Spoom::VERSION}"
59
+ end
60
+
61
+ # Utils
62
+
63
+ def self.exit_on_failure?
64
+ true
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,59 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require 'find'
5
+ require 'open3'
6
+
7
+ module Spoom
8
+ module Cli
9
+ class Bump < Thor
10
+ extend T::Sig
11
+ include Helper
12
+
13
+ default_task :bump
14
+
15
+ desc "bump DIRECTORY", "change Sorbet sigils from one strictness to another when no errors"
16
+ option :from, type: :string, default: Spoom::Sorbet::Sigils::STRICTNESS_FALSE
17
+ option :to, type: :string, default: Spoom::Sorbet::Sigils::STRICTNESS_TRUE
18
+ option :force, desc: "change strictness without type checking", type: :boolean, default: false, aliases: :f
19
+ sig { params(directory: String).void }
20
+ def bump(directory = ".")
21
+ from = options[:from]
22
+ to = options[:to]
23
+ force = options[:force]
24
+
25
+ unless Sorbet::Sigils.valid_strictness?(from)
26
+ say_error("Invalid strictness #{from} for option --from")
27
+ exit(1)
28
+ end
29
+
30
+ unless Sorbet::Sigils.valid_strictness?(to)
31
+ say_error("Invalid strictness #{to} for option --to")
32
+ exit(1)
33
+ end
34
+
35
+ files_to_bump = Sorbet::Sigils.files_with_sigil_strictness(directory, from)
36
+
37
+ Sorbet::Sigils.change_sigil_in_files(files_to_bump, to)
38
+
39
+ return [] if force
40
+
41
+ output, no_errors = Sorbet.srb_tc(path: File.expand_path(directory), capture_err: true)
42
+
43
+ return [] if no_errors
44
+
45
+ errors = Sorbet::Errors::Parser.parse_string(output)
46
+
47
+ files_with_errors = errors.map do |err|
48
+ path = err.file
49
+ File.join(directory, path) if path && File.file?(path)
50
+ end.compact.uniq
51
+
52
+ Sorbet::Sigils.change_sigil_in_files(files_with_errors, from)
53
+ end
54
+
55
+ no_commands do
56
+ end
57
+ end
58
+ end
59
+ end