def lint_with_text(self, request, text): if not text.strip(): return None cwd = request.cwd env = koprocessutils.getUserEnv() settingsDir = env.get("DJANGO_SETTINGS_MODULE", None) if not settingsDir: settingsDir = self._getSettingsDir(cwd) if settingsDir: # Save the current buffer to a temporary file. tmpFileName = tempfile.mktemp() fout = open(tmpFileName, 'wb') try: fout.write(text) fout.close() #XXX: How to tell whether we're using Python or Python3? prefName = "pythonExtraPaths" pythonPath = request.prefset.getString(prefName, "") pythonPathEnv = env.get("PYTHONPATH", "") if pythonPathEnv: if pythonPath: pythonPath += os.pathsep + pythonPathEnv else: pythonPath = pythonPathEnv if pythonPath: if sys.platform.startswith("win"): pythonPath = pythonPath.replace('\\', '/') env["PYTHONPATH"] = pythonPath elif env.has_key("PYTHONPATH"): del env["PYTHONPATH"] results = koLintResults() pythonExe = self._pythonInfo.getExecutableFromDocument(request.koDoc) argv = [pythonExe, self._djangoLinterPath, tmpFileName, settingsDir] p = process.ProcessOpen(argv, cwd=cwd, env=env, stdin=None) output, error = p.communicate() #log.debug("Django output: output:[%s], error:[%s]", output, error) retval = p.returncode finally: os.unlink(tmpFileName) if retval == 1: if error: results.addResult(self._buildResult(text, error)) else: results.addResult(self._buildResult(text, "Unexpected error")) else: result = KoLintResult() result.lineStart = 1 result.lineEnd = 1 result.columnStart = 1 result.columnEnd = 1 + len(text.splitlines(1)[0]) result.description = "Can't find settings.py for this Django file" result.encodedDescription = result.description result.severity = result.SEV_ERROR results = koLintResults() results.addResult(result) return results
def __init__(self, user_path, request, text): self.valid = True self.results = koLintResults() self.request = request self.text = text self.cwd = request.cwd if self.text: self.textlines = text.splitlines() else: self.textlines = [""] self.valid = False self.user_path = user_path if not user_path: self.add_internal_error(MSG_NO_PATH) self.valid = False self.coffeelint_exe = find_coffeelint(self.user_path) if not self.coffeelint_exe: self.add_internal_error(MSG_NO_COFFEELINT) self.valid = False # CoffeeLint looks for a coffeelint.json config file somewhere at or # above the directory of the input file. Unfortunately, we're # loading from tmp, not cwd. # The user still expects the config file in cwd (or above) to be honored, # so we have to do the searching ourselves. :S self.configfile = find_filename(self.cwd, "coffeelint.json")
def lint_with_text(self, request, text): log.info(request) log.debug(text) if not text.strip(): return None # consider adding lint preferences? maybe for compiler selection, paths, etc? n = uuid.uuid1() dst_name = n.hex + ".out" dst_path = os.path.join(request.cwd, dst_name) compilation_command = ['go', 'build', '-o', dst_name] try: env = koprocessutils.getUserEnv() results = koLintResults() log.info('Running ' + ' '.join(compilation_command)) p = process.ProcessOpen(compilation_command, cwd=request.cwd, env=env, stdin=None) output, error = p.communicate() log.debug("output: output:[%s], error:[%s]", output, error) output = output + error retval = p.returncode finally: try: os.unlink(dst_path) except OSError: pass if output: for line in output.splitlines(): if line[0] == '#': continue results.addResult(self._buildResult(text, line, request.koDoc.baseName)) return results
def _parseWarnings(self, warntext, text, leadingWS): """Parse out warnings from the text like the following and return a list of KoLintResult's. Example output: t.py:3: SyntaxWarning: import * only allowed at module level def foo(): t.py:1: DeprecationWarning: the regex module is deprecated; please use the re module import regex Also sometimes get lines like this: t.py: Token Error: ('EOF in multi-line string', (3, 6)) Note that this is picked up in the SyntaxError processing so we can skip that here for now. """ textlines = text.splitlines(1) if leadingWS: del textlines[0] warningRe = re.compile("^(?P<fname>.*?):(?P<line>\d+): (?P<desc>.*)$") results = koLintResults() for line in warntext.splitlines(): match = warningRe.match(line) if match: # Ignore lines that don't match this, e.g. " def foo():" r = KoLintResult() lineNo = int(match.group('line')) if leadingWS: lineNo -= 1 koLintResult.createAddResult(results, textlines, r.SEV_WARNING, lineNo, match.group('desc'), leadingWS) return results
def lint_with_text(self, request, text): """Lint the given XML content. Raise an exception and set an error on koLastErrorService if there is a problem. """ text = encodeRequestText(request, text) text = eollib.convertToEOLFormat(text, eollib.EOL_LF) cwd = request.cwd parser = expat.ParserCreate() results = koLintResults() try: # We need to remove the BOM on UTF-8 data to prevent expat from # crashing. We should check to see if this is still necesary # with every new Python version (we are at 2.0 now). utf8bom = u'\ufeff'.encode('utf-8') if text.startswith(utf8bom): parser.Parse(text[len(utf8bom):], 1) else: parser.Parse(text, 1) except expat.error: result = KoLintResult() result.description = "XML Error: %s" % expat.ErrorString(parser.ErrorCode) # find an existing, non-empty line on which to display result # XXX This logic should be in the LintDisplayer (should # rearchitect a la Trent's lintx) text = eollib.convertToEOLFormat(request.content, eollib.EOL_LF) lines = text.split("\n") if parser.ErrorLineNumber > len(lines): lineStart = len(lines) else: lineStart = parser.ErrorLineNumber lineStart = parser.ErrorLineNumber retreated = 0 while 1: if lineStart <= len(lines) and len(lines[lineStart-1]): break elif lineStart == 0: log.warn("Could not find a suitable line on which " "to display lint result for line %d.", parser.ErrorLineNumber) return None else: lineStart -= 1 retreated = 1 if retreated: result.description += " (error is on line %d, but displayed "\ "here)" % parser.ErrorLineNumber result.lineStart = result.lineEnd = lineStart result.columnStart = 1 result.columnEnd = len(lines[result.lineEnd-1]) + 1 result.severity = result.SEV_ERROR results.addResult(result) return results
def lint_with_text(self, request, text): """Return a list of koILintResult's given a ISciMoz object.""" cwd = request.cwd import re lines = text.split('\n') lineNum = 1 complainRe = re.compile(r'\bself\b') results = koLintResults() for line in lines: # for testing, lets just bitch about the word 'self' print 'linting:', repr(line) complainMatch = complainRe.search(line) if complainMatch: r = KoLintResult() r.lineStart = lineNum r.lineEnd = lineNum r.columnStart = complainMatch.start() + 1 r.columnEnd = complainMatch.end() + 1 r.description = "I don't like you use of 'self' there pardner." r.severity = r.SEV_WARNING results.addResult(r) print 'error: (%d,%d)(%d,%d): %s' %\ (r.lineStart, r.lineEnd, r.columnStart, r.columnEnd, r.description) lineNum = lineNum + 1 return results
def runGenericLinter(text, extension, cmd_start, err_ptns, warn_ptns, cwd, useStderr): tmpfilename = tempfile.mktemp() + extension fout = open(tmpfilename, "wb") fout.write(text) fout.close() cmd = cmd_start + [tmpfilename] try: p = process.ProcessOpen(cmd, cwd=cwd, env=koprocessutils.getUserEnv(), stdin=None) stdout, stderr = p.communicate() if useStderr: errLines = stderr.splitlines(0) # Don't need the newlines. else: errLines = stdout.splitlines(0) # Don't need the newlines. textLines = None except: log.exception("Failed to run %s, cwd %r", cmd, cwd) return None finally: os.unlink(tmpfilename) results = koLintResults() all_ptns = zip(err_ptns, [SEV_ERROR] * len(err_ptns)) + zip(warn_ptns, [SEV_WARNING] * len(warn_ptns)) for line in errLines: for ptn, sev in all_ptns: m = ptn.match(line) if m: if textLines is None: textLines = text.splitlines() m1 = _leading_ws_ptn.match(line) createAddResult(results, textLines, sev, m.group(1), m.group(2), m1 and m1.group(1) or None) break return results
def parse(self, filepath, cwd=None): results = koLintResults() entries = [] cmd = [self.xpcshell_exe, self.csslint_filepath, filepath] stdout = None # We only need the stdout result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=self._setLDLibraryPath(), stdin=None) stdout, stderr = p.communicate() entries = json.loads(stdout or "[]") except: log.exception("Problem running xcshell: %r\n,output:%r\n", cmd, stdout) return results for entry in entries: # Convert to Komodo lint result object. #print 'entry: %r' % (entry, ) results.addResult(KoLintResult(description=entry.get('description', ''), severity=entry.get('severity', 1), lineStart=entry.get('lineStart', 0), lineEnd=entry.get('lineEnd', -1), columnStart=entry.get('columnStart', 0), columnEnd=entry.get('columnEnd', 0))) return results
def lint_with_text(self, request, text): log.info(request) logging.shit = [request, text] if not self.go_compiler: return if not text.strip(): return None # consider adding lint preferences? maybe for compiler selection, paths, etc? # Save the current buffer to a temporary file. handle, tempfile_name = tempfile.mkstemp(suffix='.go', prefix='~', dir=request.cwd) fout = open(tempfile_name, 'wb') short_tempfile_name = os.path.basename(tempfile_name) try: fout.write(text) fout.close() env = koprocessutils.getUserEnv() results = koLintResults() p = process.ProcessOpen([self.go_compiler, 'build', short_tempfile_name], cwd=request.cwd, env=env, stdin=None) output, error = p.communicate() log.debug("%s output: output:[%s], error:[%s]", self.go_compiler, output, error) retval = p.returncode finally: os.unlink(tempfile_name) if retval != 0: if output: for line in output.splitlines()[1:]: results.addResult(self._buildResult(text, line, tempfile_name)) else: results.addResult(self._buildResult(text, "Unexpected error")) return results
def ActionScriptWarnsToLintResults(warns, filename, code, status): defaultSeverity = ((status == 0 and KoLintResult.SEV_WARNING) or KoLintResult.SEV_ERROR) lintResults = koLintResults() warnRe = re.compile( r'(?P<fileName>.*?):(?P<lineNum>\d+): (?:characters (?P<rangeStart>\d+)-(?P<rangeEnd>\d+))\s*:\s*(?P<message>.*)') for warn in warns: match = warnRe.search(warn) if match and match.group('fileName') == filename: lineNum = int(match.group('lineNum')) rangeStart = match.groupdict().get('rangeStart', None) rangeEnd = match.groupdict().get('rangeEnd', None) lr = KoLintResult() lr.description = match.group('message') lr.lineStart = lineNum lr.lineEnd = lineNum if rangeStart and rangeEnd: lr.columnStart = int(rangeStart) + 1 lr.columnEnd = int(rangeEnd) + 1 else: lr.columnStart = 1 lr.columnEnd = len(lines[lr.lineStart - 1]) + 1 lr.severity = defaultSeverity lintResults.addResult(lr) else: log.debug("%s: no match", warn) log.debug("returning %d lint results", lintResults.getNumResults()) return lintResults
def lint(self, request): text = request.content.encode(request.encoding.python_encoding_name) prefset = request.koDoc.getEffectivePrefs() ascExe = self._getInterpreter(prefset) if ascExe is None: lintResults = koLintResults() lr = KoLintResult() lr.description = "Can't find an ActionScript interpreter" lr.lineStart = lr.lineEnd = 1 lr.columnStart = 1 lr.columnEnd = 1 + len(text.splitlines()[0]) lr.severity = KoLintResult.SEV_WARNING lintResults.addResult(lr) log.debug('no interpreter') return lintResults tmpFileName = None cwd = request.cwd if cwd: tmpFileName = os.path.join(cwd, "tmp_ko_aslint_ko%s.as" % (self._koVer.replace(".", "_").replace("-", "_"))) try: fout = open(tmpFileName, 'wb') fout.write(text) fout.close() except (OSError, IOError), ex: tmpFileName = None
def lint_with_text(self, request, text): results = koLintResults() log.debug(request) env = koprocessutils.getUserEnv() try: subprocess.call(['go', 'env'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) except OSError: log.error('"go" binary not found!') results.addResult(_errorResult('"go" binary not found! (PATH=%s)' % env['PATH'])) return results # ensure GOPATH is present if 'GOPATH' not in env: results.addResult(_errorResult('"GOPATH" not in environment, please check your general or project settings')) return results if not text.strip(): return None # consider adding lint preferences? maybe for compiler selection, paths, etc? # Save the current buffer to a temporary file. base_temp_dir = tempfile.mkdtemp(prefix='kogo') temp_dir = os.path.join(base_temp_dir,'go') def non_go_files(dir,files): result = [] for file in files: if not file.endswith('.go'): result.append(file) return result shutil.copytree(request.cwd, temp_dir, ignore=non_go_files) buf = open(os.path.join(temp_dir, request.koDoc.baseName),'w') buf.write(text) buf.close() compilation_command = ['go', 'build'] try: log.info('Running ' + ' '.join(compilation_command)) p = process.ProcessOpen(compilation_command, cwd=temp_dir, env=env, stdin=None) output, error = p.communicate() log.debug("output: output:[%s], error:[%s]", output, error) retval = p.returncode finally: shutil.rmtree(base_temp_dir, ignore_errors=True) if retval != 0: all_output = output.splitlines() + error.splitlines() if all_output: for line in all_output: if line and line[0] == '#': continue results.addResult(_buildResult(text, line, request.koDoc.baseName)) else: results.addResult(self._buildResult(text, "Unexpected error")) return results
def lint_with_text(self, request, text): if not text: return None prefset = request.prefset if not prefset.getBooleanPref("lint_coffee_script"): return try: coffeeExe = which.which("coffee", path=self._userPath) if not coffeeExe: return if sys.platform.startswith("win") and os.path.exists(coffeeExe + ".cmd"): coffeeExe += ".cmd" except which.WhichError: msg = "coffee not found" if msg not in _complained: _complained[msg] = None log.error(msg) return tmpfilename = tempfile.mktemp() + '.coffee' fout = open(tmpfilename, 'wb') fout.write(text) fout.close() textlines = text.splitlines() cwd = request.cwd cmd = [coffeeExe, "-l", "-c", tmpfilename] # We only need the stderr result. try: p = process.ProcessOpen(cmd, cwd=cwd, stdin=None) _, stderr = p.communicate() warnLines = stderr.splitlines(0) # Don't need the newlines. except: log.exception("Problem running %s", coffeeExe) warnLines = [] finally: os.unlink(tmpfilename) ptn = re.compile(r'^Error: In (.*),\s*(.*) on line (\d+):\s*(.*)') syntaxErrorPtn = re.compile(r'^SyntaxError: In (.*),\s*(.*) on line (\d+)') results = koLintResults() for line in warnLines: m = ptn.match(line) if m: part1 = m.group(2) lineNo = int(m.group(3)) part2 = m.group(4) desc = "%s on line %d: %s" % (part1, lineNo, part2) severity = koLintResult.SEV_ERROR koLintResult.createAddResult(results, textlines, severity, lineNo, desc) else: m = syntaxErrorPtn.match(line) if m: part1 = m.group(2) lineNo = int(m.group(3)) desc = "SyntaxError: %s on line %d" % (part1, lineNo) severity = koLintResult.SEV_ERROR koLintResult.createAddResult(results, textlines, severity, lineNo, desc) return results
def lint(self, request): try: return self._html_linter.lint(request, TPLInfo=self._tplPatterns) except: if "lint" not in self._checkValidVersion_complained: self._checkValidVersion_complained["lint"] = True log.exception("Problem in koPHPLinter.lint") return koLintResults()
def lint(self, request): try: html_linter = UnwrapObject(self._koLintService.getLinterForLanguage("HTML")) return html_linter.lint(request, TPLInfo=self._tplPatterns) except: if "lint" not in self._checkValidVersion_complained: self._checkValidVersion_complained["lint"] = True log.exception("Problem in koPHPLinter.lint") return koLintResults()
def lint_with_text(self, request, text): if not text: return None prefset = request.prefset if not prefset.getBooleanPref(self.lint_prefname): return pythonExe = self._pythonInfo.getExecutableFromPrefs(prefset) if not pythonExe: return try: checkerExe = which.which("pyflakes", path=_getUserPath()) except which.WhichError: checkerExe = None if not checkerExe: log.warn("pyflakes not found") return fout, tmpfilename = _localTmpFileName() try: fout.write(text) fout.close() textlines = text.splitlines() cwd = request.cwd # For the env, don't add a PYTHONPATH entry for cwd, as it can break # module import lookups for pyflakes. E.g. # foo/ # __init__.py - an "from foo import bar" in this file will break env = self._get_fixed_env(prefset, cwd=None) cmd = [pythonExe, checkerExe, tmpfilename] # stdout for pyflakes.checker.Checker # stderr for __builtin__.compile() p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None) stdout, stderr = p.communicate() warnLines = [] errorLines = [] if p.returncode and stderr and not stdout: m = re.match("^(.*?):(\d+):(\d+): invalid syntax", stderr) if m is None: _complainIfNeeded(stderr, "Error running pyflakes on file %r\n%s", request.koDoc.displayPath, stderr) # It's a syntax error - convert it. error = "%s:%s: invalid syntax (at column %s)" % ( m.group(1), m.group(2), m.group(3)) errorLines = [error] else: warnLines = stdout.splitlines() errorLines = stderr.splitlines(0) # Don't need the newlines. finally: os.unlink(tmpfilename) results = koLintResults() # "createAddResult" will change lineno in some situation, so we use our version self._createAddResult(results, textlines, errorLines, koLintResult.SEV_ERROR) self._createAddResult(results, textlines, warnLines, koLintResult.SEV_WARNING) return results
def lint_with_text(self, request, text): # log.debug("XBL text: %s", text) jsResults = self._js_linter.lint_with_text(request, text) # log.debug("XBL lint results: %s", # [str(x) for x in jsResults.getResults()]) fixedResults = koLintResults() for res in jsResults.getResults(): if 'return not in function' not in res.description: fixedResults.addResult(res) return fixedResults
def lint_with_text(self, request, text): if self._fmt_cmd_start is None: return cwd = request.cwd or None results = koLintResults() tmpfilename = tempfile.mktemp() + ".go" fout = open(tmpfilename, "wb") fout.write(text) fout.close() cmd = self._fmt_cmd_start + [tmpfilename] env = koprocessutils.getUserEnv() bad_keys = [] for k, v in env.items(): if not isinstance(v, (str, unicode)): bad_keys.append(k) for k in bad_keys: del env[k] try: p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None) stdout, stderr = p.communicate() if not stderr: return results except: log.exception("Failed to run %s, cwd %r", cmd, cwd) return results finally: os.unlink(tmpfilename) errLines = stderr.splitlines(0) # Don't need the newlines. textLines = text.splitlines(0) for line in errLines: m = self._ptn_err.match(line) if m: fname = m.group(1) if tmpfilename not in fname: continue lineNo = int(m.group(2)) columnStart = int(m.group(3)) desc = m.group(4) m1 = self._problem_token.search(desc) if m1: columnEnd = columnStart + len(m1.group(1)) else: columnEnd = columnStart + 1 result = KoLintResult( description=desc, severity=SEV_ERROR, lineStart=lineNo, lineEnd=lineNo, columnStart=columnStart, columnEnd=columnEnd, ) results.addResult(result) return results
def lint_with_text(self, request, text): if not text: return None prefset = request.prefset if not prefset.getBooleanPref("lint_typescript"): return try: tsLintExe = which.which("tslint", path=self._userPath) if not tsLintExe: return if sys.platform.startswith("win") and os.path.exists(tsLintExe + ".cmd"): tsLintExe += ".cmd" except which.WhichError: msg = "tslint not found" if msg not in _complained: _complained[msg] = None log.error(msg) return tmpfilename = tempfile.mktemp() + '.ts' fout = open(tmpfilename, 'wb') fout.write(text) fout.close() textlines = text.splitlines() cwd = request.cwd configfile = prefset.getStringPref("tslintConfigFile") if configfile: cmd = [tsLintExe, '-c', configfile, tmpfilename] else: cmd = [tsLintExe, tmpfilename] # We only need the stdout result. try: p = process.ProcessOpen(cmd, cwd=cwd, stdin=None) stdout, _ = p.communicate() warnLines = stdout.splitlines(0) # Don't need the newlines. except: log.exception("Problem running %s", tsLintExe) warnLines = [] finally: os.unlink(tmpfilename) ptn = re.compile(r'^.+?\[(\d+),\s+(\d+)\]:\s+([^\r\n]+)') results = koLintResults() for line in warnLines: m = ptn.match(line) if m: lineNo = int(m.group(1)) colNo = int(m.group(2)) desc = "%s (on column %d)" % (m.group(3), colNo) severity = koLintResult.SEV_ERROR koLintResult.createAddResult(results, textlines, severity, lineNo, desc, columnStart=colNo) return results
def _resetLines(self, lintResults, text): lines = text.splitlines() fixedResults = koLintResults() for res in lintResults.getResults(): try: targetLine = lines[res.lineEnd - 1] except IndexError: log.exception("can't index %d lines at %d", len(lines), res.lineEnd - 1) pass # Keep the original lintResult else: if res.columnEnd > len(targetLine): res.columnEnd = len(targetLine) fixedResults.addResult(res) return fixedResults
def lint_with_text(self, request, text): linters = self._koLintService.getTerminalLintersForLanguage(self._languageName) finalLintResults = koLintResults() for linter in linters: try: newLintResults = UnwrapObject(linter).lint_with_text(request, text) except: log.exception("lint_with_text exception") else: if newLintResults and newLintResults.getNumResults(): if finalLintResults.getNumResults(): finalLintResults = finalLintResults.addResults(newLintResults) else: finalLintResults = newLintResults return finalLintResults
def lint(self, request): text = request.content.encode("utf-8") tabWidth = request.koDoc.tabWidth log.debug("linting %s" % text[1:15]) results = koLintResults() try: tmp_filename = tempfile.mktemp() fout = open(tmp_filename, "wb") fout.write(text) fout.close() command = 'cat(sv_quickParse("' + tmp_filename.replace("\\", "/") + '", encoding = "UTF-8"))' # log.debug(command) except Exception, e: log.exception(e)
def lint_with_text(self, request, text): if not text: return None prefset = request.prefset if not prefset.getBooleanPref("lint_jsx"): return try: jsxHintExe = which.which("jsxhint", path=self._userPath) if not jsxHintExe: return if sys.platform.startswith("win") and os.path.exists(jsxHintExe + ".cmd"): jsxHintExe += ".cmd" except which.WhichError: msg = "jsxhint not found" if msg not in _complained: _complained[msg] = None log.error(msg) return tmpfilename = tempfile.mktemp() + ".jsx" fout = open(tmpfilename, "wb") fout.write(text) fout.close() textlines = text.splitlines() cwd = request.cwd cmd = [jsxHintExe, "--reporter=unix", tmpfilename] # We only need the stdout result. try: p = process.ProcessOpen(cmd, cwd=cwd, stdin=None) stdout, _ = p.communicate() warnLines = stdout.splitlines(0) # Don't need the newlines. except: log.exception("Problem running %s", jsxHintExe) warnLines = [] finally: os.unlink(tmpfilename) ptn = re.compile(r"^[^:]+:(\d+):(\d+): ([^\r\n]+)") results = koLintResults() for line in warnLines: m = ptn.match(line) if m: lineNo = int(m.group(1)) colNo = int(m.group(2)) desc = "%s (on column %d)" % (m.group(3), colNo) severity = koLintResult.SEV_ERROR koLintResult.createAddResult(results, textlines, severity, lineNo, desc, columnStart=colNo) return results
def lint_with_text(self, request, text): if not text: return # Make the user's configured version of python available to the # checkers. They can start this exe in a new process or just # use the current interpreter. python = self._python.getExecutableFromDocument(request.koDoc) # Add the current dir so that the checkers can find relative files. if request.cwd not in sys.path: sys.path.append(request.cwd) # Avoid issues with windows newlines by pretending they don't exist. text = re.sub(r'\r\n', r'\n', text) text_lines = text.splitlines(True) results = koLintResults() temp_file = tempfile.NamedTemporaryFile( mode='w', suffix='.py', delete=False, ) try: temp_file.write(text) temp_file.close() for checker_class in self.checker_classes: try: checker = checker_class(request, temp_file.name, text_lines, python=python) checker.add_to_results(results) except Exception: LOG.exception('Error running %s' % checker_class.__name__) finally: os.unlink(temp_file.name) return results
def lint_with_text(self, request, text): log.info(request) log.debug(text) if not text.strip(): return None # consider adding lint preferences? maybe for compiler selection, paths, etc? # Save the current buffer to a temporary file. base_temp_dir = tempfile.mkdtemp(prefix='kogo') temp_dir = os.path.join(base_temp_dir,'go') def non_go_files(dir,files): result = [] for file in files: if not file.endswith('.go'): result.append(file) return result shutil.copytree(request.cwd, temp_dir, ignore=non_go_files) compilation_command = ['go', 'build'] try: env = koprocessutils.getUserEnv() results = koLintResults() log.info('Running ' + ' '.join(compilation_command)) p = process.ProcessOpen(compilation_command, cwd=temp_dir, env=env, stdin=None) output, error = p.communicate() log.debug("output: output:[%s], error:[%s]", output, error) retval = p.returncode finally: shutil.rmtree(base_temp_dir, ignore_errors=True) if retval != 0: all_output = output.splitlines() + error.splitlines() if all_output: for line in all_output: if line and line[0] == '#': continue results.addResult(self._buildResult(text, line, request.koDoc.baseName)) else: results.addResult(self._buildResult(text, "Unexpected error")) return results
def lint_with_text(self, request, text): #pylint: disable=R0201 " Use the codeintel-based CSSLinter class to find error messages" textlines = text.splitlines() results = CSSLinter().lint(text, request.koDoc.language) lintResults = koLintResults() for r in results: if r.line_start is None: createAddResult(lintResults, textlines, r.status + 1, len(textlines) - 1, r.message) else: result = KoLintResult(description=r.message, severity=r.status + 1, lineStart=r.line_start, lineEnd=r.line_end, columnStart=r.col_start + 1, columnEnd=r.col_end + 1) lintResults.addResult(result) return lintResults
def lint_with_text(self, request, text): self.datalines = re.split('\r\n|\r|\n',text) cwd = request.cwd self.results = koLintResults() fn = None # save buffer to a temporary file try: self.fn = fn = tempfile.mktemp() self.uri = URIlib.URIParser(self.fn) fout = open(fn, 'wb') fout.write(text) fout.close() parser = components.classes["@activestate.com/koCSSParser;1"].createInstance(components.interfaces.koICSSParser) parser.parseFile(fn) except Exception, e: log.exception(e)
def lint_with_text(self, request, text): if not text: return None prefset = request.prefset if not prefset.getBooleanPref(self.lint_prefname): return pythonExe = self._pythonInfo.getExecutableFromDocument(request.koDoc) if not pythonExe: return try: checkerExe = which.which("pyflakes", path=_getUserPath()) except which.WhichError: checkerExe = None if not checkerExe: log.warn("pyflakes not found") return fout, tmpfilename = _localTmpFileName() try: fout.write(text) fout.close() textlines = text.splitlines() cwd = request.cwd env = self._get_fixed_env(prefset, cwd) cmd = [pythonExe, checkerExe, tmpfilename] # stdout for pyflakes.checker.Checker # stderr for __builtin__.compile() p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None) stdout, stderr = p.communicate() errorLines = stderr.splitlines(0) # Don't need the newlines. warnLines = stdout.splitlines() finally: os.unlink(tmpfilename) results = koLintResults() # "createAddResult" will change lineno in some situation, so we use our version self._createAddResult(results, textlines, errorLines, koLintResult.SEV_ERROR) self._createAddResult(results, textlines, warnLines, koLintResult.SEV_WARNING) return results
def parse(self, filepath, cwd=None, text=None): results = koLintResults() entries = [] cmd = [self.xpcshell_exe, self.csslint_filepath, filepath] stdout = None # We only need the stdout result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=self._setEnv(), stdin=None) stdout, stderr = p.communicate() entries = json.loads(stdout or "[]") except: log.exception("Problem running xcshell: %r\n,output:%r\n", cmd, stdout) return results lines = text.split('\n') for entry in entries: # Convert to Komodo lint result object. #print 'entry: %r' % (entry, ) line_start = entry.get('lineStart', 0) column_start = entry.get('columnStart', 0) column_end = entry.get('columnEnd', 0) if column_start + 1 == column_end: word = re.search('\\w+$', lines[line_start - 1][0:column_end - 1]) if word: column_start = word.start() + 1 results.addResult(KoLintResult(description=entry.get('description', ''), severity=entry.get('severity', 1), lineStart=line_start, lineEnd=entry.get('lineEnd', -1), columnStart=column_start, columnEnd=column_end)) return results
def _getEncodingLintResults(self, content, encoding): """Return lint results for encoding errors in the given document. "content" is the document content as a unicode string "encoding" is the currently selected encoding for the document Returns a koLintResults instance. """ try: encodedString = content.encode(encoding.python_encoding_name, "strict") except UnicodeError, ex: pass # errors are handled after the try/except/else block else: return koLintResults() # no encoding errors # Find the specific errors by encoding with "replace" and finding # where those replacements were. escapedContent = content.replace('?', 'X') encodedString = escapedContent.encode(encoding.python_encoding_name, "replace") offset = 0 indeces = [] while 1: index = encodedString.find('?', offset) if index == -1: break indeces.append(index) offset = index + 1 log.debug("encoding errors at indeces %s", indeces)
def lint_with_text(self, request, text): """Lint the given PHP content. Raise an exception if there is a problem. """ cwd = request.cwd #print "----------------------------" #print "PHP Lint" #print text #print "----------------------------" php = self.phpInfoEx.getExecutableFromDocument(request.koDoc) if php is None: errmsg = "Could not find a suitable PHP interpreter for linting." log.exception(errmsg) raise COMException(nsError.NS_ERROR_NOT_AVAILABLE, errmsg) if not self.checkValidVersion(): return None # save php buffer to a temporary file phpfilename = tempfile.mktemp() fout = open(phpfilename, 'wb') fout.write(text) fout.close() p = None try: argv = [php, '-n', '-d', 'display_errors=1', '-d', 'display_startup_errors=1', '-d', 'output_buffering=0', '-d', 'xdebug.remote_enable=off', '-d', 'error_reporting=2047', '-q', '-l', phpfilename] env = koprocessutils.getUserEnv() cwd = cwd or None p = process.ProcessOpen(argv, cwd=cwd, env=env) stdout, stderr = p.communicate() # The relevant output is contained in stdout. lines = stdout.splitlines(1) finally: os.unlink(phpfilename) results = koLintResults() if lines: datalines = re.split('\r\n|\r|\n',text) numLines = len(datalines) lines = [l for l in lines if l.find('error') != -1] for line in lines: #print line line = line.strip() # remove html from error output line = re.sub('<.*?>',"",line) lineText = line.rfind(' ') try: lineNo = int(line[lineText+1:]) except ValueError, e: continue #print "Line Number: ", lineNo result = KoLintResult() # XXX error in FILENAME at line XXX # Previous fix (change done for bug 42553 -- (change 254015) # This fix allows for either "at" or "on" between the # filename and the line # # Sample error message: # PHP Fatal error: Can't use function return value in write context in C:\home\ericp\lab\komodo\bugs\bz42553a.php on line 3 m = re.match(r'(.*?)\bin .*?(\b(?:on|at)\s+line\s+\d+)', line) if m: result.description = string.join(m.groups()) else: result.description = line result.lineStart = result.lineEnd = lineNo result.columnStart = 1 result.columnEnd = len(datalines[result.lineEnd-1]) + 1 result.severity = result.SEV_ERROR results.addResult(result)
def lint_with_text(self, request, text): encoding_name = request.encoding.python_encoding_name if encoding_name not in ("ascii", "utf-8"): try: # Spidermonkey will choke on latin1 file input - bug 105635 - so try # and use UTF-8, else fall back to the original encoding. utext = text.decode(request.encoding.python_encoding_name) text = utext.encode("utf-8") except UnicodeError: pass # Just go with the original text then. jsfilename, isMacro, datalines = self._make_tempfile_from_text( request, text) cwd = request.cwd jsInterp = self._get_js_interp_path() # Lint the temp file, the jsInterp options are described here: # https://developer.mozilla.org/en/Introduction_to_the_JavaScript_shell cmd = [jsInterp, "-c"] # Set the JS linting preferences. prefset = request.prefset if not prefset.getBooleanPref("lintJavaScript_SpiderMonkey"): return enableWarnings = prefset.getBooleanPref('lintJavaScriptEnableWarnings') if enableWarnings: cmd.append("-w") enableStrict = prefset.getBooleanPref('lintJavaScriptEnableStrict') if enableStrict: cmd.append("-s") else: cmd.append("-W") cmd.append(jsfilename) cwd = cwd or None # We only need the stderr result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=self._setLDLibraryPath(), stdin=None) stdout, stderr = p.communicate() warnLines = stderr.splitlines(0) # Don't need the newlines. except: log.exception("Problem running CommonJSLinter") warnLines = [] finally: os.unlink(jsfilename) # 'js' error reports come in 4 line chunks that look like # this: # <filename>:8: SyntaxError: missing ; before statement: # <filename>:8: ar asdf = 1; # # <filename>:8: ...^ # <filename>:8: strict warning: function does not always return value: # <filename>:8: strict warning: }, # # <filename>:8: strict warning: ...^ # There is one exception: if the file is only one line then # the third blank line is not there. THerefore we will strip # empty lines and parse 3 line chunks. strippedWarnLines = [line for line in warnLines if line.strip()] # Parse out the xpcshell lint results results = koLintResults() state = _JS_STATE_EXP_MESSAGE # count index in 3 line groups # Mozilla 8 lines have a "0" after the line # -- ignore it headerPartRe = re.compile(r"^%s:(?P<lineNo>\d+):\d*\s*(?P<rest>.*)$" % re.escape(jsfilename)) lineNo = desc = numDots = None # Implement this state machine: # Start => <starts with filename> # Message, ends with desc => # Code, echoes code, not interesting => # Num Dots, shows where on line error starts => Start i = -1 limSub1 = len(strippedWarnLines) - 1 while i < limSub1: i += 1 line = strippedWarnLines[i] if not line: continue headerMatch = headerPartRe.match(line) if not headerMatch: if state == _JS_STATE_EXP_CODE: desc += " " + line continue restLine = headerMatch.group("rest").strip() thisLineNo = int(headerMatch.group("lineNo")) if state == _JS_STATE_EXP_MESSAGE: # first line: get the error description and line number firstLineMatch = self._firstLineRe.match(restLine) if firstLineMatch: lineNo = thisLineNo if isMacro: if lineNo > len(datalines) + 1: lineNo = len(datalines) errorType = firstLineMatch.group("type") desc = firstLineMatch.group("desc") state = _JS_STATE_EXP_CODE else: # continue on this, it's likely just debug build output msg = "Unexpected output when parsing JS syntax check(1) "\ "output: '%s'\n" % line log.debug(msg) state = _JS_STATE_EXP_MESSAGE continue if lineNo != thisLineNo: # This is actually the start of a new message, so log the current one, # and start fresh self._createAddResult(results, datalines, errorType, lineNo, desc, 0) state = _JS_STATE_EXP_MESSAGE desc = None i -= 1 # Redo this line elif state == _JS_STATE_EXP_CODE: # We don't care about this line state = _JS_STATE_EXP_DOTS continue # Now we should be looking at dots assert state == _JS_STATE_EXP_DOTS lastLineMatch = self._lastLineRe.search(restLine) if not lastLineMatch: lastLineMatch = self._strictLineRe.search(restLine) if not lastLineMatch: # continue on this, it's likely just debug build output msg = "Unexpected output when parsing JS syntax check(2) "\ "output: '%s'\n" % line log.debug(msg) continue if not desc: # if we don't have it, there are debug build lines # that have messed us up, restart at zero counter = _JS_STATE_EXP_MESSAGE continue # get the column of the error numDots = len(lastLineMatch.group("dots")) self._createAddResult(results, datalines, errorType, lineNo, desc, numDots) state = _JS_STATE_EXP_MESSAGE desc = None if desc is not None: self._createAddResult(results, datalines, errorType, lineNo, desc, 0) return results
def lint_with_text(self, request, text): if not text: #log.debug("<< no text") return prefset = request.prefset if not prefset.getBooleanPref("lintWithJSHint"): return jsfilename, isMacro, datalines = self._make_tempfile_from_text( request, text) jsInterp = self._get_js_interp_path() jsLintDir = os.path.join(self.koDirs.supportDir, "lint", "javascript") jsLintApp = os.path.join(jsLintDir, "lintWrapper.js") jsLintBasename = None try: customJSLint = prefset.getStringPref("jshint_linter_chooser") if customJSLint == "specific": p = prefset.getStringPref("jshint_linter_specific") if p and os.path.exists(p): jsLintDir = os.path.dirname(p) + "/" jsLintBasename = os.path.basename(p) except: log.exception("Problem finding the custom lintjs file") options = prefset.getStringPref("jshintOptions").strip() # Lint the temp file, the jsInterp options are described here: # https://developer.mozilla.org/en/Introduction_to_the_JavaScript_shell cmd = [jsInterp, jsLintApp, "--include=" + jsLintDir] if jsLintBasename: cmd.append("--jshint-basename=" + jsLintBasename) if options: # Drop empty parts. otherParts = [s for s in re.compile(r'\s+').split(options)] cmd += [s for s in re.compile(r'\s+').split(options)] if request.koDoc.language == "Node.js": if not "node=" in options: cmd.append("node=1") if (not self.strict_option_re.match(options) and 'globalstrict=' not in options): # jshint tests options.strict !== false, otherwise strict is on # Other options are tested as simply !options.strict cmd.append('strict=false') if not "esnext" in options and not "esversion" in options: cmd.append('esnext=true') fd = open(jsfilename) cwd = request.cwd or None # We only need the stderr result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=self._setLDLibraryPath(), stdin=fd) stdout, stderr = p.communicate() if stderr: log.warn("Error in jshint: stderr: %s, command was: %s", stderr, cmd) #log.debug("jshint: stdout: %s, stderr: %s", stdout, stderr) warnLines = stdout.splitlines() # Don't need the newlines. i = 0 outputStart = "++++JSHINT OUTPUT:" while i < len(warnLines): if outputStart in warnLines[i]: warnLines = warnLines[i + 1:] break i += 1 except: log.exception("Problem running GenericJSLinter") finally: try: fd.close() except: log.error("Problem closing file des(%s)", jsfilename) try: os.unlink(jsfilename) except: log.error("Problem deleting file des(%s)", jsfilename) # 'jshint' error reports come in this form: # jshint error: at line \d+ column \d+: explanation results = koLintResults() msgRe = re.compile( "^jshint error: at line (?P<lineNo>\d+) column (?P<columnNo>\d+):\s*(?P<desc>.*?)$" ) numDataLines = len(datalines) if len(warnLines) % 2 == 1: warnLines.append("") for i in range(0, len(warnLines), 2): msgLine = warnLines[i] evidenceLine = warnLines[i + 1] m = msgRe.match(msgLine) if m: lineNo = int(m.group("lineNo")) - 1 if lineNo >= numDataLines: lineNo = numDataLines - 1 #columnNo = int(m.group("columnNo")) # build lint result object result = KoLintResult() # if the error is on the last line, work back to the last # character of the first nonblank line so we can display # the error somewhere if len(datalines[lineNo]) == 0: while lineNo > 0 and len(datalines[lineNo - 1]) == 0: lineNo -= 1 result.columnStart = 1 result.columnEnd = len(datalines[lineNo]) + 1 result.lineStart = result.lineEnd = lineNo + 1 result.severity = result.SEV_WARNING result.description = m.group("desc") results.addResult(result) return results
def lint_with_text(self, request, text): # Pull out the EJS parts and wrap into a single JS file textAsBytes = text.encode("utf-8") lim = len(textAsBytes) finalPieces = ["var __ViewO = []; "] i = 0 state = 0 results = koLintResults() textLines = textAsBytes.splitlines() lineNum = 1 haveJS = False while i < lim: if state == 0: idx = textAsBytes.find("<%", i) if idx == -1: thisBit = textAsBytes[i:] else: thisBit = textAsBytes[i:idx] lineNum += thisBit.count("\n") self._addVerbatimPieces(finalPieces, thisBit) if idx == -1: break try: c = textAsBytes[idx + 2] if c == '=': haveJS = True elif c == '#': haveJS = True elif c == '%': pass # stay at state 0 else: raise IndexError() i = idx + 3 finalPieces.append(" ") except IndexError: state = 2 i = idx + 2 finalPieces.append(" ") else: idx = textAsBytes.find("%%>", i) if idx >= 0: finalPieces.append(" ") i = idx + 3 continue idx = textAsBytes.find("%>", i) if idx == -1: thisBit = textAsBytes[i:] else: thisBit = textAsBytes[i:idx] lineNum += thisBit.count("\n") if state == 1: self._addEmittedPieces(finalPieces, thisBit) elif state == 2: self._addJSPieces(finalPieces, thisBit) else: # Convert the comment block into spaces finalPieces.append(self._dot_to_space_re.sub(' ', thisBit)) finalPieces.append(" ") if idx == -1: createAddResult(results, textLines, SEV_ERROR, lineNum, "Missing closing '%>'") break i = idx + 2 state = 0 if haveJS: jsText = ("").join(finalPieces) jsResults = self._jsLinter.lint_with_text(request, jsText) results.addResults(jsResults) return results