diff --git a/client/ayon_core/cli.py b/client/ayon_core/cli.py index 0ad4364bcd..2759b4fccf 100644 --- a/client/ayon_core/cli.py +++ b/client/ayon_core/cli.py @@ -103,19 +103,18 @@ def extractenvironments(output_json_path, project, asset, task, app, envgroup): @main_cli.command() -@click.argument("paths", nargs=-1) -@click.option("-t", "--targets", help="Targets module", default=None, +@click.argument("path", required=True) +@click.option("-t", "--targets", help="Targets", default=None, multiple=True) @click.option("-g", "--gui", is_flag=True, help="Show Publish UI", default=False) -def publish(paths, targets, gui): +def publish(path, targets, gui): """Start CLI publishing. - Publish collects json from paths provided as an argument. - More than one path is allowed. + Publish collects json from path provided as an argument. +S """ - - Commands.publish(list(paths), targets, gui) + Commands.publish(path, targets, gui) @main_cli.command(context_settings={"ignore_unknown_options": True}) diff --git a/client/ayon_core/cli_commands.py b/client/ayon_core/cli_commands.py index 156196c401..4335a3f2d9 100644 --- a/client/ayon_core/cli_commands.py +++ b/client/ayon_core/cli_commands.py @@ -3,6 +3,7 @@ import os import sys import json +import warnings class Commands: @@ -41,21 +42,21 @@ class Commands: return click_func @staticmethod - def publish(paths, targets=None, gui=False): + def publish(path: str, targets: list=None, gui:bool=False) -> None: """Start headless publishing. - Publish use json from passed paths argument. + Publish use json from passed path argument. Args: - paths (list): Paths to jsons. - targets (string): What module should be targeted - (to choose validator for example) + path (str): Path to JSON. + targets (list of str): List of pyblish targets. gui (bool): Show publish UI. Raises: RuntimeError: When there is no path to process. - """ + RuntimeError: When executed with list of JSON paths. + """ from ayon_core.lib import Logger from ayon_core.lib.applications import ( get_app_environments_for_context, @@ -73,6 +74,9 @@ class Commands: import pyblish.api import pyblish.util + if not isinstance(path, str): + raise RuntimeError("Path to JSON must be a string.") + # Fix older jobs for src_key, dst_key in ( ("AVALON_PROJECT", "AYON_PROJECT_NAME"), @@ -95,11 +99,8 @@ class Commands: publish_paths = manager.collect_plugin_paths()["publish"] - for path in publish_paths: - pyblish.api.register_plugin_path(path) - - if not any(paths): - raise RuntimeError("No publish paths specified") + for plugin_path in publish_paths: + pyblish.api.register_plugin_path(plugin_path) app_full_name = os.getenv("AYON_APP_NAME") if app_full_name: @@ -122,7 +123,7 @@ class Commands: else: pyblish.api.register_target("farm") - os.environ["AYON_PUBLISH_DATA"] = os.pathsep.join(paths) + os.environ["AYON_PUBLISH_DATA"] = path os.environ["HEADLESS_PUBLISH"] = 'true' # to use in app lib log.info("Running publish ...") diff --git a/client/ayon_core/plugins/publish/collect_rendered_files.py b/client/ayon_core/plugins/publish/collect_rendered_files.py index ca88a7aa82..8a60e7619d 100644 --- a/client/ayon_core/plugins/publish/collect_rendered_files.py +++ b/client/ayon_core/plugins/publish/collect_rendered_files.py @@ -36,18 +36,18 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): def _load_json(self, path): path = path.strip('\"') - assert os.path.isfile(path), ( - "Path to json file doesn't exist. \"{}\"".format(path) - ) + + if not os.path.isfile(path): + raise FileNotFoundError( + f"Path to json file doesn't exist. \"{path}\"") + data = None with open(path, "r") as json_file: try: data = json.load(json_file) except Exception as exc: self.log.error( - "Error loading json: " - "{} - Exception: {}".format(path, exc) - ) + "Error loading json: %s - Exception: %s", path, exc) return data def _fill_staging_dir(self, data_object, anatomy): @@ -73,30 +73,23 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): data_err = "invalid json file - missing data" required = ["user", "comment", "job", "instances", "version"] - assert all(elem in data.keys() for elem in required), data_err + + if any(elem not in data for elem in required): + raise ValueError(data_err) + if "folderPath" not in data and "asset" not in data: - raise AssertionError(data_err) + raise ValueError(data_err) if "folderPath" not in data: data["folderPath"] = data.pop("asset") - # set context by first json file - ctx = self._context.data - - ctx["folderPath"] = ctx.get("folderPath") or data.get("folderPath") - ctx["intent"] = ctx.get("intent") or data.get("intent") - ctx["comment"] = ctx.get("comment") or data.get("comment") - ctx["user"] = ctx.get("user") or data.get("user") - ctx["version"] = ctx.get("version") or data.get("version") - - # basic sanity check to see if we are working in same context - # if some other json file has different context, bail out. - ctx_err = "inconsistent contexts in json files - %s" - assert ctx.get("folderPath") == data.get("folderPath"), ctx_err % "folderPath" - assert ctx.get("intent") == data.get("intent"), ctx_err % "intent" - assert ctx.get("comment") == data.get("comment"), ctx_err % "comment" - assert ctx.get("user") == data.get("user"), ctx_err % "user" - assert ctx.get("version") == data.get("version"), ctx_err % "version" + # ftrack credentials are passed as environment variables by Deadline + # to publish job, but Muster doesn't pass them. + if data.get("ftrack") and not os.environ.get("FTRACK_API_USER"): + ftrack = data.get("ftrack") + os.environ["FTRACK_API_USER"] = ftrack["FTRACK_API_USER"] + os.environ["FTRACK_API_KEY"] = ftrack["FTRACK_API_KEY"] + os.environ["FTRACK_SERVER"] = ftrack["FTRACK_SERVER"] # now we can just add instances from json file and we are done any_staging_dir_persistent = False