Socket
Socket
Sign inDemoInstall

@prettier/plugin-ruby

Package Overview
Dependencies
1
Maintainers
13
Versions
78
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.2.2 to 4.0.0

17

CHANGELOG.md

@@ -9,2 +9,14 @@ # Changelog

## [4.0.0] - 2023-07-06
### Added
- [#1283](https://github.com/prettier/plugin-ruby/pull/1283) - oriolgual - Use `process.execPath` instead of `"node"`.
- [#1358](https://github.com/prettier/plugin-ruby/pull/1358) - davidalejandroaguilar - Add the `rubyExecutablePath` option.
- [#1359](https://github.com/prettier/plugin-ruby/pull/1359) - kddnewton - Inherit stderr from the parser process in order to provide better error messages when failing to spawn parser server. This will put out missing gem errors, for example.
### Changed
- [#1360](https://github.com/prettier/plugin-ruby/pull/1360) - kddnewton - Require prettier v3.0.0+.
## [3.2.2] - 2022-09-20

@@ -63,3 +75,3 @@

- [#1206](https://github.com/prettier/plugin-ruby/pull/1206) - kddnewton - Switch back to plain JavaScript for development.
- [#1190](https://github.com/prettier/plugin-ruby/pull/1190) - kddnewton - Switch over to using Syntax Tree for the backend.
- [#1190](https://github.com/prettier/plugin-ruby/pull/1190) - kddnewton - Switch over to using Syntax Tree for the backend. This now requires that users install the necessary gems.

@@ -1272,3 +1284,4 @@ ### Removed

[unreleased]: https://github.com/prettier/plugin-ruby/compare/v3.2.2...HEAD
[unreleased]: https://github.com/prettier/plugin-ruby/compare/v4.0.0...HEAD
[4.0.0]: https://github.com/prettier/plugin-ruby/compare/v3.2.2...v4.0.0
[3.2.2]: https://github.com/prettier/plugin-ruby/compare/v3.2.1...v3.2.2

@@ -1275,0 +1288,0 @@ [3.2.1]: https://github.com/prettier/plugin-ruby/compare/v3.2.0...v3.2.1

25

package.json
{
"name": "@prettier/plugin-ruby",
"version": "3.2.2",
"version": "4.0.0",
"description": "prettier plugin for the Ruby programming language",
"type": "module",
"main": "src/plugin.js",

@@ -9,3 +10,3 @@ "scripts": {

"lint": "eslint --cache .",
"test": "jest"
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
},

@@ -23,9 +24,9 @@ "repository": {

"dependencies": {
"prettier": ">=2.3.0"
"prettier": ">=3.0.0"
},
"devDependencies": {
"eslint": "^8.15.0",
"eslint-config-prettier": "^8.0.0",
"eslint": "^8.35.0",
"eslint-config-prettier": "^8.7.0",
"husky": "^8.0.1",
"jest": "^29.0.0",
"jest": "^29.5.0",
"pretty-quick": "^3.1.2"

@@ -39,8 +40,11 @@ },

"env": {
"es6": true,
"jest": true,
"node": true
},
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module"
},
"rules": {
"no-unused-vars": "off"
"no-undef": "off"
}

@@ -54,3 +58,4 @@ },

],
"testRegex": ".test.js$"
"testRegex": ".test.js$",
"transform": {}
},

@@ -65,5 +70,5 @@ "husky": {

"plugins": [
"."
"./src/plugin.js"
]
}
}

@@ -12,3 +12,3 @@ <div align="center">

<a href="https://github.com/prettier/plugin-ruby/actions">
<img alt="GitHub Actions" src="https://img.shields.io/github/workflow/status/prettier/plugin-ruby/Main?style=flat-square">
<img alt="GitHub Actions" src="https://img.shields.io/github/actions/workflow/status/prettier/plugin-ruby/main.yml?branch=main&style=flat-square">
</a>

@@ -72,40 +72,10 @@ <a href="https://www.npmjs.com/package/@prettier/plugin-ruby">

To run `prettier` with the Ruby plugin, you're going to need [`ruby`](https://www.ruby-lang.org/en/documentation/installation/) (version `2.7.3` or newer) and [`node`](https://nodejs.org/en/download/) (version `8.3` or newer). If you're integrating with a project that is not already using `prettier`, you should use the Ruby gem. Otherwise you can use the `npm` package directly.
The `@prettier/plugin-ruby` plugin for `prettier` is a small wrapper around the [Syntax Tree](https://github.com/ruby-syntax-tree/syntax_tree) gem that provides a Ruby formatter for `prettier`. It does this by keeping a Ruby server running in that background that `prettier` can communicate with when it needs to format a Ruby file. This means that in order to function, you will need to have both the requisite `node` and `ruby` dependencies installed. Because of this configuration, there are a couple of ways that you can get setup to use this plugin.
Note that currently the editor integrations work best with the `npm` package, as most of the major editor plugins expect a `node_modules` directory. You can get them to work with the Ruby gem, but it requires manually configuring the paths.
- If you're already using `prettier` in your project to format other files in your project and want to install this as a plugin, you can install it using `npm`.
- If you're not using `prettier` yet in your project, then we recommend using the [Syntax Tree](https://github.com/ruby-syntax-tree/syntax_tree) gem directly instead of using this plugin.
- Note that this plugin also ships a gem named `prettier` which is a wrapper around the `prettier` CLI and includes this plugin by default, but _we no longer recommend its use_. If you're using that gem, you should migrate to using [Syntax Tree](https://github.com/ruby-syntax-tree/syntax_tree) instead.
This plugin currently supports formatting the following kinds of files:
To run `prettier` with the Ruby plugin as an `npm` package, you're going to need [`ruby`](https://www.ruby-lang.org/en/documentation/installation/) (version `2.7` or newer) and [`node`](https://nodejs.org/en/download/) (version `16` or newer).
- All varieties of Ruby source files (e.g., `*.rb`, `*.gemspec`, `Gemfile`, etc.)
- [RBS type language](https://github.com/ruby/rbs) files - requires having the `rbs` gem in your gem path
- [HAML template language](https://haml.info/) files - requires having the `haml` gem in your gem path
### Ruby gem
Add this line to your application's Gemfile:
```ruby
gem "prettier"
```
And then execute:
```bash
bundle
```
Or install it yourself as:
```bash
gem install prettier
```
The `rbprettier` executable is now installed and ready for use:
```bash
bundle exec rbprettier --write '**/*'
```
### `npm` package
If you're using the `npm` CLI, then add the plugin by:

@@ -139,10 +109,11 @@

| API Option | CLI Option | Default | Description |
| --------------- | ------------------ | :-----: | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `printWidth` | `--print-width` | `80` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#print-width)). |
| `requirePragma` | `--require-pragma` | `false` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#require-pragma)). |
| `rubyPlugins` | `--ruby-plugins` | `""` | The comma-separated list of plugins to require. See [Syntax Tree](https://github.com/ruby-syntax-tree/syntax_tree#plugins). |
| `tabWidth` | `--tab-width` | `2` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#tab-width)). |
| `singleQuote` | `--single-quote` | `false` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#quotes)). |
| `trailingComma` | `--trailing-comma` | `es5` | Almost same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#trailing-commas)). Will be on for any value except `none`. |
| API Option | CLI Option | Default | Description |
| -------------------- | --------------------- | :------------------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `printWidth` | `--print-width` | `80` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#print-width)). |
| `requirePragma` | `--require-pragma` | `false` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#require-pragma)). |
| `rubyExecutablePath` | `"ruby"` | Allows you to configure your Ruby executable path. |
| `rubyPlugins` | `--ruby-plugins` | `""` | The comma-separated list of plugins to require. See [Syntax Tree](https://github.com/ruby-syntax-tree/syntax_tree#plugins). |
| `rubySingleQuote` | `--ruby-single-quote` | `false` | Whether or not to default to single quotes for Ruby code. See [Syntax Tree](https://github.com/ruby-syntax-tree/syntax_tree#plugins). |
| `tabWidth` | `--tab-width` | `2` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#tab-width)). |
| `trailingComma` | `--trailing-comma` | `es5` | Almost same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#trailing-commas)). Will be on for any value except `none`. |

@@ -164,20 +135,11 @@ Any of these can be added to your existing [prettier configuration

### Usage with RuboCop
### Ignoring code
RuboCop and Prettier for Ruby serve different purposes, but there is overlap
with some of RuboCop's functionality.
Sometimes you want to leave your formatting in place and have `prettier` not format it, but continue to format the rest of the file. `prettier` has the ability to do this with `prettier-ignore` comments, but because the underlying formatter for this plugin is [Syntax Tree](https://github.com/ruby-syntax-tree/syntax_tree), you instead would use a `stree-ignore` comment.
Prettier provides a RuboCop configuration file to disable the rules which clash.
To enable, add the following config at the top of your project's `.rubocop.yml`:
### Usage with RuboCop
#### Ruby gem
RuboCop and Prettier for Ruby serve different purposes, but there is overlap with some of RuboCop's functionality. Prettier provides a RuboCop configuration file to disable the rules which would clash. To enable this file, add the following configuration at the top of your project's `.rubocop.yml`:
```yaml
inherit_gem:
prettier: rubocop.yml
```
#### `npm` package
```yaml
inherit_from:

@@ -208,5 +170,7 @@ - node_modules/@prettier/plugin-ruby/rubocop.yml

Check out our [contributing guide](CONTRIBUTING.md). Bug reports and pull requests are welcome on GitHub at https://github.com/prettier/plugin-ruby.
Thanks so much for your interest in contributing! You can contribute in many ways, including:
You can support `prettier/plugin-ruby` [on OpenCollective](https://opencollective.com/prettier-ruby/contribute). Your organization's logo will show up here with a link to your website.
- Contributing code to fix any bugs on [GitHub](https://github.com/prettier/plugin-ruby).
- Reporting issues on [GitHub](https://github.com/prettier/plugin-ruby/issues/new).
- Supporting `prettier/plugin-ruby` on [OpenCollective](https://opencollective.com/prettier-ruby/contribute). Your organization's logo will show up here with a link to your website.

@@ -213,0 +177,0 @@ <!-- prettier-ignore-start -->

@@ -1,8 +0,188 @@

const { parseSync } = require("./parseSync");
import { spawn } from "child_process";
import fs from "fs";
import net from "net";
import os from "os";
import path from "path";
import process from "process";
import url from "url";
/*
* metadata mostly pulled from linguist and rubocop:
* https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
* https://github.com/rubocop/rubocop/blob/master/spec/rubocop/target_finder_spec.rb
*/
// In order to properly parse ruby code, we need to tell the ruby process to
// parse using UTF-8. Unfortunately, the way that you accomplish this looks
// differently depending on your platform.
function getLang() {
const { env, platform } = process;
const envValue = env.LC_ALL || env.LC_CTYPE || env.LANG;
// If an env var is set for the locale that already includes UTF-8 in the
// name, then assume we can go with that.
if (envValue && envValue.includes("UTF-8")) {
return envValue;
}
// Otherwise, we're going to guess which encoding to use based on the system.
// This is probably not the best approach in the world, as you could be on
// linux and not have C.UTF-8, but in that case you're probably passing an env
// var for it. This object below represents all of the possible values of
// process.platform per:
// https://nodejs.org/api/process.html#process_process_platform
return {
aix: "C.UTF-8",
android: "C.UTF-8",
cygwin: "C.UTF-8",
darwin: "en_US.UTF-8",
freebsd: "C.UTF-8",
haiku: "C.UTF-8",
linux: "C.UTF-8",
netbsd: "C.UTF-8",
openbsd: "C.UTF-8",
sunos: "C.UTF-8",
win32: ".UTF-8"
}[platform];
}
// Return the list of plugins that should be passed to the server process.
function getPlugins(opts) {
const plugins = new Set();
const rubyPlugins = opts.rubyPlugins.trim();
if (rubyPlugins.length > 0) {
rubyPlugins.split(",").forEach((plugin) => plugins.add(plugin.trim()));
}
if (opts.rubySingleQuote) {
plugins.add("plugin/single_quotes");
}
if (opts.trailingComma !== "none") {
plugins.add("plugin/trailing_comma");
}
return Array.from(plugins);
}
// Create a file that will act as a communication mechanism, spawn a parser
// server with that filepath as an argument, then wait for the file to be
// created that will contain the connection information.
export async function spawnServer(opts, killOnExit = true) {
const tmpdir = os.tmpdir();
const filepath = path.join(tmpdir, `prettier-ruby-parser-${process.pid}.txt`);
const server = spawn(
opts.rubyExecutablePath || "ruby",
[
url.fileURLToPath(new URL("./server.rb", import.meta.url)),
`--plugins=${getPlugins(opts).join(",")}`,
filepath
],
{
env: Object.assign({}, process.env, { LANG: getLang() }),
stdio: ["ignore", "ignore", "inherit"],
detached: true
}
);
server.unref();
if (killOnExit) {
process.on("exit", () => {
if (fs.existsSync(filepath)) {
fs.unlinkSync(filepath);
}
try {
if (server.pid) {
// Kill the server process if it's still running. If we're on windows
// we're going to use the process ID number. If we're not, we're going
// to use the negative process ID to indicate the group.
const pid = process.platform === "win32" ? server.pid : -server.pid;
process.kill(pid);
}
} catch (error) {
// If there's an error killing the process, we're going to ignore it.
}
});
}
return new Promise((resolve, reject) => {
const interval = setInterval(() => {
if (fs.existsSync(filepath)) {
const connectionJSON = fs.readFileSync(filepath).toString("utf-8");
resolve({
serverPID: server.pid,
connectionFilepath: filepath,
connectionOptions: JSON.parse(connectionJSON)
});
clearTimeout(timeout);
clearInterval(interval);
} else if (server.exitCode) {
reject(new Error("Failed to start parse server."));
clearTimeout(timeout);
clearInterval(interval);
}
}, 100);
const timeout = setTimeout(
() => {
const message =
"Failed to get connection options from parse server in time. If this happens repeatedly, try increasing the PRETTIER_RUBY_TIMEOUT_MS environment variable beyond 10000.";
clearInterval(interval);
reject(new Error(message));
},
parseInt(process.env.PRETTIER_RUBY_TIMEOUT_MS || "10000", 10)
);
});
}
let connectionOptions;
if (process.env.PRETTIER_RUBY_HOST) {
connectionOptions = JSON.parse(process.env.PRETTIER_RUBY_HOST);
}
// Formats and sends a request to the parser server. We use netcat (or something
// like it) here since Prettier requires the results of `parse` to be
// synchronous and Node.js does not offer a mechanism for synchronous socket
// requests.
async function parse(parser, source, opts) {
if (!connectionOptions) {
const spawnedServer = await spawnServer(opts);
connectionOptions = spawnedServer.connectionOptions;
}
return new Promise((resolve, reject) => {
const socket = new net.Socket();
socket.on("error", reject);
socket.on("data", (data) => {
const response = JSON.parse(data.toString("utf-8"));
if (response.error) {
const error = new Error(response.error);
if (response.loc) {
error.loc = response.loc;
}
reject(error);
}
resolve(response);
});
socket.connect(connectionOptions, () => {
socket.end(
JSON.stringify({
parser,
source,
maxwidth: opts.printWidth,
tabwidth: opts.tabWidth
})
);
});
});
}
// Metadata mostly pulled from linguist and rubocop:
// https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
// https://github.com/rubocop/rubocop/blob/master/spec/rubocop/target_finder_spec.rb
const plugin = {

@@ -84,4 +264,4 @@ languages: [

ruby: {
parse(text, _parsers, opts) {
return parseSync("ruby", text, opts);
parse(text, opts) {
return parse("ruby", text, opts);
},

@@ -100,4 +280,4 @@ astFormat: "ruby",

rbs: {
parse(text, _parsers, opts) {
return parseSync("rbs", text, opts);
parse(text, opts) {
return parse("rbs", text, opts);
},

@@ -116,4 +296,4 @@ astFormat: "rbs",

haml: {
parse(text, _parsers, opts) {
return parseSync("haml", text, opts);
parse(text, opts) {
return parse("haml", text, opts);
},

@@ -163,4 +343,20 @@ astFormat: "haml",

default: "",
description: "The comma-separated list of plugins to require",
description: "The comma-separated list of plugins to require.",
since: "3.1.0"
},
rubySingleQuote: {
type: "boolean",
category: "Ruby",
default: false,
description:
"When double quotes are not necessary for interpolation, prefers the use of single quotes for string literals.",
since: "1.0.0"
},
rubyExecutablePath: {
type: "string",
category: "Ruby",
default: "ruby",
description:
"The path to the Ruby executable to use to run the formatter.",
since: "3.3.0"
}

@@ -176,2 +372,2 @@ },

module.exports = plugin;
export default plugin;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc