def _read(path): try: with open(path) as f: data = toml.load(f) except IOError: raise return data
def _read(root, name): fname = os.path.join(root, ".%s.toml" % name) try: with open(fname) as f: data = toml.load(f) except IOError: raise return data
def test_init(): """Initialising a new project yields defaults""" test_project = tempfile.mkdtemp(dir=self._tempdir) inventory_fname = os.path.join(test_project, ".inventory.toml") config_fname = os.path.join(test_project, ".config.toml") assert 0 == subprocess.call( [sys.executable, "-u", "-m", "avalon.inventory", "--init"], cwd=test_project) assert os.path.isfile(inventory_fname), ".inventory.toml not found" assert os.path.isfile(config_fname), ".config.toml not found" with open(inventory_fname) as f: inventory_dict = toml.load(f) assert_equals(inventory_dict, inventory.DEFAULTS["inventory"]) with open(config_fname) as f: config_dict = toml.load(f) assert_equals(config_dict, inventory.DEFAULTS["config"])
def get_project_apps(entity): """ Get apps from project Requirements: 'Entity' MUST be object of ftrack entity with entity_type 'Project' Checking if app from ftrack is available in Templates/bin/{app_name}.toml Returns: Array with dictionaries with app Name and Label """ apps = [] for app in entity['custom_attributes']['applications']: try: app_config = {} app_config['name'] = app app_config['label'] = toml.load(avalon.lib.which_app(app))['label'] apps.append(app_config) except Exception as e: log.warning('Error with application {0} - {1}'.format(app, e)) return apps
def _read(path): with open(path) as f: return toml.load(f)
def launch(self, name): """Launch `app` Arguments: name (str): Name of app """ application_definition = lib.which_app(name) if application_definition is None: return terminal.log( "Application Definition for '%s' not found." % name, terminal.ERROR) try: with open(application_definition) as f: app = toml.load(f) terminal.log(json.dumps(app, indent=4), terminal.DEBUG) schema.validate(app, "application") except (schema.ValidationError, schema.SchemaError, toml.TomlDecodeError) as e: terminal.log("Application definition was invalid.", terminal.ERROR) terminal.log("%s" % e, terminal.ERROR) return terminal.log(" - %s" % application_definition, terminal.ERROR) executable = lib.which(app["executable"]) if executable is None: return terminal.log( "'%s' not found on your PATH\n%s" % (app["executable"], os.getenv("PATH")), terminal.ERROR) frame = self.current_frame() frame["environment"]["root"] = self._root template_private = frame["config"]["template"]["work"] try: workdir = template_private.format( **dict(user=getpass.getuser(), app=app["application_dir"], **frame["environment"])) except KeyError as e: return terminal.log("Missing environment variable: %s" % e, terminal.ERROR) # TODO(marcus): These shouldn't be necessary # once the templates are used. # ---------------------------------------------------------------------- template_rootpath = template_private.split("{silo}")[0] template_assetpath = template_private.split("{asset}")[0] + "{asset}" template_taskpath = template_private.split("{task}")[0] + "{task}" silospath = template_rootpath.format(**frame["environment"]) assetpath = template_assetpath.format(**frame["environment"]) taskpath = template_taskpath.format(**frame["environment"]) frame["environment"]["silospath"] = silospath frame["environment"]["assetpath"] = assetpath frame["environment"]["taskpath"] = taskpath frame["environment"]["workdir"] = workdir # ---------------------------------------------------------------------- # TODO(marcus): These will eventually replace the name-based # references currently stored in the environment. frame["environment"]["_project"] = frame["project"] frame["environment"]["_asset"] = frame["asset"] environment = os.environ.copy() environment = dict( environment, **{ "AVALON_" + key.upper(): str(value) for key, value in frame["environment"].items() }) try: app = lib.dict_format(app, **environment) except KeyError as e: terminal.log( "Application error: variable %s " "not found in application .json" % e, terminal.ERROR) terminal.log(json.dumps(environment, indent=4, sort_keys=True), terminal.ERROR) return terminal.log( "This is typically a bug in the pipeline, " "ask your developer.", terminal.ERROR) for key, value in app.get("environment", {}).items(): if isinstance(value, list): # Treat list values as application_definition variables environment[key] = os.pathsep.join(value) elif isinstance(value, six.string_types): if PY2: # Protect against unicode in the environment encoding = sys.getfilesystemencoding() environment[key] = value.encode(encoding) else: environment[key] = value else: terminal.log( "'%s': Unsupported environment variable in %s" % (value, application_definition), terminal.ERROR) raise TypeError("Unsupported environment variable") try: os.makedirs(workdir) terminal.log("Creating working directory '%s'" % workdir, terminal.INFO) except OSError as e: # An already existing working directory is fine. if e.errno == errno.EEXIST: terminal.log("Existing working directory found.", terminal.INFO) else: terminal.log("Could not create working directory.", terminal.ERROR) return terminal.log(traceback.format_exc(), terminal.ERROR) else: terminal.log("Creating default directories..", terminal.DEBUG) for dirname in app.get("default_dirs", []): terminal.log(" - %s" % dirname, terminal.DEBUG) os.makedirs(os.path.join(workdir, dirname)) # Perform application copy for src, dst in app.get("copy", {}).items(): dst = os.path.join(workdir, dst) try: terminal.log("Copying %s -> %s" % (src, dst)) shutil.copy(src, dst) except OSError as e: terminal.log("Could not copy application file: %s" % e, terminal.ERROR) terminal.log(" - %s -> %s" % (src, dst), terminal.ERROR) item = next(app for app in frame["config"]["apps"] if app["name"] == name) args = item.get("args", []) + app.get("arguments", []) try: popen = lib.launch( executable=executable, args=args, environment=environment, ) except ValueError: return terminal.log(traceback.format_exc()) except OSError: return terminal.log(traceback.format_exc()) except Exception as e: terminal.log("Something unexpected happened..") return terminal.log(traceback.format_exc()) else: terminal.log(json.dumps(environment, indent=4, sort_keys=True), terminal.DEBUG) terminal.log("Launching {executable} {args}".format( executable=executable, args=" ".join(args))) process = {} class Thread(QtCore.QThread): messaged = Signal(str) def run(self): for line in lib.stream(process["popen"].stdout): self.messaged.emit(line.rstrip()) self.messaged.emit("%s killed." % process["app"]["executable"]) thread = Thread() thread.messaged.connect(lambda line: terminal.log(line, terminal.INFO)) process.update({"app": app, "thread": thread, "popen": popen}) self._processes.append(process) thread.start() return process