forked from skylerknecht/messenger
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmessenger-builder
More file actions
executable file
·111 lines (93 loc) · 3.45 KB
/
messenger-builder
File metadata and controls
executable file
·111 lines (93 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/env python3
import argparse
import subprocess
import sys
import os
import importlib
import importlib.util
from pathlib import Path
from messenger import BANNER
import builder.clients as _clients # anchor to installed builder.clients
CLIENTS_DIR = Path(_clients.__file__).resolve().parent
LANG_MODULES = ("python", "csharp", "nodejs", "ruby")
def update_submodules(branch="main"):
repo_path = Path.cwd()
commands = [
["git", "submodule", "sync", "--recursive"],
["git", "submodule", "update", "--init", "--recursive"],
["git", "submodule", "foreach", "--recursive", f"git checkout {branch} && git pull"],
]
for cmd in commands:
subprocess.run(cmd, cwd=repo_path, check=True)
def in_git_repo_root() -> bool:
return (
os.path.isdir(".git")
and subprocess.run(
["git", "rev-parse", "--is-inside-work-tree"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
).returncode == 0
)
def available_languages():
langs = []
for p in CLIENTS_DIR.iterdir():
if p.is_dir() and (p / "builder.py").is_file():
langs.append(p.name)
return sorted(langs)
def try_import_builder(lang: str):
builder_file = CLIENTS_DIR / lang / "builder.py"
if not builder_file.exists():
return None
module_name = f"builder.clients.{lang}.builder"
spec = importlib.util.spec_from_file_location(module_name, str(builder_file))
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
def attach_language_subparser(subparsers, lang: str, mod):
sp = subparsers.add_parser(lang, help=f"Build {lang} client")
if not hasattr(mod, "add_arguments") or not callable(mod.add_arguments):
raise SystemExit(f"{lang} builder missing add_arguments(subparser)")
mod.add_arguments(sp)
if not hasattr(mod, "build") or not callable(mod.build):
raise SystemExit(f"{lang} builder missing build(args)")
sp.set_defaults(func=lambda args, _mod=mod: _mod.build(args))
def discover_and_register_languages(subparsers):
available = {}
for lang in available_languages():
mod = try_import_builder(lang)
if mod:
attach_language_subparser(subparsers, lang, mod)
available[lang] = mod
return available
def main(banner):
if len(sys.argv) > 1 and sys.argv[1] == "update-clients":
if in_git_repo_root():
print("[*] Updating submodules...")
update_submodules("main")
print("[+] Submodules updated.")
else:
print("[!] 'update-clients' only works in the git source directory.")
sys.exit(0)
if BANNER:
print(banner)
parser = argparse.ArgumentParser(
prog="messenger-builder",
formatter_class=argparse.RawTextHelpFormatter,
usage=None,
)
subparsers = parser.add_subparsers(dest="language", required=True)
available = discover_and_register_languages(subparsers)
args = parser.parse_args()
if not hasattr(args, "func"):
found = ", ".join(sorted(available.keys())) or "none"
raise SystemExit(f"No language handler found. Discovered: {found}")
try:
print('[*] Building Messenger Client')
args.func(args)
except KeyboardInterrupt:
print("\rBuild canceled.")
except Exception as e:
print(f"[!] Build failed: {type(e).__name__}: {e}")
sys.exit(1)
if __name__ == "__main__":
main(BANNER)