def on_setBreakpoints_request(self, request): from robocorp_ls_core.debug_adapter_core.dap.dap_schema import SourceBreakpoint from robocorp_ls_core.debug_adapter_core.dap.dap_schema import Breakpoint from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ( SetBreakpointsResponseBody, ) from robocorp_ls_core.debug_adapter_core.dap import dap_base_schema from robotframework_debug_adapter import file_utils from robotframework_debug_adapter.debugger_impl import RobotBreakpoint from robocorp_ls_core.robotframework_log import get_logger log = get_logger("robotframework_debug_adapter.run_robot__main__.py") # Just acknowledge that no breakpoints are valid. breakpoints = [] robot_breakpoints = [] source = request.arguments.source path = source.path filename = file_utils.norm_file_to_server(path) log.info("Normalized %s to %s", path, filename) if request.arguments.breakpoints: for bp in request.arguments.breakpoints: source_breakpoint = SourceBreakpoint(**bp) breakpoints.append( Breakpoint(verified=True, line=source_breakpoint.line, source=source).to_dict()) hit_condition = None try: if source_breakpoint.hitCondition: hit_condition = int(source_breakpoint.hitCondition) except: log.exception( "Unable to evaluate hit condition (%s) to an int. Ignoring it.", source_breakpoint.hitCondition, ) robot_breakpoints.append( RobotBreakpoint( source_breakpoint.line, source_breakpoint.condition, hit_condition, source_breakpoint.logMessage, )) if self._debugger_impl: self._debugger_impl.set_breakpoints(filename, robot_breakpoints) else: if robot_breakpoints: get_log().info("Unable to set breakpoints (no debug mode).") self.write_message( dap_base_schema.build_response( request, kwargs=dict(body=SetBreakpointsResponseBody( breakpoints=breakpoints)), ))
def start_server_process(args=(), python_exe=None, env=None): """ Calls this __main__ in another process. :param args: The list of arguments for the server process. i.e.: ["-vv", "--log-file=%s" % log_file] """ from robocorp_ls_core.robotframework_log import get_logger from robocorp_ls_core.subprocess_wrapper import subprocess import threading from robotframework_ls.options import Setup log = get_logger(__name__) if python_exe: if not os.path.exists(python_exe): raise RuntimeError("Expected %s to exist" % (python_exe, )) args = [python_exe or sys.executable, "-u", __file__] + list(args) log.debug('Starting server api process with args: "%s"' % ('" "'.join(args), )) environ = os.environ.copy() environ.pop("PYTHONPATH", "") environ.pop("PYTHONHOME", "") environ.pop("VIRTUAL_ENV", "") if env is not None: for key, val in env.items(): environ[key] = val environ["PYTHONIOENCODING"] = "utf-8" environ["PYTHONUNBUFFERED"] = "1" env_log = ["Environ:"] for key, val in environ.items(): env_log.append(" %s=%s" % (key, val)) if Setup.options.DEBUG_PROCESS_ENVIRON: log.debug("\n".join(env_log)) language_server_process = subprocess.Popen( args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, env=environ, bufsize=0, ) t = threading.Thread(target=_stderr_reader, args=(language_server_process.stderr, )) t.setName("Stderr from ServerAPI (%s)" % (args, )) t.setDaemon(True) t.start() return language_server_process
def main(args=None, after_bind=lambda server: None, language_server_class=None): original_args = args if args is not None else sys.argv[1:] try: import robotframework_ls except ImportError: # Automatically add it to the path if __main__ is being executed. sys.path.append( os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import robotframework_ls # @UnusedImport robotframework_ls.import_robocorp_ls_core() from robotframework_ls.options import Setup, Options from robocorp_ls_core.robotframework_log import ( configure_logger, log_args_and_python, get_logger, ) from robocorp_ls_core.python_ls import ( start_io_lang_server, start_tcp_lang_server, binary_stdio, ) if language_server_class is None: from robotframework_ls.robotframework_ls_impl import ( RobotFrameworkLanguageServer, ) language_server_class = RobotFrameworkLanguageServer parser = argparse.ArgumentParser() add_arguments(parser) args = parser.parse_args(args=original_args) if args.version: sys.stdout.write(robotframework_ls.__version__) sys.stdout.flush() return Setup.options = Options(args) verbose = args.verbose log_file = args.log_file or "" configure_logger("lsp", verbose, log_file) log = get_logger("robotframework_ls.__main__") log_args_and_python(log, original_args, robotframework_ls.__version__) if args.tcp: start_tcp_lang_server(args.host, args.port, language_server_class, after_bind=after_bind) else: stdin, stdout = binary_stdio() start_io_lang_server(stdin, stdout, language_server_class)
def _stderr_reader(stream): from robocorp_ls_core.robotframework_log import get_logger log = get_logger(__name__) try: while True: line = stream.readline() sys.stderr.buffer.write(line) if not line: break except: log.exception("Error reading from server api process stream.") finally: log.debug("Finished reading from server api process stream.")
def connect(port): from robotframework_ls.options import DEFAULT_TIMEOUT from robotframework_ls.impl.robot_lsp_constants import ENV_OPTION_ROBOT_DAP_TIMEOUT from robocorp_ls_core.robotframework_log import get_logger log = get_logger("robotframework_debug_adapter.run_robot__main__.py") # Set TCP keepalive on an open socket. # It activates after 1 second (TCP_KEEPIDLE,) of idleness, # then sends a keepalive ping once every 3 seconds (TCP_KEEPINTVL), # and closes the connection after 5 failed ping (TCP_KEEPCNT), or 15 seconds s = socket_module.socket(socket_module.AF_INET, socket_module.SOCK_STREAM) try: IPPROTO_TCP, SO_KEEPALIVE, TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT = ( socket_module.IPPROTO_TCP, socket_module.SO_KEEPALIVE, socket_module.TCP_KEEPIDLE, # @UndefinedVariable socket_module.TCP_KEEPINTVL, # @UndefinedVariable socket_module.TCP_KEEPCNT, # @UndefinedVariable ) s.setsockopt(socket_module.SOL_SOCKET, SO_KEEPALIVE, 1) s.setsockopt(IPPROTO_TCP, TCP_KEEPIDLE, 1) s.setsockopt(IPPROTO_TCP, TCP_KEEPINTVL, 3) s.setsockopt(IPPROTO_TCP, TCP_KEEPCNT, 5) except AttributeError: pass # May not be available everywhere. try: # 10 seconds default timeout timeout = int(os.environ.get( ENV_OPTION_ROBOT_DAP_TIMEOUT, DEFAULT_TIMEOUT)) s.settimeout(timeout) s.connect(("127.0.0.1", port)) s.settimeout(None) # no timeout after connected log.info("Connected.") return s except: log.exception("Could not connect to: %s", (port,)) raise
def main(): log = None try: src_folder = os.path.dirname( os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) try: import robotframework_ls except ImportError: # Automatically add it to the path if __main__ is being executed. assert os.path.exists( src_folder), "Expected: %s to exist" % (src_folder, ) sys.path.append(src_folder) import robotframework_ls # @UnusedImport robotframework_ls.import_robocorp_ls_core() from robocorp_ls_core.robotframework_log import get_logger log = get_logger(__name__) log.info("Initializing RobotFramework Server api. Args: %s", (sys.argv[1:], )) from robotframework_ls import __main__ from robotframework_ls.server_api.server import RobotFrameworkServerApi __main__.main(language_server_class=RobotFrameworkServerApi) except: try: if log is not None: log.exception("Error initializing RobotFrameworkServerApi.") finally: # Critical error (the logging may not be set up properly). # Print to file and stderr. with open(_critical_error_log_file, "a+") as stream: traceback.print_exc(file=stream) traceback.print_exc()
def main(): log = None try: try: import robocorp_code except ImportError: # Automatically add it to the path if __main__ is being executed. sys.path.append( os.path.dirname( os.path.dirname(os.path.dirname( os.path.dirname(__file__))))) import robocorp_code # @UnusedImport robocorp_code.import_robocorp_ls_core() from robocorp_ls_core.robotframework_log import get_logger log = get_logger(__name__) log.info("Initializing Locators Server api. Args: %s", (sys.argv[1:], )) from robocorp_code import __main__ from robocorp_code.locators.server.locator_server_api import LocatorServerApi __main__.main(language_server_class=LocatorServerApi) except: try: if log is not None: log.exception("Error initializing LocatorServerApi.") finally: # Critical error (the logging may not be set up properly). # Print to file and stderr. with open(_critical_error_log_file, "a+") as stream: traceback.print_exc(file=stream) traceback.print_exc()
from robocorp_ls_core.workspace import Workspace, Document from robocorp_ls_core.basic import overrides from robocorp_ls_core.cache import instance_cache from robotframework_ls.constants import NULL from robocorp_ls_core.robotframework_log import get_logger from robotframework_ls.impl.protocols import IRobotWorkspace, IRobotDocument from robocorp_ls_core.protocols import check_implements, IWorkspaceFolder from robocorp_ls_core.watchdog_wrapper import IFSObserver from typing import Optional, Any log = get_logger(__name__) class RobotWorkspace(Workspace): def __init__( self, root_uri, fs_observer: IFSObserver, workspace_folders=None, libspec_manager=NULL, generate_ast=True, ): self.libspec_manager = libspec_manager Workspace.__init__(self, root_uri, fs_observer, workspace_folders=workspace_folders) self._generate_ast = generate_ast @overrides(Workspace.add_folder)
def main(): log = None try: src_folder = os.path.dirname( os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) try: import robotframework_ls except ImportError: # Automatically add it to the path if __main__ is being executed. assert os.path.exists( src_folder), "Expected: %s to exist" % (src_folder, ) sys.path.append(src_folder) import robotframework_ls # @UnusedImport robotframework_ls.import_robocorp_ls_core() from robocorp_ls_core.robotframework_log import get_logger log = get_logger(__name__) log.info("Initializing RobotFramework Server api. Args: %s", (sys.argv[1:], )) from robotframework_ls import __main__ from robotframework_ls.server_api.server import RobotFrameworkServerApi args = sys.argv[1:] new_args = [] found_remote_fs_obverver_port = False for arg in args: if arg.startswith("--remote-fs-observer-port="): # Now, in this process, we don't own the RemoteFSObserver, we # just expect to connect to an existing one. found_remote_fs_obverver_port = True port = int(arg.split("=")[1].strip()) from robocorp_ls_core.remote_fs_observer_impl import RemoteFSObserver observer = RemoteFSObserver("<unused>", extensions=None) observer.connect_to_server(port) class RobotFrameworkServerApiWithObserver( RobotFrameworkServerApi): def __init__(self, *args, **kwargs): kwargs["observer"] = observer RobotFrameworkServerApi.__init__(self, *args, **kwargs) else: new_args.append(arg) if not found_remote_fs_obverver_port: raise RuntimeError( 'Expected "--remote-fs-observer-port=" to be passed in the arguments.' ) __main__.main( language_server_class=RobotFrameworkServerApiWithObserver, args=new_args) except: try: if log is not None: log.exception("Error initializing RobotFrameworkServerApi.") finally: # Critical error (the logging may not be set up properly). # Print to file and stderr. with open(_critical_error_log_file, "a+") as stream: traceback.print_exc(file=stream) traceback.print_exc()
def main(args=None, language_server_class=None): original_args = args if args is not None else sys.argv[1:] parser = argparse.ArgumentParser() add_arguments(parser) args = parser.parse_args(args=original_args) verbose = args.verbose log_file = args.log_file or "" try: try: import robotframework_interactive except ImportError: # Automatically add it to the path if __main__ is being executed. sys.path.append( os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import robotframework_interactive # @UnusedImport robotframework_interactive.import_robocorp_ls_core() from robocorp_ls_core.robotframework_log import ( configure_logger, log_args_and_python, get_logger, ) except: # Failed before having setup the logger (but after reading args). log_file = os.path.expanduser(log_file) log_file = os.path.realpath(os.path.abspath(log_file)) dirname = os.path.dirname(log_file) basename = os.path.basename(log_file) try: os.makedirs(dirname) except: pass # Ignore error if it already exists. name, ext = os.path.splitext(basename) postfix = "rf_interactive.init" log_file = os.path.join( dirname, name + "." + postfix + "." + str(os.getpid()) + ext) with open(log_file, "a+") as stream: traceback.print_exc(file=stream) raise if args.version: sys.stdout.write(robotframework_interactive.__version__) sys.stdout.flush() return configure_logger("rfinteractive", verbose, log_file) log = get_logger("robotframework_interactive.__main__") log_args_and_python(log, original_args, robotframework_interactive) try: from robotframework_interactive.server.options import Setup, Options Setup.options = Options(args) # Ok, now that we have our options, let's connect back. from robocorp_ls_core.python_ls import ( start_io_lang_server, start_tcp_lang_client, binary_stdio, ) if args.tcp: start_tcp_lang_client(args.host, args.port, language_server_class) else: stdin, stdout = binary_stdio() start_io_lang_server(stdin, stdout, language_server_class) except: log.exception("Error initializing") raise
def main(): """ Starts the debug adapter (creates a thread to read from stdin and another to write to stdout as expected by the vscode debug protocol). We pass the command processor to the reader thread as the idea is that the reader thread will read a message, convert it to an instance of the message in the schema and then forward it to the command processor which will interpret and act on it, posting the results to the writer queue. """ log = None try: import sys if sys.version_info[0] <= 2: raise AssertionError( "Python 3+ is required for the RobotFramework Debug Adapter.\nCurrent executable: " + sys.executable) try: import robotframework_debug_adapter import robotframework_ls except ImportError: # Automatically add it to the path if __main__ is being executed. sys.path.append( os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import robotframework_debug_adapter # @UnusedImport import robotframework_ls robotframework_ls.import_robocorp_ls_core() from robocorp_ls_core.debug_adapter_core.debug_adapter_threads import ( STOP_WRITER_THREAD, ) from robocorp_ls_core.robotframework_log import ( get_logger, configure_logger, log_args_and_python, ) from robotframework_debug_adapter.constants import LOG_FILENAME from robotframework_debug_adapter.constants import LOG_LEVEL configure_logger("dap", LOG_LEVEL, LOG_FILENAME) log = get_logger("robotframework_debug_adapter.__main__") log_args_and_python(log, sys.argv, robotframework_ls.__version__) from robocorp_ls_core.debug_adapter_core.debug_adapter_threads import ( reader_thread, ) from robocorp_ls_core.debug_adapter_core.debug_adapter_threads import ( writer_thread, ) from robotframework_debug_adapter.debug_adapter_comm import DebugAdapterComm try: from queue import Queue except ImportError: from Queue import Queue to_client_queue = Queue() comm = DebugAdapterComm(to_client_queue) write_to = sys.stdout read_from = sys.stdin if sys.version_info[0] <= 2: if sys.platform == "win32": # must read streams as binary on windows import msvcrt msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) else: # Py3 write_to = sys.stdout.buffer read_from = sys.stdin.buffer writer = threading.Thread( target=writer_thread, args=(write_to, to_client_queue, "write to client"), name="Write to client (dap __main__)", ) reader = threading.Thread( target=reader_thread, args=(read_from, comm.from_client, to_client_queue, b"read from client"), name="Read from client (dap __main__)", ) reader.start() writer.start() reader.join() log.debug("Exited reader.\n") to_client_queue.put(STOP_WRITER_THREAD) writer.join() log.debug("Exited writer.\n") except: if log is not None: log.exception("Error") # Critical error (the logging may not be set up properly). # Print to file and stderr. with open(_critical_error_log_file, "a+") as stream: traceback.print_exc(file=stream) traceback.print_exc() finally: if log is not None: log.debug("Exited main.\n")
def main(args=None, after_bind=lambda server: None, language_server_class=None): original_args = args if args is not None else sys.argv[1:] try: import robotframework_ls except ImportError: # Automatically add it to the path if __main__ is being executed. sys.path.append( os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import robotframework_ls # @UnusedImport robotframework_ls.import_robocorp_ls_core() from robotframework_ls.options import Setup, Options from robocorp_ls_core.robotframework_log import ( configure_logger, log_args_and_python, get_logger, ) from robocorp_ls_core.python_ls import ( start_io_lang_server, start_tcp_lang_server, binary_stdio, ) if language_server_class is None: from robotframework_ls.robotframework_ls_impl import ( RobotFrameworkLanguageServer, ) language_server_class = RobotFrameworkLanguageServer parser = argparse.ArgumentParser() add_arguments(parser) args = parser.parse_args(args=original_args) if args.version: sys.stdout.write(robotframework_ls.__version__) sys.stdout.flush() return Setup.options = Options(args) verbose = args.verbose log_file = args.log_file or "" if not log_file: # If not specified in args, also check the environment variables. log_file = os.environ.get("ROBOTFRAMEWORK_LS_LOG_FILE", "") if log_file: # If the log file comes from the environment, make sure the log-level # also comes from it (with a log-level==2 by default). Setup.options.log_file = log_file try: verbose = int( os.environ.get("ROBOTFRAMEWORK_LS_LOG_LEVEL", "2")) except: verbose = 2 Setup.options.verbose = verbose configure_logger("lsp", verbose, log_file) log = get_logger("robotframework_ls.__main__") log_args_and_python(log, original_args, robotframework_ls) if args.tcp: start_tcp_lang_server(args.host, args.port, language_server_class, after_bind=after_bind) else: stdin, stdout = binary_stdio() start_io_lang_server(stdin, stdout, language_server_class)
def get_log(): from robocorp_ls_core.robotframework_log import get_logger return get_logger("robotframework_debug_adapter.run_robot__main__.py")