From eff48e6d94ebbb952fc68221907e263f0d350101 Mon Sep 17 00:00:00 2001 From: David Lai Date: Tue, 1 Sep 2020 17:46:04 +0800 Subject: [PATCH 1/9] Loose AVALON_ASSET, AVALON_TASK --- avalon/maya/commands.py | 11 +++++++++-- avalon/maya/pipeline.py | 8 ++++---- avalon/nuke/command.py | 10 +++++++++- avalon/nuke/pipeline.py | 3 ++- avalon/tools/creator/app.py | 2 +- avalon/tools/loader/app.py | 2 +- avalon/tools/workfiles/app.py | 9 ++++----- res/houdini/MainMenuCommon.XML | 3 ++- 8 files changed, 32 insertions(+), 16 deletions(-) diff --git a/avalon/maya/commands.py b/avalon/maya/commands.py index c2eab8b51..8987edc0a 100644 --- a/avalon/maya/commands.py +++ b/avalon/maya/commands.py @@ -14,8 +14,15 @@ def reset_frame_range(): """Set frame range to current asset""" - shot = api.Session["AVALON_ASSET"] - shot = io.find_one({"name": shot, "type": "asset"}) + shot_name = api.Session.get("AVALON_ASSET") + if shot_name is None: + cmds.warning("No AVALON_ASSET setup in current working session.") + return + + shot = io.find_one({"name": shot_name, "type": "asset"}) + if shot is None: + cmds.error("Shot '%s' not found in database." % shot_name) + return try: diff --git a/avalon/maya/pipeline.py b/avalon/maya/pipeline.py index ba4005b99..73e1cfa71 100644 --- a/avalon/maya/pipeline.py +++ b/avalon/maya/pipeline.py @@ -125,8 +125,8 @@ def deferred(): # Create context menu context_label = "{}, {}".format( - api.Session["AVALON_ASSET"], - api.Session["AVALON_TASK"] + api.Session.get("AVALON_ASSET", "--"), + api.Session.get("AVALON_TASK", "--") ) cmds.menuItem( @@ -275,8 +275,8 @@ def _update_menu_task_label(): logger.warning("Can't find menuItem: {}".format(object_name)) return - label = "{}, {}".format(api.Session["AVALON_ASSET"], - api.Session["AVALON_TASK"]) + label = "{}, {}".format(api.Session.get("AVALON_ASSET", "--"), + api.Session.get("AVALON_TASK", "--")) cmds.menuItem(object_name, edit=True, label=label) diff --git a/avalon/nuke/command.py b/avalon/nuke/command.py index 58106995a..2a571723d 100644 --- a/avalon/nuke/command.py +++ b/avalon/nuke/command.py @@ -18,8 +18,16 @@ def reset_frame_range(): fps = float(api.Session.get("AVALON_FPS", 25)) nuke.root()["fps"].setValue(fps) - name = api.Session["AVALON_ASSET"] + name = api.Session.get("AVALON_ASSET") + if name is None: + log.warning("No AVALON_ASSET setup in current working session.") + return + asset = io.find_one({"name": name, "type": "asset"}) + if asset is None: + log.error("No AVALON_ASSET setup in current working session.") + return + asset_data = asset["data"] handles = get_handles(asset) diff --git a/avalon/nuke/pipeline.py b/avalon/nuke/pipeline.py index 149675c15..35cd7bbb0 100644 --- a/avalon/nuke/pipeline.py +++ b/avalon/nuke/pipeline.py @@ -274,7 +274,8 @@ def _install_menu(): menu = menubar.addMenu(api.Session["AVALON_LABEL"]) label = "{0}, {1}".format( - api.Session["AVALON_ASSET"], api.Session["AVALON_TASK"] + api.Session.get("AVALON_ASSET", "--"), + api.Session.get("AVALON_TASK", "--") ) context_action = menu.addCommand(label) context_action.setEnabled(False) diff --git a/avalon/tools/creator/app.py b/avalon/tools/creator/app.py index 25c79c1d6..ea2e0a00d 100644 --- a/avalon/tools/creator/app.py +++ b/avalon/tools/creator/app.py @@ -396,7 +396,7 @@ def refresh(self): listing = self.data["Listing"] asset = self.data["Asset"] - asset.setText(api.Session["AVALON_ASSET"]) + asset.setText(api.Session.get("AVALON_ASSET", "")) has_families = False diff --git a/avalon/tools/loader/app.py b/avalon/tools/loader/app.py index a0fd8337a..6b418b86a 100644 --- a/avalon/tools/loader/app.py +++ b/avalon/tools/loader/app.py @@ -430,7 +430,7 @@ def show(debug=False, parent=None, use_context=False): window.setStyleSheet(style.load_stylesheet()) if use_context: - context = {"asset": api.Session["AVALON_ASSET"]} + context = {"asset": api.Session.get("AVALON_ASSET")} window.set_context(context, refresh=True) else: window.refresh() diff --git a/avalon/tools/workfiles/app.py b/avalon/tools/workfiles/app.py index 70c614de7..f69934470 100644 --- a/avalon/tools/workfiles/app.py +++ b/avalon/tools/workfiles/app.py @@ -805,7 +805,7 @@ def on_asset_changed(self): def set_context(self, context): - if "asset" in context: + if context.get("asset"): asset = context["asset"] asset_document = io.find_one({ "name": asset, @@ -818,7 +818,7 @@ def set_context(self, context): # Force a refresh on Tasks? self.widgets["tasks"].set_asset(asset_document) - if "task" in context: + if context.get("task"): self.widgets["tasks"].select_task(context["task"]) def refresh(self): @@ -892,9 +892,8 @@ def show(root=None, debug=False, parent=None, use_context=True): window.refresh() if use_context: - context = {"asset": api.Session["AVALON_ASSET"], - "silo": api.Session["AVALON_SILO"], - "task": api.Session["AVALON_TASK"]} + context = {"asset": api.Session.get("AVALON_ASSET"), + "task": api.Session.get("AVALON_TASK")} window.set_context(context) window.show() diff --git a/res/houdini/MainMenuCommon.XML b/res/houdini/MainMenuCommon.XML index a492ef7cd..c72ece8a0 100644 --- a/res/houdini/MainMenuCommon.XML +++ b/res/houdini/MainMenuCommon.XML @@ -6,7 +6,8 @@ From 7929e234c8029104b445fbc86b3b41d145fdcd38 Mon Sep 17 00:00:00 2001 From: David Lai Date: Tue, 1 Sep 2020 19:37:54 +0800 Subject: [PATCH 2/9] Initialize workdir on host install if not yet initialized --- avalon/io.py | 3 +++ avalon/pipeline.py | 46 ++++++++++++++++++++++++++++++++--- avalon/tools/workfiles/app.py | 17 +------------ 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/avalon/io.py b/avalon/io.py index 5243660c9..251480552 100644 --- a/avalon/io.py +++ b/avalon/io.py @@ -132,6 +132,9 @@ def _from_environment(): # Name of current app ("AVALON_APP", None), + # Full name of current app (e.g. versioned name) + ("AVALON_APP_NAME", None), + # Path to working directory ("AVALON_WORKDIR", None), diff --git a/avalon/pipeline.py b/avalon/pipeline.py index c1d9f1f18..a10c7c102 100644 --- a/avalon/pipeline.py +++ b/avalon/pipeline.py @@ -59,7 +59,7 @@ def install(host): io.install() missing = list() - for key in ("AVALON_PROJECT", "AVALON_ASSET"): + for key in ("AVALON_PROJECTS", "AVALON_PROJECT"): if key not in Session: missing.append(key) @@ -72,6 +72,10 @@ def install(host): project = Session["AVALON_PROJECT"] log.info("Activating %s.." % project) + if not os.getenv("_AVALON_APP_INITIALIZED"): + log.info("Initializing working directory..") + initialize(Session) + config = find_config() # Optional host install function @@ -94,6 +98,37 @@ def install(host): log.info("Successfully installed Avalon!") +def initialize(session): + """Initialize Work Directory + + This finds the current AVALON_APP_NAME and tries to triggers its + `.toml` initialization step. Note that this will only be valid + whenever `AVALON_APP_NAME` is actually set in the current session. + + """ + # Find the application definition + app_name = session.get("AVALON_APP_NAME") + if not app_name: + log.error("No AVALON_APP_NAME session variable is set. " + "Unable to initialize app Work Directory.") + return + + app_definition = lib.get_application(app_name) + App = type( + "app_%s" % app_name, + (Application,), + { + "name": app_name, + "config": app_definition.copy() + } + ) + + # Initialize within the new session's environment + app = App() + env = app.environ(session) + app.initialize(env) + + def find_config(): log.info("Finding configuration for project..") @@ -423,7 +458,7 @@ def initialize(self, environment): self.log.error("Could not copy application file: %s" % e) self.log.error(" - %s -> %s" % (src, dst)) - def launch(self, environment): + def launch(self, environment, initialized=False): executable = lib.which(self.config["executable"]) if executable is None: @@ -432,6 +467,9 @@ def launch(self, environment): % (self.config["executable"], os.getenv("PATH")) ) + if initialized: + environment["_AVALON_APP_INITIALIZED"] = "1" + args = self.config.get("args", []) return lib.launch( executable=executable, @@ -444,12 +482,14 @@ def process(self, session, **kwargs): """Process the full Application action""" environment = self.environ(session) + initialized = False if kwargs.get("initialize", True): self.initialize(environment) + initialized = True if kwargs.get("launch", True): - return self.launch(environment) + return self.launch(environment, initialized) def _format(self, original, **kwargs): """Utility recursive dict formatting that logs the error clearly.""" diff --git a/avalon/tools/workfiles/app.py b/avalon/tools/workfiles/app.py index f69934470..e190e7a62 100644 --- a/avalon/tools/workfiles/app.py +++ b/avalon/tools/workfiles/app.py @@ -652,22 +652,7 @@ def initialize_work_directory(self): task=self._task) session.update(changes) - # Find the application definition - app_name = os.environ.get("AVALON_APP_NAME") - if not app_name: - log.error("No AVALON_APP_NAME session variable is set. " - "Unable to initialize app Work Directory.") - return - - app_definition = pipeline.lib.get_application(app_name) - App = type("app_%s" % app_name, - (pipeline.Application,), - {"config": app_definition.copy()}) - - # Initialize within the new session's environment - app = App() - env = app.environ(session) - app.initialize(env) + pipeline.initialize(session) # Force a full to the asset as opposed to just self.refresh() so # that it will actually check again whether the Work directory exists From 5851eb903e244794de740c6ce33e4f3b1fb06c24 Mon Sep 17 00:00:00 2001 From: David Lai Date: Wed, 2 Sep 2020 01:09:19 +0800 Subject: [PATCH 3/9] Add session schema version 3 AVALON_ASSET is not required in this version --- avalon/io.py | 5 +- avalon/schema/session-3.0.json | 146 +++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 avalon/schema/session-3.0.json diff --git a/avalon/io.py b/avalon/io.py index 251480552..ff918ac12 100644 --- a/avalon/io.py +++ b/avalon/io.py @@ -114,6 +114,9 @@ def _from_environment(): session = { item[0]: os.getenv(item[0], item[1]) for item in ( + # The schema name that should be used to validate this session + ("AVALON_SESSION_SCHEMA", "avalon-core:session-2.0"), + # Root directory of projects on disk ("AVALON_PROJECTS", None), @@ -202,7 +205,7 @@ def _from_environment(): ) if os.getenv(item[0], item[1]) is not None } - session["schema"] = "avalon-core:session-2.0" + session["schema"] = session["AVALON_SESSION_SCHEMA"] try: schema.validate(session) except schema.ValidationError as e: diff --git a/avalon/schema/session-3.0.json b/avalon/schema/session-3.0.json new file mode 100644 index 000000000..7fa20ef4a --- /dev/null +++ b/avalon/schema/session-3.0.json @@ -0,0 +1,146 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + + "title": "avalon-core:session-2.0", + "description": "The Avalon environment", + + "type": "object", + + "additionalProperties": true, + + "required": [ + "AVALON_PROJECTS", + "AVALON_PROJECT", + "AVALON_CONFIG" + ], + + "properties": { + "AVALON_PROJECTS": { + "description": "Absolute path to root of project directories", + "type": "string", + "example": "/nas/projects" + }, + "AVALON_PROJECT": { + "description": "Name of project", + "type": "string", + "pattern": "^\\w*$", + "example": "Hulk" + }, + "AVALON_ASSET": { + "description": "Name of asset", + "type": "string", + "pattern": "^\\w*$", + "example": "Bruce" + }, + "AVALON_SILO": { + "description": "Name of asset group or container", + "type": "string", + "pattern": "^\\w*$", + "example": "assets" + }, + "AVALON_TASK": { + "description": "Name of task", + "type": "string", + "pattern": "^\\w*$", + "example": "modeling" + }, + "AVALON_CONFIG": { + "description": "Name of Avalon configuration", + "type": "string", + "pattern": "^\\w*$", + "example": "polly" + }, + "AVALON_WORKDIR": { + "description": "Current working directory of a host, such as Maya's location of workspace.mel", + "type": "string", + "example": "/mnt/projects/alita/assets/vector/maya" + }, + "AVALON_APP": { + "description": "Name of application", + "type": "string", + "pattern": "^\\w*$", + "example": "maya2016" + }, + "AVALON_MONGO": { + "description": "Address to the asset database", + "type": "string", + "pattern": "^mongodb://[\\w/@:.]*$", + "example": "mongodb://localhost:27017", + "default": "mongodb://localhost:27017" + }, + "AVALON_DB": { + "description": "Name of database", + "type": "string", + "pattern": "^\\w*$", + "example": "avalon", + "default": "avalon" + }, + "AVALON_LABEL": { + "description": "Nice name of Avalon, used in e.g. graphical user interfaces", + "type": "string", + "example": "Mindbender", + "default": "Avalon" + }, + "AVALON_SENTRY": { + "description": "Address to Sentry", + "type": "string", + "pattern": "^http[\\w/@:.]*$", + "example": "https://5b872b280de742919b115bdc8da076a5:8d278266fe764361b8fa6024af004a9c@logs.mindbender.com/2", + "default": null + }, + "AVALON_DEADLINE": { + "description": "Address to Deadline", + "type": "string", + "pattern": "^http[\\w/@:.]*$", + "example": "http://192.168.99.101", + "default": null + }, + "AVALON_TIMEOUT": { + "description": "Wherever there is a need for a timeout, this is the default value.", + "type": "string", + "pattern": "^[0-9]*$", + "default": "1000", + "example": "1000" + }, + "AVALON_UPLOAD": { + "description": "Boolean of whether to upload published material to central asset repository", + "type": "string", + "default": null, + "example": "True" + }, + "AVALON_USERNAME": { + "description": "Generic username", + "type": "string", + "pattern": "^\\w*$", + "default": "avalon", + "example": "myself" + }, + "AVALON_PASSWORD": { + "description": "Generic password", + "type": "string", + "pattern": "^\\w*$", + "default": "secret", + "example": "abc123" + }, + "AVALON_INSTANCE_ID": { + "description": "Unique identifier for instances in a working file", + "type": "string", + "pattern": "^[\\w.]*$", + "default": "avalon.instance", + "example": "avalon.instance" + }, + "AVALON_CONTAINER_ID": { + "description": "Unique identifier for a loaded representation in a working file", + "type": "string", + "pattern": "^[\\w.]*$", + "default": "avalon.container", + "example": "avalon.container" + }, + "AVALON_DEBUG": { + "description": "Enable debugging mode. Some applications may use this for e.g. extended verbosity or mock plug-ins.", + "type": "string", + "default": null, + "example": "True" + } + } +} From a0ad8ee497bfd280ab568e108491a72db2487ff5 Mon Sep 17 00:00:00 2001 From: David Lai Date: Wed, 2 Sep 2020 01:15:09 +0800 Subject: [PATCH 4/9] Skip AVALON_WORKDIR compose if predefined --- avalon/pipeline.py | 20 ++++++++++---------- avalon/tools/workfiles/app.py | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/avalon/pipeline.py b/avalon/pipeline.py index a10c7c102..10d312fe0 100644 --- a/avalon/pipeline.py +++ b/avalon/pipeline.py @@ -74,7 +74,8 @@ def install(host): if not os.getenv("_AVALON_APP_INITIALIZED"): log.info("Initializing working directory..") - initialize(Session) + no_predefined_workdir = "AVALON_WORKDIR" not in Session + initialize(Session, reset_workdir=no_predefined_workdir) config = find_config() @@ -98,7 +99,7 @@ def install(host): log.info("Successfully installed Avalon!") -def initialize(session): +def initialize(session, reset_workdir): """Initialize Work Directory This finds the current AVALON_APP_NAME and tries to triggers its @@ -122,10 +123,8 @@ def initialize(session): "config": app_definition.copy() } ) - - # Initialize within the new session's environment app = App() - env = app.environ(session) + env = app.environ(session, reset_workdir) app.initialize(env) @@ -379,7 +378,7 @@ def is_compatible(self, session): return False return True - def environ(self, session): + def environ(self, session, reset_workdir=True): """Build application environment""" session = session.copy() @@ -387,10 +386,11 @@ def environ(self, session): session["AVALON_APP_NAME"] = self.name # Compute work directory - project = io.find_one({"type": "project"}) - template = project["config"]["template"]["work"] - workdir = _format_work_template(template, session) - session["AVALON_WORKDIR"] = os.path.normpath(workdir) + if reset_workdir: + project = io.find_one({"type": "project"}) + template = project["config"]["template"]["work"] + workdir = _format_work_template(template, session) + session["AVALON_WORKDIR"] = os.path.normpath(workdir) # Construct application environment from .toml config app_environment = self.config.get("environment", {}) diff --git a/avalon/tools/workfiles/app.py b/avalon/tools/workfiles/app.py index e190e7a62..a0d3a7841 100644 --- a/avalon/tools/workfiles/app.py +++ b/avalon/tools/workfiles/app.py @@ -651,8 +651,8 @@ def initialize_work_directory(self): asset=self._asset, task=self._task) session.update(changes) - - pipeline.initialize(session) + # Initialize within the new session's environment + pipeline.initialize(session, reset_workdir=True) # Force a full to the asset as opposed to just self.refresh() so # that it will actually check again whether the Work directory exists From b5c81369a8b0661b31c0bf3b0f71948ab076a441 Mon Sep 17 00:00:00 2001 From: David Lai Date: Wed, 2 Sep 2020 01:21:54 +0800 Subject: [PATCH 5/9] Improve workdir initialization Create sub-workdirs (default_dirs) even workdir exists. Avoid re-copy existed file. --- avalon/pipeline.py | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/avalon/pipeline.py b/avalon/pipeline.py index 10d312fe0..56293f5d1 100644 --- a/avalon/pipeline.py +++ b/avalon/pipeline.py @@ -426,24 +426,24 @@ def initialize(self, environment): workdir = environment["AVALON_WORKDIR"] workdir_existed = os.path.exists(workdir) if not workdir_existed: - os.makedirs(workdir) self.log.info("Creating working directory '%s'" % workdir) + os.makedirs(workdir) - # Create default directories from app configuration - default_dirs = self.config.get("default_dirs", []) - default_dirs = self._format(default_dirs, **environment) - if default_dirs: - self.log.debug("Creating default directories..") - for dirname in default_dirs: - try: - os.makedirs(os.path.join(workdir, dirname)) - self.log.debug(" - %s" % dirname) - except OSError as e: - # An already existing default directory is fine. - if e.errno == errno.EEXIST: - pass - else: - raise + # Create default directories from app configuration + default_dirs = self.config.get("default_dirs", []) + default_dirs = self._format(default_dirs, **environment) + if default_dirs: + self.log.debug("Creating default directories..") + for dirname in default_dirs: + try: + os.makedirs(os.path.join(workdir, dirname)) + self.log.debug(" - %s" % dirname) + except OSError as e: + # An already existing default directory is fine. + if e.errno == errno.EEXIST: + pass + else: + raise # Perform application copy for src, dst in self.config.get("copy", {}).items(): @@ -451,6 +451,9 @@ def initialize(self, environment): # Expand env vars src, dst = self._format([src, dst], **environment) + if os.path.isfile(dst): + continue + try: self.log.info("Copying %s -> %s" % (src, dst)) shutil.copy(src, dst) From 1c1872c1f7e420da7a00e65fe2e2448b202e0a7c Mon Sep 17 00:00:00 2001 From: David Lai Date: Wed, 2 Sep 2020 21:35:24 +0800 Subject: [PATCH 6/9] Add config-2.0.json With Allzpark, project config doesn't require [[apps]] --- avalon/inventory.py | 20 ++++++++- avalon/schema/config-2.0.json | 85 +++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 avalon/schema/config-2.0.json diff --git a/avalon/inventory.py b/avalon/inventory.py index a33dc126e..59d3ca6e1 100644 --- a/avalon/inventory.py +++ b/avalon/inventory.py @@ -146,7 +146,8 @@ def save(name, config, inventory): handlers = { "avalon-core:inventory-1.0": _save_inventory_1_0, - "avalon-core:config-1.0": _save_config_1_0 + "avalon-core:config-1.0": _save_config_1_0, + "avalon-core:config-2.0": _save_config_2_0, } for data in (inventory, config): @@ -340,6 +341,23 @@ def _save_config_1_0(project_name, data): io.replace_one(_filter, document) +def _save_config_2_0(project_name, data): + _filter = {"type": "project"} + + document = io.find_one(_filter) + + config = document["config"] + + config["tasks"] = data.get("tasks", []) + config["template"].update(data.get("template", {})) + config["families"] = data.get("families", []) + config["groups"] = data.get("groups", []) + + schema.validate(document) + + io.replace_one(_filter, document) + + def _report(added, updated): if added: print("+ added:") diff --git a/avalon/schema/config-2.0.json b/avalon/schema/config-2.0.json new file mode 100644 index 000000000..58d360861 --- /dev/null +++ b/avalon/schema/config-2.0.json @@ -0,0 +1,85 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + + "title": "avalon-core:config-2.0", + "description": "A project configuration.", + + "type": "object", + + "additionalProperties": false, + "required": [ + "template", + "tasks" + ], + + "properties": { + "schema": { + "description": "Schema identifier for payload", + "type": "string" + }, + "template": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^.*$": { + "type": "string" + } + } + }, + "tasks": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "icon": {"type": "string"}, + "group": {"type": "string"}, + "label": {"type": "string"} + }, + "required": ["name"] + } + }, + "apps": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "icon": {"type": "string"}, + "group": {"type": "string"}, + "label": {"type": "string"} + }, + "required": ["name"] + } + }, + "families": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "icon": {"type": "string"}, + "label": {"type": "string"}, + "hideFilter": {"type": "boolean"} + }, + "required": ["name"] + } + }, + "groups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "icon": {"type": "string"}, + "color": {"type": "string"}, + "order": {"type": ["integer", "number"]} + }, + "required": ["name"] + } + }, + "copy": { + "type": "object" + } + } +} From 42bb4b77b32e96492762dcc0c71c0a63433eb59a Mon Sep 17 00:00:00 2001 From: David Lai Date: Wed, 2 Sep 2020 21:35:37 +0800 Subject: [PATCH 7/9] Fix title --- avalon/schema/session-3.0.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avalon/schema/session-3.0.json b/avalon/schema/session-3.0.json index 7fa20ef4a..4513e6692 100644 --- a/avalon/schema/session-3.0.json +++ b/avalon/schema/session-3.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "avalon-core:session-2.0", + "title": "avalon-core:session-3.0", "description": "The Avalon environment", "type": "object", From a07e2838a0e3e1b77270dbdd75d040a9eec89263 Mon Sep 17 00:00:00 2001 From: David Lai Date: Wed, 2 Sep 2020 21:39:38 +0800 Subject: [PATCH 8/9] Partial revert 7929e234 Remove 'AVALON_PROJECTS' since it wasn't in the original implementation. --- avalon/pipeline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avalon/pipeline.py b/avalon/pipeline.py index 56293f5d1..e79292176 100644 --- a/avalon/pipeline.py +++ b/avalon/pipeline.py @@ -59,7 +59,7 @@ def install(host): io.install() missing = list() - for key in ("AVALON_PROJECTS", "AVALON_PROJECT"): + for key in ("AVALON_PROJECT", ): if key not in Session: missing.append(key) From b6429f5a2f9c3ebb5726cfdb6cc065531b51dbb4 Mon Sep 17 00:00:00 2001 From: David Lai Date: Mon, 5 Oct 2020 22:51:44 +0800 Subject: [PATCH 9/9] Revert "Add config-2.0.json" This reverts commit 1c1872c1 --- avalon/inventory.py | 20 +-------- avalon/schema/config-2.0.json | 85 ----------------------------------- 2 files changed, 1 insertion(+), 104 deletions(-) delete mode 100644 avalon/schema/config-2.0.json diff --git a/avalon/inventory.py b/avalon/inventory.py index 59d3ca6e1..a33dc126e 100644 --- a/avalon/inventory.py +++ b/avalon/inventory.py @@ -146,8 +146,7 @@ def save(name, config, inventory): handlers = { "avalon-core:inventory-1.0": _save_inventory_1_0, - "avalon-core:config-1.0": _save_config_1_0, - "avalon-core:config-2.0": _save_config_2_0, + "avalon-core:config-1.0": _save_config_1_0 } for data in (inventory, config): @@ -341,23 +340,6 @@ def _save_config_1_0(project_name, data): io.replace_one(_filter, document) -def _save_config_2_0(project_name, data): - _filter = {"type": "project"} - - document = io.find_one(_filter) - - config = document["config"] - - config["tasks"] = data.get("tasks", []) - config["template"].update(data.get("template", {})) - config["families"] = data.get("families", []) - config["groups"] = data.get("groups", []) - - schema.validate(document) - - io.replace_one(_filter, document) - - def _report(added, updated): if added: print("+ added:") diff --git a/avalon/schema/config-2.0.json b/avalon/schema/config-2.0.json deleted file mode 100644 index 58d360861..000000000 --- a/avalon/schema/config-2.0.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - - "title": "avalon-core:config-2.0", - "description": "A project configuration.", - - "type": "object", - - "additionalProperties": false, - "required": [ - "template", - "tasks" - ], - - "properties": { - "schema": { - "description": "Schema identifier for payload", - "type": "string" - }, - "template": { - "type": "object", - "additionalProperties": false, - "patternProperties": { - "^.*$": { - "type": "string" - } - } - }, - "tasks": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": {"type": "string"}, - "icon": {"type": "string"}, - "group": {"type": "string"}, - "label": {"type": "string"} - }, - "required": ["name"] - } - }, - "apps": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": {"type": "string"}, - "icon": {"type": "string"}, - "group": {"type": "string"}, - "label": {"type": "string"} - }, - "required": ["name"] - } - }, - "families": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": {"type": "string"}, - "icon": {"type": "string"}, - "label": {"type": "string"}, - "hideFilter": {"type": "boolean"} - }, - "required": ["name"] - } - }, - "groups": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": {"type": "string"}, - "icon": {"type": "string"}, - "color": {"type": "string"}, - "order": {"type": ["integer", "number"]} - }, - "required": ["name"] - } - }, - "copy": { - "type": "object" - } - } -}