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