From 7b6df389d74e2645781b4aee10368d26f2cfa4f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lassi=20S=C3=A4ike?= Date: Thu, 7 Nov 2024 20:19:57 +0200 Subject: [PATCH] Support distributing as Blender extension (WIP) --- .github/workflows/release.yml | 42 ++++++++++--- Cargo.lock | 2 +- Cargo.toml | 2 +- plumber/__init__.py | 115 +++++++++++++--------------------- plumber/addon.py | 11 +--- plumber/blender_manifest.toml | 19 ++++++ plumber/preferences.py | 4 +- plumber/tools.py | 2 +- pyproject.toml | 2 +- requirements-dev.txt | 1 + setup.py | 6 +- setup_trace.py | 6 +- 12 files changed, 114 insertions(+), 98 deletions(-) create mode 100644 plumber/blender_manifest.toml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9cd5806..0abcc19 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,6 +31,22 @@ jobs: strategy: matrix: os: [macos-13, macos-latest, windows-latest] + include: + - os: macos-13 + blender-install: | + brew update + brew install --cask blender + filename-match: "dist/*-macos_x64.zip" + - os: macos-latest + blender-install: | + brew update + brew install --cask blender + filename-match: "dist/*-macos_arm64.zip" + - os: windows-latest + blender-install: | + choco install blender --version=4.2.2 + echo "C:\Program Files\Blender Foundation\Blender 4.2\" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + filename-match: "dist/*-windows_x64.zip" fail-fast: false runs-on: ${{ matrix.os }} @@ -48,16 +64,17 @@ jobs: python -m pip install --upgrade pip pip install -r requirements-dev.txt - name: Build - run: python setup.py bdist_blender_addon - - name: Rename artifact - shell: bash - run: for filename in dist/*.zip; do mv "${filename}" "${filename%.zip}-${{ runner.os }}-${{ runner.arch }}.zip"; done; + run: python setup.py build_rust --inplace + - name: Install Blender + run: ${{ matrix.blender-install }} + - name: Package addon into Blender extension + run: blender --command extension build --source-dir plumber --output-dir dist --split-platforms - name: Release uses: softprops/action-gh-release@v2 with: draft: true fail_on_unmatched_files: true - files: dist/*.zip + files: ${{ matrix.filename-match }} build-manylinux: runs-on: ubuntu-latest @@ -78,13 +95,18 @@ jobs: python -m pip install --upgrade pip pip install -r requirements-dev.txt - name: Build - run: python setup.py bdist_blender_addon - - name: Rename artifact - shell: bash - run: for filename in dist/*.zip; do mv "${filename}" "${filename%.zip}-${{ runner.os }}-${{ runner.arch }}.zip"; done; + run: python setup.py build_rust --inplace + - name: Install Blender + run: | + sudo dnf install -y wget tar xz + wget https://download.blender.org/release/Blender4.2/blender-4.2.3-linux-x64.tar.xz + tar -xf blender-4.2.3-linux-x64.tar.xz + echo "$PWD/blender-4.2.3-linux-x64" >> $GITHUB_PATH + - name: Package addon into Blender extension + run: blender --command extension build --source-dir plumber --output-dir dist --split-platforms - name: Release uses: softprops/action-gh-release@v2 with: draft: true fail_on_unmatched_files: true - files: dist/*.zip + files: "dist/*-linux_x64.zip" diff --git a/Cargo.lock b/Cargo.lock index a591586..6379545 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -607,7 +607,7 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "plumber" -version = "1.1.1" +version = "1.1.1-extensiontest" dependencies = [ "crossbeam-channel", "float-ord", diff --git a/Cargo.toml b/Cargo.toml index 0e73845..c259060 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "plumber" -version = "1.1.1" +version = "1.1.1-extensiontest" authors = ["Lassi Säike"] edition = "2021" diff --git a/plumber/__init__.py b/plumber/__init__.py index 6f16ec9..0d25910 100644 --- a/plumber/__init__.py +++ b/plumber/__init__.py @@ -1,73 +1,48 @@ import platform import os -bl_info = { - "name": "Plumber", - "author": "Lassi Säike", - "version": (1, 1, 1), - "blender": (2, 90, 0), - "location": "File > Import -> Plumber", - "description": "Imports Source Engine assets.", - "warning": "", - "tracker_url": "https://github.com/lasa01/plumber", - "category": "Import-Export", -} - -version = bl_info["version"] -version_pre = bl_info["warning"] - -version_str = ".".join(map(str, version)) - -if version_pre != "": - version_str += f"-{version_pre}" - -# check if imported by setup.py or actually running in Blender -try: - from bpy.app import version as bpy_version -except ImportError: - bpy_version = None - -if bpy_version is not None: - is_windows = platform.system() == "Windows" - - def register(): - if is_windows: - # Check if the extension module was renamed on the last unregister, - # and either rename it back or delete it if the addon was updated with a newer extension module - ext_path = os.path.join(os.path.dirname(__file__), "plumber.pyd") - unloaded_ext_path = os.path.join( - os.path.dirname(os.path.dirname(__file__)), "plumber.pyd.unloaded" - ) - - if os.path.isfile(unloaded_ext_path): - if os.path.isfile(ext_path): - try: - os.remove(unloaded_ext_path) - except OSError: - print( - "[Plumber] [WARN] old files remaining, restart Blender to finish post-update clean up" - ) - else: - os.rename(unloaded_ext_path, ext_path) - - from . import addon - - addon.register() - - def unregister(): - from . import addon - - addon.unregister() - - if is_windows: - # Rename the extension module to allow updating the addon without restarting Blender, - # since the extension module will stay open and can't be overwritten even if the addon is unloaded - ext_path = os.path.join(os.path.dirname(__file__), "plumber.pyd") - unloaded_ext_path = os.path.join( - os.path.dirname(os.path.dirname(__file__)), "plumber.pyd.unloaded" - ) - - try: - os.rename(ext_path, unloaded_ext_path) - except OSError: - pass +is_windows = platform.system() == "Windows" + + +def register(): + if is_windows: + # Check if the extension module was renamed on the last unregister, + # and either rename it back or delete it if the addon was updated with a newer extension module + ext_path = os.path.join(os.path.dirname(__file__), "plumber.pyd") + unloaded_ext_path = os.path.join( + os.path.dirname(os.path.dirname(__file__)), "plumber.pyd.unloaded" + ) + + if os.path.isfile(unloaded_ext_path): + if os.path.isfile(ext_path): + try: + os.remove(unloaded_ext_path) + except OSError: + print( + "[Plumber] [WARN] old files remaining, restart Blender to finish post-update clean up" + ) + else: + os.rename(unloaded_ext_path, ext_path) + + from . import addon + + addon.register() + + +def unregister(): + from . import addon + + addon.unregister() + + if is_windows: + # Rename the extension module to allow updating the addon without restarting Blender, + # since the extension module will stay open and can't be overwritten even if the addon is unloaded + ext_path = os.path.join(os.path.dirname(__file__), "plumber.pyd") + unloaded_ext_path = os.path.join( + os.path.dirname(os.path.dirname(__file__)), "plumber.pyd.unloaded" + ) + + try: + os.rename(ext_path, unloaded_ext_path) + except OSError: + pass diff --git a/plumber/addon.py b/plumber/addon.py index 1652386..a534ef3 100644 --- a/plumber/addon.py +++ b/plumber/addon.py @@ -1,7 +1,7 @@ import bpy from bpy.types import Context, Menu -from . import preferences, importer, tools, benchmark, version_str +from . import preferences, importer, tools, benchmark from .importer import ImportMdl, ImportVmf, ImportVmt, ImportVtf from .tools import IMPORT_MT_plumber_browse @@ -32,15 +32,6 @@ def menu_func_import(self: Menu, context: Context): def register(): - from . import plumber - - rust_version = plumber.version() - if rust_version != version_str: - raise Exception( - f"Native code version {rust_version} does not match Python code version {version_str}. " - + "Please restart Blender and reinstall the addon." - ) - preferences.register() importer.register() tools.register() diff --git a/plumber/blender_manifest.toml b/plumber/blender_manifest.toml new file mode 100644 index 0000000..170cc59 --- /dev/null +++ b/plumber/blender_manifest.toml @@ -0,0 +1,19 @@ +schema_version = "1.0.0" + +id = "plumber" +version = "1.1.1-extensiontest" +name = "Plumber" +tagline = "Imports Source 1 engine maps, models, materials and textures" +maintainer = "Lassi Säike " +type = "add-on" +website = "https://github.com/lasa01/Plumber" +tags = ["Import-Export"] +blender_version_min = "4.2.0" +license = ["SPDX:GPL-3.0-or-later"] +platforms = ["windows-x64", "macos-x64", "macos-arm64", "linux-x64"] + +[permissions] +files = "Import/extract assets from/to disk, detect installed games" + +[build] +paths_exclude_pattern = ["__pycache__/", "/.git/", "/*.zip", "/*.pyi"] diff --git a/plumber/preferences.py b/plumber/preferences.py index 0c27594..98a6779 100644 --- a/plumber/preferences.py +++ b/plumber/preferences.py @@ -377,7 +377,7 @@ class AddonPreferences(AddonPreferences): ) def update_enable_file_browser_panel(self, context: Context): - from plumber.tools import GameFileBrowserPanel + from .tools import GameFileBrowserPanel if not self.enable_file_browser_panel: bpy.utils.unregister_class(GameFileBrowserPanel) @@ -392,7 +392,7 @@ def update_enable_file_browser_panel(self, context: Context): ) def update_enable_benchmarking(self, context: Context): - from plumber.benchmark import BenchmarkVmf + from .benchmark import BenchmarkVmf if not self.enable_benchmarking: bpy.utils.unregister_class(BenchmarkVmf) diff --git a/plumber/tools.py b/plumber/tools.py index 2e455a8..c1200b6 100644 --- a/plumber/tools.py +++ b/plumber/tools.py @@ -12,7 +12,7 @@ ) import bpy -from plumber.importer import ( +from .importer import ( DisableCommonPanel, GameFileImporterOperator, GameFileImporterOperatorProps, diff --git a/pyproject.toml b/pyproject.toml index 3164f1b..ff12d65 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,2 +1,2 @@ [build-system] -requires = ["setuptools", "setuptools-rust", "blender.distutils"] +requires = ["setuptools", "setuptools-rust", "blender.distutils", "toml"] diff --git a/requirements-dev.txt b/requirements-dev.txt index af49070..bd0950d 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -3,3 +3,4 @@ setuptools setuptools-rust blender.distutils black +toml diff --git a/setup.py b/setup.py index 17eb251..8f3c15e 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,11 @@ from setuptools import setup, find_packages, sic from setuptools_rust import Binding, RustExtension +import toml -from plumber import version_str +with open("plumber/blender_manifest.toml", "r") as f: + manifest = toml.load(f) + +version_str = manifest["version"] rust_extension = RustExtension( "plumber.plumber", diff --git a/setup_trace.py b/setup_trace.py index 07738fb..86c93a3 100644 --- a/setup_trace.py +++ b/setup_trace.py @@ -1,7 +1,11 @@ from setuptools import setup, find_packages, sic from setuptools_rust import Binding, RustExtension +import toml -from plumber import version_str +with open("plumber/blender_manifest.toml", "r") as f: + manifest = toml.load(f) + +version_str = manifest["version"] rust_extension = RustExtension( "plumber.plumber",