def set_packages(self, packages): package_paths = self.context_model.packages_path self.help_1 = PackageHelp(self.variant.name, paths=package_paths) self.tab.setTabEnabled(0, self.help_1.success) if self.help_1.success: self._apply_help(self.help_1, 0) label = "latest help (%s)" % self.help_1.package.qualified_name self.tab.setTabText(0, label) exact_range = VersionRange.from_version(self.variant.version, "==") self.help_2 = PackageHelp(self.variant.name, exact_range, paths=package_paths) self.tab.setTabEnabled(1, self.help_2.success) label = None if self.help_2.success: self._apply_help(self.help_2, 1) label = "help for %s" if label: self.tab.setTabText(1, label % self.help_2.package.qualified_name) if self.help_1.success or self.help_2.success: self.tab.show() else: self.no_help_label.show()
def get_package(name, version, paths=None): """Get an exact version of a package. Args: name (str): Name of the package, eg 'maya'. version (Version or str): Version of the package, eg '1.0.0' paths (list of str, optional): paths to search for package, defaults to `config.packages_path`. Returns: `Package` object, or None if the package was not found. """ if isinstance(version, basestring): range_ = VersionRange("==%s" % version) else: range_ = VersionRange.from_version(version, "==") it = iter_packages(name, range_, paths) try: return it.next() except StopIteration: return None
def set_packages(self, packages): package_paths = self.context_model.packages_path self.help_1 = PackageHelp(self.variant.name, paths=package_paths) self.tab.setTabEnabled(0, self.help_1.success) if self.help_1.success: self._apply_help(self.help_1, 0) label = "latest help (%s)" % self.help_1.package.qualified_name self.tab.setTabText(0, label) exact_range = VersionRange.from_version(self.variant.version, "==") self.help_2 = PackageHelp(self.variant.name, exact_range, paths=package_paths) self.tab.setTabEnabled(1, self.help_2.success) label = None if self.help_2.success: self._apply_help(self.help_2, 1) label = "help for %s" if label: self.tab.setTabText(1, label % self.help_2.package.qualified_name) if self.help_1.success or self.help_2.success: self.tab.show() else: self.no_help_label.show()
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())
def test_version_range(self): def _eq(a, b): _print("'%s' == '%s'" % (a, b)) a_range = VersionRange(a) b_range = VersionRange(b) self.assertTrue(a_range == b_range) self.assertTrue(a_range.issuperset(a_range)) self.assertTrue(a_range.issuperset(b_range)) self.assertTrue(VersionRange(str(a_range)) == a_range) self.assertTrue(VersionRange(str(b_range)) == a_range) self.assertTrue(hash(a_range) == hash(b_range)) a_ = a.replace('.', '-') a_ = a_.replace("--", "..") a_range_ = VersionRange(a_) self.assertTrue(a_range_ == a_range) self.assertTrue(hash(a_range_) == hash(a_range)) range_strs = a.split('|') ranges = [VersionRange(x) for x in range_strs] ranges_ = ranges[0].union(ranges[1:]) self.assertTrue(ranges_ == a_range) self.assertTrue(a_range | b_range == a_range) self.assertTrue(a_range - b_range is None) self.assertTrue(b_range - a_range is None) self.assertTrue(VersionRange() & a_range == a_range) self.assertTrue(b_range.span() & a_range == a_range) a_inv = a_range.inverse() self.assertTrue(a_inv == ~b_range) if a_inv: self.assertTrue(~a_inv == a_range) self.assertTrue(a_range | a_inv == VersionRange()) self.assertTrue(a_range & a_inv is None) a_ranges = a_range.split() a_range_ = a_ranges[0].union(a_ranges[1:]) self.assertTrue(a_range_ == b_range) def _and(a, b, c): _print("'%s' & '%s' == '%s'" % (a, b, c)) a_range = VersionRange(a) b_range = VersionRange(b) c_range = None if c is None else VersionRange(c) self.assertTrue(a_range & b_range == c_range) self.assertTrue(b_range & a_range == c_range) a_or_b = a_range | b_range a_and_b = a_range & b_range a_sub_b = a_range - b_range b_sub_a = b_range - a_range ranges = [a_and_b, a_sub_b, b_sub_a] ranges = [x for x in ranges if x] self.assertTrue(ranges[0].union(ranges[1:]) == a_or_b) def _inv(a, b): a_range = VersionRange(a) b_range = VersionRange(b) self.assertTrue(~a_range == b_range) self.assertTrue(~b_range == a_range) self.assertTrue(a_range | b_range == VersionRange()) self.assertTrue(a_range & b_range is None) # simple cases _print() _eq("", "") _eq("1", "1") _eq("1.0.0", "1.0.0") _eq("3+<3_", "3") _eq("_+<__", "_") _eq("1.2+<=2.0", "1.2..2.0") _eq("10+,<20", "10+<20") _eq("1+<1.0", "1+<1.0") _eq(">=2", "2+") # optimised cases _eq("3|3", "3") _eq("3|1", "1|3") _eq("5|3|1", "1|3|5") _eq("1|1_", "1+<1__") _eq("1|1_|1__", "1+,<1___") _eq("|", "") _eq("||", "||||||||") _eq("1|1_+", "1+") _eq("<1|1", "<1_") _eq("1+<3|3+<5", "1+<5") _eq(">4<6|1+<3", "1+<3|>4,<6") _eq("4+<6|1+<3|", "") _eq("4|2+", "2+") _eq("3|<5", "<5") _eq("<3|>3", ">3|<3") _eq("3+|<3", "") _eq("3+|<4", "") _eq("2+<=6|3+<5", "2..6") _eq("3+,<5|2+<=6", "2+<=6") _eq("2|2+", "2+") _eq("2|2.1+", "2+") _eq("2|<2.1", "<2_") _eq("3..3", "==3") _eq(">=3,<=3", "==3") # AND'ing _and("3", "3", "3") _and("1", "==1", "==1") _and("", "==1", "==1") _and("3", "4", None) _and("<3", "5+", None) _and("4+<6", "6+<8", None) _and("2+", "<=4", "2..4") _and("1", "1.0", "1.0") _and("4..6", "6+<8", "==6") # inverse _inv("3+", "<3") _inv("<=3", ">3") _inv("3.5", "<3.5|3.5_+") self.assertTrue(~VersionRange() is None) # odd (but valid) cases _eq(">", ">") # greater than the empty version _eq("+", "") # greater or equal to empty version (is all vers) _eq(">=", "") # equivalent to above _eq("<=", "==") # less or equal to empty version (is only empty) _eq("..", "==") # from empty version to empty version _eq("+<=", "==") # equivalent to above invalid_range = [ "4+<2", # lower bound greater than upper ">3<3", # both greater and less than same version ">3<=3", # greater and less or equal to same version "3+<3" # greater and equal to, and less than, same version ] for s in invalid_range: self.assertRaises(VersionError, VersionRange, s) invalid_syntax = [ "<", # less than the empty version "><", # both greater and less than empty version ">3>4", # both are lower bounds "<3<4", # both are upper bounds "<4>3", # upper bound before lower ",<4", # leading comma "4+,", # trailing comma "1>=", # pre-lower-op in post "+1", # post-lower-op in pre "4<", # pre-upper-op in post "1+<2<3" # more than two bounds ] for s in invalid_syntax: self.assertRaises(VersionError, VersionRange, s) # test simple logic self.assertTrue(VersionRange("").is_any()) self.assertTrue(VersionRange("2+<4").bounded()) self.assertTrue(VersionRange("2+").lower_bounded()) self.assertTrue(not VersionRange("2+").upper_bounded()) self.assertTrue(not VersionRange("2+").bounded()) self.assertTrue(VersionRange("<2").upper_bounded()) self.assertTrue(not VersionRange("<2").lower_bounded()) self.assertTrue(not VersionRange("<2").bounded()) # test range from version(s) v = Version("3") self.assertTrue( VersionRange.from_version(v, "eq") == VersionRange("==3")) self.assertTrue( VersionRange.from_version(v, "gt") == VersionRange(">3")) self.assertTrue( VersionRange.from_version(v, "gte") == VersionRange("3+")) self.assertTrue( VersionRange.from_version(v, "lt") == VersionRange("<3")) self.assertTrue( VersionRange.from_version(v, "lte") == VersionRange("<=3")) range1 = VersionRange.from_version(Version("2"), "gte") range2 = VersionRange.from_version(Version("4"), "lte") _eq(str(range1 & range2), "2..4") v2 = Version("6.0") v3 = Version("4") self.assertTrue( VersionRange.from_versions([v, v2, v3]) == VersionRange( "==3|==4|==6.0")) # test behaviour in sets def _eq2(a, b): _print("'%s' == '%s'" % (a, b)) self.assertTrue(a == b) a = VersionRange("1+<=2.5") b = VersionRange("1..2.5") c = VersionRange(">=5") d = VersionRange(">6.1.0") e = VersionRange("3.2") _eq2(set([a]) - set([a]), set()) _eq2(set([a]) - set([b]), set()) _eq2(set([a, a]) - set([a]), set()) _eq2(set([b, c, d, e]) - set([a]), set([c, d, e])) _eq2(set([b, c, e]) | set([c, d]), set([b, c, d, e])) _eq2(set([b, c]) & set([c, d]), set([c]))
def test_version_range(self): def _eq(a, b): _print("'%s' == '%s'" % (a, b)) a_range = VersionRange(a) b_range = VersionRange(b) self.assertTrue(a_range == b_range) self.assertTrue(a_range.issuperset(a_range)) self.assertTrue(a_range.issuperset(b_range)) self.assertTrue(VersionRange(str(a_range)) == a_range) self.assertTrue(VersionRange(str(b_range)) == a_range) self.assertTrue(hash(a_range) == hash(b_range)) a_ = a.replace('.', '-') a_ = a_.replace("--", "..") a_range_ = VersionRange(a_) self.assertTrue(a_range_ == a_range) self.assertTrue(hash(a_range_) == hash(a_range)) range_strs = a.split('|') ranges = [VersionRange(x) for x in range_strs] ranges_ = ranges[0].union(ranges[1:]) self.assertTrue(ranges_ == a_range) self.assertTrue(a_range | b_range == a_range) self.assertTrue(a_range - b_range is None) self.assertTrue(b_range - a_range is None) self.assertTrue(VersionRange() & a_range == a_range) self.assertTrue(b_range.span() & a_range == a_range) a_inv = a_range.inverse() self.assertTrue(a_inv == ~b_range) if a_inv: self.assertTrue(~a_inv == a_range) self.assertTrue(a_range | a_inv == VersionRange()) self.assertTrue(a_range & a_inv is None) a_ranges = a_range.split() a_range_ = a_ranges[0].union(a_ranges[1:]) self.assertTrue(a_range_ == b_range) def _and(a, b, c): _print("'%s' & '%s' == '%s'" % (a, b, c)) a_range = VersionRange(a) b_range = VersionRange(b) c_range = None if c is None else VersionRange(c) self.assertTrue(a_range & b_range == c_range) self.assertTrue(b_range & a_range == c_range) a_or_b = a_range | b_range a_and_b = a_range & b_range a_sub_b = a_range - b_range b_sub_a = b_range - a_range ranges = [a_and_b, a_sub_b, b_sub_a] ranges = [x for x in ranges if x] self.assertTrue(ranges[0].union(ranges[1:]) == a_or_b) def _inv(a, b): a_range = VersionRange(a) b_range = VersionRange(b) self.assertTrue(~a_range == b_range) self.assertTrue(~b_range == a_range) self.assertTrue(a_range | b_range == VersionRange()) self.assertTrue(a_range & b_range is None) # simple cases _print() _eq("", "") _eq("1", "1") _eq("1.0.0", "1.0.0") _eq("3+<3_", "3") _eq("_+<__", "_") _eq("1.2+<=2.0", "1.2..2.0") _eq("10+,<20", "10+<20") _eq("1+<1.0", "1+<1.0") _eq(">=2", "2+") # optimised cases _eq("3|3", "3") _eq("3|1", "1|3") _eq("5|3|1", "1|3|5") _eq("1|1_", "1+<1__") _eq("1|1_|1__", "1+,<1___") _eq("|", "") _eq("||", "||||||||") _eq("1|1_+", "1+") _eq("<1|1", "<1_") _eq("1+<3|3+<5", "1+<5") _eq(">4<6|1+<3", "1+<3|>4,<6") _eq("4+<6|1+<3|", "") _eq("4|2+", "2+") _eq("3|<5", "<5") _eq("<3|>3", ">3|<3") _eq("3+|<3", "") _eq("3+|<4", "") _eq("2+<=6|3+<5", "2..6") _eq("3+,<5|2+<=6", "2+<=6") _eq("2|2+", "2+") _eq("2|2.1+", "2+") _eq("2|<2.1", "<2_") _eq("3..3", "==3") _eq(">=3,<=3", "==3") # AND'ing _and("3", "3", "3") _and("1", "==1", "==1") _and("", "==1", "==1") _and("3", "4", None) _and("<3", "5+", None) _and("4+<6", "6+<8", None) _and("2+", "<=4", "2..4") _and("1", "1.0", "1.0") _and("4..6", "6+<8", "==6") # inverse _inv("3+", "<3") _inv("<=3", ">3") _inv("3.5", "<3.5|3.5_+") self.assertTrue(~VersionRange() is None) # odd (but valid) cases _eq(">", ">") # greater than the empty version _eq("+", "") # greater or equal to empty version (is all vers) _eq(">=", "") # equivalent to above _eq("<=", "==") # less or equal to empty version (is only empty) _eq("..", "==") # from empty version to empty version _eq("+<=", "==") # equivalent to above invalid_range = [ "4+<2", # lower bound greater than upper ">3<3", # both greater and less than same version ">3<=3", # greater and less or equal to same version "3+<3" # greater and equal to, and less than, same version ] for s in invalid_range: self.assertRaises(VersionError, VersionRange, s) invalid_syntax = [ "<", # less than the empty version "><", # both greater and less than empty version ">3>4", # both are lower bounds "<3<4", # both are upper bounds "<4>3", # upper bound before lower ",<4", # leading comma "4+,", # trailing comma "1>=", # pre-lower-op in post "+1", # post-lower-op in pre "4<", # pre-upper-op in post "1+<2<3" # more than two bounds ] for s in invalid_syntax: self.assertRaises(VersionError, VersionRange, s) # test simple logic self.assertTrue(VersionRange("").is_any()) self.assertTrue(VersionRange("2+<4").bounded()) self.assertTrue(VersionRange("2+").lower_bounded()) self.assertTrue(not VersionRange("2+").upper_bounded()) self.assertTrue(not VersionRange("2+").bounded()) self.assertTrue(VersionRange("<2").upper_bounded()) self.assertTrue(not VersionRange("<2").lower_bounded()) self.assertTrue(not VersionRange("<2").bounded()) # test range from version(s) v = Version("3") self.assertTrue(VersionRange.from_version(v, "eq") == VersionRange("==3")) self.assertTrue(VersionRange.from_version(v, "gt") == VersionRange(">3")) self.assertTrue(VersionRange.from_version(v, "gte") == VersionRange("3+")) self.assertTrue(VersionRange.from_version(v, "lt") == VersionRange("<3")) self.assertTrue(VersionRange.from_version(v, "lte") == VersionRange("<=3")) range1 = VersionRange.from_version(Version("2"), "gte") range2 = VersionRange.from_version(Version("4"), "lte") _eq(str(range1 & range2), "2..4") v2 = Version("6.0") v3 = Version("4") self.assertTrue(VersionRange.from_versions([v, v2, v3]) == VersionRange("==3|==4|==6.0")) # test behaviour in sets def _eq2(a, b): _print("'%s' == '%s'" % (a, b)) self.assertTrue(a == b) a = VersionRange("1+<=2.5") b = VersionRange("1..2.5") c = VersionRange(">=5") d = VersionRange(">6.1.0") e = VersionRange("3.2") _eq2(set([a]) - set([a]), set()) _eq2(set([a]) - set([b]), set()) _eq2(set([a, a]) - set([a]), set()) _eq2(set([b, c, d, e]) - set([a]), set([c, d, e])) _eq2(set([b, c, e]) | set([c, d]), set([b, c, d, e])) _eq2(set([b, c]) & set([c, d]), set([c]))