spoom 1.1.11 → 1.1.12
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 +1 -0
- data/README.md +6 -0
- data/Rakefile +1 -0
- data/lib/spoom/cli/bump.rb +11 -7
- data/lib/spoom/cli/coverage.rb +11 -7
- data/lib/spoom/cli/helper.rb +5 -4
- data/lib/spoom/cli/lsp.rb +2 -1
- data/lib/spoom/cli/run.rb +16 -6
- data/lib/spoom/cli.rb +6 -4
- data/lib/spoom/context.rb +219 -0
- data/lib/spoom/coverage/d3/base.rb +12 -8
- data/lib/spoom/coverage/d3/circle_map.rb +40 -37
- data/lib/spoom/coverage/d3/pie.rb +30 -26
- data/lib/spoom/coverage/d3/timeline.rb +86 -82
- data/lib/spoom/coverage/d3.rb +72 -70
- data/lib/spoom/coverage/report.rb +6 -6
- data/lib/spoom/coverage/snapshot.rb +40 -33
- data/lib/spoom/coverage.rb +84 -81
- data/lib/spoom/file_tree.rb +2 -0
- data/lib/spoom/git.rb +107 -97
- data/lib/spoom/printer.rb +4 -0
- data/lib/spoom/sorbet/errors.rb +29 -11
- data/lib/spoom/sorbet/lsp/base.rb +1 -1
- data/lib/spoom/sorbet/lsp/errors.rb +23 -17
- data/lib/spoom/sorbet/lsp/structures.rb +85 -54
- data/lib/spoom/sorbet/lsp.rb +71 -63
- data/lib/spoom/sorbet/metrics.rb +18 -16
- data/lib/spoom/sorbet/sigils.rb +59 -54
- data/lib/spoom/sorbet.rb +11 -8
- data/lib/spoom/timeline.rb +1 -0
- data/lib/spoom/version.rb +1 -1
- data/lib/spoom.rb +43 -25
- metadata +20 -20
- data/lib/spoom/test_helpers/project.rb +0 -138
@@ -23,12 +23,16 @@ module Spoom
|
|
23
23
|
const :contents, String
|
24
24
|
const :range, T.nilable(Range)
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
class << self
|
27
|
+
extend T::Sig
|
28
|
+
|
29
|
+
sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Hover) }
|
30
|
+
def from_json(json)
|
31
|
+
Hover.new(
|
32
|
+
contents: json["contents"]["value"],
|
33
|
+
range: json["range"] ? Range.from_json(json["range"]) : nil
|
34
|
+
)
|
35
|
+
end
|
32
36
|
end
|
33
37
|
|
34
38
|
sig { override.params(printer: SymbolPrinter).void }
|
@@ -50,12 +54,16 @@ module Spoom
|
|
50
54
|
const :line, Integer
|
51
55
|
const :char, Integer
|
52
56
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
class << self
|
58
|
+
extend T::Sig
|
59
|
+
|
60
|
+
sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Position) }
|
61
|
+
def from_json(json)
|
62
|
+
Position.new(
|
63
|
+
line: json["line"].to_i,
|
64
|
+
char: json["character"].to_i
|
65
|
+
)
|
66
|
+
end
|
59
67
|
end
|
60
68
|
|
61
69
|
sig { override.params(printer: SymbolPrinter).void }
|
@@ -76,12 +84,16 @@ module Spoom
|
|
76
84
|
const :start, Position
|
77
85
|
const :end, Position
|
78
86
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
87
|
+
class << self
|
88
|
+
extend T::Sig
|
89
|
+
|
90
|
+
sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Range) }
|
91
|
+
def from_json(json)
|
92
|
+
Range.new(
|
93
|
+
start: Position.from_json(json["start"]),
|
94
|
+
end: Position.from_json(json["end"])
|
95
|
+
)
|
96
|
+
end
|
85
97
|
end
|
86
98
|
|
87
99
|
sig { override.params(printer: SymbolPrinter).void }
|
@@ -104,12 +116,16 @@ module Spoom
|
|
104
116
|
const :uri, String
|
105
117
|
const :range, LSP::Range
|
106
118
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
119
|
+
class << self
|
120
|
+
extend T::Sig
|
121
|
+
|
122
|
+
sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Location) }
|
123
|
+
def from_json(json)
|
124
|
+
Location.new(
|
125
|
+
uri: json["uri"],
|
126
|
+
range: Range.from_json(json["range"])
|
127
|
+
)
|
128
|
+
end
|
113
129
|
end
|
114
130
|
|
115
131
|
sig { override.params(printer: SymbolPrinter).void }
|
@@ -132,20 +148,24 @@ module Spoom
|
|
132
148
|
const :doc, Object # TODO
|
133
149
|
const :params, T::Array[T.untyped] # TODO
|
134
150
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
151
|
+
class << self
|
152
|
+
extend T::Sig
|
153
|
+
|
154
|
+
sig { params(json: T::Hash[T.untyped, T.untyped]).returns(SignatureHelp) }
|
155
|
+
def from_json(json)
|
156
|
+
SignatureHelp.new(
|
157
|
+
label: json["label"],
|
158
|
+
doc: json["documentation"],
|
159
|
+
params: json["parameters"],
|
160
|
+
)
|
161
|
+
end
|
142
162
|
end
|
143
163
|
|
144
164
|
sig { override.params(printer: SymbolPrinter).void }
|
145
165
|
def accept_printer(printer)
|
146
166
|
printer.print(label)
|
147
167
|
printer.print("(")
|
148
|
-
printer.print(params.map { |l| "#{l[
|
168
|
+
printer.print(params.map { |l| "#{l["label"]}: #{l["documentation"]}" }.join(", "))
|
149
169
|
printer.print(")")
|
150
170
|
end
|
151
171
|
|
@@ -164,14 +184,18 @@ module Spoom
|
|
164
184
|
const :message, String
|
165
185
|
const :informations, Object
|
166
186
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
187
|
+
class << self
|
188
|
+
extend T::Sig
|
189
|
+
|
190
|
+
sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Diagnostic) }
|
191
|
+
def from_json(json)
|
192
|
+
Diagnostic.new(
|
193
|
+
range: Range.from_json(json["range"]),
|
194
|
+
code: json["code"].to_i,
|
195
|
+
message: json["message"],
|
196
|
+
informations: json["relatedInformation"]
|
197
|
+
)
|
198
|
+
end
|
175
199
|
end
|
176
200
|
|
177
201
|
sig { override.params(printer: SymbolPrinter).void }
|
@@ -196,35 +220,40 @@ module Spoom
|
|
196
220
|
const :range, T.nilable(Range)
|
197
221
|
const :children, T::Array[DocumentSymbol]
|
198
222
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
223
|
+
class << self
|
224
|
+
extend T::Sig
|
225
|
+
|
226
|
+
sig { params(json: T::Hash[T.untyped, T.untyped]).returns(DocumentSymbol) }
|
227
|
+
def from_json(json)
|
228
|
+
DocumentSymbol.new(
|
229
|
+
name: json["name"],
|
230
|
+
detail: json["detail"],
|
231
|
+
kind: json["kind"],
|
232
|
+
location: json["location"] ? Location.from_json(json["location"]) : nil,
|
233
|
+
range: json["range"] ? Range.from_json(json["range"]) : nil,
|
234
|
+
children: json["children"] ? json["children"].map { |symbol| DocumentSymbol.from_json(symbol) } : [],
|
235
|
+
)
|
236
|
+
end
|
209
237
|
end
|
210
238
|
|
211
239
|
sig { override.params(printer: SymbolPrinter).void }
|
212
240
|
def accept_printer(printer)
|
213
241
|
h = serialize.hash
|
214
242
|
return if printer.seen.include?(h)
|
243
|
+
|
215
244
|
printer.seen.add(h)
|
216
245
|
|
217
246
|
printer.printt
|
218
247
|
printer.print(kind_string)
|
219
|
-
printer.print(
|
248
|
+
printer.print(" ")
|
220
249
|
printer.print_colored(name, Color::BLUE, Color::BOLD)
|
221
|
-
printer.print_colored(
|
250
|
+
printer.print_colored(" (", Color::LIGHT_BLACK)
|
222
251
|
if range
|
223
252
|
printer.print_object(range)
|
224
253
|
elsif location
|
225
254
|
printer.print_object(location)
|
226
255
|
end
|
227
|
-
printer.print_colored(
|
256
|
+
printer.print_colored(")", Color::LIGHT_BLACK)
|
228
257
|
printer.printn
|
229
258
|
unless children.empty?
|
230
259
|
printer.indent
|
@@ -303,6 +332,7 @@ module Spoom
|
|
303
332
|
sig { params(object: T.nilable(PrintableSymbol)).void }
|
304
333
|
def print_object(object)
|
305
334
|
return unless object
|
335
|
+
|
306
336
|
object.accept_printer(self)
|
307
337
|
end
|
308
338
|
|
@@ -315,6 +345,7 @@ module Spoom
|
|
315
345
|
def clean_uri(uri)
|
316
346
|
prefix = self.prefix
|
317
347
|
return uri unless prefix
|
348
|
+
|
318
349
|
uri.delete_prefix(prefix)
|
319
350
|
end
|
320
351
|
|
@@ -322,7 +353,7 @@ module Spoom
|
|
322
353
|
def print_list(objects)
|
323
354
|
objects.each do |object|
|
324
355
|
printt
|
325
|
-
print
|
356
|
+
print("* ")
|
326
357
|
print_object(object)
|
327
358
|
printn
|
328
359
|
end
|
data/lib/spoom/sorbet/lsp.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
4
|
+
require "open3"
|
5
|
+
require "json"
|
6
6
|
|
7
|
-
require_relative
|
8
|
-
require_relative
|
9
|
-
require_relative
|
7
|
+
require_relative "lsp/base"
|
8
|
+
require_relative "lsp/structures"
|
9
|
+
require_relative "lsp/errors"
|
10
10
|
|
11
11
|
module Spoom
|
12
12
|
module LSP
|
@@ -58,10 +58,10 @@ module Spoom
|
|
58
58
|
json = JSON.parse(raw_string)
|
59
59
|
|
60
60
|
# Handle error in the LSP protocol
|
61
|
-
raise ResponseError.from_json(json[
|
61
|
+
raise ResponseError.from_json(json["error"]) if json["error"]
|
62
62
|
|
63
63
|
# Handle typechecking errors
|
64
|
-
raise Error::Diagnostics.from_json(json[
|
64
|
+
raise Error::Diagnostics.from_json(json["params"]) if json["method"] == "textDocument/publishDiagnostics"
|
65
65
|
|
66
66
|
json
|
67
67
|
end
|
@@ -71,16 +71,17 @@ module Spoom
|
|
71
71
|
sig { params(workspace_path: String).void }
|
72
72
|
def open(workspace_path)
|
73
73
|
raise Error::AlreadyOpen, "Error: CLI already opened" if @open
|
74
|
+
|
74
75
|
send(Request.new(
|
75
76
|
next_id,
|
76
|
-
|
77
|
+
"initialize",
|
77
78
|
{
|
78
|
-
|
79
|
-
|
80
|
-
|
79
|
+
"rootPath" => workspace_path,
|
80
|
+
"rootUri" => "file://#{workspace_path}",
|
81
|
+
"capabilities" => {},
|
81
82
|
},
|
82
83
|
))
|
83
|
-
send(Notification.new(
|
84
|
+
send(Notification.new("initialized", {}))
|
84
85
|
@open = true
|
85
86
|
end
|
86
87
|
|
@@ -88,133 +89,140 @@ module Spoom
|
|
88
89
|
def hover(uri, line, column)
|
89
90
|
json = send(Request.new(
|
90
91
|
next_id,
|
91
|
-
|
92
|
+
"textDocument/hover",
|
92
93
|
{
|
93
|
-
|
94
|
-
|
94
|
+
"textDocument" => {
|
95
|
+
"uri" => uri,
|
95
96
|
},
|
96
|
-
|
97
|
-
|
98
|
-
|
97
|
+
"position" => {
|
98
|
+
"line" => line,
|
99
|
+
"character" => column,
|
99
100
|
},
|
100
101
|
}
|
101
102
|
))
|
102
103
|
|
103
|
-
return nil unless json && json[
|
104
|
-
|
104
|
+
return nil unless json && json["result"]
|
105
|
+
|
106
|
+
Hover.from_json(json["result"])
|
105
107
|
end
|
106
108
|
|
107
109
|
sig { params(uri: String, line: Integer, column: Integer).returns(T::Array[SignatureHelp]) }
|
108
110
|
def signatures(uri, line, column)
|
109
111
|
json = send(Request.new(
|
110
112
|
next_id,
|
111
|
-
|
113
|
+
"textDocument/signatureHelp",
|
112
114
|
{
|
113
|
-
|
114
|
-
|
115
|
+
"textDocument" => {
|
116
|
+
"uri" => uri,
|
115
117
|
},
|
116
|
-
|
117
|
-
|
118
|
-
|
118
|
+
"position" => {
|
119
|
+
"line" => line,
|
120
|
+
"character" => column,
|
119
121
|
},
|
120
122
|
}
|
121
123
|
))
|
122
124
|
|
123
|
-
return [] unless json && json[
|
124
|
-
|
125
|
+
return [] unless json && json["result"] && json["result"]["signatures"]
|
126
|
+
|
127
|
+
json["result"]["signatures"].map { |loc| SignatureHelp.from_json(loc) }
|
125
128
|
end
|
126
129
|
|
127
130
|
sig { params(uri: String, line: Integer, column: Integer).returns(T::Array[Location]) }
|
128
131
|
def definitions(uri, line, column)
|
129
132
|
json = send(Request.new(
|
130
133
|
next_id,
|
131
|
-
|
134
|
+
"textDocument/definition",
|
132
135
|
{
|
133
|
-
|
134
|
-
|
136
|
+
"textDocument" => {
|
137
|
+
"uri" => uri,
|
135
138
|
},
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
+
"position" => {
|
140
|
+
"line" => line,
|
141
|
+
"character" => column,
|
139
142
|
},
|
140
143
|
}
|
141
144
|
))
|
142
145
|
|
143
|
-
return [] unless json && json[
|
144
|
-
|
146
|
+
return [] unless json && json["result"]
|
147
|
+
|
148
|
+
json["result"].map { |loc| Location.from_json(loc) }
|
145
149
|
end
|
146
150
|
|
147
151
|
sig { params(uri: String, line: Integer, column: Integer).returns(T::Array[Location]) }
|
148
152
|
def type_definitions(uri, line, column)
|
149
153
|
json = send(Request.new(
|
150
154
|
next_id,
|
151
|
-
|
155
|
+
"textDocument/typeDefinition",
|
152
156
|
{
|
153
|
-
|
154
|
-
|
157
|
+
"textDocument" => {
|
158
|
+
"uri" => uri,
|
155
159
|
},
|
156
|
-
|
157
|
-
|
158
|
-
|
160
|
+
"position" => {
|
161
|
+
"line" => line,
|
162
|
+
"character" => column,
|
159
163
|
},
|
160
164
|
}
|
161
165
|
))
|
162
166
|
|
163
|
-
return [] unless json && json[
|
164
|
-
|
167
|
+
return [] unless json && json["result"]
|
168
|
+
|
169
|
+
json["result"].map { |loc| Location.from_json(loc) }
|
165
170
|
end
|
166
171
|
|
167
172
|
sig { params(uri: String, line: Integer, column: Integer, include_decl: T::Boolean).returns(T::Array[Location]) }
|
168
173
|
def references(uri, line, column, include_decl = true)
|
169
174
|
json = send(Request.new(
|
170
175
|
next_id,
|
171
|
-
|
176
|
+
"textDocument/references",
|
172
177
|
{
|
173
|
-
|
174
|
-
|
178
|
+
"textDocument" => {
|
179
|
+
"uri" => uri,
|
175
180
|
},
|
176
|
-
|
177
|
-
|
178
|
-
|
181
|
+
"position" => {
|
182
|
+
"line" => line,
|
183
|
+
"character" => column,
|
179
184
|
},
|
180
|
-
|
181
|
-
|
185
|
+
"context" => {
|
186
|
+
"includeDeclaration" => include_decl,
|
182
187
|
},
|
183
188
|
}
|
184
189
|
))
|
185
190
|
|
186
|
-
return [] unless json && json[
|
187
|
-
|
191
|
+
return [] unless json && json["result"]
|
192
|
+
|
193
|
+
json["result"].map { |loc| Location.from_json(loc) }
|
188
194
|
end
|
189
195
|
|
190
196
|
sig { params(query: String).returns(T::Array[DocumentSymbol]) }
|
191
197
|
def symbols(query)
|
192
198
|
json = send(Request.new(
|
193
199
|
next_id,
|
194
|
-
|
200
|
+
"workspace/symbol",
|
195
201
|
{
|
196
|
-
|
202
|
+
"query" => query,
|
197
203
|
}
|
198
204
|
))
|
199
205
|
|
200
|
-
return [] unless json && json[
|
201
|
-
|
206
|
+
return [] unless json && json["result"]
|
207
|
+
|
208
|
+
json["result"].map { |loc| DocumentSymbol.from_json(loc) }
|
202
209
|
end
|
203
210
|
|
204
211
|
sig { params(uri: String).returns(T::Array[DocumentSymbol]) }
|
205
212
|
def document_symbols(uri)
|
206
213
|
json = send(Request.new(
|
207
214
|
next_id,
|
208
|
-
|
215
|
+
"textDocument/documentSymbol",
|
209
216
|
{
|
210
|
-
|
211
|
-
|
217
|
+
"textDocument" => {
|
218
|
+
"uri" => uri,
|
212
219
|
},
|
213
220
|
}
|
214
221
|
))
|
215
222
|
|
216
|
-
return [] unless json && json[
|
217
|
-
|
223
|
+
return [] unless json && json["result"]
|
224
|
+
|
225
|
+
json["result"].map { |loc| DocumentSymbol.from_json(loc) }
|
218
226
|
end
|
219
227
|
|
220
228
|
sig { void }
|
data/lib/spoom/sorbet/metrics.rb
CHANGED
@@ -6,26 +6,28 @@ require_relative "sigils"
|
|
6
6
|
module Spoom
|
7
7
|
module Sorbet
|
8
8
|
module MetricsParser
|
9
|
-
extend T::Sig
|
10
|
-
|
11
9
|
DEFAULT_PREFIX = "ruby_typer.unknown.."
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
parse_string(File.read(path), prefix)
|
16
|
-
end
|
11
|
+
class << self
|
12
|
+
extend T::Sig
|
17
13
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
14
|
+
sig { params(path: String, prefix: String).returns(T::Hash[String, Integer]) }
|
15
|
+
def parse_file(path, prefix = DEFAULT_PREFIX)
|
16
|
+
parse_string(File.read(path), prefix)
|
17
|
+
end
|
18
|
+
|
19
|
+
sig { params(string: String, prefix: String).returns(T::Hash[String, Integer]) }
|
20
|
+
def parse_string(string, prefix = DEFAULT_PREFIX)
|
21
|
+
parse_hash(JSON.parse(string), prefix)
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
sig { params(obj: T::Hash[String, T.untyped], prefix: String).returns(T::Hash[String, Integer]) }
|
25
|
+
def parse_hash(obj, prefix = DEFAULT_PREFIX)
|
26
|
+
obj["metrics"].each_with_object(Hash.new(0)) do |metric, metrics|
|
27
|
+
name = metric["name"]
|
28
|
+
name = name.sub(prefix, "")
|
29
|
+
metrics[name] = metric["value"] || 0
|
30
|
+
end
|
29
31
|
end
|
30
32
|
end
|
31
33
|
end
|
data/lib/spoom/sorbet/sigils.rb
CHANGED
@@ -27,70 +27,75 @@ module Spoom
|
|
27
27
|
|
28
28
|
SIGIL_REGEXP = T.let(/^#[\ t]*typed[\ t]*:[ \t]*(\w*)[ \t]*/.freeze, Regexp)
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
def self.sigil_string(strictness)
|
33
|
-
"# typed: #{strictness}"
|
34
|
-
end
|
30
|
+
class << self
|
31
|
+
extend T::Sig
|
35
32
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
33
|
+
# returns the full sigil comment string for the passed strictness
|
34
|
+
sig { params(strictness: String).returns(String) }
|
35
|
+
def sigil_string(strictness)
|
36
|
+
"# typed: #{strictness}"
|
37
|
+
end
|
41
38
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
39
|
+
# returns true if the passed string is a valid strictness (else false)
|
40
|
+
sig { params(strictness: String).returns(T::Boolean) }
|
41
|
+
def valid_strictness?(strictness)
|
42
|
+
VALID_STRICTNESS.include?(strictness.strip)
|
43
|
+
end
|
47
44
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
45
|
+
# returns the strictness of a sigil in the passed file content string (nil if no sigil)
|
46
|
+
sig { params(content: String).returns(T.nilable(String)) }
|
47
|
+
def strictness_in_content(content)
|
48
|
+
SIGIL_REGEXP.match(content)&.[](1)
|
49
|
+
end
|
53
50
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
content = File.read(path, encoding: Encoding::ASCII_8BIT)
|
60
|
-
strictness_in_content(content)
|
61
|
-
end
|
51
|
+
# returns a string which is the passed content but with the sigil updated to a new strictness
|
52
|
+
sig { params(content: String, new_strictness: String).returns(String) }
|
53
|
+
def update_sigil(content, new_strictness)
|
54
|
+
content.sub(SIGIL_REGEXP, sigil_string(new_strictness))
|
55
|
+
end
|
62
56
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
57
|
+
# returns a string containing the strictness of a sigil in a file at the passed path
|
58
|
+
# * returns nil if no sigil
|
59
|
+
sig { params(path: T.any(String, Pathname)).returns(T.nilable(String)) }
|
60
|
+
def file_strictness(path)
|
61
|
+
return nil unless File.file?(path)
|
68
62
|
|
69
|
-
|
63
|
+
content = File.read(path, encoding: Encoding::ASCII_8BIT)
|
64
|
+
strictness_in_content(content)
|
65
|
+
end
|
70
66
|
|
71
|
-
|
72
|
-
|
67
|
+
# changes the sigil in the file at the passed path to the specified new strictness
|
68
|
+
sig { params(path: T.any(String, Pathname), new_strictness: String).returns(T::Boolean) }
|
69
|
+
def change_sigil_in_file(path, new_strictness)
|
70
|
+
content = File.read(path, encoding: Encoding::ASCII_8BIT)
|
71
|
+
new_content = update_sigil(content, new_strictness)
|
73
72
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
path_list.filter do |path|
|
78
|
-
change_sigil_in_file(path, new_strictness)
|
73
|
+
File.write(path, new_content, encoding: Encoding::ASCII_8BIT)
|
74
|
+
|
75
|
+
strictness_in_content(new_content) == new_strictness
|
79
76
|
end
|
80
|
-
end
|
81
77
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
78
|
+
# changes the sigil to have a new strictness in a list of files
|
79
|
+
sig { params(path_list: T::Array[String], new_strictness: String).returns(T::Array[String]) }
|
80
|
+
def change_sigil_in_files(path_list, new_strictness)
|
81
|
+
path_list.filter do |path|
|
82
|
+
change_sigil_in_file(path, new_strictness)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# finds all files in the specified directory with the passed strictness
|
87
|
+
sig do
|
88
|
+
params(
|
89
|
+
directory: T.any(String, Pathname),
|
90
|
+
strictness: String,
|
91
|
+
extension: String
|
92
|
+
).returns(T::Array[String])
|
93
|
+
end
|
94
|
+
def files_with_sigil_strictness(directory, strictness, extension: ".rb")
|
95
|
+
paths = Dir.glob("#{File.expand_path(directory)}/**/*#{extension}").sort.uniq
|
96
|
+
paths.filter do |path|
|
97
|
+
file_strictness(path) == strictness
|
98
|
+
end
|
94
99
|
end
|
95
100
|
end
|
96
101
|
end
|