예제 #1
0
        def _mac_get_color_from_process(self,
                                        startingcolor="",
                                        startingalpha="",
                                        callback=None,
                                        originalThread=None):
            koDirSvc = components.classes[
                "@activestate.com/koDirs;1"].getService()
            colorpicker_exe = os.path.join(koDirSvc.supportDir, "colorpicker",
                                           "osx_colorpicker")
            import process
            cmd = [colorpicker_exe]
            if startingcolor:
                # remove hash
                if startingcolor.startswith("#"):
                    startingcolor = startingcolor[1:]
                cmd += ["-startColor", startingcolor]
            p = process.ProcessOpen(cmd,
                                    stdin=None,
                                    stdout=process.PIPE,
                                    stderr=None)
            stdout, stderr = p.communicate()

            newcolor = stdout.strip()
            if newcolor:
                newcolor = "#" + newcolor

            if callback and originalThread:

                def run_callback():
                    callback.handleResult(newcolor, startingalpha)

                originalThread.dispatch(
                    run_callback,
                    components.interfaces.nsIThread.DISPATCH_NORMAL)

            return newcolor
예제 #2
0
    def available_imports(self, buf, trg, ctlr):
        env = buf.env
        go_exe = self.get_go_exe(env)
        if not go_exe:
            raise CodeIntelError("Unable to locate go executable")

        if go_exe not in self._packages_from_exe:
            cmd = [go_exe, 'list', 'std']
            cwd = None
            if buf.path != "<Unsaved>":
                cwd = os.path.dirname(buf.path)
            env_vars = env.get_all_envvars()
            log.debug("running cmd %r", cmd)
            try:
                p = process.ProcessOpen(cmd, cwd=cwd, env=env_vars)
            except OSError, e:
                raise CodeIntelError("Error executing '%s': %s" % (cmd, e))
            output, error = p.communicate()
            if error:
                log.warn("cmd %r error [%s]", cmd, error)
                raise CodeIntelError(error)
            package_names = [x.strip() for x in output.splitlines() if x]
            log.debug("retrieved %d package names", len(package_names))
            self._packages_from_exe[go_exe] = package_names
예제 #3
0
 def getVersionForBinary(self, cvsExe):
     """A CVS version include not only the standard 1.2.3-type numbers
     but also the "build family", of which CVSNT is a different one.
     For example:
         1.11.2 CVS
         1.11.1.3 CVSNT
     Returns None if the version cannot be determined.
     """
     if not os.path.exists(cvsExe):
         raise ServerException(nsError.NS_ERROR_FILE_NOT_FOUND)
     p = process.ProcessOpen([cvsExe, '-v'], stdin=None)
     output, error = p.communicate()
     retval = p.returncode
     
     versionRe = re.compile(r'\((?P<family>.+?)\)\s+(?P<version>[\d\.\w]+?)[\s\-]',
                            re.MULTILINE)
     match = versionRe.search(output)
     if match:
         version = "%s %s" % (match.group('version'),
                              match.group('family'))
         return version
     else:
         log.warn('Could not determine CVS version [%s] "%s"', cvsExe, output)
         return None
예제 #4
0
    def _python_info_from_python(self, python, env):
        """Call the given Python and return:
            (<version>, <sys.prefix>, <lib-dir>, <site-lib-dir>, <sys.path>)

        TODO: Unicode path issues?
        """
        import process
        argv = [python, "-c", self.info_cmd]
        log.debug("run `%s -c ...'", python)
        p = process.ProcessOpen(argv, env=env.get_all_envvars(), stdin=None)
        stdout, stderr = p.communicate()
        stdout_lines = stdout.splitlines(0)
        retval = p.returncode
        if retval:
            log.warn(
                "failed to determine Python info:\n"
                "  path: %s\n"
                "  retval: %s\n"
                "  stdout:\n%s\n"
                "  stderr:\n%s\n", python, retval,
                indent('\n'.join(stdout_lines)), indent(stderr))

        # We are only to rely on the first 2 digits being in the form x.y.
        ver_match = re.search("([0-9]+.[0-9]+)", stdout_lines[0])
        if ver_match:
            ver = ver_match.group(1)
        else:
            ver = None
        prefix = stdout_lines[1]
        if sys.platform == "win32":
            libdir = join(prefix, "Lib")
        else:
            libdir = join(prefix, "lib", "python" + ver)
        sitelibdir = join(libdir, "site-packages")
        sys_path = stdout_lines[2:]
        return ver, prefix, libdir, sitelibdir, sys_path
예제 #5
0
    def _jslint_with_text(self, request, text, prefSwitchName,
                          prefOptionsName):
        if not text:
            #log.debug("<< no text")
            return
        prefset = request.prefset
        if not prefset.getBooleanPref(prefSwitchName):
            return
        jsfilename, isMacro, datalines = self._make_tempfile_from_text(
            request, text)
        jsInterp = self._get_js_interp_path()
        jsLintDir = os.path.join(self.koDirs.supportDir, "lint", "javascript")
        jsLintApp = os.path.join(jsLintDir, "lintWrapper.js")
        jsLintBasename = None
        if prefSwitchName == "lintWithJSLint":
            appName = "jslint"
        else:
            appName = "jshint"
        try:
            customJSLint = prefset.getStringPref(appName + "_linter_chooser")
            if customJSLint == "specific":
                p = prefset.getStringPref(appName + "_linter_specific")
                if p and os.path.exists(p):
                    jsLintDir = os.path.dirname(p) + "/"
                    jsLintBasename = os.path.basename(p)
        except:
            log.exception("Problem finding the custom lintjs file")
        options = prefset.getStringPref(prefOptionsName).strip()
        # Lint the temp file, the jsInterp options are described here:
        # https://developer.mozilla.org/en/Introduction_to_the_JavaScript_shell
        cmd = [jsInterp, jsLintApp, "--include=" + jsLintDir]
        if jsLintBasename:
            if prefSwitchName == "lintWithJSLint":
                cmd.append("--jslint-basename=" + jsLintBasename)
            else:
                cmd.append("--jshint-basename=" + jsLintBasename)
        elif prefSwitchName == "lintWithJSHint":
            cmd.append("--jshint")
        if options:
            # Drop empty parts.
            otherParts = [s for s in re.compile(r'\s+').split(options)]
            cmd += [s for s in re.compile(r'\s+').split(options)]
        if request.koDoc.language == "Node.js":
            if not "node=" in options:
                cmd.append("node=1")
        if (prefSwitchName == "lintWithJSHint"
                and not self.strict_option_re.match(options)
                and 'globalstrict=' not in options):
            # jshint tests options.strict !== false, otherwise strict is on
            # Other options are tested as simply !options.strict
            cmd.append('strict=false')

        fd = open(jsfilename)
        cwd = request.cwd or None
        # We only need the stderr result.
        try:
            p = process.ProcessOpen(cmd,
                                    cwd=cwd,
                                    env=self._setLDLibraryPath(),
                                    stdin=fd)
            stdout, stderr = p.communicate()
            if stderr:
                log.warn("Error in jslint/jshint: stderr: %s, command was: %s",
                         stderr, cmd)
            #log.debug("jslint(%s): stdout: %s, stderr: %s", prefSwitchName, stdout, stderr)
            warnLines = stdout.splitlines()  # Don't need the newlines.
            i = 0
            outputStart = "++++JSLINT OUTPUT:"
            while i < len(warnLines):
                if outputStart in warnLines[i]:
                    warnLines = warnLines[i + 1:]
                    break
                i += 1
        except:
            log.exception("Problem running GenericJSLinter")
        finally:
            try:
                fd.close()
            except:
                log.error("Problem closing file des(%s)", jsfilename)
            try:
                os.unlink(jsfilename)
            except:
                log.error("Problem deleting file des(%s)", jsfilename)

        # 'jslint' error reports come in this form:
        # jslint error: at line \d+ column \d+: explanation
        results = koLintResults()
        msgRe = re.compile(
            "^jslint error: at line (?P<lineNo>\d+) column (?P<columnNo>\d+):\s*(?P<desc>.*?)$"
        )
        numDataLines = len(datalines)
        if len(warnLines) % 2 == 1:
            warnLines.append("")
        for i in range(0, len(warnLines), 2):
            msgLine = warnLines[i]
            evidenceLine = warnLines[i + 1]
            m = msgRe.match(msgLine)
            if m:
                lineNo = int(m.group("lineNo"))
                #columnNo = int(m.group("columnNo"))
                # build lint result object
                result = KoLintResult()
                evidenceLineNo = lineNo
                if evidenceLineNo >= numDataLines:
                    evidenceLineNo = numDataLines - 1
                if evidenceLine in datalines[evidenceLineNo]:
                    lineNo = evidenceLineNo
                    pass
                elif evidenceLineNo > 0 and evidenceLine in datalines[
                        evidenceLineNo - 1]:
                    lineNo = evidenceLineNo - 1
                elif lineNo >= numDataLines:
                    lineNo = numDataLines - 1
                # if the error is on the last line, work back to the last
                # character of the first nonblank line so we can display
                # the error somewhere
                if len(datalines[lineNo]) == 0:
                    while lineNo > 0 and len(datalines[lineNo - 1]) == 0:
                        lineNo -= 1
                result.columnStart = 1
                result.columnEnd = len(datalines[lineNo]) + 1
                result.lineStart = result.lineEnd = lineNo + 1
                result.severity = result.SEV_WARNING
                result.description = m.group("desc")
                results.addResult(result)

        return results
예제 #6
0
    def lint_with_text(self, request, text):
        encoding_name = request.encoding.python_encoding_name
        cwd = request.cwd
        prefset = request.prefset
        prefName = "lint_%s_with_standard_python" % self.language_name_lc
        if not prefset.getBooleanPref(prefName):
            return
        try:
            # Get the Python interpreter (prefs or first valid one on the path).
            interpreter_pref_name = "%sDefaultInterpreter" % (
                self.language_name_lc, )
            python = prefset.getString(interpreter_pref_name)
            if not python:
                python = self._pythonInfo.executablePath
                if not python:
                    return
            if not self._pythonInfo.isSupportedBinary(python):
                raise ServerException(
                    nsError.NS_ERROR_FAILURE,
                    "Invalid %r executable: %r" % (self.language_name, python))
            # Determine the pycompile settings.
            if self.language_name == "Python3":
                compilePy = os.path.join(self._koDirSvc.supportDir, "python",
                                         "py3compile.py")
                if encoding_name not in self._simple_python3_string_encodings:
                    # First, make sure the text is Unicode
                    if type(text) == self._stringType:
                        text = text.decode(encoding_name)
                    # Now save it as utf-8 -- python3 knows how to read utf-8
                    text = text.encode("utf-8")
            else:
                compilePy = os.path.join(self._koDirSvc.supportDir, "python",
                                         "pycompile.py")
            if request.koDoc.displayPath.startswith("macro2://"):
                text = projectUtils.wrapPythonMacro(text)
                leadingWS = _leading_ws_re.match(text.splitlines()[1]).group(1)
            else:
                leadingWS = None

            # Save the current buffer to a temporary file.
            cwd = cwd or None
            # Standard Python syntax-checking files can live in a tmp directory
            # because the checker doesn't attempt to verify or read imported
            # modules.
            fout, tmpFileName = _localTmpFileName()
            fout.write(text)
            fout.close()

            results = koLintResults()
            try:
                argv = [python, '-u', compilePy, tmpFileName]
                #print "---- check syntax of the following with %r" % argv
                #sys.stdout.write(text)
                #print "-"*70

                env = self._get_fixed_env(prefset)
                if sys.platform.startswith("win") and cwd is not None\
                   and cwd.startswith("\\\\"):
                    # Don't try to switch to a UNC path because pycompile.py
                    # ends up spitting out:
                    #     CMD.EXE was started with '\\netshare\apps\Komodo\stuff' as the current directory
                    #     path.  UNC paths are not supported.  Defaulting to Windows directory.
                    # XXX Could perhaps try to ensure that command is not
                    #     run via "cmd.exe /c", but don't know if that would
                    #     help either.
                    cwd = None

                p = process.ProcessOpen(argv, cwd=cwd, env=env, stdin=None)
                output, error = p.communicate()
                retval = p.returncode
                #print "-"*60, "env"
                #pprint(env)
                #print "-"*60, "output"
                #print output
                #print "-"*60, "error"
                #print error
                #print "-"*70
                if retval:
                    errmsg = "Error checking syntax: retval=%s, stderr=%s"\
                             % (retval, error)
                    log.exception(errmsg)
                    raise ServerException(nsError.NS_ERROR_UNEXPECTED, errmsg)
                else:
                    # Parse syntax errors in the output.
                    dicts = eval(output)
                    for d in dicts:
                        results.addResult(self._buildResult(d, leadingWS))
                    # Parse warnings in the error.
                    results.addResults(
                        self._parseWarnings(error, text, leadingWS))
            finally:
                os.unlink(tmpFileName)
        except ServerException:
            log.exception("ServerException")
            raise
        except:
            # non-ServerException's are unexpected internal errors
            log.exception("unexpected internal error")
            raise
        return results
예제 #7
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
예제 #8
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
예제 #9
0
    def lint_with_text(self, request, text):
        """Lint the given PHP content.
        
        Raise an exception if there is a problem.
        """
        cwd = request.cwd
        
        #print "----------------------------"
        #print "PHP Lint"
        #print text
        #print "----------------------------"
        php = self.phpInfoEx.getExecutableFromDocument(request.koDoc)
        if php is None:
            errmsg = "Could not find a suitable PHP interpreter for linting."
            raise COMException(nsError.NS_ERROR_NOT_AVAILABLE, errmsg)

        self.checkValidVersion()

        # save php buffer to a temporary file
        phpfilename = tempfile.mktemp()
        fout = open(phpfilename, 'wb')
        fout.write(text)
        fout.close()

        p = None
        try:
            argv = [php, '-n', '-d', 'display_errors=1',
                    '-d', 'display_startup_errors=1',
                    '-d', 'output_buffering=0',
                    '-d', 'xdebug.remote_enable=off',
                    '-d', 'error_reporting=2047',
                    '-q', '-l', phpfilename]
            env = koprocessutils.getUserEnv()
            cwd = cwd or None
            p = process.ProcessOpen(argv, cwd=cwd, env=env)
            stdout, stderr = p.communicate()
            # The relevant output is contained in stdout.
            lines = stdout.splitlines(1)
        finally:
            os.unlink(phpfilename)
        
        results = koLintResults()
        if lines:
            datalines = re.split('\r\n|\r|\n',text)
            numLines = len(datalines)
            lines = [l for l in lines if l.find('error') != -1]
            
            for line in lines:
                #print line
                line = line.strip()
                # remove html from error output
                line = re.sub('<.*?>',"",line)
                lineText = line.rfind(' ')
                try:
                    lineNo = int(line[lineText+1:])
                except ValueError, e:
                    continue
                #print "Line Number: ", lineNo
                result = KoLintResult()
                # XXX error in FILENAME at line XXX
                # Previous fix (change  done for bug 42553 -- (change 254015)
                # This fix allows for either "at" or "on" between the
                # filename and the line #
                # Sample error message:
                # PHP Fatal error:  Can't use function return value in write context in C:\home\ericp\lab\komodo\bugs\bz42553a.php on line 3
                m = re.match(r'(.*?)\bin .*?(\b(?:on|at)\s+line\s+\d+)', line)
                if m:
                    result.description = string.join(m.groups())
                else:
                    result.description = line
                result.lineStart = result.lineEnd = lineNo
                result.columnStart = 1
                result.columnEnd = len(datalines[result.lineEnd-1]) + 1
                result.severity = result.SEV_ERROR
                results.addResult(result)
예제 #10
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
예제 #11
0
 def test_ProcessOpen_read_all(self):
     p = process.ProcessOpen(['talk'])
     output = p.stdout.read()
     self.failUnless(output == 'o0o1o2o3o4')
     error = p.stderr.read()
     self.failUnless(error == 'e0e1e2e3e4')
예제 #12
0
    def lint_with_text(self, request, text):
        if not request.prefset.getBoolean("lint_eslint_enabled", False):
            log.debug("EsLint: not enabled")
            return

        is_project = False
        cwd = None
        cmd = []
        config = None

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

        # priority:
        # 1 - node_modules's eslint
        # 2 - eslint binary set by user [fallback]
        # 3 - eslint binary found on $PATH [fallback]
        if "win" in sys.platform:
            eslint = os.path.join(cwd, 'node_modules/.bin/eslint.cmd')
        else:
            eslint = os.path.join(cwd, 'node_modules/.bin/eslint')
        if not os.path.exists(eslint):
            log.debug("EsLint: {} does not exist".format(eslint))
            eslint = request.prefset.getString('eslint_binary', '')
            if not os.path.exists(eslint):
                log.debug("EsLint: eslint executable is not set/not found")
                try:
                    eslint = which.which('eslint')
                    log.debug("EsLint: eslint executable found on $PATH")
                except which.WhichError:
                    log.debug(
                        "EsLint: eslint executable is not found on $PATH")
                    return
            else:
                log.debug("EsLint: eslint executable is set by the user")

        if cwd is not None:
            # priority:
            # 1 - user config in the cwd
            # 2 - user config set by user [fallback]
            for file_format in ['js', 'yml', 'json']:
                config = os.path.join(cwd, '.eslintrc.{}'.format(file_format))
                log.debug(config)
                if os.path.exists(config):
                    break
            if not os.path.exists(config):
                config = request.prefset.getString('eslint_config', '')
        else:
            log.debug("EsLint: cwd is empty")
            return
        if config and os.path.isfile(config):
            cmd = [
                eslint, '--no-color', '--format', 'json', '--config', config
            ]
        else:
            log.info("EsLint: .eslintrc is not found")
            return

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

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

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

        results = koLintResults()
        try:
            log.debug("EsLint: stdout = %s" % stdout)
            log.debug("EsLint: stderr = %s" % stderr)
            data = json.loads(stdout)[0]['messages']
        except Exception, e:
            log.warn('Failed to parse the eslint output!')
            log.warn('The output was: {}'.format(stdout))
            return
예제 #13
0
    def lint_with_text(self, request, text):
        """Lint the given Tcl content.
        
        Raise an exception if there is a problem.
        """
        if gHaveGetProxiedEffectivePrefs:
            prefset = getProxiedEffectivePrefs(request)
        else:
            # Komodo 8 sets the prefet on the request.
            prefset = request.prefset
        argv = self._getLinterArgv(prefset)
        env = koprocessutils.getUserEnv()

        # if there is no setting for the dev kit environment, use
        # the shared directory for it.  This enables site wide
        # use of *.pdx and *.pcx files for debugging

        if "TCLDEVKIT_LOCAL" not in env:
            koDirs = components.classes["@activestate.com/koDirs;1"].\
                getService(components.interfaces.koIDirs)
            sharedDir = os.path.join(koDirs.commonDataDir, "tcl")
            env["TCLDEVKIT_LOCAL"] = sharedDir

        if prefset.hasPref("tclExtraPaths"):
            tclExtraPaths = prefset.getStringPref("tclExtraPaths")
            # If TCLLIBPATH is set, then it must contain a valid Tcl
            # list giving directories to search during auto-load
            # operations. Directories must be specified in Tcl format,
            # using "/" as the path separator, regardless of platform.
            # This variable is only used when initializing the
            # auto_path variable.  Also escape spaces in paths.
            tclExtraPaths = tclExtraPaths.replace('\\', '/')
            tclExtraPaths = tclExtraPaths.replace(' ', '\ ')
            TCLLIBPATH = ' '.join(tclExtraPaths.split(os.pathsep))
            env["TCLLIBPATH"] = TCLLIBPATH

        cwd = request.cwd or None
        print 'argv: %r' % (argv, )
        p = process.ProcessOpen(argv, cwd=cwd, env=env)
        lOutput, lErrOut = p.communicate(text)
        lOutput = lOutput.splitlines(1)
        #print '======'
        #print lOutput
        #print '======'
        #print lErrOut
        #print '<<<<<<'

        if not lOutput and lErrOut:
            raise ServerException(nsError.NS_ERROR_UNEXPECTED, lErrOut)
        
        if not lOutput:
            # this should never happen unless the tcl linter is broken, or
            # not executable on linux.
            raise ServerException(nsError.NS_ERROR_UNEXPECTED,
                                  "No output from Tcl linter available")
        
        if lOutput[0].startswith("TclPro") or \
           lOutput[0].startswith("scanning"):
            # The open source TclPro has the header stripped,
            # so we need to check for both "TclPro" and "scanning"
            lInput = text.split('\n')
            return self._TclPro_lint(lInput, lOutput)
        else:
            errmsg = "unrecognized lint output format:\n%s" % lOutput[0]
            raise ServerException(nsError.NS_ERROR_UNEXPECTED, errmsg)
예제 #14
0
        if sys.platform.startswith("win"):
            path = buf.path.replace('\\', '/')
        else:
            path = buf.path

        try:
            gooutline_exe_path = self.compile_gooutline(buf)
        except Exception, e:
            log.error("Error compiling outline: %s", e)
            raise

        cmd = [gooutline_exe_path, buf.path]
        env = buf.env.get_all_envvars()
        log.debug("running [%s]", cmd)
        try:
            p = process.ProcessOpen(cmd, env=env)
        except OSError, e:
            log.error("Error executing '%s': %s", cmd, e)
            return

        output, error = p.communicate()
        if error:
            log.warn("'%s' stderr: [%s]", cmd[0], error)

        xml = '<codeintel version="2.0">\n' + output + '</codeintel>'
        return tree_from_cix(xml)


#---- registration

예제 #15
0
 def test_ProcessOpen_minus_42(self):
     p = process.ProcessOpen(['quiet', '-42'])
     retval = p.wait()
     self._assertRetvalIs(-42, retval)
                         "ActionScript content: %s" % ex
                self._lastErrorSvc.setLastError(3, errmsg)
                raise ServerException(nsError.NS_ERROR_UNEXPECTED)
            fout = open(tmpFileName, 'wb')
            fout.write(text)
            fout.close()

        try:
            argv = [ascExe, "-strict"]
            # mtasc gets confused by pathnames
            mtasc_filename = os.path.basename(tmpFileName)
            argv += [mtasc_filename]
            cwd = cwd or None  # convert '' to None (cwd=='' for new files)
            log.debug("Run cmd %s in dir %s", " ".join(argv), cwd)
            env = koprocessutils.getUserEnv()
            p = process.ProcessOpen(argv, cwd=cwd, env=env)
            results = p.stderr.readlines()
            log.debug("results: %s", "\n".join(results))
            p.close()
            status = None
            try:
                raw_status = p.wait(timeout=3.0)
                if sys.platform.startswith("win"):
                    status = raw_status
                else:
                    status = raw_status >> 8

                lintResults = ActionScriptWarnsToLintResults(
                    results, mtasc_filename, text, status)
            except process.ProcessError:
                # Don't do anything with this exception right now.
예제 #17
0
    def lint_with_text(self, request, text):
        jsfilename, isMacro, datalines = self._make_tempfile_from_text(request, text)
        cwd = request.cwd
        jsInterp = self._get_js_interp_path()

        # Lint the temp file, the jsInterp options are described here:
        # https://developer.mozilla.org/en/Introduction_to_the_JavaScript_shell
        cmd = [jsInterp, "-C"]

        # Set the JS linting preferences.
        prefset = getProxiedEffectivePrefsByName(request, 'lintJavaScriptEnableWarnings')
        if not prefset.getBooleanPref("lintJavaScript_SpiderMonkey"):
            return
        enableWarnings = prefset.getBooleanPref('lintJavaScriptEnableWarnings')
        if enableWarnings:
            cmd.append("-w")
            enableStrict = prefset.getBooleanPref('lintJavaScriptEnableStrict')
            if enableStrict:
                cmd.append("-s")
        else:
            cmd.append("-W")

        cmd.append(jsfilename)
        cwd = cwd or None
        # We only need the stderr result.
        try:
            p = process.ProcessOpen(cmd, cwd=cwd, stdin=None)
            stdout, stderr = p.communicate()
            warnLines = stderr.splitlines(0) # Don't need the newlines.
        finally:
            os.unlink(jsfilename)
        
        # 'js' error reports come in 4 line chunks that look like
        # this:
        #    <filename>:8: SyntaxError: missing ; before statement:
        #    <filename>:8: ar asdf = 1;
        #
        #    <filename>:8: ...^
        #    <filename>:8: strict warning: function does not always return value:
        #    <filename>:8: strict warning:     },
        #
        #    <filename>:8: strict warning: ...^
        # There is one exception: if the file is only one line then
        # the third blank line is not there. THerefore we will strip
        # empty lines and parse 3 line chunks.
        strippedWarnLines = [line for line in warnLines if line.strip()]

        # Parse out the xpcshell lint results
        results = koLintResults()
        counter = 0  # count index in 3 line groups
        firstLineRe = re.compile("^%s:(?P<lineNo>\d+):\s*(?P<type>.*?):(?P<desc>.*?)\s*$" %\
            re.escape(jsfilename))
        lastLineRe = re.compile("^%s:(?P<lineNo>\d+):\s*(?P<dots>.*?)\^\s*$" %\
            re.escape(jsfilename))
        strictLineRe = re.compile("^%s:(?P<lineNo>\d+):\s*(?P<type>.*?):\s*(?P<dots>.*?)\^\s*$" %\
            re.escape(jsfilename))
        desc = numDots = None
        for line in strippedWarnLines:
            if counter == 0 and line.startswith(jsfilename):
                # first line: get the error description and line number
                firstLineMatch = firstLineRe.search(line.strip())
                if firstLineMatch:
                    lineNo = int(firstLineMatch.group("lineNo"))
                    if isMacro:
                        if lineNo > len(datalines) + 1:
                            lineNo = len(datalines)
                        else:
                            lineNo -= 1
                    errorType = firstLineMatch.group("type")
                    desc = firstLineMatch.group("desc")
                else:
                    # continue on this, it's likely just debug build output
                    msg = "Unexpected output when parsing JS syntax check "\
                        "output: '%s'\n" % line
                    log.debug(msg)
                    continue
            elif counter == 2:
                if not desc:
                    # if we don't have it, there is debug build lines
                    # that have messed us up, restart at zero
                    counter = 0
                    continue
                # get the column of the error
                lastLineMatch = lastLineRe.search(line.strip())
                if not lastLineMatch:
                    lastLineMatch = strictLineRe.search(line.strip())
                    
                if lastLineMatch:
                    numDots = len(lastLineMatch.group("dots"))
                else:
                    # continue on this, it's likely just debug build output
                    msg = "Unexpected output when parsing JS syntax check "\
                          "output: '%s'\n" % line
                    log.debug(msg)
                    continue
                self._createAddResult(results, datalines, errorType, lineNo, desc, numDots)
                desc = numDots = None
            counter = (counter + 1) % 3

        if desc is not None:
            self._createAddResult(results, datalines, errorType, lineNo, desc, numDots)
        return results
예제 #18
0
 def test_ProcessOpen_readline(self):
     p = process.ProcessOpen('hello10')
     for i in range(10):
         output = p.stdout.readline()
         self.failUnless(output == "hello\n")
예제 #19
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
예제 #20
0
 def test_ProcessOpen_readlines(self):
     p = process.ProcessOpen('hello10')
     output = p.stdout.readlines()
     self.failUnless(output == ["hello\n"] * 10)
예제 #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
예제 #22
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
예제 #23
0
    def lint_with_text(self, request, text):
        if not text:
            return None
        prefset = request.prefset
        if not prefset.getBooleanPref(self.lint_prefname):
            return
        pythonExe = self._pythonInfo.getExecutableFromPrefs(prefset)
        if not pythonExe:
            return
        try:
            checkerExe = which.which("pyflakes", path=_getUserPath())
        except which.WhichError:
            checkerExe = None
        if not checkerExe:
            log.warn("pyflakes not found")
            return
        fout, tmpfilename = _localTmpFileName()
        try:
            fout.write(text)
            fout.close()
            textlines = text.splitlines()
            cwd = request.cwd

            # For the env, don't add a PYTHONPATH entry for cwd, as it can break
            # module import lookups for pyflakes. E.g.
            #  foo/
            #    __init__.py  - an "from foo import bar" in this file will break
            env = self._get_fixed_env(prefset, cwd=None)

            cmd = [pythonExe, checkerExe, tmpfilename]
            # stdout for pyflakes.checker.Checker
            # stderr for __builtin__.compile()
            p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None)
            stdout, stderr = p.communicate()
            warnLines = []
            errorLines = []
            if p.returncode and stderr and not stdout:
                m = re.match(
                    "^(.*?):(\d+):(\d+): (invalid syntax|unexpected indent)",
                    stderr)
                if m is None:
                    _complainIfNeeded(stderr,
                                      "Error running pyflakes on file %r\n%s",
                                      request.koDoc.displayPath, stderr)
                # It's a syntax error - convert it.
                error = "%s:%s: invalid syntax (at column %s)" % (
                    m.group(1), m.group(2), m.group(3))
                errorLines = [error]
            else:
                warnLines = stdout.splitlines()
                errorLines = stderr.splitlines(0)  # Don't need the newlines.
        finally:
            os.unlink(tmpfilename)
        results = koLintResults()

        # "createAddResult" will change lineno in some situation, so we use our version
        self._createAddResult(results, textlines, errorLines,
                              koLintResult.SEV_ERROR)
        self._createAddResult(results, textlines, warnLines,
                              koLintResult.SEV_WARNING)
        return results
예제 #24
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
예제 #25
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
예제 #26
0
    def lint_with_text(self, request, text):
        """Lint the given C/C++ file.
        
        Raise an exception and set an error on koLastErrorService if there
        is a problem.
        """

        cwd = request.cwd

        #print "----------------------------"
        #print "C++ Lint"
        #print text
        #print "----------------------------"
        cc = self.appInfoEx.executablePath
        if cc is None:
            raise Exception(
                "Could not find a suitable C/C++ interpreter for linting.")

        if request.koDoc.file:
            ext = request.koDoc.file.ext
        else:
            ext = koCPPLanguage.defaultExtension

        # save buffer to a temporary file
        try:
            filename = tempfile.mktemp(suffix=ext)
            fout = open(filename, 'wb')
            fout.write(text)
            fout.close()
        except ex:
            raise Exception(
                "Unable to save temporary file for C/C++ linting: %s", str(ex))

        if cc.startswith('cl') or cc.lower().endswith("\\cl.exe"):
            argv = [cc, '-c']
            isGCC = False
            # ms cl errors
            re_string = r'(?P<file>.+)?\((?P<line>\d+)\)\s:\s(?:(?P<type>.+)?\s(?P<number>C\d+)):\s(?P<message>.*)'
        else:  # gcc or cc
            argv = [cc, '-c']
            isGCC = True
            # gcc errors
            re_string = r'(?P<file>[^:]+)?:(?P<line>\d+?)(?::(?P<column>\d+))?:\s(?P<type>.+)?:\s(?P<message>.*)'

        argv += [filename]
        _re = re.compile(re_string)
        p = None
        #print argv
        try:
            env = koprocessutils.getUserEnv()
            cwd = cwd or None
            # XXX gcc hangs if we read stdout, so we don't pipe stdout,
            # need to test this again since using subprocess and also
            # test this with msvc.
            p = process.ProcessOpen(argv, cwd=cwd, env=env, stdin=None)
            stdout, stderr = p.communicate()
            if isGCC:
                lineSource = stderr
            else:
                lineSource = stdout
            lines = lineSource.splitlines(1)
            #print lines
        finally:
            pass  #os.unlink(filename)

        try:
            results = koLintResults()
            if lines:
                datalines = re.split('\r\n|\r|\n', text)
                numLines = len(datalines)
                result = None
                for line in lines:
                    #print line
                    if result and line[0] == ' ':
                        result.description += '\n' + line
                        continue

                    g = _re.match(line)
                    if not g:
                        continue
                    err = g.groupdict()
                    #print repr(err)
                    result = KoLintResult()
                    # XXX error in FILENAME at line XXX
                    result.lineStart = result.lineEnd = int(err['line'])
                    result.columnStart = 1
                    result.columnEnd = len(datalines[result.lineEnd - 1]) + 1
                    if 'error' in err['type']:
                        result.severity = result.SEV_ERROR
                    elif 'warn' in err['type']:
                        result.severity = result.SEV_WARNING
                    else:
                        result.severity = result.SEV_ERROR

                    if 'number' in err:
                        result.description = "%s %s: %s" % (
                            err['type'], err['number'], err['message'])
                    else:
                        result.description = "%s: %s" % (err['type'],
                                                         err['message'])
                    results.addResult(result)
        except:
            errmsg = "Exception in C/C++ linting while parsing results"
            self._lastErrorSvc.setLastError(1, errmsg)
            log.exception(errmsg)
        #print "----------------------------"
        return results
예제 #27
0
    def lint_with_text(self, request, text):
        encoding_name = request.encoding.python_encoding_name
        if encoding_name not in ("ascii", "utf-8"):
            try:
                # Spidermonkey will choke on latin1 file input - bug 105635 - so try
                # and use UTF-8, else fall back to the original encoding.
                utext = text.decode(request.encoding.python_encoding_name)
                text = utext.encode("utf-8")
            except UnicodeError:
                pass  # Just go with the original text then.
        jsfilename, isMacro, datalines = self._make_tempfile_from_text(
            request, text)
        cwd = request.cwd
        jsInterp = self._get_js_interp_path()

        # Lint the temp file, the jsInterp options are described here:
        # https://developer.mozilla.org/en/Introduction_to_the_JavaScript_shell
        cmd = [jsInterp, "-c"]

        # Set the JS linting preferences.
        prefset = request.prefset
        if not prefset.getBooleanPref("lintJavaScript_SpiderMonkey"):
            return
        enableWarnings = prefset.getBooleanPref('lintJavaScriptEnableWarnings')
        if enableWarnings:
            cmd.append("-w")
            enableStrict = prefset.getBooleanPref('lintJavaScriptEnableStrict')
            if enableStrict:
                cmd.append("-s")
        else:
            cmd.append("-W")

        cmd.append(jsfilename)
        cwd = cwd or None
        # We only need the stderr result.
        try:
            p = process.ProcessOpen(cmd,
                                    cwd=cwd,
                                    env=self._setLDLibraryPath(),
                                    stdin=None)
            stdout, stderr = p.communicate()
            warnLines = stderr.splitlines(0)  # Don't need the newlines.
        except:
            log.exception("Problem running CommonJSLinter")
            warnLines = []
        finally:
            os.unlink(jsfilename)

        # 'js' error reports come in 4 line chunks that look like
        # this:
        #    <filename>:8: SyntaxError: missing ; before statement:
        #    <filename>:8: ar asdf = 1;
        #
        #    <filename>:8: ...^
        #    <filename>:8: strict warning: function does not always return value:
        #    <filename>:8: strict warning:     },
        #
        #    <filename>:8: strict warning: ...^
        # There is one exception: if the file is only one line then
        # the third blank line is not there. THerefore we will strip
        # empty lines and parse 3 line chunks.
        strippedWarnLines = [line for line in warnLines if line.strip()]

        # Parse out the xpcshell lint results
        results = koLintResults()
        state = _JS_STATE_EXP_MESSAGE  # count index in 3 line groups
        # Mozilla 8 lines have a "0" after the line # -- ignore it
        headerPartRe = re.compile(r"^%s:(?P<lineNo>\d+):\d*\s*(?P<rest>.*)$" %
                                  re.escape(jsfilename))

        lineNo = desc = numDots = None
        # Implement this state machine:
        # Start => <starts with filename>
        # Message, ends with desc =>
        # Code, echoes code, not interesting =>
        # Num Dots, shows where on line error starts => Start
        i = -1
        limSub1 = len(strippedWarnLines) - 1
        while i < limSub1:
            i += 1
            line = strippedWarnLines[i]
            if not line:
                continue
            headerMatch = headerPartRe.match(line)
            if not headerMatch:
                if state == _JS_STATE_EXP_CODE:
                    desc += " " + line
                continue
            restLine = headerMatch.group("rest").strip()
            thisLineNo = int(headerMatch.group("lineNo"))
            if state == _JS_STATE_EXP_MESSAGE:
                # first line: get the error description and line number
                firstLineMatch = self._firstLineRe.match(restLine)
                if firstLineMatch:
                    lineNo = thisLineNo
                    if isMacro:
                        if lineNo > len(datalines) + 1:
                            lineNo = len(datalines)
                        else:
                            lineNo -= 1
                    errorType = firstLineMatch.group("type")
                    desc = firstLineMatch.group("desc")
                    state = _JS_STATE_EXP_CODE
                else:
                    # continue on this, it's likely just debug build output
                    msg = "Unexpected output when parsing JS syntax check(1) "\
                        "output: '%s'\n" % line
                    log.debug(msg)
                    state = _JS_STATE_EXP_MESSAGE
                continue

            if lineNo != thisLineNo:
                # This is actually the start of a new message, so log the current one,
                # and start fresh
                self._createAddResult(results, datalines, errorType, lineNo,
                                      desc, 0)
                state = _JS_STATE_EXP_MESSAGE
                desc = None
                i -= 1  # Redo this line
            elif state == _JS_STATE_EXP_CODE:
                # We don't care about this line
                state = _JS_STATE_EXP_DOTS
                continue

            # Now we should be looking at dots
            assert state == _JS_STATE_EXP_DOTS
            lastLineMatch = self._lastLineRe.search(restLine)
            if not lastLineMatch:
                lastLineMatch = self._strictLineRe.search(restLine)
                if not lastLineMatch:
                    # continue on this, it's likely just debug build output
                    msg = "Unexpected output when parsing JS syntax check(2) "\
                          "output: '%s'\n" % line
                    log.debug(msg)
                    continue
            if not desc:
                # if we don't have it, there are debug build lines
                # that have messed us up, restart at zero
                counter = _JS_STATE_EXP_MESSAGE
                continue
            # get the column of the error
            numDots = len(lastLineMatch.group("dots"))
            self._createAddResult(results, datalines, errorType, lineNo, desc,
                                  numDots)
            state = _JS_STATE_EXP_MESSAGE
            desc = None

        if desc is not None:
            self._createAddResult(results, datalines, errorType, lineNo, desc,
                                  0)
        return results
예제 #28
0
    def lint_with_text(self, request, text):
        cwd = request.cwd
        prefset = request.prefset
        # Remove a possible "-d" in the shebang line, this will tell Perl to
        # launch the debugger which, if the PDK is installed, is the PDK
        # debugger.  Be careful to handle single-line files correctly.
        splitText = text.split("\n", 1)
        firstLine = RemoveDashDFromShebangLine(splitText[0])
        if len(splitText) > 1:
            text = "\n".join([firstLine, splitText[1]])
        else:
            text = firstLine
        if prefset.getBooleanPref("perl_lintOption_disableBeginBlocks"):
            if len(text) > _init_matcher_cutoff:
                # Use a faster pattern when we have lots of text.
                text = _begin_to_init_faster_re.sub("INIT", text)
            else:
                text = _begin_to_init_re.sub("INIT", text)
        # Save perl buffer to a temporary file.

        tmpFileName = self._writeTempFile(cwd, text)
        try:
            perlExe = self._selectPerlExe(prefset)
            lintOptions = prefset.getStringPref("perl_lintOption")
            option = '-' + lintOptions
            perlExtraPaths = prefset.getStringPref("perlExtraPaths")
            if perlExtraPaths:
                if sys.platform.startswith("win"):
                    perlExtraPaths = perlExtraPaths.replace('\\', '/')
                perlExtraPaths = [
                    x for x in perlExtraPaths.split(os.pathsep) if x.strip()
                ]
            argv = [perlExe]
            for incpath in perlExtraPaths:
                argv += ['-I', incpath]
            if prefset.getBooleanPref(
                    "perl_lintOption_includeCurrentDirForLinter"):
                argv += ['-I', '.']

            # bug 27963: Fix instances of <<use PerlTray>> from code
            # to make them innocuous for the syntax checker.
            # 'use PerlTray' in comments or strings will trigger a false positive
            if sys.platform.startswith(
                    "win") and self._use_perltray_module.search(text):
                argv += ['-I', self._perlTrayDir]

            argv.append(option)
            argv.append(tmpFileName)
            cwd = cwd or None  # convert '' to None (cwd=='' for new files)
            env = koprocessutils.getUserEnv()
            # We only need stderr output.

            p = process.ProcessOpen(argv, cwd=cwd, env=env, stdin=None)
            _, stderr = p.communicate()
            lintResults = PerlWarnsToLintResults(stderr.splitlines(1),
                                                 tmpFileName,
                                                 request.koDoc.displayPath,
                                                 text)
        finally:
            os.unlink(tmpFileName)

        return lintResults
    def lint_with_text(self, request, text):
        if not text.strip():
            return None
        cwd = request.cwd
        env = koprocessutils.getUserEnv()
        settingsDir = env.get("DJANGO_SETTINGS_MODULE", None)
        if not settingsDir:
            settingsDir = self._getSettingsDir(cwd)
        if settingsDir:
            # Save the current buffer to a temporary file.
            tmpFileName = tempfile.mktemp()
            fout = open(tmpFileName, 'wb')
            try:
                fout.write(text)
                fout.close()

                #XXX: How to tell whether we're using Python or Python3?
                prefName = "pythonExtraPaths"
                pythonPath =  request.prefset.getString(prefName, "")
                pythonPathEnv = env.get("PYTHONPATH", "")
                if pythonPathEnv:
                    if pythonPath:
                        pythonPath += os.pathsep + pythonPathEnv
                    else:
                        pythonPath = pythonPathEnv
                if pythonPath:
                    if sys.platform.startswith("win"):
                        pythonPath = pythonPath.replace('\\', '/')
                    env["PYTHONPATH"] = pythonPath
                elif env.has_key("PYTHONPATH"):
                    del env["PYTHONPATH"]

                # First try to use Python2 to run the django linter. If django
                # is not found, use Python3 instead.
                results = koLintResults()
                pythonExe = self._pythonInfo.getExecutableFromDocument(request.koDoc)
                djangoLinterPath = self._djangoLinterPath
                if pythonExe:
                    p = process.ProcessOpen([pythonExe, "-c", "import django"], env=env, stdin=None)
                    output, error = p.communicate()
                    #log.debug("Django output: output:[%s], error:[%s]", output, error)
                    if error.find('ImportError:') >= 0 and \
                       self._python3Info.getExecutableFromDocument(request.koDoc):
                        pythonExe = self._python3Info.getExecutableFromDocument(request.koDoc)
                        djangoLinterPath = self._djangoLinter3Path
                else:
                    pythonExe = self._python3Info.getExecutableFromDocument(request.koDoc)
                    djangoLinterPath = self._djangoLinter3Path
                #log.debug("pythonExe = " + pythonExe)
                #log.debug("djangoLinterPath = " + djangoLinterPath)
                argv = [pythonExe, djangoLinterPath,
                        tmpFileName, settingsDir]
                p = process.ProcessOpen(argv, cwd=cwd, env=env, stdin=None)
                output, error = p.communicate()
                retval = p.returncode
                #log.debug("Django output: output:[%s], error:[%s], retval:%d", output, error)
            finally:
                os.unlink(tmpFileName)
            if error:
                results.addResult(self._buildResult(text, error))
            elif retval != 0:
                results.addResult(self._buildResult(text, "Unexpected error"))
        else:
            result = KoLintResult()
            result.lineStart = 1
            result.lineEnd = 1
            result.columnStart = 1
            result.columnEnd = 1 + len(text.splitlines(1)[0])
            result.description = "Can't find settings.py for this Django file"
            result.encodedDescription = result.description
            result.severity = result.SEV_ERROR
            results = koLintResults()
            results.addResult(result)
        return results
예제 #30
0
    def lint_with_text(self, request, text):
        prefset = request.prefset
        criticLevel = prefset.getStringPref('perl_lintOption_perlCriticLevel')
        if criticLevel == 'off':
            return

        if not self.isPerlCriticInstalled(False):
            # This check is necessary in case Perl::Critic and/or criticism were uninstalled
            # between Komodo sessions.  appInfoEx.isPerlCriticInstalled caches the state
            # until the pref is changed.
            return

        # Bug 82713: Since linting isn't done on the actual file, but a copy,
        # Perl-Critic will complain about legitimate package declarations.
        # Find them, and append an annotation to turn the Perl-Critic feature off.
        # This will also tag comments, strings, and POD, but that won't affect
        # lint results.
        # This is no longer needed with Perl-Critic 1.5, which
        # goes by the filename given in any #line directives
        perlCriticVersion = self.getPerlCriticVersion()
        currFile = request.koDoc.file
        baseFileName = None
        if currFile:
            baseFileName = currFile.baseName[0:-len(currFile.ext)]
            if perlCriticVersion < 1.500:
                munger = re.compile(
                    r'''^\s*(?P<package1>package \s+ (?:[\w\d_]+::)*) 
                                         (?P<baseFileName>%s)
                                         (?P<space1>\s*;)
                                         (?P<space2>\s*)
                                         (?P<rest>(?:\#.*)?)$''' %
                    (baseFileName, ), re.MULTILINE | re.VERBOSE)
                text = munger.sub(self._insertPerlCriticFilenameMatchInhibitor,
                                  text)
        elif perlCriticVersion >= 1.500 and currFile:
            text = "#line 1 " + currFile.baseName + "\n" + text

        cwd = request.cwd or None  # convert '' to None (cwd=='' for new files)
        tmpFileName = self._writeTempFile(cwd, text)
        try:
            perlExe = self._selectPerlExe(prefset)
            lintOptions = prefset.getStringPref("perl_lintOption")
            option = '-' + lintOptions
            if perlCriticVersion <= 1.100 or not baseFileName:
                pcOption = '-Mcriticism=' + criticLevel
            else:
                settings = {
                    '-severity': criticLevel,
                    'as-filename': baseFileName
                }
                perlcritic_checking_rcfile = prefset.getStringPref(
                    "perlcritic_checking_rcfile")
                if perlcritic_checking_rcfile and os.path.exists(
                        perlcritic_checking_rcfile):
                    settings['-profile'] = perlcritic_checking_rcfile
                pcOption = "-Mcriticism (" + ", ".join([
                    "'%s' => '%s'" % (key, value)
                    for key, value in settings.items()
                ]) + ")"
            perlExtraPaths = prefset.getStringPref("perlExtraPaths")
            if perlExtraPaths:
                if sys.platform.startswith("win"):
                    perlExtraPaths = perlExtraPaths.replace('\\', '/')
                perlExtraPaths = [
                    x for x in perlExtraPaths.split(os.pathsep) if x.strip()
                ]
            argv = [perlExe]
            for incpath in perlExtraPaths:
                argv += ['-I', incpath]
            if 'T' in lintOptions and prefset.getBooleanPref(
                    "perl_lintOption_includeCurrentDirForLinter"):
                argv += ['-I', '.']

            # bug 27963: Fix instances of <<use PerlTray>> from code
            # to make them innocuous for the syntax checker.
            # 'use PerlTray' in comments or strings will trigger a false positive
            if sys.platform.startswith(
                    "win") and self._use_perltray_module.search(text):
                argv += ['-I', self._perlTrayDir]

            argv.append(option)
            argv.append(pcOption)
            argv.append(tmpFileName)
            env = koprocessutils.getUserEnv()
            # We only need stderr output.

            p = process.ProcessOpen(argv, cwd=cwd, env=env, stdin=None)
            _, stderr = p.communicate()
            lintResults = PerlWarnsToLintResults(stderr.splitlines(1),
                                                 tmpFileName,
                                                 request.koDoc.displayPath,
                                                 text)
        finally:
            os.unlink(tmpFileName)

        return lintResults