From 7accb372cd65df831233d379b861a3da84e7f0d9 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 15 Aug 2022 14:00:11 +0200 Subject: [PATCH 01/26] remove tray publisher from experimental tools --- openpype/modules/traypublish_action.py | 15 ++------------- openpype/tools/experimental_tools/tools_def.py | 5 ----- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/openpype/modules/traypublish_action.py b/openpype/modules/traypublish_action.py index 39163b8eb8..1038bac47b 100644 --- a/openpype/modules/traypublish_action.py +++ b/openpype/modules/traypublish_action.py @@ -2,7 +2,7 @@ import os from openpype.lib import get_openpype_execute_args from openpype.lib.execute import run_detached_process from openpype.modules import OpenPypeModule -from openpype_interfaces import ITrayAction +from openpype.modules.interfaces import ITrayAction class TrayPublishAction(OpenPypeModule, ITrayAction): @@ -21,20 +21,9 @@ class TrayPublishAction(OpenPypeModule, ITrayAction): "publish" ) ] - self._experimental_tools = None def tray_init(self): - from openpype.tools.experimental_tools import ExperimentalTools - - self._experimental_tools = ExperimentalTools() - - def tray_menu(self, *args, **kwargs): - super(TrayPublishAction, self).tray_menu(*args, **kwargs) - traypublisher = self._experimental_tools.get("traypublisher") - visible = False - if traypublisher and traypublisher.enabled: - visible = True - self._action_item.setVisible(visible) + return def on_action_trigger(self): self.run_traypublisher() diff --git a/openpype/tools/experimental_tools/tools_def.py b/openpype/tools/experimental_tools/tools_def.py index fa2971dc1d..38a49e8ab5 100644 --- a/openpype/tools/experimental_tools/tools_def.py +++ b/openpype/tools/experimental_tools/tools_def.py @@ -89,11 +89,6 @@ class ExperimentalTools: "New publisher", "Combined creation and publishing into one tool.", self._show_publisher - ), - ExperimentalTool( - "traypublisher", - "New Standalone Publisher", - "Standalone publisher using new publisher. Requires restart" ) ] From 8e6dcbc048be40e038e3406fd3b3ae22e1631c9a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 15 Aug 2022 14:00:20 +0200 Subject: [PATCH 02/26] change label of tray publisher action --- openpype/modules/traypublish_action.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/traypublish_action.py b/openpype/modules/traypublish_action.py index 1038bac47b..29aea07210 100644 --- a/openpype/modules/traypublish_action.py +++ b/openpype/modules/traypublish_action.py @@ -6,7 +6,7 @@ from openpype.modules.interfaces import ITrayAction class TrayPublishAction(OpenPypeModule, ITrayAction): - label = "New Publish (beta)" + label = "Tray Publish" name = "traypublish_tool" def initialize(self, modules_settings): From ed6cadb22b331f985348e5ed22168cea5ebb24d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Wed, 12 Oct 2022 18:25:14 +0200 Subject: [PATCH 03/26] :construction: remove staging from version logic --- igniter/bootstrap_repos.py | 219 +++++-------------------------------- igniter/tools.py | 11 +- 2 files changed, 30 insertions(+), 200 deletions(-) diff --git a/igniter/bootstrap_repos.py b/igniter/bootstrap_repos.py index ccc9d4ac52..bbb3dd506c 100644 --- a/igniter/bootstrap_repos.py +++ b/igniter/bootstrap_repos.py @@ -61,7 +61,6 @@ class OpenPypeVersion(semver.VersionInfo): path (str): path to OpenPype """ - staging = False path = None _VERSION_REGEX = re.compile(r"(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)(?:-(?P(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?") # noqa: E501 _installed_version = None @@ -82,12 +81,10 @@ class OpenPypeVersion(semver.VersionInfo): build (str): an optional build string version (str): if set, it will be parsed and will override parameters like `major`, `minor` and so on. - staging (bool): set to True if version is staging. path (Path): path to version location. """ self.path = None - self.staging = False if "version" in kwargs.keys(): if not kwargs.get("version"): @@ -112,29 +109,8 @@ class OpenPypeVersion(semver.VersionInfo): if "path" in kwargs.keys(): kwargs.pop("path") - if kwargs.get("staging"): - self.staging = kwargs.get("staging", False) - kwargs.pop("staging") - - if "staging" in kwargs.keys(): - kwargs.pop("staging") - - if self.staging: - if kwargs.get("build"): - if "staging" not in kwargs.get("build"): - kwargs["build"] = f"{kwargs.get('build')}-staging" - else: - kwargs["build"] = "staging" - - if kwargs.get("build") and "staging" in kwargs.get("build", ""): - self.staging = True - super().__init__(*args, **kwargs) - def __eq__(self, other): - result = super().__eq__(other) - return bool(result and self.staging == other.staging) - def __repr__(self): return f"<{self.__class__.__name__}: {str(self)} - path={self.path}>" @@ -149,43 +125,11 @@ class OpenPypeVersion(semver.VersionInfo): return True if self.finalize_version() == other.finalize_version() and \ - self.prerelease == other.prerelease and \ - self.is_staging() and not other.is_staging(): + self.prerelease == other.prerelease: return True return result - def set_staging(self) -> OpenPypeVersion: - """Set version as staging and return it. - - This will preserve current one. - - Returns: - OpenPypeVersion: Set as staging. - - """ - if self.staging: - return self - return self.replace(parts={"build": f"{self.build}-staging"}) - - def set_production(self) -> OpenPypeVersion: - """Set version as production and return it. - - This will preserve current one. - - Returns: - OpenPypeVersion: Set as production. - - """ - if not self.staging: - return self - return self.replace( - parts={"build": self.build.replace("-staging", "")}) - - def is_staging(self) -> bool: - """Test if current version is staging one.""" - return self.staging - def get_main_version(self) -> str: """Return main version component. @@ -215,8 +159,6 @@ class OpenPypeVersion(semver.VersionInfo): if not m: return None version = OpenPypeVersion.parse(string[m.start():m.end()]) - if "staging" in string[m.start():m.end()]: - version.staging = True return version @classmethod @@ -226,8 +168,6 @@ class OpenPypeVersion(semver.VersionInfo): openpype_version = cls(major=v.major, minor=v.minor, patch=v.patch, prerelease=v.prerelease, build=v.build) - if v.build and "staging" in v.build: - openpype_version.staging = True return openpype_version def __hash__(self): @@ -379,80 +319,28 @@ class OpenPypeVersion(semver.VersionInfo): return False @classmethod - def get_local_versions( - cls, production: bool = None, - staging: bool = None - ) -> List: + def get_local_versions(cls) -> List: """Get all versions available on this machine. - Arguments give ability to specify if filtering is needed. If both - arguments are set to None all found versions are returned. - - Args: - production (bool): Return production versions. - staging (bool): Return staging versions. - Returns: list: of compatible versions available on the machine. """ - # Return all local versions if arguments are set to None - if production is None and staging is None: - production = True - staging = True - - elif production is None and not staging: - production = True - - elif staging is None and not production: - staging = True - - # Just return empty output if both are disabled - if not production and not staging: - return [] - # DEPRECATED: backwards compatible way to look for versions in root dir_to_search = Path(user_data_dir("openpype", "pypeclub")) versions = OpenPypeVersion.get_versions_from_directory(dir_to_search) - filtered_versions = [] - for version in versions: - if version.is_staging(): - if staging: - filtered_versions.append(version) - elif production: - filtered_versions.append(version) - return list(sorted(set(filtered_versions))) + return list(sorted(set(versions))) @classmethod - def get_remote_versions( - cls, production: bool = None, - staging: bool = None - ) -> List: + def get_remote_versions(cls) -> List: """Get all versions available in OpenPype Path. - Arguments give ability to specify if filtering is needed. If both - arguments are set to None all found versions are returned. - - Args: - production (bool): Return production versions. - staging (bool): Return staging versions. + Returns: + list of OpenPypeVersions: Versions found in OpenPype path. """ # Return all local versions if arguments are set to None - if production is None and staging is None: - production = True - staging = True - - elif production is None and not staging: - production = True - - elif staging is None and not production: - staging = True - - # Just return empty output if both are disabled - if not production and not staging: - return [] dir_to_search = None if cls.openpype_path_is_accessible(): @@ -473,14 +361,7 @@ class OpenPypeVersion(semver.VersionInfo): versions = cls.get_versions_from_directory(dir_to_search) - filtered_versions = [] - for version in versions: - if version.is_staging(): - if staging: - filtered_versions.append(version) - elif production: - filtered_versions.append(version) - return list(sorted(set(filtered_versions))) + return list(sorted(set(versions))) @staticmethod def get_versions_from_directory( @@ -559,7 +440,6 @@ class OpenPypeVersion(semver.VersionInfo): @staticmethod def get_latest_version( - staging: bool = False, local: bool = None, remote: bool = None ) -> Union[OpenPypeVersion, None]: @@ -577,7 +457,6 @@ class OpenPypeVersion(semver.VersionInfo): 'False' in that case only build version can be used. Args: - staging (bool, optional): List staging versions if True. local (bool, optional): List local versions if True. remote (bool, optional): List remote versions if True. @@ -596,28 +475,15 @@ class OpenPypeVersion(semver.VersionInfo): remote = True installed_version = OpenPypeVersion.get_installed_version() - local_versions = [] - remote_versions = [] - if local: - local_versions = OpenPypeVersion.get_local_versions( - staging=staging - ) - if remote: - remote_versions = OpenPypeVersion.get_remote_versions( - staging=staging - ) - all_versions = local_versions + remote_versions - if not staging: - all_versions.append(installed_version) - - if not all_versions: - return None + local_versions = OpenPypeVersion.get_local_versions() if local else [] + remote_versions = OpenPypeVersion.get_remote_versions() if remote else [] # noqa: E501 + all_versions = local_versions + remote_versions + installed_version all_versions.sort() return all_versions[-1] @classmethod - def get_expected_studio_version(cls, staging=False, global_settings=None): + def get_expected_studio_version(cls, global_settings=None): """Expected OpenPype version that should be used at the moment. If version is not defined in settings the latest found version is @@ -626,13 +492,12 @@ class OpenPypeVersion(semver.VersionInfo): Using precached global settings is needed for usage inside OpenPype. Args: - staging (bool): Staging version or production version. global_settings (dict): Optional precached global settings. Returns: OpenPypeVersion: Version that should be used. """ - result = get_expected_studio_version_str(staging, global_settings) + result = get_expected_studio_version_str(global_settings) if not result: return None return OpenPypeVersion(version=result) @@ -1121,14 +986,12 @@ class BootstrapRepos: @staticmethod def find_openpype_version( - version: Union[str, OpenPypeVersion], - staging: bool + version: Union[str, OpenPypeVersion] ) -> Union[OpenPypeVersion, None]: """Find location of specified OpenPype version. Args: version (Union[str, OpenPypeVersion): Version to find. - staging (bool): Filter staging versions. Returns: requested OpenPypeVersion. @@ -1141,9 +1004,7 @@ class BootstrapRepos: if installed_version == version: return installed_version - local_versions = OpenPypeVersion.get_local_versions( - staging=staging, production=not staging - ) + local_versions = OpenPypeVersion.get_local_versions() zip_version = None for local_version in local_versions: if local_version == version: @@ -1155,37 +1016,25 @@ class BootstrapRepos: if zip_version is not None: return zip_version - remote_versions = OpenPypeVersion.get_remote_versions( - staging=staging, production=not staging - ) - for remote_version in remote_versions: - if remote_version == version: - return remote_version - return None + remote_versions = OpenPypeVersion.get_remote_versions() + return next( + ( + remote_version for remote_version in remote_versions + if remote_version == version + ), None) @staticmethod - def find_latest_openpype_version( - staging: bool - ) -> Union[OpenPypeVersion, None]: + def find_latest_openpype_version() -> Union[OpenPypeVersion, None]: """Find the latest available OpenPype version in all location. - Args: - staging (bool): True to look for staging versions. - Returns: Latest OpenPype version on None if nothing was found. """ installed_version = OpenPypeVersion.get_installed_version() - local_versions = OpenPypeVersion.get_local_versions( - staging=staging - ) - remote_versions = OpenPypeVersion.get_remote_versions( - staging=staging - ) - all_versions = local_versions + remote_versions - if not staging: - all_versions.append(installed_version) + local_versions = OpenPypeVersion.get_local_versions() + remote_versions = OpenPypeVersion.get_remote_versions() + all_versions = local_versions + remote_versions + installed_version if not all_versions: return None @@ -1205,7 +1054,6 @@ class BootstrapRepos: def find_openpype( self, openpype_path: Union[Path, str] = None, - staging: bool = False, include_zips: bool = False ) -> Union[List[OpenPypeVersion], None]: """Get ordered dict of detected OpenPype version. @@ -1219,8 +1067,6 @@ class BootstrapRepos: Args: openpype_path (Path or str, optional): Try to find OpenPype on the given path or url. - staging (bool, optional): Filter only staging version, skip them - otherwise. include_zips (bool, optional): If set True it will try to find OpenPype in zip files in given directory. @@ -1268,7 +1114,7 @@ class BootstrapRepos: for dir_to_search in dirs_to_search: try: openpype_versions += self.get_openpype_versions( - dir_to_search, staging) + dir_to_search) except ValueError: # location is invalid, skip it pass @@ -1633,15 +1479,11 @@ class BootstrapRepos: return False return True - def get_openpype_versions( - self, - openpype_dir: Path, - staging: bool = False) -> list: + def get_openpype_versions(self, openpype_dir: Path) -> list: """Get all detected OpenPype versions in directory. Args: openpype_dir (Path): Directory to scan. - staging (bool, optional): Find staging versions if True. Returns: list of OpenPypeVersion @@ -1659,8 +1501,7 @@ class BootstrapRepos: for item in openpype_dir.iterdir(): # if the item is directory with major.minor version, dive deeper if item.is_dir() and re.match(r"^\d+\.\d+$", item.name): - _versions = self.get_openpype_versions( - item, staging=staging) + _versions = self.get_openpype_versions(item) if _versions: openpype_versions += _versions @@ -1683,11 +1524,7 @@ class BootstrapRepos: continue detected_version.path = item - if staging and detected_version.is_staging(): - openpype_versions.append(detected_version) - - if not staging and not detected_version.is_staging(): - openpype_versions.append(detected_version) + openpype_versions.append(detected_version) return sorted(openpype_versions) diff --git a/igniter/tools.py b/igniter/tools.py index a9d592acf0..5c2c64a14b 100644 --- a/igniter/tools.py +++ b/igniter/tools.py @@ -184,11 +184,7 @@ def get_openpype_path_from_settings(settings: dict) -> Union[str, None]: if paths and isinstance(paths, str): paths = [paths] - # Loop over paths and return only existing - for path in paths: - if os.path.exists(path): - return path - return None + return next((path for path in paths if os.path.exists(path)), None) def get_expected_studio_version_str( @@ -206,10 +202,7 @@ def get_expected_studio_version_str( mongo_url = os.environ.get("OPENPYPE_MONGO") if global_settings is None: global_settings = get_openpype_global_settings(mongo_url) - if staging: - key = "staging_version" - else: - key = "production_version" + key = "staging_version" if staging else "production_version" return global_settings.get(key) or "" From 84b3bc3db2bd2a0f31af991b98e3c3a022e8e4e4 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 13 Oct 2022 11:34:57 +0200 Subject: [PATCH 04/26] :recycle: remove staging logic --- igniter/bootstrap_repos.py | 18 ++---- openpype/cli.py | 17 +++-- openpype/lib/openpype_version.py | 8 +++ start.py | 104 +++++++++++-------------------- 4 files changed, 54 insertions(+), 93 deletions(-) diff --git a/igniter/bootstrap_repos.py b/igniter/bootstrap_repos.py index bbb3dd506c..6d583469ef 100644 --- a/igniter/bootstrap_repos.py +++ b/igniter/bootstrap_repos.py @@ -57,7 +57,6 @@ class OpenPypeVersion(semver.VersionInfo): """Class for storing information about OpenPype version. Attributes: - staging (bool): True if it is staging version path (str): path to OpenPype """ @@ -161,15 +160,6 @@ class OpenPypeVersion(semver.VersionInfo): version = OpenPypeVersion.parse(string[m.start():m.end()]) return version - @classmethod - def parse(cls, version): - """Extends parse to handle ta handle staging variant.""" - v = super().parse(version) - openpype_version = cls(major=v.major, minor=v.minor, - patch=v.patch, prerelease=v.prerelease, - build=v.build) - return openpype_version - def __hash__(self): return hash(self.path) if self.path else hash(str(self)) @@ -448,7 +438,6 @@ class OpenPypeVersion(semver.VersionInfo): The version does not contain information about path and source. This is utility version to get the latest version from all found. - Build version is not listed if staging is enabled. Arguments 'local' and 'remote' define if local and remote repository versions are used. All versions are used if both are not set (or set @@ -483,7 +472,7 @@ class OpenPypeVersion(semver.VersionInfo): return all_versions[-1] @classmethod - def get_expected_studio_version(cls, global_settings=None): + def get_expected_studio_version(cls, staging=False, global_settings=None): """Expected OpenPype version that should be used at the moment. If version is not defined in settings the latest found version is @@ -492,12 +481,13 @@ class OpenPypeVersion(semver.VersionInfo): Using precached global settings is needed for usage inside OpenPype. Args: + staging (bool): Staging version or production version. global_settings (dict): Optional precached global settings. Returns: OpenPypeVersion: Version that should be used. """ - result = get_expected_studio_version_str(global_settings) + result = get_expected_studio_version_str(staging, global_settings) if not result: return None return OpenPypeVersion(version=result) @@ -567,7 +557,7 @@ class BootstrapRepos: """Get path for specific version in list of OpenPype versions. Args: - version (str): Version string to look for (1.2.4+staging) + version (str): Version string to look for (1.2.4-nightly.1+test) version_list (list of OpenPypeVersion): list of version to search. Returns: diff --git a/openpype/cli.py b/openpype/cli.py index 398d1a94c0..e3eacad8aa 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -16,14 +16,13 @@ from .pype_commands import PypeCommands @click.option("--use-staging", is_flag=True, expose_value=False, help="use staging variants") @click.option("--list-versions", is_flag=True, expose_value=False, - help=("list all detected versions. Use With `--use-staging " - "to list staging versions.")) + help="list all detected versions.") @click.option("--validate-version", expose_value=False, help="validate given version integrity") @click.option("--debug", is_flag=True, expose_value=False, - help=("Enable debug")) + help="Enable debug") @click.option("--verbose", expose_value=False, - help=("Change OpenPype log level (debug - critical or 0-50)")) + help="Change OpenPype log level (debug - critical or 0-50)") def main(ctx): """Pype is main command serving as entry point to pipeline system. @@ -416,20 +415,18 @@ def unpack_project(zipfile, root): @main.command() def interactive(): - """Interative (Python like) console. + """Interactive (Python like) console. - Helpfull command not only for development to directly work with python + Helpful command not only for development to directly work with python interpreter. Warning: - Executable 'openpype_gui' on windows won't work. + Executable 'openpype_gui' on Windows won't work. """ from openpype.version import __version__ - banner = "OpenPype {}\nPython {} on {}".format( - __version__, sys.version, sys.platform - ) + banner = f"OpenPype {__version__}\nPython {sys.version} on {sys.platform}" code.interact(banner) diff --git a/openpype/lib/openpype_version.py b/openpype/lib/openpype_version.py index d547d34755..8c74f96da6 100644 --- a/openpype/lib/openpype_version.py +++ b/openpype/lib/openpype_version.py @@ -11,6 +11,7 @@ repository or locally available. import os import sys +import warnings import openpype.version @@ -60,9 +61,16 @@ def is_running_from_build(): def is_running_staging(): """Currently used OpenPype is staging version. + Deprecated: + Since 3.15 + Returns: bool: True if openpype version containt 'staging'. """ + warnings.warn( + "Staging version logic set by version string is deprecated.", + DeprecationWarning + ) if "staging" in get_openpype_version(): return True return False diff --git a/start.py b/start.py index d1198a85e4..e59de93236 100644 --- a/start.py +++ b/start.py @@ -516,8 +516,6 @@ def _process_arguments() -> tuple: if m and m.group('version'): use_version = m.group('version') _print(f">>> Requested version [ {use_version} ]") - if "+staging" in use_version: - use_staging = True break if use_version is None: @@ -682,8 +680,7 @@ def _find_frozen_openpype(use_version: str = None, Path: Path to version to be used. Raises: - RuntimeError: If no OpenPype version are found or no staging version - (if requested). + RuntimeError: If no OpenPype version are found. """ # Collect OpenPype versions @@ -698,13 +695,10 @@ def _find_frozen_openpype(use_version: str = None, if use_version.lower() == "latest": # Version says to use latest version _print(">>> Finding latest version defined by use version") - openpype_version = bootstrap.find_latest_openpype_version( - use_staging) + openpype_version = bootstrap.find_latest_openpype_version() else: _print(f">>> Finding specified version \"{use_version}\"") - openpype_version = bootstrap.find_openpype_version( - use_version, use_staging - ) + openpype_version = bootstrap.find_openpype_version(use_version) if openpype_version is None: raise OpenPypeVersionNotFound( @@ -714,8 +708,7 @@ def _find_frozen_openpype(use_version: str = None, elif studio_version is not None: # Studio has defined a version to use _print(f">>> Finding studio version \"{studio_version}\"") - openpype_version = bootstrap.find_openpype_version( - studio_version, use_staging) + openpype_version = bootstrap.find_openpype_version(studio_version) if openpype_version is None: raise OpenPypeVersionNotFound(( "Requested OpenPype version " @@ -728,20 +721,15 @@ def _find_frozen_openpype(use_version: str = None, _print(( ">>> Finding latest version " f"with [ {installed_version} ]")) - openpype_version = bootstrap.find_latest_openpype_version( - use_staging) + openpype_version = bootstrap.find_latest_openpype_version() if openpype_version is None: - if use_staging: - reason = "Didn't find any staging versions." - else: - reason = "Didn't find any versions." - raise OpenPypeVersionNotFound(reason) + raise OpenPypeVersionNotFound("Didn't find any versions.") # get local frozen version and add it to detected version so if it is # newer it will be used instead. if installed_version == openpype_version: - version_path = _bootstrap_from_code(use_version, use_staging) + version_path = _bootstrap_from_code(use_version) openpype_version = OpenPypeVersion( version=BootstrapRepos.get_version(version_path), path=version_path) @@ -805,8 +793,8 @@ def _find_frozen_openpype(use_version: str = None, return openpype_version.path -def _bootstrap_from_code(use_version, use_staging): - """Bootstrap live code (or the one coming with frozen OpenPype. +def _bootstrap_from_code(use_version): + """Bootstrap live code (or the one coming with frozen OpenPype). Args: use_version: (str): specific version to use. @@ -829,33 +817,25 @@ def _bootstrap_from_code(use_version, use_staging): local_version = bootstrap.get_version(Path(_openpype_root)) switch_str = f" - will switch to {use_version}" if use_version and use_version != local_version else "" # noqa _print(f" - booting version: {local_version}{switch_str}") - assert local_version + if not local_version: + raise OpenPypeVersionNotFound( + f"Cannot find version at {_openpype_root}") else: # get current version of OpenPype local_version = OpenPypeVersion.get_installed_version_str() # All cases when should be used different version than build - if (use_version and use_version != local_version) or use_staging: + if use_version and use_version != local_version: if use_version: # Explicit version should be used - version_to_use = bootstrap.find_openpype_version( - use_version, use_staging - ) + version_to_use = bootstrap.find_openpype_version(use_version) if version_to_use is None: raise OpenPypeVersionIncompatible( f"Requested version \"{use_version}\" was not found.") else: - # Staging version should be used - version_to_use = bootstrap.find_latest_openpype_version( - use_staging - ) + version_to_use = bootstrap.find_latest_openpype_version() if version_to_use is None: - if use_staging: - reason = "Didn't find any staging versions." - else: - # This reason is backup for possible bug in code - reason = "Didn't find any versions." - raise OpenPypeVersionNotFound(reason) + raise OpenPypeVersionNotFound("Didn't find any versions.") # Start extraction of version if needed if version_to_use.path.is_file(): @@ -913,10 +893,7 @@ def _bootstrap_from_code(use_version, use_staging): def _boot_validate_versions(use_version, local_version): _print(f">>> Validating version [ {use_version} ]") - openpype_versions = bootstrap.find_openpype(include_zips=True, - staging=True) - openpype_versions += bootstrap.find_openpype(include_zips=True, - staging=False) + openpype_versions = bootstrap.find_openpype(include_zips=True) v: OpenPypeVersion found = [v for v in openpype_versions if str(v) == use_version] if not found: @@ -932,14 +909,7 @@ def _boot_validate_versions(use_version, local_version): _print(f'{">>> " if valid else "!!! "}{message}') -def _boot_print_versions(use_staging, local_version, openpype_root): - if not use_staging: - _print("--- This will list only non-staging versions detected.") - _print(" To see staging versions, use --use-staging argument.") - else: - _print("--- This will list only staging versions detected.") - _print(" To see other version, omit --use-staging argument.") - +def _boot_print_versions(openpype_root): if getattr(sys, 'frozen', False): local_version = bootstrap.get_version(Path(openpype_root)) else: @@ -947,16 +917,12 @@ def _boot_print_versions(use_staging, local_version, openpype_root): compatible_with = OpenPypeVersion(version=local_version) if "--all" in sys.argv: - compatible_with = None _print("--- Showing all version (even those not compatible).") else: _print(("--- Showing only compatible versions " f"with [ {compatible_with.major}.{compatible_with.minor} ]")) - openpype_versions = bootstrap.find_openpype( - include_zips=True, - staging=use_staging, - ) + openpype_versions = bootstrap.find_openpype(include_zips=True) openpype_versions = [ version for version in openpype_versions if version.is_compatible( @@ -966,12 +932,11 @@ def _boot_print_versions(use_staging, local_version, openpype_root): list_versions(openpype_versions, local_version) -def _boot_handle_missing_version(local_version, use_staging, message): +def _boot_handle_missing_version(local_version, message): _print(message) if os.environ.get("OPENPYPE_HEADLESS_MODE") == "1": openpype_versions = bootstrap.find_openpype( - include_zips=True, staging=use_staging - ) + include_zips=True) list_versions(openpype_versions, local_version) else: igniter.show_message_dialog("Version not found", message) @@ -1005,7 +970,6 @@ def boot(): "is overridden by command line argument.")) else: _print(">>> version set by environment variable") - use_staging = "staging" in os.getenv("OPENPYPE_VERSION") use_version = os.getenv("OPENPYPE_VERSION") # ------------------------------------------------------------------------ @@ -1059,7 +1023,7 @@ def boot(): os.environ["OPENPYPE_PATH"] = openpype_path if "print_versions" in commands: - _boot_print_versions(use_staging, local_version, OPENPYPE_ROOT) + _boot_print_versions(OPENPYPE_ROOT) sys.exit(1) # ------------------------------------------------------------------------ @@ -1072,7 +1036,7 @@ def boot(): try: version_path = _find_frozen_openpype(use_version, use_staging) except OpenPypeVersionNotFound as exc: - _boot_handle_missing_version(local_version, use_staging, str(exc)) + _boot_handle_missing_version(local_version, str(exc)) sys.exit(1) except RuntimeError as e: @@ -1088,10 +1052,10 @@ def boot(): _print("--- version is valid") else: try: - version_path = _bootstrap_from_code(use_version, use_staging) + version_path = _bootstrap_from_code(use_version) except OpenPypeVersionNotFound as exc: - _boot_handle_missing_version(local_version, use_staging, str(exc)) + _boot_handle_missing_version(local_version, str(exc)) sys.exit(1) # set this to point either to `python` from venv in case of live code @@ -1172,10 +1136,10 @@ def get_info(use_staging=None) -> list: inf.append(("OpenPype variant", "staging")) else: inf.append(("OpenPype variant", "production")) - inf.append( - ("Running OpenPype from", os.environ.get('OPENPYPE_REPOS_ROOT')) + inf.extend([ + ("Running OpenPype from", os.environ.get('OPENPYPE_REPOS_ROOT')), + ("Using mongodb", components["host"])] ) - inf.append(("Using mongodb", components["host"])) if os.environ.get("FTRACK_SERVER"): inf.append(("Using FTrack at", @@ -1194,11 +1158,13 @@ def get_info(use_staging=None) -> list: mongo_components = get_default_components() if mongo_components["host"]: - inf.append(("Logging to MongoDB", mongo_components["host"])) - inf.append((" - port", mongo_components["port"] or "")) - inf.append((" - database", Logger.log_database_name)) - inf.append((" - collection", Logger.log_collection_name)) - inf.append((" - user", mongo_components["username"] or "")) + inf.extend([ + ("Logging to MongoDB", mongo_components["host"]), + (" - port", mongo_components["port"] or ""), + (" - database", Logger.log_database_name), + (" - collection", Logger.log_collection_name), + (" - user", mongo_components["username"] or "") + ]) if mongo_components["auth_db"]: inf.append((" - auth source", mongo_components["auth_db"])) From 59e23f21d02613d97217bf188f613796759c22b5 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 13 Oct 2022 11:35:38 +0200 Subject: [PATCH 05/26] :memo: change staging logic in documentation --- website/docs/admin_distribute.md | 10 +++------- website/docs/admin_openpype_commands.md | 2 +- website/docs/admin_use.md | 5 +---- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/website/docs/admin_distribute.md b/website/docs/admin_distribute.md index 2cccce0fbd..169b97e63d 100644 --- a/website/docs/admin_distribute.md +++ b/website/docs/admin_distribute.md @@ -52,14 +52,10 @@ The default locations are: ### Staging vs. Production -You can have version of OpenPype with experimental features you want to try somewhere but you -don't want to disrupt your production. You can tag version as **staging** simply by appending `+staging` -to its name. +You can have version of OpenPype with experimental features you want to try somewhere, but you +don't want to disrupt your production. You can set such version in th Settings. -So if you have OpenPype version like `OpenPype-v3.0.0.zip` just name it `OpenPype-v3.0.0+staging.zip`. -When both these versions are present, production one will always take precedence over staging. - -You can run OpenPype with `--use-staging` argument to add use staging versions. +You can run OpenPype with `--use-staging` argument to use staging version specified in the Settings. :::note Running staging version is identified by orange **P** icon in system tray. diff --git a/website/docs/admin_openpype_commands.md b/website/docs/admin_openpype_commands.md index 85f661d51e..131b6c0a51 100644 --- a/website/docs/admin_openpype_commands.md +++ b/website/docs/admin_openpype_commands.md @@ -22,7 +22,7 @@ openpype_console --use-version=3.0.0-foo+bar `--use-staging` - to use staging versions of OpenPype. -`--list-versions [--use-staging]` - to list available versions. +`--list-versions` - to list available versions. `--validate-version` - to validate integrity of given version diff --git a/website/docs/admin_use.md b/website/docs/admin_use.md index 1c4ae9e01c..c92ac3a77a 100644 --- a/website/docs/admin_use.md +++ b/website/docs/admin_use.md @@ -43,8 +43,7 @@ You can use following command line arguments: openpype_console --use-version=3.0.1 ``` -`--use-staging` - to specify you prefer staging version. In that case it will be used -(if found) instead of production one. +`--use-staging` - to specify you prefer staging version. In that case it will be used instead of production one. :::tip List available versions To list all available versions, use: @@ -52,8 +51,6 @@ To list all available versions, use: ```shell openpype_console --list-versions ``` - -You can add `--use-staging` to list staging versions. ::: If you want to validate integrity of some available version, you can use: From 7bd7c0391c12a55236122d216f1f123e8f571021 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 13 Oct 2022 11:59:10 +0200 Subject: [PATCH 06/26] :white_check_mark: fix tests --- tests/unit/igniter/test_bootstrap_repos.py | 30 ++++++++++++---------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/tests/unit/igniter/test_bootstrap_repos.py b/tests/unit/igniter/test_bootstrap_repos.py index 10278c4928..8b32bbe03c 100644 --- a/tests/unit/igniter/test_bootstrap_repos.py +++ b/tests/unit/igniter/test_bootstrap_repos.py @@ -33,11 +33,11 @@ def test_openpype_version(printer): assert str(v2) == "1.2.3-x" assert v1 > v2 - v3 = OpenPypeVersion(1, 2, 3, staging=True) - assert str(v3) == "1.2.3+staging" + v3 = OpenPypeVersion(1, 2, 3) + assert str(v3) == "1.2.3" - v4 = OpenPypeVersion(1, 2, 3, staging="True", prerelease="rc.1") - assert str(v4) == "1.2.3-rc.1+staging" + v4 = OpenPypeVersion(1, 2, 3, prerelease="rc.1") + assert str(v4) == "1.2.3-rc.1" assert v3 > v4 assert v1 > v4 assert v4 < OpenPypeVersion(1, 2, 3, prerelease="rc.1") @@ -73,7 +73,7 @@ def test_openpype_version(printer): OpenPypeVersion(4, 8, 10), OpenPypeVersion(4, 8, 20), OpenPypeVersion(4, 8, 9), - OpenPypeVersion(1, 2, 3, staging=True), + OpenPypeVersion(1, 2, 3), OpenPypeVersion(1, 2, 3, build="foo") ] res = sorted(sort_versions) @@ -104,27 +104,26 @@ def test_openpype_version(printer): with pytest.raises(ValueError): _ = OpenPypeVersion(version="booobaa") - v11 = OpenPypeVersion(version="4.6.7-foo+staging") + v11 = OpenPypeVersion(version="4.6.7-foo") assert v11.major == 4 assert v11.minor == 6 assert v11.patch == 7 - assert v11.staging is True assert v11.prerelease == "foo" def test_get_main_version(): - ver = OpenPypeVersion(1, 2, 3, staging=True, prerelease="foo") + ver = OpenPypeVersion(1, 2, 3, prerelease="foo") assert ver.get_main_version() == "1.2.3" def test_get_version_path_from_list(): versions = [ OpenPypeVersion(1, 2, 3, path=Path('/foo/bar')), - OpenPypeVersion(3, 4, 5, staging=True, path=Path("/bar/baz")), + OpenPypeVersion(3, 4, 5, path=Path("/bar/baz")), OpenPypeVersion(6, 7, 8, prerelease="x", path=Path("boo/goo")) ] path = BootstrapRepos.get_version_path_from_list( - "3.4.5+staging", versions) + "3.4.5", versions) assert path == Path("/bar/baz") @@ -362,12 +361,15 @@ def test_find_openpype(fix_bootstrap, tmp_path_factory, monkeypatch, printer): result = fix_bootstrap.find_openpype(include_zips=True) # we should have results as file were created assert result is not None, "no OpenPype version found" - # latest item in `result` should be latest version found. + # latest item in `result` should be the latest version found. + # this will be `7.2.10-foo+staging` even with *staging* in since we've + # dropped the logic to handle staging separately and in alphabetical + # sorting it is after `strange`. expected_path = Path( d_path / "{}{}{}".format( - test_versions_2[3].prefix, - test_versions_2[3].version, - test_versions_2[3].suffix + test_versions_2[4].prefix, + test_versions_2[4].version, + test_versions_2[4].suffix ) ) assert result, "nothing found" From 9330d92fdc8520f7f032fcec803a6c0848b37460 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 13 Oct 2022 15:26:30 +0200 Subject: [PATCH 07/26] fix 'get_remote_versions' call in version entity --- openpype/settings/entities/__init__.py | 8 ++------ openpype/settings/entities/op_version_entity.py | 17 +++-------------- .../schemas/system_schema/schema_general.json | 4 ++-- 3 files changed, 7 insertions(+), 22 deletions(-) diff --git a/openpype/settings/entities/__init__.py b/openpype/settings/entities/__init__.py index b2cb2204f4..5e3a76094e 100644 --- a/openpype/settings/entities/__init__.py +++ b/openpype/settings/entities/__init__.py @@ -123,10 +123,7 @@ from .dict_conditional import ( ) from .anatomy_entities import AnatomyEntity -from .op_version_entity import ( - ProductionVersionsInputEntity, - StagingVersionsInputEntity -) +from .op_version_entity import VersionsInputEntity __all__ = ( "DefaultsNotDefined", @@ -188,6 +185,5 @@ __all__ = ( "AnatomyEntity", - "ProductionVersionsInputEntity", - "StagingVersionsInputEntity" + "VersionsInputEntity", ) diff --git a/openpype/settings/entities/op_version_entity.py b/openpype/settings/entities/op_version_entity.py index 782d65a446..f79048222e 100644 --- a/openpype/settings/entities/op_version_entity.py +++ b/openpype/settings/entities/op_version_entity.py @@ -66,24 +66,13 @@ class OpenPypeVersionInput(TextEntity): return super(OpenPypeVersionInput, self).convert_to_valid_type(value) -class ProductionVersionsInputEntity(OpenPypeVersionInput): +class VersionsInputEntity(OpenPypeVersionInput): """Entity meant only for global settings to define production version.""" - schema_types = ["production-versions-text"] + schema_types = ["versions-text"] def _get_openpype_versions(self): - versions = get_remote_versions(staging=False, production=True) + versions = get_remote_versions() if versions is None: return [] versions.append(get_installed_version()) return sorted(versions) - - -class StagingVersionsInputEntity(OpenPypeVersionInput): - """Entity meant only for global settings to define staging version.""" - schema_types = ["staging-versions-text"] - - def _get_openpype_versions(self): - versions = get_remote_versions(staging=True, production=False) - if versions is None: - return [] - return sorted(versions) diff --git a/openpype/settings/entities/schemas/system_schema/schema_general.json b/openpype/settings/entities/schemas/system_schema/schema_general.json index 5b6d8d5d62..d6c22fe54c 100644 --- a/openpype/settings/entities/schemas/system_schema/schema_general.json +++ b/openpype/settings/entities/schemas/system_schema/schema_general.json @@ -146,12 +146,12 @@ "label": "Define explicit OpenPype version that should be used. Keep empty to use latest available version." }, { - "type": "production-versions-text", + "type": "versions-text", "key": "production_version", "label": "Production version" }, { - "type": "staging-versions-text", + "type": "versions-text", "key": "staging_version", "label": "Staging version" }, From 1bf4fca218b1cd7969f41a2d7dc994d9f8f08467 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 25 Oct 2022 11:34:56 +0200 Subject: [PATCH 08/26] don't store settings to ordered list of staging and production (unused anyway) --- openpype/settings/handlers.py | 35 ++--------------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/openpype/settings/handlers.py b/openpype/settings/handlers.py index def8c16ea7..24544e24e2 100644 --- a/openpype/settings/handlers.py +++ b/openpype/settings/handlers.py @@ -577,8 +577,6 @@ class MongoSettingsHandler(SettingsHandler): key_suffix = "_versioned" _version_order_key = "versions_order" _all_versions_keys = "all_versions" - _production_versions_key = "production_versions" - _staging_versions_key = "staging_versions" def __init__(self): # Get mongo connection @@ -997,10 +995,7 @@ class MongoSettingsHandler(SettingsHandler): return self._version_order_checked = True - from openpype.lib.openpype_version import ( - get_OpenPypeVersion, - is_running_staging - ) + from openpype.lib.openpype_version import get_OpenPypeVersion OpenPypeVersion = get_OpenPypeVersion() # Skip if 'OpenPypeVersion' is not available @@ -1012,25 +1007,11 @@ class MongoSettingsHandler(SettingsHandler): if not doc: doc = {"type": self._version_order_key} - if self._production_versions_key not in doc: - doc[self._production_versions_key] = [] - - if self._staging_versions_key not in doc: - doc[self._staging_versions_key] = [] - if self._all_versions_keys not in doc: doc[self._all_versions_keys] = [] - if is_running_staging(): - versions_key = self._staging_versions_key - else: - versions_key = self._production_versions_key - # Skip if current version is already available - if ( - self._current_version in doc[self._all_versions_keys] - and self._current_version in doc[versions_key] - ): + if self._current_version in doc[self._all_versions_keys]: return if self._current_version not in doc[self._all_versions_keys]: @@ -1047,18 +1028,6 @@ class MongoSettingsHandler(SettingsHandler): str(version) for version in sorted(all_objected_versions) ] - if self._current_version not in doc[versions_key]: - objected_versions = [ - OpenPypeVersion(version=self._current_version) - ] - for version_str in doc[versions_key]: - objected_versions.append(OpenPypeVersion(version=version_str)) - - # Update versions list and push changes to Mongo - doc[versions_key] = [ - str(version) for version in sorted(objected_versions) - ] - self.collection.replace_one( {"type": self._version_order_key}, doc, From 2341f08492f09c12c0011a63e1a68df895c3ba4a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 25 Oct 2022 16:45:40 +0200 Subject: [PATCH 09/26] store '--use-staging' to 'OPENPYPE_USE_STAGING' env variable --- start.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/start.py b/start.py index e59de93236..2fca2a763d 100644 --- a/start.py +++ b/start.py @@ -242,6 +242,9 @@ if "--debug" in sys.argv: sys.argv.remove("--debug") os.environ["OPENPYPE_DEBUG"] = "1" +if "--use-staging" in sys.argv: + sys.argv.remove("--use-staging") + os.environ["OPENPYPE_USE_STAGING"] = "1" import igniter # noqa: E402 from igniter import BootstrapRepos # noqa: E402 @@ -484,7 +487,6 @@ def _process_arguments() -> tuple: """ # check for `--use-version=3.0.0` argument and `--use-staging` use_version = None - use_staging = False commands = [] # OpenPype version specification through arguments @@ -542,10 +544,6 @@ def _process_arguments() -> tuple: " proper version string.")) sys.exit(1) - if "--use-staging" in sys.argv: - use_staging = True - sys.argv.remove("--use-staging") - if "--list-versions" in sys.argv: commands.append("print_versions") sys.argv.remove("--list-versions") @@ -568,7 +566,7 @@ def _process_arguments() -> tuple: sys.argv.pop(idx) sys.argv.insert(idx, "tray") - return use_version, use_staging, commands + return use_version, commands def _determine_mongodb() -> str: @@ -962,7 +960,8 @@ def boot(): # Process arguments # ------------------------------------------------------------------------ - use_version, use_staging, commands = _process_arguments() + use_version, commands = _process_arguments() + use_staging = os.environ.get("OPENPYPE_USE_STAGING") == "1" if os.getenv("OPENPYPE_VERSION"): if use_version: From 0e9164f7ff458606f4adb56845507819a42d7c57 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 25 Oct 2022 16:46:03 +0200 Subject: [PATCH 10/26] settings have function to receive global settings --- openpype/settings/__init__.py | 4 ++- openpype/settings/handlers.py | 64 +++++++++++++++++++++++++++-------- openpype/settings/lib.py | 11 ++++++ 3 files changed, 63 insertions(+), 16 deletions(-) diff --git a/openpype/settings/__init__.py b/openpype/settings/__init__.py index ca7157812d..22d734ae58 100644 --- a/openpype/settings/__init__.py +++ b/openpype/settings/__init__.py @@ -18,11 +18,12 @@ from .exceptions import ( ) from .lib import ( get_general_environments, + get_global_settings, get_system_settings, get_project_settings, get_current_project_settings, get_anatomy_settings, - get_local_settings + get_local_settings, ) from .entities import ( SystemSettings, @@ -49,6 +50,7 @@ __all__ = ( "SaveWarningExc", "get_general_environments", + "get_global_settings", "get_system_settings", "get_project_settings", "get_current_project_settings", diff --git a/openpype/settings/handlers.py b/openpype/settings/handlers.py index 24544e24e2..373029d9df 100644 --- a/openpype/settings/handlers.py +++ b/openpype/settings/handlers.py @@ -181,7 +181,16 @@ class SettingsStateInfo: @six.add_metaclass(ABCMeta) -class SettingsHandler: +class SettingsHandler(object): + global_keys = { + "openpype_path", + "admin_password", + "log_to_server", + "disk_mapping", + "production_version", + "staging_version" + } + @abstractmethod def save_studio_settings(self, data): """Save studio overrides of system settings. @@ -328,6 +337,19 @@ class SettingsHandler: """ pass + @abstractmethod + def get_global_settings(self): + """Studio global settings available across versions. + + Output must contain all keys from 'global_keys'. If value is not set + the output value should be 'None'. + + Returns: + Dict[str, Any]: Global settings same across versions. + """ + + pass + # Clear methods - per version # - clearing may be helpfull when a version settings were created for # testing purposes @@ -566,14 +588,6 @@ class CacheValues: class MongoSettingsHandler(SettingsHandler): """Settings handler that use mongo for storing and loading of settings.""" - global_general_keys = ( - "openpype_path", - "admin_password", - "log_to_server", - "disk_mapping", - "production_version", - "staging_version" - ) key_suffix = "_versioned" _version_order_key = "versions_order" _all_versions_keys = "all_versions" @@ -603,6 +617,7 @@ class MongoSettingsHandler(SettingsHandler): self.collection = settings_collection[database_name][collection_name] + self.global_settings_cache = CacheValues() self.system_settings_cache = CacheValues() self.project_settings_cache = collections.defaultdict(CacheValues) self.project_anatomy_cache = collections.defaultdict(CacheValues) @@ -636,6 +651,23 @@ class MongoSettingsHandler(SettingsHandler): self._prepare_project_settings_keys() return self._attribute_keys + def get_global_settings_doc(self): + if self.global_settings_cache.is_outdated: + global_settings_doc = self.collection.find_one({ + "type": GLOBAL_SETTINGS_KEY + }) or {} + self.global_settings_cache.update_data(global_settings_doc, None) + return self.global_settings_cache.data_copy() + + def get_global_settings(self): + global_settings_doc = self.get_global_settings_doc() + global_settings = global_settings_doc.get("data", {}) + return { + key: global_settings[key] + for key in self.global_keys + if key in global_settings + } + def _extract_global_settings(self, data): """Extract global settings data from system settings overrides. @@ -652,7 +684,7 @@ class MongoSettingsHandler(SettingsHandler): general_data = data["general"] # Add predefined keys to global settings if are set - for key in self.global_general_keys: + for key in self.global_keys: if key not in general_data: continue # Pop key from values @@ -696,7 +728,7 @@ class MongoSettingsHandler(SettingsHandler): # Check if data contain any key from predefined keys any_key_found = False if globals_data: - for key in self.global_general_keys: + for key in self.global_keys: if key in globals_data: any_key_found = True break @@ -723,7 +755,7 @@ class MongoSettingsHandler(SettingsHandler): system_settings_data["general"] = system_general overridden_keys = system_general.get(M_OVERRIDDEN_KEY) or [] - for key in self.global_general_keys: + for key in self.global_keys: if key not in globals_data: continue @@ -765,6 +797,10 @@ class MongoSettingsHandler(SettingsHandler): global_settings = self._extract_global_settings( system_settings_data ) + self.global_settings_cache.update_data( + global_settings, + None + ) system_settings_doc = self.collection.find_one( { @@ -1267,9 +1303,7 @@ class MongoSettingsHandler(SettingsHandler): def get_studio_system_settings_overrides(self, return_version): """Studio overrides of system settings.""" if self.system_settings_cache.is_outdated: - globals_document = self.collection.find_one({ - "type": GLOBAL_SETTINGS_KEY - }) + globals_document = self.get_global_settings_doc() document, version = self._get_system_settings_overrides_doc() last_saved_info = SettingsStateInfo.from_document( diff --git a/openpype/settings/lib.py b/openpype/settings/lib.py index 5eaddf6e6e..d6f31b2593 100644 --- a/openpype/settings/lib.py +++ b/openpype/settings/lib.py @@ -1043,6 +1043,17 @@ def get_current_project_settings(): return get_project_settings(project_name) +@require_handler +def get_global_settings(): + default_settings = load_openpype_default_settings() + default_values = default_settings["system_settings"]["general"] + studio_values = _SETTINGS_HANDLER.get_global_settings() + return { + key: studio_values.get(key, default_values.get(key)) + for key in _SETTINGS_HANDLER.global_keys + } + + def get_general_environments(): """Get general environments. From 5958229ac87d7a86c1379a355fa4d12a04f1e6f4 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 25 Oct 2022 16:46:32 +0200 Subject: [PATCH 11/26] added function to check if staging is enabled --- openpype/lib/openpype_version.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openpype/lib/openpype_version.py b/openpype/lib/openpype_version.py index 8c74f96da6..e287d20e2d 100644 --- a/openpype/lib/openpype_version.py +++ b/openpype/lib/openpype_version.py @@ -58,6 +58,10 @@ def is_running_from_build(): return True +def is_staging_enabled(): + return os.environ.get("OPENPYPE_USE_STAGING") == "1" + + def is_running_staging(): """Currently used OpenPype is staging version. From 929db9fd13c283cecb5ed21e12669206c093d2d4 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 25 Oct 2022 16:46:53 +0200 Subject: [PATCH 12/26] fixed 'get_latest_version' --- igniter/bootstrap_repos.py | 2 +- openpype/lib/openpype_version.py | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/igniter/bootstrap_repos.py b/igniter/bootstrap_repos.py index fd411272c4..2854a047ae 100644 --- a/igniter/bootstrap_repos.py +++ b/igniter/bootstrap_repos.py @@ -466,7 +466,7 @@ class OpenPypeVersion(semver.VersionInfo): installed_version = OpenPypeVersion.get_installed_version() local_versions = OpenPypeVersion.get_local_versions() if local else [] remote_versions = OpenPypeVersion.get_remote_versions() if remote else [] # noqa: E501 - all_versions = local_versions + remote_versions + installed_version + all_versions = local_versions + remote_versions + [installed_version] all_versions.sort() return all_versions[-1] diff --git a/openpype/lib/openpype_version.py b/openpype/lib/openpype_version.py index e287d20e2d..4c927ed191 100644 --- a/openpype/lib/openpype_version.py +++ b/openpype/lib/openpype_version.py @@ -143,13 +143,11 @@ def get_remote_versions(*args, **kwargs): return None -def get_latest_version(staging=None, local=None, remote=None): +def get_latest_version(local=None, remote=None): """Get latest version from repository path.""" - if staging is None: - staging = is_running_staging() + if op_version_control_available(): return get_OpenPypeVersion().get_latest_version( - staging=staging, local=local, remote=remote ) From 1cd4cbcc09079c07c50fbe802e9b9947401a4a77 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 25 Oct 2022 16:47:03 +0200 Subject: [PATCH 13/26] reimplemented 'is_running_staging' --- openpype/lib/openpype_version.py | 59 ++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/openpype/lib/openpype_version.py b/openpype/lib/openpype_version.py index 4c927ed191..586fc56eb7 100644 --- a/openpype/lib/openpype_version.py +++ b/openpype/lib/openpype_version.py @@ -11,7 +11,6 @@ repository or locally available. import os import sys -import warnings import openpype.version @@ -65,19 +64,59 @@ def is_staging_enabled(): def is_running_staging(): """Currently used OpenPype is staging version. - Deprecated: - Since 3.15 + This function is not 100% proper check of staging version. It is possible + to have enabled to use staging version but be in different one. + + The function is based on 4 factors: + - env 'OPENPYPE_IS_STAGING' is set + - current production version + - current staging version + - use staging is enabled + + First checks for 'OPENPYPE_IS_STAGING' environment which can be set to '1'. + The value should be set only when a process without access to + OpenPypeVersion is launched (e.g. in DCCs). If current version is same + as production version it is expected that it is not staging, and it + doesn't matter what would 'is_staging_enabled' return. If current version + is same as staging version it is expected we're in staging. In all other + cases 'is_staging_enabled' is used as source of outpu value. + + The function is used to decide which icon is used. To check e.g. updates + the output should be combined with other functions from this file. Returns: - bool: True if openpype version containt 'staging'. + bool: Using staging version or not. """ - warnings.warn( - "Staging version logic set by version string is deprecated.", - DeprecationWarning - ) - if "staging" in get_openpype_version(): + + if os.environ.get("OPENPYPE_IS_STAGING") == "1": return True - return False + + if not op_version_control_available(): + return False + + from openpype.settings import get_global_settings + + global_settings = get_global_settings() + production_version = global_settings["production_version"] + latest_version = None + if not production_version or production_version == "latest": + latest_version = get_latest_version(local=False, remote=True) + production_version = latest_version + + current_version = get_openpype_version() + if current_version == production_version: + return False + + staging_version = global_settings["staging_version"] + if not staging_version or staging_version == "latest": + if latest_version is None: + latest_version = get_latest_version(local=False, remote=True) + staging_version = latest_version + + if current_version == production_version: + return True + + return is_staging_enabled() # ---------------------------------------- From 8f617d5d6e6410639fb147acbfd2c71bc564b1f3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 25 Oct 2022 16:47:56 +0200 Subject: [PATCH 14/26] use 'run_detached_process' from lib to start new tray --- openpype/tools/tray/pype_tray.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/openpype/tools/tray/pype_tray.py b/openpype/tools/tray/pype_tray.py index 3842a4e216..8817990f07 100644 --- a/openpype/tools/tray/pype_tray.py +++ b/openpype/tools/tray/pype_tray.py @@ -2,7 +2,6 @@ import collections import os import sys import atexit -import subprocess import platform @@ -11,8 +10,9 @@ from Qt import QtCore, QtGui, QtWidgets import openpype.version from openpype import resources, style from openpype.lib import ( - get_openpype_execute_args, Logger, + get_openpype_execute_args, + run_detached_process, ) from openpype.lib.openpype_version import ( op_version_control_available, @@ -590,14 +590,8 @@ class TrayManager: kwargs["env"].pop("OPENPYPE_VERSION", None) args.extend(additional_args) - if platform.system().lower() == "windows": - flags = ( - subprocess.CREATE_NEW_PROCESS_GROUP - | subprocess.DETACHED_PROCESS - ) - kwargs["creationflags"] = flags - subprocess.Popen(args, **kwargs) + run_detached_process(args, **kwargs) self.exit() def exit(self): From ebbcbdde1221fedbbb315e6a5c3e1e17a4cf10de Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 25 Oct 2022 16:48:58 +0200 Subject: [PATCH 15/26] simplified args for subprocess --- openpype/tools/tray/pype_tray.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/openpype/tools/tray/pype_tray.py b/openpype/tools/tray/pype_tray.py index 8817990f07..a49471a944 100644 --- a/openpype/tools/tray/pype_tray.py +++ b/openpype/tools/tray/pype_tray.py @@ -562,9 +562,7 @@ class TrayManager: logic will decide which version will be used. """ args = get_openpype_execute_args() - kwargs = { - "env": dict(os.environ.items()) - } + envs = dict(os.environ.items()) # Create a copy of sys.argv additional_args = list(sys.argv) @@ -577,7 +575,7 @@ class TrayManager: expected_version = get_expected_version() if expected_version is not None: reset_version = False - kwargs["env"]["OPENPYPE_VERSION"] = str(expected_version) + envs["OPENPYPE_VERSION"] = str(expected_version) else: # Trigger reset of version if expected version was not found reset_version = True @@ -587,11 +585,11 @@ class TrayManager: # Add staging flag if was running from staging if is_running_staging(): args.append("--use-staging") - kwargs["env"].pop("OPENPYPE_VERSION", None) + envs.pop("OPENPYPE_VERSION", None) args.extend(additional_args) - run_detached_process(args, **kwargs) + run_detached_process(args, env=envs) self.exit() def exit(self): From 0b68cbae5c064353119c74e32eee5db08e6c3d28 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 25 Oct 2022 16:49:13 +0200 Subject: [PATCH 16/26] added cleanup of additional arguments --- openpype/tools/tray/pype_tray.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/openpype/tools/tray/pype_tray.py b/openpype/tools/tray/pype_tray.py index a49471a944..3a457d2951 100644 --- a/openpype/tools/tray/pype_tray.py +++ b/openpype/tools/tray/pype_tray.py @@ -571,7 +571,9 @@ class TrayManager: if args[-1] == additional_args[0]: additional_args.pop(0) + cleanup_additional_args = False if use_expected_version: + cleanup_additional_args = True expected_version = get_expected_version() if expected_version is not None: reset_version = False @@ -585,8 +587,17 @@ class TrayManager: # Add staging flag if was running from staging if is_running_staging(): args.append("--use-staging") + cleanup_additional_args = True envs.pop("OPENPYPE_VERSION", None) + if cleanup_additional_args: + _additional_args = [] + for arg in additional_args: + if arg == "--use-staging" or arg.startswith("--use-version"): + continue + _additional_args.append(arg) + additional_args = _additional_args + args.extend(additional_args) run_detached_process(args, env=envs) From d2127b510c83866a78b8c42f889ad5ebeb7ea042 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 25 Oct 2022 16:49:30 +0200 Subject: [PATCH 17/26] skip '--use-staging' argument as env is already set --- openpype/tools/tray/pype_tray.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/openpype/tools/tray/pype_tray.py b/openpype/tools/tray/pype_tray.py index 3a457d2951..4a7d3e84b0 100644 --- a/openpype/tools/tray/pype_tray.py +++ b/openpype/tools/tray/pype_tray.py @@ -584,9 +584,6 @@ class TrayManager: # Pop OPENPYPE_VERSION if reset_version: - # Add staging flag if was running from staging - if is_running_staging(): - args.append("--use-staging") cleanup_additional_args = True envs.pop("OPENPYPE_VERSION", None) From ec0855ce7466bbcb3f66605d848f512a2b847fe4 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 25 Oct 2022 18:54:13 +0200 Subject: [PATCH 18/26] one more fix of list comprehention --- igniter/bootstrap_repos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/igniter/bootstrap_repos.py b/igniter/bootstrap_repos.py index 2854a047ae..49de83cebd 100644 --- a/igniter/bootstrap_repos.py +++ b/igniter/bootstrap_repos.py @@ -1026,7 +1026,7 @@ class BootstrapRepos: installed_version = OpenPypeVersion.get_installed_version() local_versions = OpenPypeVersion.get_local_versions() remote_versions = OpenPypeVersion.get_remote_versions() - all_versions = local_versions + remote_versions + installed_version + all_versions = local_versions + remote_versions + [installed_version] if not all_versions: return None From 0f8df529d0b7e51a28fccdf2afb1335105a0b46c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 25 Oct 2022 18:54:19 +0200 Subject: [PATCH 19/26] removed unused import --- openpype/tools/tray/pype_tray.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/tools/tray/pype_tray.py b/openpype/tools/tray/pype_tray.py index 4a7d3e84b0..ada2e42121 100644 --- a/openpype/tools/tray/pype_tray.py +++ b/openpype/tools/tray/pype_tray.py @@ -21,7 +21,6 @@ from openpype.lib.openpype_version import ( is_current_version_studio_latest, is_current_version_higher_than_expected, is_running_from_build, - is_running_staging, get_openpype_version, ) from openpype.modules import TrayModulesManager From 46d06b01b0e9f7c4781381a880f42271000c7063 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 26 Oct 2022 10:45:32 +0200 Subject: [PATCH 20/26] fix args in get expected version --- openpype/lib/openpype_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/lib/openpype_version.py b/openpype/lib/openpype_version.py index 586fc56eb7..23a4cd3443 100644 --- a/openpype/lib/openpype_version.py +++ b/openpype/lib/openpype_version.py @@ -207,7 +207,7 @@ def get_expected_version(staging=None): if expected_version is None: # Look for latest if expected version is not set in settings expected_version = get_latest_version( - staging=staging, + local=False, remote=True ) return expected_version From 12522aa5902e0dfeb459ba4fea0a872a868e72bf Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 26 Oct 2022 11:00:57 +0200 Subject: [PATCH 21/26] fix how the expected studio version is checked --- openpype/lib/openpype_version.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/lib/openpype_version.py b/openpype/lib/openpype_version.py index 23a4cd3443..e052002468 100644 --- a/openpype/lib/openpype_version.py +++ b/openpype/lib/openpype_version.py @@ -195,9 +195,9 @@ def get_latest_version(local=None, remote=None): def get_expected_studio_version(staging=None): """Expected production or staging version in studio.""" - if staging is None: - staging = is_running_staging() if op_version_control_available(): + if staging is None: + staging = is_staging_enabled() return get_OpenPypeVersion().get_expected_studio_version(staging) return None From ff3325ddc67cfb981ccf7f9e9383415733ede6cd Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 26 Oct 2022 12:16:10 +0200 Subject: [PATCH 22/26] added option to receive staging and production icon explicitly --- openpype/resources/__init__.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/openpype/resources/__init__.py b/openpype/resources/__init__.py index 49eee21002..0d7778e546 100644 --- a/openpype/resources/__init__.py +++ b/openpype/resources/__init__.py @@ -39,15 +39,21 @@ def get_liberation_font_path(bold=False, italic=False): return font_path +def get_openpype_production_icon_filepath(): + return get_resource("icons", "openpype_icon.png") + + +def get_openpype_staging_icon_filepath(): + return get_resource("icons", "openpype_icon_staging.png") + + def get_openpype_icon_filepath(staging=None): if staging is None: staging = is_running_staging() if staging: - icon_file_name = "openpype_icon_staging.png" - else: - icon_file_name = "openpype_icon.png" - return get_resource("icons", icon_file_name) + return get_openpype_staging_icon_filepath() + return get_openpype_production_icon_filepath() def get_openpype_splash_filepath(staging=None): From c59d5f814c390d44a9553971e412102077a5805a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 26 Oct 2022 12:16:30 +0200 Subject: [PATCH 23/26] show a dialog in tray when staging and production versions are same --- openpype/tools/tray/pype_tray.py | 68 ++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/openpype/tools/tray/pype_tray.py b/openpype/tools/tray/pype_tray.py index ada2e42121..01749aba61 100644 --- a/openpype/tools/tray/pype_tray.py +++ b/openpype/tools/tray/pype_tray.py @@ -22,6 +22,8 @@ from openpype.lib.openpype_version import ( is_current_version_higher_than_expected, is_running_from_build, get_openpype_version, + is_running_staging, + is_staging_enabled, ) from openpype.modules import TrayModulesManager from openpype.settings import ( @@ -201,6 +203,68 @@ class VersionUpdateDialog(QtWidgets.QDialog): self.accept() +class ProductionStagingDialog(QtWidgets.QDialog): + """Tell user that he has enabled staging but is in production version. + + This is showed only when staging is enabled with '--use-staging' and it's + version is the same as production's version. + """ + + def __init__(self, parent=None): + super(ProductionStagingDialog, self).__init__(parent) + + icon = QtGui.QIcon(resources.get_openpype_icon_filepath()) + self.setWindowIcon(icon) + self.setWindowTitle("Production and Staging versions are the same") + self.setWindowFlags( + self.windowFlags() + | QtCore.Qt.WindowStaysOnTopHint + ) + + top_widget = QtWidgets.QWidget(self) + + staging_pixmap = QtGui.QPixmap( + resources.get_openpype_staging_icon_filepath() + ) + staging_icon_label = PixmapLabel(staging_pixmap, top_widget) + message = ( + "Because production and staging versions are the same" + " your changes and work will affect both." + ) + content_label = QtWidgets.QLabel(message, self) + content_label.setWordWrap(True) + + top_layout = QtWidgets.QHBoxLayout(top_widget) + top_layout.setContentsMargins(0, 0, 0, 0) + top_layout.setSpacing(10) + top_layout.addWidget( + staging_icon_label, 0, + QtCore.Qt.AlignTop | QtCore.Qt.AlignHCenter + ) + top_layout.addWidget(content_label, 1) + + footer_widget = QtWidgets.QWidget(self) + ok_btn = QtWidgets.QPushButton("I understand", footer_widget) + + footer_layout = QtWidgets.QHBoxLayout(footer_widget) + footer_layout.setContentsMargins(0, 0, 0, 0) + footer_layout.addStretch(1) + footer_layout.addWidget(ok_btn) + + main_layout = QtWidgets.QVBoxLayout(self) + main_layout.addWidget(top_widget, 0) + main_layout.addStretch(1) + main_layout.addWidget(footer_widget, 0) + + self.setStyleSheet(style.load_stylesheet()) + self.resize(400, 140) + + ok_btn.clicked.connect(self._on_ok_clicked) + + def _on_ok_clicked(self): + self.close() + + class BuildVersionDialog(QtWidgets.QDialog): """Build/Installation version is too low for current OpenPype version. @@ -461,6 +525,10 @@ class TrayManager: dialog = BuildVersionDialog() dialog.exec_() + elif is_staging_enabled() and not is_running_staging(): + dialog = ProductionStagingDialog() + dialog.exec_() + def _validate_settings_defaults(self): valid = True try: From 96719a39b4719dd6d23b638547825bca88fadc7a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 26 Oct 2022 12:21:37 +0200 Subject: [PATCH 24/26] set 'OPENPYPE_IS_STAGING' on app launch --- openpype/lib/applications.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/lib/applications.py b/openpype/lib/applications.py index 990dc7495a..317a17796e 100644 --- a/openpype/lib/applications.py +++ b/openpype/lib/applications.py @@ -1368,6 +1368,7 @@ def get_app_environments_for_context( from openpype.modules import ModulesManager from openpype.pipeline import AvalonMongoDB, Anatomy + from openpype.lib.openpype_version import is_running_staging # Avalon database connection dbcon = AvalonMongoDB() @@ -1404,6 +1405,8 @@ def get_app_environments_for_context( "env": env }) data["env"].update(anatomy.root_environments()) + if is_running_staging(): + data["env"]["OPENPYPE_IS_STAGING"] = "1" prepare_app_environments(data, env_group, modules_manager) prepare_context_environments(data, env_group, modules_manager) From 4d3961e04446bb3515c2f56b0cdd11731825524a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 10 Nov 2022 11:43:17 +0100 Subject: [PATCH 25/26] changed label of standalone publisher --- openpype/hosts/standalonepublisher/addon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/standalonepublisher/addon.py b/openpype/hosts/standalonepublisher/addon.py index 65a4226664..67204b581b 100644 --- a/openpype/hosts/standalonepublisher/addon.py +++ b/openpype/hosts/standalonepublisher/addon.py @@ -10,7 +10,7 @@ STANDALONEPUBLISH_ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) class StandAlonePublishAddon(OpenPypeModule, ITrayAction, IHostAddon): - label = "Publish" + label = "Publisher (legacy)" name = "standalonepublisher" host_name = "standalonepublisher" From e07d26c9392104f3b236435443b6564bfe5adffb Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 10 Nov 2022 11:43:27 +0100 Subject: [PATCH 26/26] disable standalone publisher by default --- openpype/settings/defaults/system_settings/modules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/settings/defaults/system_settings/modules.json b/openpype/settings/defaults/system_settings/modules.json index c84d23d3fc..703e72cb5d 100644 --- a/openpype/settings/defaults/system_settings/modules.json +++ b/openpype/settings/defaults/system_settings/modules.json @@ -195,7 +195,7 @@ "enabled": true }, "standalonepublish_tool": { - "enabled": true + "enabled": false }, "project_manager": { "enabled": true