prettier 2.1.0 → 3.0.0
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/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
|
+
};
|