Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify and allow to configure rubocop formatter #403

Merged
merged 5 commits into from
Jan 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 1 addition & 20 deletions lib/solargraph/diagnostics/rubocop_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,13 @@ module RubocopHelpers
# @param code [String]
# @return [Array(Array<String>, Array<String>)]
def generate_options filename, code
args = ['-f', 'j']
rubocop_file = find_rubocop_file(filename)
args.push('-c', fix_drive_letter(rubocop_file)) unless rubocop_file.nil?
args.push filename
args = ['-f', 'j', filename]
base_options = RuboCop::Options.new
options, paths = base_options.parse(args)
options[:stdin] = code
[options, paths]
end

# Find a RuboCop configuration file in a file's directory tree.
#
# @param filename [String]
# @return [String, nil]
def find_rubocop_file filename
return nil unless File.exist?(filename)
filename = File.realpath(filename)
dir = File.dirname(filename)
until File.dirname(dir) == dir
here = File.join(dir, '.rubocop.yml')
return here if File.exist?(here)
dir = File.dirname(dir)
end
nil
end

# RuboCop internally uses capitalized drive letters for Windows paths,
# so we need to convert the paths provided to the command.
#
Expand Down
5 changes: 5 additions & 0 deletions lib/solargraph/language_server/host.rb
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,11 @@ def read_text uri
library.read_text(filename)
end

def formatter_config uri
library = library_for(uri)
library.workspace.config.formatter
end

# @param uri [String]
# @param line [Integer]
# @param column [Integer]
Expand Down
63 changes: 46 additions & 17 deletions lib/solargraph/language_server/message/text_document/formatting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,58 @@ module TextDocument
class Formatting < Base
include Solargraph::Diagnostics::RubocopHelpers

class BlankRubocopFormatter < ::RuboCop::Formatter::BaseFormatter; end

def process
filename = uri_to_file(params['textDocument']['uri'])
Dir.mktmpdir do |tempdir|
tempfile = File.join(tempdir, File.basename(filename))
rubocop_file = Diagnostics::RubocopHelpers.find_rubocop_file(filename)
original = host.read_text(params['textDocument']['uri'])
File.write tempfile, original
begin
args = ['-a', '-f', 'fi', tempfile]
args.unshift('-c', fix_drive_letter(rubocop_file)) unless rubocop_file.nil?
options, paths = RuboCop::Options.new.parse(args)
store = RuboCop::ConfigStore.new
redirect_stdout { RuboCop::Runner.new(options, store).run(paths) }
result = File.read(tempfile)
format original, result
rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
set_error(Solargraph::LanguageServer::ErrorCodes::INTERNAL_ERROR, "[#{e.class}] #{e.message}")
end
file_uri = params['textDocument']['uri']
config = config_for(file_uri)
original = host.read_text(file_uri)
args = cli_args(file_uri, config)

options, paths = RuboCop::Options.new.parse(args)
options[:stdin] = original
redirect_stdout do
RuboCop::Runner.new(options, RuboCop::ConfigStore.new).run(paths)
end
result = options[:stdin]

format original, result
rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
set_error(Solargraph::LanguageServer::ErrorCodes::INTERNAL_ERROR, "[#{e.class}] #{e.message}")
end

private

def config_for(file_uri)
conf = host.formatter_config(file_uri)
return {} unless conf.is_a?(Hash)

conf['rubocop'] || {}
end

def cli_args file, config
args = [
config['cops'] == 'all' ? '--auto-correct-all' : '--auto-correct',
'--cache', 'false',
'--format', 'Solargraph::LanguageServer::Message::' \
'TextDocument::Formatting::BlankRubocopFormatter',
]

['except', 'only'].each do |arg|
cops = cop_list(config[arg])
args += ["--#{arg}", cops] if cops
end

args += config['extra_args'] if config['extra_args']
args + [file]
end

def cop_list(value)
value = value.join(',') if value.respond_to?(:join)
return nil if value == '' || !value.is_a?(String)
value
end

# @param original [String]
# @param result [String]
# @return [void]
Expand Down
15 changes: 15 additions & 0 deletions lib/solargraph/workspace/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ def reporters
raw_data['reporters']
end

# A hash of options supported by the formatter
#
# @return [Hash]
def formatter
raw_data['formatter']
end

# An array of plugins to require.
#
# @return [Array<String>]
Expand Down Expand Up @@ -144,6 +151,14 @@ def default_config
'require' => [],
'domains' => [],
'reporters' => %w[rubocop require_not_found],
'formatter' => {
'rubocop' => {
'cops' => 'safe',
'except' => [],
'only' => [],
'extra_args' =>[]
}
},
'require_paths' => [],
'plugins' => [],
'max_files' => MAX_FILES
Expand Down
7 changes: 0 additions & 7 deletions spec/diagnostics/rubocop_helpers_spec.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
describe Solargraph::Diagnostics::RubocopHelpers do
it "finds a .rubocop.yml file in a parent directory" do
file = File.realpath(File.join 'spec', 'fixtures', 'rubocop-subfolder-configuration', 'folder1', 'folder2', 'test.rb')
conf = File.realpath(File.join 'spec', 'fixtures', 'rubocop-subfolder-configuration', '.rubocop.yml')
found = Solargraph::Diagnostics::RubocopHelpers.find_rubocop_file(file)
expect(found).to eq(conf)
end

it "converts lower-case drive letters to upper-case" do
input = 'c:/one/two'
output = Solargraph::Diagnostics::RubocopHelpers.fix_drive_letter(input)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
describe Solargraph::LanguageServer::Message::TextDocument::Formatting do
it 'gracefully handles empty files' do
host = double(:Host, read_text: '')
host = double(:Host, read_text: '', formatter_config: {})
request = {
'params' => {
'textDocument' => {
Expand Down