def start_backend(self):
        retval = True
        if self.is_local_hsdev:
            Logging.log('Starting local \'hsdev\' server', Logging.LOG_INFO)

            use_log_level = (self.version >= [0, 2, 3, 2])
            log_config = Settings.PLUGIN.hsdev_log_config
            log_level = Settings.PLUGIN.hsdev_log_level

            cmd = self.concat_args([(True, ["hsdev"]),
                                    (True, ["run"]),
                                    (self.port, ["--port", str(self.port)]),
                                    (self.cache, ["--cache", self.cache]),
                                    (self.log_file, ["--log", self.log_file]),
                                    (not use_log_level and log_config, ["--log-config", log_config]),
                                    (use_log_level, ["--log-level", log_level])])

            hsdev_proc = ProcHelper.exec_with_wrapper(self.exec_with, self.install_dir, cmd)
            if hsdev_proc.process is not None:
                # Use TextIOWrapper here because it combines decoding with newline handling,
                # which means less to maintain.
                hsdev_proc.process.stdout = io.TextIOWrapper(hsdev_proc.process.stdout, 'utf-8')
                hsdev_proc.process.stderr = io.TextIOWrapper(hsdev_proc.process.stderr, 'utf-8')

                # Read and wait for hsdev's startup messge. 15 seconds should be enough time for the message to appear.
                # Otherwise, kill the thread because we don't want to get stuck waiting forever.
                startup_reader = HsDevStartupReader(hsdev_proc.process.stdout)
                startup_reader.start()
                startup_reader.wait_startup(15.0)
                if startup_reader.successful():
                    port = startup_reader.port()
                    if port != self.port:
                        Logging.log('hsdev: server port changed, was {0}, now {1}'.format(self.port, port), Logging.LOG_WARNING)
                        self.port = port
                    self.drain_stdout = OutputCollector.DescriptorDrain('hsdev stdout', hsdev_proc.process.stdout)
                    self.drain_stderr = OutputCollector.DescriptorDrain('hsdev stderr', hsdev_proc.process.stderr)
                    self.drain_stdout.start()
                    self.drain_stderr.start()
                    self.hsdev_process = hsdev_proc

                    Logging.log('Local \'hsdev\' server started successfully.', Logging.LOG_INFO)
                else:
                    # This is a bit of a "Hail Mary!" because readline() could just hang forever. Just to make sure,
                    # kill the process too!
                    startup_reader.stop()
                    hsdev_proc.process.kill()
                    if hsdev_proc.process_err is not None:
                        Logging.log('Possible reason for timeout: {0}'.format(hsdev_proc.process_err))
                    self.hsdev_process = None
                    retval = False

                    sublime.error_message('Timed out waiting for \'hsdev\' to start up.')
            else:
                errmsg = 'Could not start local \'hsdev\' server because:\n\n' + hsdev_proc.process_err
                sublime.error_message(errmsg)
                self.hsdev_process = None
                retval = False

        return retval
Beispiel #2
0
    def start_backend(self):
        retval = True
        if self.is_local_hsdev:
            Logging.log('Starting local \'hsdev\' server', Logging.LOG_INFO)

            use_log_level = (self.version >= [0, 2, 3, 2])
            log_config = Settings.PLUGIN.hsdev_log_config
            log_level = Settings.PLUGIN.hsdev_log_level

            cmd = self.concat_args([(True, ["hsdev"]),
                                    (True, ["run"]),
                                    (self.port, ["--port", str(self.port)]),
                                    (self.cache, ["--cache", self.cache]),
                                    (self.log_file, ["--log", self.log_file]),
                                    (not use_log_level and log_config, ["--log-config", log_config]),
                                    (use_log_level, ["--log-level", log_level])])

            hsdev_proc = ProcHelper.exec_with_wrapper(self.exec_with, self.install_dir, cmd)
            if hsdev_proc.process is not None:
                # Use TextIOWrapper here because it combines decoding with newline handling,
                # which means less to maintain.
                hsdev_proc.process.stdout = io.TextIOWrapper(hsdev_proc.process.stdout, 'utf-8')
                hsdev_proc.process.stderr = io.TextIOWrapper(hsdev_proc.process.stderr, 'utf-8')

                # Read and wait for hsdev's startup messge. 15 seconds should be enough time for the message to appear.
                # Otherwise, kill the thread because we don't want to get stuck waiting forever.
                startup_reader = HsDevStartupReader(hsdev_proc.process.stdout)
                startup_reader.start()
                startup_reader.wait_startup(15.0)
                if startup_reader.successful():
                    port = startup_reader.port()
                    if port != self.port:
                        Logging.log('hsdev: server port changed, was {0}, now {1}'.format(self.port, port), Logging.LOG_WARNING)
                        self.port = port
                    self.drain_stdout = OutputCollector.DescriptorDrain('hsdev stdout', hsdev_proc.process.stdout)
                    self.drain_stderr = OutputCollector.DescriptorDrain('hsdev stderr', hsdev_proc.process.stderr)
                    self.drain_stdout.start()
                    self.drain_stderr.start()
                    self.hsdev_process = hsdev_proc

                    Logging.log('Local \'hsdev\' server started successfully.', Logging.LOG_INFO)
                else:
                    # This is a bit of a "Hail Mary!" because readline() could just hang forever. Just to make sure,
                    # kill the process too!
                    startup_reader.stop()
                    hsdev_proc.process.kill()
                    if hsdev_proc.process_err is not None:
                        Logging.log('Possible reason for timeout: {0}'.format(hsdev_proc.process_err))
                    self.hsdev_process = None
                    retval = False

                    sublime.error_message('Timed out waiting for \'hsdev\' to start up.')
            else:
                errmsg = 'Could not start local \'hsdev\' server because:\n\n' + hsdev_proc.process_err
                sublime.error_message(errmsg)
                self.hsdev_process = None
                retval = False

        return retval
    def clean_imports(self, filename):
        cmd = ['hsclearimports', filename, '--max-import-list', '64']
        hsclean_proc = ProcHelper.exec_with_wrapper(self.exec_with, self.install_dir, cmd)
        if hsclean_proc.process is not None:
            exit_code, result, err = hsclean_proc.wait()
            if exit_code == 0:
                return (True, result.splitlines())

            return (False, err)

        return (False, ['\'hscleanimports\' utility not found.'])
Beispiel #4
0
    def clean_imports(self, filename):
        cmd = ['hsclearimports', filename, '--max-import-list', '64']
        hsclean_proc = ProcHelper.exec_with_wrapper(self.exec_with, self.install_dir, cmd)
        if hsclean_proc.process is not None:
            exit_code, result, err = hsclean_proc.wait()
            if exit_code == 0:
                return (True, result.splitlines())

            return (False, err)

        return (False, ['\'hscleanimports\' utility not found.'])
    def contents_to_module(self, contents):
        imp_module = None
        hsinspect_proc = ProcHelper.exec_with_wrapper(self.exec_with, self.install_dir, ['hsinspect'])
        if hsinspect_proc.process is not None:
            exit_code, result, _ = hsinspect_proc.wait(input_str=contents)
            if exit_code == 0:
                pyresult = json.loads(result).get('result')
                if pyresult is not None:
                    if Logging.is_log_level(Logging.LOG_DEBUG):
                        pprint.pprint(pyresult, width=127)
                    modinfo = pyresult.get('module')
                    if modinfo is not None:
                        imp_module = ResultParse.parse_module(modinfo)

        return imp_module
Beispiel #6
0
    def contents_to_module(self, contents):
        imp_module = None
        hsinspect_proc = ProcHelper.exec_with_wrapper(self.exec_with, self.install_dir, ['hsinspect'])
        if hsinspect_proc.process is not None:
            exit_code, result, _ = hsinspect_proc.wait(input_str=contents)
            if exit_code == 0:
                pyresult = json.loads(result).get('result')
                if pyresult is not None:
                    if Logging.is_log_level(Logging.LOG_DEBUG):
                        pprint.pprint(pyresult, width=127)
                    modinfo = pyresult.get('module')
                    if modinfo is not None:
                        imp_module = ResultParse.parse_module(modinfo)

        return imp_module
    def hsdev_version(exec_with, install_dir):
        retval = [0, 0, 0, 0]
        hsdev_proc = ProcHelper.exec_with_wrapper(exec_with, install_dir, ['hsdev', 'version'])
        if hsdev_proc.process is not None:
            exit_code, out, _ = hsdev_proc.wait()
            if exit_code == 0:
                ## 'cabal new-run' can spit out multiple lines of status before executing the task:
                for line in out.splitlines():
                    hsver = re.match(r'(?P<major>\d+)\.(?P<minor>\d+)\.(?P<revision>\d+)\.(?P<build>\d+)', line)
                    if hsver:
                        major = int(hsver.group('major'))
                        minor = int(hsver.group('minor'))
                        revision = int(hsver.group('revision'))
                        build = int(hsver.group('build'))
                        retval = [major, minor, revision, build]
                        break

        return retval
Beispiel #8
0
    def hsdev_version(exec_with, install_dir):
        retval = [0, 0, 0, 0]
        hsdev_proc = ProcHelper.exec_with_wrapper(exec_with, install_dir, ['hsdev', 'version'])
        if hsdev_proc.process is not None:
            exit_code, out, _ = hsdev_proc.wait()
            if exit_code == 0:
                ## 'cabal new-run' can spit out multiple lines of status before executing the task:
                for line in out.splitlines():
                    hsver = re.match(r'(?P<major>\d+)\.(?P<minor>\d+)\.(?P<revision>\d+)\.(?P<build>\d+)', line)
                    if hsver:
                        major = int(hsver.group('major'))
                        minor = int(hsver.group('minor'))
                        revision = int(hsver.group('revision'))
                        build = int(hsver.group('build'))
                        retval = [major, minor, revision, build]
                        break

        return retval
Beispiel #9
0
    def hsdev_version(exec_with, install_dir, output_compiler_version=False):
        retval = [0, 0, 0, 0]
        compiler_version = None
        cmd = ['hsdev', 'version']
        if output_compiler_version:
            cmd.append('-c')
        hsdev_proc = ProcHelper.exec_with_wrapper(exec_with, install_dir, cmd)
        if hsdev_proc.process is not None:
            exit_code, out, _ = hsdev_proc.wait()
            if exit_code == 0:
                ## 'cabal new-run' can spit out multiple lines of status before executing the task:
                for line in out.splitlines():
                    hsver = re.match(r'(?P<major>\d+)\.(?P<minor>\d+)\.(?P<revision>\d+)\.(?P<build>\d+)', line)
                    if hsver:
                        major = int(hsver.group('major'))
                        minor = int(hsver.group('minor'))
                        revision = int(hsver.group('revision'))
                        build = int(hsver.group('build'))
                        retval = [major, minor, revision, build]
                        compiler_version = line.split()[1] if output_compiler_version else None
                        break

        return (retval, compiler_version) if output_compiler_version else retval