build_all.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import os
  2. import re
  3. import sys
  4. from winpty import PtyProcess
  5. class BuildAll:
  6. def __init__(self):
  7. self.current_dir = os.path.dirname(os.path.abspath(__file__))
  8. @staticmethod
  9. def __get_python_env_name_from_args():
  10. for arg in sys.argv[1:]:
  11. if arg.startswith("-python_env_name="):
  12. return arg.split("=")[1]
  13. return None
  14. def build_all(self):
  15. python_env_name = self.__get_python_env_name_from_args()
  16. if not python_env_name:
  17. python_env_name = input("请输入conda python环境的名称(例如:base): ")
  18. # confirm_remove = input("是否删除输出目录及其所有内容? (y/N) ").strip().lower()
  19. confirm_remove = "y"
  20. pyinstaller_confirm_flag = "-y" if confirm_remove == 'y' else ""
  21. commands = [
  22. (f"conda activate {python_env_name} && Pyinstaller {pyinstaller_confirm_flag} -D launcher.py",
  23. self.current_dir),
  24. (f"conda activate {python_env_name} && Pyinstaller {pyinstaller_confirm_flag} -D server.py",
  25. os.path.join(self.current_dir, "server")),
  26. ("npm run build:win", os.path.join(self.current_dir, "client"))
  27. ]
  28. for cmd, cwd in commands:
  29. if not self.__pre_execute_check(cmd, cwd):
  30. return
  31. self.__execute_cmd_with_pty(cmd, cwd)
  32. @staticmethod
  33. def __pre_execute_check(cmd, cwd):
  34. if "Pyinstaller" in cmd:
  35. script_name = cmd.split(" ")[-1]
  36. absolute_path = os.path.join(cwd, script_name)
  37. if not os.path.exists(absolute_path):
  38. print(f"Error: Python脚本 '{absolute_path}' 不存在!")
  39. return False
  40. elif cmd.startswith("npm "):
  41. pass
  42. return True
  43. def __execute_cmd_with_pty(self, cmd, cwd=None):
  44. counter_output_is_all_none: int = 0
  45. process = PtyProcess.spawn(["cmd", "/c", cmd], cwd=cwd)
  46. process.setwinsize(20, 9999)
  47. while process.isalive():
  48. try:
  49. output: str = process.readline()
  50. output = self.__remove_ansi_escape_codes(output)
  51. output = self.__remove_leading_newlines(output)
  52. if output in ["", " ", "\n", "\r\n", "\n\r"]:
  53. if counter_output_is_all_none != 0:
  54. continue
  55. else:
  56. counter_output_is_all_none += 1
  57. print("\n", end='')
  58. continue
  59. else:
  60. counter_output_is_all_none = 0
  61. output = self.__remove_ending_newlines(output)
  62. print(output, end='\n')
  63. except EOFError:
  64. break # 当伪终端关闭时跳出循环
  65. @staticmethod
  66. def __remove_ansi_escape_codes(s):
  67. ansi_escape = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
  68. return ansi_escape.sub('', s)
  69. @staticmethod
  70. def __remove_leading_newlines(s):
  71. while s.startswith(('\n\r', '\r\n', '\n', '\r')):
  72. for seq in ['\n\r', '\r\n', '\n', '\r']:
  73. if s.startswith(seq):
  74. s = s[len(seq):]
  75. return s
  76. @staticmethod
  77. def __remove_ending_newlines(s):
  78. sequences = ['\n\r', '\r\n', '\n', '\r']
  79. while s.endswith(tuple(sequences)):
  80. for seq in sequences:
  81. if s.endswith(seq):
  82. s = s[:-len(seq)]
  83. return s
  84. if __name__ == "__main__":
  85. builder = BuildAll()
  86. builder.build_all()