eva-exploit 3.4.21__tar.gz → 3.5__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.
- {eva_exploit-3.4.21 → eva_exploit-3.5}/PKG-INFO +5 -2
- {eva_exploit-3.4.21 → eva_exploit-3.5}/README.md +4 -1
- {eva_exploit-3.4.21 → eva_exploit-3.5}/config.py +1 -1
- {eva_exploit-3.4.21 → eva_exploit-3.5}/eva.py +3 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/eva_exploit.egg-info/PKG-INFO +5 -2
- {eva_exploit-3.4.21 → eva_exploit-3.5}/eva_exploit.egg-info/SOURCES.txt +1 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/modules/exploit_search.py +3 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/modules/llm.py +3 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/pyproject.toml +1 -1
- {eva_exploit-3.4.21 → eva_exploit-3.5}/sessions/eva_session.py +3 -0
- eva_exploit-3.5/utils/config_loader.py +132 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/utils/system.py +117 -34
- {eva_exploit-3.4.21 → eva_exploit-3.5}/eva_exploit.egg-info/dependency_links.txt +0 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/eva_exploit.egg-info/entry_points.txt +0 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/eva_exploit.egg-info/requires.txt +0 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/eva_exploit.egg-info/top_level.txt +0 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/modules/__init__.py +0 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/modules/attack_map.py +0 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/modules/prompt_builder.py +0 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/modules/reporting.py +0 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/modules/tooling.py +0 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/modules/vuln_intel.py +0 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/modules/workflow.py +0 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/sessions/__init__.py +0 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/setup.cfg +0 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/utils/__init__.py +0 -0
- {eva_exploit-3.4.21 → eva_exploit-3.5}/utils/ui.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: eva-exploit
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.5
|
|
4
4
|
Summary: Exploit Vector Agent
|
|
5
5
|
Author: ARCANGEL0
|
|
6
6
|
License: MIT
|
|
@@ -249,6 +249,9 @@ eva --config
|
|
|
249
249
|
# deletes all sessions and files
|
|
250
250
|
eva --delete
|
|
251
251
|
|
|
252
|
+
# configure custom api and payload handler
|
|
253
|
+
eva --custom-api
|
|
254
|
+
|
|
252
255
|
# vulnerability / exploit intel search
|
|
253
256
|
eva --search i have a wingftp server running on version 4.7.3, find me exploits for it
|
|
254
257
|
|
|
@@ -342,7 +345,7 @@ Let me start with basic system reconnaissance to understand the target better...
|
|
|
342
345
|
- ❌ Might be unstable or down sometimes, low stability.
|
|
343
346
|
|
|
344
347
|
### ⟅ Custom API
|
|
345
|
-
- **Endpoint**: Configurable
|
|
348
|
+
- **Endpoint**: Configurable API to use your own as you wish. Please run `eva --custom-api` to set API handler and payload
|
|
346
349
|
- **About**:
|
|
347
350
|
- ✅ Custom model integration
|
|
348
351
|
- ✅ Modifiable as you wish
|
|
@@ -237,6 +237,9 @@ eva --config
|
|
|
237
237
|
# deletes all sessions and files
|
|
238
238
|
eva --delete
|
|
239
239
|
|
|
240
|
+
# configure custom api and payload handler
|
|
241
|
+
eva --custom-api
|
|
242
|
+
|
|
240
243
|
# vulnerability / exploit intel search
|
|
241
244
|
eva --search i have a wingftp server running on version 4.7.3, find me exploits for it
|
|
242
245
|
|
|
@@ -330,7 +333,7 @@ Let me start with basic system reconnaissance to understand the target better...
|
|
|
330
333
|
- ❌ Might be unstable or down sometimes, low stability.
|
|
331
334
|
|
|
332
335
|
### ⟅ Custom API
|
|
333
|
-
- **Endpoint**: Configurable
|
|
336
|
+
- **Endpoint**: Configurable API to use your own as you wish. Please run `eva --custom-api` to set API handler and payload
|
|
334
337
|
- **About**:
|
|
335
338
|
- ✅ Custom model integration
|
|
336
339
|
- ✅ Modifiable as you wish
|
|
@@ -11,6 +11,9 @@ import subprocess
|
|
|
11
11
|
import sys
|
|
12
12
|
import time
|
|
13
13
|
import shutil
|
|
14
|
+
from utils.config_loader import ensure_config_module
|
|
15
|
+
|
|
16
|
+
ensure_config_module()
|
|
14
17
|
import config as config_module
|
|
15
18
|
# ============ Check modules, and autoinstall if not present ============
|
|
16
19
|
try:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: eva-exploit
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.5
|
|
4
4
|
Summary: Exploit Vector Agent
|
|
5
5
|
Author: ARCANGEL0
|
|
6
6
|
License: MIT
|
|
@@ -249,6 +249,9 @@ eva --config
|
|
|
249
249
|
# deletes all sessions and files
|
|
250
250
|
eva --delete
|
|
251
251
|
|
|
252
|
+
# configure custom api and payload handler
|
|
253
|
+
eva --custom-api
|
|
254
|
+
|
|
252
255
|
# vulnerability / exploit intel search
|
|
253
256
|
eva --search i have a wingftp server running on version 4.7.3, find me exploits for it
|
|
254
257
|
|
|
@@ -342,7 +345,7 @@ Let me start with basic system reconnaissance to understand the target better...
|
|
|
342
345
|
- ❌ Might be unstable or down sometimes, low stability.
|
|
343
346
|
|
|
344
347
|
### ⟅ Custom API
|
|
345
|
-
- **Endpoint**: Configurable
|
|
348
|
+
- **Endpoint**: Configurable API to use your own as you wish. Please run `eva --custom-api` to set API handler and payload
|
|
346
349
|
- **About**:
|
|
347
350
|
- ✅ Custom model integration
|
|
348
351
|
- ✅ Modifiable as you wish
|
|
@@ -17,6 +17,9 @@ from datetime import datetime, timezone
|
|
|
17
17
|
|
|
18
18
|
from colorama import Fore,Back,Style
|
|
19
19
|
|
|
20
|
+
from utils.config_loader import ensure_config_module
|
|
21
|
+
|
|
22
|
+
ensure_config_module()
|
|
20
23
|
from config import API_ENDPOINT, MAPS_DIR, REPORTS_DIR, SESSIONS_DIR, username
|
|
21
24
|
from modules.attack_map import generate_attack_map_files, open_attack_map
|
|
22
25
|
from modules.exploit_search import run_exploit_search
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import importlib
|
|
4
|
+
import importlib.util
|
|
5
|
+
import sys
|
|
6
|
+
from importlib import metadata
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _resolve_app_version():
|
|
11
|
+
try:
|
|
12
|
+
return metadata.version("eva-exploit")
|
|
13
|
+
except metadata.PackageNotFoundError:
|
|
14
|
+
return "3.4.3"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _default_config_source():
|
|
18
|
+
app_version = _resolve_app_version()
|
|
19
|
+
return f"""#!/usr/bin/env python3
|
|
20
|
+
import getpass
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
APP_NAME = "EVA"
|
|
24
|
+
APP_VERSION = "{app_version}"
|
|
25
|
+
GITHUB_REPO = "arcangel0/EVA"
|
|
26
|
+
PYPI_PACKAGE = "eva-exploit"
|
|
27
|
+
API_ENDPOINT = "NOT_SET"
|
|
28
|
+
CUSTOM_API_HANDLER = "custom.py"
|
|
29
|
+
G4F_MODEL = "gpt-oss-120b"
|
|
30
|
+
G4F_URL = "https://api.gpt4free.workers.dev/api/novaai/chat/completions"
|
|
31
|
+
OLLAMA_MODEL = "ALIENTELLIGENCE/whiterabbitv2"
|
|
32
|
+
SEARCHVULN_MODEL = "gpt-oss:120b-cloud"
|
|
33
|
+
SEARCVULN_URL = "https://ollama.com/api/chat"
|
|
34
|
+
OLLAMA_API_KEY = "NOT_SET"
|
|
35
|
+
OPENAI_API_KEY = "NOT_SET"
|
|
36
|
+
ANTHROPIC_API_KEY = "NOT_SET"
|
|
37
|
+
GEMINI_API_KEY = "NOT_SET"
|
|
38
|
+
ANTHROPIC_MODEL = "claude-3-5-sonnet-latest"
|
|
39
|
+
GEMINI_MODEL = "gemini-2.0-flash"
|
|
40
|
+
OLLAMA_CLOUD_TIMEOUT = 45
|
|
41
|
+
CONFIG_DIR = Path.home() / "EVA_data"
|
|
42
|
+
SESSIONS_DIR = CONFIG_DIR / "sessions"
|
|
43
|
+
REPORTS_DIR = CONFIG_DIR / "reports"
|
|
44
|
+
MAPS_DIR = CONFIG_DIR / "attack_maps"
|
|
45
|
+
TERMS_ACCEPTEDTHING = CONFIG_DIR / ".confirm"
|
|
46
|
+
try:
|
|
47
|
+
CONFIG_DIR.mkdir(parents=True, exist_ok=True)
|
|
48
|
+
SESSIONS_DIR.mkdir(parents=True, exist_ok=True)
|
|
49
|
+
REPORTS_DIR.mkdir(parents=True, exist_ok=True)
|
|
50
|
+
MAPS_DIR.mkdir(parents=True, exist_ok=True)
|
|
51
|
+
except OSError:
|
|
52
|
+
CONFIG_DIR = Path("/tmp") / "EVA_data"
|
|
53
|
+
SESSIONS_DIR = CONFIG_DIR / "sessions"
|
|
54
|
+
REPORTS_DIR = CONFIG_DIR / "reports"
|
|
55
|
+
MAPS_DIR = CONFIG_DIR / "attack_maps"
|
|
56
|
+
TERMS_ACCEPTEDTHING = CONFIG_DIR / ".confirm"
|
|
57
|
+
try:
|
|
58
|
+
CONFIG_DIR.mkdir(parents=True, exist_ok=True)
|
|
59
|
+
SESSIONS_DIR.mkdir(parents=True, exist_ok=True)
|
|
60
|
+
REPORTS_DIR.mkdir(parents=True, exist_ok=True)
|
|
61
|
+
MAPS_DIR.mkdir(parents=True, exist_ok=True)
|
|
62
|
+
except OSError:
|
|
63
|
+
pass
|
|
64
|
+
username = getpass.getuser()
|
|
65
|
+
MAX_RETRIES = 10
|
|
66
|
+
RETRY_DELAY = 10
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _load_module_from_path(path):
|
|
71
|
+
spec = importlib.util.spec_from_file_location("config", str(path))
|
|
72
|
+
if not spec or not spec.loader:
|
|
73
|
+
return None
|
|
74
|
+
module = importlib.util.module_from_spec(spec)
|
|
75
|
+
spec.loader.exec_module(module)
|
|
76
|
+
sys.modules["config"] = module
|
|
77
|
+
return module
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _load_module_from_source(source, source_name="<eva-generated-config>"):
|
|
81
|
+
spec = importlib.util.spec_from_loader("config", loader=None, origin=source_name)
|
|
82
|
+
module = importlib.util.module_from_spec(spec)
|
|
83
|
+
module.__file__ = source_name
|
|
84
|
+
exec(compile(source, source_name, "exec"), module.__dict__)
|
|
85
|
+
sys.modules["config"] = module
|
|
86
|
+
return module
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _candidate_fallback_paths():
|
|
90
|
+
return [
|
|
91
|
+
Path.home() / "EVA_data" / "config.py",
|
|
92
|
+
Path("/tmp") / "eva_config.py",
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _load_or_create_fallback(path, source):
|
|
97
|
+
if path.exists():
|
|
98
|
+
return _load_module_from_path(path)
|
|
99
|
+
try:
|
|
100
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
101
|
+
path.write_text(source, encoding="utf-8")
|
|
102
|
+
except OSError:
|
|
103
|
+
return None
|
|
104
|
+
return _load_module_from_path(path)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def ensure_config_module():
|
|
108
|
+
existing = sys.modules.get("config")
|
|
109
|
+
if existing is not None:
|
|
110
|
+
return existing
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
return importlib.import_module("config")
|
|
114
|
+
except ModuleNotFoundError:
|
|
115
|
+
pass
|
|
116
|
+
|
|
117
|
+
repo_config = Path(__file__).resolve().parents[1] / "config.py"
|
|
118
|
+
if repo_config.exists():
|
|
119
|
+
loaded = _load_module_from_path(repo_config)
|
|
120
|
+
if loaded is not None:
|
|
121
|
+
return loaded
|
|
122
|
+
|
|
123
|
+
source = _default_config_source()
|
|
124
|
+
for path in _candidate_fallback_paths():
|
|
125
|
+
loaded = _load_or_create_fallback(path, source)
|
|
126
|
+
if loaded is not None:
|
|
127
|
+
return loaded
|
|
128
|
+
|
|
129
|
+
return _load_module_from_source(source)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
config_module = ensure_config_module()
|
|
@@ -18,6 +18,9 @@ from importlib import metadata
|
|
|
18
18
|
from pathlib import Path
|
|
19
19
|
from urllib import error, request
|
|
20
20
|
import tomllib
|
|
21
|
+
from utils.config_loader import ensure_config_module
|
|
22
|
+
|
|
23
|
+
ensure_config_module()
|
|
21
24
|
import config as config_module
|
|
22
25
|
|
|
23
26
|
from colorama import Fore, Style
|
|
@@ -249,11 +252,74 @@ def _is_newer(latest, current):
|
|
|
249
252
|
_UPDATE_STATUS_CACHE = None
|
|
250
253
|
|
|
251
254
|
|
|
255
|
+
def _module_git_root():
|
|
256
|
+
here = Path(__file__).resolve()
|
|
257
|
+
for base in (here.parent, *here.parents):
|
|
258
|
+
if (base / ".git").exists():
|
|
259
|
+
return base
|
|
260
|
+
return None
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def _installed_package_version():
|
|
264
|
+
try:
|
|
265
|
+
return metadata.version(PYPI_PACKAGE)
|
|
266
|
+
except metadata.PackageNotFoundError:
|
|
267
|
+
return None
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def _is_path_in_repo(raw_path, repo_root):
|
|
271
|
+
if not raw_path:
|
|
272
|
+
return False
|
|
273
|
+
try:
|
|
274
|
+
candidate = Path(raw_path).expanduser()
|
|
275
|
+
if not candidate.exists():
|
|
276
|
+
return False
|
|
277
|
+
candidate = candidate.resolve()
|
|
278
|
+
return candidate.is_relative_to(repo_root.resolve())
|
|
279
|
+
except OSError:
|
|
280
|
+
return False
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def _running_from_repo_checkout(repo_root):
|
|
284
|
+
main_module = sys.modules.get("__main__")
|
|
285
|
+
main_file = getattr(main_module, "__file__", "")
|
|
286
|
+
if _is_path_in_repo(main_file, repo_root):
|
|
287
|
+
return True
|
|
288
|
+
argv0 = sys.argv[0] if sys.argv else ""
|
|
289
|
+
if argv0 and Path(argv0).expanduser().exists() and _is_path_in_repo(argv0, repo_root):
|
|
290
|
+
return True
|
|
291
|
+
return False
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def _read_local_version(base_path):
|
|
295
|
+
pyproject = base_path / "pyproject.toml"
|
|
296
|
+
if pyproject.exists():
|
|
297
|
+
try:
|
|
298
|
+
data = tomllib.loads(pyproject.read_text(encoding="utf-8"))
|
|
299
|
+
version = data.get("project", {}).get("version")
|
|
300
|
+
if version:
|
|
301
|
+
return str(version).strip()
|
|
302
|
+
except (tomllib.TOMLDecodeError, OSError):
|
|
303
|
+
pass
|
|
304
|
+
|
|
305
|
+
cfg_path = base_path / "config.py"
|
|
306
|
+
if cfg_path.exists():
|
|
307
|
+
try:
|
|
308
|
+
raw = cfg_path.read_text(encoding="utf-8")
|
|
309
|
+
except OSError:
|
|
310
|
+
return None
|
|
311
|
+
match = re.search(r'^APP_VERSION\s*=\s*["\']([^"\']+)["\']', raw, flags=re.MULTILINE)
|
|
312
|
+
if match:
|
|
313
|
+
return match.group(1).strip()
|
|
314
|
+
return None
|
|
315
|
+
|
|
316
|
+
|
|
252
317
|
def _git_branch():
|
|
253
|
-
|
|
318
|
+
repo_root = _module_git_root()
|
|
319
|
+
if repo_root is None:
|
|
254
320
|
return "main"
|
|
255
321
|
branch_detect = subprocess.run(
|
|
256
|
-
["git", "rev-parse", "--abbrev-ref", "HEAD"],
|
|
322
|
+
["git", "-C", str(repo_root), "rev-parse", "--abbrev-ref", "HEAD"],
|
|
257
323
|
capture_output=True,
|
|
258
324
|
text=True
|
|
259
325
|
)
|
|
@@ -263,13 +329,15 @@ def _git_branch():
|
|
|
263
329
|
|
|
264
330
|
|
|
265
331
|
def _update_source():
|
|
266
|
-
|
|
332
|
+
repo_root = _module_git_root()
|
|
333
|
+
installed_version = _installed_package_version()
|
|
334
|
+
if repo_root is not None and command_exists("git") and _running_from_repo_checkout(repo_root):
|
|
267
335
|
return "github"
|
|
268
|
-
|
|
269
|
-
metadata.version(PYPI_PACKAGE)
|
|
336
|
+
if installed_version:
|
|
270
337
|
return "pypi"
|
|
271
|
-
|
|
338
|
+
if repo_root is not None and command_exists("git"):
|
|
272
339
|
return "github"
|
|
340
|
+
return "pypi"
|
|
273
341
|
|
|
274
342
|
|
|
275
343
|
def _can_reach_tls_host(host):
|
|
@@ -282,18 +350,25 @@ def _can_reach_tls_host(host):
|
|
|
282
350
|
|
|
283
351
|
|
|
284
352
|
def get_current_version():
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
353
|
+
repo_root = _module_git_root()
|
|
354
|
+
installed_version = _installed_package_version()
|
|
355
|
+
|
|
356
|
+
if repo_root is not None and _running_from_repo_checkout(repo_root):
|
|
357
|
+
local_version = _read_local_version(repo_root)
|
|
358
|
+
if local_version:
|
|
359
|
+
return local_version
|
|
360
|
+
|
|
361
|
+
if installed_version:
|
|
362
|
+
return installed_version
|
|
363
|
+
|
|
364
|
+
if repo_root is not None:
|
|
365
|
+
local_version = _read_local_version(repo_root)
|
|
366
|
+
if local_version:
|
|
367
|
+
return local_version
|
|
368
|
+
|
|
369
|
+
local_version = _read_local_version(Path.cwd())
|
|
370
|
+
if local_version:
|
|
371
|
+
return local_version
|
|
297
372
|
return APP_VERSION
|
|
298
373
|
|
|
299
374
|
|
|
@@ -339,7 +414,11 @@ def get_update_status(force=False):
|
|
|
339
414
|
latest = None
|
|
340
415
|
available = bool(latest) and _is_newer(latest, current)
|
|
341
416
|
|
|
342
|
-
|
|
417
|
+
repo_root = _module_git_root()
|
|
418
|
+
if source == "github" and repo_root is not None:
|
|
419
|
+
command = f"git -C {shlex.quote(str(repo_root))} pull --tags origin {branch}"
|
|
420
|
+
else:
|
|
421
|
+
command = "eva -u"
|
|
343
422
|
prefix = "|> Update github checkout running " if source == "github" else "|> Update eva to latest version running "
|
|
344
423
|
|
|
345
424
|
_UPDATE_STATUS_CACHE = {
|
|
@@ -377,21 +456,22 @@ def run_self_update():
|
|
|
377
456
|
source = status.get("source")
|
|
378
457
|
print(Style.BRIGHT + Fore.MAGENTA + f"Update {latest} found! Installing . . . . " + Style.RESET_ALL)
|
|
379
458
|
|
|
459
|
+
repo_root = _module_git_root()
|
|
380
460
|
updated = False
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
461
|
+
if source == "github" and repo_root is not None and command_exists("git"):
|
|
462
|
+
branch = _git_branch()
|
|
463
|
+
pull_result = subprocess.run(
|
|
464
|
+
["git", "-C", str(repo_root), "pull", "--tags", "origin", branch],
|
|
465
|
+
text=True
|
|
466
|
+
)
|
|
467
|
+
updated = pull_result.returncode == 0
|
|
468
|
+
else:
|
|
469
|
+
pip_cmd = [sys.executable, "-m", "pip", "install", "--upgrade", PYPI_PACKAGE, "--break-system-packages"]
|
|
470
|
+
pip_result = subprocess.run(pip_cmd, text=True, capture_output=True)
|
|
471
|
+
if pip_result.returncode != 0 and "no such option: --break-system-packages" in (pip_result.stderr or "").lower():
|
|
472
|
+
pip_cmd = [sys.executable, "-m", "pip", "install", "--upgrade", PYPI_PACKAGE]
|
|
473
|
+
pip_result = subprocess.run(pip_cmd, text=True)
|
|
474
|
+
updated = pip_result.returncode == 0
|
|
395
475
|
|
|
396
476
|
print(Fore.CYAN + "Almost done . . . . ")
|
|
397
477
|
if updated:
|
|
@@ -402,7 +482,10 @@ def run_self_update():
|
|
|
402
482
|
|
|
403
483
|
print(Fore.RED + "\n[!] Could not auto-update EVA in this environment.")
|
|
404
484
|
if source == "github":
|
|
405
|
-
|
|
485
|
+
if repo_root is not None:
|
|
486
|
+
print(Fore.YELLOW + f"Try manually: git -C {shlex.quote(str(repo_root))} pull --tags origin {_git_branch()}")
|
|
487
|
+
else:
|
|
488
|
+
print(Fore.YELLOW + f"Try manually: git pull --tags origin {_git_branch()}")
|
|
406
489
|
else:
|
|
407
490
|
print(Fore.YELLOW + f"Try manually: {sys.executable} -m pip install --upgrade {PYPI_PACKAGE}")
|
|
408
491
|
return 1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|