feat(core): rewrite installer with modular config, dynamic drive resolver, and clean orchestration
This commit is contained in:
167
main.py
167
main.py
@@ -1,27 +1,148 @@
|
||||
import os
|
||||
"""
|
||||
Main Orchestrator for Acc Installer.
|
||||
Executes directory setup, file copy, archive extraction, and automated installation.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import sys
|
||||
import subprocess
|
||||
import time
|
||||
from typing import Optional
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
MODULE_DIR = os.path.join(BASE_DIR, "module")
|
||||
from module.config import InstallerConfig, detect_target_drive
|
||||
from module.downloader_copier import setup_directories_and_copy
|
||||
from module.extract_acc import extract_acc_archive
|
||||
from module.install_novindesk import install_novindesk
|
||||
|
||||
scripts = [
|
||||
"downloader_copier.py",
|
||||
"extract_acc.py",
|
||||
"install_novindesk.py"
|
||||
]
|
||||
|
||||
for script in scripts:
|
||||
script_path = os.path.join(MODULE_DIR, script)
|
||||
print(f"[+] Running {script}...")
|
||||
result = subprocess.run([sys.executable, script_path], capture_output=True, text=True)
|
||||
|
||||
if result.returncode == 0:
|
||||
print(f"[+] {script} executed successfully.\n")
|
||||
else:
|
||||
print(f"[-] Error running {script}:")
|
||||
if result.stdout:
|
||||
print(result.stdout)
|
||||
if result.stderr:
|
||||
print(result.stderr)
|
||||
break
|
||||
def setup_logger(verbose: bool = False) -> logging.Logger:
|
||||
level = logging.DEBUG if verbose else logging.INFO
|
||||
logging.basicConfig(
|
||||
level=level,
|
||||
format="%(asctime)s [%(levelname)s] %(message)s",
|
||||
datefmt="%H:%M:%S"
|
||||
)
|
||||
return logging.getLogger("acc_installer")
|
||||
|
||||
|
||||
def parse_arguments() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="NovinPardaz Acc Installer - Automated Setup Pipeline",
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter
|
||||
)
|
||||
parser.add_argument(
|
||||
"--source",
|
||||
type=str,
|
||||
default=r"C:\SoftwareNP",
|
||||
help="Source directory containing installation archives"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--drive",
|
||||
type=str,
|
||||
default=None,
|
||||
help="Target drive for installation (e.g. 'D:\\'). Auto-detected if not specified."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dry-run",
|
||||
action="store_true",
|
||||
help="Simulate execution without modifying files or launching processes"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--skip-acc",
|
||||
action="store_true",
|
||||
help="Skip extraction of NovinAcc archive"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--skip-desk",
|
||||
action="store_true",
|
||||
help="Skip installation of NovinDesk"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-ui",
|
||||
action="store_true",
|
||||
help="Disable automatic UI interaction during NovinDesk installation"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--verbose",
|
||||
"-v",
|
||||
action="store_true",
|
||||
help="Enable detailed debug logging"
|
||||
)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def run_pipeline(config: InstallerConfig,
|
||||
skip_acc: bool = False,
|
||||
skip_desk: bool = False,
|
||||
auto_ui: bool = True) -> bool:
|
||||
"""
|
||||
Executes the installer pipeline steps sequentially.
|
||||
"""
|
||||
start_time = time.time()
|
||||
print("=" * 60)
|
||||
print(" NovinPardaz Acc Installer Pipeline ")
|
||||
print("=" * 60)
|
||||
print(f" Source Directory : {config.source_dir}")
|
||||
print(f" Target Drive : {config.target_drive}")
|
||||
print(f" Target Base Dir : {config.base_dir}")
|
||||
print(f" Dry Run Mode : {config.dry_run}")
|
||||
print("-" * 60)
|
||||
|
||||
try:
|
||||
# Step 1: Directory Setup & Software Copy
|
||||
print("\n[Step 1/3] Setting up directories and copying software files...")
|
||||
setup_directories_and_copy(config)
|
||||
print("[+] Step 1 completed successfully.")
|
||||
|
||||
# Step 2: Extract NovinAcc Archive
|
||||
if not skip_acc:
|
||||
print("\n[Step 2/3] Extracting NovinAcc accounting archive...")
|
||||
extract_acc_archive(config)
|
||||
print("[+] Step 2 completed successfully.")
|
||||
else:
|
||||
print("\n[Step 2/3] Skipped NovinAcc extraction (--skip-acc specified).")
|
||||
|
||||
# Step 3: Install NovinDesk
|
||||
if not skip_desk:
|
||||
print("\n[Step 3/3] Extracting and launching NovinDesk installer...")
|
||||
install_novindesk(config, auto_ui=auto_ui)
|
||||
print("[+] Step 3 completed successfully.")
|
||||
else:
|
||||
print("\n[Step 3/3] Skipped NovinDesk installation (--skip-desk specified).")
|
||||
|
||||
elapsed = time.time() - start_time
|
||||
print("\n" + "=" * 60)
|
||||
print(f"[SUCCESS] All installation steps completed in {elapsed:.2f} seconds.")
|
||||
print("=" * 60)
|
||||
return True
|
||||
|
||||
except Exception as exc:
|
||||
elapsed = time.time() - start_time
|
||||
print(f"\n[-] Installation pipeline failed after {elapsed:.2f} seconds!")
|
||||
print(f"[-] Error: {exc}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
|
||||
def main() -> None:
|
||||
args = parse_arguments()
|
||||
setup_logger(args.verbose)
|
||||
|
||||
target_drive = args.drive if args.drive else detect_target_drive()
|
||||
config = InstallerConfig(
|
||||
source_dir=args.source,
|
||||
target_drive=target_drive,
|
||||
dry_run=args.dry_run
|
||||
)
|
||||
|
||||
success = run_pipeline(
|
||||
config=config,
|
||||
skip_acc=args.skip_acc,
|
||||
skip_desk=args.skip_desk,
|
||||
auto_ui=not args.no_ui
|
||||
)
|
||||
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user