syntax_tree 3.3.0 → 3.4.0

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: 92ff69f19d5433566404bce6888eae08a442861821612c986489db05679ecd22
4
- data.tar.gz: e05511cf866fa1e0cfde540f0a0bc84a88414b128583a37a68c73658ff667b16
3
+ metadata.gz: 52707e3169fedfce017259222e4740b2e1032d210dfb628d454134eef578a7b6
4
+ data.tar.gz: aed3d5b3e6de7ed1e156c5b104007db6a01dab65e0ee80913afa2c1b5c63a5c0
5
5
  SHA512:
6
- metadata.gz: 3d98f8b9a997ef9278ad2ea9c1600ee5abc52c646d157b0180f6cf6956ebde2ccc6d9ea917436231645a7d4bf58ce1627fbae393b89e81b683157bc5263d65e0
7
- data.tar.gz: 924ccb54dec3055dca88aef5efe839d2c979abedfdf96f5e0996e18390b3e246b676cdb1c8aba6d51edfed42219bff3c80b4bfcead0eb3f6b926e585c96f0a1b
6
+ metadata.gz: b81b4753a5e765712bd31081dedca6e50c67d04a7935a717fc56d278424154e6ed95b648ac1cbdd59b500ee44c2d8d89f57f52e3851f9615e378d8c9c2c6abe1
7
+ data.tar.gz: 32c95446f19190b8e73d9c3ce83ff4bd5573f5787f844cf695551a2d32c0c159af8c514714c4648a99be4e66189910bde7f01557ea973f6e17aaba66ace7fce2
data/.rubocop.yml CHANGED
@@ -44,7 +44,7 @@ Style/ExplicitBlockArgument:
44
44
  Enabled: false
45
45
 
46
46
  Style/FormatString:
47
- EnforcedStyle: percent
47
+ Enabled: false
48
48
 
49
49
  Style/GuardClause:
50
50
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -6,6 +6,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [3.4.0] - 2022-08-19
10
+
11
+ ### Added
12
+
13
+ - [#127](https://github.com/ruby-syntax-tree/syntax_tree/pull/127) - Allow the language server to handle other file extensions if it is activated for those extensions.
14
+ - [#133](https://github.com/ruby-syntax-tree/syntax_tree/pull/133) - Add documentation on supporting vim and neovim.
15
+
16
+ ### Changed
17
+
18
+ - [#132](https://github.com/ruby-syntax-tree/syntax_tree/pull/132) - Provide better error messages when end quotes and end keywords are missing from tokens.
19
+ - [#134](https://github.com/ruby-syntax-tree/syntax_tree/pull/134) - Ensure the correct `end` keyword is getting removed by `begin..rescue` clauses.
20
+ - [#137](https://github.com/ruby-syntax-tree/syntax_tree/pull/137) - Better support regular expressions with no ending token.
21
+
9
22
  ## [3.3.0] - 2022-08-02
10
23
 
11
24
  ### Added
@@ -319,7 +332,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
319
332
 
320
333
  - 🎉 Initial release! 🎉
321
334
 
322
- [unreleased]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v3.3.0...HEAD
335
+ [unreleased]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v3.4.0...HEAD
336
+ [3.4.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v3.3.0...v3.4.0
323
337
  [3.3.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v3.2.1...v3.3.0
324
338
  [3.2.1]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v3.2.0...v3.2.1
325
339
  [3.2.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v3.1.0...v3.2.0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- syntax_tree (3.3.0)
4
+ syntax_tree (3.4.0)
5
5
  prettier_print
6
6
 
7
7
  GEM
@@ -12,24 +12,24 @@ GEM
12
12
  json (2.6.2)
13
13
  minitest (5.16.2)
14
14
  parallel (1.22.1)
15
- parser (3.1.2.0)
15
+ parser (3.1.2.1)
16
16
  ast (~> 2.4.1)
17
17
  prettier_print (0.1.0)
18
18
  rainbow (3.1.1)
19
19
  rake (13.0.6)
20
20
  regexp_parser (2.5.0)
21
21
  rexml (3.2.5)
22
- rubocop (1.32.0)
22
+ rubocop (1.35.0)
23
23
  json (~> 2.3)
24
24
  parallel (~> 1.10)
25
- parser (>= 3.1.0.0)
25
+ parser (>= 3.1.2.1)
26
26
  rainbow (>= 2.2.2, < 4.0)
27
27
  regexp_parser (>= 1.8, < 3.0)
28
28
  rexml (>= 3.2.5, < 4.0)
29
- rubocop-ast (>= 1.19.1, < 2.0)
29
+ rubocop-ast (>= 1.20.1, < 2.0)
30
30
  ruby-progressbar (~> 1.7)
31
31
  unicode-display_width (>= 1.4.0, < 3.0)
32
- rubocop-ast (1.19.1)
32
+ rubocop-ast (1.21.0)
33
33
  parser (>= 3.1.1.0)
34
34
  ruby-progressbar (1.11.0)
35
35
  simplecov (0.21.2)
data/README.md CHANGED
@@ -20,6 +20,7 @@ It is built with only standard library dependencies. It additionally ships with
20
20
  - [match](#match)
21
21
  - [write](#write)
22
22
  - [Configuration](#configuration)
23
+ - [Globbing](#globbing)
23
24
  - [Library](#library)
24
25
  - [SyntaxTree.read(filepath)](#syntaxtreereadfilepath)
25
26
  - [SyntaxTree.parse(source)](#syntaxtreeparsesource)
@@ -44,7 +45,7 @@ It is built with only standard library dependencies. It additionally ships with
44
45
  - [Integration](#integration)
45
46
  - [Rake](#rake)
46
47
  - [RuboCop](#rubocop)
47
- - [VSCode](#vscode)
48
+ - [Editors](#editors)
48
49
  - [Contributing](#contributing)
49
50
  - [License](#license)
50
51
 
@@ -245,6 +246,24 @@ This should be a text file with each argument on a separate line.
245
246
 
246
247
  If this file is present, it will _always_ be used for CLI commands. You can also pass options from the command line as in the examples above. The options in the `.streerc` file are passed to the CLI first, then the arguments from the command line. In the case of exclusive options (e.g. `--print-width`), this means that the command line options override what's in the config file. In the case of options that can take multiple inputs (e.g. `--plugins`), the effect is additive. That is, the plugins passed from the command line will be loaded _in addition to_ the plugins in the config file.
247
248
 
249
+ ### Globbing
250
+
251
+ When running commands with `stree`, it's common to pass in lists of files. For example:
252
+
253
+ ```sh
254
+ stree write 'lib/*.rb' 'test/*.rb'
255
+ ```
256
+
257
+ The commands in the CLI accept any number of arguments. This means you _could_ pass `**/*.rb` (note the lack of quotes). This would make your shell expand out the file paths listed according to its own rules. (For example, [here](https://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html) are the rules for GNU bash.)
258
+
259
+ However, it's recommended to instead use quotes, which means that Ruby is responsible for performing the file path expansion instead. This ensures a consistent experience across different environments and shells. The globs must follow the Ruby-specific globbing syntax as specified in the documentation for [Dir](https://ruby-doc.org/core-3.1.1/Dir.html#method-c-glob).
260
+
261
+ Baked into this syntax is the ability to provide exceptions to file name patterns as well. For example, if you are in a Rails app and want to exclude files named `schema.rb` but write all other Ruby files, you can use the following syntax:
262
+
263
+ ```shell
264
+ stree write "**/{[!schema]*,*}.rb"
265
+ ```
266
+
248
267
  ## Library
249
268
 
250
269
  Syntax Tree can be used as a library to access the syntax tree underlying Ruby source code.
@@ -548,9 +567,11 @@ inherit_gem:
548
567
  syntax_tree: config/rubocop.yml
549
568
  ```
550
569
 
551
- ### VSCode
570
+ ### Editors
552
571
 
553
- To integrate Syntax Tree into VSCode, you should use the official VSCode extension [ruby-syntax-tree/vscode-syntax-tree](https://github.com/ruby-syntax-tree/vscode-syntax-tree).
572
+ * [Neovim](https://neovim.io/) - [neovim/nvim-lspconfig](https://github.com/neovim/nvim-lspconfig).
573
+ * [Vim](https://www.vim.org/) - [dense-analysis/ale](https://github.com/dense-analysis/ale).
574
+ * [VSCode](https://code.visualstudio.com/) - [ruby-syntax-tree/vscode-syntax-tree](https://github.com/ruby-syntax-tree/vscode-syntax-tree).
554
575
 
555
576
  ## Contributing
556
577
 
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "optparse"
4
+
3
5
  module SyntaxTree
4
6
  # Syntax Tree ships with the `stree` CLI, which can be used to inspect and
5
7
  # manipulate Ruby code. This module is responsible for powering that CLI.
6
8
  module CLI
7
- CONFIG_FILE = ".streerc"
8
-
9
9
  # A utility wrapper around colored strings in the output.
10
10
  class Color
11
11
  attr_reader :value, :code
@@ -70,6 +70,12 @@ module SyntaxTree
70
70
 
71
71
  # The parent action class for the CLI that implements the basics.
72
72
  class Action
73
+ attr_reader :options
74
+
75
+ def initialize(options)
76
+ @options = options
77
+ end
78
+
73
79
  def run(item)
74
80
  end
75
81
 
@@ -93,15 +99,9 @@ module SyntaxTree
93
99
  class UnformattedError < StandardError
94
100
  end
95
101
 
96
- attr_reader :print_width
97
-
98
- def initialize(print_width:)
99
- @print_width = print_width
100
- end
101
-
102
102
  def run(item)
103
103
  source = item.source
104
- if source != item.handler.format(source, print_width)
104
+ if source != item.handler.format(source, options.print_width)
105
105
  raise UnformattedError
106
106
  end
107
107
  rescue StandardError
@@ -124,19 +124,13 @@ module SyntaxTree
124
124
  class NonIdempotentFormatError < StandardError
125
125
  end
126
126
 
127
- attr_reader :print_width
128
-
129
- def initialize(print_width:)
130
- @print_width = print_width
131
- end
132
-
133
127
  def run(item)
134
128
  handler = item.handler
135
129
 
136
130
  warning = "[#{Color.yellow("warn")}] #{item.filepath}"
137
- formatted = handler.format(item.source, print_width)
131
+ formatted = handler.format(item.source, options.print_width)
138
132
 
139
- if formatted != handler.format(formatted, print_width)
133
+ if formatted != handler.format(formatted, options.print_width)
140
134
  raise NonIdempotentFormatError
141
135
  end
142
136
  rescue StandardError
@@ -166,14 +160,8 @@ module SyntaxTree
166
160
 
167
161
  # An action of the CLI that formats the input source and prints it out.
168
162
  class Format < Action
169
- attr_reader :print_width
170
-
171
- def initialize(print_width:)
172
- @print_width = print_width
173
- end
174
-
175
163
  def run(item)
176
- puts item.handler.format(item.source, print_width)
164
+ puts item.handler.format(item.source, options.print_width)
177
165
  end
178
166
  end
179
167
 
@@ -197,18 +185,12 @@ module SyntaxTree
197
185
  # An action of the CLI that formats the input source and writes the
198
186
  # formatted output back to the file.
199
187
  class Write < Action
200
- attr_reader :print_width
201
-
202
- def initialize(print_width:)
203
- @print_width = print_width
204
- end
205
-
206
188
  def run(item)
207
189
  filepath = item.filepath
208
190
  start = Time.now
209
191
 
210
192
  source = item.source
211
- formatted = item.handler.format(source, print_width)
193
+ formatted = item.handler.format(source, options.print_width)
212
194
  File.write(filepath, formatted) if filepath != :stdin
213
195
 
214
196
  color = source == formatted ? Color.gray(filepath) : filepath
@@ -264,74 +246,114 @@ module SyntaxTree
264
246
  The maximum line width to use when formatting.
265
247
  HELP
266
248
 
249
+ # This represents all of the options that can be passed to the CLI. It is
250
+ # responsible for parsing the list and then returning the file paths at the
251
+ # end.
252
+ class Options
253
+ attr_reader :print_width
254
+
255
+ def initialize(print_width: DEFAULT_PRINT_WIDTH)
256
+ @print_width = print_width
257
+ end
258
+
259
+ def parse(arguments)
260
+ parser.parse(arguments)
261
+ end
262
+
263
+ private
264
+
265
+ def parser
266
+ OptionParser.new do |opts|
267
+ # If there are any plugins specified on the command line, then load
268
+ # them by requiring them here. We do this by transforming something
269
+ # like
270
+ #
271
+ # stree format --plugins=haml template.haml
272
+ #
273
+ # into
274
+ #
275
+ # require "syntax_tree/haml"
276
+ #
277
+ opts.on("--plugins=PLUGINS") do |plugins|
278
+ plugins.split(",").each { |plugin| require "syntax_tree/#{plugin}" }
279
+ end
280
+
281
+ # If there is a print width specified on the command line, then
282
+ # parse that out here and use it when formatting.
283
+ opts.on("--print-width=NUMBER", Integer) do |print_width|
284
+ @print_width = print_width
285
+ end
286
+ end
287
+ end
288
+ end
289
+
290
+ # We allow a minimal configuration file to act as additional command line
291
+ # arguments to the CLI. Each line of the config file should be a new
292
+ # argument, as in:
293
+ #
294
+ # --plugins=plugin/single_quote
295
+ # --print-width=100
296
+ #
297
+ # When invoking the CLI, we will read this config file and then parse it if
298
+ # it exists in the current working directory.
299
+ class ConfigFile
300
+ FILENAME = ".streerc"
301
+
302
+ attr_reader :filepath
303
+
304
+ def initialize
305
+ @filepath = File.join(Dir.pwd, FILENAME)
306
+ end
307
+
308
+ def exists?
309
+ File.readable?(filepath)
310
+ end
311
+
312
+ def arguments
313
+ exists? ? File.readlines(filepath, chomp: true) : []
314
+ end
315
+ end
316
+
267
317
  class << self
268
318
  # Run the CLI over the given array of strings that make up the arguments
269
319
  # passed to the invocation.
270
320
  def run(argv)
271
321
  name, *arguments = argv
272
- print_width = DEFAULT_PRINT_WIDTH
273
-
274
- config_file = File.join(Dir.pwd, CONFIG_FILE)
275
- if File.readable?(config_file)
276
- arguments.unshift(*File.readlines(config_file, chomp: true))
277
- end
278
322
 
279
- while arguments.first&.start_with?("--")
280
- case (argument = arguments.shift)
281
- when /^--plugins=(.+)$/
282
- # If there are any plugins specified on the command line, then load
283
- # them by requiring them here. We do this by transforming something
284
- # like
285
- #
286
- # stree format --plugins=haml template.haml
287
- #
288
- # into
289
- #
290
- # require "syntax_tree/haml"
291
- #
292
- $1.split(",").each { |plugin| require "syntax_tree/#{plugin}" }
293
- when /^--print-width=(\d+)$/
294
- # If there is a print width specified on the command line, then
295
- # parse that out here and use it when formatting.
296
- print_width = Integer($1)
297
- else
298
- warn("Unknown CLI option: #{argument}")
299
- warn(HELP)
300
- return 1
301
- end
302
- end
323
+ config_file = ConfigFile.new
324
+ arguments.unshift(*config_file.arguments)
303
325
 
304
- case name
305
- when "help"
306
- puts HELP
307
- return 0
308
- when "lsp"
309
- require "syntax_tree/language_server"
310
- LanguageServer.new(print_width: print_width).run
311
- return 0
312
- when "version"
313
- puts SyntaxTree::VERSION
314
- return 0
315
- end
326
+ options = Options.new
327
+ options.parse(arguments)
316
328
 
317
329
  action =
318
330
  case name
319
331
  when "a", "ast"
320
- AST.new
332
+ AST.new(options)
321
333
  when "c", "check"
322
- Check.new(print_width: print_width)
334
+ Check.new(options)
323
335
  when "debug"
324
- Debug.new(print_width: print_width)
336
+ Debug.new(options)
325
337
  when "doc"
326
- Doc.new
338
+ Doc.new(options)
339
+ when "help"
340
+ puts HELP
341
+ return 0
327
342
  when "j", "json"
328
- Json.new
343
+ Json.new(options)
344
+ when "lsp"
345
+ require "syntax_tree/language_server"
346
+ LanguageServer.new(print_width: options.print_width).run
347
+ return 0
329
348
  when "m", "match"
330
- Match.new
349
+ Match.new(options)
331
350
  when "f", "format"
332
- Format.new(print_width: print_width)
351
+ Format.new(options)
352
+ when "version"
353
+ puts SyntaxTree::VERSION
354
+ return 0
333
355
  when "w", "write"
334
- Write.new(print_width: print_width)
356
+ Write.new(options)
335
357
  else
336
358
  warn(HELP)
337
359
  return 1
@@ -56,7 +56,7 @@ module SyntaxTree
56
56
  store.delete(uri)
57
57
  in { method: "textDocument/formatting", id:, params: { textDocument: { uri: } } }
58
58
  contents = store[uri]
59
- write(id: id, result: contents ? [format(store[uri])] : nil)
59
+ write(id: id, result: contents ? [format(store[uri], uri.split(".").last)] : nil)
60
60
  in { method: "textDocument/inlayHint", id:, params: { textDocument: { uri: } } }
61
61
  contents = store[uri]
62
62
  write(id: id, result: contents ? inlay_hints(store[uri]) : nil)
@@ -86,7 +86,9 @@ module SyntaxTree
86
86
  }
87
87
  end
88
88
 
89
- def format(source)
89
+ def format(source, extension)
90
+ text = SyntaxTree::HANDLERS[".#{extension}"].format(source, print_width)
91
+
90
92
  {
91
93
  range: {
92
94
  start: {
@@ -98,7 +100,7 @@ module SyntaxTree
98
100
  character: 0
99
101
  }
100
102
  },
101
- newText: SyntaxTree.format(source, print_width)
103
+ newText: text
102
104
  }
103
105
  end
104
106
 
@@ -117,5 +119,9 @@ module SyntaxTree
117
119
  output.print("Content-Length: #{response.bytesize}\r\n\r\n#{response}")
118
120
  output.flush
119
121
  end
122
+
123
+ def log(message)
124
+ write(method: "window/logMessage", params: { type: 4, message: message })
125
+ end
120
126
  end
121
127
  end
@@ -57,6 +57,26 @@ module SyntaxTree
57
57
  end
58
58
  end
59
59
 
60
+ # This represents all of the tokens coming back from the lexer. It is
61
+ # replacing a simple array because it keeps track of the last deleted token
62
+ # from the list for better error messages.
63
+ class TokenList < SimpleDelegator
64
+ attr_reader :last_deleted
65
+
66
+ def initialize(object)
67
+ super
68
+ @last_deleted = nil
69
+ end
70
+
71
+ def delete(value)
72
+ @last_deleted = super || @last_deleted
73
+ end
74
+
75
+ def delete_at(index)
76
+ @last_deleted = super
77
+ end
78
+ end
79
+
60
80
  # [String] the source being parsed
61
81
  attr_reader :source
62
82
 
@@ -124,7 +144,7 @@ module SyntaxTree
124
144
  # Most of the time, when a parser event consumes one of these events, it
125
145
  # will be deleted from the list. So ideally, this list stays pretty short
126
146
  # over the course of parsing a source string.
127
- @tokens = []
147
+ @tokens = TokenList.new([])
128
148
 
129
149
  # Here we're going to build up a list of SingleByteString or
130
150
  # MultiByteString objects. They're each going to represent a string in the
@@ -174,6 +194,33 @@ module SyntaxTree
174
194
  line[column].to_i - line.start
175
195
  end
176
196
 
197
+ # Returns the current location that is being looked at for the parser for
198
+ # the purpose of locating the error.
199
+ def find_token_error(location)
200
+ if location
201
+ # If we explicitly passed a location into this find_token_error method,
202
+ # that means that's the source of the error, so we'll use that
203
+ # information for our error object.
204
+ lineno = location.start_line
205
+ [lineno, location.start_char - line_counts[lineno - 1].start]
206
+ elsif lineno && column
207
+ # If there is a line number associated with the current ripper state,
208
+ # then we'll use that information to generate the error.
209
+ [lineno, column]
210
+ elsif (location = tokens.last_deleted&.location)
211
+ # If we've already deleted a token from the list of tokens that we are
212
+ # consuming, then we'll fall back to that token's location.
213
+ lineno = location.start_line
214
+ [lineno, location.start_char - line_counts[lineno - 1].start]
215
+ else
216
+ # Finally, it's possible that when we hit this error the parsing thread
217
+ # for ripper has died. In that case, lineno and column both return nil.
218
+ # So we're just going to set it to line 1, column 0 in the hopes that
219
+ # that makes any sense.
220
+ [1, 0]
221
+ end
222
+ end
223
+
177
224
  # As we build up a list of tokens, we'll periodically need to go backwards
178
225
  # and find the ones that we've already hit in order to determine the
179
226
  # location information for nodes that use them. For example, if you have a
@@ -201,14 +248,7 @@ module SyntaxTree
201
248
  unless index
202
249
  token = value == :any ? type.name.split("::", 2).last : value
203
250
  message = "Cannot find expected #{token}"
204
-
205
- if location
206
- lineno = location.start_line
207
- column = location.start_char - line_counts[lineno - 1].start
208
- raise ParseError.new(message, lineno, column)
209
- else
210
- raise ParseError.new(message, lineno, column)
211
- end
251
+ raise ParseError.new(message, *find_token_error(location))
212
252
  end
213
253
 
214
254
  tokens.delete_at(index)
@@ -677,8 +717,7 @@ module SyntaxTree
677
717
  else
678
718
  keyword = find_token(Kw, "begin")
679
719
  end_location =
680
- if bodystmt.rescue_clause || bodystmt.ensure_clause ||
681
- bodystmt.else_clause
720
+ if bodystmt.else_clause
682
721
  bodystmt.location
683
722
  else
684
723
  find_token(Kw, "end").location
@@ -2798,14 +2837,21 @@ module SyntaxTree
2798
2837
  # :call-seq:
2799
2838
  # on_regexp_literal: (
2800
2839
  # RegexpContent regexp_content,
2801
- # RegexpEnd ending
2840
+ # (nil | RegexpEnd) ending
2802
2841
  # ) -> RegexpLiteral
2803
2842
  def on_regexp_literal(regexp_content, ending)
2843
+ location = regexp_content.location
2844
+
2845
+ if ending.nil?
2846
+ message = "Cannot find expected regular expression ending"
2847
+ raise ParseError.new(message, *find_token_error(location))
2848
+ end
2849
+
2804
2850
  RegexpLiteral.new(
2805
2851
  beginning: regexp_content.beginning,
2806
2852
  ending: ending.value,
2807
2853
  parts: regexp_content.parts,
2808
- location: regexp_content.location.to(ending.location)
2854
+ location: location.to(ending.location)
2809
2855
  )
2810
2856
  end
2811
2857
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SyntaxTree
4
- VERSION = "3.3.0"
4
+ VERSION = "3.4.0"
5
5
  end
data/lib/syntax_tree.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "delegate"
3
4
  require "etc"
4
5
  require "json"
5
6
  require "pp"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: syntax_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Newton
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-02 00:00:00.000000000 Z
11
+ date: 2022-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: prettier_print