# # ruby_linter.py # Part of SublimeLinter3, a code checking framework for Sublime Text 3 # # Written by Aparajita Fishman # # Project: https://github.com/SublimeLinter/SublimeLinter3 # License: MIT # """This module exports the RubyLinter subclass of Linter.""" import os import re import shlex from . import linter, persist, util CMD_RE = re.compile(r'(?P.+?)@ruby') class RubyLinter(linter.Linter): """ This Linter subclass provides ruby-specific functionality. Linters that check ruby using gems should inherit from this class. By doing so, they automatically get the following features: - comment_re is defined correctly for ruby. - Support for rbenv and rvm (via rvm-auto-ruby). """ comment_re = r'\s*#' @classmethod def initialize(cls): """Perform class-level initialization.""" super().initialize() if cls.executable_path is not None: return if not callable(cls.cmd) and cls.cmd: cls.executable_path = cls.lookup_executables(cls.cmd) elif cls.executable: cls.executable_path = cls.lookup_executables(cls.executable) if not cls.executable_path: cls.disabled = True @classmethod def reinitialize(cls): """Perform class-level initialization after plugins have been loaded at startup.""" # Be sure to clear cls.executable_path so that lookup_executables will run. cls.executable_path = None cls.initialize() @classmethod def lookup_executables(cls, cmd): """ Attempt to locate the gem and ruby specified in cmd, return new cmd list. The following forms are valid: gem@ruby gem ruby If rbenv is installed and the gem is also under rbenv control, the gem will be executed directly. Otherwise [ruby <, gem>] will be returned. If rvm-auto-ruby is installed, [rvm-auto-ruby <, gem>] will be returned. Otherwise [ruby] or [gem] will be returned. """ ruby = None rbenv = util.which('rbenv') if not rbenv: ruby = util.which('rvm-auto-ruby') if not ruby: ruby = util.which('ruby') if not rbenv and not ruby: persist.printf( 'WARNING: {} deactivated, cannot locate ruby, rbenv or rvm-auto-ruby' .format(cls.name, cmd[0]) ) return [] if isinstance(cmd, str): cmd = shlex.split(cmd) match = CMD_RE.match(cmd[0]) if match: gem = match.group('gem') elif cmd[0] != 'ruby': gem = cmd[0] else: gem = '' if gem: gem_path = util.which(gem) if gem_path: if (rbenv and ('{0}.rbenv{0}shims{0}'.format(os.sep) in gem_path or (os.altsep and '{0}.rbenv{0}shims{0}'.format(os.altsep in gem_path)))): ruby_cmd = [gem_path] else: ruby_cmd = [ruby, gem_path] else: persist.printf( 'WARNING: {} deactivated, cannot locate the gem \'{}\'' .format(cls.name, gem) ) return [] else: ruby_cmd = [ruby] if cls.env is None: # Don't use GEM_HOME with rbenv, it prevents it from using gem shims if rbenv: cls.env = {} else: gem_home = util.get_environment_variable('GEM_HOME') if gem_home: cls.env = {'GEM_HOME': gem_home} else: cls.env = {} return ruby_cmd