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): 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_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_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 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): #pylint: disable=R0201 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): #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): try: prefset = request.prefset linterPrefName = "%sLinterType" % self.cmd scssLinterType = prefset.getStringPref(linterPrefName) if scssLinterType == "none": return if scssLinterType == "builtin": return KoCSSLinter().lint_with_text(request, text) interpreterPrefName = "%sDefaultInterpreter" % self.cmd scssPath = prefset.getStringPref(interpreterPrefName) # The 'or' part handles any language for "Find on Path" if (not scssPath) or not os.path.exists(scssPath): try: scssPath = which.which(self.cmd) except which.WhichError: pass if not scssPath or not os.path.exists(scssPath): log.warn("Setting %sLinterType to 'default': %s not found", self.cmd, self.cmd) prefset.setStringPref(linterPrefName, "builtin") return KoCSSLinter().lint_with_text(request, text) else: prefset.setStringPref(interpreterPrefName, scssPath) rubyPath = prefset.getStringPref("rubyDefaultInterpreter") if (not rubyPath) or not os.path.exists(rubyPath): try: rubyPath = which.which("ruby") except which.WhichError: pass if (not rubyPath) or not os.path.exists(rubyPath): log.warn( "Setting %s to 'default': no ruby found to drive %s", linterPrefName, self.cmd) prefset.setStringPref(linterPrefName, "builtin") return KoCSSLinter.lint_with_text(self, request, text) else: prefset.setStringPref("rubyDefaultInterpreter", rubyPath) # Run scss tmpfilename = tempfile.mktemp() + '.' + self.cmd fout = open(tmpfilename, 'wb') fout.write(text) fout.close() textlines = text.splitlines() cmd = [rubyPath, scssPath, "-c", tmpfilename] koLintResult.insertNiceness(cmd) cwd = request.cwd or None # We only need the stderr result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=koprocessutils.getUserEnv(), stdin=None) stderr = p.communicate()[1] warnLines = stderr.splitlines(0) # Don't need the newlines. except: warnLines = [] finally: os.unlink(tmpfilename) except: log.exception("scss: lint_with_text: big fail") warnLines = [] results = koLintResults() prevLine = "" for line in warnLines: m = self._scss_emsg_ptn.match(line) if m: lineNo = int(m.group(1)) m2 = self._syntaxErrorPtn.match(prevLine) if m2: severity = koLintResult.SEV_ERROR msg = m2.group(1) else: severity = koLintResult.SEV_WARNING msg = prevLine desc = "scss: " + msg koLintResult.createAddResult(results, textlines, severity, lineNo, desc) else: prevLine = line return results
def lint_with_text(self, request, text): try: prefset = request.prefset lessLinterType = prefset.getStringPref("lessLinterType") if lessLinterType == "none": return if lessLinterType == "builtin": return KoCSSLinter.lint_with_text(self, request, text) lessPath = prefset.getStringPref("lessDefaultInterpreter") # The 'or' part handles any language for "Find on Path" if (not lessPath) or not os.path.exists(lessPath): try: lessPath = which.which("lessc") except which.WhichError: pass if (not lessPath) or not os.path.exists(lessPath): log.warn( "Setting lessLinterType to 'default': less not found") prefset.setStringPref("lessLinterType", "builtin") return KoCSSLinter.lint_with_text(self, request, text) else: prefset.setStringPref("lessDefaultInterpreter", lessPath) nodePath = prefset.getStringPref("nodejsDefaultInterpreter") if (not nodePath) or not os.path.exists(nodePath): try: nodePath = which.which("node") except which.WhichError: pass if (not nodePath) or not os.path.exists(nodePath): log.warn( "Setting lessLinterType to 'default': no node found to drive less" ) prefset.setStringPref("lessLinterType", "builtin") return KoCSSLinter.lint_with_text(self, request, text) else: prefset.setStringPref("nodejsDefaultInterpreter", nodePath) # Run less tmpfilename = tempfile.mktemp() + '.less' fout = open(tmpfilename, 'wb') fout.write(text) fout.close() textlines = text.splitlines() cmd = [nodePath, lessPath, "--no-color", tmpfilename] koLintResult.insertNiceness(cmd) cwd = request.cwd or None # We only need the stderr result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=koprocessutils.getUserEnv(), stdin=None) stderr = p.communicate()[1] warnLines = stderr.splitlines(0) # Don't need the newlines. except: warnLines = [] finally: os.unlink(tmpfilename) except: log.exception("less: lint_with_text: big fail") warnLines = [] # They're all errors for this checker # (and they all say "Syntax Checker!") # (at least version 1.3.0 of the LESS Compiler does). severity = koLintResult.SEV_ERROR results = koLintResults() for line in warnLines: m = self._less_emsg_ptn.match(line) if m: lineNo = int(m.group(2)) desc = m.group(1) koLintResult.createAddResult(results, textlines, severity, lineNo, desc) return results
def lint_with_text(self, request, text): if not text: return None prefset = request.prefset if not prefset.getBooleanPref(self.lint_prefname): return pychecker = prefset.getStringPref(self.wrapper_location) if not pychecker: return if sys.platform.startswith("win") and not os.path.exists(pychecker): if os.path.exists(pychecker + ".bat"): pychecker = pychecker + ".bat" elif os.path.exists(pychecker + ".exe"): pychecker = pychecker + ".exe" if not os.path.exists(pychecker): return fout, tmpfilename = _localTmpFileName() try: fout.write(text) fout.close() textlines = text.splitlines() cwd = request.cwd env = self._get_fixed_env(prefset, cwd) rcfilePath = prefset.getStringPref(self.rcfile_prefname) if rcfilePath and os.path.exists(rcfilePath): extraArgs = [ '--config=%s' % (rcfilePath,) ] else: extraArgs = [] cmd = [pychecker, "--keepgoing", "--only"] + extraArgs + [tmpfilename] cwd = request.cwd or None # We only need the stdout result. p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None) stdout, stderr = p.communicate() warnLines = stdout.splitlines(0) # Don't need the newlines. errorLines = stderr.splitlines(0) finally: try: os.unlink(tmpfilename) # pychecker leaves .pyc files around, so delete them as well os.unlink(tmpfilename + "c") except: pass # Check raw output for an exception results = koLintResults() re_escaped_filename = re.escape(tmpfilename) exception_ptn = re.compile('''Caught exception importing module.+?File "%s", line (\d+), in <module>.+?\s*(\w+(?:Error|Exception):\s+.*)''' % re_escaped_filename, re.DOTALL) m = exception_ptn.search(stderr) if m: lineNo = int(m.group(1)) desc = m.group(2) koLintResult.createAddResult(results, textlines, koLintResult.SEV_ERROR, lineNo, desc) warn_ptn = re.compile(r'^%s:(\d+):\s+(.+)' % re_escaped_filename) error_ptn = re.compile(r'(.*[Ee]rror:.*?)\s*\(%s,\s+line\s+(\d+)\)' % re_escaped_filename) for line in warnLines: m = warn_ptn.match(line) if m: lineNo = int(m.group(1)) desc = m.group(2) koLintResult.createAddResult(results, textlines, koLintResult.SEV_WARNING, lineNo, "pychecker: " + desc) for line in errorLines: m = error_ptn.match(line) if m: lineNo = int(m.group(2)) desc = m.group(1) koLintResult.createAddResult(results, textlines, koLintResult.SEV_ERROR, lineNo, "pychecker: " + desc) return results
def lint_with_text(self, request, text): if not text: return None prefset = request.prefset if not prefset.getBooleanPref(self.lint_prefname): return # if not prefset.getBooleanPref("lintWithPylint"): return pythonExe = self._pythonInfo.getExecutableFromDocument(request.koDoc) if not pythonExe: return cwd = request.cwd fout, tmpfilename = _localTmpFileName() try: tmpBaseName = os.path.splitext(os.path.basename(tmpfilename))[0] fout.write(text) fout.close() textlines = text.splitlines() env = self._get_fixed_env(prefset, cwd) rcfilePath = prefset.getStringPref(self.rcfile_prefname) if rcfilePath and os.path.exists(rcfilePath): extraArgs = [ '--rcfile="%s"' % (rcfilePath,) ] else: extraArgs = [] preferredLineWidth = prefset.getLongPref("editAutoWrapColumn") if preferredLineWidth > 0: extraArgs.append("--max-line-length=%d" % preferredLineWidth) baseArgs = [pythonExe, '-c', 'import sys; from pylint.lint import Run; Run(sys.argv[1:])'] cmd = baseArgs + ["-f", "text", "-r", "n", "-i", "y"] + extraArgs cmd.append(tmpfilename) cwd = request.cwd or None # We only need the stdout result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None) stdout, stderr = p.communicate() if stderr: origStderr = stderr okStrings = ["No config file found, using default configuration",] for okString in okStrings: stderr = stderr.replace(okString, "", 1) stderr = stderr.strip() if stderr: pathMessageKey = "%s-%s" % (request.koDoc.displayPath, origStderr) _complainIfNeeded(pathMessageKey, "Error in pylint: %s", origStderr) return warnLines = stdout.splitlines(0) # Don't need the newlines. except: log.exception("Failed to run %s", cmd) stdout = "" warnLines = [] finally: os.unlink(tmpfilename) ptn = re.compile(r'^([A-Z])(\d+):\s*(\d+)(?:,\d+)?:\s*(.*)') # dependency: _localTmpFileName() prepends a '#' on the basename #invalid_name_ptn = pe.compile(r'C0103:\s*[\d:,]+\s*Invalid name "#.+?"') results = koLintResults() for line in warnLines: m = ptn.match(line) if m: status = m.group(1) statusCode = m.group(2) lineNo = int(m.group(3)) desc = "pylint: %s%s %s" % (status, statusCode, m.group(4)) if status in ("E", "F"): severity = koLintResult.SEV_ERROR elif status in ("C", "R", "W"): if statusCode == "0103": # Don't let pylint complain about the tempname, but fake # a check on the actual module name. m = self.invalidModuleName_RE.match(line) if m: complainedName = m.group(2) if complainedName != tmpBaseName: # Not a real complaint continue shouldMatch_RE = self._createShouldMatchPtn(m.group(4)) koFile = request.koDoc.file actualBaseName = koFile.baseName[:-len(koFile.ext)] if shouldMatch_RE.match(actualBaseName): # The current file is actually valid continue # Fix the description desc = "pylint: " + m.group(1) + actualBaseName + m.group(3) + m.group(4) + m.group(5) severity = koLintResult.SEV_WARNING else: #log.debug("Skip %s", line) continue koLintResult.createAddResult(results, textlines, severity, lineNo, desc) return results
def lint_with_text(self, request, text): try: prefset = request.prefset lessLinterType = prefset.getStringPref("lessLinterType") if lessLinterType == "none": return if lessLinterType == "builtin": return KoCSSLinter.lint_with_text(self, request, text) lessPath = prefset.getStringPref("lessDefaultInterpreter") # The 'or' part handles any language for "Find on Path" if (not lessPath) or not os.path.exists(lessPath): try: lessPath = which.which("lessc") except which.WhichError: pass if (not lessPath) or not os.path.exists(lessPath): log.warn("Setting lessLinterType to 'default': less not found") prefset.setStringPref("lessLinterType", "builtin") return KoCSSLinter.lint_with_text(self, request, text) else: prefset.setStringPref("lessDefaultInterpreter", lessPath) nodePath = prefset.getStringPref("nodejsDefaultInterpreter") if (not nodePath) or not os.path.exists(nodePath): try: nodePath = which.which("node") except which.WhichError: pass if (not nodePath) or not os.path.exists(nodePath): log.warn("Setting lessLinterType to 'default': no node found to drive less") prefset.setStringPref("lessLinterType", "builtin") return KoCSSLinter.lint_with_text(self, request, text) else: prefset.setStringPref("nodejsDefaultInterpreter", nodePath) # Run less tmpfilename = tempfile.mktemp() + '.less' fout = open(tmpfilename, 'wb') fout.write(text) fout.close() textlines = text.splitlines() cmd = [nodePath, lessPath, "--no-color", tmpfilename] #koLintResult.insertNiceness(cmd) cwd = request.cwd or None # We only need the stderr result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=koprocessutils.getUserEnv(), stdin=None) stderr = p.communicate()[1] warnLines = stderr.splitlines(0) # Don't need the newlines. except: warnLines = [] finally: os.unlink(tmpfilename) except: log.exception("less: lint_with_text: big fail") warnLines = [] # They're all errors for this checker # (and they all say "Syntax Checker!") # (at least version 1.3.0 of the LESS Compiler does). severity = koLintResult.SEV_ERROR results = koLintResults() for line in warnLines: m = self._less_emsg_ptn.match(line) if m: lineNo = int(m.group(2)) desc = m.group(1) column = int(m.group(3)) koLintResult.createAddResult(results, textlines, severity, lineNo, desc, columnStart=column) else: m = self._less_emsg_ptn_old.match(line) if m: lineNo = int(m.group(2)) desc = m.group(1) koLintResult.createAddResult(results, textlines, severity, lineNo, desc) return results
def lint_with_text(self, request, text): if not text: return None prefset = request.prefset if not prefset.getBooleanPref(self.lint_prefname): return # if not prefset.getBooleanPref("lintWithPylint"): return pythonExe = self._pythonInfo.getExecutableFromDocument(request.koDoc) if not pythonExe: return cwd = request.cwd fout, tmpfilename = _localTmpFileName() try: tmpBaseName = os.path.splitext(os.path.basename(tmpfilename))[0] fout.write(text) fout.close() textlines = text.splitlines() env = self._get_fixed_env(prefset, cwd) rcfilePath = prefset.getStringPref(self.rcfile_prefname) if rcfilePath and os.path.exists(rcfilePath): extraArgs = ['--rcfile=%s' % (rcfilePath, )] else: extraArgs = [] preferredLineWidth = prefset.getLongPref("editAutoWrapColumn") if preferredLineWidth > 0: extraArgs.append("--max-line-length=%d" % preferredLineWidth) baseArgs = [ pythonExe, '-c', 'import sys; from pylint.lint import Run; Run(sys.argv[1:])' ] cmd = baseArgs + ["-f", "text", "-r", "n", "-i", "y"] + extraArgs cmd.append(tmpfilename) cwd = request.cwd or None # We only need the stdout result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None) stdout, stderr = p.communicate() if stderr: origStderr = stderr okStrings = [ "No config file found, using default configuration", ] for okString in okStrings: stderr = stderr.replace(okString, "", 1) stderr = stderr.strip() if stderr: pathMessageKey = "%s-%s" % (request.koDoc.displayPath, origStderr) _complainIfNeeded(pathMessageKey, "Error in pylint: %s", origStderr) return warnLines = stdout.splitlines(0) # Don't need the newlines. except: log.exception("Failed to run %s", cmd) stdout = "" warnLines = [] finally: os.unlink(tmpfilename) ptn = re.compile(r'^([A-Z])(\d+):\s*(\d+)(?:,\d+)?:\s*(.*)') # dependency: _localTmpFileName() prepends a '#' on the basename #invalid_name_ptn = pe.compile(r'C0103:\s*[\d:,]+\s*Invalid name "#.+?"') results = koLintResults() for line in warnLines: m = ptn.match(line) if m: status = m.group(1) statusCode = m.group(2) lineNo = int(m.group(3)) desc = "pylint: %s%s %s" % (status, statusCode, m.group(4)) if status in ("E", "F"): severity = koLintResult.SEV_ERROR elif status in ("C", "R", "W"): if statusCode == "0103": # Don't let pylint complain about the tempname, but fake # a check on the actual module name. m = self.invalidModuleName_RE.match(line) if m: complainedName = m.group(2) if complainedName != tmpBaseName: # Not a real complaint continue shouldMatch_RE = self._createShouldMatchPtn( m.group(4)) koFile = request.koDoc.file actualBaseName = koFile.baseName[:-len(koFile.ext)] if shouldMatch_RE.match(actualBaseName): # The current file is actually valid continue # Fix the description desc = "pylint: " + m.group( 1) + actualBaseName + m.group(3) + m.group( 4) + m.group(5) severity = koLintResult.SEV_WARNING else: #log.debug("Skip %s", line) continue koLintResult.createAddResult(results, textlines, severity, lineNo, desc) return results
def lint_with_text(self, request, text): if not text: return None prefset = getProxiedEffectivePrefs(request) if not prefset.getBooleanPref("lint_python_with_pychecker"): return pychecker = prefset.getStringPref("pychecker_wrapper_location") if not pychecker: return if sys.platform.startswith("win") and not os.path.exists(pychecker): if os.path.exists(pychecker + ".bat"): pychecker = pychecker + ".bat" elif os.path.exists(pychecker + ".exe"): pychecker = pychecker + ".exe" if not os.path.exists(pychecker): return tmpfilename = tempfile.mktemp() + '.py' fout = open(tmpfilename, 'wb') fout.write(text) fout.close() textlines = text.splitlines() cwd = request.cwd env = self._get_fixed_env(prefset) rcfilePath = prefset.getStringPref("pychecker_checking_rcfile") if rcfilePath and os.path.exists(rcfilePath): if self.nonIdentChar_RE.search(rcfilePath): rcfilePath = '"' + rcfilePath + '"' extraArgs = [ "--config=" + rcfilePath ] else: extraArgs = [] cmd = [pychecker, "--keepgoing", "--only"] + extraArgs + [tmpfilename] cwd = request.cwd or None # We only need the stdout result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None) stdout, stderr = p.communicate() warnLines = stdout.splitlines(0) # Don't need the newlines. errorLines = stderr.splitlines(0) finally: os.unlink(tmpfilename) # Check raw output for an exception results = koLintResults() re_escaped_filename = re.escape(tmpfilename) exception_ptn = re.compile('''Caught exception importing module.+?File "%s", line (\d+), in <module>.+?\s*(\w+(?:Error|Exception):\s+.*)''' % re_escaped_filename, re.DOTALL) m = exception_ptn.search(stderr) if m: lineNo = int(m.group(1)) desc = m.group(2) koLintResult.createAddResult(results, textlines, koLintResult.SEV_ERROR, lineNo, desc) warn_ptn = re.compile(r'^%s:(\d+):\s+(.+)' % re_escaped_filename) error_ptn = re.compile(r'(.*[Ee]rror:.*?)\s*\(%s,\s+line\s+(\d+)\)' % re_escaped_filename) for line in warnLines: m = warn_ptn.match(line) if m: lineNo = int(m.group(1)) desc = m.group(2) koLintResult.createAddResult(results, textlines, koLintResult.SEV_WARNING, lineNo, "pychecker: " + desc) for line in errorLines: m = error_ptn.match(line) if m: lineNo = int(m.group(2)) desc = m.group(1) koLintResult.createAddResult(results, textlines, koLintResult.SEV_ERROR, lineNo, "pychecker: " + desc) return results
def lint_with_text(self, request, text): if not text: return None prefset = getProxiedEffectivePrefs(request) if not prefset.getBooleanPref("lint_python_with_pylint"): return # if not prefset.getBooleanPref("lintWithPylint"): return pythonExe = self._pythonInfo.getExecutableFromDocument(request.koDoc) if not pythonExe: return tmpfilename = tempfile.mktemp() + '.py' fout = open(tmpfilename, 'wb') fout.write(text) fout.close() textlines = text.splitlines() cwd = request.cwd env = self._get_fixed_env(prefset) rcfilePath = prefset.getStringPref("pylint_checking_rcfile") if rcfilePath and os.path.exists(rcfilePath): if self.nonIdentChar_RE.search(rcfilePath): rcfilePath = '"' + rcfilePath + '"' extraArgs = [ "--rcfile=" + rcfilePath ] else: # Hardwire in these three messages: extraArgs = []# [ "-d", "C0103", "-d" , "C0111", "-d", "F0401"] preferredLineWidth = prefset.getLongPref("editAutoWrapColumn") if preferredLineWidth > 0: extraArgs.append("--max-line-length=%d" % preferredLineWidth) baseArgs = [pythonExe, '-c', 'import sys; from pylint.lint import Run; Run(sys.argv[1:])'] cmd = baseArgs + ["-f", "text", "-r", "n", "-i", "y"] + extraArgs # Put config file entry here: .rcfile=<file> cmd.append(tmpfilename) cwd = request.cwd or None # We only need the stdout result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None) stdout, _ = p.communicate() warnLines = stdout.splitlines(0) # Don't need the newlines. except: log.exception("Failed to run %s", cmd) stdout = "" warnLines = [] finally: os.unlink(tmpfilename) ptn = re.compile(r'^([A-Z])(\d+):\s*(\d+)(?:,\d+)?:\s*(.*)') results = koLintResults() for line in warnLines: m = ptn.match(line) if m: status = m.group(1) statusCode = m.group(2) lineNo = int(m.group(3)) desc = "pylint: %s%s %s" % (status, statusCode, m.group(4)) if status in ("E", "F"): severity = koLintResult.SEV_ERROR elif status in ("C", "R", "W"): severity = koLintResult.SEV_WARNING else: #log.debug("Skip %s", line) continue koLintResult.createAddResult(results, textlines, severity, lineNo, desc) 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
def lint_with_text(self, request, text): if not text: return None prefset = request.prefset # self.lint_prefname: "lint_python_with_pylint" or "lint_python3_with_pylint3" if not prefset.getBoolean(self.lint_prefname): return pythonExe = self._pythonInfo.getExecutableFromPrefs(prefset) if not pythonExe: return if not hasattr(self, "_pylint_version"): self._set_pylint_version(pythonExe) cwd = request.cwd fout, tmpfilename = _localTmpFileName() try: tmpBaseName = os.path.splitext(os.path.basename(tmpfilename))[0] fout.write(text) fout.close() textlines = text.splitlines() env = self._get_fixed_env(prefset, cwd) rcfilePath = prefset.getStringPref(self.rcfile_prefname) rcfileToCheck = None if rcfilePath and os.path.exists(rcfilePath): extraArgs = ['--rcfile=%s' % (rcfilePath, )] rcfileToCheck = rcfilePath else: # Check for the default ~/.pylintrc defaultRC = os.path.expanduser(os.path.join("~", ".pylintrc")) if os.path.exists(defaultRC): rcfileToCheck = defaultRC extraArgs = [] preferredLineWidth = prefset.getLongPref("editAutoWrapColumn") if preferredLineWidth > 0: usePreferredLineWidth = True if rcfileToCheck is not None: _max_line_length_re = re.compile(r'\s*max-line-length') _disables_C0301_re = re.compile( r'\s*disable\s*=.*?\bC0301\b') f = open(rcfileToCheck, "r") try: for txt in iter(f): if _disables_C0301_re.match(txt) \ or _max_line_length_re.match(txt): usePreferredLineWidth = False break except: pass finally: f.close() if usePreferredLineWidth: extraArgs.append("--max-line-length=%d" % preferredLineWidth) baseArgs = [ pythonExe, '-c', 'import sys; from pylint.lint import Run; Run(sys.argv[1:])' ] cmd = baseArgs + ["-f", "text", "-r", "n"] + extraArgs if self._pylint_version == 1: cmd.append("-i") cmd.append("y") else: # _pylint_version == 2 cmd.append("--msg-template") cmd.append("{msg_id}: {line},{column}: {msg}") cmd.append(tmpfilename) cwd = request.cwd or None # We only need the stdout result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None) stdout, stderr = p.communicate() if stderr: origStderr = stderr okStrings = [ "No config file found, using default configuration", ] for okString in okStrings: stderr = stderr.replace(okString, "", 1) stderr = stderr.strip() if stderr: pathMessageKey = "%s-%s" % (request.koDoc.displayPath, origStderr) _complainIfNeeded(pathMessageKey, "Error in pylint: %s", origStderr) warnLines = stdout.splitlines(0) # Don't need the newlines. except: log.exception("Failed to run %s", cmd) stdout = "" warnLines = [] finally: os.unlink(tmpfilename) ptn = re.compile(r'^([A-Z])(\d+):\s*(\d+)(?:,\d+)?:\s*(.*)') invalidModuleName_RE = re.compile( r'(Invalid\s+module\s+name\s+")(\#.+?)(")') # dependency: _localTmpFileName() prepends a '#' on the basename results = koLintResults() for line in warnLines: m = ptn.match(line) if m: status = m.group(1) statusCode = m.group(2) lineNo = int(m.group(3)) message = m.group(4) desc = "pylint: %s%s %s" % (status, statusCode, message) if status in ("E", "F"): if statusCode == "0401" and "import '#" in message: # When attempting to perform relative imports, pylint # does not take the cwd into account, but the path of # the temporary file being linted. Reject this error. continue severity = koLintResult.SEV_ERROR elif status in ("C", "R", "W"): if statusCode == "0103": # Don't let pylint complain about the tempname, but fake # a check on the actual module name. m2 = invalidModuleName_RE.match(message) if m2: complainedName = m2.group(2) if complainedName == tmpBaseName: # Not a real complaint continue # Don't bother further analysis, in case pylint # behaves differently between python2 and python3 # # If the message is about a bad module that isn't # the temporary module, let it ride as is elif statusCode == "0406" and re.match( "^\\s*from\\s+\\.", textlines[lineNo - 1]): # When attempting to perform relative imports, pylint # does not take the cwd into account, but the path of # the temporary file being linted. As a result pylint # may warn that this file is importing itself. Reject # this warning. continue severity = koLintResult.SEV_WARNING else: #log.debug("Skip %s", line) continue koLintResult.createAddResult(results, textlines, severity, lineNo, desc) return results
def lint_with_text(self, request, text): if not text: return None prefset = request.prefset # if not prefset.getBooleanPref("lintPythonWithPep8"): return if not prefset.getBooleanPref(self.lint_prefname): return pythonExe = self._pythonInfo.getExecutableFromPrefs(prefset) if not pythonExe: return cwd = request.cwd fout, tmpfilename = _localTmpFileName() try: tmpBaseName = os.path.splitext(os.path.basename(tmpfilename))[0] fout.write(text) fout.close() textlines = text.splitlines() env = self._get_fixed_env(prefset, cwd) cmd = [pythonExe, '-m', 'pep8'] checkRCFile = False rcfilePath = prefset.getStringPref(self.rcfile_prefname) if rcfilePath and os.path.exists(rcfilePath): extraArgs = ['--config=%s' % (rcfilePath, )] checkRCFile = True else: extraArgs = [] # default location: ~/.pep8 homeDir = os.path.expanduser("~") rcfilePath = os.path.join(homeDir, ".pep8") if not os.path.exists(rcfilePath): rcfilePath = os.path.join(homeDir, ".config", "pep8") checkRCFile = os.path.exists(rcfilePath) preferredLineWidth = prefset.getLongPref("editAutoWrapColumn") if preferredLineWidth > 0: usePreferredLineWidth = True if checkRCFile: _disables_E0501_re = re.compile( r'\s*disable\s*=.*?\bE0?501\b') _max_line_length_re = re.compile(r'\s*max-line-length') f = open(rcfilePath, "r") try: for txt in iter(f): if _disables_E0501_re.match(txt) \ or _max_line_length_re.match(txt): usePreferredLineWidth = False break except: log.exception("Problem checking max-line-length") finally: f.close() if usePreferredLineWidth: extraArgs.append("--max-line-length=%d" % preferredLineWidth) cmd += extraArgs cmd.append(tmpfilename) cwd = request.cwd or None # We only need the stdout result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None) stdout, stderr = p.communicate() # pep8 returns 1 if syntax errors were found, 0 otherwise. # If pep8 returns something else, this means that a runtime # error occured if p.returncode not in [0, 1]: pathMessageKey = "%s-%s" % (request.koDoc.displayPath, stderr) _complainIfNeeded(pathMessageKey, "Error in pep8: %s", stderr) return warnLines = stdout.splitlines( False) # Don't need the newlines. except: log.exception("Failed to run %s", cmd) stdout = "" warnLines = [] finally: os.unlink(tmpfilename) ptn = re.compile( r'(?P<filename>.*?):(?P<lineNum>\d+):(?P<columnNum>\d+):\s*(?P<status>[EW])(?P<statusCode>\d+)\s+(?P<message>.*)' ) results = koLintResults() for m in map(ptn.match, warnLines): if m: lineNo = int(m.group("lineNum")) columnNum = int(m.group("columnNum")) desc = "pep8: %s%s %s" % (m.group("status"), m.group("statusCode"), m.group("message")) # Everything pep8 complains about is a warning, by definition severity = koLintResult.SEV_WARNING koLintResult.createAddResult(results, textlines, severity, lineNo, desc, columnStart=columnNum) return results
def lint_with_text(self, request, text): if not text: return None prefset = request.prefset # self.lint_prefname: "lint_python_with_pylint" or "lint_python3_with_pylint3" if not prefset.getBoolean(self.lint_prefname): return pythonExe = self._pythonInfo.getExecutableFromPrefs(prefset) if not pythonExe: return if not hasattr(self, "_pylint_version"): self._set_pylint_version(pythonExe) cwd = request.cwd fout, tmpfilename = _localTmpFileName() try: tmpBaseName = os.path.splitext(os.path.basename(tmpfilename))[0] fout.write(text) fout.close() textlines = text.splitlines() env = self._get_fixed_env(prefset, cwd) rcfilePath = prefset.getStringPref(self.rcfile_prefname) rcfileToCheck = None if rcfilePath and os.path.exists(rcfilePath): extraArgs = [ '--rcfile=%s' % (rcfilePath,) ] rcfileToCheck = rcfilePath else: # Check for the default ~/.pylintrc defaultRC = os.path.expanduser(os.path.join("~", ".pylintrc")) if os.path.exists(defaultRC): rcfileToCheck = defaultRC extraArgs = [] preferredLineWidth = prefset.getLongPref("editAutoWrapColumn") if preferredLineWidth > 0: usePreferredLineWidth = True if rcfileToCheck is not None: _max_line_length_re = re.compile(r'\s*max-line-length') _disables_C0301_re = re.compile(r'\s*disable\s*=.*?\bC0301\b') f = open(rcfileToCheck, "r") try: for txt in iter(f): if _disables_C0301_re.match(txt) \ or _max_line_length_re.match(txt): usePreferredLineWidth = False break except: pass finally: f.close() if usePreferredLineWidth: extraArgs.append("--max-line-length=%d" % preferredLineWidth) baseArgs = [pythonExe, '-c', 'import sys; from pylint.lint import Run; Run(sys.argv[1:])'] cmd = baseArgs + ["-f", "text", "-r", "n"] + extraArgs if self._pylint_version == 1: cmd.append("-i") cmd.append("y") else: # _pylint_version == 2 cmd.append("--msg-template") cmd.append("{msg_id}: {line},{column}: {msg}") cmd.append(tmpfilename) cwd = request.cwd or None # We only need the stdout result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None) stdout, stderr = p.communicate() if stderr: origStderr = stderr okStrings = ["No config file found, using default configuration",] for okString in okStrings: stderr = stderr.replace(okString, "", 1) stderr = stderr.strip() if stderr: pathMessageKey = "%s-%s" % (request.koDoc.displayPath, origStderr) _complainIfNeeded(pathMessageKey, "Error in pylint: %s", origStderr) warnLines = stdout.splitlines(0) # Don't need the newlines. except: log.exception("Failed to run %s", cmd) stdout = "" warnLines = [] finally: os.unlink(tmpfilename) ptn = re.compile(r'^([A-Z])(\d+):\s*(\d+)(?:,\d+)?:\s*(.*)') invalidModuleName_RE = re.compile(r'(Invalid\s+module\s+name\s+")(\#.+?)(")') # dependency: _localTmpFileName() prepends a '#' on the basename results = koLintResults() for line in warnLines: m = ptn.match(line) if m: status = m.group(1) statusCode = m.group(2) lineNo = int(m.group(3)) message = m.group(4) desc = "pylint: %s%s %s" % (status, statusCode, message) if status in ("E", "F"): if statusCode == "0401" and "import '#" in message: # When attempting to perform relative imports, pylint # does not take the cwd into account, but the path of # the temporary file being linted. Reject this error. continue severity = koLintResult.SEV_ERROR elif status in ("C", "R", "W"): if statusCode == "0103": # Don't let pylint complain about the tempname, but fake # a check on the actual module name. m2 = invalidModuleName_RE.match(message) if m2: complainedName = m2.group(2) if complainedName == tmpBaseName: # Not a real complaint continue # Don't bother further analysis, in case pylint # behaves differently between python2 and python3 # # If the message is about a bad module that isn't # the temporary module, let it ride as is elif statusCode == "0406" and re.match("^\\s*from\\s+\\.", textlines[lineNo - 1]): # When attempting to perform relative imports, pylint # does not take the cwd into account, but the path of # the temporary file being linted. As a result pylint # may warn that this file is importing itself. Reject # this warning. continue severity = koLintResult.SEV_WARNING else: #log.debug("Skip %s", line) continue koLintResult.createAddResult(results, textlines, severity, lineNo, desc) return results
def lint_with_text(self, request, text): if not text: return None prefset = request.prefset if not prefset.getBooleanPref(self.lint_prefname): return pychecker = prefset.getStringPref(self.wrapper_location) if not pychecker: return if sys.platform.startswith("win") and not os.path.exists(pychecker): if os.path.exists(pychecker + ".bat"): pychecker = pychecker + ".bat" elif os.path.exists(pychecker + ".exe"): pychecker = pychecker + ".exe" if not os.path.exists(pychecker): return fout, tmpfilename = _localTmpFileName() try: fout.write(text) fout.close() textlines = text.splitlines() cwd = request.cwd env = self._get_fixed_env(prefset, cwd) rcfilePath = prefset.getStringPref(self.rcfile_prefname) if rcfilePath and os.path.exists(rcfilePath): extraArgs = ['--config=%s' % (rcfilePath, )] else: extraArgs = [] cmd = [pychecker, "--keepgoing", "--only" ] + extraArgs + [tmpfilename] cwd = request.cwd or None # We only need the stdout result. p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None) stdout, stderr = p.communicate() warnLines = stdout.splitlines(0) # Don't need the newlines. errorLines = stderr.splitlines(0) finally: try: os.unlink(tmpfilename) # pychecker leaves .pyc files around, so delete them as well os.unlink(tmpfilename + "c") except: pass # Check raw output for an exception results = koLintResults() re_escaped_filename = re.escape(tmpfilename) exception_ptn = re.compile( '''Caught exception importing module.+?File "%s", line (\d+), in <module>.+?\s*(\w+(?:Error|Exception):\s+.*)''' % re_escaped_filename, re.DOTALL) m = exception_ptn.search(stderr) if m: lineNo = int(m.group(1)) desc = m.group(2) koLintResult.createAddResult(results, textlines, koLintResult.SEV_ERROR, lineNo, desc) warn_ptn = re.compile(r'^%s:(\d+):\s+(.+)' % re_escaped_filename) error_ptn = re.compile(r'(.*[Ee]rror:.*?)\s*\(%s,\s+line\s+(\d+)\)' % re_escaped_filename) for line in warnLines: m = warn_ptn.match(line) if m: lineNo = int(m.group(1)) desc = m.group(2) koLintResult.createAddResult(results, textlines, koLintResult.SEV_WARNING, lineNo, "pychecker: " + desc) for line in errorLines: m = error_ptn.match(line) if m: lineNo = int(m.group(2)) desc = m.group(1) koLintResult.createAddResult(results, textlines, koLintResult.SEV_ERROR, lineNo, "pychecker: " + desc) return results
def lint_with_text(self, request, text): if not text: return None prefset = request.prefset # if not prefset.getBooleanPref("lintPythonWithPep8"): return if not prefset.getBooleanPref(self.lint_prefname): return pythonExe = self._pythonInfo.getExecutableFromPrefs(prefset) if not pythonExe: return cwd = request.cwd fout, tmpfilename = _localTmpFileName() try: tmpBaseName = os.path.splitext(os.path.basename(tmpfilename))[0] fout.write(text) fout.close() textlines = text.splitlines() env = self._get_fixed_env(prefset, cwd) cmd = [pythonExe, '-m', 'pep8'] checkRCFile = False rcfilePath = prefset.getStringPref(self.rcfile_prefname) if rcfilePath and os.path.exists(rcfilePath): extraArgs = [ '--config=%s' % (rcfilePath,) ] checkRCFile = True else: extraArgs = [] # default location: ~/.pep8 homeDir = os.path.expanduser("~") rcfilePath = os.path.join(homeDir, ".pep8") if not os.path.exists(rcfilePath): rcfilePath = os.path.join(homeDir, ".config", "pep8") checkRCFile = os.path.exists(rcfilePath) preferredLineWidth = prefset.getLongPref("editAutoWrapColumn") if preferredLineWidth > 0: usePreferredLineWidth = True if checkRCFile: _disables_E0501_re = re.compile(r'\s*disable\s*=.*?\bE0?501\b') _max_line_length_re = re.compile(r'\s*max-line-length') f = open(rcfilePath, "r") try: for txt in iter(f): if _disables_E0501_re.match(txt) \ or _max_line_length_re.match(txt): usePreferredLineWidth = False break except: log.exception("Problem checking max-line-length") finally: f.close() if usePreferredLineWidth: extraArgs.append("--max-line-length=%d" % preferredLineWidth) cmd += extraArgs cmd.append(tmpfilename) cwd = request.cwd or None # We only need the stdout result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None) stdout, stderr = p.communicate() if stderr.strip(): pathMessageKey = "%s-%s" % (request.koDoc.displayPath, stderr) _complainIfNeeded(pathMessageKey, "Error in pep8: %s", stderr) return warnLines = stdout.splitlines(False) # Don't need the newlines. except: log.exception("Failed to run %s", cmd) stdout = "" warnLines = [] finally: os.unlink(tmpfilename) ptn = re.compile(r'(?P<filename>.*?):(?P<lineNum>\d+):(?P<columnNum>\d+):\s*(?P<status>[EW])(?P<statusCode>\d+)\s+(?P<message>.*)') results = koLintResults() for m in map(ptn.match, warnLines): if m: lineNo = int(m.group("lineNum")) columnNum = int(m.group("columnNum")) desc = "pep8: %s%s %s" % (m.group("status"), m.group("statusCode"), m.group("message")) # Everything pep8 complains about is a warning, by definition severity = koLintResult.SEV_WARNING koLintResult.createAddResult(results, textlines, severity, lineNo, desc, columnStart=columnNum) 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
def lint_with_text(self, request, text): try: prefset = request.prefset linterPrefName = "%sLinterType" % self.cmd scssLinterType = prefset.getStringPref(linterPrefName) if scssLinterType == "none": return if scssLinterType == "builtin": return KoCSSLinter().lint_with_text(request, text) interpreterPrefName = "%sDefaultInterpreter" % self.cmd scssPath = prefset.getStringPref(interpreterPrefName) # The 'or' part handles any language for "Find on Path" if (not scssPath) or not os.path.exists(scssPath): try: scssPath = which.which(self.cmd) except which.WhichError: pass if not scssPath or not os.path.exists(scssPath): log.warn("Setting %sLinterType to 'default': %s not found", self.cmd, self.cmd) prefset.setStringPref(linterPrefName, "builtin") return KoCSSLinter().lint_with_text(request, text) else: prefset.setStringPref(interpreterPrefName, scssPath) rubyPath = prefset.getStringPref("rubyDefaultInterpreter") if (not rubyPath) or not os.path.exists(rubyPath): try: rubyPath = which.which("ruby") except which.WhichError: pass if (not rubyPath) or not os.path.exists(rubyPath): log.warn("Setting %s to 'default': no ruby found to drive %s", linterPrefName, self.cmd) prefset.setStringPref(linterPrefName, "builtin") return KoCSSLinter.lint_with_text(self, request, text) else: prefset.setStringPref("rubyDefaultInterpreter", rubyPath) # Run scss tmpfilename = tempfile.mktemp() + '.' + self.cmd fout = open(tmpfilename, 'wb') fout.write(text) fout.close() textlines = text.splitlines() cmd = [rubyPath, scssPath, "-c", tmpfilename] #koLintResult.insertNiceness(cmd) cwd = request.cwd or None # We only need the stderr result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=koprocessutils.getUserEnv(), stdin=None) stderr = p.communicate()[1] warnLines = stderr.splitlines(0) # Don't need the newlines. except: warnLines = [] finally: os.unlink(tmpfilename) except: log.exception("scss: lint_with_text: big fail") warnLines = [] results = koLintResults() prevLine = "" for line in warnLines: m = self._scss_emsg_ptn.match(line) if m: lineNo = int(m.group(1)) m2 = self._syntaxErrorPtn.match(prevLine) if m2: severity = koLintResult.SEV_ERROR msg = m2.group(1) else: severity = koLintResult.SEV_WARNING msg = prevLine desc = "scss: " + msg koLintResult.createAddResult(results, textlines, severity, lineNo, desc) else: prevLine = line return results