Skip to content

Commit

Permalink
Support auto-restart RuboCop server
Browse files Browse the repository at this point in the history
This PR supports auto-restart RuboCop server when updating RuboCop.

First, cache RuboCop version when the RuboCop server starts.
And, auto-restarts when the runtime (client) RuboCop version does not
match the cached RuboCop version.
  • Loading branch information
koic authored and bbatsov committed Jun 21, 2022
1 parent aafc988 commit dfc6e87
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 10 deletions.
8 changes: 8 additions & 0 deletions docs/modules/ROOT/pages/usage/server.adoc
Expand Up @@ -49,6 +49,14 @@ user 16060 0.0 0.0 5078568 2264 ?? S 7:54AM 0:00.00 r
user 16337 0.0 0.0 5331560 2396 ?? S 23:51PM 0:00.00 rubocop --server /Users/user/src/github.com/rubocop/rubocop-rails
```

When you update and run `rubocop`, the server process will restart automatically.

```console
% rubocop --server
RuboCop version incompatibility found, RuboCop server restarting...
RuboCop server starting on 127.0.0.1:60665.
```

== Restart Server

The started server does not reload the configuration file.
Expand Down
8 changes: 8 additions & 0 deletions lib/rubocop/server/cache.rb
Expand Up @@ -64,6 +64,10 @@ def status_path
dir.join('status')
end

def version_path
dir.join('version')
end

def pid_running?
Process.kill(0, pid_path.read.to_i) == 1
rescue Errno::ESRCH
Expand Down Expand Up @@ -95,6 +99,10 @@ def write_pid_file
def write_status_file(status)
status_path.write(status)
end

def write_version_file(version)
version_path.write(version)
end
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions lib/rubocop/server/client_command.rb
Expand Up @@ -10,6 +10,8 @@
# https://github.com/fohte/rubocop-daemon/blob/master/LICENSE.txt
#
module RuboCop
autoload :Version, 'rubocop/version'

module Server
# @api private
module ClientCommand
Expand Down
6 changes: 0 additions & 6 deletions lib/rubocop/server/client_command/base.rb
Expand Up @@ -38,12 +38,6 @@ def check_running_server
warn 'RuboCop server is not running.' unless running
end
end

def ensure_server!
return if check_running_server

ClientCommand::Start.new([]).run
end
end
end
end
Expand Down
15 changes: 15 additions & 0 deletions lib/rubocop/server/client_command/exec.rb
Expand Up @@ -28,6 +28,21 @@ def run

private

def ensure_server!
if incompatible_version?
puts 'RuboCop version incompatibility found, RuboCop server restarting...'
ClientCommand::Stop.new.run
elsif check_running_server
return
end

ClientCommand::Start.new.run
end

def incompatible_version?
RuboCop::Version::STRING != Cache.version_path.read
end

def status
unless Cache.status_path.file?
raise "RuboCop server: Could not find status file at: #{Cache.status_path}"
Expand Down
10 changes: 6 additions & 4 deletions lib/rubocop/server/client_command/start.rb
Expand Up @@ -29,10 +29,12 @@ def run
exit 0
end

Server::Core.new.start(
ENV.fetch('RUBOCOP_SERVER_HOST', '127.0.0.1'),
ENV.fetch('RUBOCOP_SERVER_PORT', 0)
)
Cache.write_version_file(RuboCop::Version::STRING)

host = ENV.fetch('RUBOCOP_SERVER_HOST', '127.0.0.1')
port = ENV.fetch('RUBOCOP_SERVER_PORT', 0)

Server::Core.new.start(host, port)
end
end
end
Expand Down
37 changes: 37 additions & 0 deletions spec/rubocop/server/rubocop_server_spec.rb
@@ -0,0 +1,37 @@
# frozen_string_literal: true

RSpec.describe 'rubocop --server', :isolated_environment do # rubocop:disable RSpec/DescribeClass
let(:rubocop) { "#{RuboCop::ConfigLoader::RUBOCOP_HOME}/exe/rubocop" }

include_context 'cli spec behavior'

if RuboCop::Server.support_server?
context 'when using `--server` option after updating RuboCop' do
before do
options = '--server --only Style/FrozenStringLiteralComment,Style/StringLiterals'
`ruby -I . "#{rubocop}" #{options}`

# Emulating RuboCop updates. `0.99.9` is a version value for testing that
# will never be used in the real world RuboCop version.
RuboCop::Server::Cache.write_version_file('0.99.9')
end

after do
`ruby -I . "#{rubocop}" --stop-server`
end

it 'displays a restart information message' do
create_file('example.rb', <<~RUBY)
# frozen_string_literal: true
x = 0
puts x
RUBY
options = '--server --only Style/FrozenStringLiteralComment,Style/StringLiterals'
expect(`ruby -I . "#{rubocop}" #{options}`).to start_with(
'RuboCop version incompatibility found, RuboCop server restarting...'
)
end
end
end
end

0 comments on commit dfc6e87

Please sign in to comment.