diff --git a/lldb/scripts/swig_bot_lib/client.py b/lldb/scripts/swig_bot_lib/client.py index 80a3114ddb83..74c9f163388a 100644 --- a/lldb/scripts/swig_bot_lib/client.py +++ b/lldb/scripts/swig_bot_lib/client.py @@ -133,7 +133,7 @@ def establish_remote_connection(ip_port): logging.info("Connection established...") return s -def transmit_data(connection, packed_input): +def transmit_request(connection, packed_input): logging.info("Sending {} bytes of compressed data." .format(len(packed_input))) connection.sendall(struct.pack("!I", len(packed_input))) @@ -144,6 +144,35 @@ def transmit_data(connection, packed_input): response = sockutil.recvall(connection, response_len) return response +def handle_response(options, connection, response): + logging.debug("Received {} byte response.".format(len(response))) + logging.debug("Creating output directory {}" + .format(options.target_dir)) + os.makedirs(options.target_dir, exist_ok=True) + + logging.info("Unpacking response archive into {}" + .format(options.target_dir)) + local.unpack_archive(options.target_dir, response) + response_file_path = os.path.normpath( + os.path.join(options.target_dir, "swig_output.json")) + if not os.path.isfile(response_file_path): + logging.error("Response file '{}' does not exist." + .format(response_file_path)) + return + try: + response = remote.deserialize_response_status( + io.open(response_file_path)) + if response[0] != 0: + logging.error("An error occurred during generation. Status={}" + .format(response[0])) + logging.error(response[1]) + else: + logging.info("SWIG generation successful.") + if len(response[1]) > 0: + logging.info(response[1]) + finally: + os.unlink(response_file_path) + def run(args): options = process_args(args) @@ -176,10 +205,9 @@ def run(args): logging.info("(null) -> config.json") packed_input.writestr("config.json", config) packed_input.close() - connection = establish_remote_connection(options.remote) - response = transmit_data(connection, zip_data.getvalue()) - logging.debug("Received {} byte response.".format(len(response))) + response = transmit_request(connection, zip_data.getvalue()) + handle_response(options, connection, response) finally: if connection is not None: connection.close() \ No newline at end of file diff --git a/lldb/scripts/swig_bot_lib/local.py b/lldb/scripts/swig_bot_lib/local.py index 9ee04c1d59d8..7cca0b3cabbb 100644 --- a/lldb/scripts/swig_bot_lib/local.py +++ b/lldb/scripts/swig_bot_lib/local.py @@ -44,44 +44,45 @@ def pack_archive(bytes_io, src_root, filters): except RuntimeError: zip_file = zipfile.ZipFile(bytes_io, mode='w', compression=zipfile.ZIP_STORED) + archive_entries = [] + if filters is not None: + def filter_func(t): + subfolder = t[0] + ext = t[1] + full_path = os.path.normpath(os.path.join(src_root, subfolder)) + candidates = [os.path.normpath(os.path.join(full_path, f)) + for f in os.listdir(full_path)] + actual = filter( + lambda f : os.path.isfile(f) and os.path.splitext(f)[1] == ext, + candidates) + return (subfolder, map(lambda f : os.path.basename(f), actual)) + archive_entries = map(filter_func, filters) + else: + for (root, dirs, files) in os.walk(src_root): + logging.debug("Adding files {} from directory {} to output package" + .format(files, root)) + if len(files) > 0: + rel_root = os.path.relpath(root, src_root) + archive_entries.append((rel_root, files)) - def filter_func(t): - subfolder = t[0] - ext = t[1] - full_path = os.path.normpath(os.path.join(src_root, subfolder)) - candidates = [os.path.normpath(os.path.join(full_path, f)) - for f in os.listdir(full_path)] - actual = filter( - lambda f : os.path.isfile(f) and os.path.splitext(f)[1] == ext, - candidates) - return (subfolder, map(lambda f : os.path.basename(f), actual)) - archive_entries = map(filter_func, filters) - + archive_entries = list(archive_entries) for entry in archive_entries: subfolder = entry[0] - files = entry[1] + files = list(entry[1]) for file in files: - relative_path = os.path.normpath(os.path.join(subfolder, file)) - full_path = os.path.normpath( - os.path.join(src_root, relative_path)) - logging.info("{} -> {}".format(full_path, relative_path)) - zip_file.write(full_path, relative_path) + rel_path = os.path.normpath(os.path.join(subfolder, file)) + full_path = os.path.join(src_root, rel_path) + logging.info("{} -> {}".format(full_path, rel_path)) + zip_file.write(full_path, rel_path) return zip_file -def unpack_archive(subfolder, archive_bytes): - tempfolder = os.path.join(tempfile.gettempdir(), subfolder) - os.makedirs(tempfolder, exist_ok=True) - - tempfolder = tempfile.mkdtemp(dir=tempfolder) - logging.debug("Extracting archive to {}".format(tempfolder)) - +def unpack_archive(folder, archive_bytes): zip_data = io.BytesIO(archive_bytes) logging.debug("Opening zip archive...") zip_file = zipfile.ZipFile(zip_data, mode='r') - zip_file.extractall(tempfolder) + zip_file.extractall(folder) zip_file.close() - return tempfolder def generate(options): include_folder = os.path.join(options.src_root, "include") @@ -93,7 +94,7 @@ def generate(options): out_dir = os.path.join(options.target_dir, lang.title()) if not os.path.exists(out_dir): os.makedirs(out_dir) - out_file = os.path.join(out_dir, "LLDBWrap{}".format(lang.title())) + out_file = os.path.join(out_dir, "LLDBWrap{}.cpp".format(lang.title())) swig_command = [ options.swig_executable, "-c++", @@ -122,7 +123,9 @@ def generate(options): logging.info("swig generation succeeded") if swig_output is not None and len(swig_output) > 0: logging.info("swig output: %s", swig_output) + return (0, swig_output) except subprocess.CalledProcessError as e: logging.error("An error occurred executing swig. returncode={}" .format(e.returncode)) logging.error(e.output) + return (e.returncode, e.output) \ No newline at end of file diff --git a/lldb/scripts/swig_bot_lib/remote.py b/lldb/scripts/swig_bot_lib/remote.py index 74edb67f69cd..590a873d6270 100644 --- a/lldb/scripts/swig_bot_lib/remote.py +++ b/lldb/scripts/swig_bot_lib/remote.py @@ -28,3 +28,12 @@ def parse_config(json_reader): json_data = json_reader.read() options_dict = json.loads(json_data) return options_dict + +def serialize_response_status(status): + status = {"retcode": status[0], "output": status[1]} + return json.dumps(status) + +def deserialize_response_status(json_reader): + json_data = json_reader.read() + response_dict = json.loads(json_data) + return (response_dict["retcode"], response_dict["output"]) diff --git a/lldb/scripts/swig_bot_lib/server.py b/lldb/scripts/swig_bot_lib/server.py index b7f14cfd599b..f83e0be44a54 100644 --- a/lldb/scripts/swig_bot_lib/server.py +++ b/lldb/scripts/swig_bot_lib/server.py @@ -81,7 +81,13 @@ def accept_once(sock, options): pack_location = None try: - pack_location = local.unpack_archive("swig-bot", data) + tempfolder = os.path.join(tempfile.gettempdir(), "swig-bot") + os.makedirs(tempfolder, exist_ok=True) + + pack_location = tempfile.mkdtemp(dir=tempfolder) + logging.debug("Extracting archive to {}".format(pack_location)) + + local.unpack_archive(pack_location, data) logging.debug("Successfully unpacked archive...") config_file = os.path.normpath(os.path.join(pack_location, @@ -98,12 +104,16 @@ def accept_once(sock, options): .format(config.languages, config.swig_executable, config.src_root, config.target_dir)) - local.generate(config) - logging.debug("Finished running swig. Packaging up output") + status = local.generate(config) + logging.debug("Finished running swig. Packaging up files {}" + .format(os.listdir(config.target_dir))) zip_data = io.BytesIO() - zip_file = local.pack_archive(zip_data, - config.target_dir, - [(".", None)]) + zip_file = local.pack_archive(zip_data, config.target_dir, None) + response_status = remote.serialize_response_status(status) + logging.debug("Sending response status {}".format(response_status)) + logging.info("(swig output) -> swig_output.json") + zip_file.writestr("swig_output.json", response_status) + zip_file.close() response_data = zip_data.getvalue() logging.info("Sending {} byte response".format(len(response_data)))