Skip to content

Commit

Permalink
Ruby: Lint: added Rubocop linter
Browse files Browse the repository at this point in the history
Signed-off-by: Defman21 <[email protected]>
  • Loading branch information
Defman21 committed Aug 2, 2017
1 parent 41c0978 commit 0438f32
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/chrome/komodo/content/pref/pref-syntax-checking.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,23 @@ function javaScriptInfo(languageName) {
};
}

languageInfo.Ruby = {
browseForRubocopBinary: () => {
let rubocop_binary = document.getElementById('rubocop_binary');
let currentPath = rubocop_binary.value;
let path = ko.filepicker.browseForExeFile(null, currentPath || "");
if (path)
rubocop_binary.value = path;
},
browseForRubocopConfig: () => {
let rubocop_config = document.getElementById('rubocop_config');
let currentPath = rubocop_config.value;
let path = ko.filepicker.browseForExeFile(null, currentPath || "");
if (path)
rubocop_config.value = path;
}
};

function typescript_setup() {
if (!('TypeScript' in dialog)) {
dialog.TypeScript = {};
Expand Down
40 changes: 40 additions & 0 deletions src/chrome/komodo/content/pref/pref-syntax-checking.xul
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,46 @@
</menulist>
</hbox>
</groupbox>
<groupbox orient="vertical">
<caption label="&rubocopChecking.label;"/>
<description>
&rubocopChecking.description;
</description>
<hbox align="center">
<checkbox id="lint_rubocop_enabled"
pref="true"
preftype="boolean"
label="&rubocopChecking.checkbox;" />
</hbox>
<hbox>
<description>
&rubocopChecking.binary;
</description>
<textbox id="rubocop_binary"
flex="1"
value=''
pref="true"
placeholder="&rubocopChecking.binaryPlaceholder;"
preftype="string"/>
<button id='rubocop_linter_browse'
label="&browse.label;"
oncommand="languageInfo.Ruby.browseForRubocopBinary();"/>
</hbox>
<hbox>
<description>
&rubocopChecking.config;
</description>
<textbox id="rubocop_config"
flex="1"
value=''
pref="true"
placeholder="&rubocopChecking.configPlaceholder;"
preftype="string"/>
<button id='eslint_config_browse'
label="&browse.label;"
oncommand="languageInfo.Ruby.browseForRubocopConfig();"/>
</hbox>
</groupbox>
</vbox>

<vbox id="langSyntaxCheck-Sass">
Expand Down
7 changes: 7 additions & 0 deletions src/chrome/komodo/locale/en-US/pref/pref.dtd
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,13 @@ adding an additional caret at the clicked position.">
<!ENTITY rubyDebuggerNotWorking.description "The Ruby debugger extension does not work with the version of Ruby selected or that is on your path. You need to use Ruby version 1.8.2 or later. You can get Ruby from the Ruby home page at">
<!ENTITY filePrefRubyUseThisInterpreter.label "Use this interpreter">
<!ENTITY filePrefRubyLevelStricness.description "You can configure the level of strictness that is used when doing background syntax checks.">
<!ENTITY rubocopChecking.label "Rubocop Linter Checking">
<!ENTITY rubocopChecking.checkbox "Enable the Rubocop linter">
<!ENTITY rubocopChecking.description "Use the Rubocop linter when doing background syntax checking.">
<!ENTITY rubocopChecking.binary "Rubocop binary:">
<!ENTITY rubocopChecking.binaryPlaceholder "Find on path...">
<!ENTITY rubocopChecking.config "Rubocop config:">
<!ENTITY rubocopChecking.configPlaceholder "Find in current working directory...">
<!ENTITY filePrefRubyAdditionalDirectory.description "Specify any additional directories that you want Komodo to add to the Ruby path when debugging, syntax checking or in the interactive shell.">
<!ENTITY filePrefRubyExcludeDirectory.description "Specify any directories you want to exclude from code autocompletion scans.">

Expand Down
1 change: 1 addition & 0 deletions src/lint/Conscript
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ if ($havePy2to3) {
$cons->InstallXpcomComponent('koCSSExLinter.py');
$cons->InstallXpcomComponent('koHTMLLinter.py');
$cons->InstallXpcomComponent('koPHPLinter.py');
$cons->InstallXpcomComponent('koRubocopLinter.py');
$cons->InstallXpcomComponent('koJavaScriptLinter.py');
$cons->InstallXpcomComponent('koLintService.py');
$cons->InstallPythonUtility('koLintResults.py');
Expand Down
110 changes: 110 additions & 0 deletions src/lint/koRubocopLinter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
from xpcom import components
from koLintResult import KoLintResult, SEV_ERROR, SEV_WARNING, SEV_INFO
from koLintResults import koLintResults
import os
import logging
import tempfile
import process
import koprocessutils
import which
import json

Cc = components.classes
Ci = components.interfaces

log = logging.getLogger("koRubocopLinter")
#log.setLevel(logging.DEBUG)


class KoRubocopLinter(object):
_com_interfaces_ = [Ci.koILinter]
_reg_clsid_ = "{0BED01B1-6BAD-4B55-A407-3C6273C0032D}"
_reg_contractid_ = "@addons.defman.me/koRubocopLinter;1"
_reg_categories_ = [
("category-komodo-linter", 'Ruby'),
]

def __init__(self,):
self.ignore_cops = ["Style/FileName"]
self.file_ext = '.rb'
self.project = Cc["@activestate.com/koPartService;1"].getService(Ci.koIPartService)
self.ruby_linter = Cc["@activestate.com/koLinter?language=Ruby;1"].getService(Ci.koILinter)

def lint(self, request):
text = request.content.encode(request.encoding.python_encoding_name)
return self.lint_with_text(request, text)

def lint_with_text(self, request, text):
if not request.prefset.getBoolean("lint_rubocop_enabled", False):
log.debug("Rubocop: not enabled")
return self.ruby_linter.lint(request)
try:
rubocop = request.prefset.getString('rubocop_binary' ,'')
if rubocop == '':
log.debug('Rubocop: looking for the rubocop executable on $PATH')
rubocop = which.which('rubocop')
except which.WhichError:
log.debug("Rubocop: rubocop is not found")
return self.ruby_linter.lint(request)

cwd = None
cmd = []
rbfile = None

if self.project.currentProject is not None:
cwd = self.project.currentProject.liveDirectory
log.debug("Rubocop: using current project directory")
else:
cwd = request.cwd
log.debug("Rubocop: cwd = %s" % (cwd))

if cwd is not None:
for ext in ['yaml', 'yml']:
config = os.path.join(cwd, '.rubocop.{}'.format(ext))
if os.path.exists(config):
log.debug("Config file: {}".format(config))
break
else:
config = request.prefset.getString('rubocop_config', '')
log.debug("Config file (set by user): {}".format(config))
if config and os.path.isfile(config):
cmd = [rubocop, '--format', 'json', '--config', config]
else:
cmd = [rubocop, '--format', 'json']
log.debug("Rubocop: .rubocop.yml or .rubocop.yaml are not found")

cmd += ['--stdin', request.koDoc.file.encodedPath]

log.debug("Rubocop: command = %s" % (" ".join(cmd)))

env = koprocessutils.getUserEnv()
cwd = cwd or None
p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=process.PIPE)
stdout, stderr = p.communicate(input=text)

results = koLintResults()
data = json.loads(stdout)['files'][0]

for offense in data['offenses']:
if offense['cop_name'] in self.ignore_cops:
log.debug("Rubocop: cop '%s' ignored" % (offense['cop_name']))
continue
line = offense['location']['line']
column = offense['location']['column']
column_end = column + offense['location']['length']
if offense['severity'] in ['refactor', 'convention']:
severity = SEV_INFO
elif offense['severity'] == "warning":
severity = SEV_WARNING
else:
severity = SEV_ERROR
description = "%s: %s" % (offense['cop_name'], offense['message'])
result = KoLintResult(description=description,
severity=severity,
lineStart=line,
lineEnd=line,
columnStart=column,
columnEnd=column_end)
results.addResult(result)
log.debug("Rubocop: lint results: %d" % (len(data['offenses'])))
return results

0 comments on commit 0438f32

Please sign in to comment.