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 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 dev_main(): import os.path 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.__main__ import main sys.argv = [ sys.argv[0], "-vv", "--tcp", "--port=1456", # "--log-file=c:/temp/robotlog.log", ] main()
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()
__file__ = os.path.abspath(__file__) if not os.path.exists(os.path.join(os.path.abspath("."), "dev.py")): raise RuntimeError( 'Please execute commands from the directory containing "dev.py"') import fire try: import robotframework_ls except ImportError: # I.e.: add relative path (the cwd must be the directory containing this file). sys.path.append("src") import robotframework_ls robotframework_ls.import_robocorp_ls_core() def _fix_contents_version(contents, version): import re contents = re.sub(r"(version\s*=\s*)\"\d+\.\d+\.\d+", r'\1"%s' % (version, ), contents) contents = re.sub(r"(__version__\s*=\s*)\"\d+\.\d+\.\d+", r'\1"%s' % (version, ), contents) contents = re.sub(r"(\"version\"\s*:\s*)\"\d+\.\d+\.\d+", r'\1"%s' % (version, ), contents) contents = re.sub(r"(blob/robotframework-lsp)-\d+\.\d+\.\d+", r"\1-%s" % (version, ), contents) return contents
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 test_debug_adapter_threaded( debugger_api_core, dap_log_file, robot_thread, dap_logs_dir ): """ This is an example on how to setup the debugger structure in-memory but still talking through the DAP instead of using the core APIs. debugger_api_core: helper to get file to run / compute breakpoint position. dap_log_file: a place to store logs. robot_thread: helper run robot in a thread. dap_logs_dir: another api to store the logs needed. """ import robotframework_ls from robotframework_debug_adapter_tests.fixtures import dbg_wait_for from robocorp_ls_core.debug_adapter_core.debug_adapter_threads import ( STOP_WRITER_THREAD, ) robotframework_ls.import_robocorp_ls_core() # Configure the logger from robocorp_ls_core.robotframework_log import configure_logger reader, writer = None, None with configure_logger("robot", 3, dap_log_file): # i.e: create the server socket which will wait for the debugger connection. client_thread = _ClientThread() try: client_thread.start() address = client_thread.get_address() from robotframework_debug_adapter.run_robot__main__ import ( connect, _RobotTargetComm, ) # Note: _RobotTargetComm takes care of initializing the debugger. processor = _RobotTargetComm(connect(address[1]), debug=True) reader, writer = processor.start_communication_threads( mark_as_pydevd_threads=False ) assert client_thread.started.wait(2) # Ok, at this point the setup should be done, let's set a breakpoint # then ask to run and see if it stops there. target = debugger_api_core.get_dap_case_file("case_log.robot") debugger_api_core.target = target line = debugger_api_core.get_line_index_with_content("check that log works") client_thread.debugger_api.set_breakpoints(target, line) # Actually run it (do it in a thread so that we can verify # things on this thread). robot_thread.run_target(target) json_hit = client_thread.debugger_api.wait_for_thread_stopped( file=target, line=line ) client_thread.debugger_api.continue_event(json_hit.thread_id) dbg_wait_for( lambda: robot_thread.result_code is not None, msg="Robot execution did not finish properly.", ) # Run it once more to check that the communication is still in place # -- i.e.: we don't actually terminate it if the connection was done # in memory. from robotframework_debug_adapter_tests.fixtures import RunRobotThread robot_thread2 = RunRobotThread(dap_logs_dir) robot_thread2.run_target(target) json_hit = client_thread.debugger_api.wait_for_thread_stopped( file=target, line=line ) client_thread.debugger_api.continue_event(json_hit.thread_id) dbg_wait_for( lambda: robot_thread2.result_code is not None, msg="Robot execution did not finish properly.", ) finally: # Upon finish the client should close the sockets to finish the readers. client_thread.finish.set() # Upon finish ask the writer thread to exit too (it won't automatically finish # even if sockets are closed). processor.write_message(STOP_WRITER_THREAD) assert client_thread.sockets_closed.wait(1) if reader is not None: reader.join(2) assert not reader.is_alive(), "Expected reader to have exited already." if writer is not None: writer.join(2) assert not writer.is_alive(), "Expected writer to have exited already."
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 main(): src_folder = 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 ( configure_logger, log_args_and_python, ) from robotframework_debug_adapter.constants import LOG_FILENAME from robotframework_debug_adapter.constants import LOG_LEVEL configure_logger("robot", LOG_LEVEL, LOG_FILENAME) log = get_log() log_args_and_python(log, sys.argv, robotframework_ls.__version__) from robotframework_ls.options import DEFAULT_TIMEOUT args = sys.argv[1:] assert args[0] == "--port" port = args[1] debug = True if args[2] == "--debug" else False robot_args = args[3:] if debug: robot_args = [ "--listener=robotframework_debug_adapter.listeners.DebugListener", "--listener=robotframework_debug_adapter.listeners.DebugListenerV2", ] + robot_args s = connect(int(port)) processor = _RobotTargetComm(s, debug=debug) processor.start_communication_threads() if not processor.configuration_done.wait(DEFAULT_TIMEOUT): sys.stderr.write( "Process not configured for launch in the available timeout.\n" ) sys.exit(1) try: try: import robot except ImportError: sys.stderr.write("\nError importing robot.\n") sys.stderr.write("Python executable: %s.\n\n" % (sys.executable,)) raise from robot import run_cli exitcode = run_cli(robot_args, exit=False) finally: processor.terminate() if processor.terminated.wait(2): log.debug("Processed dap terminate event in robot.") sys.exit(exitcode)
def main(): src_folder = 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 ( configure_logger, log_args_and_python, close_logging_streams, ) from robotframework_debug_adapter.constants import LOG_FILENAME from robotframework_debug_adapter.constants import LOG_LEVEL configure_logger("robot", LOG_LEVEL, LOG_FILENAME) log = get_log() log_args_and_python(log, sys.argv, robotframework_ls) from robotframework_ls.options import DEFAULT_TIMEOUT args = sys.argv[1:] assert args[0] == "--port" port = int(args[1]) debug = True if args[2] == "--debug" else False robot_args = args[3:] if debug: robot_args = [ "--listener=robotframework_debug_adapter.listeners.DebugListener", "--listener=robotframework_debug_adapter.listeners.DebugListenerV2", ] + robot_args s = connect(port) if debug: # Make sure that we can use pydevd (initialize only in debug mode). import robotframework_debug_adapter.vendored.force_pydevd # @UnusedImport import pydevd pydevd.settrace( "127.0.0.1", port=port, suspend=False, trace_only_current_thread=False, overwrite_prev_trace=True, patch_multiprocessing=False, block_until_connected=True, wait_for_ready_to_run=False, notify_stdin=False, ) processor = _RobotTargetComm(s, debug=debug) reader, writer = processor.start_communication_threads(debug) if not processor.configuration_done.wait(DEFAULT_TIMEOUT): sys.stderr.write( "Process not configured for launch in the available timeout.\n") sys.exit(1) try: try: import robot except ImportError: sys.stderr.write("\nError importing robot.\n") sys.stderr.write("Python executable: %s.\n\n" % (sys.executable, )) raise from robot import run_cli exitcode = run_cli(robot_args, exit=False) finally: processor.terminate() if processor.terminated.wait(2): log.debug("Processed dap terminate event in robot.") close_logging_streams() sys.exit(exitcode)