Skip to content

Commit

Permalink
gergo/newInstaller (#136)
Browse files Browse the repository at this point in the history
* add new installer mechanism

* ci(circleci): add new package connector step

* ci(circleci): install dependencies before packaging

* chore(deps): remove local specklepy dep

* chore(deps): relock again

* ci(circleci): rewrite full ci WIP

* fix(installer): ensure pip call was commented outy

* ci(circleci): updates

* ci(circleci): fix naming

* ci(circleci): update filters

* ci(circleci): update semver location

* ci(circleci): update dependency graph

* getting the specific installer branch

* get proper ci tools

* force remove new lines from installer tags

* fix installer patch pathing

* properly saving packaged zip

* add python to dotnet installer

* add zip again

* only zip the published isntaller

* publish only usefull stuff

* ci(circleci): update details in deploy

* ci(circleci): fix filters

* ci(cirleci): fix mac  build triggers

* make sure semver is set

* ci(circleci): fix env var restore in deploy

* ci(circleci): fix missing semver in files

* ci(circleci): wtf is microsoft doing with env vars in net6 containers?

* ci(circleci): fix persist to workspace pathing

* fix zipping dir

* mkdir for the zip folder

* mkdir -p

* force copy

* copy 101

* mkdir 101

* top level cp operation

* pipe the zip

* no CD

* only parameter

* build for osx 13 for arm

* moving back to a mac build machine

* fixc arm mac runtime

* remove old linux installer build

* allow alpha numbered version

* remove ci tools branch
  • Loading branch information
gjedlicska authored Dec 14, 2022
1 parent b1481bd commit fa124c2
Show file tree
Hide file tree
Showing 10 changed files with 566 additions and 516 deletions.
373 changes: 133 additions & 240 deletions .circleci/config.yml

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ __pycache__/
Installers/
modules/
.tool-versions
requirements.txt
requirements.txt
SEMVER
20 changes: 11 additions & 9 deletions bpy_speckle/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
import bpy
from bpy_speckle.installer import ensure_dependencies

ensure_dependencies()

from specklepy.logging import metrics

from bpy_speckle.ui import *
from bpy_speckle.properties import *
from bpy_speckle.operators import *
from bpy_speckle.callbacks import *
from bpy.app.handlers import persistent

bl_info = {
"name": "SpeckleBlender 2.0",
Expand All @@ -18,15 +29,6 @@
Import SpeckleBlender classes
"""

from specklepy.api.client import SpeckleClient # , SpeckleCache
from specklepy.logging import metrics

from bpy_speckle.ui import *
from bpy_speckle.properties import *
from bpy_speckle.operators import *
from bpy_speckle.callbacks import *
from bpy.app.handlers import persistent

"""
Add load handler to initialize Speckle when
loading a Blender file
Expand Down
125 changes: 125 additions & 0 deletions bpy_speckle/installer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
from pathlib import Path
from importlib import import_module

import bpy
import sys

print("Starting Speckle Blender installation")
print(sys.executable)

PYTHON_PATH = sys.executable



def modules_path() -> Path:
modules_path = Path(bpy.utils.script_path_user(), "addons", "modules")
modules_path.mkdir(exist_ok=True, parents=True)

# set user modules path at beginning of paths for earlier hit
if sys.path[1] != modules_path:
sys.path.insert(1, modules_path)

return modules_path


print(f"Found blender modules path {modules_path()}")


def is_pip_available() -> bool:
try:
import_module("pip") # noqa F401
return True
except ImportError:
return False


def ensure_pip() -> None:
print("Installing pip... "),

from subprocess import run

completed_process = run([PYTHON_PATH, "-m", "ensurepip"])

if completed_process.returncode == 0:
print("Successfully installed pip")
else:
raise Exception("Failed to install pip.")


def get_requirements_path() -> Path:
# we assume that a requirements.txt exists next to the __init__.py file
path = Path(Path(__file__).parent, "requirements.txt")
assert path.exists()
return path


def install_requirements() -> None:
# set up addons/modules under the user
# script path. Here we'll install the
# dependencies
path = modules_path()
print(f"Installing Speckle dependencies to {path}")

from subprocess import run

completed_process = run(
[
PYTHON_PATH,
"-m",
"pip",
"install",
"-t",
str(path),
"-r",
str(get_requirements_path()),
],
capture_output=True,
text=True,
)

if completed_process.returncode != 0:
print("Please try manually installing speckle-blender")
raise Exception(
"""
Failed to install speckle-blender.
See console for manual install instruction.
"""
)


def install_dependencies() -> None:
if not is_pip_available():
ensure_pip()

install_requirements()


def _import_dependencies() -> None:
import_module("specklepy")
# the code above doesn't work for now, it fails on importing graphql-core
# despite that, the connector seams to be working as expected
# But it would be nice to make this solution work
# it would ensure that all dependencies are fully loaded
# requirements = get_requirements_path().read_text()
# reqs = [
# req.split(" ; ")[0].split("==")[0].split("[")[0].replace("-", "_")
# for req in requirements.split("\n")
# if req and not req.startswith(" ")
# ]
# for req in reqs:
# print(req)
# import_module("specklepy")


def ensure_dependencies() -> None:
try:
_import_dependencies()
print("Found all dependencies, proceed with loading")
except ImportError:
print("Failed to load all dependencies, trying to install them...")
install_dependencies()
raise Exception("Please restart Blender.")


if __name__ == "__main__":
ensure_dependencies()
4 changes: 4 additions & 0 deletions export_dependencies.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -e -o pipefail

poetry export --only main -o bpy_speckle/requirements.txt
14 changes: 0 additions & 14 deletions local_build_modules.sh

This file was deleted.

20 changes: 20 additions & 0 deletions patch_installer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import sys
from pathlib import Path


def patch_installer(tag: str):
"""Patches the installer with the correct connector version and specklepy version"""
tag = tag.replace("\n", "")
iss_file = "speckle-sharp-ci-tools/blender.iss"
iss_path = Path(iss_file)
lines = iss_path.read_text().split("\n")
lines.insert(12, f'#define AppVersion "{tag.split("-")[0]}"')
lines.insert(13, f'#define AppInfoVersion "{tag}"')

iss_path.write_text("\n".join(lines))
print(f"Patched installer with connector v{tag}")


if __name__ == "__main__":
tag = sys.argv[1]
patch_installer(tag)
36 changes: 0 additions & 36 deletions patch_version.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import re
import sys


def patch_connector(tag):
"""Patches the connector version within the connector init file"""
bpy_file = "bpy_speckle/__init__.py"
Expand All @@ -19,48 +18,13 @@ def patch_connector(tag):
with open(bpy_file, "w") as file:
file.writelines(lines)


def patch_installer(tag):
"""Patches the installer with the correct connector version and specklepy version"""
iss_file = "speckle-sharp-ci-tools/blender.iss"

py_tag = get_specklepy_version()
with open(iss_file, "r") as file:
lines = file.readlines()
lines.insert(11, f'#define SpecklepyVersion "{py_tag}"\n')
lines.insert(12, f'#define AppVersion "{tag.split("-")[0]}"\n')
lines.insert(13, f'#define AppInfoVersion "{tag}"\n')

with open(iss_file, "w") as file:
file.writelines(lines)
print(f"Patched installer with connector v{tag} and specklepy v{py_tag}")


def get_specklepy_version():
"""Get version of specklepy to install from the pyproject.toml"""
version = "2.3.3"
with open("pyproject.toml", "r") as f:
lines = [line for line in f if line.startswith("specklepy = ")]
if not lines:
raise Exception("Could not find specklepy in pyproject.toml")
match = re.search(r"[0-9]+(\.[0-9]+)*", lines[0])
if match:
version = match[0]
return version


def main():
if len(sys.argv) < 2:
print(get_specklepy_version())
return

tag = sys.argv[1]
if not re.match(r"([0-9]+)\.([0-9]+)\.([0-9]+)", tag):
raise ValueError(f"Invalid tag provided: {tag}")

print(f"Patching version: {tag}")
patch_connector(tag.split("-")[0])
patch_installer(tag)


if __name__ == "__main__":
Expand Down
Loading

0 comments on commit fa124c2

Please sign in to comment.