def load(cls, path): if not os.path.exists(path): open(path) # raise IOError filepath = os.path.join(path, "suite.yaml") if not os.path.isfile(filepath): raise SuiteError("Not a suite: %r" % path) try: with open(filepath) as f: data = yaml.load(f.read(), Loader=yaml.FullLoader) except YAMLError as e: raise SuiteError("Failed loading suite: %s" % str(e)) s = cls.from_dict(data) s.load_path = os.path.realpath(path) return s
def _validate_tool(self, context_name, tool_name): context = self.context(context_name) context_tools = context.get_tools(request_only=True) for _, tool_names in context_tools.values(): if tool_name in tool_names: return raise SuiteError("No such tool %r in context %r" % (tool_name, context_name))
def validate(self): """Validate the suite.""" for context_name in self.context_names: context = self.context(context_name) try: context.validate() except ResolvedContextError as e: raise SuiteError("Error in context %r: %s" % (context_name, str(e)))
def add_context(self, name, context): """Add a context to the suite. Args: name (str): Name to store the context under. context (ResolvedContext): Context to add. """ if name in self.contexts: raise SuiteError("Context already in suite: %r" % name) if not context.success: raise SuiteError("Context is not resolved: %r" % name) self.contexts[name] = dict(name=name, context=context.copy(), tool_aliases={}, hidden_tools=set(), priority=self._next_priority) self._flush_tools()
def save(self, path, verbose=False): """Save the suite to disk. Args: path (str): Path to save the suite to. If a suite is already saved at `path`, then it will be overwritten. Otherwise, if `path` exists, an error is raised. """ path = os.path.realpath(path) if os.path.exists(path): if self.load_path and self.load_path == path: if verbose: print "saving over previous suite..." for context_name in self.context_names: self.context(context_name) # load before dir deleted shutil.rmtree(path) else: raise SuiteError("Cannot save, path exists: %r" % path) contexts_path = os.path.join(path, "contexts") os.makedirs(contexts_path) # write suite data data = self.to_dict() filepath = os.path.join(path, "suite.yaml") with open(filepath, "w") as f: f.write(dump_yaml(data)) # write contexts for context_name in self.context_names: context = self.context(context_name) context._set_parent_suite(path, context_name) filepath = self._context_path(context_name, path) if verbose: print "writing %r..." % filepath context.save(filepath) # create alias wrappers tools_path = os.path.join(path, "bin") os.makedirs(tools_path) if verbose: print "creating alias wrappers in %r..." % tools_path tools = self.get_tools() for tool_alias, d in tools.iteritems(): tool_name = d["tool_name"] context_name = d["context_name"] if verbose: print ("creating %r -> %r (%s context)..." % (tool_alias, tool_name, context_name)) filepath = os.path.join(tools_path, tool_alias) create_forwarding_script(filepath, module="suite", func_name="_FWD__invoke_suite_tool_alias", context_name=context_name, tool_name=tool_name)
def alias_tool(self, context_name, tool_name, tool_alias): """Register an alias for a specific tool. Note that a tool alias takes precedence over a context prefix/suffix. Args: context_name (str): Context containing the tool. tool_name (str): Name of tool to alias. tool_alias (str): Alias to give the tool. """ data = self._context(context_name) aliases = data["tool_aliases"] if tool_name in aliases: raise SuiteError("Tool %r in context %r is already aliased to %r" % (tool_name, context_name, aliases[tool_name])) self._validate_tool(context_name, tool_name) aliases[tool_name] = tool_alias self._flush_tools()
def _context(self, name): data = self.contexts.get(name) if not data: raise SuiteError("No such context: %r" % name) return data