hexatools-cli 1.0.0__tar.gz
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_cli-1.0.0/LICENSE +0 -0
- hexatools_cli-1.0.0/PKG-INFO +11 -0
- hexatools_cli-1.0.0/README.md +0 -0
- hexatools_cli-1.0.0/hexatools/__init__.py +0 -0
- hexatools_cli-1.0.0/hexatools/main.py +221 -0
- hexatools_cli-1.0.0/hexatools_cli.egg-info/PKG-INFO +11 -0
- hexatools_cli-1.0.0/hexatools_cli.egg-info/SOURCES.txt +10 -0
- hexatools_cli-1.0.0/hexatools_cli.egg-info/dependency_links.txt +1 -0
- hexatools_cli-1.0.0/hexatools_cli.egg-info/entry_points.txt +2 -0
- hexatools_cli-1.0.0/hexatools_cli.egg-info/top_level.txt +1 -0
- hexatools_cli-1.0.0/setup.cfg +4 -0
- hexatools_cli-1.0.0/setup.py +16 -0
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -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,10 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
setup.py
|
|
4
|
+
hexatools/__init__.py
|
|
5
|
+
hexatools/main.py
|
|
6
|
+
hexatools_cli.egg-info/PKG-INFO
|
|
7
|
+
hexatools_cli.egg-info/SOURCES.txt
|
|
8
|
+
hexatools_cli.egg-info/dependency_links.txt
|
|
9
|
+
hexatools_cli.egg-info/entry_points.txt
|
|
10
|
+
hexatools_cli.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
hexatools
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="hexatools-cli", # Beri nama unik agar tidak bentrok di PyPI
|
|
5
|
+
version="1.0.0",
|
|
6
|
+
packages=find_packages(),
|
|
7
|
+
install_requires=[], # Tambahkan library pihak ketiga di sini jika ada
|
|
8
|
+
entry_points={
|
|
9
|
+
"console_scripts": [
|
|
10
|
+
"hexatools=hexatools.main:main", # Perintah 'hexatools' menjalankan fungsi main()
|
|
11
|
+
],
|
|
12
|
+
},
|
|
13
|
+
author="HEXA",
|
|
14
|
+
description="Master CLI Tool by HEXA",
|
|
15
|
+
python_requires=">=3.10.6",
|
|
16
|
+
)
|