def _get_context(self, requires, quiet=False): # if using current env, only return current context if it meets # requirements, otherwise return None if self.use_current_env: current_context = ResolvedContext.get_current() if current_context is None: return None reqs = map(Requirement, requires) current_reqs = current_context.get_resolve_as_exact_requests() meets_requirements = ( RequirementList(current_reqs) == RequirementList(current_reqs + reqs) ) if meets_requirements: return current_context else: return None # create context or use cached context key = tuple(requires) context = self.contexts.get(key) if context is None: if self.verbose and not quiet: self._print_header( "Resolving test environment: %s\n", ' '.join(map(quote, requires)) ) with open(os.devnull, 'w') as f: context = ResolvedContext( package_requests=requires, package_paths=self.package_paths, buf=(f if quiet else None), timestamp=self.timestamp, **self.context_kwargs ) self.contexts[key] = context if not context.success and not quiet: context.print_info(buf=self.stderr) return context
def _eq(reqs, expected_reqs): _print("requirements(%s) == requirements(%s)" % (' '.join(reqs), ' '.join(expected_reqs))) reqs_ = [Requirement(x) for x in reqs] reqlist = RequirementList(reqs_) _print("result: %s" % str(reqlist)) exp_reqs_ = [Requirement(x) for x in expected_reqs] self.assertTrue(reqlist.requirements == exp_reqs_)
def _confl(reqs, a, b): _print("requirements(%s) == %s <--!--> %s" % (' '.join(reqs), a, b)) reqs_ = [Requirement(x) for x in reqs] reqlist = RequirementList(reqs_) _print("result: %s" % str(reqlist)) a_req = Requirement(a) b_req = Requirement(b) self.assertTrue(reqlist.conflict == (a_req, b_req))
def _on_variant_requires(self, variant, params): """ Only run test on variants whose direct requirements are a subset of, and do not conflict with, the list given in 'value' param. For example, if on_variants.requires is ['foo', 'bah'] then only variants containing both these requirements will be selected; ['!foo', 'bah'] would select those variants with bah present and not foo. """ requires_filter = params["value"] reqlist = RequirementList(variant.variant_requires + requires_filter) if reqlist.conflict: return False # test if variant requires is a subset of given requires filter. # This works because RequirementList merges requirements. # if RequirementList(variant.variant_requires) != reqlist: return False return True
def _on_variant_requires(self, variant, params): """ Only run test on variants whose direct requirements are a subset of, and do not conflict with, the list given in 'value' param. For example, if on_variants.value is ['foo', 'bah'] then only variants containing both these requirements will be selected; ['!foo', 'bah'] would select those variants with bah present and not foo; ['!foo'] would select all variants without foo present. """ requires_filter = params["value"] reqlist = RequirementList(variant.variant_requires + requires_filter) if reqlist.conflict: return False # If the combined requirements, minus conflict requests, is equal to the # variant's requirements, then this variant is selected. # reqs1 = RequirementList(x for x in reqlist if not x.conflict) reqs2 = RequirementList(x for x in variant.variant_requires if not x.conflict) return (reqs1 == reqs2)
def _eq(reqs, expected_reqs): _print("requirements(%s) == requirements(%s)" % (' '.join(reqs), ' '.join(expected_reqs))) reqs_ = [Requirement(x) for x in reqs] reqlist = RequirementList(reqs_) _print("result: %s" % str(reqlist)) exp_reqs_ = [Requirement(x) for x in expected_reqs] self.assertTrue(reqlist.requirements == exp_reqs_) exp_names = set(x.name for x in exp_reqs_ if not x.conflict) self.assertTrue(reqlist.names == exp_names) exp_confl_names = set(x.name for x in exp_reqs_ if x.conflict) self.assertTrue(reqlist.conflict_names == exp_confl_names)
def _contextChanged(self, flags=0): self._set_stale(self.context_model.is_stale()) if flags & (ContextModel.PACKAGES_PATH_CHANGED | ContextModel.CONTEXT_CHANGED): # update icons new_icons = [] if self.variant.index is not None: package = self.variant.parent if package.num_variants > 1: txt = "1 of %d variants" % package.num_variants new_icons.append(("variant", txt)) if self.variant.is_local: new_icons.append(("local", "package is local")) package_paths = PackageSearchPath(self.context_model.packages_path) package_filter = PackageFilterList.from_pod(self.context_model.package_filter) # TODO: move this all into a thread, it's blocking up the GUI during context load if self.variant in package_paths: # find all >= version packages, so we can determine tick type ge_range = VersionRange.from_version(self.variant.version, ">=") packages = None try: it = package_paths.iter_packages(name=self.variant.name, range_=ge_range) packages = sorted(it, key=lambda x: x.version) except: pass # apply a tick icon if appropriate ticked = False if packages: # test if variant is latest package latest_pkg = packages[-1] if self.variant.version == latest_pkg.version: new_icons.append(("green_tick", "package is latest")) ticked = True range_ = None packages_ = None # test if variant is in request, and is latest possible if not ticked: range_ = None try: request = self.context().requested_packages(True) reqlist = RequirementList(request) if self.variant.name in reqlist.names: variant_ = reqlist.get(self.variant.name) if not variant_.conflict: range_ = variant_.range except: pass if range_ is not None: packages_ = [x for x in packages if x.version in range_] if packages_: latest_pkg = packages_[-1] if self.variant.version == latest_pkg.version: new_icons.append(("yellow_tick", "package is latest possible")) ticked = True packages2 = [x for x in (packages_ or packages) if x.version > self.variant.version] # test if variant is latest within package filter if (not ticked and packages2 and package_filter): if all(package_filter.excludes(x) for x in packages2): new_icons.append(("yellow_tick", "package is latest possible")) ticked = True # test if variant was latest package at time of resolve if not ticked and self.variant.timestamp: untimestamped_packages = [x for x in packages if not x.timestamp] if not untimestamped_packages: resolve_time = self.context().timestamp old_packages = [x for x in packages if x.timestamp <= resolve_time] if old_packages: latest_pkg = old_packages[-1] if self.variant.version == latest_pkg.version: new_icons.append( ("green_white_tick", "package was latest at time of resolve")) ticked = True # test if variant is in request, and was latest possible at # the time of resolve if (not ticked and self.variant.timestamp and range_ is not None and packages_ is not None): untimestamped_packages = any(x for x in packages_ if not x.timestamp) if not untimestamped_packages: resolve_time = self.context().timestamp old_packages = [x for x in packages_ if x.timestamp <= resolve_time] if old_packages: latest_pkg = old_packages[-1] if self.variant.version == latest_pkg.version: new_icons.append( ("yellow_white_tick", "package was latest possible at time of resolve")) ticked = True # test if variant is within package filter, and was latest # possible at the time of resolve if (not ticked and packages2 and package_filter and self.variant.timestamp): untimestamped_packages = any(x for x in (packages_ or packages) if not x.timestamp) if not untimestamped_packages: newer_package = any(x for x in packages2 if not package_filter.excludes(x) and x.timestamp <= resolve_time) if not newer_package: new_icons.append( ("yellow_white_tick", "package was latest possible at time of resolve")) ticked = True # bring in the old man if not ticked: new_icons.append( ("old_man", "newer packages are/were available")) else: new_icons.append(("error", "package is not in the search path")) self._set_icons(new_icons) if (not self.hide_locks) and (flags & (ContextModel.LOCKS_CHANGED | ContextModel.CONTEXT_CHANGED)): # update lock icon lock = self.context_model.get_patch_lock(self.variant.name) if lock is None: lock = self.context_model.default_patch_lock icon_name = "%s_faint" % lock.name else: icon_name = lock.name # update lock tooltip if lock == PatchLock.no_lock: desc = lock.description else: req = self._get_lock_requirement(lock) if req: if lock == PatchLock.lock: desc = "Exact version (%s)" % str(req) else: unit = lock.description.split()[0] desc = ("%s version updates only (%s.*)" % (unit.capitalize(), str(req))) else: desc = lock.description self._set_lock_icon(icon_name, desc.lower())