Example #1
0
    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
Example #2
0
    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
Example #3
0
 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
Example #4
0
 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
Example #5
0
 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
Example #6
0
 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
Example #8
0
 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
Example #9
0
 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
Example #10
0
    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
Example #11
0
    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
Example #12
0
    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
Example #13
0
 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
Example #14
0
 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
Example #15
0
    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
Example #16
0
    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
Example #17
0
    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
Example #18
0
 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
Example #19
0
    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
Example #20
0
    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
Example #21
0
 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
Example #22
0
    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
Example #23
0
 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
Example #25
0
 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