def _spawn(self, command): """Spawn the given command (or argv) and return true iff successful""" try: env = koprocessutils.getUserEnv() except ServerException, ex: log.error(str(ex)) return 1
def __init__(self): # The specific installation path for which the other attributes # apply to. It may be required for this to be set for certain # attributes to be determined. # attribute wstring installationPath; self.installationPath = '' # The path to the executable for the interpreter e.g. "usr/bin/perl" # attribute wstring executablePath; self.executablePath = '' self._executables = [] # True if user is licensed for the current version of this app. # (For an app that does not require a license this will always be # true.) # attribute boolean haveLicense; self.haveLicense = 1 # The build number. (May be null if it is not applicable.) # attribute long buildNumber; self.buildNumber = 0 # version (duh, null if don't know how to determine) # attribute string version; version = '' # path to local help file (null if none) # attribute wstring localHelpFile; self.localHelpFile = '' # Web URL to main help file (null if none) # attribute wstring webHelpURL; self.webHelpURL = '' self._userPath = koprocessutils.getUserEnv()["PATH"].split(os.pathsep)
def runGenericLinter(text, extension, cmd_start, err_ptns, warn_ptns, cwd, useStderr): tmpfilename = tempfile.mktemp() + extension fout = open(tmpfilename, "wb") fout.write(text) fout.close() cmd = cmd_start + [tmpfilename] try: p = process.ProcessOpen(cmd, cwd=cwd, env=koprocessutils.getUserEnv(), stdin=None) stdout, stderr = p.communicate() if useStderr: errLines = stderr.splitlines(0) # Don't need the newlines. else: errLines = stdout.splitlines(0) # Don't need the newlines. textLines = None except: log.exception("Failed to run %s, cwd %r", cmd, cwd) return None finally: os.unlink(tmpfilename) results = koLintResults() all_ptns = zip(err_ptns, [SEV_ERROR] * len(err_ptns)) + zip(warn_ptns, [SEV_WARNING] * len(warn_ptns)) for line in errLines: for ptn, sev in all_ptns: m = ptn.match(line) if m: if textLines is None: textLines = text.splitlines() m1 = _leading_ws_ptn.match(line) createAddResult(results, textLines, sev, m.group(1), m.group(2), m1 and m1.group(1) or None) break return results
def lint_with_text(self, request, text): log.info(request) logging.shit = [request, text] if not self.go_compiler: return if not text.strip(): return None # consider adding lint preferences? maybe for compiler selection, paths, etc? # Save the current buffer to a temporary file. handle, tempfile_name = tempfile.mkstemp(suffix='.go', prefix='~', dir=request.cwd) fout = open(tempfile_name, 'wb') short_tempfile_name = os.path.basename(tempfile_name) try: fout.write(text) fout.close() env = koprocessutils.getUserEnv() results = koLintResults() p = process.ProcessOpen([self.go_compiler, 'build', short_tempfile_name], cwd=request.cwd, env=env, stdin=None) output, error = p.communicate() log.debug("%s output: output:[%s], error:[%s]", self.go_compiler, output, error) retval = p.returncode finally: os.unlink(tempfile_name) if retval != 0: if output: for line in output.splitlines()[1:]: results.addResult(self._buildResult(text, line, tempfile_name)) else: results.addResult(self._buildResult(text, "Unexpected error")) return results
def getVersionForBinary(self, pythonExe): """Get the $major.$minor version (as a string) of the current Python executable. Returns the empty string if cannot determine version. Dev Notes: - Specify cwd to avoid accidentally running in a dir with a conflicting Python DLL. """ if not os.path.exists(pythonExe): raise ServerException(nsError.NS_ERROR_FILE_NOT_FOUND) version = "" if pythonExe is None: return version cwd = os.path.dirname(pythonExe) env = koprocessutils.getUserEnv() argv = [pythonExe, "-c", "import sys; sys.stdout.write(sys.version)"] p = process.ProcessOpen(argv, cwd=cwd, env=env, stdin=None) stdout, stderr = p.communicate() if not p.returncode: # Some example output: # 2.0 (#8, Mar 7 2001, 16:04:37) [MSC 32 bit (Intel)] # 2.5.2 (r252:60911, Mar 27 2008, 17:57:18) [MSC v.1310 32 bit (Intel)] # 2.6rc2 (r26rc2:66504, Sep 26 2008, 15:20:44) [MSC v.1500 32 bit (Intel)] version_re = re.compile(r"^(\d+\.\d+)") match = version_re.match(stdout) if match: version = match.group(1) return version
def observe(self, subject, topic, data): if topic == self.defaultInterpreterPrefName: self.reset() elif topic == "user_environment_changed": # Re-create the user path and drop any caches. self._userPath = koprocessutils.getUserEnv().get("PATH", "").split(os.pathsep) self.reset()
def lint_with_text(self, request, text): log.info(request) log.debug(text) if not text.strip(): return None # consider adding lint preferences? maybe for compiler selection, paths, etc? n = uuid.uuid1() dst_name = n.hex + ".out" dst_path = os.path.join(request.cwd, dst_name) compilation_command = ['go', 'build', '-o', dst_name] try: env = koprocessutils.getUserEnv() results = koLintResults() log.info('Running ' + ' '.join(compilation_command)) p = process.ProcessOpen(compilation_command, cwd=request.cwd, env=env, stdin=None) output, error = p.communicate() log.debug("output: output:[%s], error:[%s]", output, error) output = output + error retval = p.returncode finally: try: os.unlink(dst_path) except OSError: pass if output: for line in output.splitlines(): if line[0] == '#': continue results.addResult(self._buildResult(text, line, request.koDoc.baseName)) return results
def async_eval_at_trg(self, buf, trg, ctlr): if not self.gocode_present: return if _xpcom_: trg = UnwrapObject(trg) ctlr = UnwrapObject(ctlr) pos = trg.pos if trg.type == "call-signature": pos = pos - 1 env = koprocessutils.getUserEnv() cmd = ['gocode', '-f=json', 'autocomplete', buf.path, '%s' % pos] p = process.ProcessOpen(cmd, env=env) output, error = p.communicate(buf.accessor.text) try: completion_data = json.loads(output) completion_data = completion_data[1] except IndexError: # exit on empty gocode output return except ValueError, e: log.exception('Exception while parsing json') return
def lint_with_text(self, request, text): if not text.strip(): return None cwd = request.cwd env = koprocessutils.getUserEnv() settingsDir = env.get("DJANGO_SETTINGS_MODULE", None) if not settingsDir: settingsDir = self._getSettingsDir(cwd) if settingsDir: # Save the current buffer to a temporary file. tmpFileName = tempfile.mktemp() fout = open(tmpFileName, 'wb') try: fout.write(text) fout.close() #XXX: How to tell whether we're using Python or Python3? prefName = "pythonExtraPaths" pythonPath = request.prefset.getString(prefName, "") pythonPathEnv = env.get("PYTHONPATH", "") if pythonPathEnv: if pythonPath: pythonPath += os.pathsep + pythonPathEnv else: pythonPath = pythonPathEnv if pythonPath: if sys.platform.startswith("win"): pythonPath = pythonPath.replace('\\', '/') env["PYTHONPATH"] = pythonPath elif env.has_key("PYTHONPATH"): del env["PYTHONPATH"] results = koLintResults() pythonExe = self._pythonInfo.getExecutableFromDocument(request.koDoc) argv = [pythonExe, self._djangoLinterPath, tmpFileName, settingsDir] p = process.ProcessOpen(argv, cwd=cwd, env=env, stdin=None) output, error = p.communicate() #log.debug("Django output: output:[%s], error:[%s]", output, error) retval = p.returncode finally: os.unlink(tmpFileName) if retval == 1: if error: results.addResult(self._buildResult(text, error)) else: results.addResult(self._buildResult(text, "Unexpected error")) else: result = KoLintResult() result.lineStart = 1 result.lineEnd = 1 result.columnStart = 1 result.columnEnd = 1 + len(text.splitlines(1)[0]) result.description = "Can't find settings.py for this Django file" result.encodedDescription = result.description result.severity = result.SEV_ERROR results = koLintResults() results.addResult(result) return results
def check_for_gocode(self): try: env = koprocessutils.getUserEnv() process.ProcessOpen(["gocode"], env=env) return True except OSError: log.error('"gocode" binary not found, cannot offer completion for golang.') return False
def _setLDLibraryPath(self): env = koprocessutils.getUserEnv() ldLibPath = env.get("LD_LIBRARY_PATH", None) if ldLibPath: env["LD_LIBRARY_PATH"] = self.koDirs.mozBinDir + ":" + ldLibPath else: env["LD_LIBRARY_PATH"] = self.koDirs.mozBinDir return env
def lint_with_text(self, request, text): results = koLintResults() log.debug(request) env = koprocessutils.getUserEnv() try: subprocess.call(['go', 'env'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) except OSError: log.error('"go" binary not found!') results.addResult(_errorResult('"go" binary not found! (PATH=%s)' % env['PATH'])) return results # ensure GOPATH is present if 'GOPATH' not in env: results.addResult(_errorResult('"GOPATH" not in environment, please check your general or project settings')) return results if not text.strip(): return None # consider adding lint preferences? maybe for compiler selection, paths, etc? # Save the current buffer to a temporary file. base_temp_dir = tempfile.mkdtemp(prefix='kogo') temp_dir = os.path.join(base_temp_dir,'go') def non_go_files(dir,files): result = [] for file in files: if not file.endswith('.go'): result.append(file) return result shutil.copytree(request.cwd, temp_dir, ignore=non_go_files) buf = open(os.path.join(temp_dir, request.koDoc.baseName),'w') buf.write(text) buf.close() compilation_command = ['go', 'build'] try: log.info('Running ' + ' '.join(compilation_command)) p = process.ProcessOpen(compilation_command, cwd=temp_dir, env=env, stdin=None) output, error = p.communicate() log.debug("output: output:[%s], error:[%s]", output, error) retval = p.returncode finally: shutil.rmtree(base_temp_dir, ignore_errors=True) if retval != 0: all_output = output.splitlines() + error.splitlines() if all_output: for line in all_output: if line and line[0] == '#': continue results.addResult(_buildResult(text, line, request.koDoc.baseName)) else: results.addResult(self._buildResult(text, "Unexpected error")) return results
def lint_with_text(self, request, text): 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 find_user_path(): try: return koprocessutils.getUserEnv()["PATH"].split(os.pathsep) except: msg = "can't get user path" if msg not in _complained: _complained[msg] = None log.exception(msg) return None
def _setEnv(self): env = koprocessutils.getUserEnv() ldLibPath = env.get("LD_LIBRARY_PATH", None) if ldLibPath: env["LD_LIBRARY_PATH"] = self.mozBinDir + ":" + ldLibPath else: env["LD_LIBRARY_PATH"] = self.mozBinDir env['PYTHONPATH'] = os.pathsep.join(sys.path) return env
def __init__(self): try: self._userPath = koprocessutils.getUserEnv()["PATH"].split(os.pathsep) except: msg = "KoJSXLinter: can't get user path" if msg not in _complained: _complained[msg] = None log.exception(msg) self._userPath = None
def _getEncodedUserEnv(self): env = koprocessutils.getUserEnv() encoding = sys.getfilesystemencoding() _enc_env = {} for key, value in env.items(): try: _enc_env[key.encode(encoding)] = value.encode(encoding) except UnicodeEncodeError: pass return _enc_env
def lint_with_text(self, request, text): if self._fmt_cmd_start is None: return cwd = request.cwd or None results = koLintResults() tmpfilename = tempfile.mktemp() + ".go" fout = open(tmpfilename, "wb") fout.write(text) fout.close() cmd = self._fmt_cmd_start + [tmpfilename] env = koprocessutils.getUserEnv() bad_keys = [] for k, v in env.items(): if not isinstance(v, (str, unicode)): bad_keys.append(k) for k in bad_keys: del env[k] try: p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None) stdout, stderr = p.communicate() if not stderr: return results except: log.exception("Failed to run %s, cwd %r", cmd, cwd) return results finally: os.unlink(tmpfilename) errLines = stderr.splitlines(0) # Don't need the newlines. textLines = text.splitlines(0) for line in errLines: m = self._ptn_err.match(line) if m: fname = m.group(1) if tmpfilename not in fname: continue lineNo = int(m.group(2)) columnStart = int(m.group(3)) desc = m.group(4) m1 = self._problem_token.search(desc) if m1: columnEnd = columnStart + len(m1.group(1)) else: columnEnd = columnStart + 1 result = KoLintResult( description=desc, severity=SEV_ERROR, lineStart=lineNo, lineEnd=lineNo, columnStart=columnStart, columnEnd=columnEnd, ) results.addResult(result) return results
def _GetPHPOutputAndError(self, phpCode, php=None): """Run the given PHP code and return the output. If some error occurs then the error is logged and the empty string is returned. (Basically we are taking the position that PHP is unreliable.) """ if php is None: php = self.get_executablePath() if not php: # XXX Would be better, IMO, to raise an exception here. return None, "No PHP executable could be found." env = koprocessutils.getUserEnv() ini = self._getInterpreterConfig() if ini: env["PHPRC"] = ini argv = [php, '-q'] if not "PHPRC" in env: # php will look in cwd for php.ini also. cwd = os.path.dirname(php) else: cwd = None fd, filepath = tempfile.mkstemp(suffix=".php") try: os.write(fd, phpCode) os.close(fd) argv.append(filepath) try: p = process.ProcessOpen(argv, cwd=cwd, env=env) except OSError, e: if e.errno == 0 or e.errno == 32: # this happens if you are playing # in prefs and change the executable, but # not the ini file (ie ini is for a different # version of PHP) log.error("Caught expected PHP execution error, don't worry be happy: %s", e.strerror) else: log.error("Caught PHP execution exception: %s", e.strerror) return None, e.strerror try: p.wait(5) except process.ProcessError: # Timed out. log.error("PHP command timed out: %r", argv) return None, "PHP interpreter did not return in time." stdout = p.stdout.read() stderr = p.stderr.read() return stdout.strip(), stderr.strip()
def haveModules(self, modules): interpreter = self.get_executablePath() if not interpreter: log.info("%s: path not set", self.exenames[0]) return False argv = [interpreter, '-c', ' '.join(['import ' + str(mod) + ';' for mod in modules])] env = koprocessutils.getUserEnv() try: p = process.ProcessOpen(argv, env=env, stdin=None) except: log.error("KoPythonCommonInfoEx.haveModules: Failed to run cmd %s", argv) return False retval = p.wait() return not retval
def __init__(self): self._sysUtils = components.classes["@activestate.com/koSysUtils;1"].\ getService(components.interfaces.koISysUtils) self._koDirSvc = components.classes["@activestate.com/koDirs;1"].\ getService(components.interfaces.koIDirs) koLintService = components.classes["@activestate.com/koLintService;1"].getService(components.interfaces.koILintService) self._userPath = koprocessutils.getUserEnv()["PATH"].split(os.pathsep) self._pythonInfo = components.classes["@activestate.com/koAppInfoEx?app=Python;1"]\ .createInstance(components.interfaces.koIAppInfoEx) self._djangoLinterPath = join(dirname(dirname(__file__)), "pylib", "djangoLinter.py") self._settingsForDirs = {} self._lineSplitterRE = re.compile(r'\r?\n') self._html_linter = koLintService.getLinterForLanguage("HTML") self._nonNewline = re.compile(r'[^\r\n]')
def __init__(self): self._fsLock = threading.Lock() # A queue of feature names for which the status has been requested. self._fsQueue = Queue.Queue() # A thread to gather the status of the features named in the Queue. self._fsThread = None self._fsThreadExiting = threading.Event() # Get a schwack of services and components and proxy them all. self._observerSvc = components.classes["@mozilla.org/observer-service;1"].getService( components.interfaces.nsIObserverService ) self._lastErrorSvc = components.classes["@activestate.com/koLastErrorService;1"].getService( components.interfaces.koILastErrorService ) self._prefs = ( components.classes["@activestate.com/koPrefService;1"] .getService(components.interfaces.koIPrefService) .prefs ) self._nodejsInfoEx = components.classes["@activestate.com/koAppInfoEx?app=NodeJS;1"].createInstance( components.interfaces.koIAppInfoEx ) self._perlInfoEx = components.classes["@activestate.com/koAppInfoEx?app=Perl;1"].createInstance( components.interfaces.koIAppInfoEx ) self._phpInfoEx = components.classes["@activestate.com/koAppInfoEx?app=PHP;1"].createInstance( components.interfaces.koIAppInfoEx ) self._pythonInfoEx = components.classes["@activestate.com/koAppInfoEx?app=Python;1"].getService( components.interfaces.koIAppInfoEx ) self._python3InfoEx = components.classes["@activestate.com/koAppInfoEx?app=Python3;1"].getService( components.interfaces.koIAppInfoEx ) self._rubyInfoEx = components.classes["@activestate.com/koAppInfoEx?app=Ruby;1"].createInstance( components.interfaces.koIAppInfoEx ) self._userPath = koprocessutils.getUserEnv()["PATH"].split(os.pathsep) self._observerSvc.addObserver(self, "xpcom-shutdown", 0) self._observerSvc.addObserver(self, "feature_status_request", 0) self._ignoreExceptions = 0
def getVersionForBinary(self, golangExe): if not os.path.exists(golangExe): raise ServerException(nsError.NS_ERROR_FILE_NOT_FOUND) argv = [golangExe, "version"] # Set GOROOT to point to this instance of go env = koprocessutils.getUserEnv() goRoot = env.get("GOROOT", None) env["GOROOT"] = os.path.dirname(os.path.dirname(golangExe)) p = process.ProcessOpen(argv, stdin=None, env=env) stdout, stderr = p.communicate() pattern = re.compile("go version\s+go\s*(\d+(?:\.\d+){0,2})") match = pattern.match(stdout) if match: return match.group(1) else: msg = "Can't find a version in `%s -v` output of '%s'/'%s'" % (golangExe, stdout, stderr) raise ServerException(nsError.NS_ERROR_UNEXPECTED, msg)
def _get_fixed_env(self, prefset, cwd=None): env = koprocessutils.getUserEnv() prefName = "%sExtraPaths" % self.language_name_lc newParts = filter(bool, prefset.getString(prefName, "").split(os.pathsep)) if cwd: newParts.append(cwd) if not newParts: # Nothing to fix up return env pythonPath = os.pathsep.join(newParts) pythonPathEnv = env.get("PYTHONPATH", "") if pythonPathEnv: pythonPath += os.pathsep + pythonPathEnv if sys.platform.startswith("win"): pythonPath = pythonPath.replace('\\', '/') env["PYTHONPATH"] = pythonPath return env
def runCommandInTerminal(self, async_callback, terminalHandler, args, env): # Run asynchronously self.terminalHandler = UnwrapObject(terminalHandler) import koprocessutils currentEnv = koprocessutils.getUserEnv() newEnvParts = env.split(";") for part in newEnvParts: parts = part.split("=") if len(parts) == 2: currentEnv[parts[0]] = parts[1] else: currentEnv[parts[0]] = "" self.env = currentEnv async_svc = components.classes["@activestate.com/koAsyncService;1"].\ getService(components.interfaces.koIAsyncService) async_op = koAsyncOperationBase(self._doRunCommandInTerminal, args) async_svc.run("Stackato %s" % (args[0]), async_op, async_callback, [], False) return async_op
def lint_with_text(self, request, text): log.info(request) log.debug(text) if not text.strip(): return None # consider adding lint preferences? maybe for compiler selection, paths, etc? # Save the current buffer to a temporary file. base_temp_dir = tempfile.mkdtemp(prefix='kogo') temp_dir = os.path.join(base_temp_dir,'go') def non_go_files(dir,files): result = [] for file in files: if not file.endswith('.go'): result.append(file) return result shutil.copytree(request.cwd, temp_dir, ignore=non_go_files) compilation_command = ['go', 'build'] try: env = koprocessutils.getUserEnv() results = koLintResults() log.info('Running ' + ' '.join(compilation_command)) p = process.ProcessOpen(compilation_command, cwd=temp_dir, env=env, stdin=None) output, error = p.communicate() log.debug("output: output:[%s], error:[%s]", output, error) retval = p.returncode finally: shutil.rmtree(base_temp_dir, ignore_errors=True) if retval != 0: all_output = output.splitlines() + error.splitlines() if all_output: for line in all_output: if line and line[0] == '#': continue results.addResult(self._buildResult(text, line, request.koDoc.baseName)) else: results.addResult(self._buildResult(text, "Unexpected error")) return results
def get_firefox_paths(self): #TODO: Could just use the new `self._gen_possible_browsers_and_types()` # and only use the `browser_type == 'firefox'` results. firefoxes = [] # If on Windows, add the browser(s) assigned as the default handlers # for .html, .htm, etc. (i.e. for common browser-y filetypes). if sys.platform.startswith("win"): import wininteg for ext in (".html", ".htm"): try: type, name, actions = wininteg.getFileAssociation(ext) except wininteg.WinIntegError: pass else: if actions: command = actions[0][2] argv = self._parseAssociationAction(command) if argv and "firefox" in argv[0].lower(): firefoxes.append(argv[0]) # Search the PATH as it was when Komodo started, otherwise Komodo's # internal mozilla.exe might be listed as a possible browser. # http://bugs.activestate.com/show_bug.cgi?id=26373 PATH = koprocessutils.getUserEnv().get("PATH", "") path = PATH.split(os.pathsep) if sys.platform.startswith('win'): firefoxes += which.whichall("firefox", exts=['.exe'], path=path) elif sys.platform == 'darwin': path = ['/Applications', '/Network/Applications'] + path firefoxes += which.whichall("Firefox.app", path=path) else: firefoxes += which.whichall("firefox", path=path) # check for duplicates firefoxesWithoutDups = [] for i in range(len(firefoxes)): for j in range(i+1, len(firefoxes)): if self._SameFile(firefoxes[i], firefoxes[j]): break else: firefoxesWithoutDups.append(firefoxes[i]) return firefoxesWithoutDups
def run_externally(self, options): command = [self.python, '-c', self.pylint_python_code] environment = koprocessutils.getUserEnv() environment['KOMODO_PATHS_BEFORE'] = self.preferences.get_string('pythonExtraPaths', scope='') environment['KOMODO_PATHS_AFTER'] = os.pathsep.join(sys.path) pylint_process = process.ProcessOpen( cmd=command + options, cwd=self.request.cwd, env=environment, stdin=None, ) stdout, stderr = pylint_process.communicate() if stderr != self.pylint_config_warning: LOG.critical('Error running pylint script: %s' % stderr) LOG.warn('Command: %s' % command) LOG.warn('Environment: %s' % environment) LOG.warn('Standard Output: %s' % stdout) return stdout.strip()
def _set_pylint_version(self, pythonExe): """ Pylint pseudo-versions: 1: Accepts -i/--include-ids 2: No longer accepts -i Y/N, accepts --msg-template STRING """ cmd = [pythonExe, '-c', 'import sys; from pylint.lint import Run; Run(["--version"])'] try: env = koprocessutils.getUserEnv() p = process.ProcessOpen(cmd, env=env, stdin=None) stdout, stderr = p.communicate() versionInfo = re.compile(r'^.*?\s+(\d+)\.(\d+)\.(\d+)').match(stdout) if versionInfo: ver = [int(x) for x in versionInfo.groups()] if ver < [1, 0, 0]: self._pylint_version = 1 # -f text -r n -i y --rcfile.... else: self._pylint_version = 2 # -f text -r n --include-ids y except: log.exception("_set_pylint_version: failed to get pylint version") if not hasattr(self, "_pylint_version"): # Fallback: self._pylint_version = 1
def __init__(self): self._executable_is_valid_cache = {} self._prefSvc = components.classes["@activestate.com/koPrefService;1"].\ getService(components.interfaces.koIPrefService) self._userPath = koprocessutils.getUserEnv().get("PATH", "").split(os.pathsep) # Listen for changes to the user environment. This must be called on the # main thread - bug 96530. @components.ProxyToMainThread def ProxyAddObserver(obj): # TODO: This will cause a leak - as we don't remove the observer, but # since these are mostly services, it's not a big problem. obsSvc = components.classes["@mozilla.org/observer-service;1"]. \ getService(components.interfaces.nsIObserverService) obsSvc.addObserver(obj, "user_environment_changed", False) ProxyAddObserver(self) try: self._prefSvc.prefs.prefObserverService.addObserver(self, self.defaultInterpreterPrefName, 0) except Exception, e: log.warn("Unable to listen for preference change for: %r", self.defaultInterpreterPrefName)
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 _userPath(self): return koprocessutils.getUserEnv().get("PATH", "").split(os.pathsep)
def lint_with_text(self, request, text): try: prefset = request.prefset linterPrefName = "%sLinterType" % self.cmd scssLinterType = prefset.getStringPref(linterPrefName) if scssLinterType == "none": return if scssLinterType == "builtin": return KoCSSLinter().lint_with_text(request, text) interpreterPrefName = "%sDefaultInterpreter" % self.cmd scssPath = prefset.getStringPref(interpreterPrefName) # The 'or' part handles any language for "Find on Path" if (not scssPath) or not os.path.exists(scssPath): try: scssPath = which.which(self.cmd) except which.WhichError: pass if not scssPath or not os.path.exists(scssPath): log.warn("Setting %sLinterType to 'default': %s not found", self.cmd, self.cmd) prefset.setStringPref(linterPrefName, "builtin") return KoCSSLinter().lint_with_text(request, text) else: prefset.setStringPref(interpreterPrefName, scssPath) rubyPath = prefset.getStringPref("rubyDefaultInterpreter") if (not rubyPath) or not os.path.exists(rubyPath): try: rubyPath = which.which("ruby") except which.WhichError: pass if (not rubyPath) or not os.path.exists(rubyPath): log.warn( "Setting %s to 'default': no ruby found to drive %s", linterPrefName, self.cmd) prefset.setStringPref(linterPrefName, "builtin") return KoCSSLinter.lint_with_text(self, request, text) else: prefset.setStringPref("rubyDefaultInterpreter", rubyPath) # Run scss tmpfilename = tempfile.mktemp() + '.' + self.cmd fout = open(tmpfilename, 'wb') fout.write(text) fout.close() textlines = text.splitlines() cmd = [rubyPath, scssPath, "-c", tmpfilename] #koLintResult.insertNiceness(cmd) cwd = request.cwd or None # We only need the stderr result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=koprocessutils.getUserEnv(), stdin=None) stderr = p.communicate()[1] warnLines = stderr.splitlines(0) # Don't need the newlines. except: warnLines = [] finally: os.unlink(tmpfilename) except: log.exception("scss: lint_with_text: big fail") warnLines = [] results = koLintResults() prevLine = "" for line in warnLines: m = self._scss_emsg_ptn.match(line) if m: lineNo = int(m.group(1)) m2 = self._syntaxErrorPtn.match(prevLine) if m2: severity = koLintResult.SEV_ERROR msg = m2.group(1) else: severity = koLintResult.SEV_WARNING msg = prevLine desc = "scss: " + msg koLintResult.createAddResult(results, textlines, severity, lineNo, desc) else: prevLine = line return results
def lint_with_text(self, request, text): 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 PHP content. Raise an exception if there is a problem. """ cwd = request.cwd #print "----------------------------" #print "PHP Lint" #print text #print "----------------------------" php = self.phpInfoEx.getExecutableFromDocument(request.koDoc) if php is None: errmsg = "Could not find a suitable PHP interpreter for linting." log.exception(errmsg) raise COMException(nsError.NS_ERROR_NOT_AVAILABLE, errmsg) if not self.checkValidVersion(): return None # save php buffer to a temporary file phpfilename = tempfile.mktemp() fout = open(phpfilename, 'wb') fout.write(text) fout.close() p = None try: argv = [php, '-n', '-d', 'display_errors=1', '-d', 'display_startup_errors=1', '-d', 'output_buffering=0', '-d', 'xdebug.remote_enable=off', '-d', 'error_reporting=2047', '-q', '-l', phpfilename] env = koprocessutils.getUserEnv() cwd = cwd or None p = process.ProcessOpen(argv, cwd=cwd, env=env) stdout, stderr = p.communicate() # The relevant output is contained in stdout. lines = stdout.splitlines(1) finally: os.unlink(phpfilename) results = koLintResults() if lines: datalines = re.split('\r\n|\r|\n',text) numLines = len(datalines) lines = [l for l in lines if l.find('error') != -1] for line in lines: #print line line = line.strip() # remove html from error output line = re.sub('<.*?>',"",line) lineText = line.rfind(' ') try: lineNo = int(line[lineText+1:]) except ValueError, e: continue #print "Line Number: ", lineNo result = KoLintResult() # XXX error in FILENAME at line XXX # Previous fix (change done for bug 42553 -- (change 254015) # This fix allows for either "at" or "on" between the # filename and the line # # Sample error message: # PHP Fatal error: Can't use function return value in write context in C:\home\ericp\lab\komodo\bugs\bz42553a.php on line 3 m = re.match(r'(.*?)\bin .*?(\b(?:on|at)\s+line\s+\d+)', line) if m: result.description = string.join(m.groups()) else: result.description = line result.lineStart = result.lineEnd = lineNo result.columnStart = 1 result.columnEnd = len(datalines[result.lineEnd-1]) + 1 result.severity = result.SEV_ERROR results.addResult(result)
def _gen_possible_browsers_and_types(self): browser_paths = _PathSet( ) # set of yielded browser paths, used to avoid dupes # If on Windows, add the browser(s) assigned as the default handlers # for .html, .htm, etc. (i.e. for common browser-y filetypes). if sys.platform.startswith("win"): import wininteg for ext in (".html", ".htm"): try: type, name, actions = wininteg.getFileAssociation(ext) except wininteg.WinIntegError: pass else: if actions: command = actions[0][2] argv = self._parseAssociationAction(command) if not argv: continue browser = argv[0] if browser not in browser_paths: browser_paths.add(browser) yield browser, self._guess_browser_type_from_path( browser) # Search the PATH as it was when Komodo started, otherwise Komodo's # internal mozilla.exe might be listed as a possible browser. # http://bugs.activestate.com/show_bug.cgi?id=26373 PATH = koprocessutils.getUserEnv().get("PATH", "") path = PATH.split(os.pathsep) if sys.platform.startswith('win'): from applib import _get_win_folder # Gather some default install dirs on Windows, because some of the # current stock of Windows browsers don't register themselves in # the usual ways. default_install_dirs_from_browser_type = defaultdict(list) programFiles = os.environ.get("ProgramFiles") if programFiles: default_install_dirs_from_browser_type["safari"].append( join(programFiles, "Safari")) default_install_dirs_from_browser_type["opera"].append( join(programFiles, "Opera")) try: localAppDataDir = _get_win_folder("CSIDL_LOCAL_APPDATA") except Exception, ex: log.warn("error getting local appdata dir: %s", ex) else: if localAppDataDir: default_install_dirs_from_browser_type[ "googlechrome"].append( join(localAppDataDir, "Google", "Chrome", "Application")) matches = [] for browser_type in ("firefox", "internetexplorer", "safari", "googlechrome", "chromium", "opera", "mozilla", "msnexplorer", "flock"): exe_name = self._exe_name_from_browser_type.get( browser_type, browser_type) bpath = path + default_install_dirs_from_browser_type.get( browser_type, []) for browser in which.whichall(exe_name, exts=[".exe"], path=bpath): if browser not in browser_paths: browser_paths.add(browser) yield browser, browser_type
def lint_with_text(self, request, text): if not text.strip(): return None cwd = request.cwd env = koprocessutils.getUserEnv() settingsDir = env.get("DJANGO_SETTINGS_MODULE", None) if not settingsDir: settingsDir = self._getSettingsDir(cwd) if settingsDir: # Save the current buffer to a temporary file. tmpFileName = tempfile.mktemp() fout = open(tmpFileName, 'wb') try: fout.write(text) fout.close() #XXX: How to tell whether we're using Python or Python3? prefName = "pythonExtraPaths" pythonPath = request.prefset.getString(prefName, "") pythonPathEnv = env.get("PYTHONPATH", "") if pythonPathEnv: if pythonPath: pythonPath += os.pathsep + pythonPathEnv else: pythonPath = pythonPathEnv if pythonPath: if sys.platform.startswith("win"): pythonPath = pythonPath.replace('\\', '/') env["PYTHONPATH"] = pythonPath elif env.has_key("PYTHONPATH"): del env["PYTHONPATH"] results = koLintResults() pythonExe = self._pythonInfo.getExecutableFromDocument( request.koDoc) argv = [ pythonExe, self._djangoLinterPath, tmpFileName, settingsDir ] p = process.ProcessOpen(argv, cwd=cwd, env=env, stdin=None) output, error = p.communicate() #log.debug("Django output: output:[%s], error:[%s]", output, error) retval = p.returncode finally: os.unlink(tmpFileName) if retval == 1: if error: results.addResult(self._buildResult(text, error)) else: results.addResult( self._buildResult(text, "Unexpected error")) else: result = KoLintResult() result.lineStart = 1 result.lineEnd = 1 result.columnStart = 1 result.columnEnd = 1 + len(text.splitlines(1)[0]) result.description = "Can't find settings.py for this Django file" result.encodedDescription = result.description result.severity = result.SEV_ERROR results = koLintResults() results.addResult(result) return results
def 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)
def _getUserPath(): return koprocessutils.getUserEnv()["PATH"].split(os.pathsep)
def lint_with_text(self, request, text): prefset = getProxiedEffectivePrefs(request) criticLevel = prefset.getStringPref('perl_lintOption_perlCriticLevel') if criticLevel == 'off': return if not self._appInfoEx.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._appInfoEx.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: pcOption = '''-Mcriticism (-severity => '%s', 'as-filename' => '%s')''' % ( criticLevel, baseFileName) 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
def lint_with_text(self, request, text): try: prefset = request.prefset lessLinterType = prefset.getStringPref("lessLinterType") if lessLinterType == "none": return if lessLinterType == "builtin": return KoCSSLinter.lint_with_text(self, request, text) lessPath = prefset.getStringPref("lessDefaultInterpreter") # The 'or' part handles any language for "Find on Path" if (not lessPath) or not os.path.exists(lessPath): try: lessPath = which.which("lessc") except which.WhichError: pass if (not lessPath) or not os.path.exists(lessPath): log.warn( "Setting lessLinterType to 'default': less not found") prefset.setStringPref("lessLinterType", "builtin") return KoCSSLinter.lint_with_text(self, request, text) else: prefset.setStringPref("lessDefaultInterpreter", lessPath) nodePath = prefset.getStringPref("nodejsDefaultInterpreter") if (not nodePath) or not os.path.exists(nodePath): try: nodePath = which.which("node") except which.WhichError: pass if (not nodePath) or not os.path.exists(nodePath): log.warn( "Setting lessLinterType to 'default': no node found to drive less" ) prefset.setStringPref("lessLinterType", "builtin") return KoCSSLinter.lint_with_text(self, request, text) else: prefset.setStringPref("nodejsDefaultInterpreter", nodePath) # Run less tmpfilename = tempfile.mktemp() + '.less' fout = open(tmpfilename, 'wb') fout.write(text) fout.close() textlines = text.splitlines() cmd = [nodePath, lessPath, "--no-color", tmpfilename] #koLintResult.insertNiceness(cmd) cwd = request.cwd or None # We only need the stderr result. try: p = process.ProcessOpen(cmd, cwd=cwd, env=koprocessutils.getUserEnv(), stdin=None) stderr = p.communicate()[1] warnLines = stderr.splitlines(0) # Don't need the newlines. except: warnLines = [] finally: os.unlink(tmpfilename) except: log.exception("less: lint_with_text: big fail") warnLines = [] # They're all errors for this checker # (and they all say "Syntax Checker!") # (at least version 1.3.0 of the LESS Compiler does). severity = koLintResult.SEV_ERROR results = koLintResults() for line in warnLines: m = self._less_emsg_ptn.match(line) if m: lineNo = int(m.group(2)) desc = m.group(1) column = int(m.group(3)) koLintResult.createAddResult(results, textlines, severity, lineNo, desc, columnStart=column) else: m = self._less_emsg_ptn_old.match(line) if m: lineNo = int(m.group(2)) desc = m.group(1) koLintResult.createAddResult(results, textlines, severity, lineNo, desc) return results