SVN: UX improvements #136

Merged
Demeter Dzadik merged 15 commits from Mets/blender-studio-pipeline:svn_ux_improvements into main 2023-08-01 15:39:18 +02:00
7 changed files with 61 additions and 8 deletions
Showing only changes of commit cad91a94a0 - Show all commits

View File

@ -19,6 +19,12 @@ from .threaded.background_process import Processes
class SVN_addon_preferences(AddonPreferences): class SVN_addon_preferences(AddonPreferences):
bl_idname = __package__ bl_idname = __package__
is_svn_installed: BoolProperty(
name="Is SVN Installed",
description="Whether the `svn` command works at all in the user's command line. If not, user needs to install SVN",
default=False
)
repositories: CollectionProperty(type=SVN_repository) repositories: CollectionProperty(type=SVN_repository)
def init_repo(self, context, repo_path: Path or str): def init_repo(self, context, repo_path: Path or str):

View File

@ -27,12 +27,14 @@ class SVN_scene_properties(PropertyGroup):
description="Absolute directory path of the SVN repository's root in the file system", description="Absolute directory path of the SVN repository's root in the file system",
) )
def get_repo(self, context): def get_repo(self, context) -> Optional['SVN_repository']:
"""Return the current repository. """Return the current repository.
Depending on preferences, this is either the repo the current .blend file is in, Depending on preferences, this is either the repo the current .blend file is in,
or whatever repo is selected in the preferences UI. or whatever repo is selected in the preferences UI.
""" """
prefs = get_addon_prefs(context) prefs = get_addon_prefs(context)
if not prefs.is_svn_installed:
return
if prefs.active_repo_mode == 'CURRENT_BLEND': if prefs.active_repo_mode == 'CURRENT_BLEND':
return self.get_scene_repo(context) return self.get_scene_repo(context)
@ -40,15 +42,20 @@ class SVN_scene_properties(PropertyGroup):
return prefs.active_repo return prefs.active_repo
def get_scene_repo(self, context) -> Optional['SVN_repository']: def get_scene_repo(self, context) -> Optional['SVN_repository']:
"""Return the repository of the current file, even if the add-on is
configured to another repository.
"""
prefs = get_addon_prefs(context)
if not prefs.is_svn_installed:
return
if not self.svn_url or not self.svn_directory: if not self.svn_url or not self.svn_directory:
return return
prefs = get_addon_prefs(context)
for repo in prefs.repositories: for repo in prefs.repositories:
if (repo.url == self.svn_url) and (Path(repo.directory) == Path(self.svn_directory)): if (repo.url == self.svn_url) and (Path(repo.directory) == Path(self.svn_directory)):
return repo return repo
registry = [ registry = [
SVN_scene_properties, SVN_scene_properties,
] ]

View File

@ -4,7 +4,6 @@
import subprocess import subprocess
from typing import List from typing import List
def get_credential_commands(context) -> List[str]: def get_credential_commands(context) -> List[str]:
repo = context.scene.svn.get_repo(context) repo = context.scene.svn.get_repo(context)
assert (repo.is_cred_entered), "No username or password entered for this repository. The UI shouldn't have allowed you to get into a state where you can press an SVN operation button without having your credentials entered, so this is a bug!" assert (repo.is_cred_entered), "No username or password entered for this repository. The UI shouldn't have allowed you to get into a state where you can press an SVN operation button without having your credentials entered, so this is a bug!"
@ -29,6 +28,9 @@ def execute_svn_command(context, command: List[str], *, ignore_errors=False, pri
SVN root. SVN root.
""" """
repo = context.scene.svn.get_repo(context) repo = context.scene.svn.get_repo(context)
if "svn" not in command:
command.insert(0, "svn")
if use_cred: if use_cred:
command += get_credential_commands(context) command += get_credential_commands(context)
@ -46,3 +48,7 @@ def execute_svn_command(context, command: List[str], *, ignore_errors=False, pri
print(f"Command returned error: {command}") print(f"Command returned error: {command}")
print(err_msg) print(err_msg)
raise error raise error
def check_svn_installed():
code, message = subprocess.getstatusoutput('svn')
return code != 127

View File

@ -4,7 +4,7 @@
from ..svn_info import get_svn_info from ..svn_info import get_svn_info
from ..util import get_addon_prefs from ..util import get_addon_prefs
from .. import constants from .. import constants
from .execute_subprocess import execute_svn_command from .execute_subprocess import execute_svn_command, check_svn_installed
from .background_process import BackgroundProcess, Processes from .background_process import BackgroundProcess, Processes
from bpy.types import Operator from bpy.types import Operator
from bpy.props import StringProperty from bpy.props import StringProperty
@ -64,11 +64,18 @@ def ensure_svn_of_current_file(_scene=None):
""" """
context = bpy.context context = bpy.context
prefs = get_addon_prefs(context)
prefs.is_svn_installed = check_svn_installed()
if not prefs.is_svn_installed:
return
scene_svn = context.scene.svn scene_svn = context.scene.svn
prefs = get_addon_prefs(context)
prefs.sync_repo_info_file() prefs.sync_repo_info_file()
if prefs.active_repo_idx == -1 and len(prefs.repositories) > 0:
prefs.active_repo_idx = 0
repo = prefs.active_repo repo = prefs.active_repo
if repo and repo.is_cred_entered and repo.authenticated: if repo and repo.is_cred_entered and repo.authenticated:
status = Processes.get('Status') status = Processes.get('Status')

View File

@ -149,8 +149,10 @@ class SVN_UL_file_list(UIList):
row.prop(self, 'show_file_paths', text="", row.prop(self, 'show_file_paths', text="",
toggle=True, icon="FILE_FOLDER") toggle=True, icon="FILE_FOLDER")
row.prop(context.scene.svn.get_repo(context),
'file_search_filter', text="") repo = context.scene.svn.get_repo(context)
if repo:
row.prop(repo, 'file_search_filter', text="")
def draw_process_info(context, layout): def draw_process_info(context, layout):

View File

@ -90,6 +90,9 @@ class SVN_UL_log(UIList):
def is_log_useful(context): def is_log_useful(context):
repo = context.scene.svn.get_repo(context) repo = context.scene.svn.get_repo(context)
if not repo:
return False
if len(repo.log) == 0 or len(repo.external_files) == 0: if len(repo.log) == 0 or len(repo.external_files) == 0:
return False return False
active_file = repo.active_file active_file = repo.active_file

View File

@ -99,12 +99,34 @@ class SVN_MT_add_repo(Menu):
def draw_prefs(self, context): def draw_prefs(self, context):
if not self.is_svn_installed:
draw_prefs_no_svn(self, context)
return
if self.checkout_mode: if self.checkout_mode:
draw_prefs_checkout(self, context) draw_prefs_checkout(self, context)
else: else:
draw_prefs_repos(self, context) draw_prefs_repos(self, context)
def draw_prefs_no_svn(self, context):
terminal, url = "terminal", "https://subversion.apache.org/packages.html"
system = platform.system()
if system == "Windows":
terminal = "command line (cmd.exe)"
url = "https://subversion.apache.org/packages.html#windows"
elif system == "Darwin":
terminal = "Mac terminal"
url = "https://subversion.apache.org/packages.html#osx"
layout = self.layout
col = layout.column()
col.alert=True
col.label(text="Please ensure that Subversion (aka. SVN) is installed on your system.")
col.label(text=f"Typing `svn` into the {terminal} should yield a result.")
layout.operator("wm.url_open", icon='URL', text='Open Subversion Distribution Page').url=url
def draw_prefs_checkout(self, context): def draw_prefs_checkout(self, context):
def get_terminal_howto(): def get_terminal_howto():
msg_windows = "If you don't, cancel this operation and toggle it using Window->Toggle System Console." msg_windows = "If you don't, cancel this operation and toggle it using Window->Toggle System Console."