diff --git a/rubocop_command.py b/rubocop_command.py index 243baf4..fad8ec2 100644 --- a/rubocop_command.py +++ b/rubocop_command.py @@ -8,11 +8,13 @@ from RuboCop.rubocop_runner import RubocopRunner from RuboCop.constants import * from RuboCop.rubocop_listener import RubocopEventListener + from RuboCop.rubocop_plugin import RubocopPlugin else: from file_tools import FileTools from rubocop_runner import RubocopRunner from constants import * from rubocop_listener import RubocopEventListener + from rubocop_plugin import RubocopPlugin # Base class for all RuboCop commands class RubocopCommand(sublime_plugin.TextCommand): @@ -31,47 +33,21 @@ def load_config(self): 'custom_rubocop_cmd': s.get('rubocop_command'), 'rvm_auto_ruby_path': s.get('rvm_auto_ruby_path'), 'rbenv_path': s.get('rbenv_path'), - 'on_windows': self.on_windows(), + 'on_windows': RubocopPlugin.on_windows(), 'rubocop_config_file': cfg_file, - 'is_st2': self.is_st2() + 'is_st2': RubocopPlugin.is_st2(), + 'chdir': RubocopPlugin.current_project_folder() } ) - def on_windows(self): - return sublime.platform() == 'windows' - - def is_st2(self): - return int(sublime.version()) < 3000 - - def is_st3(self): - return int(sublime.version()) >= 3000 - def used_options(self): return [] - def current_project_folder(self): - if self.is_st3(): - project = sublime.active_window().project_data() - project_base_path = os.path.dirname(sublime.active_window().project_file_name() or '') - if not (project is None): - if 'folders' in project: - folders = project['folders'] - if len(folders) > 0: - first_folder = folders[0] - if 'path' in first_folder: - path = first_folder['path'] - return (path if os.path.isabs(path) else os.path.join(project_base_path, path)) or '' - else: - folders = sublime.active_window().folders() - if (not (folders is None)) and (len(folders) > 0): - return folders[0] - return '' - def run_rubocop_on(self, pathlist): if len(pathlist) == 0: return - working_dir = self.current_project_folder() + working_dir = RubocopPlugin.current_project_folder() quoted_paths = [] for path in pathlist: @@ -115,7 +91,6 @@ def run(self, edit): cancel_op = self.user_wants_to_cancel() if cancel_op: return - view = self.view path = view.file_name() quoted_file_path = FileTools.quote(path) @@ -135,9 +110,7 @@ def run(self, edit): view.run_command('save') RubocopEventListener.instance().clear_marks(view) - - quoted_file_path = FileTools.quote(path) - + # Run rubocop with auto-correction self.runner.run([quoted_file_path], ['-a']) @@ -160,13 +133,13 @@ def user_wants_to_cancel(self): """) def write_to_file(self, f, content, view): - if self.is_st2(): + if RubocopPlugin.is_st2(): f.write(content) return f.write(bytes(content, view.encoding())) def read_from_file(self, f, view): - if self.is_st2(): + if RubocopPlugin.is_st2(): return f.read() return f.read().decode(view.encoding()) diff --git a/rubocop_listener.py b/rubocop_listener.py index b63a6bf..a295443 100644 --- a/rubocop_listener.py +++ b/rubocop_listener.py @@ -8,10 +8,12 @@ from RuboCop.file_tools import FileTools from RuboCop.rubocop_runner import RubocopRunner from RuboCop.constants import * + from RuboCop.rubocop_plugin import RubocopPlugin else: from file_tools import FileTools from rubocop_runner import RubocopRunner from constants import * + from rubocop_plugin import RubocopPlugin # Event listener to provide on the fly checks when saving a ruby file. class RubocopEventListener(sublime_plugin.EventListener): @@ -93,7 +95,7 @@ def run_rubocop(self, view): rvm_path = view.settings().get('rvm_auto_ruby_path', s.get('rvm_auto_ruby_path')) rbenv_path = view.settings().get('rbenv_path', s.get('rbenv_path')) cfg_file = view.settings().get('rubocop_config_file', s.get('rubocop_config_file')) - chdir = view.settings().get('rubocop_chdir', s.get('rubocop_chdir')) + chdir = view.settings().get('rubocop_chdir', s.get('rubocop_chdir')) or RubocopPlugin.current_project_folder() if cfg_file: cfg_file = FileTools.quote(cfg_file) @@ -105,7 +107,7 @@ def run_rubocop(self, view): 'custom_rubocop_cmd': cmd, 'rvm_auto_ruby_path': rvm_path, 'rbenv_path': rbenv_path, - 'on_windows': sublime.platform() == 'windows', + 'on_windows': RubocopPlugin.on_windows(), 'rubocop_config_file': cfg_file, 'chdir': chdir, 'is_st2': sublime.version() < '3000' diff --git a/rubocop_plugin.py b/rubocop_plugin.py new file mode 100644 index 0000000..e48aa80 --- /dev/null +++ b/rubocop_plugin.py @@ -0,0 +1,35 @@ +import sublime +import os + +class RubocopPlugin: + + @staticmethod + def on_windows(): + return sublime.platform() == 'windows' + + @staticmethod + def is_st2(): + return int(sublime.version()) < 3000 + + @staticmethod + def is_st3(): + return int(sublime.version()) >= 3000 + + @staticmethod + def current_project_folder(): + if RubocopPlugin.is_st3(): + project = sublime.active_window().project_data() + project_base_path = os.path.dirname(sublime.active_window().project_file_name() or '') + if not (project is None): + if 'folders' in project: + folders = project['folders'] + if len(folders) > 0: + first_folder = folders[0] + if 'path' in first_folder: + path = first_folder['path'] + return (path if os.path.isabs(path) else os.path.join(project_base_path, path)) or '' + else: + folders = sublime.active_window().folders() + if (not (folders is None)) and (len(folders) > 0): + return folders[0] + return '' \ No newline at end of file diff --git a/rubocop_runner.py b/rubocop_runner.py index 52e9e69..f7a000d 100644 --- a/rubocop_runner.py +++ b/rubocop_runner.py @@ -2,6 +2,7 @@ import subprocess import shlex import locale +import sublime RVM_DEFAULT_PATH = '~/.rvm/bin/rvm-auto-ruby' RBENV_DEFAULT_PATH = '~/.rbenv/bin/rbenv' @@ -40,15 +41,34 @@ def load_rbenv(self): return True return False + # + # RuboCop exits with the following status codes: + # 0 if no offenses are found or if the severity of all offenses are less + # than --fail-level. (By default, if you use --autocorrect, offenses which are + # autocorrected do not cause RuboCop to fail.) + # 1 if one or more offenses equal or greater to --fail-level are found. + # (By default, this is any offense which is not autocorrected.) + # 2 if RuboCop terminates abnormally due to invalid configuration, invalid CLI + # options, or an internal error. + # + @staticmethod + def is_err_unespected(returncode): + returncode not in [0, 1] + def run(self, pathlist, options=[]): call_list = self.command_list(pathlist, options) use_shell = False if self.on_windows: use_shell = True - + print("RubocopRunner executing: {} \n in folder: {} \n shell: {}".format(call_list, self.chdir, use_shell)) p = subprocess.Popen(call_list, shell=use_shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.chdir) out, err = p.communicate() + + if RubocopRunner.is_err_unespected(p.returncode): + print("RubocopRunner out: ", out) + print("RubocopRunner err: ", err) + sublime.error_message("RubocopRunner returned error code: {}".format(p.returncode)); return out def command_string(self, pathlist, options=[]):