prettier 2.1.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -6
- data/README.md +16 -16
- data/exe/rbprettier +2 -2
- data/lib/prettier/rake/task.rb +5 -5
- data/lib/prettier.rb +11 -11
- data/package.json +9 -23
- data/rubocop.yml +6 -6
- data/{dist/parser → src}/getInfo.js +0 -1
- data/{dist/parser → src}/netcat.js +0 -1
- data/src/parseSync.js +212 -0
- data/src/plugin.js +161 -0
- data/{dist/parser → src}/server.rb +45 -31
- metadata +94 -78
- data/bin/console +0 -7
- data/dist/haml/embed.js +0 -53
- data/dist/haml/parser.js +0 -31
- data/dist/haml/parser.rb +0 -149
- data/dist/haml/printer.js +0 -336
- data/dist/parser/parseSync.js +0 -179
- data/dist/plugin.js +0 -143
- data/dist/prettier.js +0 -15
- data/dist/rbs/parser.js +0 -34
- data/dist/rbs/parser.rb +0 -155
- data/dist/rbs/printer.js +0 -525
- data/dist/ruby/embed.js +0 -115
- data/dist/ruby/location.js +0 -19
- data/dist/ruby/nodes/alias.js +0 -60
- data/dist/ruby/nodes/aref.js +0 -51
- data/dist/ruby/nodes/args.js +0 -138
- data/dist/ruby/nodes/arrays.js +0 -122
- data/dist/ruby/nodes/assign.js +0 -37
- data/dist/ruby/nodes/blocks.js +0 -90
- data/dist/ruby/nodes/calls.js +0 -263
- data/dist/ruby/nodes/case.js +0 -50
- data/dist/ruby/nodes/class.js +0 -54
- data/dist/ruby/nodes/commands.js +0 -138
- data/dist/ruby/nodes/conditionals.js +0 -246
- data/dist/ruby/nodes/constants.js +0 -35
- data/dist/ruby/nodes/flow.js +0 -59
- data/dist/ruby/nodes/hashes.js +0 -126
- data/dist/ruby/nodes/heredocs.js +0 -30
- data/dist/ruby/nodes/hooks.js +0 -35
- data/dist/ruby/nodes/ints.js +0 -27
- data/dist/ruby/nodes/lambdas.js +0 -70
- data/dist/ruby/nodes/loops.js +0 -75
- data/dist/ruby/nodes/massign.js +0 -60
- data/dist/ruby/nodes/methods.js +0 -50
- data/dist/ruby/nodes/operators.js +0 -68
- data/dist/ruby/nodes/params.js +0 -95
- data/dist/ruby/nodes/patterns.js +0 -119
- data/dist/ruby/nodes/regexp.js +0 -45
- data/dist/ruby/nodes/rescue.js +0 -86
- data/dist/ruby/nodes/return.js +0 -100
- data/dist/ruby/nodes/statements.js +0 -110
- data/dist/ruby/nodes/strings.js +0 -220
- data/dist/ruby/nodes/super.js +0 -26
- data/dist/ruby/nodes/undef.js +0 -31
- data/dist/ruby/nodes.js +0 -177
- data/dist/ruby/parser.js +0 -35
- data/dist/ruby/parser.rb +0 -9134
- data/dist/ruby/printer.js +0 -67
- data/dist/ruby/toProc.js +0 -91
- data/dist/types/haml.js +0 -4
- data/dist/types/plugin.js +0 -3
- data/dist/types/rbs.js +0 -4
- data/dist/types/ruby.js +0 -4
- data/dist/types/utils.js +0 -2
- data/dist/types.js +0 -34
- data/dist/utils/containsAssignment.js +0 -18
- data/dist/utils/getChildNodes.js +0 -305
- data/dist/utils/getTrailingComma.js +0 -6
- data/dist/utils/hasAncestor.js +0 -15
- data/dist/utils/inlineEnsureParens.js +0 -49
- data/dist/utils/isEmptyBodyStmt.js +0 -10
- data/dist/utils/isEmptyParams.js +0 -12
- data/dist/utils/isEmptyStmts.js +0 -10
- data/dist/utils/literal.js +0 -8
- data/dist/utils/literallineWithoutBreakParent.js +0 -8
- data/dist/utils/makeCall.js +0 -14
- data/dist/utils/noIndent.js +0 -11
- data/dist/utils/printEmptyCollection.js +0 -46
- data/dist/utils/skipAssignIndent.js +0 -19
- data/dist/utils.js +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: edc974795ef0adb86312682bdedfa30cca29905f660b97334326494b8623144f
|
4
|
+
data.tar.gz: 9dcdc7ecb78e7ee4fa333b45e9f2e4b5ea5df4615869ce6b172377bf21126560
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed0166367d99fc0af3135d76c47dae06bcddd92eaf9a7d3d680726d403a2eed16f08af8fe410c527113bf00d1a0fe11b4c6743820e4c907b2de2707884655ef3
|
7
|
+
data.tar.gz: c8fa9abb2ecf3561c913f9505f7d07c56e322c6f3031d44b9725c314bfb1576c0dc68c7c7e28f8a15f9d876c4307c0c90549e1db83a4c94b184e0a872413208d
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,23 @@ 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.0.0] - 2022-05-04
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- [#1190](https://github.com/prettier/plugin-ruby/pull/1190) - kddnewton - Encoding for source files is now guessed in a much better way.
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
|
17
|
+
- [#1198](https://github.com/prettier/plugin-ruby/issues/1198) - pas-f, kddnewton - Fix crashes on JRuby with do blocks.
|
18
|
+
- [#1131](https://github.com/prettier/plugin-ruby/issues/1131) - hyrious, kddnewton - Ensure zombie processes are not left around when the server exits.
|
19
|
+
- [#1206](https://github.com/prettier/plugin-ruby/pull/1206) - kddnewton - Switch back to plain JavaScript for development.
|
20
|
+
- [#1190](https://github.com/prettier/plugin-ruby/pull/1190) - kddnewton - Switch over to using Syntax Tree for the backend.
|
21
|
+
|
22
|
+
### Removed
|
23
|
+
|
24
|
+
- [#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.
|
25
|
+
|
9
26
|
## [2.1.0] - 2022-04-04
|
10
27
|
|
11
28
|
### Added
|
@@ -316,7 +333,6 @@ The comment in the above example should stay in place.
|
|
316
333
|
|
317
334
|
```ruby
|
318
335
|
begin
|
319
|
-
|
320
336
|
rescue Foo, Bar
|
321
337
|
# comment
|
322
338
|
end
|
@@ -472,7 +488,8 @@ return (a or b) if c?
|
|
472
488
|
- kddnewton - Support for the `nokw_param` node for specifying when methods should no accept keywords, as in:
|
473
489
|
|
474
490
|
```ruby
|
475
|
-
def foo(**nil)
|
491
|
+
def foo(**nil)
|
492
|
+
end
|
476
493
|
```
|
477
494
|
|
478
495
|
- kddnewton - Support for the `args_forward` node for forwarding all types of arguments, as in:
|
@@ -518,9 +535,9 @@ will now be printed as:
|
|
518
535
|
|
519
536
|
```ruby
|
520
537
|
Config::Download.new(
|
521
|
-
|
522
|
-
filename:
|
523
|
-
url:
|
538
|
+
"prettier",
|
539
|
+
filename: "prettier.yml",
|
540
|
+
url: "https://raw.githubusercontent.com/..."
|
524
541
|
).perform
|
525
542
|
```
|
526
543
|
|
@@ -1208,7 +1225,8 @@ would previously result in `array[]`, but now prints properly.
|
|
1208
1225
|
|
1209
1226
|
- Initial release 🎉
|
1210
1227
|
|
1211
|
-
[unreleased]: https://github.com/prettier/plugin-ruby/compare/
|
1228
|
+
[unreleased]: https://github.com/prettier/plugin-ruby/compare/v3.0.0...HEAD
|
1229
|
+
[3.0.0]: https://github.com/prettier/plugin-ruby/compare/v2.1.0...v3.0.0
|
1212
1230
|
[2.1.0]: https://github.com/prettier/plugin-ruby/compare/v2.0.0...v2.1.0
|
1213
1231
|
[2.0.0]: https://github.com/prettier/plugin-ruby/compare/v2.0.0-rc4...v2.0.0
|
1214
1232
|
[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 << (
|
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] ||
|
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
|
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 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,25 @@ 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
|
132
|
-
|
|
133
|
-
| `printWidth`
|
134
|
-
| `requirePragma`
|
135
|
-
| `
|
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
|
+
| `tabWidth` | `--tab-width` | `2` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#tab-width)). |
|
142
142
|
|
143
143
|
Any of these can be added to your existing [prettier configuration
|
144
144
|
file](https://prettier.io/docs/en/configuration.html). For example:
|
145
145
|
|
146
146
|
```json
|
147
147
|
{
|
148
|
-
"
|
148
|
+
"tabWidth": 4
|
149
149
|
}
|
150
150
|
```
|
151
151
|
|
152
152
|
Or, they can be passed to `prettier` as arguments:
|
153
153
|
|
154
154
|
```bash
|
155
|
-
bundle exec rbprettier --
|
155
|
+
bundle exec rbprettier --tab-width 4 --write '**/*'
|
156
156
|
```
|
157
157
|
|
158
158
|
### Usage with RuboCop
|
data/exe/rbprettier
CHANGED
data/lib/prettier/rake/task.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
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 =
|
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
|
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([(
|
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
|
4
|
-
require
|
3
|
+
require "json" unless defined?(JSON)
|
4
|
+
require "open3"
|
5
5
|
|
6
6
|
module Prettier
|
7
|
-
PLUGIN = -File.expand_path(
|
8
|
-
BINARY = -File.join(PLUGIN,
|
9
|
-
VERSION = -JSON.parse(File.read(File.join(PLUGIN,
|
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?(
|
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({
|
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(
|
33
|
+
is located (#{File.expand_path("..", __dir__)}) and running:
|
34
34
|
|
35
|
-
`yarn
|
35
|
+
`yarn install`
|
36
36
|
or
|
37
|
-
`npm install
|
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": "
|
3
|
+
"version": "3.0.0",
|
4
4
|
"description": "prettier plugin for the Ruby programming language",
|
5
|
-
"main": "
|
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
25
|
"eslint": "^8.1.0",
|
32
26
|
"eslint-config-prettier": "^8.0.0",
|
33
27
|
"husky": "^7.0.0",
|
34
|
-
"jest": "^
|
35
|
-
"pretty-quick": "^3.1.2"
|
36
|
-
"ts-jest": "^27.0.5",
|
37
|
-
"ts-node": "^10.2.1",
|
38
|
-
"typescript": "^4.5.2"
|
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.
|
60
|
-
"globalTeardown": "./test/js/globalTeardown.
|
61
|
-
"preset": "ts-jest",
|
46
|
+
"globalSetup": "./test/js/globalSetup.js",
|
47
|
+
"globalTeardown": "./test/js/globalTeardown.js",
|
62
48
|
"setupFilesAfterEnv": [
|
63
|
-
"./test/js/setupTests.
|
49
|
+
"./test/js/setupTests.js"
|
64
50
|
],
|
65
|
-
"testRegex": ".test.
|
51
|
+
"testRegex": ".test.js$"
|
66
52
|
},
|
67
53
|
"husky": {
|
68
54
|
"hooks": {
|
data/rubocop.yml
CHANGED
@@ -13,7 +13,7 @@ Layout:
|
|
13
13
|
Layout/LineLength:
|
14
14
|
Enabled: true
|
15
15
|
|
16
|
-
Style/MultilineIfModifier:
|
16
|
+
Style/MultilineIfModifier:
|
17
17
|
Enabled: false
|
18
18
|
|
19
19
|
# When method chains with multiple blocks are chained together, rubocop will let
|
@@ -23,19 +23,19 @@ Style/MultilineIfModifier: # rubyModifier
|
|
23
23
|
Style/MultilineBlockChain:
|
24
24
|
Enabled: false
|
25
25
|
|
26
|
-
Style/SymbolArray:
|
26
|
+
Style/SymbolArray:
|
27
27
|
Enabled: false
|
28
28
|
|
29
|
-
Style/WordArray:
|
29
|
+
Style/WordArray:
|
30
30
|
Enabled: false
|
31
31
|
|
32
|
-
Style/TrailingCommaInArguments:
|
32
|
+
Style/TrailingCommaInArguments:
|
33
33
|
Enabled: false
|
34
34
|
|
35
|
-
Style/TrailingCommaInArrayLiteral:
|
35
|
+
Style/TrailingCommaInArrayLiteral:
|
36
36
|
Enabled: false
|
37
37
|
|
38
|
-
Style/TrailingCommaInHashLiteral:
|
38
|
+
Style/TrailingCommaInHashLiteral:
|
39
39
|
Enabled: false
|
40
40
|
|
41
41
|
# lambdas that are constructed with the lambda method call cannot be safely
|
@@ -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,212 @@
|
|
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() {
|
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("ruby", [serverRbPath, filepath], {
|
118
|
+
env: Object.assign({}, process.env, { LANG: getLang() }),
|
119
|
+
detached: true,
|
120
|
+
stdio: "inherit"
|
121
|
+
});
|
122
|
+
|
123
|
+
server.unref();
|
124
|
+
process.on("exit", () => {
|
125
|
+
if (existsSync(filepath)) {
|
126
|
+
unlinkSync(filepath);
|
127
|
+
}
|
128
|
+
|
129
|
+
if (cleanupTempFiles != null) {
|
130
|
+
cleanupTempFiles();
|
131
|
+
}
|
132
|
+
|
133
|
+
try {
|
134
|
+
if (server.pid) {
|
135
|
+
// Kill the server process if it's still running. If we're on windows
|
136
|
+
// we're going to use the process ID number. If we're not, we're going
|
137
|
+
// to use the negative process ID to indicate the group.
|
138
|
+
const pid = process.platform === "win32" ? server.pid : -server.pid;
|
139
|
+
process.kill(pid);
|
140
|
+
}
|
141
|
+
} catch (e) {
|
142
|
+
if (process.env.PLUGIN_RUBY_CI) {
|
143
|
+
throw new Error(`Failed to kill the parser server: ${e}`);
|
144
|
+
}
|
145
|
+
}
|
146
|
+
});
|
147
|
+
|
148
|
+
const info = spawnSync("node", [getInfoJsPath, filepath]);
|
149
|
+
|
150
|
+
if (info.status !== 0) {
|
151
|
+
throw new Error(`
|
152
|
+
We failed to spawn our parser server. Please report this error on GitHub
|
153
|
+
at https://github.com/prettier/plugin-ruby. The error message was:
|
154
|
+
|
155
|
+
${info.stderr.toString()}.
|
156
|
+
`);
|
157
|
+
}
|
158
|
+
|
159
|
+
const [cmd, ...args] = info.stdout.toString().split(" ");
|
160
|
+
return { cmd, args };
|
161
|
+
}
|
162
|
+
|
163
|
+
// If we're in a yarn Plug'n'Play environment, then the relative paths being
|
164
|
+
// used by the parser server and the various scripts used to communicate
|
165
|
+
// therein are not going to work with its virtual file system.
|
166
|
+
function runningInPnPZip() {
|
167
|
+
return process.versions.pnp && __dirname.includes(".zip");
|
168
|
+
}
|
169
|
+
|
170
|
+
// Formats and sends a request to the parser server. We use netcat (or something
|
171
|
+
// like it) here since Prettier requires the results of `parse` to be
|
172
|
+
// synchronous and Node.js does not offer a mechanism for synchronous socket
|
173
|
+
// requests.
|
174
|
+
function parseSync(parser, source) {
|
175
|
+
if (!parserArgs) {
|
176
|
+
parserArgs = spawnServer();
|
177
|
+
}
|
178
|
+
|
179
|
+
const response = spawnSync(parserArgs.cmd, parserArgs.args, {
|
180
|
+
input: `${parser}|${source}`,
|
181
|
+
maxBuffer: 15 * 1024 * 1024
|
182
|
+
});
|
183
|
+
|
184
|
+
const stdout = response.stdout.toString();
|
185
|
+
const stderr = response.stderr.toString();
|
186
|
+
const { status } = response;
|
187
|
+
|
188
|
+
// If we didn't receive anything over stdout or we have a bad exit status,
|
189
|
+
// then throw whatever we can.
|
190
|
+
if (stdout.length === 0 || (status !== null && status !== 0)) {
|
191
|
+
throw new Error(stderr || "An unknown error occurred");
|
192
|
+
}
|
193
|
+
|
194
|
+
const parsed = JSON.parse(stdout);
|
195
|
+
|
196
|
+
if (parsed.error) {
|
197
|
+
const error = new Error(parsed.error);
|
198
|
+
if (parsed.loc) {
|
199
|
+
error.loc = parsed.loc;
|
200
|
+
}
|
201
|
+
|
202
|
+
throw error;
|
203
|
+
}
|
204
|
+
|
205
|
+
return parsed;
|
206
|
+
}
|
207
|
+
|
208
|
+
module.exports = {
|
209
|
+
getLang,
|
210
|
+
getInfoFilepath,
|
211
|
+
parseSync
|
212
|
+
};
|