Beispiel #1
0
 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)
Beispiel #3
0
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
Beispiel #4
0
    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
Beispiel #5
0
    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
Beispiel #6
0
 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()
Beispiel #7
0
    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
Beispiel #8
0
    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
Beispiel #10
0
 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
Beispiel #12
0
    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
Beispiel #15
0
 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
Beispiel #18
0
 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
Beispiel #19
0
    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()
Beispiel #20
0
    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
Beispiel #23
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)
Beispiel #24
0
 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
Beispiel #26
0
    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
Beispiel #27
0
    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
Beispiel #28
0
    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()
Beispiel #29
0
 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
Beispiel #30
0
    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)
Beispiel #31
0
    def lint_with_text(self, request, text):
        """Lint the given C/C++ file.
        
        Raise an exception and set an error on koLastErrorService if there
        is a problem.
        """
        
        cwd = request.cwd
        
        #print "----------------------------"
        #print "C++ Lint"
        #print text
        #print "----------------------------"
        cc = self.appInfoEx.executablePath
        if cc is None:
            raise Exception("Could not find a suitable C/C++ interpreter for linting.")

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

        if cc.startswith('cl') or cc.lower().endswith("\\cl.exe"):
            argv = [cc, '-c']
            isGCC = False
            # ms cl errors
            re_string = r'(?P<file>.+)?\((?P<line>\d+)\)\s:\s(?:(?P<type>.+)?\s(?P<number>C\d+)):\s(?P<message>.*)'
        else: # gcc or cc
            argv = [cc, '-c']
            isGCC = True
            # gcc errors
            re_string = r'(?P<file>[^:]+)?:(?P<line>\d+?)(?::(?P<column>\d+))?:\s(?P<type>.+)?:\s(?P<message>.*)'
            
        argv += [filename]
        _re = re.compile(re_string)
        p = None
        #print argv
        try:
            env = koprocessutils.getUserEnv()
            cwd = cwd or None
            # XXX gcc hangs if we read stdout, so we don't pipe stdout,
            # need to test this again since using subprocess and also
            # test this with msvc.
            p = process.ProcessOpen(argv, cwd=cwd, env=env, stdin=None)
            stdout, stderr = p.communicate()
            if isGCC:
                lineSource = stderr
            else:
                lineSource = stdout
            lines = lineSource.splitlines(1)
            #print lines
        finally:
            pass #os.unlink(filename)
        
        try:
            results = koLintResults()
            if lines:
                datalines = re.split('\r\n|\r|\n',text)
                numLines = len(datalines)
                result = None
                for line in lines:
                    #print line
                    if result and line[0] == ' ':
                        result.description += '\n'+line
                        continue

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

                    if 'number' in err:
                        result.description = "%s %s: %s" % (err['type'],err['number'],err['message'])
                    else:
                        result.description = "%s: %s" % (err['type'],err['message'])
                    results.addResult(result)
        except:
            errmsg = "Exception in C/C++ linting while parsing results"
            self._lastErrorSvc.setLastError(1, errmsg)
            log.exception(errmsg)
        #print "----------------------------"
        return results
Beispiel #32
0
 def _userPath(self):
     return koprocessutils.getUserEnv().get("PATH", "").split(os.pathsep)
Beispiel #33
0
    def lint_with_text(self, request, text):
        try:
            prefset = request.prefset
            linterPrefName = "%sLinterType" % self.cmd
            scssLinterType = prefset.getStringPref(linterPrefName)
            if scssLinterType == "none":
                return
            if scssLinterType == "builtin":
                return KoCSSLinter().lint_with_text(request, text)
            interpreterPrefName = "%sDefaultInterpreter" % self.cmd
            scssPath = prefset.getStringPref(interpreterPrefName)
            # The 'or' part handles any language for "Find on Path"
            if (not scssPath) or not os.path.exists(scssPath):
                try:
                    scssPath = which.which(self.cmd)
                except which.WhichError:
                    pass
            if not scssPath or not os.path.exists(scssPath):
                log.warn("Setting %sLinterType to 'default': %s not found",
                         self.cmd, self.cmd)
                prefset.setStringPref(linterPrefName, "builtin")
                return KoCSSLinter().lint_with_text(request, text)
            else:
                prefset.setStringPref(interpreterPrefName, scssPath)
            rubyPath = prefset.getStringPref("rubyDefaultInterpreter")
            if (not rubyPath) or not os.path.exists(rubyPath):
                try:
                    rubyPath = which.which("ruby")
                except which.WhichError:
                    pass
                if (not rubyPath) or not os.path.exists(rubyPath):
                    log.warn(
                        "Setting %s to 'default': no ruby found to drive %s",
                        linterPrefName, self.cmd)
                    prefset.setStringPref(linterPrefName, "builtin")
                    return KoCSSLinter.lint_with_text(self, request, text)
                else:
                    prefset.setStringPref("rubyDefaultInterpreter", rubyPath)

            # Run scss
            tmpfilename = tempfile.mktemp() + '.' + self.cmd
            fout = open(tmpfilename, 'wb')
            fout.write(text)
            fout.close()
            textlines = text.splitlines()
            cmd = [rubyPath, scssPath, "-c", tmpfilename]
            #koLintResult.insertNiceness(cmd)
            cwd = request.cwd or None
            # We only need the stderr result.
            try:
                p = process.ProcessOpen(cmd,
                                        cwd=cwd,
                                        env=koprocessutils.getUserEnv(),
                                        stdin=None)
                stderr = p.communicate()[1]
                warnLines = stderr.splitlines(0)  # Don't need the newlines.
            except:
                warnLines = []
            finally:
                os.unlink(tmpfilename)
        except:
            log.exception("scss: lint_with_text: big fail")
            warnLines = []
        results = koLintResults()
        prevLine = ""
        for line in warnLines:
            m = self._scss_emsg_ptn.match(line)
            if m:
                lineNo = int(m.group(1))
                m2 = self._syntaxErrorPtn.match(prevLine)
                if m2:
                    severity = koLintResult.SEV_ERROR
                    msg = m2.group(1)
                else:
                    severity = koLintResult.SEV_WARNING
                    msg = prevLine
                desc = "scss: " + msg
                koLintResult.createAddResult(results, textlines, severity,
                                             lineNo, desc)
            else:
                prevLine = line
        return results
    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
Beispiel #35
0
    def lint_with_text(self, request, text):
        """Lint the given PHP content.
        
        Raise an exception if there is a problem.
        """
        cwd = request.cwd
        
        #print "----------------------------"
        #print "PHP Lint"
        #print text
        #print "----------------------------"
        php = self.phpInfoEx.getExecutableFromDocument(request.koDoc)
        if php is None:
            errmsg = "Could not find a suitable PHP interpreter for linting."
            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)
Beispiel #36
0
    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
Beispiel #37
0
    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
Beispiel #38
0
    def lint_with_text(self, request, text):
        """Lint the given Tcl content.
        
        Raise an exception if there is a problem.
        """
        if gHaveGetProxiedEffectivePrefs:
            prefset = getProxiedEffectivePrefs(request)
        else:
            # Komodo 8 sets the prefet on the request.
            prefset = request.prefset
        argv = self._getLinterArgv(prefset)
        env = koprocessutils.getUserEnv()

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

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

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

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

        if not lOutput and lErrOut:
            raise ServerException(nsError.NS_ERROR_UNEXPECTED, lErrOut)
        
        if not lOutput:
            # this should never happen unless the tcl linter is broken, or
            # not executable on linux.
            raise ServerException(nsError.NS_ERROR_UNEXPECTED,
                                  "No output from Tcl linter available")
        
        if lOutput[0].startswith("TclPro") or \
           lOutput[0].startswith("scanning"):
            # The open source TclPro has the header stripped,
            # so we need to check for both "TclPro" and "scanning"
            lInput = text.split('\n')
            return self._TclPro_lint(lInput, lOutput)
        else:
            errmsg = "unrecognized lint output format:\n%s" % lOutput[0]
            raise ServerException(nsError.NS_ERROR_UNEXPECTED, errmsg)
def _getUserPath():
    return koprocessutils.getUserEnv()["PATH"].split(os.pathsep)
Beispiel #40
0
    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
Beispiel #41
0
    def lint_with_text(self, request, text):
        try:
            prefset = request.prefset
            lessLinterType = prefset.getStringPref("lessLinterType")
            if lessLinterType == "none":
                return
            if lessLinterType == "builtin":
                return KoCSSLinter.lint_with_text(self, request, text)
            lessPath = prefset.getStringPref("lessDefaultInterpreter")
            # The 'or' part handles any language for "Find on Path"
            if (not lessPath) or not os.path.exists(lessPath):
                try:
                    lessPath = which.which("lessc")
                except which.WhichError:
                    pass
                if (not lessPath) or not os.path.exists(lessPath):
                    log.warn(
                        "Setting lessLinterType to 'default': less not found")
                    prefset.setStringPref("lessLinterType", "builtin")
                    return KoCSSLinter.lint_with_text(self, request, text)
                else:
                    prefset.setStringPref("lessDefaultInterpreter", lessPath)
            nodePath = prefset.getStringPref("nodejsDefaultInterpreter")
            if (not nodePath) or not os.path.exists(nodePath):
                try:
                    nodePath = which.which("node")
                except which.WhichError:
                    pass
                if (not nodePath) or not os.path.exists(nodePath):
                    log.warn(
                        "Setting lessLinterType to 'default': no node found to drive less"
                    )
                    prefset.setStringPref("lessLinterType", "builtin")
                    return KoCSSLinter.lint_with_text(self, request, text)
                else:
                    prefset.setStringPref("nodejsDefaultInterpreter", nodePath)

            # Run less
            tmpfilename = tempfile.mktemp() + '.less'
            fout = open(tmpfilename, 'wb')
            fout.write(text)
            fout.close()
            textlines = text.splitlines()
            cmd = [nodePath, lessPath, "--no-color", tmpfilename]
            #koLintResult.insertNiceness(cmd)
            cwd = request.cwd or None
            # We only need the stderr result.
            try:
                p = process.ProcessOpen(cmd,
                                        cwd=cwd,
                                        env=koprocessutils.getUserEnv(),
                                        stdin=None)
                stderr = p.communicate()[1]
                warnLines = stderr.splitlines(0)  # Don't need the newlines.
            except:
                warnLines = []
            finally:
                os.unlink(tmpfilename)
        except:
            log.exception("less: lint_with_text: big fail")
            warnLines = []

        # They're all errors for this checker
        # (and they all say "Syntax Checker!")
        # (at least version 1.3.0 of the LESS Compiler does).
        severity = koLintResult.SEV_ERROR
        results = koLintResults()
        for line in warnLines:
            m = self._less_emsg_ptn.match(line)
            if m:
                lineNo = int(m.group(2))
                desc = m.group(1)
                column = int(m.group(3))
                koLintResult.createAddResult(results,
                                             textlines,
                                             severity,
                                             lineNo,
                                             desc,
                                             columnStart=column)
            else:
                m = self._less_emsg_ptn_old.match(line)
                if m:
                    lineNo = int(m.group(2))
                    desc = m.group(1)
                    koLintResult.createAddResult(results, textlines, severity,
                                                 lineNo, desc)
        return results