Skip to content

Commit

Permalink
Integrate rubocop-daemon
Browse files Browse the repository at this point in the history
The integrated daemon feature is described in the docs/modules/ROOT/pages/usage/server.adoc
included in this PR.

## Daemon options

```console
% bundle exec rubocop --help
(snip)

Server Options:
        --[no-]server                If the daemon process has not started yet, start the
                                     server process and execute inspection with server.
                                     Default is false.
                                     You can specify the daemon host and port with
                                     the $RUBOCOP_SERVER_HOST and the $RUBOCOP_SERVER_PORT
                                     environment variables.
        --restart-server             Restart server process.
        --start-server               Start server process.
        --stop-server                Stop server process.
        --server-status              Show server status.
```

The daemon mode `--daemon` is disabled by default because it is not yet
stable as an integrated feature.

## Design note

`RuboCop::Daemon::CLI`'s daemon options are not integrated into
`RuboCop::CLI` and `RuboCop::Options`.
Because `RuboCop::CLI` and `RuboCop::Options` classes have many dependencies
and require the rubocop client (`exe/rubocop`) to make unnecessary `require '...'`.

It's important to be lightweight because the daemon mode runs fast,
so this design decided to have command line daemon options
own (lightweight) option parse logic.

And this design only exe/rubocop and lib/rubocop/options.rb files have changed,
So almost all daemon code keep independent.

NOTE: This feature cannot be used on JRuby and Windows that do not support fork.
  • Loading branch information
koic committed Jun 10, 2022
1 parent f8d8693 commit c76ff8d
Show file tree
Hide file tree
Showing 35 changed files with 795 additions and 315 deletions.
1 change: 1 addition & 0 deletions bin/console
Expand Up @@ -4,6 +4,7 @@
require 'bundler/setup'
require 'irb'
require 'rubocop'
require 'rubocop/server'

ARGV.clear

Expand Down
1 change: 1 addition & 0 deletions changelog/new_integrate_rubocop_server.md
@@ -0,0 +1 @@
* [#10706](https://github.com/rubocop/rubocop/pull/10706): Integrate rubocop-daemon to add server options. ([@koic][])
1 change: 1 addition & 0 deletions codespell.txt
@@ -1,4 +1,5 @@
ba
creat
enviromnent
filetest
fo
Expand Down
1 change: 1 addition & 0 deletions docs/modules/ROOT/nav.adoc
Expand Up @@ -5,6 +5,7 @@
** xref:usage/basic_usage.adoc[Basic Usage]
** xref:usage/autocorrect.adoc[Autocorrect]
** xref:usage/caching.adoc[Caching]
** xref:usage/server.adoc[Server]
* xref:configuration.adoc[Configuration]
* xref:cops.adoc[Cops]
* xref:formatters.adoc[Formatters]
Expand Down
2 changes: 1 addition & 1 deletion docs/modules/ROOT/pages/integration_with_other_tools.adoc
Expand Up @@ -7,7 +7,7 @@ to do autocorrection for you. In these cases, `rubocop` ends up getting called r
which may result in some slowness, as `rubocop` has to require its entire environment on
each call.

You can alleviate some of that boot time by using
You can alleviate some of that boot time by using xref:server.adoc["Server"] or
https://github.com/fohte/rubocop-daemon[rubocop-daemon]. `rubocop-daemon` is a
wrapper around `rubocop` that loads everything into a daemonized process so that
subsequent runs save on that boot time after the first execution. Please see the
Expand Down
84 changes: 84 additions & 0 deletions docs/modules/ROOT/pages/usage/server.adoc
@@ -0,0 +1,84 @@
= Server Mode

You can reduce the RuboCop boot time by using the `--server` option.

The server option speeds up the launch of the `rubocop` command by serverizing
the process that loaded the RuboCop runtime production files (i.e. `require 'rubocop'`).

NOTE: The feature cannot be used on JRuby and Windows that do not support fork.

== Run with Server

There are two ways to enable server.

- `rubocop --server` ... If server process has not started yet,
start server process and execute inspection with server.
- `rubocop --start-server` ... Just start server process.

When server is started, it outputs the host and port.

```console
% rubocop --start-server
RuboCop server starting on 127.0.0.1:55772.
```

NOTE: The `rubocop` command is executed using server process if server is started.
Whenever server process is not running, it will load the RuboCop runtime files and execute.
(same behavior as 1.30 and lower)

If server is already running, just display the PID. The new server will not start.

```console
% rubocop --start-server
RuboCop server (16060) is already running.
```

A started server process name is `rubocop --server` with project directory path.

```console
% ps aux | grep 'rubocop --server'
user 16060 0.0 0.0 5078568 2264 ?? S 7:54AM 0:00.00 rubocop --server /Users/user/src/github.com/rubocop/rubocop
user 16337 0.0 0.0 5331560 2396 ?? S 23:51PM 0:00.00 rubocop --server /Users/user/src/github.com/rubocop/rubocop-rails
```

== Restart Server

The started server does not reload the configuration file.
You will need to restart server when you upgrade RuboCop or change
the RuboCop configuration.

```console
% rubocop --restart-server
RuboCop server starting on 127.0.0.1:55822.
```

This may be supported so that no reboot is required in future.

== Command Line Options

These are options for server operations.

* `--server` ... If server process has not started yet, start the
server process and execute inspection with server. You can specify
the server host and port with the $RUBOCOP_SERVER_HOST and
the $RUBOCOP_SERVER_PORT environment variables.
* `--no-server` ... If server process has been started, stop the
server process and execute inspection with server.
* `--restart-server` ... Restart server process.
* `--start-server` ... Start server process.
* `--stop-server` ... Stop server process.
* `--server-status` ... Show server status.

== Environment Variables

You can change the startup host and port of server process with
environment variables.

* `$RUBOCOP_SERVER_HOST`
* `$RUBOCOP_SERVER_PORT`

The following is an example:

```console
% RUBOCOP_SERVER_PORT=98989 rubocop --start-server
```
22 changes: 15 additions & 7 deletions exe/rubocop
Expand Up @@ -3,13 +3,21 @@

$LOAD_PATH.unshift("#{__dir__}/../lib")

require 'rubocop'
require 'benchmark'
require 'rubocop/server'
server_cli = RuboCop::Server::CLI.new
exit_status = server_cli.run
exit exit_status if server_cli.exit?

cli = RuboCop::CLI.new
result = 0
if RuboCop::Server.running?
exit_status = RuboCop::Server::ClientCommand::Exec.new.run
else
require 'rubocop'
require 'benchmark'

time = Benchmark.realtime { result = cli.run }
cli = RuboCop::CLI.new

puts "Finished in #{time} seconds" if cli.options[:debug] || cli.options[:display_time]
exit result
time = Benchmark.realtime { exit_status = cli.run }

puts "Finished in #{time} seconds" if cli.options[:debug] || cli.options[:display_time]
end
exit exit_status
41 changes: 0 additions & 41 deletions lib/rubocop/daemon.rb

This file was deleted.

62 changes: 0 additions & 62 deletions lib/rubocop/daemon/cli.rb

This file was deleted.

23 changes: 0 additions & 23 deletions lib/rubocop/daemon/client_command.rb

This file was deleted.

35 changes: 0 additions & 35 deletions lib/rubocop/daemon/client_command/restart.rb

This file was deleted.

48 changes: 0 additions & 48 deletions lib/rubocop/daemon/client_command/start.rb

This file was deleted.

0 comments on commit c76ff8d

Please sign in to comment.