Merge pull request #1148 from ynput/feature/envs-in-roots

Chore: Environment variables in roots
This commit is contained in:
Jakub Trllo 2025-04-07 15:39:13 +02:00 committed by GitHub
commit a1e2efc51b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 47 additions and 14 deletions

View file

@ -1,12 +1,15 @@
from ayon_api import get_project, get_folder_by_path, get_task_by_name
from ayon_core.pipeline import Anatomy
from ayon_core.pipeline.anatomy import RootMissingEnv
from ayon_applications import PreLaunchHook
from ayon_applications.exceptions import ApplicationLaunchFailed
from ayon_applications.utils import (
EnvironmentPrepData,
prepare_app_environments,
prepare_context_environments
)
from ayon_core.pipeline import Anatomy
class GlobalHostDataHook(PreLaunchHook):
@ -67,9 +70,12 @@ class GlobalHostDataHook(PreLaunchHook):
self.data["project_entity"] = project_entity
# Anatomy
try:
self.data["anatomy"] = Anatomy(
project_name, project_entity=project_entity
)
except RootMissingEnv as exc:
raise ApplicationLaunchFailed(str(exc))
folder_path = self.data.get("folder_path")
if not folder_path:

View file

@ -1,5 +1,6 @@
from .exceptions import (
ProjectNotSet,
RootMissingEnv,
RootCombinationError,
TemplateMissingKey,
AnatomyTemplateUnsolved,
@ -9,6 +10,7 @@ from .anatomy import Anatomy
__all__ = (
"ProjectNotSet",
"RootMissingEnv",
"RootCombinationError",
"TemplateMissingKey",
"AnatomyTemplateUnsolved",

View file

@ -5,6 +5,11 @@ class ProjectNotSet(Exception):
"""Exception raised when is created Anatomy without project name."""
class RootMissingEnv(KeyError):
"""Raised when root requires environment variables which is not filled."""
pass
class RootCombinationError(Exception):
"""This exception is raised when templates has combined root types."""

View file

@ -2,9 +2,11 @@ import os
import platform
import numbers
from ayon_core.lib import Logger
from ayon_core.lib import Logger, StringTemplate
from ayon_core.lib.path_templates import FormatObject
from .exceptions import RootMissingEnv
class RootItem(FormatObject):
"""Represents one item or roots.
@ -21,18 +23,36 @@ class RootItem(FormatObject):
multi root setup otherwise None value is expected.
"""
def __init__(self, parent, root_raw_data, name):
super(RootItem, self).__init__()
super().__init__()
self._log = None
lowered_platform_keys = {}
for key, value in root_raw_data.items():
lowered_platform_keys[key.lower()] = value
lowered_platform_keys = {
key.lower(): value
for key, value in root_raw_data.items()
}
self.raw_data = lowered_platform_keys
self.cleaned_data = self._clean_roots(lowered_platform_keys)
self.name = name
self.parent = parent
self.available_platforms = set(lowered_platform_keys.keys())
self.value = lowered_platform_keys.get(platform.system().lower())
current_platform = platform.system().lower()
# WARNING: Using environment variables in roots is not considered
# as production safe. Some features may not work as expected, for
# example USD resolver or site sync.
try:
self.value = lowered_platform_keys[current_platform].format_map(
os.environ
)
except KeyError:
result = StringTemplate(self.value).format(os.environ.copy())
is_are = "is" if len(result.missing_keys) == 1 else "are"
missing_keys = ", ".join(result.missing_keys)
raise RootMissingEnv(
f"Root \"{name}\" requires environment variable/s"
f" {missing_keys} which {is_are} not available."
)
self.clean_value = self._clean_root(self.value)
def __format__(self, *args, **kwargs):
@ -105,10 +125,10 @@ class RootItem(FormatObject):
def _clean_roots(self, raw_data):
"""Clean all values of raw root item values."""
cleaned = {}
for key, value in raw_data.items():
cleaned[key] = self._clean_root(value)
return cleaned
return {
key: self._clean_root(value)
for key, value in raw_data.items()
}
def path_remapper(self, path, dst_platform=None, src_platform=None):
"""Remap path for specific platform.