prettier 2.1.0 → 3.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +36 -6
  3. data/README.md +17 -16
  4. data/exe/rbprettier +2 -2
  5. data/lib/prettier/rake/task.rb +5 -5
  6. data/lib/prettier.rb +11 -11
  7. data/package.json +11 -25
  8. data/rubocop.yml +32 -12
  9. data/{dist/parser → src}/getInfo.js +0 -1
  10. data/{dist/parser → src}/netcat.js +0 -1
  11. data/src/parseSync.js +216 -0
  12. data/src/plugin.js +170 -0
  13. data/{dist/parser → src}/server.rb +50 -31
  14. metadata +94 -78
  15. data/bin/console +0 -7
  16. data/dist/haml/embed.js +0 -53
  17. data/dist/haml/parser.js +0 -31
  18. data/dist/haml/parser.rb +0 -149
  19. data/dist/haml/printer.js +0 -336
  20. data/dist/parser/parseSync.js +0 -179
  21. data/dist/plugin.js +0 -143
  22. data/dist/prettier.js +0 -15
  23. data/dist/rbs/parser.js +0 -34
  24. data/dist/rbs/parser.rb +0 -155
  25. data/dist/rbs/printer.js +0 -525
  26. data/dist/ruby/embed.js +0 -115
  27. data/dist/ruby/location.js +0 -19
  28. data/dist/ruby/nodes/alias.js +0 -60
  29. data/dist/ruby/nodes/aref.js +0 -51
  30. data/dist/ruby/nodes/args.js +0 -138
  31. data/dist/ruby/nodes/arrays.js +0 -122
  32. data/dist/ruby/nodes/assign.js +0 -37
  33. data/dist/ruby/nodes/blocks.js +0 -90
  34. data/dist/ruby/nodes/calls.js +0 -263
  35. data/dist/ruby/nodes/case.js +0 -50
  36. data/dist/ruby/nodes/class.js +0 -54
  37. data/dist/ruby/nodes/commands.js +0 -138
  38. data/dist/ruby/nodes/conditionals.js +0 -246
  39. data/dist/ruby/nodes/constants.js +0 -35
  40. data/dist/ruby/nodes/flow.js +0 -59
  41. data/dist/ruby/nodes/hashes.js +0 -126
  42. data/dist/ruby/nodes/heredocs.js +0 -30
  43. data/dist/ruby/nodes/hooks.js +0 -35
  44. data/dist/ruby/nodes/ints.js +0 -27
  45. data/dist/ruby/nodes/lambdas.js +0 -70
  46. data/dist/ruby/nodes/loops.js +0 -75
  47. data/dist/ruby/nodes/massign.js +0 -60
  48. data/dist/ruby/nodes/methods.js +0 -50
  49. data/dist/ruby/nodes/operators.js +0 -68
  50. data/dist/ruby/nodes/params.js +0 -95
  51. data/dist/ruby/nodes/patterns.js +0 -119
  52. data/dist/ruby/nodes/regexp.js +0 -45
  53. data/dist/ruby/nodes/rescue.js +0 -86
  54. data/dist/ruby/nodes/return.js +0 -100
  55. data/dist/ruby/nodes/statements.js +0 -110
  56. data/dist/ruby/nodes/strings.js +0 -220
  57. data/dist/ruby/nodes/super.js +0 -26
  58. data/dist/ruby/nodes/undef.js +0 -31
  59. data/dist/ruby/nodes.js +0 -177
  60. data/dist/ruby/parser.js +0 -35
  61. data/dist/ruby/parser.rb +0 -9134
  62. data/dist/ruby/printer.js +0 -67
  63. data/dist/ruby/toProc.js +0 -91
  64. data/dist/types/haml.js +0 -4
  65. data/dist/types/plugin.js +0 -3
  66. data/dist/types/rbs.js +0 -4
  67. data/dist/types/ruby.js +0 -4
  68. data/dist/types/utils.js +0 -2
  69. data/dist/types.js +0 -34
  70. data/dist/utils/containsAssignment.js +0 -18
  71. data/dist/utils/getChildNodes.js +0 -305
  72. data/dist/utils/getTrailingComma.js +0 -6
  73. data/dist/utils/hasAncestor.js +0 -15
  74. data/dist/utils/inlineEnsureParens.js +0 -49
  75. data/dist/utils/isEmptyBodyStmt.js +0 -10
  76. data/dist/utils/isEmptyParams.js +0 -12
  77. data/dist/utils/isEmptyStmts.js +0 -10
  78. data/dist/utils/literal.js +0 -8
  79. data/dist/utils/literallineWithoutBreakParent.js +0 -8
  80. data/dist/utils/makeCall.js +0 -14
  81. data/dist/utils/noIndent.js +0 -11
  82. data/dist/utils/printEmptyCollection.js +0 -46
  83. data/dist/utils/skipAssignIndent.js +0 -19
  84. data/dist/utils.js +0 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 34ffeeada2b06900ec6759f31a42ca387c8748a6a22843a1792fd906bfb4ffda
4
- data.tar.gz: ddbceb38e8263f881fd12f66560615db880cf7870f0cb926671c2da656aad6f8
3
+ metadata.gz: 967c98f2226d3ae025e0fe136f8cddd80115480baaa375a4906a8b7729cf5549
4
+ data.tar.gz: 31c55db39cdeb5e423ddd89d5000217d7dd226ada3a854e6a36b5ddf0274b807
5
5
  SHA512:
6
- metadata.gz: 300acaf432b28f15d5b7690effbe7ca8fff778af699c5f79d0872c15f3241ec9be2e8fd83f86a9e65e6807cd152504b78d79760b30926c418bc7358d5d9f7524
7
- data.tar.gz: a7d658200446e7dde838d07b502303fa30e168e800f3053e48e6cf05940fbb92892d0eaca9c48304a48b13d6c94dce09019bb7a2c18acc18c48b3c241d4d4637
6
+ metadata.gz: 4411eeaefa1cc33f118a6f4660801cd1da8341f1954e8993a9b5e20f5c3a148b220899bde756fa359080f393b567d5312cb0774571b9ec859af0d1cba1a9e2da
7
+ data.tar.gz: fda90238c9d58046c394ba09b11671ba0d617efff319a21077638ac86ed18f2cd2bfbf81192e92f0b0c62fd48987290276ca114202fcd5e00136512622d6ffe3
data/CHANGELOG.md CHANGED
@@ -6,6 +6,35 @@ 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.1.1] - 2022-05-12
10
+
11
+ ### Changed
12
+
13
+ - [#1125](https://github.com/prettier/plugin-ruby/pull/1225) - kddnewton - Update the bundled rubocop config to be in sync with Syntax Tree.
14
+
15
+ ## [3.1.0] - 2022-05-12
16
+
17
+ ### Added
18
+
19
+ - [#1224](https://github.com/prettier/plugin-ruby/pull/1224) - kddnewton - Support passing the `rubyPlugins` option to configure Syntax Tree.
20
+
21
+ ## [3.0.0] - 2022-05-04
22
+
23
+ ### Added
24
+
25
+ - [#1190](https://github.com/prettier/plugin-ruby/pull/1190) - kddnewton - Encoding for source files is now guessed in a much better way.
26
+
27
+ ### Changed
28
+
29
+ - [#1198](https://github.com/prettier/plugin-ruby/issues/1198) - pas-f, kddnewton - Fix crashes on JRuby with do blocks.
30
+ - [#1131](https://github.com/prettier/plugin-ruby/issues/1131) - hyrious, kddnewton - Ensure zombie processes are not left around when the server exits.
31
+ - [#1206](https://github.com/prettier/plugin-ruby/pull/1206) - kddnewton - Switch back to plain JavaScript for development.
32
+ - [#1190](https://github.com/prettier/plugin-ruby/pull/1190) - kddnewton - Switch over to using Syntax Tree for the backend.
33
+
34
+ ### Removed
35
+
36
+ - [#1190](https://github.com/prettier/plugin-ruby/pull/1190) - kddnewton - The configuration options have been removed. Instead, configuration is to be done through modifying Syntax Tree.
37
+
9
38
  ## [2.1.0] - 2022-04-04
10
39
 
11
40
  ### Added
@@ -316,7 +345,6 @@ The comment in the above example should stay in place.
316
345
 
317
346
  ```ruby
318
347
  begin
319
-
320
348
  rescue Foo, Bar
321
349
  # comment
322
350
  end
@@ -472,7 +500,8 @@ return (a or b) if c?
472
500
  - kddnewton - Support for the `nokw_param` node for specifying when methods should no accept keywords, as in:
473
501
 
474
502
  ```ruby
475
- def foo(**nil); end
503
+ def foo(**nil)
504
+ end
476
505
  ```
477
506
 
478
507
  - kddnewton - Support for the `args_forward` node for forwarding all types of arguments, as in:
@@ -518,9 +547,9 @@ will now be printed as:
518
547
 
519
548
  ```ruby
520
549
  Config::Download.new(
521
- 'prettier',
522
- filename: 'prettier.yml',
523
- url: 'https://raw.githubusercontent.com/...'
550
+ "prettier",
551
+ filename: "prettier.yml",
552
+ url: "https://raw.githubusercontent.com/..."
524
553
  ).perform
525
554
  ```
526
555
 
@@ -1208,7 +1237,8 @@ would previously result in `array[]`, but now prints properly.
1208
1237
 
1209
1238
  - Initial release 🎉
1210
1239
 
1211
- [unreleased]: https://github.com/prettier/plugin-ruby/compare/v2.1.0...HEAD
1240
+ [unreleased]: https://github.com/prettier/plugin-ruby/compare/v3.0.0...HEAD
1241
+ [3.0.0]: https://github.com/prettier/plugin-ruby/compare/v2.1.0...v3.0.0
1212
1242
  [2.1.0]: https://github.com/prettier/plugin-ruby/compare/v2.0.0...v2.1.0
1213
1243
  [2.0.0]: https://github.com/prettier/plugin-ruby/compare/v2.0.0-rc4...v2.0.0
1214
1244
  [2.0.0-rc4]: https://github.com/prettier/plugin-ruby/compare/v2.0.0-rc3...v2.0.0-rc4
data/README.md CHANGED
@@ -59,9 +59,9 @@ d = [
59
59
  30_643_069_058
60
60
  ]
61
61
  a, s = [], $*[0]
62
- s.each_byte { |b| a << ('%036b' % d[b.chr.to_i]).scan(/\d{6}/) }
62
+ s.each_byte { |b| a << ("%036b" % d[b.chr.to_i]).scan(/\d{6}/) }
63
63
  a.transpose.each do |a|
64
- a.join.each_byte { |i| print i == 49 ? ($*[1] || '#') : 32.chr }
64
+ a.join.each_byte { |i| print i == 49 ? ($*[1] || "#") : 32.chr }
65
65
  puts
66
66
  end
67
67
  ```
@@ -83,7 +83,7 @@ This plugin currently supports formatting the following kinds of files:
83
83
  Add this line to your application's Gemfile:
84
84
 
85
85
  ```ruby
86
- gem 'prettier'
86
+ gem "prettier"
87
87
  ```
88
88
 
89
89
  And then execute:
@@ -118,6 +118,12 @@ Or if you're using `yarn`, then add the plugin by:
118
118
  yarn add --dev prettier @prettier/plugin-ruby
119
119
  ```
120
120
 
121
+ You'll also need to add the necessary Ruby dependencies. You can do this by running:
122
+
123
+ ```bash
124
+ gem install bundler syntax_tree syntax_tree-haml syntax_tree-rbs
125
+ ```
126
+
121
127
  The `prettier` executable is now installed and ready for use:
122
128
 
123
129
  ```bash
@@ -128,31 +134,26 @@ The `prettier` executable is now installed and ready for use:
128
134
 
129
135
  Below are the options (from [`src/plugin.js`](src/plugin.js)) that `@prettier/plugin-ruby` currently supports:
130
136
 
131
- | API Option | CLI Option | Default | Description |
132
- | ------------------ | ---------------------- | :------: | ------------------------------------------------------------------------------------------------------------------------------------ |
133
- | `printWidth` | `--print-width` | `80` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#print-width)). |
134
- | `requirePragma` | `--require-pragma` | `false` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#require-pragma)). |
135
- | `rubyArrayLiteral` | `--ruby-array-literal` | `true` | When possible, favor the use of string and symbol array literals. |
136
- | `rubyHashLabel` | `--ruby-hash-label` | `true` | When possible, uses the shortened hash key syntax, as opposed to hash rockets. |
137
- | `rubyModifier` | `--ruby-modifier` | `true` | When it fits on one line, allows while and until statements to use the modifier form. |
138
- | `rubySingleQuote` | `--ruby-single-quote` | `true` | When double quotes are not necessary for interpolation, prefers the use of single quotes for string literals. |
139
- | `rubyToProc` | `--ruby-to-proc` | `false` | When possible, convert blocks to the more concise `Symbol#to_proc` syntax. |
140
- | `tabWidth` | `--tab-width` | `2` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#tab-width)). |
141
- | `trailingComma` | `--trailing-comma` | `"none"` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#trailing-comma)). `"es5"` is equivalent to `true`. |
137
+ | API Option | CLI Option | Default | Description |
138
+ | --------------- | ------------------ | :-----: | --------------------------------------------------------------------------------------------------------------------------- |
139
+ | `printWidth` | `--print-width` | `80` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#print-width)). |
140
+ | `requirePragma` | `--require-pragma` | `false` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#require-pragma)). |
141
+ | `rubyPlugins` | `--ruby-plugins` | `""` | The comma-separated list of plugins to require. See [Syntax Tree](https://github.com/ruby-syntax-tree/syntax_tree#plugins). |
142
+ | `tabWidth` | `--tab-width` | `2` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#tab-width)). |
142
143
 
143
144
  Any of these can be added to your existing [prettier configuration
144
145
  file](https://prettier.io/docs/en/configuration.html). For example:
145
146
 
146
147
  ```json
147
148
  {
148
- "rubySingleQuote": false
149
+ "tabWidth": 4
149
150
  }
150
151
  ```
151
152
 
152
153
  Or, they can be passed to `prettier` as arguments:
153
154
 
154
155
  ```bash
155
- bundle exec rbprettier --ruby-single-quote false --write '**/*'
156
+ bundle exec rbprettier --tab-width 4 --write '**/*'
156
157
  ```
157
158
 
158
159
  ### Usage with RuboCop
data/exe/rbprettier CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- $:.unshift(File.expand_path(File.join('..', 'lib'), __dir__))
5
- require 'prettier'
4
+ $:.unshift(File.expand_path(File.join("..", "lib"), __dir__))
5
+ require "prettier"
6
6
 
7
7
  exit(Prettier.run(ARGV))
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rake'
4
- require 'rake/tasklib'
3
+ require "rake"
4
+ require "rake/tasklib"
5
5
 
6
6
  module Prettier
7
7
  module Rake
@@ -35,7 +35,7 @@ module Prettier
35
35
  def initialize(name = :prettier)
36
36
  @name = name
37
37
  @write = true
38
- @source_files = 'lib/**/*.rb'
38
+ @source_files = "lib/**/*.rb"
39
39
 
40
40
  yield self if block_given?
41
41
  define_task
@@ -44,12 +44,12 @@ module Prettier
44
44
  private
45
45
 
46
46
  def define_task
47
- desc 'Runs prettier over source files'
47
+ desc "Runs prettier over source files"
48
48
  task(name) { run_task }
49
49
  end
50
50
 
51
51
  def run_task
52
- Prettier.run([('--write' if write), source_files].compact)
52
+ Prettier.run([("--write" if write), source_files].compact)
53
53
  exit($?.exitstatus) if $?&.exited?
54
54
  end
55
55
  end
data/lib/prettier.rb CHANGED
@@ -1,19 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json' unless defined?(JSON)
4
- require 'open3'
3
+ require "json" unless defined?(JSON)
4
+ require "open3"
5
5
 
6
6
  module Prettier
7
- PLUGIN = -File.expand_path('..', __dir__)
8
- BINARY = -File.join(PLUGIN, 'node_modules', 'prettier', 'bin-prettier.js')
9
- VERSION = -JSON.parse(File.read(File.join(PLUGIN, 'package.json')))['version']
7
+ PLUGIN = -File.expand_path("..", __dir__)
8
+ BINARY = -File.join(PLUGIN, "node_modules", "prettier", "bin-prettier.js")
9
+ VERSION = -JSON.parse(File.read(File.join(PLUGIN, "package.json")))["version"]
10
10
 
11
11
  def self.run(args)
12
- quoted = args.map { |arg| arg.start_with?('-') ? arg : "\"#{arg}\"" }
13
- command = "node #{BINARY} --plugin \"#{PLUGIN}\" #{quoted.join(' ')}"
12
+ quoted = args.map { |arg| arg.start_with?("-") ? arg : "\"#{arg}\"" }
13
+ command = "node #{BINARY} --plugin \"#{PLUGIN}\" #{quoted.join(" ")}"
14
14
 
15
15
  stdout, stderr, status =
16
- Open3.capture3({ 'RBPRETTIER' => '1' }, command, stdin_data: STDIN)
16
+ Open3.capture3({ "RBPRETTIER" => "1" }, command, stdin_data: STDIN)
17
17
  STDOUT.puts(stdout)
18
18
 
19
19
  # If we completed successfully, then just exit out.
@@ -30,11 +30,11 @@ module Prettier
30
30
  If you installed this dependency through git instead of from rubygems,
31
31
  it does not install the necessary files by default. To fix this you can
32
32
  either install them yourself by cd-ing into the directory where this gem
33
- is located (#{File.expand_path('..', __dir__)}) and running:
33
+ is located (#{File.expand_path("..", __dir__)}) and running:
34
34
 
35
- `yarn && yarn prepublishOnly`
35
+ `yarn install`
36
36
  or
37
- `npm install && npm run prepublishOnly`
37
+ `npm install`
38
38
  or
39
39
  you can change the source in your Gemfile to point directly to rubygems.
40
40
  MSG
data/package.json CHANGED
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "@prettier/plugin-ruby",
3
- "version": "2.1.0",
3
+ "version": "3.1.1",
4
4
  "description": "prettier plugin for the Ruby programming language",
5
- "main": "dist/plugin.js",
5
+ "main": "src/plugin.js",
6
6
  "scripts": {
7
7
  "checkFormat": "prettier --check '**/*'",
8
8
  "lint": "eslint --cache .",
9
- "prepublishOnly": "tsc -p tsconfig.build.json && cp src/parser/getInfo.js dist/parser && cp src/parser/netcat.js dist/parser && cp src/parser/server.rb dist/parser && cp src/haml/parser.rb dist/haml && cp src/rbs/parser.rb dist/rbs && cp src/ruby/parser.rb dist/ruby",
10
9
  "test": "jest"
11
10
  },
12
11
  "repository": {
@@ -23,24 +22,15 @@
23
22
  "prettier": ">=2.3.0"
24
23
  },
25
24
  "devDependencies": {
26
- "@types/jest": "^27.0.1",
27
- "@types/node": "^17.0.0",
28
- "@types/prettier": "^2.4.2",
29
- "@typescript-eslint/eslint-plugin": "^5.18.0",
30
- "@typescript-eslint/parser": "^5.18.0",
31
- "eslint": "^8.1.0",
25
+ "eslint": "^8.15.0",
32
26
  "eslint-config-prettier": "^8.0.0",
33
- "husky": "^7.0.0",
34
- "jest": "^27.0.1",
35
- "pretty-quick": "^3.1.2",
36
- "ts-jest": "^27.0.5",
37
- "ts-node": "^10.2.1",
38
- "typescript": "^4.5.2"
27
+ "husky": "^8.0.1",
28
+ "jest": "^28.0.1",
29
+ "pretty-quick": "^3.1.2"
39
30
  },
40
31
  "eslintConfig": {
41
32
  "extends": [
42
33
  "eslint:recommended",
43
- "plugin:@typescript-eslint/recommended",
44
34
  "prettier"
45
35
  ],
46
36
  "env": {
@@ -48,21 +38,17 @@
48
38
  "jest": true,
49
39
  "node": true
50
40
  },
51
- "parser": "@typescript-eslint/parser",
52
41
  "rules": {
53
- "no-unused-vars": "off",
54
- "@typescript-eslint/explicit-module-boundary-types": "off",
55
- "@typescript-eslint/no-explicit-any": "off"
42
+ "no-unused-vars": "off"
56
43
  }
57
44
  },
58
45
  "jest": {
59
- "globalSetup": "./test/js/globalSetup.ts",
60
- "globalTeardown": "./test/js/globalTeardown.ts",
61
- "preset": "ts-jest",
46
+ "globalSetup": "./test/js/globalSetup.js",
47
+ "globalTeardown": "./test/js/globalTeardown.js",
62
48
  "setupFilesAfterEnv": [
63
- "./test/js/setupTests.ts"
49
+ "./test/js/setupTests.js"
64
50
  ],
65
- "testRegex": ".test.ts$"
51
+ "testRegex": ".test.js$"
66
52
  },
67
53
  "husky": {
68
54
  "hooks": {
data/rubocop.yml CHANGED
@@ -1,6 +1,5 @@
1
1
  # Disabling all Layout/* rules, as they're unnecessary when the user is using
2
- # prettier to handle all of the formatting.
3
-
2
+ # Syntax Tree to handle all of the formatting.
4
3
  Layout:
5
4
  Enabled: false
6
5
 
@@ -13,7 +12,17 @@ Layout:
13
12
  Layout/LineLength:
14
13
  Enabled: true
15
14
 
16
- Style/MultilineIfModifier: # rubyModifier
15
+ Style/MultilineIfModifier:
16
+ Enabled: false
17
+
18
+ # Syntax Tree will expand empty methods to put the end keyword on the subsequent
19
+ # line to reduce git diff noise.
20
+ Style/EmptyMethod:
21
+ EnforcedStyle: expanded
22
+
23
+ # lambdas that are constructed with the lambda method call cannot be safely
24
+ # turned into lambda literals without removing a method call.
25
+ Style/Lambda:
17
26
  Enabled: false
18
27
 
19
28
  # When method chains with multiple blocks are chained together, rubocop will let
@@ -23,22 +32,33 @@ Style/MultilineIfModifier: # rubyModifier
23
32
  Style/MultilineBlockChain:
24
33
  Enabled: false
25
34
 
26
- Style/SymbolArray: # rubyArrayLiteral
27
- Enabled: false
35
+ # Syntax Tree by default uses double quotes, so changing the configuration here
36
+ # to match that.
37
+ Style/StringLiterals:
38
+ EnforcedStyle: double_quotes
39
+
40
+ Style/StringLiteralsInInterpolation:
41
+ EnforcedStyle: double_quotes
42
+
43
+ Style/QuotedSymbols:
44
+ EnforcedStyle: double_quotes
28
45
 
29
- Style/WordArray: # rubyArrayLiteral
46
+ # We let users have a little more freedom with symbol and words arrays. If the
47
+ # user only has an individual item like ["value"] then we don't bother
48
+ # converting it because it ends up being just noise.
49
+ Style/SymbolArray:
30
50
  Enabled: false
31
51
 
32
- Style/TrailingCommaInArguments: # trailingComma
52
+ Style/WordArray:
33
53
  Enabled: false
34
54
 
35
- Style/TrailingCommaInArrayLiteral: # trailingComma
55
+ # We don't support trailing commas in Syntax Tree by default, so just turning
56
+ # these off for now.
57
+ Style/TrailingCommaInArguments:
36
58
  Enabled: false
37
59
 
38
- Style/TrailingCommaInHashLiteral: # trailingComma
60
+ Style/TrailingCommaInArrayLiteral:
39
61
  Enabled: false
40
62
 
41
- # lambdas that are constructed with the lambda method call cannot be safely
42
- # turned into lambda literals without removing a method call.
43
- Style/Lambda:
63
+ Style/TrailingCommaInHashLiteral:
44
64
  Enabled: false
@@ -1,4 +1,3 @@
1
- // eslint-disable-next-line @typescript-eslint/no-var-requires
2
1
  const { existsSync, readFileSync } = require("fs");
3
2
 
4
3
  // This is how long to wait for the parser to spin up. For the most part, 5
@@ -2,7 +2,6 @@
2
2
  // On average, this is 2-3x slower than netcat, but still much faster than
3
3
  // spawning a new Ruby process.
4
4
 
5
- // eslint-disable-next-line @typescript-eslint/no-var-requires
6
5
  const { createConnection } = require("net");
7
6
 
8
7
  const sock = process.argv[process.argv.length - 1];
data/src/parseSync.js ADDED
@@ -0,0 +1,216 @@
1
+ const { spawn, spawnSync } = require("child_process");
2
+ const {
3
+ existsSync,
4
+ unlinkSync,
5
+ mkdtempSync,
6
+ copyFileSync,
7
+ mkdirSync,
8
+ rmdirSync
9
+ } = require("fs");
10
+ const os = require("os");
11
+ const path = require("path");
12
+ const process = require("process");
13
+
14
+ let parserArgs;
15
+
16
+ if (process.env.PRETTIER_RUBY_HOST) {
17
+ const [cmd, ...args] = process.env.PRETTIER_RUBY_HOST.split(" ");
18
+ parserArgs = { cmd, args };
19
+ }
20
+
21
+ // In order to properly parse ruby code, we need to tell the ruby process to
22
+ // parse using UTF-8. Unfortunately, the way that you accomplish this looks
23
+ // differently depending on your platform.
24
+ /* istanbul ignore next */
25
+ function getLang() {
26
+ const { env, platform } = process;
27
+ const envValue = env.LC_ALL || env.LC_CTYPE || env.LANG;
28
+
29
+ // If an env var is set for the locale that already includes UTF-8 in the
30
+ // name, then assume we can go with that.
31
+ if (envValue && envValue.includes("UTF-8")) {
32
+ return envValue;
33
+ }
34
+
35
+ // Otherwise, we're going to guess which encoding to use based on the system.
36
+ // This is probably not the best approach in the world, as you could be on
37
+ // linux and not have C.UTF-8, but in that case you're probably passing an env
38
+ // var for it. This object below represents all of the possible values of
39
+ // process.platform per:
40
+ // https://nodejs.org/api/process.html#process_process_platform
41
+ return {
42
+ aix: "C.UTF-8",
43
+ android: "C.UTF-8",
44
+ cygwin: "C.UTF-8",
45
+ darwin: "en_US.UTF-8",
46
+ freebsd: "C.UTF-8",
47
+ haiku: "C.UTF-8",
48
+ linux: "C.UTF-8",
49
+ netbsd: "C.UTF-8",
50
+ openbsd: "C.UTF-8",
51
+ sunos: "C.UTF-8",
52
+ win32: ".UTF-8"
53
+ }[platform];
54
+ }
55
+
56
+ // Generate the filepath that should be used to communicate the connection
57
+ // information between this process and the parser server.
58
+ function getInfoFilepath() {
59
+ return path.join(os.tmpdir(), `prettier-ruby-parser-${process.pid}.info`);
60
+ }
61
+
62
+ // Create a file that will act as a communication mechanism, spawn a parser
63
+ // server with that filepath as an argument, then spawn another process that
64
+ // will read that information in order to enable us to connect to it in the
65
+ // spawnSync function.
66
+ function spawnServer(opts) {
67
+ const tempDir = mkdtempSync(path.join(os.tmpdir(), "prettier-plugin-ruby-"));
68
+ const filepath = getInfoFilepath();
69
+
70
+ let serverRbPath = path.join(__dirname, "./server.rb");
71
+ let getInfoJsPath = path.join(__dirname, "./getInfo.js");
72
+ let cleanupTempFiles;
73
+
74
+ if (runningInPnPZip()) {
75
+ // If we're running in a Yarn PnP environment inside a ZIP file, it's not possible to run
76
+ // the Ruby server or the getInfo.js script directly. Instead, we need to copy them and all
77
+ // the files they depend on to a temporary directory.
78
+
79
+ const sourceFiles = ["server.rb", "getInfo.js", "netcat.js"];
80
+ serverRbPath = path.join(tempDir, "server.rb");
81
+ getInfoJsPath = path.join(tempDir, "getInfo.js");
82
+
83
+ sourceFiles.forEach((rubyFile) => {
84
+ const destDir = path.join(tempDir, path.dirname(rubyFile));
85
+ if (!existsSync(destDir)) {
86
+ mkdirSync(destDir);
87
+ }
88
+ copyFileSync(
89
+ path.join(__dirname, "..", "src", rubyFile),
90
+ path.join(tempDir, rubyFile)
91
+ );
92
+ });
93
+
94
+ cleanupTempFiles = () => {
95
+ [
96
+ getInfoJsPath,
97
+ ...sourceFiles.map((rubyFile) => path.join(tempDir, rubyFile))
98
+ ].forEach((tmpFilePath) => {
99
+ if (existsSync(tmpFilePath)) {
100
+ unlinkSync(tmpFilePath);
101
+ }
102
+ });
103
+
104
+ sourceFiles.forEach((rubyFile) => {
105
+ const tempSubdir = path.join(tempDir, path.dirname(rubyFile));
106
+ if (existsSync(tempSubdir)) {
107
+ rmdirSync(tempSubdir);
108
+ }
109
+ });
110
+
111
+ if (existsSync(tempDir)) {
112
+ rmdirSync(tempDir);
113
+ }
114
+ };
115
+ }
116
+
117
+ const server = spawn(
118
+ "ruby",
119
+ [serverRbPath, `--plugins=${opts.rubyPlugins}`, filepath],
120
+ {
121
+ env: Object.assign({}, process.env, { LANG: getLang() }),
122
+ detached: true,
123
+ stdio: "inherit"
124
+ }
125
+ );
126
+
127
+ server.unref();
128
+ process.on("exit", () => {
129
+ if (existsSync(filepath)) {
130
+ unlinkSync(filepath);
131
+ }
132
+
133
+ if (cleanupTempFiles != null) {
134
+ cleanupTempFiles();
135
+ }
136
+
137
+ try {
138
+ if (server.pid) {
139
+ // Kill the server process if it's still running. If we're on windows
140
+ // we're going to use the process ID number. If we're not, we're going
141
+ // to use the negative process ID to indicate the group.
142
+ const pid = process.platform === "win32" ? server.pid : -server.pid;
143
+ process.kill(pid);
144
+ }
145
+ } catch (e) {
146
+ if (process.env.PLUGIN_RUBY_CI) {
147
+ throw new Error(`Failed to kill the parser server: ${e}`);
148
+ }
149
+ }
150
+ });
151
+
152
+ const info = spawnSync("node", [getInfoJsPath, filepath]);
153
+
154
+ if (info.status !== 0) {
155
+ throw new Error(`
156
+ We failed to spawn our parser server. Please report this error on GitHub
157
+ at https://github.com/prettier/plugin-ruby. The error message was:
158
+
159
+ ${info.stderr.toString()}.
160
+ `);
161
+ }
162
+
163
+ const [cmd, ...args] = info.stdout.toString().split(" ");
164
+ return { cmd, args };
165
+ }
166
+
167
+ // If we're in a yarn Plug'n'Play environment, then the relative paths being
168
+ // used by the parser server and the various scripts used to communicate
169
+ // therein are not going to work with its virtual file system.
170
+ function runningInPnPZip() {
171
+ return process.versions.pnp && __dirname.includes(".zip");
172
+ }
173
+
174
+ // Formats and sends a request to the parser server. We use netcat (or something
175
+ // like it) here since Prettier requires the results of `parse` to be
176
+ // synchronous and Node.js does not offer a mechanism for synchronous socket
177
+ // requests.
178
+ function parseSync(parser, source, opts) {
179
+ if (!parserArgs) {
180
+ parserArgs = spawnServer(opts);
181
+ }
182
+
183
+ const response = spawnSync(parserArgs.cmd, parserArgs.args, {
184
+ input: `${parser}|${source}`,
185
+ maxBuffer: 15 * 1024 * 1024
186
+ });
187
+
188
+ const stdout = response.stdout.toString();
189
+ const stderr = response.stderr.toString();
190
+ const { status } = response;
191
+
192
+ // If we didn't receive anything over stdout or we have a bad exit status,
193
+ // then throw whatever we can.
194
+ if (stdout.length === 0 || (status !== null && status !== 0)) {
195
+ throw new Error(stderr || "An unknown error occurred");
196
+ }
197
+
198
+ const parsed = JSON.parse(stdout);
199
+
200
+ if (parsed.error) {
201
+ const error = new Error(parsed.error);
202
+ if (parsed.loc) {
203
+ error.loc = parsed.loc;
204
+ }
205
+
206
+ throw error;
207
+ }
208
+
209
+ return parsed;
210
+ }
211
+
212
+ module.exports = {
213
+ getLang,
214
+ getInfoFilepath,
215
+ parseSync
216
+ };