def print_summary(self): from rez.utils.formatting import columnise pr = Printer(sys.stdout) txt = "Test results:\n%s" % ('-' * 80) pr(txt, heading) print( "%d succeeded, %d failed, %d skipped\n" % (self.num_success, self.num_failed, self.num_skipped) ) rows = [ ("Test", "Status", "Variant", "Description"), ("----", "------", "-------", "-----------") ] for test_result in self.test_results: rows.append(( test_result["test_name"], test_result["status"], test_result["variant"].root, test_result["description"] )) strs = columnise(rows) print('\n'.join(strs))
def print_package_versions(self): """Print a list of versions of the package this tool comes from, and indicate which version this tool is from.""" variants = self.context.get_tool_variants(self.tool_name) if variants: if len(variants) > 1: self._print_conflicting(variants) return 1 else: from rez.packages import iter_packages variant = next(iter(variants)) it = iter_packages(name=variant.name) rows = [] colors = [] for pkg in sorted(it, key=lambda x: x.version, reverse=True): if pkg.version == variant.version: name = "* %s" % pkg.qualified_name col = heading else: name = " %s" % pkg.qualified_name col = local if pkg.is_local else None label = "(local)" if pkg.is_local else "" rows.append((name, pkg.path, label)) colors.append(col) _pr = Printer() for col, line in zip(colors, columnise(rows)): _pr(line, col) return 0
def release(self, release_message=None, variants=None): self._print_header("Releasing %s..." % self.package.qualified_name) # test that we're in a state to release self.pre_release() release_path = self.package.config.release_packages_path release_data = self.get_release_data() changelog = release_data.get("changelog") previous_version = release_data.get("previous_version") previous_revision = release_data.get("previous_revision") # run pre-release hooks self.run_hooks(ReleaseHookEvent.pre_release, install_path=release_path, variants=variants, release_message=release_message, changelog=changelog, previous_version=previous_version, previous_revision=previous_revision) # release variants num_visited, released_variants = self.visit_variants( self._release_variant, variants=variants, release_message=release_message) # ignore skipped variants released_variants = [x for x in released_variants if x is not None] num_released = len(released_variants) # run post-release hooks self.run_hooks(ReleaseHookEvent.post_release, install_path=release_path, variants=released_variants, release_message=release_message, changelog=changelog, previous_version=previous_version, previous_revision=previous_revision) # perform post-release actions: tag repo etc if released_variants: self.post_release(release_message=release_message) self._print_header("Release Summary") msg = "\n%d of %d releases were successful" % (num_released, num_visited) if num_released < num_visited: Printer()(msg, warning) else: self._print(msg) if self.all_test_results.num_tests: print('') self.all_test_results.print_summary() print('') return num_released
def print_search_results(self, search_results, buf=sys.stdout): """Print formatted search results. Args: search_results (list of `ResourceSearchResult`): Search to format. """ formatted_lines = self.format_search_results(search_results) pr = Printer(buf) for txt, style in formatted_lines: pr(txt, style)
def _print_package_info(self, value, buf=sys.stdout, b=False): word = "is also" if b else "is" _pr = Printer(buf) request_str = os.path.basename(value) if request_str != value: return False def _print_package(package): if isinstance(package, Package): name = package.qualified_name else: name = package.qualified_package_name # Variant _pr("Package: %s" % name) path_str = "URI: %s" % package.uri if package.is_local: path_str += " (local)" _pr(path_str) try: req = PackageRequest(request_str) except: return False if req.conflict: return False package_name = req.name version_range = req.range # check for the package in the active context if self.context: variant = self.context.get_resolved_package(package_name) if variant and variant.version in version_range: _pr("'%s' %s a package in the active context:" % (package_name, word)) _print_package(variant) if self.context.load_path: _pr("Context: %s" % self.context.load_path) return True # find the package it = iter_packages(package_name, version_range) packages = sorted(it, key=lambda x: x.version) if packages: txt = "'%s' %s a package. The latest version" % (package_name, word) if not version_range.is_any(): txt += " in the range '%s'" % str(version_range) txt += " is:" _pr(txt) _print_package(packages[-1]) return True return False
def _print_header(self, txt, n=1): if self.quiet: return self._print('') if n <= 1: br = '=' * 80 title = "%s\n%s\n%s" % (br, txt, br) else: title = "%s\n%s" % (txt, '-' * len(txt)) pr = Printer(sys.stdout) pr(title, heading)
def _print_context_info(self, value, buf=sys.stdout, b=False): word = "is also" if b else "is" _pr = Printer(buf) path = os.path.abspath(value) if not os.path.isfile(path): return False try: ResolvedContext.load(path) except: return False _pr("'%s' %s a context. Use 'rez-context' for more information." % (path, word)) return True
def _print_suite_info(self, value, buf=sys.stdout, b=False): word = "is also" if b else "is" _pr = Printer(buf) path = os.path.abspath(value) if not os.path.isdir(path): return False try: Suite.load(path) except: return False _pr("'%s' %s a suite. Use 'rez-suite' for more information." % (path, word)) return True
def print_info(self, buf=sys.stdout, verbose=False): """Prints a message summarising the contents of the suite.""" _pr = Printer(buf) if not self.contexts: _pr("Suite is empty.") return context_names = sorted(self.contexts.keys()) _pr("Suite contains %d contexts:" % len(context_names)) if not verbose: _pr(' '.join(context_names)) return tools = self.get_tools().values() context_tools = defaultdict(set) context_variants = defaultdict(set) for entry in tools: context_name = entry["context_name"] context_tools[context_name].add(entry["tool_name"]) context_variants[context_name].add(str(entry["variant"])) _pr() rows = [["NAME", "VISIBLE TOOLS", "PATH"], ["----", "-------------", "----"]] for context_name in context_names: context_path = self._context_path(context_name) or '-' ntools = len(context_tools.get(context_name, [])) if ntools: nvariants = len(context_variants[context_name]) short_desc = "%d tools from %d packages" % (ntools, nvariants) else: short_desc = "no tools" rows.append((context_name, short_desc, context_path)) _pr("\n".join(columnise(rows)))
def build(self, context, variant, build_path, install_path, install=False, build_type=BuildType.local): """Perform the build. Note that most of the func args aren't used here - that's because this info is already passed to the custom build command via environment variables. """ ret = {} if self.write_build_scripts: # write out the script that places the user in a build env build_env_script = os.path.join(build_path, "build-env") create_forwarding_script(build_env_script, module=("build_system", "custom"), func_name="_FWD__spawn_build_shell", working_dir=self.working_dir, build_path=build_path, variant_index=variant.index, install=install, install_path=install_path) ret["success"] = True ret["build_env_script"] = build_env_script return ret # get build command command = self.package.build_command # False just means no build command if command is False: ret["success"] = True return ret def expand(txt): return txt.format(build_path=build_path, install="install" if install else '', install_path=install_path, name=self.package.name, root=self.package.root, variant_index=variant.index if variant.index is not None else '', version=self.package.version).strip() if isinstance(command, basestring): if self.build_args: command = command + ' ' + ' '.join(map(quote, self.build_args)) command = expand(command) cmd_str = command else: # list command = command + self.build_args command = list(map(expand, command)) cmd_str = ' '.join(map(quote, command)) if self.verbose: pr = Printer(sys.stdout) pr("Running build command: %s" % cmd_str, heading) # run the build command def _callback(executor): self._add_build_actions(executor, context=context, package=self.package, variant=variant, build_type=build_type, install=install, build_path=build_path, install_path=install_path) if self.opts: # write args defined in ./parse_build_args.py out as env vars extra_args = getattr(self.opts.parser, "_rezbuild_extra_args", []) for key, value in list(vars(self.opts).items()): if key in extra_args: varname = "__PARSE_ARG_%s" % key.upper() # do some value conversions if isinstance(value, bool): value = 1 if value else 0 elif isinstance(value, (list, tuple)): value = list(map(str, value)) value = list(map(quote, value)) value = ' '.join(value) executor.env[varname] = value retcode, _, _ = context.execute_shell(command=command, block=True, cwd=build_path, post_actions_callback=_callback) ret["success"] = (not retcode) return ret
def _print_conflicting(cls, variants): vars_str = " ".join(x.qualified_package_name for x in variants) msg = "Packages (in conflict): %s" % vars_str Printer()(msg, critical)
def print_header(txt, *nargs): pr = Printer(sys.stdout) pr(txt % nargs, heading)
def print_tools(self, buf=sys.stdout, verbose=False, context_name=None): """Print table of tools available in the suite. Args: context_name (str): If provided, only print the tools from this context. """ def _get_row(entry): context_name_ = entry["context_name"] tool_alias = entry["tool_alias"] tool_name = entry["tool_name"] properties = [] col = None variant = entry["variant"] if isinstance(variant, set): properties.append("(in conflict)") col = critical if verbose: package = ", ".join(x.qualified_package_name for x in variant) else: v = next(iter(variant)) package = "%s (+%d more)" % (v.qualified_package_name, len(variant) - 1) else: package = variant.qualified_package_name if tool_name == tool_alias: tool_name = "-" else: properties.append("(aliased)") if col is None: col = alias_col msg = " ".join(properties) row = [tool_alias, tool_name, package, context_name_, msg] return row, col if context_name: self._context(context_name) # check context exists context_names = [context_name] else: context_names = sorted(self.contexts.keys()) rows = [["TOOL", "ALIASING", "PACKAGE", "CONTEXT", ""], ["----", "--------", "-------", "-------", ""]] colors = [None, None] entries_dict = defaultdict(list) for d in self.get_tools().values(): entries_dict[d["context_name"]].append(d) if verbose: # add hidden entries for d in self.hidden_tools: d_ = d.copy() d_["hidden"] = True entries_dict[d["context_name"]].append(d_) # add conflicting tools for docs in self.tool_conflicts.values(): for d in docs: d_ = d.copy() d_["conflicting"] = True entries_dict[d["context_name"]].append(d_) for i, context_name in enumerate(context_names): entries = entries_dict.get(context_name, []) if entries: if i: rows.append(('', '', '', '', '')) colors.append(None) entries = sorted(entries, key=lambda x: x["tool_alias"].lower()) for entry in entries: row, col = _get_row(entry) if "hidden" in entry: row[-1] = "(hidden)" rows.append(row) colors.append(warning) elif "conflicting" in entry: row[-1] = "(not visible)" rows.append(row) colors.append(warning) else: rows.append(row) colors.append(col) if rows: _pr = Printer(buf) for col, line in zip(colors, columnise(rows)): _pr(line, col) else: _pr("No tools available.")
def _print_tool_info(self, value, buf=sys.stdout, b=False): word = "is also" if b else "is" _pr = Printer(buf) def _load_wrapper(filepath): try: return Wrapper(filepath) except: return # find it on disk filepath = None unpathed = (os.path.basename(value) == value) if unpathed: filepath = which(value) if filepath is None: path = os.path.abspath(value) if os.path.exists(path): filepath = path if not filepath or not os.path.isfile(filepath): return False # is it a suite wrapper? tool_name = os.path.basename(filepath) w = _load_wrapper(filepath) if w: _pr("'%s' %s a suite tool:" % (tool_name, word)) w.print_about() return True # is it a tool in a current context? if self.context: variants = self.context.get_tool_variants(tool_name) if variants: _pr("'%s' %s a tool in the active context:" % (tool_name, word)) _pr("Tool: %s" % tool_name) if self.context.load_path: _pr("Context: %s" % self.context.load_path) if len(variants) > 1: vars_str = " ".join(x.qualified_package_name for x in variants) msg = "Packages (in conflict): %s" % vars_str _pr(msg, critical) else: variant = iter(variants).next() _pr("Package: %s" % variant.qualified_package_name) return True # is it actually a suite wrapper, but it's being hidden by another tool # on $PATH with the same name? if unpathed: for suite in self.suites: filepath_ = os.path.join(suite.tools_path, tool_name) if os.path.isfile(filepath_): w = _load_wrapper(filepath_) if w: _pr( "'%s' %s a suite tool, but is hidden by an unknown tool '%s':" % (tool_name, word, filepath), warning) w.print_about() return True return False
def print_tools(self, pattern=None, buf=sys.stdout): """Print a list of visible tools. Args: pattern (str): Only list tools that match this glob pattern. """ seen = set() rows = [] context = self.context if context: data = context.get_tools() conflicts = set(context.get_conflicting_tools().keys()) for _, (variant, tools) in sorted(data.items()): pkg_str = variant.qualified_package_name for tool in tools: if pattern and not fnmatch(tool, pattern): continue if tool in conflicts: label = "(in conflict)" color = critical else: label = '' color = None rows.append( [tool, '-', pkg_str, "active context", label, color]) seen.add(tool) for suite in self.suites: for tool, d in suite.get_tools().iteritems(): if tool in seen: continue if pattern and not fnmatch(tool, pattern): continue label = [] color = None path = which(tool) if path: path_ = os.path.join(suite.tools_path, tool) if path != path_: label.append("(hidden by unknown tool '%s')" % path) color = warning variant = d["variant"] if isinstance(variant, set): pkg_str = ", ".join(variant) label.append("(in conflict)") color = critical else: pkg_str = variant.qualified_package_name orig_tool = d["tool_name"] if orig_tool == tool: orig_tool = '-' label = ' '.join(label) source = ("context '%s' in suite '%s'" % (d["context_name"], suite.load_path)) rows.append([tool, orig_tool, pkg_str, source, label, color]) seen.add(tool) _pr = Printer(buf) if not rows: _pr("No matching tools.") return False headers = [["TOOL", "ALIASING", "PACKAGE", "SOURCE", "", None], ["----", "--------", "-------", "------", "", None]] rows = headers + sorted(rows, key=lambda x: x[0].lower()) print_colored_columns(_pr, rows) return True