-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhooks.py
More file actions
124 lines (94 loc) · 3.37 KB
/
hooks.py
File metadata and controls
124 lines (94 loc) · 3.37 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
from __future__ import annotations
import importlib.metadata
import json
import os
import subprocess
import sys
from typing import Any
from helpers import files, projects
from helpers.print_style import PrintStyle
from usr.plugins.ladybug_memory.helpers import ladybug_memory
PACKAGE_NAME = "real_ladybug"
PACKAGE_SPEC = "real_ladybug>=0.14.1"
INSTALL_STATE_FILE = ".ladybug_install_state.json"
def _plugin_root() -> str:
return os.path.dirname(__file__)
def _state_file() -> str:
return files.get_abs_path(_plugin_root(), INSTALL_STATE_FILE)
def _installed_version() -> str:
try:
return importlib.metadata.version(PACKAGE_NAME)
except importlib.metadata.PackageNotFoundError:
return ""
def _run_pip(*args: str) -> tuple[bool, str]:
cmd = [sys.executable, "-m", "pip", *args]
result = subprocess.run(
cmd,
text=True,
capture_output=True,
)
output = (result.stdout or "") + ("\n" + result.stderr if result.stderr else "")
ok = result.returncode == 0
return ok, output.strip()
def _write_state(data: dict[str, Any]) -> None:
files.write_file(_state_file(), json.dumps(data, indent=2))
def _read_state() -> dict[str, Any]:
path = _state_file()
if not files.exists(path):
return {}
try:
return json.loads(files.read_file(path))
except Exception:
return {}
def install(**kwargs):
before = _installed_version()
ok, output = _run_pip("install", PACKAGE_SPEC)
if not ok:
raise RuntimeError(f"Failed to install {PACKAGE_SPEC}:\n{output}")
after = _installed_version()
managed = bool(after and not before)
_write_state(
{
"package": PACKAGE_NAME,
"version": after,
"managed_by_plugin": managed,
}
)
PrintStyle.standard(
f"[ladybug_memory] Dependency ready: {PACKAGE_NAME} {after or '(unknown version)'}"
)
return {"package": PACKAGE_NAME, "version": after, "managed_by_plugin": managed}
def pre_update(**kwargs):
ladybug_memory.clear_cached_connections()
def uninstall(**kwargs):
ladybug_memory.clear_cached_connections()
removed_paths: list[str] = []
projects_parent = projects.get_projects_parent_folder()
for project_name in files.get_subdirectories(projects_parent):
project_workspace = files.get_abs_path(
projects.get_project_meta(project_name), "ladybug_memory"
)
if files.exists(project_workspace):
files.delete_dir(project_workspace)
removed_paths.append(project_workspace)
state = _read_state()
managed = bool(state.get("managed_by_plugin"))
pinned_version = str(state.get("version") or "")
current_version = _installed_version()
if managed and current_version and (not pinned_version or pinned_version == current_version):
ok, output = _run_pip("uninstall", "-y", PACKAGE_NAME)
if ok:
PrintStyle.standard(
f"[ladybug_memory] Uninstalled managed dependency: {PACKAGE_NAME}"
)
else:
PrintStyle.warning(
"[ladybug_memory] Failed to uninstall managed dependency "
f"{PACKAGE_NAME}: {output}"
)
if files.exists(_state_file()):
files.delete_file(_state_file())
return {
"removed_workspaces": removed_paths,
"dependency_managed": managed,
}