-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall_deps.py
More file actions
144 lines (127 loc) · 6.26 KB
/
install_deps.py
File metadata and controls
144 lines (127 loc) · 6.26 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# -*- coding: utf-8 -*-
import subprocess
import sys
import os
import re
import importlib.util
import builtins
EMBEDDED_PYTHON_DIR = os.path.dirname(sys.executable)
def is_installed(module_name):
"""
Checks if a Python module is already installed or is a built-in module.
"""
if module_name in sys.builtin_module_names or module_name in builtins.__dict__:
return True # Built-in module
return importlib.util.find_spec(module_name) is not None
def ensure_pip():
"""
Ensures pip is installed in the embedded Python environment.
If pip is not found, it attempts to install it using ensurepip.
"""
try:
importlib.util.find_spec("pip")
print("pip is already installed.")
except ImportError:
print("pip not found. Attempting to install pip using ensurepip...")
try:
result = subprocess.run([sys.executable, "-m", "ensurepip", "--default-pip"],
capture_output=True, text=True, check=True)
print("ensurepip Output:\n", result.stdout)
if result.stderr:
print("ensurepip Errors:\n", result.stderr)
print("pip installed successfully.")
except subprocess.CalledProcessError as e:
print(f"Error installing pip: {e.stderr}")
print("Please ensure your embedded Python distribution is complete and supports ensurepip.")
print("\nIf you are encountering 'Access Denied' errors, try running the application as an administrator.")
sys.exit(1)
except Exception as e:
print(f"An unexpected error occurred while ensuring pip: {e}")
print("\nIf you are encountering 'Access Denied' errors, try running the application as an administrator.")
sys.exit(1)
def install_package_with_pip(package_name):
"""
Installs a Python package using pip.
This function will simply try to install the package.
If it fails (e.g., package not found on PyPI, or compilation issues),
it will report the error but NOT exit the script.
"""
print(f"Attempting to install '{package_name}' using pip...")
try:
command_args = [sys.executable, "-m", "pip", "install", package_name]
result = subprocess.run(command_args,
capture_output=True, text=True, check=False)
if result.returncode == 0:
print(f"Successfully installed '{package_name}'.")
if result.stdout:
print("Pip Output:\n", result.stdout)
if result.stderr:
print("Pip Warnings/Errors:\n", result.stderr)
else:
print(f"Failed to install '{package_name}' using pip.")
print(f" Command: {' '.join(command_args)}")
print(f" Return Code: {result.returncode}")
print(f" Error Output:\n{result.stderr}")
print(f"Skipping '{package_name}' as it could not be installed.")
print("\nIf you are encountering 'Access Denied' errors, try running the application as an administrator.")
except Exception as e:
print(f"An unexpected error occurred while attempting to install '{package_name}': {e}")
print(f"Skipping '{package_name}' due to unexpected error.")
print("\nIf you are encountering 'Access Denied' errors, try running the application as an administrator.")
def extract_imports(script_path):
"""
Extracts top-level module names from import statements in a Python script.
It will only exclude built-in Python modules.
"""
modules = set()
try:
with open(script_path, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
match = re.match(r"^\s*import\s+([a-zA-Z_][a-zA-Z0-9_.]*)", line)
if match:
module_name = match.group(1).split(".")[0]
if not is_installed(module_name):
modules.add(module_name)
continue
match = re.match(r"^\s*from\s+([a-zA-Z_][a-zA-Z0-9_.]*)\s+import", line)
if match:
module_name = match.group(1).split(".")[0]
if not is_installed(module_name):
modules.add(module_name)
continue
except FileNotFoundError:
print(f"Error: Script file not found at '{script_path}' for import extraction.")
print("\nIf you are encountering 'Access Denied' errors, try running the application as an administrator.")
except Exception as e:
print(f"An error occurred during import extraction from '{script_path}': {e}")
print("\nIf you are encountering 'Access Denied' errors, try running the application as an administrator.")
return modules
def install_missing_dependencies(script_path):
"""
Identifies missing dependencies for a given script and attempts to install them.
Installation failures for individual packages are reported but do not stop the process.
"""
if not os.path.exists(script_path):
print(f"Error: Python script '{script_path}' not found. Cannot resolve dependencies.")
print("\nIf you are encountering 'Access Denied' errors, try running the application as an administrator.")
return
print(f"Analyzing '{script_path}' for dependencies...")
required_modules = extract_imports(script_path)
print(f"Identified potential dependencies: {', '.join(required_modules) if required_modules else 'None'}")
for module in required_modules:
if not is_installed(module):
print(f"'{module}' is not installed. Attempting installation...")
install_package_with_pip(module)
else:
print(f"'{module}' is already installed.")
if __name__ == "__main__":
ensure_pip()
if len(sys.argv) < 2:
print("Error: No target Python script filename provided to install_deps.py.")
print("Usage: python install_deps.py <path_to_main_script.py>")
sys.exit(1)
main_script_path = sys.argv[1]
install_missing_dependencies(main_script_path)