mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 02:02:22 +00:00
Install Git and ifcmerge (revised)
The ZIP installer now contains a `libs/bin` folder that contains `ifcmerge`. Bonsai on `register()` adds this folder to the system `PATH` for the current Blender session. Advantage of this is that we don't have to fiddle with the registry on windows, or install files to `~/.local/bin` on Linux, it _should_ work on Darwin, updates are automatic, and we have a mechanism to ship other executables if required. (Note that ifcmerge.exe increases the size of the Windows Bonsai ZIP download by about 7MB) If Git isn't installed on Windows, the Git panel now offers to install it from the Windows Package Manager Community Repository using `winget`.
This commit is contained in:
+6
-3
@@ -229,12 +229,15 @@ endif
|
||||
# Required for Desktop icon and file association
|
||||
cp -r bonsai/libs/desktop build/bonsai/libs/
|
||||
|
||||
# folder for executable files
|
||||
mkdir -p build/bonsai/libs/bin
|
||||
|
||||
# required for three-way git merging
|
||||
ifeq ($(PLATFORM), win)
|
||||
cd build/bonsai/libs/desktop && wget https://github.com/brunopostle/ifcmerge/releases/download/2024-06-24/ifcmerge.zip
|
||||
cd build/bonsai/libs/desktop && unzip ifcmerge.zip && rm ifcmerge.zip
|
||||
cd build/bonsai/libs/bin && wget https://github.com/brunopostle/ifcmerge/releases/download/2024-06-24/ifcmerge.zip
|
||||
cd build/bonsai/libs/bin && unzip ifcmerge.zip && rm ifcmerge.zip
|
||||
else
|
||||
cd build/bonsai/libs/desktop && wget https://raw.githubusercontent.com/brunopostle/ifcmerge/main/ifcmerge
|
||||
cd build/bonsai/libs/bin && wget https://raw.githubusercontent.com/brunopostle/ifcmerge/main/ifcmerge && chmod +x ifcmerge
|
||||
endif
|
||||
|
||||
# Generate translations module for Bonsai build
|
||||
|
||||
@@ -258,6 +258,9 @@ def register():
|
||||
icons = icon_preview
|
||||
bpy.app.translations.register("bonsai", translations_dict)
|
||||
|
||||
import bonsai.tool as tool
|
||||
tool.Blender.ensure_bin_in_path()
|
||||
|
||||
|
||||
def unregister():
|
||||
global icons
|
||||
|
||||
@@ -38,7 +38,6 @@ classes = (
|
||||
operator.RefreshGit,
|
||||
operator.SwitchRevision,
|
||||
operator.InstallGit,
|
||||
operator.InstallIfcmerge,
|
||||
prop.IfcGitTag,
|
||||
prop.IfcGitListItem,
|
||||
prop.IfcGitProperties,
|
||||
|
||||
@@ -389,7 +389,9 @@ class ObjectLog(bpy.types.Operator):
|
||||
|
||||
|
||||
class InstallGit(bpy.types.Operator):
|
||||
"""Installs Git if possible"""
|
||||
"""Install Git Version Control System from the
|
||||
Windows Package Manager Community Repository,
|
||||
requires restarting Blender after installation"""
|
||||
|
||||
bl_label = "Install Git"
|
||||
bl_idname = "ifcgit.install_git"
|
||||
@@ -406,16 +408,3 @@ class InstallGit(bpy.types.Operator):
|
||||
core.install_git(tool.IfcGit, self)
|
||||
refresh()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class InstallIfcmerge(bpy.types.Operator):
|
||||
"""Installs ifcmerge if possible"""
|
||||
|
||||
bl_label = "Install ifcmerge"
|
||||
bl_idname = "ifcgit.install_ifcmerge"
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
def execute(self, context):
|
||||
core.install_ifcmerge(tool.IfcGit, self)
|
||||
refresh()
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -30,19 +30,10 @@ class IFCGIT_PT_panel(bpy.types.Panel):
|
||||
if platform.system() == "Windows":
|
||||
row.operator(
|
||||
"ifcgit.install_git",
|
||||
text="Install Git from Microsoft Store",
|
||||
text="Install Git",
|
||||
icon="PACKAGE",
|
||||
)
|
||||
return
|
||||
elif not IfcGitData.data["ifcmerge_exe"]:
|
||||
# TODO check if ifcmerge is up-to-date
|
||||
row = layout.row()
|
||||
row.label(text="ifcmerge is not installed", icon="ERROR")
|
||||
row.operator(
|
||||
"ifcgit.install_ifcmerge",
|
||||
text="Install ifcmerge",
|
||||
icon="PACKAGE",
|
||||
)
|
||||
|
||||
props = context.scene.IfcGitProperties
|
||||
|
||||
|
||||
@@ -138,12 +138,3 @@ def install_git(ifcgit: tool.IfcGit, operator: bpy.types.Operator) -> None:
|
||||
ifcgit.install_git_windows(operator=operator)
|
||||
else:
|
||||
print("install_git() not implemented")
|
||||
|
||||
|
||||
def install_ifcmerge(ifcgit: tool.IfcGit, operator: bpy.types.Operator) -> None:
|
||||
if platform.system() == "Windows":
|
||||
ifcgit.install_ifcmerge_windows(name_exe="ifcmerge.exe", operator=operator)
|
||||
elif platform.system() == "Linux":
|
||||
ifcgit.install_ifcmerge_linux(name_exe="ifcmerge", operator=operator)
|
||||
elif platform.system() == "Darwin":
|
||||
print("install_ifcmerge() not implemented")
|
||||
|
||||
@@ -21,6 +21,7 @@ import bpy
|
||||
import bmesh
|
||||
import json
|
||||
import os
|
||||
import platform
|
||||
from ifcopenshell import entity_instance
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.util.element
|
||||
@@ -430,6 +431,18 @@ class Blender(bonsai.core.tool.Blender):
|
||||
return blender_path
|
||||
return bpy.path.abspath("//") / blender_path
|
||||
|
||||
@classmethod
|
||||
def ensure_bin_in_path(cls) -> None:
|
||||
"""Check 'bin' folder is in PATH, if not add for this session"""
|
||||
bin_dir = str(Path(__file__).parent.parent.resolve() / "libs" / "bin")
|
||||
current_path = os.environ["PATH"]
|
||||
if bin_dir not in current_path:
|
||||
if platform.system() == "Windows":
|
||||
path_separator = ";"
|
||||
else:
|
||||
path_separator = ":"
|
||||
os.environ["PATH"] = current_path + path_separator + bin_dir
|
||||
|
||||
@classmethod
|
||||
def get_default_selection_keypmap(cls) -> tuple:
|
||||
"""keymap to replicate default blender selection behaviour with click and box selection"""
|
||||
|
||||
@@ -20,7 +20,6 @@ from __future__ import annotations
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import shutil
|
||||
import bpy
|
||||
import logging
|
||||
from bonsai.bim import import_ifc
|
||||
@@ -551,7 +550,7 @@ class IfcGit:
|
||||
@classmethod
|
||||
def install_git_windows(cls, operator: bpy.types.Operator) -> None:
|
||||
"""Command to install Git on Windows using winget"""
|
||||
command = ["winget", "install", "--id", "Git.Git", "-e", "--source", "msstore"]
|
||||
command = ["winget", "install", "--id", "Git.Git", "-e", "--source", "winget"]
|
||||
try:
|
||||
subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
except subprocess.CalledProcessError as e:
|
||||
@@ -559,40 +558,6 @@ class IfcGit:
|
||||
except FileNotFoundError:
|
||||
operator.report({"ERROR"}, "Winget is not available. Make sure Windows Package Manager is installed.")
|
||||
|
||||
@classmethod
|
||||
def install_ifcmerge_linux(cls, name_exe: str, operator: bpy.types.Operator) -> None:
|
||||
"""Command to install ifcmerge on Linux"""
|
||||
src_dir = os.path.join(os.path.dirname(__file__), "../libs/desktop")
|
||||
destdir = os.path.join(os.environ["HOME"], ".local", "bin")
|
||||
try:
|
||||
os.makedirs(destdir, exist_ok=True)
|
||||
shutil.copy(os.path.join(src_dir, name_exe), destdir)
|
||||
os.chmod(os.path.join(destdir, name_exe), 0o755)
|
||||
except Exception as e:
|
||||
operator.report({"ERROR"}, f"Error installing file: {e}")
|
||||
|
||||
@classmethod
|
||||
def install_ifcmerge_windows(cls, name_exe: str, operator: bpy.types.Operator) -> None:
|
||||
"""Command to install ifcmerge on Windows"""
|
||||
src_dir = os.path.join(os.path.dirname(__file__), "..\\libs\\desktop")
|
||||
destdir = os.path.join(os.environ["USERPROFILE"], "AppData", "Local", "Bonsai", "bin")
|
||||
try:
|
||||
os.makedirs(destdir, exist_ok=True)
|
||||
shutil.copy(os.path.join(src_dir, name_exe), destdir)
|
||||
except Exception as e:
|
||||
operator.report({"ERROR"}, f"Error installing file: {e}")
|
||||
|
||||
current_path = os.environ["PATH"]
|
||||
|
||||
if destdir not in current_path:
|
||||
os.environ["PATH"] = current_path + ";" + destdir
|
||||
command = f'setx PATH "%PATH%;{destdir}"'
|
||||
try:
|
||||
subprocess.run(command, check=True, shell=True)
|
||||
print(f"User %PATH% updated permanently with: {destdir}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
operator.report({"ERROR"}, f"Error permanently updating %PATH%: {e}")
|
||||
|
||||
|
||||
class IfcGitRepo:
|
||||
repo: git.Repo = None
|
||||
|
||||
Reference in New Issue
Block a user