Skip to content

Commit c43628a

Browse files
committed
Dev: Add quick installation commands via install.py
1 parent 9e2dedd commit c43628a

2 files changed

Lines changed: 152 additions & 0 deletions

File tree

.vscode/tasks.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,23 @@
1010
"args": ["./build.py"],
1111
"group": "build"
1212
},
13+
{
14+
"label": "Install Versions",
15+
"type": "shell",
16+
"command": "python \"install.py\" SINGLE_VERSION",
17+
"group": "build",
18+
},
19+
{
20+
"label": "Install Versions (Multi-version)",
21+
"type": "shell",
22+
"command": "python \"install.py\" MULTI_VERSION",
23+
"group": "build",
24+
},
25+
{
26+
"label": "Install Versions (Symlink)",
27+
"type": "shell",
28+
"command": "python \"install.py\" SYMLINK",
29+
"group": "build",
30+
}
1331
]
1432
}

install.py

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import re
2+
import shutil
3+
import argparse
4+
import platform
5+
6+
from pathlib import Path
7+
from dataclasses import dataclass
8+
9+
10+
build_folder = Path(Path.cwd(), "release")
11+
12+
13+
@dataclass
14+
class AddonBuild:
15+
version_string : tuple
16+
install_path : Path
17+
zip_path : Path
18+
19+
20+
def get_version_string(zip_path):
21+
return str(re.findall(r"\d\.\d", zip_path.stem)[-1])
22+
23+
24+
def userdata_folder():
25+
sys_platform = platform.system()
26+
27+
if sys_platform in {"linux", "linux2"}:
28+
return "~/.config/blender/"
29+
elif sys_platform == "darwin":
30+
return "~/Library/Application Support/Blender/"
31+
elif sys_platform in {"win32", "Windows"}:
32+
return "~/AppData/Roaming/Blender Foundation/Blender/"
33+
34+
35+
def version_to_string(version, depth=None, separator="."):
36+
if depth is not None:
37+
version = version[:depth]
38+
39+
return separator.join(map(str, version[:depth]))
40+
41+
42+
def get_addon_builds(user_folder, addon_name, use_multiversion=False):
43+
versions = (path for path in build_folder.glob("*.zip") if not path.stem.endswith("(multi-version)"))
44+
multiversion_zip = next(path for path in build_folder.glob("*.zip") if path.stem.endswith("(multi-version)"))
45+
for zip_path in versions:
46+
version_string = get_version_string(zip_path)
47+
addon_path = Path(
48+
Path(user_folder).expanduser(),
49+
version_string,
50+
f"scripts/addons/{addon_name}",
51+
)
52+
53+
if use_multiversion:
54+
yield AddonBuild(version_string, addon_path, multiversion_zip)
55+
else:
56+
yield AddonBuild(version_string, addon_path, zip_path)
57+
58+
59+
def uninstall_addon_builds(builds):
60+
for build in builds:
61+
version_string = build.version_string
62+
addon_path = build.install_path
63+
64+
if not addon_path.exists():
65+
print(f"Blender {version_string}: No installation found in \"{addon_path}\"")
66+
continue
67+
68+
if addon_path.is_junction() or addon_path.is_symlink():
69+
addon_path.unlink()
70+
print(f"Blender {version_string}: Unlinked working directory from \"{addon_path}\"")
71+
continue
72+
else:
73+
shutil.rmtree(addon_path)
74+
print(f"Blender {version_string}: Uninstalled addon in \"{addon_path}\"")
75+
continue
76+
77+
78+
def install_addon_builds(builds):
79+
for build in builds:
80+
version_string = build.version_string
81+
install_path = build.install_path
82+
zip_path = build.zip_path
83+
84+
shutil.unpack_archive(zip_path, install_path.parent)
85+
print(f"Blender {version_string}: Installed addon \"{zip_path.stem}\" in \"{install_path}\"")
86+
87+
88+
def symlink_current_directory(builds):
89+
for build in builds:
90+
version_string = build.version_string
91+
install_path = build.install_path
92+
93+
install_path.symlink_to(target=Path.cwd())
94+
print(f"Blender {version_string}: Linked working directory from \"{install_path}\"")
95+
96+
97+
def parse_arguments():
98+
parser = argparse.ArgumentParser()
99+
parser.add_argument("mode", choices=["SYMLINK", "MULTI_VERSION", "SINGLE_VERSION"], help="Specifies whether to install addon through symlinks, multiversion zip, or individual version zips.")
100+
args = parser.parse_args()
101+
102+
if args.mode == "SYMLINK":
103+
use_symlinks = True
104+
use_multiversion = False
105+
106+
elif args.mode == "MULTI_VERSION":
107+
use_symlinks = False
108+
use_multiversion = True
109+
110+
elif args.mode == "SINGLE_VERSION":
111+
use_symlinks = False
112+
use_multiversion = False
113+
114+
return (use_symlinks, use_multiversion)
115+
116+
117+
def run():
118+
use_symlinks, use_multiversion = parse_arguments()
119+
builds = tuple(get_addon_builds(userdata_folder(), addon_name="Node Tabber", use_multiversion=use_multiversion))
120+
121+
print("===== UNINSTALLING ADDON BUILDS =====")
122+
uninstall_addon_builds(builds)
123+
print()
124+
125+
print("===== INSTALLING ADDON BUILDS =====")
126+
if use_symlinks:
127+
symlink_current_directory(builds)
128+
else:
129+
install_addon_builds(builds)
130+
print()
131+
132+
133+
if __name__ == "__main__":
134+
run()

0 commit comments

Comments
 (0)