hexatools-cli 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
hexatools/__init__.py ADDED
File without changes
hexatools/main.py ADDED
@@ -0,0 +1,221 @@
1
+ import os
2
+ import sys
3
+ import subprocess
4
+ import shutil
5
+ from pathlib import Path
6
+
7
+
8
+ # --- Helper Functions for Style ---
9
+ class Colors:
10
+ GREEN = "\033[32m"
11
+ RED = "\033[31m"
12
+ BLUE = "\033[34m"
13
+ CYAN = "\033[1;36m"
14
+ RESET = "\033[0m"
15
+
16
+
17
+ def print_success(msg):
18
+ print(f" {Colors.GREEN}✔{Colors.RESET} {msg}")
19
+
20
+
21
+ def print_error(msg):
22
+ print(f" {Colors.RED}✘{Colors.RESET} {msg}")
23
+
24
+
25
+ def print_info(msg):
26
+ print(f" {Colors.BLUE}ℹ{Colors.RESET} {msg}")
27
+
28
+
29
+ def print_header(msg):
30
+ print(f"\n{Colors.CYAN}{msg}{Colors.RESET}")
31
+
32
+
33
+ def prompt_input(label):
34
+ try:
35
+ return input(f" {label}").strip()
36
+ except EOFError:
37
+ return ""
38
+
39
+
40
+ # --- Logic Functions ---
41
+
42
+
43
+ def run_command(command, shell=True, cwd=None):
44
+ """Menjalankan command system dengan output real-time"""
45
+ try:
46
+ subprocess.run(command, shell=shell, check=True, cwd=cwd)
47
+ except subprocess.CalledProcessError as e:
48
+ print_error(f"Gagal menjalankan perintah: {e}")
49
+
50
+
51
+ def check_requirements():
52
+ print_header("Environment Check")
53
+ tools = ["node", "npm", "composer", "php", "git", "code"]
54
+ for tool in tools:
55
+ if shutil.which(tool):
56
+ print_success(f"{tool}: Installed")
57
+ else:
58
+ print_error(f"{tool}: Not found")
59
+ print("")
60
+
61
+
62
+ def handle_port_kill(port):
63
+ print_header("Port Killer")
64
+ print_info(f"Checking process on port {port}...")
65
+
66
+ # Mencari PID menggunakan netstat (Windows)
67
+ try:
68
+ output = subprocess.check_output(
69
+ f"netstat -ano | findstr :{port}", shell=True
70
+ ).decode()
71
+ if not output:
72
+ raise Exception()
73
+
74
+ # Ambil PID (kolom terakhir)
75
+ lines = output.strip().split("\n")
76
+ pid = lines[0].strip().split()[-1]
77
+
78
+ print_info(f"Process PID: {pid}. Killing process...")
79
+ run_command(f"taskkill /F /PID {pid}")
80
+ print_success(f"Port {port} freed.")
81
+ except:
82
+ print_error(f"No process found on port {port}")
83
+
84
+
85
+ def setup_virtual_host(project_name):
86
+ print_info(f"Setting up Virtual Host for {project_name}.test ...")
87
+ host_path = r"C:\Windows\System32\drivers\etc\hosts"
88
+ new_line = f"\n127.0.0.1 {project_name}.test"
89
+
90
+ try:
91
+ with open(host_path, "a") as f:
92
+ f.write(new_line)
93
+ print_success(f"Domain http://{project_name}.test added to hosts file!")
94
+ except PermissionError:
95
+ print_error("Failed to write to hosts file. PLEASE RUN AS ADMINISTRATOR!")
96
+
97
+
98
+ def handle_build():
99
+ print_header("HEXATOOLS BUILD WIZARD")
100
+ print("-" * 38)
101
+
102
+ # 1. Pilih Tipe Project
103
+ print(" Select project type:")
104
+ print(" 1) Web Application (Laravel/Express)")
105
+ print(" 2) Frontend Framework (React/Vite)")
106
+ choice = prompt_input(" > ")
107
+
108
+ # 2. Tentukan Lokasi
109
+ print_header("Setup Project Location")
110
+ print(" Select installation directory:")
111
+ print(" 1) Laragon (C:\\laragon\\www)")
112
+ print(" 2) XAMPP (C:\\xampp\\htdocs)")
113
+ print(" 3) Current Directory")
114
+ loc_choice = prompt_input(" > ")
115
+
116
+ if loc_choice == "1":
117
+ target_base = Path("C:/laragon/www")
118
+ is_localhost = True
119
+ elif loc_choice == "2":
120
+ target_base = Path("C:/xampp/htdocs")
121
+ is_localhost = True
122
+ else:
123
+ target_base = Path.cwd()
124
+ is_localhost = False
125
+
126
+ project_name = prompt_input(" Enter Project Name: ")
127
+ final_path = target_base / project_name
128
+
129
+ print(f"\nTarget directory: {final_path}")
130
+
131
+ # 3. Logic Framework
132
+ framework = ""
133
+ if choice == "1":
134
+ print_header("Select Backend Framework")
135
+ print(" 1) Laravel")
136
+ print(" 2) Express.js")
137
+ fw_choice = prompt_input(" > ")
138
+
139
+ if fw_choice == "1":
140
+ print_header("Select Laravel Version")
141
+ print(" 1) Latest")
142
+ print(" 2) Versi 10.x")
143
+ ver = prompt_input(" > ")
144
+
145
+ pkg = "laravel/laravel" if ver == "1" else "laravel/laravel:^10.0"
146
+ framework = f"Laravel ({'Latest' if ver == '1' else '10.x'})"
147
+
148
+ print_info(f"Running: composer create-project {pkg}")
149
+ run_command(f'composer create-project {pkg} "{final_path}"')
150
+ else:
151
+ framework = "Express.js"
152
+ final_path.mkdir(parents=True, exist_ok=True)
153
+ print_info("Initializing Express project...")
154
+ run_command("npm init -y", cwd=final_path)
155
+ run_command("npm install express", cwd=final_path)
156
+ else:
157
+ framework = "React (Vite)"
158
+ print_info(f"Running: npm create vite@latest {project_name}")
159
+ # Menjalankan vite dengan argumen otomatis
160
+ run_command(
161
+ f"npm create vite@latest {project_name} -- --template react",
162
+ cwd=target_base,
163
+ )
164
+
165
+ print_header("Finalizing")
166
+ print_success(f"Project {project_name} ({framework}) created successfully!")
167
+
168
+ if is_localhost:
169
+ setup_virtual_host(project_name)
170
+
171
+ open_vs = prompt_input("Open in VS Code? (y/n): ")
172
+ if open_vs.lower() == "y":
173
+ run_command(f'code "{final_path}"')
174
+
175
+
176
+ def print_usage():
177
+ print(
178
+ f"""
179
+ {Colors.CYAN}
180
+ ╔═╗╦═╗╔═╗╔═╗╔╦╗╔═╗╔═╗╦ ╦
181
+ ╠═╝╠╦╝║╣ ║ ╦ ║ ║ ║║ ║║ ║
182
+ ╩ ╩╚═╚═╝╚═╝ ╩ ╚═╝╚═╝╩═╝╩═╝
183
+ Master CLI Tool by HEXA (Python Version){Colors.RESET}
184
+
185
+ Usage:
186
+ hexatools build - Interactive wizard to create a new project
187
+ hexatools port kill <port> - Kill a process running on a specific port
188
+ hexatools check - Check environment requirements
189
+ hexatools help - Show this help message
190
+ """
191
+ )
192
+
193
+
194
+ # --- Main Entry Point ---
195
+
196
+
197
+ def main():
198
+ if len(sys.argv) < 2:
199
+ print_usage()
200
+ return
201
+
202
+ command = sys.argv[1].lower()
203
+
204
+ if command == "build":
205
+ handle_build()
206
+ elif command == "port":
207
+ if len(sys.argv) > 3 and sys.argv[2] == "kill":
208
+ handle_port_kill(sys.argv[3])
209
+ else:
210
+ print_error("Usage: hexatools port kill <port>")
211
+ elif command == "check":
212
+ check_requirements()
213
+ elif command in ["help", "--help", "-h"]:
214
+ print_usage()
215
+ else:
216
+ print_error(f"Command tidak dikenal: {command}")
217
+ print_usage()
218
+
219
+
220
+ if __name__ == "__main__":
221
+ main()
@@ -0,0 +1,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: hexatools-cli
3
+ Version: 1.0.0
4
+ Summary: Master CLI Tool by HEXA
5
+ Author: HEXA
6
+ Requires-Python: >=3.10.6
7
+ License-File: LICENSE
8
+ Dynamic: author
9
+ Dynamic: license-file
10
+ Dynamic: requires-python
11
+ Dynamic: summary
@@ -0,0 +1,8 @@
1
+ hexatools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ hexatools/main.py,sha256=5l6-hf2rByDjMy9tA2iqF8FhplFp3YlYny7CvvzQfk4,6524
3
+ hexatools_cli-1.0.0.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ hexatools_cli-1.0.0.dist-info/METADATA,sha256=Xh1b9WK8dz7ithwQ30V-t6k6on-nPgk4StQa7ikpx4Q,242
5
+ hexatools_cli-1.0.0.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
6
+ hexatools_cli-1.0.0.dist-info/entry_points.txt,sha256=i7pggaZmu6ga-PxlpdSAJ5MU_kVqwXfozpEpJ7DCvwQ,50
7
+ hexatools_cli-1.0.0.dist-info/top_level.txt,sha256=7Y1sE3GX8TXmlxUSK72quoO8EZM9a0eBPiHYAcc8E6w,10
8
+ hexatools_cli-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ hexatools = hexatools.main:main
File without changes
@@ -0,0 +1 @@
1
+ hexatools