spoom 1.0.8 → 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.
- checksums.yaml +4 -4
- data/Gemfile +0 -1
- data/lib/spoom.rb +1 -0
- data/lib/spoom/cli.rb +15 -5
- data/lib/spoom/cli/bump.rb +34 -14
- data/lib/spoom/cli/config.rb +2 -2
- data/lib/spoom/cli/coverage.rb +27 -23
- data/lib/spoom/cli/helper.rb +84 -10
- data/lib/spoom/cli/lsp.rb +10 -10
- data/lib/spoom/cli/run.rb +6 -6
- data/lib/spoom/printer.rb +0 -1
- data/lib/spoom/sorbet.rb +1 -0
- data/lib/spoom/test_helpers/project.rb +9 -0
- data/lib/spoom/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55531f68ca5416d234dc35cff63a0213a0f27ba0cf6fa840e183b90896661c3b
|
4
|
+
data.tar.gz: 2963d8788e5914ac38e00d30720d44a83691ef8c9165918cd2b7270b71775a3b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b243083cf4ecae47f51bbfa6283e3272099c35ea28a7c471f731237eba01d5ce1f3634b9326ff3c19b7c36c58d38f97065e021e41070fd583efde13acfa2588
|
7
|
+
data.tar.gz: f0f2b0c272f46214a8d7bc21a9efc1e74f7646515a023a234612c96aaeb26c917c79a2db80169b275879c8da28cc57e49adf6e2f2a57c2f5e77abf0a018a6955
|
data/Gemfile
CHANGED
data/lib/spoom.rb
CHANGED
data/lib/spoom/cli.rb
CHANGED
@@ -38,19 +38,29 @@ module Spoom
|
|
38
38
|
subcommand "tc", Spoom::Cli::Run
|
39
39
|
|
40
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"
|
41
43
|
def files
|
42
44
|
in_sorbet_project!
|
43
45
|
|
44
46
|
path = exec_path
|
45
|
-
config =
|
47
|
+
config = sorbet_config
|
46
48
|
files = Spoom::Sorbet.srb_files(config, path: path)
|
47
49
|
|
48
|
-
|
50
|
+
unless options[:rbi]
|
51
|
+
files = files.reject { |file| file.end_with?(".rbi") }
|
52
|
+
end
|
53
|
+
|
49
54
|
if files.empty?
|
50
|
-
|
51
|
-
|
55
|
+
say_error("No file matching `#{sorbet_config_file}`")
|
56
|
+
exit(1)
|
57
|
+
end
|
58
|
+
|
59
|
+
if options[:tree]
|
52
60
|
tree = FileTree.new(files, strip_prefix: path)
|
53
|
-
tree.print(colors: options[:color], indent_level:
|
61
|
+
tree.print(colors: options[:color], indent_level: 0)
|
62
|
+
else
|
63
|
+
puts files
|
54
64
|
end
|
55
65
|
end
|
56
66
|
|
data/lib/spoom/cli/bump.rb
CHANGED
@@ -24,6 +24,8 @@ module Spoom
|
|
24
24
|
desc: "Only display what would happen, do not actually change sigils"
|
25
25
|
option :only, type: :string, default: nil, aliases: :o,
|
26
26
|
desc: "Only change specified list (one file by line)"
|
27
|
+
option :suggest_bump_command, type: :string,
|
28
|
+
desc: "Command to suggest if files can be bumped"
|
27
29
|
sig { params(directory: String).void }
|
28
30
|
def bump(directory = ".")
|
29
31
|
in_sorbet_project!
|
@@ -33,35 +35,43 @@ module Spoom
|
|
33
35
|
force = options[:force]
|
34
36
|
dry = options[:dry]
|
35
37
|
only = options[:only]
|
38
|
+
cmd = options[:suggest_bump_command]
|
36
39
|
exec_path = File.expand_path(self.exec_path)
|
37
40
|
|
38
41
|
unless Sorbet::Sigils.valid_strictness?(from)
|
39
|
-
say_error("Invalid strictness
|
42
|
+
say_error("Invalid strictness `#{from}` for option `--from`")
|
40
43
|
exit(1)
|
41
44
|
end
|
42
45
|
|
43
46
|
unless Sorbet::Sigils.valid_strictness?(to)
|
44
|
-
say_error("Invalid strictness
|
47
|
+
say_error("Invalid strictness `#{to}` for option `--to`")
|
45
48
|
exit(1)
|
46
49
|
end
|
47
50
|
|
51
|
+
say("Checking files...")
|
52
|
+
|
48
53
|
directory = File.expand_path(directory)
|
49
54
|
files_to_bump = Sorbet::Sigils.files_with_sigil_strictness(directory, from)
|
50
55
|
|
56
|
+
files_from_config = config_files(path: exec_path)
|
57
|
+
files_to_bump.select! { |file| files_from_config.include?(file) }
|
58
|
+
|
51
59
|
if only
|
52
60
|
list = File.read(only).lines.map { |file| File.expand_path(file.strip) }
|
53
61
|
files_to_bump.select! { |file| list.include?(File.expand_path(file)) }
|
54
62
|
end
|
55
63
|
|
64
|
+
say("\n")
|
65
|
+
|
56
66
|
if files_to_bump.empty?
|
57
|
-
|
67
|
+
say("No file to bump from `#{from}` to `#{to}`")
|
58
68
|
exit(0)
|
59
69
|
end
|
60
70
|
|
61
71
|
Sorbet::Sigils.change_sigil_in_files(files_to_bump, to)
|
62
72
|
|
63
73
|
if force
|
64
|
-
print_changes(files_to_bump, from: from, to: to, dry: dry, path: exec_path)
|
74
|
+
print_changes(files_to_bump, command: cmd, from: from, to: to, dry: dry, path: exec_path)
|
65
75
|
undo_changes(files_to_bump, from) if dry
|
66
76
|
exit(files_to_bump.empty?)
|
67
77
|
end
|
@@ -69,7 +79,7 @@ module Spoom
|
|
69
79
|
output, no_errors = Sorbet.srb_tc(path: exec_path, capture_err: true, sorbet_bin: options[:sorbet])
|
70
80
|
|
71
81
|
if no_errors
|
72
|
-
print_changes(files_to_bump, from: from, to: to, dry: dry, path: exec_path)
|
82
|
+
print_changes(files_to_bump, command: cmd, from: from, to: to, dry: dry, path: exec_path)
|
73
83
|
undo_changes(files_to_bump, from) if dry
|
74
84
|
exit(files_to_bump.empty?)
|
75
85
|
end
|
@@ -86,32 +96,42 @@ module Spoom
|
|
86
96
|
undo_changes(files_with_errors, from)
|
87
97
|
|
88
98
|
files_changed = files_to_bump - files_with_errors
|
89
|
-
print_changes(files_changed, from: from, to: to, dry: dry, path: exec_path)
|
99
|
+
print_changes(files_changed, command: cmd, from: from, to: to, dry: dry, path: exec_path)
|
90
100
|
undo_changes(files_to_bump, from) if dry
|
91
101
|
exit(files_changed.empty?)
|
92
102
|
end
|
93
103
|
|
94
104
|
no_commands do
|
95
|
-
def print_changes(files, from: "false", to: "true", dry: false, path: File.expand_path("."))
|
105
|
+
def print_changes(files, command:, from: "false", to: "true", dry: false, path: File.expand_path("."))
|
96
106
|
if files.empty?
|
97
|
-
|
107
|
+
say("No file to bump from `#{from}` to `#{to}`")
|
98
108
|
return
|
99
109
|
end
|
100
|
-
|
101
|
-
|
102
|
-
|
110
|
+
message = StringIO.new
|
111
|
+
message << (dry ? "Can bump" : "Bumped")
|
112
|
+
message << " `#{files.size}` file#{'s' if files.size > 1}"
|
113
|
+
message << " from `#{from}` to `#{to}`:"
|
114
|
+
say(message.string)
|
103
115
|
files.each do |file|
|
104
116
|
file_path = Pathname.new(file).relative_path_from(path)
|
105
|
-
|
117
|
+
say(" + #{file_path}")
|
106
118
|
end
|
107
|
-
if dry
|
108
|
-
|
119
|
+
if dry && command
|
120
|
+
say("\nRun `#{command}` to bump them")
|
121
|
+
elsif dry
|
122
|
+
say("\nRun `spoom bump --from #{from} --to #{to}` to bump them")
|
109
123
|
end
|
110
124
|
end
|
111
125
|
|
112
126
|
def undo_changes(files, from_strictness)
|
113
127
|
Sorbet::Sigils.change_sigil_in_files(files, from_strictness)
|
114
128
|
end
|
129
|
+
|
130
|
+
def config_files(path: ".")
|
131
|
+
config = sorbet_config
|
132
|
+
files = Sorbet.srb_files(config, path: path)
|
133
|
+
files.map { |file| File.expand_path(file) }
|
134
|
+
end
|
115
135
|
end
|
116
136
|
end
|
117
137
|
end
|
data/lib/spoom/cli/config.rb
CHANGED
@@ -14,9 +14,9 @@ module Spoom
|
|
14
14
|
desc "show", "Show Sorbet config"
|
15
15
|
def show
|
16
16
|
in_sorbet_project!
|
17
|
-
config =
|
17
|
+
config = sorbet_config
|
18
18
|
|
19
|
-
say("Found Sorbet config at `#{
|
19
|
+
say("Found Sorbet config at `#{sorbet_config_file}`.")
|
20
20
|
|
21
21
|
say("\nPaths typechecked:")
|
22
22
|
if config.paths.empty?
|
data/lib/spoom/cli/coverage.rb
CHANGED
@@ -30,7 +30,7 @@ module Spoom
|
|
30
30
|
FileUtils.mkdir_p(save_dir)
|
31
31
|
file = "#{save_dir}/#{snapshot.commit_sha || snapshot.timestamp}.json"
|
32
32
|
File.write(file, snapshot.to_json)
|
33
|
-
|
33
|
+
say("\nSnapshot data saved under `#{file}`")
|
34
34
|
end
|
35
35
|
|
36
36
|
desc "timeline", "Replay a project and collect metrics"
|
@@ -47,14 +47,18 @@ module Spoom
|
|
47
47
|
sha_before = Spoom::Git.last_commit(path: path)
|
48
48
|
unless sha_before
|
49
49
|
say_error("Not in a git repository")
|
50
|
-
|
50
|
+
say_error("\nSpoom needs to checkout into your previous commits to build the timeline.", status: nil)
|
51
51
|
exit(1)
|
52
52
|
end
|
53
53
|
|
54
54
|
unless Spoom::Git.workdir_clean?(path: path)
|
55
55
|
say_error("Uncommited changes")
|
56
|
-
|
57
|
-
|
56
|
+
say_error(<<~ERR, status: nil)
|
57
|
+
|
58
|
+
Spoom needs to checkout into your previous commits to build the timeline."
|
59
|
+
|
60
|
+
Please `git commit` or `git stash` your changes then try again
|
61
|
+
ERR
|
58
62
|
exit(1)
|
59
63
|
end
|
60
64
|
|
@@ -74,13 +78,13 @@ module Spoom
|
|
74
78
|
ticks = timeline.ticks
|
75
79
|
|
76
80
|
if ticks.empty?
|
77
|
-
say_error("No commits to replay, try different
|
81
|
+
say_error("No commits to replay, try different `--from` and `--to` options")
|
78
82
|
exit(1)
|
79
83
|
end
|
80
84
|
|
81
85
|
ticks.each_with_index do |sha, i|
|
82
86
|
date = Spoom::Git.commit_time(sha, path: path)
|
83
|
-
|
87
|
+
say("Analyzing commit `#{sha}` - #{date&.strftime('%F')} (#{i + 1} / #{ticks.size})")
|
84
88
|
|
85
89
|
Spoom::Git.checkout(sha, path: path)
|
86
90
|
|
@@ -96,12 +100,12 @@ module Spoom
|
|
96
100
|
next unless snapshot
|
97
101
|
|
98
102
|
snapshot.print(indent_level: 2)
|
99
|
-
|
103
|
+
say("\n")
|
100
104
|
|
101
105
|
next unless save_dir
|
102
106
|
file = "#{save_dir}/#{sha}.json"
|
103
107
|
File.write(file, snapshot.to_json)
|
104
|
-
|
108
|
+
say(" Snapshot data saved under `#{file}`\n\n")
|
105
109
|
end
|
106
110
|
Spoom::Git.checkout(sha_before, path: path)
|
107
111
|
end
|
@@ -146,20 +150,20 @@ module Spoom
|
|
146
150
|
report = Spoom::Coverage.report(snapshots, palette: palette, path: exec_path)
|
147
151
|
file = options[:file]
|
148
152
|
File.write(file, report.html)
|
149
|
-
|
150
|
-
|
153
|
+
say("Report generated under `#{file}`")
|
154
|
+
say("\nUse `spoom coverage open` to open it.")
|
151
155
|
end
|
152
156
|
|
153
157
|
desc "open", "Open the typing coverage report"
|
154
158
|
def open(file = "spoom_report.html")
|
155
159
|
unless File.exist?(file)
|
156
|
-
say_error("No report file to open
|
157
|
-
|
160
|
+
say_error("No report file to open `#{file}`")
|
161
|
+
say_error(<<~ERR, status: nil)
|
158
162
|
|
159
|
-
If you already generated a report under another name use #{
|
163
|
+
If you already generated a report under another name use #{blue('spoom coverage open PATH')}.
|
160
164
|
|
161
|
-
To generate a report run #{
|
162
|
-
|
165
|
+
To generate a report run #{blue('spoom coverage report')}.
|
166
|
+
ERR
|
163
167
|
exit(1)
|
164
168
|
end
|
165
169
|
|
@@ -171,7 +175,7 @@ module Spoom
|
|
171
175
|
return nil unless string
|
172
176
|
Time.parse(string)
|
173
177
|
rescue ArgumentError
|
174
|
-
say_error("Invalid date `#{string}` for option
|
178
|
+
say_error("Invalid date `#{string}` for option `#{option}` (expected format `YYYY-MM-DD`)")
|
175
179
|
exit(1)
|
176
180
|
end
|
177
181
|
|
@@ -180,21 +184,21 @@ module Spoom
|
|
180
184
|
opts[:chdir] = path
|
181
185
|
out, status = Open3.capture2e("bundle install", opts)
|
182
186
|
unless status.success?
|
183
|
-
say_error("Can't run `bundle install` for commit
|
184
|
-
|
187
|
+
say_error("Can't run `bundle install` for commit `#{sha}`. Skipping snapshot")
|
188
|
+
say_error(out, status: nil)
|
185
189
|
return false
|
186
190
|
end
|
187
191
|
true
|
188
192
|
end
|
189
193
|
|
190
194
|
def message_no_data(file)
|
191
|
-
say_error("No snapshot files found in
|
192
|
-
|
195
|
+
say_error("No snapshot files found in `#{file}`")
|
196
|
+
say_error(<<~ERR, status: nil)
|
193
197
|
|
194
|
-
If you already generated snapshot files under another directory use #{
|
198
|
+
If you already generated snapshot files under another directory use #{blue('spoom coverage report PATH')}.
|
195
199
|
|
196
|
-
To generate snapshot files run #{
|
197
|
-
|
200
|
+
To generate snapshot files run #{blue('spoom coverage timeline --save-dir spoom_data')}.
|
201
|
+
ERR
|
198
202
|
end
|
199
203
|
end
|
200
204
|
end
|
data/lib/spoom/cli/helper.rb
CHANGED
@@ -11,16 +11,32 @@ module Spoom
|
|
11
11
|
extend T::Sig
|
12
12
|
include Thor::Shell
|
13
13
|
|
14
|
+
# Print `message` on `$stdout`
|
15
|
+
sig { params(message: String).void }
|
16
|
+
def say(message)
|
17
|
+
buffer = StringIO.new
|
18
|
+
buffer << highlight(message)
|
19
|
+
buffer << "\n" unless message.end_with?("\n")
|
20
|
+
|
21
|
+
$stdout.print(buffer.string)
|
22
|
+
$stdout.flush
|
23
|
+
end
|
24
|
+
|
14
25
|
# Print `message` on `$stderr`
|
15
26
|
#
|
16
27
|
# The message is prefixed by a status (default: `Error`).
|
17
|
-
sig
|
18
|
-
|
19
|
-
|
20
|
-
|
28
|
+
sig do
|
29
|
+
params(
|
30
|
+
message: String,
|
31
|
+
status: T.nilable(String),
|
32
|
+
nl: T::Boolean
|
33
|
+
).void
|
34
|
+
end
|
35
|
+
def say_error(message, status: "Error", nl: true)
|
21
36
|
buffer = StringIO.new
|
22
|
-
buffer << "#{status}:
|
23
|
-
buffer <<
|
37
|
+
buffer << "#{red(status)}: " if status
|
38
|
+
buffer << highlight(message)
|
39
|
+
buffer << "\n" if nl && !message.end_with?("\n")
|
24
40
|
|
25
41
|
$stderr.print(buffer.string)
|
26
42
|
$stderr.flush
|
@@ -29,7 +45,7 @@ module Spoom
|
|
29
45
|
# Is `spoom` ran inside a project with a `sorbet/config` file?
|
30
46
|
sig { returns(T::Boolean) }
|
31
47
|
def in_sorbet_project?
|
32
|
-
File.file?(
|
48
|
+
File.file?(sorbet_config_file)
|
33
49
|
end
|
34
50
|
|
35
51
|
# Enforce that `spoom` is ran inside a project with a `sorbet/config` file
|
@@ -39,9 +55,9 @@ module Spoom
|
|
39
55
|
def in_sorbet_project!
|
40
56
|
unless in_sorbet_project?
|
41
57
|
say_error(
|
42
|
-
"not in a Sorbet project (
|
58
|
+
"not in a Sorbet project (`#{sorbet_config_file}` not found)\n\n" \
|
43
59
|
"When running spoom from another path than the project's root, " \
|
44
|
-
"use
|
60
|
+
"use `--path PATH` to specify the path to the root."
|
45
61
|
)
|
46
62
|
Kernel.exit(1)
|
47
63
|
end
|
@@ -54,22 +70,80 @@ module Spoom
|
|
54
70
|
end
|
55
71
|
|
56
72
|
sig { returns(String) }
|
57
|
-
def
|
73
|
+
def sorbet_config_file
|
58
74
|
Pathname.new("#{exec_path}/#{Spoom::Sorbet::CONFIG_PATH}").cleanpath.to_s
|
59
75
|
end
|
60
76
|
|
77
|
+
sig { returns(Sorbet::Config) }
|
78
|
+
def sorbet_config
|
79
|
+
Sorbet::Config.parse_file(sorbet_config_file)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Colors
|
83
|
+
|
84
|
+
# Color used to highlight expressions in backticks
|
85
|
+
HIGHLIGHT_COLOR = :blue
|
86
|
+
|
61
87
|
# Is the `--color` option true?
|
62
88
|
sig { returns(T::Boolean) }
|
63
89
|
def color?
|
64
90
|
T.unsafe(self).options[:color] # TODO: requires_ancestor
|
65
91
|
end
|
66
92
|
|
93
|
+
sig { params(string: String).returns(String) }
|
94
|
+
def highlight(string)
|
95
|
+
return string unless color?
|
96
|
+
|
97
|
+
res = StringIO.new
|
98
|
+
word = StringIO.new
|
99
|
+
in_ticks = T.let(false, T::Boolean)
|
100
|
+
string.chars.each do |c|
|
101
|
+
if c == '`' && !in_ticks
|
102
|
+
in_ticks = true
|
103
|
+
elsif c == '`' && in_ticks
|
104
|
+
in_ticks = false
|
105
|
+
res << colorize(word.string, HIGHLIGHT_COLOR)
|
106
|
+
word = StringIO.new
|
107
|
+
elsif in_ticks
|
108
|
+
word << c
|
109
|
+
else
|
110
|
+
res << c
|
111
|
+
end
|
112
|
+
end
|
113
|
+
res.string
|
114
|
+
end
|
115
|
+
|
67
116
|
# Colorize a string if `color?`
|
68
117
|
sig { params(string: String, color: Symbol).returns(String) }
|
69
118
|
def colorize(string, color)
|
70
119
|
return string unless color?
|
71
120
|
string.colorize(color)
|
72
121
|
end
|
122
|
+
|
123
|
+
sig { params(string: String).returns(String) }
|
124
|
+
def blue(string)
|
125
|
+
colorize(string, :blue)
|
126
|
+
end
|
127
|
+
|
128
|
+
sig { params(string: String).returns(String) }
|
129
|
+
def gray(string)
|
130
|
+
colorize(string, :light_black)
|
131
|
+
end
|
132
|
+
|
133
|
+
sig { params(string: String).returns(String) }
|
134
|
+
def green(string)
|
135
|
+
colorize(string, :green)
|
136
|
+
end
|
137
|
+
|
138
|
+
sig { params(string: String).returns(String) }
|
139
|
+
def red(string)
|
140
|
+
colorize(string, :red)
|
141
|
+
end
|
142
|
+
|
143
|
+
sig { params(string: String).returns(String) }
|
144
|
+
def yellow(string)
|
145
|
+
colorize(string, :yellow)
|
146
|
+
end
|
73
147
|
end
|
74
148
|
end
|
75
149
|
end
|
data/lib/spoom/cli/lsp.rb
CHANGED
@@ -28,7 +28,7 @@ module Spoom
|
|
28
28
|
Dir["**/*.rb"].each do |file|
|
29
29
|
res = client.document_symbols(to_uri(file))
|
30
30
|
next if res.empty?
|
31
|
-
|
31
|
+
say("Symbols from `#{file}`:")
|
32
32
|
printer.print_objects(res)
|
33
33
|
end
|
34
34
|
end
|
@@ -39,11 +39,11 @@ module Spoom
|
|
39
39
|
def hover(file, line, col)
|
40
40
|
run do |client|
|
41
41
|
res = client.hover(to_uri(file), line.to_i, col.to_i)
|
42
|
-
say
|
42
|
+
say("Hovering `#{file}:#{line}:#{col}`:")
|
43
43
|
if res
|
44
44
|
symbol_printer.print_object(res)
|
45
45
|
else
|
46
|
-
|
46
|
+
say("<no data>")
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -53,7 +53,7 @@ module Spoom
|
|
53
53
|
def defs(file, line, col)
|
54
54
|
run do |client|
|
55
55
|
res = client.definitions(to_uri(file), line.to_i, col.to_i)
|
56
|
-
|
56
|
+
say("Definitions for `#{file}:#{line}:#{col}`:")
|
57
57
|
symbol_printer.print_list(res)
|
58
58
|
end
|
59
59
|
end
|
@@ -63,7 +63,7 @@ module Spoom
|
|
63
63
|
def find(query)
|
64
64
|
run do |client|
|
65
65
|
res = client.symbols(query).reject { |symbol| symbol.location.uri.start_with?("https") }
|
66
|
-
|
66
|
+
say("Symbols matching `#{query}`:")
|
67
67
|
symbol_printer.print_objects(res)
|
68
68
|
end
|
69
69
|
end
|
@@ -73,7 +73,7 @@ module Spoom
|
|
73
73
|
def symbols(file)
|
74
74
|
run do |client|
|
75
75
|
res = client.document_symbols(to_uri(file))
|
76
|
-
|
76
|
+
say("Symbols from `#{file}`:")
|
77
77
|
symbol_printer.print_objects(res)
|
78
78
|
end
|
79
79
|
end
|
@@ -83,7 +83,7 @@ module Spoom
|
|
83
83
|
def refs(file, line, col)
|
84
84
|
run do |client|
|
85
85
|
res = client.references(to_uri(file), line.to_i, col.to_i)
|
86
|
-
|
86
|
+
say("References to `#{file}:#{line}:#{col}`:")
|
87
87
|
symbol_printer.print_list(res)
|
88
88
|
end
|
89
89
|
end
|
@@ -93,7 +93,7 @@ module Spoom
|
|
93
93
|
def sigs(file, line, col)
|
94
94
|
run do |client|
|
95
95
|
res = client.signatures(to_uri(file), line.to_i, col.to_i)
|
96
|
-
|
96
|
+
say("Signature for `#{file}:#{line}:#{col}`:")
|
97
97
|
symbol_printer.print_list(res)
|
98
98
|
end
|
99
99
|
end
|
@@ -103,7 +103,7 @@ module Spoom
|
|
103
103
|
def types(file, line, col)
|
104
104
|
run do |client|
|
105
105
|
res = client.type_definitions(to_uri(file), line.to_i, col.to_i)
|
106
|
-
say
|
106
|
+
say("Type for `#{file}:#{line}:#{col}`:")
|
107
107
|
symbol_printer.print_list(res)
|
108
108
|
end
|
109
109
|
end
|
@@ -137,7 +137,7 @@ module Spoom
|
|
137
137
|
rescue Spoom::LSP::Error::Diagnostics => err
|
138
138
|
say_error("Sorbet returned typechecking errors for `#{symbol_printer.clean_uri(err.uri)}`")
|
139
139
|
err.diagnostics.each do |d|
|
140
|
-
say_error("#{d.message} (#{d.code})", " #{d.range}")
|
140
|
+
say_error("#{d.message} (#{d.code})", status: " #{d.range}")
|
141
141
|
end
|
142
142
|
exit(1)
|
143
143
|
rescue Spoom::LSP::Error::BadHeaders => err
|
data/lib/spoom/cli/run.rb
CHANGED
@@ -36,13 +36,13 @@ module Spoom
|
|
36
36
|
|
37
37
|
unless limit || code || sort
|
38
38
|
output, status = T.unsafe(Spoom::Sorbet).srb_tc(*arg, path: path, capture_err: false, sorbet_bin: sorbet)
|
39
|
-
|
39
|
+
say_error(output, status: nil, nl: false)
|
40
40
|
exit(status)
|
41
41
|
end
|
42
42
|
|
43
43
|
output, status = T.unsafe(Spoom::Sorbet).srb_tc(*arg, path: path, capture_err: true, sorbet_bin: sorbet)
|
44
44
|
if status
|
45
|
-
|
45
|
+
say_error(output, status: nil, nl: false)
|
46
46
|
exit(0)
|
47
47
|
end
|
48
48
|
|
@@ -65,14 +65,14 @@ module Spoom
|
|
65
65
|
lines = lines.uniq if uniq
|
66
66
|
|
67
67
|
lines.each do |line|
|
68
|
-
|
68
|
+
say_error(line, status: nil)
|
69
69
|
end
|
70
70
|
|
71
71
|
if count
|
72
72
|
if errors_count == errors.size
|
73
|
-
|
73
|
+
say_error("Errors: #{errors_count}", status: nil)
|
74
74
|
else
|
75
|
-
|
75
|
+
say_error("Errors: #{errors.size} shown, #{errors_count} total", status: nil)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
@@ -82,7 +82,7 @@ module Spoom
|
|
82
82
|
no_commands do
|
83
83
|
def format_error(error, format)
|
84
84
|
line = format
|
85
|
-
line = line.gsub(/%C/,
|
85
|
+
line = line.gsub(/%C/, yellow(error.code.to_s))
|
86
86
|
line = line.gsub(/%F/, error.file)
|
87
87
|
line = line.gsub(/%L/, error.line.to_s)
|
88
88
|
line = line.gsub(/%M/, colorize_message(error.message))
|
data/lib/spoom/printer.rb
CHANGED
data/lib/spoom/sorbet.rb
CHANGED
@@ -76,6 +76,15 @@ module Spoom
|
|
76
76
|
Spoom::Git.exec("GIT_COMMITTER_DATE=\"#{date}\" git commit -m '#{message}' --date '#{date}'", path: path)
|
77
77
|
end
|
78
78
|
|
79
|
+
# Run `bundle install` in this project
|
80
|
+
sig { returns([T.nilable(String), T.nilable(String), T::Boolean]) }
|
81
|
+
def bundle_install
|
82
|
+
opts = {}
|
83
|
+
opts[:chdir] = path
|
84
|
+
out, err, status = Open3.capture3("bundle", "install", opts)
|
85
|
+
[out, err, status.success?]
|
86
|
+
end
|
87
|
+
|
79
88
|
# Run a command with `bundle exec` in this project
|
80
89
|
sig { params(cmd: String, args: String).returns([T.nilable(String), T.nilable(String), T::Boolean]) }
|
81
90
|
def bundle_exec(cmd, *args)
|
data/lib/spoom/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spoom
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexandre Terrasa
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-02-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|