From 1145b73b58e39c9dca71af7f6139f619ea88b5e3 Mon Sep 17 00:00:00 2001 From: Pullusb Date: Sun, 23 Jan 2022 16:27:30 +0100 Subject: [PATCH] Add git updater (beta) 1.9.3 - feat: Add an update button at bottom of preferences if addon is a cloned repository --- CHANGELOG.md | 4 +++ OP_git_update.py | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ __init__.py | 32 ++++++++++++++++-- 3 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 OP_git_update.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 44741a6..609bb16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +1.9.3 + +- feat: Add an update button at bottom of preferences if addon is a cloned repository + 1.9.2 - feat: Palette linker has a name exclusion list in preferences diff --git a/OP_git_update.py b/OP_git_update.py new file mode 100644 index 0000000..fd91730 --- /dev/null +++ b/OP_git_update.py @@ -0,0 +1,84 @@ +import bpy +import shutil +import subprocess +from pathlib import Path +import os +from os.path import basename +# import re + +from .utils import show_message_box + +"""## not used for now +class GPTB_OT_check_git(bpy.types.Operator): + '''check if git is in path''' + bl_idname = "gptb.check_git" + bl_label = "Check if git is in system path" + bl_options = {'REGISTER', 'INTERNAL'} + + def invoke(self, context, event): + self.ok = shutil.which('git') + return context.window_manager.invoke_props_dialog(self, width=250) + + def draw(self, context): + layout = self.layout + if self.ok: + layout.label(text='Ok ! git is in system PATH', icon='INFO') + else: + layout.label(text='Git is not in system PATH', icon='CANCEL') + layout.operator('wm.url_open', text='Download And Install From Here', icon='URL').url = 'https://git-scm.com/download/' +""" + + +def git_update(folder: str) -> str: + ''' Try to git pull fast foward only in passed folder and return console output''' + os.chdir(folder) + name = basename(folder) + print(f'Pulling in {name}') + pull_cmd = ['git', 'pull', '--ff-only'] # git pull --ff-only + pull_ret = subprocess.check_output(pull_cmd) + return pull_ret.decode() + + +class GPTB_OT_git_pull(bpy.types.Operator): + """Update addon with git pull if possible""" + bl_idname = "gptb.git_pull" + bl_label = "Gptoolbox Git Pull Update" + bl_options = {'REGISTER', 'INTERNAL'} + + # def invoke(self, context, event): + # return self.execute(context) + + # def draw(self, context): + + def execute(self, context): + if not shutil.which('git'): + self.report({'ERROR'}, 'Git not found in path, if just installed, restart Blender/Computer') + return {'CANCELLED'} + + ret = git_update(Path(__file__).parent.as_posix()) + + if 'Already up to date' in ret: + self.report({'INFO'}, 'Already up to date') + show_message_box(ret.rstrip('\n').split('\n')) + elif 'Fast-forward' in ret and 'Updating' in ret: + self.report({'INFO'}, 'Updated ! Restart Blender') + show_message_box(['Updated! Restart Blender.'] + ret.rstrip('\n').split('\n')) + + return {'FINISHED'} + +classes = ( +# GPTB_OT_check_git, +GPTB_OT_git_pull, +) + +def register(): + if bpy.app.background: + return + for cl in classes: + bpy.utils.register_class(cl) + +def unregister(): + if bpy.app.background: + return + for cl in reversed(classes): + bpy.utils.unregister_class(cl) diff --git a/__init__.py b/__init__.py index fb5bc0d..de96b3d 100755 --- a/__init__.py +++ b/__init__.py @@ -15,7 +15,7 @@ bl_info = { "name": "GP toolbox", "description": "Tool set for Grease Pencil in animation production", "author": "Samuel Bernou, Christophe Seux", -"version": (1, 9, 2), +"version": (1, 9, 3), "blender": (2, 91, 0), "location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties", "warning": "", @@ -27,6 +27,8 @@ bl_info = { # from . import addon_updater_ops # from .utils import * +from pathlib import Path +from shutil import which from .utils import get_addon_prefs, draw_kmi # from .functions import * @@ -54,6 +56,7 @@ from . import OP_layer_manager from . import OP_layer_picker from . import OP_layer_nav from . import OP_material_picker +from . import OP_git_update from . import OP_eraser_brush from . import TOOL_eraser_brush from . import handler_draw_cam @@ -141,6 +144,10 @@ class GPTB_prefs(bpy.types.AddonPreferences): #--# PROJECT PREFERENCES #--# # subtype (string) – Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILE_NAME', 'BYTE_STRING', 'PASSWORD', 'NONE']. + + # update variables + is_git_repo : BoolProperty(default=False) + has_git : BoolProperty(default=False) ## fps @@ -472,6 +479,17 @@ class GPTB_prefs(bpy.types.AddonPreferences): # row.prop(self, 'nav_interval') # Do not expose refresh rate for now, not usefull to user... box.prop(self, 'use_precise_eraser') + + if self.is_git_repo: + box = layout.box() + box.label(text='Addon Update') + if self.is_git_repo and self.has_git: + box.operator('gptb.git_pull', text='Check / Get Last Update', icon='PLUGIN') + else: + box.label(text='Toolbox can be updated using git') + row = box.row() + row.operator('wm.url_open', text='Download and install git here', icon='URL').url = 'https://git-scm.com/download/' + row.label(text='then restart blender') if self.pref_tabs == 'KEYS': # layout.label(text='Shortcuts :') @@ -702,6 +720,7 @@ def register(): OP_layer_manager.register() OP_eraser_brush.register() OP_material_picker.register() + OP_git_update.register() OP_layer_picker.register() OP_layer_nav.register() TOOL_eraser_brush.register() @@ -713,10 +732,16 @@ def register(): set_env_properties() ## add handler (if option is on) - if get_addon_prefs().use_relative_remap_on_save: + prefs = get_addon_prefs() + if prefs.use_relative_remap_on_save: if not 'remap_relative' in [hand.__name__ for hand in bpy.app.handlers.save_pre]: bpy.app.handlers.save_pre.append(remap_relative) - + + prefs.is_git_repo = (Path(__file__).parent / '.git').exists() + prefs.has_git = bool(which('git')) + + ## change a variable in prefs if a '.git is detected' + def unregister(): # remove handler @@ -732,6 +757,7 @@ def unregister(): TOOL_eraser_brush.unregister() OP_layer_nav.unregister() OP_layer_picker.unregister() + OP_git_update.unregister() OP_material_picker.unregister() OP_eraser_brush.unregister() OP_layer_manager.unregister()