Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

General: Fix finding of last version #3656

Merged
merged 12 commits into from
Aug 16, 2022
143 changes: 73 additions & 70 deletions igniter/bootstrap_repos.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,16 +411,7 @@ def get_local_versions(

# 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, compatible_with=compatible_with
)
if compatible_with:
dir_to_search = Path(
user_data_dir("openpype", "pypeclub")) / f"{compatible_with.major}.{compatible_with.minor}" # noqa
versions += OpenPypeVersion.get_versions_from_directory(
dir_to_search, compatible_with=compatible_with
)

versions = OpenPypeVersion.get_versions_from_directory(dir_to_search)

filtered_versions = []
for version in versions:
Expand Down Expand Up @@ -498,14 +489,11 @@ def get_remote_versions(

@staticmethod
def get_versions_from_directory(
openpype_dir: Path,
compatible_with: OpenPypeVersion = None) -> List:
openpype_dir: Path) -> List:
"""Get all detected OpenPype versions in directory.

Args:
openpype_dir (Path): Directory to scan.
compatible_with (OpenPypeVersion): Return only versions compatible
with build version specified as OpenPypeVersion.

Returns:
list of OpenPypeVersion
Expand All @@ -515,17 +503,27 @@ def get_versions_from_directory(

"""
installed_version = OpenPypeVersion.get_installed_version()
if not compatible_with:
compatible_with = installed_version
_openpype_versions = []
openpype_versions = []
if not openpype_dir.exists() and not openpype_dir.is_dir():
return _openpype_versions
return openpype_versions

# iterate over directory in first level and find all that might
# contain OpenPype.
for item in openpype_dir.iterdir():

# if file, strip extension, in case of dir not.
# if the item is directory with major.minor version, dive deeper
try:
ver_dir = item.name.split(".")[
0] == installed_version.major and \
item.name.split(".")[
1] == installed_version.minor # noqa: E051
if item.is_dir() and ver_dir:
_versions = OpenPypeVersion.get_versions_from_directory(
item)
if _versions:
openpype_versions.append(_versions)
except IndexError:
pass
# if file exists, strip extension, in case of dir don't.
Copy link
Collaborator

@BigRoy BigRoy Aug 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't the item.name match exactly with f"{installed_version.major}.{installed_version.minor}"?
So wouldn't this just be if item.name == f"{installed_version.major}.{installed_version.minor}" or alike?

Should be faster too, and more readable. Less string splitting and just a single comparison. major_minor could even be defined outside of the iterdir() loop.

major_minor = f"{installed_version.major}.{installed_version.minor}"
if item.is_dir() and item.name == major_minor:
    _versions = OpenPypeVersion.get_versions_from_directory(item)
    openpype_versions.extend(_versions)

I also expected this should be openpype_versions.extend() instead of append when looking at the code?

And shouldn't we also "continue" if we've already identified it as a major minor subfolder, so add

    continue

Copy link
Member Author

@antirotor antirotor Aug 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is actually wrong as it shouldn't compare those at all and dive deeper if it matches regex ^\d+\.\d+$

name = item.name if item.is_dir() else item.stem
result = OpenPypeVersion.version_in_str(name)

Expand All @@ -543,13 +541,10 @@ def get_versions_from_directory(
)[0]:
continue

if not detected_version.is_compatible(compatible_with):
continue

detected_version.path = item
_openpype_versions.append(detected_version)
openpype_versions.append(detected_version)

return sorted(_openpype_versions)
return sorted(openpype_versions)

@staticmethod
def get_installed_version_str() -> str:
Expand Down Expand Up @@ -577,15 +572,14 @@ def get_installed_version(cls):
def get_latest_version(
staging: bool = False,
local: bool = None,
remote: bool = None,
compatible_with: OpenPypeVersion = None
remote: bool = None
) -> Union[OpenPypeVersion, None]:
"""Get latest available version.
"""Get the latest available version.

The version does not contain information about path and source.

This is utility version to get latest version from all found. Build
version is not listed if staging is enabled.
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
Expand All @@ -597,8 +591,9 @@ def get_latest_version(
staging (bool, optional): List staging versions if True.
local (bool, optional): List local versions if True.
remote (bool, optional): List remote versions if True.
compatible_with (OpenPypeVersion, optional) Return only version
compatible with compatible_with.

Returns:
Latest OpenPypeVersion or None

"""
if local is None and remote is None:
Expand All @@ -612,8 +607,6 @@ def get_latest_version(
remote = True

installed_version = OpenPypeVersion.get_installed_version()
if not compatible_with:
compatible_with = installed_version
local_versions = []
remote_versions = []
if local:
Expand All @@ -633,10 +626,7 @@ def get_latest_version(

all_versions.sort()
latest_version: OpenPypeVersion
antirotor marked this conversation as resolved.
Show resolved Hide resolved
latest_version = all_versions[-1]
if not latest_version.is_compatible(compatible_with):
return None
return latest_version
return all_versions[-1]

@classmethod
def get_expected_studio_version(cls, staging=False, global_settings=None):
Expand Down Expand Up @@ -1191,13 +1181,27 @@ def find_openpype_version(

@staticmethod
def find_latest_openpype_version(
staging, compatible_with: OpenPypeVersion = None):
staging: bool,
compatible_with: OpenPypeVersion = None
) -> Union[OpenPypeVersion, None]:
"""Find the latest available OpenPype version in all location.

Args:
staging (bool): True to look for staging versions.
compatible_with (OpenPypeVersion, optional): If set, it will
try to find the latest version compatible with the
one specified.

Returns:
Latest OpenPype version on None if nothing was found.

"""
installed_version = OpenPypeVersion.get_installed_version()
local_versions = OpenPypeVersion.get_local_versions(
staging=staging, compatible_with=compatible_with
staging=staging
)
remote_versions = OpenPypeVersion.get_remote_versions(
staging=staging, compatible_with=compatible_with
staging=staging
)
all_versions = local_versions + remote_versions
if not staging:
Expand All @@ -1206,6 +1210,12 @@ def find_latest_openpype_version(
if not all_versions:
return None

if compatible_with:
all_versions = [
version for version in all_versions
if version.is_compatible(installed_version)
]

all_versions.sort()
latest_version = all_versions[-1]
if latest_version == installed_version:
Expand All @@ -1222,8 +1232,7 @@ def find_openpype(
self,
openpype_path: Union[Path, str] = None,
staging: bool = False,
include_zips: bool = False,
compatible_with: OpenPypeVersion = None
include_zips: bool = False
) -> Union[List[OpenPypeVersion], None]:
"""Get ordered dict of detected OpenPype version.

Expand Down Expand Up @@ -1256,36 +1265,29 @@ def find_openpype(

"""
installed_version = OpenPypeVersion.get_installed_version()
if not compatible_with:
compatible_with = installed_version
if openpype_path and not isinstance(openpype_path, Path):
raise NotImplementedError(
("Finding OpenPype in non-filesystem locations is"
" not implemented yet."))

version_dir = f"{compatible_with.major}.{compatible_with.minor}"

# if checks bellow for OPENPYPE_PATH and registry fails, use data_dir
# DEPRECATED: lookup in root of this folder is deprecated in favour
# of major.minor sub-folders.
dirs_to_search = [self.data_dir, self.data_dir / version_dir]
dirs_to_search = [self.data_dir]

if openpype_path:
dirs_to_search = [openpype_path, openpype_path / version_dir]
dirs_to_search = [openpype_path]
elif os.getenv("OPENPYPE_PATH") \
and Path(os.getenv("OPENPYPE_PATH")).exists():
# first try OPENPYPE_PATH and if that is not available,
# try registry.
dirs_to_search = [Path(os.getenv("OPENPYPE_PATH")),
Path(os.getenv("OPENPYPE_PATH")) / version_dir]
dirs_to_search = [Path(os.getenv("OPENPYPE_PATH"))]
else:
try:
registry_dir = Path(
str(self.registry.get_item("openPypePath")))
if registry_dir.exists():
dirs_to_search = [
registry_dir, registry_dir / version_dir
]
dirs_to_search = [registry_dir]

except ValueError:
# nothing found in registry, we'll use data dir
Expand All @@ -1295,7 +1297,7 @@ def find_openpype(
for dir_to_search in dirs_to_search:
try:
openpype_versions += self.get_openpype_versions(
dir_to_search, staging, compatible_with=compatible_with)
dir_to_search, staging)
except ValueError:
# location is invalid, skip it
pass
Expand Down Expand Up @@ -1663,15 +1665,12 @@ def _is_openpype_in_zip(self,
def get_openpype_versions(
self,
openpype_dir: Path,
staging: bool = False,
compatible_with: OpenPypeVersion = None) -> list:
staging: bool = False) -> list:
"""Get all detected OpenPype versions in directory.

Args:
openpype_dir (Path): Directory to scan.
staging (bool, optional): Find staging versions if True.
compatible_with (OpenPypeVersion, optional): Get only versions
compatible with the one specified.

Returns:
list of OpenPypeVersion
Expand All @@ -1681,17 +1680,24 @@ def get_openpype_versions(

"""
installed_version = OpenPypeVersion.get_installed_version()
if not compatible_with:
compatible_with = installed_version
if not openpype_dir.exists() and not openpype_dir.is_dir():
raise ValueError(f"specified directory {openpype_dir} is invalid")

_openpype_versions = []
openpype_versions = []
# iterate over directory in first level and find all that might
# contain OpenPype.
for item in openpype_dir.iterdir():

# if file, strip extension, in case of dir not.
# if the item is directory with major.minor version, dive deeper
try:
ver_dir = item.name.split(".")[0] == installed_version.major and item.name.split(".")[1] == installed_version.minor # noqa: E051
if item.is_dir() and ver_dir:
_versions = self.get_openpype_versions(
item, staging=staging)
if _versions:
openpype_versions.append(_versions)
except IndexError:
pass
# if it is file, strip extension, in case of dir don't.
name = item.name if item.is_dir() else item.stem
result = OpenPypeVersion.version_in_str(name)

Expand All @@ -1709,17 +1715,14 @@ def get_openpype_versions(
):
continue

if not detected_version.is_compatible(compatible_with):
continue

detected_version.path = item
if staging and detected_version.is_staging():
_openpype_versions.append(detected_version)
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)
return sorted(openpype_versions)


class OpenPypeVersionExists(Exception):
Expand Down
19 changes: 18 additions & 1 deletion igniter/install_thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def run(self):
progress_callback=self.set_progress, message=self.message)
local_version = OpenPypeVersion.get_installed_version_str()

# if user did entered nothing, we install OpenPype from local version.
# if user did enter nothing, we install OpenPype from local version.
# zip content of `repos`, copy it to user data dir and append
# version to it.
if not self._path:
Expand Down Expand Up @@ -93,6 +93,23 @@ def run(self):
detected = bs.find_openpype(include_zips=True)

if detected:
if not OpenPypeVersion.get_installed_version().is_compatible(
detected[-1]):
self.message.emit((
f"Latest detected version {detected[-1]} "
"is not compatible with the currently running "
f"{local_version}"
), True)
self.message.emit((
"Filtering detected versions to compatible ones..."
), False)

detected = [
version for version in detected
if version.is_compatible(
OpenPypeVersion.get_installed_version())
]

if OpenPypeVersion(
version=local_version, path=Path()) < detected[-1]:
self.message.emit((
Expand Down
2 changes: 1 addition & 1 deletion openpype/version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-
"""Package declaring Pype version."""
"""Package declaring OpenPype version."""
__version__ = "3.13.1-nightly.1"
Loading