jupyter-builder 0.1.0a3__py3-none-any.whl → 0.1.0a4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jupyter_builder/commands.py +4 -8
- jupyter_builder/federated_extensions.py +17 -21
- jupyter_builder/jupyterlab_semver.py +574 -2
- jupyter_builder/yarn.js +8 -13
- jupyter_builder-0.1.0a4.dist-info/METADATA +175 -0
- {jupyter_builder-0.1.0a3.dist-info → jupyter_builder-0.1.0a4.dist-info}/RECORD +9 -9
- {jupyter_builder-0.1.0a3.dist-info → jupyter_builder-0.1.0a4.dist-info}/WHEEL +1 -1
- jupyter_builder-0.1.0a3.dist-info/METADATA +0 -119
- {jupyter_builder-0.1.0a3.dist-info → jupyter_builder-0.1.0a4.dist-info}/entry_points.txt +0 -0
- {jupyter_builder-0.1.0a3.dist-info → jupyter_builder-0.1.0a4.dist-info}/licenses/LICENSE +0 -0
jupyter_builder/commands.py
CHANGED
|
@@ -79,14 +79,10 @@ def _compare_ranges(spec1, spec2, drop_prerelease1=False, drop_prerelease2=False
|
|
|
79
79
|
|
|
80
80
|
# Check for overlap.
|
|
81
81
|
if (
|
|
82
|
-
gte(x1, y1, True)
|
|
83
|
-
and ly(
|
|
84
|
-
or
|
|
85
|
-
|
|
86
|
-
or gte(y1, x1, True)
|
|
87
|
-
and lx(y1, x2, True)
|
|
88
|
-
or gx(y2, x1, True)
|
|
89
|
-
and lx(y2, x2, True)
|
|
82
|
+
(gte(x1, y1, True) and ly(x1, y2, True))
|
|
83
|
+
or (gy(x2, y1, True) and ly(x2, y2, True))
|
|
84
|
+
or (gte(y1, x1, True) and lx(y1, x2, True))
|
|
85
|
+
or (gx(y2, x1, True) and lx(y2, x2, True))
|
|
90
86
|
):
|
|
91
87
|
# if we ever find an overlap, we can return immediately
|
|
92
88
|
return 0
|
|
@@ -32,10 +32,9 @@ try:
|
|
|
32
32
|
except ImportError:
|
|
33
33
|
from tomli import load
|
|
34
34
|
|
|
35
|
+
from .commands import _test_overlap
|
|
35
36
|
from .core_path import default_core_path
|
|
36
37
|
|
|
37
|
-
# from .commands import _test_overlap TO BE DONE -----------------------------
|
|
38
|
-
|
|
39
38
|
DEPRECATED_ARGUMENT = object()
|
|
40
39
|
|
|
41
40
|
HERE = osp.abspath(osp.dirname(__file__))
|
|
@@ -201,9 +200,7 @@ def build_labextension( # noqa: PLR0913
|
|
|
201
200
|
path, logger=None, development=False, static_url=None, source_map=False, core_path=None
|
|
202
201
|
):
|
|
203
202
|
"""Build a labextension in the given path"""
|
|
204
|
-
|
|
205
203
|
core_path = default_core_path() if core_path is None else str(Path(core_path).resolve())
|
|
206
|
-
|
|
207
204
|
ext_path = str(Path(path).resolve())
|
|
208
205
|
|
|
209
206
|
if logger:
|
|
@@ -293,23 +290,22 @@ def _ensure_builder(ext_path, core_path):
|
|
|
293
290
|
raise ValueError(msg)
|
|
294
291
|
target = osp.dirname(target)
|
|
295
292
|
|
|
296
|
-
#
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
# raise ValueError(msg)
|
|
293
|
+
# Check for compatible versions
|
|
294
|
+
overlap = _test_overlap(
|
|
295
|
+
dep_version1, dep_version2, drop_prerelease1=True, drop_prerelease2=True
|
|
296
|
+
)
|
|
297
|
+
if not overlap:
|
|
298
|
+
with open(
|
|
299
|
+
osp.join(target, "node_modules", "@jupyterlab", "builder", "package.json")
|
|
300
|
+
) as fid:
|
|
301
|
+
dep_version2 = json.load(fid).get("version")
|
|
302
|
+
overlap = _test_overlap(
|
|
303
|
+
dep_version1, dep_version2, drop_prerelease1=True, drop_prerelease2=True
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
if not overlap:
|
|
307
|
+
msg = f"Extensions require a devDependency on @jupyterlab/builder@{dep_version1}, you have a dependency on {dep_version2}" # noqa: E501
|
|
308
|
+
raise ValueError(msg)
|
|
313
309
|
|
|
314
310
|
return osp.join(
|
|
315
311
|
target, "node_modules", "@jupyterlab", "builder", "lib", "build-labextension.js"
|
|
@@ -32,6 +32,7 @@ import re
|
|
|
32
32
|
|
|
33
33
|
logger = logging.getLogger(__name__)
|
|
34
34
|
|
|
35
|
+
|
|
35
36
|
SEMVER_SPEC_VERSION = "2.0.0"
|
|
36
37
|
|
|
37
38
|
string_type = str
|
|
@@ -549,8 +550,7 @@ class SemVer:
|
|
|
549
550
|
else:
|
|
550
551
|
self.prerelease = [identifier, 0]
|
|
551
552
|
else:
|
|
552
|
-
|
|
553
|
-
raise ValueError(msg)
|
|
553
|
+
raise ValueError(f"invalid increment argument: {release}")
|
|
554
554
|
self.format()
|
|
555
555
|
self.raw = self.version
|
|
556
556
|
return self
|
|
@@ -639,9 +639,581 @@ def lt(a, b, loose):
|
|
|
639
639
|
return compare(a, b, loose) < 0
|
|
640
640
|
|
|
641
641
|
|
|
642
|
+
def eq(a, b, loose):
|
|
643
|
+
return compare(a, b, loose) == 0
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
def neq(a, b, loose):
|
|
647
|
+
return compare(a, b, loose) != 0
|
|
648
|
+
|
|
649
|
+
|
|
642
650
|
def gte(a, b, loose):
|
|
643
651
|
return compare(a, b, loose) >= 0
|
|
644
652
|
|
|
645
653
|
|
|
646
654
|
def lte(a, b, loose):
|
|
647
655
|
return compare(a, b, loose) <= 0
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
def cmp(a, op, b, loose): # noqa PLR0911
|
|
659
|
+
logger.debug("cmp: %s", op)
|
|
660
|
+
if op == "===":
|
|
661
|
+
return a == b
|
|
662
|
+
elif op == "!==":
|
|
663
|
+
return a != b
|
|
664
|
+
elif op == "" or op == "=" or op == "==":
|
|
665
|
+
return eq(a, b, loose)
|
|
666
|
+
elif op == "!=":
|
|
667
|
+
return neq(a, b, loose)
|
|
668
|
+
elif op == ">":
|
|
669
|
+
return gt(a, b, loose)
|
|
670
|
+
elif op == ">=":
|
|
671
|
+
return gte(a, b, loose)
|
|
672
|
+
elif op == "<":
|
|
673
|
+
return lt(a, b, loose)
|
|
674
|
+
elif op == "<=":
|
|
675
|
+
return lte(a, b, loose)
|
|
676
|
+
else:
|
|
677
|
+
raise ValueError(f"Invalid operator: {op}")
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
def comparator(comp, loose):
|
|
681
|
+
if isinstance(comp, Comparator):
|
|
682
|
+
if comp.loose == loose:
|
|
683
|
+
return comp
|
|
684
|
+
else:
|
|
685
|
+
comp = comp.value
|
|
686
|
+
|
|
687
|
+
# if (!(this instanceof Comparator))
|
|
688
|
+
# return new Comparator(comp, loose)
|
|
689
|
+
return Comparator(comp, loose)
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
make_comparator = comparator
|
|
693
|
+
|
|
694
|
+
ANY = object()
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
class Comparator:
|
|
698
|
+
semver = None
|
|
699
|
+
|
|
700
|
+
def __init__(self, comp, loose):
|
|
701
|
+
logger.debug("comparator: %s %s", comp, loose)
|
|
702
|
+
self.loose = loose
|
|
703
|
+
self.parse(comp)
|
|
704
|
+
|
|
705
|
+
if self.semver == ANY:
|
|
706
|
+
self.value = ""
|
|
707
|
+
else:
|
|
708
|
+
self.value = self.operator + self.semver.version
|
|
709
|
+
|
|
710
|
+
def parse(self, comp):
|
|
711
|
+
r = regexp[COMPARATORLOOSE] if self.loose else regexp[COMPARATOR]
|
|
712
|
+
logger.debug("parse comp=%s", comp)
|
|
713
|
+
m = r.search(comp)
|
|
714
|
+
|
|
715
|
+
if m is None:
|
|
716
|
+
raise ValueError(f"Invalid comparator: {comp}")
|
|
717
|
+
|
|
718
|
+
self.operator = m.group(1)
|
|
719
|
+
# if it literally is just '>' or '' then allow anything.
|
|
720
|
+
if m.group(2) is None:
|
|
721
|
+
self.semver = ANY
|
|
722
|
+
else:
|
|
723
|
+
self.semver = semver(m.group(2), self.loose)
|
|
724
|
+
|
|
725
|
+
def __repr__(self):
|
|
726
|
+
return f'<SemVer Comparator "{self}">'
|
|
727
|
+
|
|
728
|
+
def __str__(self):
|
|
729
|
+
return self.value
|
|
730
|
+
|
|
731
|
+
def test(self, version):
|
|
732
|
+
logger.debug("Comparator, test %s, %s", version, self.loose)
|
|
733
|
+
if self.semver == ANY:
|
|
734
|
+
return True
|
|
735
|
+
else:
|
|
736
|
+
return cmp(version, self.operator, self.semver, self.loose)
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
def make_range(range_, loose):
|
|
740
|
+
if isinstance(range_, Range) and range_.loose == loose:
|
|
741
|
+
return range_
|
|
742
|
+
|
|
743
|
+
# if (!(this instanceof Range))
|
|
744
|
+
# return new Range(range, loose);
|
|
745
|
+
return Range(range_, loose)
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
class Range:
|
|
749
|
+
def __init__(self, range_, loose):
|
|
750
|
+
self.loose = loose
|
|
751
|
+
# First, split based on boolean or ||
|
|
752
|
+
self.raw = range_
|
|
753
|
+
xs = [self.parse_range(r.strip()) for r in re.split(r"\s*\|\|\s*", range_)]
|
|
754
|
+
self.set = [r for r in xs if r]
|
|
755
|
+
|
|
756
|
+
if not len(self.set):
|
|
757
|
+
raise ValueError(f"Invalid SemVer Range: {range_}")
|
|
758
|
+
|
|
759
|
+
self.format()
|
|
760
|
+
|
|
761
|
+
def __repr__(self):
|
|
762
|
+
return f'<SemVer Range "{self.range}">'
|
|
763
|
+
|
|
764
|
+
def format(self):
|
|
765
|
+
self.range = "||".join(
|
|
766
|
+
[" ".join(c.value for c in comps).strip() for comps in self.set]
|
|
767
|
+
).strip()
|
|
768
|
+
logger.debug("Range format %s", self.range)
|
|
769
|
+
return self.range
|
|
770
|
+
|
|
771
|
+
def __str__(self):
|
|
772
|
+
return self.range
|
|
773
|
+
|
|
774
|
+
def parse_range(self, range_):
|
|
775
|
+
loose = self.loose
|
|
776
|
+
logger.debug("range %s %s", range_, loose)
|
|
777
|
+
# `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
|
|
778
|
+
hr = regexp[HYPHENRANGELOOSE] if loose else regexp[HYPHENRANGE]
|
|
779
|
+
|
|
780
|
+
range_ = hr.sub(
|
|
781
|
+
hyphen_replace,
|
|
782
|
+
range_,
|
|
783
|
+
)
|
|
784
|
+
logger.debug("hyphen replace %s", range_)
|
|
785
|
+
|
|
786
|
+
# `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
|
|
787
|
+
range_ = regexp[COMPARATORTRIM].sub(comparatorTrimReplace, range_)
|
|
788
|
+
logger.debug("comparator trim %s, %s", range_, regexp[COMPARATORTRIM])
|
|
789
|
+
|
|
790
|
+
# `~ 1.2.3` => `~1.2.3`
|
|
791
|
+
range_ = regexp[TILDETRIM].sub(tildeTrimReplace, range_)
|
|
792
|
+
|
|
793
|
+
# `^ 1.2.3` => `^1.2.3`
|
|
794
|
+
range_ = regexp[CARETTRIM].sub(caretTrimReplace, range_)
|
|
795
|
+
|
|
796
|
+
# normalize spaces
|
|
797
|
+
range_ = " ".join(re.split(r"\s+", range_))
|
|
798
|
+
|
|
799
|
+
# At this point, the range is completely trimmed and
|
|
800
|
+
# ready to be split into comparators.
|
|
801
|
+
comp_re = regexp[COMPARATORLOOSE] if loose else regexp[COMPARATOR]
|
|
802
|
+
set_ = re.split(
|
|
803
|
+
r"\s+", " ".join([parse_comparator(comp, loose) for comp in range_.split(" ")])
|
|
804
|
+
)
|
|
805
|
+
if self.loose:
|
|
806
|
+
# in loose mode, throw out any that are not valid comparators
|
|
807
|
+
set_ = [comp for comp in set_ if comp_re.search(comp)]
|
|
808
|
+
set_ = [make_comparator(comp, loose) for comp in set_]
|
|
809
|
+
return set_
|
|
810
|
+
|
|
811
|
+
def test(self, version):
|
|
812
|
+
if not version: # xxx
|
|
813
|
+
return False
|
|
814
|
+
|
|
815
|
+
if isinstance(version, string_type):
|
|
816
|
+
version = make_semver(version, loose=self.loose)
|
|
817
|
+
|
|
818
|
+
return any(test_set(e, version) for e in self.set)
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
# Mostly just for testing and legacy API reasons
|
|
822
|
+
def to_comparators(range_, loose):
|
|
823
|
+
return [
|
|
824
|
+
" ".join([c.value for c in comp]).strip().split(" ")
|
|
825
|
+
for comp in make_range(range_, loose).set
|
|
826
|
+
]
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
# comprised of xranges, tildes, stars, and gtlt's at this point.
|
|
830
|
+
# already replaced the hyphen ranges
|
|
831
|
+
# turn into a set of JUST comparators.
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
def parse_comparator(comp, loose):
|
|
835
|
+
logger.debug("comp %s", comp)
|
|
836
|
+
comp = replace_carets(comp, loose)
|
|
837
|
+
logger.debug("caret %s", comp)
|
|
838
|
+
comp = replace_tildes(comp, loose)
|
|
839
|
+
logger.debug("tildes %s", comp)
|
|
840
|
+
comp = replace_xranges(comp, loose)
|
|
841
|
+
logger.debug("xrange %s", comp)
|
|
842
|
+
comp = replace_stars(comp, loose)
|
|
843
|
+
logger.debug("stars %s", comp)
|
|
844
|
+
return comp
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
def is_x(id_):
|
|
848
|
+
return id_ is None or id_ == "" or id_.lower() == "x" or id_ == "*"
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
# ~, ~> --> * (any, kinda silly)
|
|
852
|
+
# ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0
|
|
853
|
+
# ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0
|
|
854
|
+
# ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0
|
|
855
|
+
# ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0
|
|
856
|
+
# ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
def replace_tildes(comp, loose):
|
|
860
|
+
return " ".join([replace_tilde(c, loose) for c in re.split(r"\s+", comp.strip())])
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
def replace_tilde(comp, loose):
|
|
864
|
+
r = regexp[TILDELOOSE] if loose else regexp[TILDE]
|
|
865
|
+
|
|
866
|
+
def repl(mob):
|
|
867
|
+
_ = mob.group(0)
|
|
868
|
+
M, m, p, pr, _ = mob.groups()
|
|
869
|
+
logger.debug("tilde %s %s %s %s %s %s", comp, _, M, m, p, pr)
|
|
870
|
+
if is_x(M):
|
|
871
|
+
ret = ""
|
|
872
|
+
elif is_x(m):
|
|
873
|
+
ret = ">=" + M + ".0.0 <" + str(int(M) + 1) + ".0.0"
|
|
874
|
+
elif is_x(p):
|
|
875
|
+
# ~1.2 == >=1.2.0 <1.3.0
|
|
876
|
+
ret = ">=" + M + "." + m + ".0 <" + M + "." + str(int(m) + 1) + ".0"
|
|
877
|
+
elif pr:
|
|
878
|
+
logger.debug("replaceTilde pr %s", pr)
|
|
879
|
+
if pr[0] != "-":
|
|
880
|
+
pr = "-" + pr
|
|
881
|
+
ret = ">=" + M + "." + m + "." + p + pr + " <" + M + "." + str(int(m) + 1) + ".0"
|
|
882
|
+
else:
|
|
883
|
+
# ~1.2.3 == >=1.2.3 <1.3.0
|
|
884
|
+
ret = ">=" + M + "." + m + "." + p + " <" + M + "." + str(int(m) + 1) + ".0"
|
|
885
|
+
logger.debug("tilde return, %s", ret)
|
|
886
|
+
return ret
|
|
887
|
+
|
|
888
|
+
return r.sub(repl, comp)
|
|
889
|
+
|
|
890
|
+
|
|
891
|
+
# ^ --> * (any, kinda silly)
|
|
892
|
+
# ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0
|
|
893
|
+
# ^2.0, ^2.0.x --> >=2.0.0 <3.0.0
|
|
894
|
+
# ^1.2, ^1.2.x --> >=1.2.0 <2.0.0
|
|
895
|
+
# ^1.2.3 --> >=1.2.3 <2.0.0
|
|
896
|
+
# ^1.2.0 --> >=1.2.0 <2.0.0
|
|
897
|
+
def replace_carets(comp, loose):
|
|
898
|
+
return " ".join([replace_caret(c, loose) for c in re.split(r"\s+", comp.strip())])
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
def replace_caret(comp, loose):
|
|
902
|
+
r = regexp[CARETLOOSE] if loose else regexp[CARET]
|
|
903
|
+
|
|
904
|
+
def repl(mob):
|
|
905
|
+
m0 = mob.group(0)
|
|
906
|
+
M, m, p, pr, _ = mob.groups()
|
|
907
|
+
logger.debug("caret %s %s %s %s %s %s", comp, m0, M, m, p, pr)
|
|
908
|
+
|
|
909
|
+
if is_x(M):
|
|
910
|
+
ret = ""
|
|
911
|
+
elif is_x(m):
|
|
912
|
+
ret = ">=" + M + ".0.0 <" + str(int(M) + 1) + ".0.0"
|
|
913
|
+
elif is_x(p):
|
|
914
|
+
if M == "0":
|
|
915
|
+
ret = ">=" + M + "." + m + ".0 <" + M + "." + str(int(m) + 1) + ".0"
|
|
916
|
+
else:
|
|
917
|
+
ret = ">=" + M + "." + m + ".0 <" + str(int(M) + 1) + ".0.0"
|
|
918
|
+
elif pr:
|
|
919
|
+
logger.debug("replaceCaret pr %s", pr)
|
|
920
|
+
if pr[0] != "-":
|
|
921
|
+
pr = "-" + pr
|
|
922
|
+
if M == "0":
|
|
923
|
+
if m == "0":
|
|
924
|
+
ret = (
|
|
925
|
+
">="
|
|
926
|
+
+ M
|
|
927
|
+
+ "."
|
|
928
|
+
+ m
|
|
929
|
+
+ "."
|
|
930
|
+
+ (p or "")
|
|
931
|
+
+ pr
|
|
932
|
+
+ " <"
|
|
933
|
+
+ M
|
|
934
|
+
+ "."
|
|
935
|
+
+ m
|
|
936
|
+
+ "."
|
|
937
|
+
+ str(int(p or 0) + 1)
|
|
938
|
+
)
|
|
939
|
+
else:
|
|
940
|
+
ret = (
|
|
941
|
+
">="
|
|
942
|
+
+ M
|
|
943
|
+
+ "."
|
|
944
|
+
+ m
|
|
945
|
+
+ "."
|
|
946
|
+
+ (p or "")
|
|
947
|
+
+ pr
|
|
948
|
+
+ " <"
|
|
949
|
+
+ M
|
|
950
|
+
+ "."
|
|
951
|
+
+ str(int(m) + 1)
|
|
952
|
+
+ ".0"
|
|
953
|
+
)
|
|
954
|
+
else:
|
|
955
|
+
ret = ">=" + M + "." + m + "." + (p or "") + pr + " <" + str(int(M) + 1) + ".0.0"
|
|
956
|
+
else:
|
|
957
|
+
if M == "0":
|
|
958
|
+
if m == "0":
|
|
959
|
+
ret = (
|
|
960
|
+
">="
|
|
961
|
+
+ M
|
|
962
|
+
+ "."
|
|
963
|
+
+ m
|
|
964
|
+
+ "."
|
|
965
|
+
+ (p or "")
|
|
966
|
+
+ " <"
|
|
967
|
+
+ M
|
|
968
|
+
+ "."
|
|
969
|
+
+ m
|
|
970
|
+
+ "."
|
|
971
|
+
+ str(int(p or 0) + 1)
|
|
972
|
+
)
|
|
973
|
+
else:
|
|
974
|
+
ret = (
|
|
975
|
+
">="
|
|
976
|
+
+ M
|
|
977
|
+
+ "."
|
|
978
|
+
+ m
|
|
979
|
+
+ "."
|
|
980
|
+
+ (p or "")
|
|
981
|
+
+ " <"
|
|
982
|
+
+ M
|
|
983
|
+
+ "."
|
|
984
|
+
+ str(int(m) + 1)
|
|
985
|
+
+ ".0"
|
|
986
|
+
)
|
|
987
|
+
else:
|
|
988
|
+
ret = ">=" + M + "." + m + "." + (p or "") + " <" + str(int(M) + 1) + ".0.0"
|
|
989
|
+
logger.debug("caret return %s", ret)
|
|
990
|
+
return ret
|
|
991
|
+
|
|
992
|
+
return r.sub(repl, comp)
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
def replace_xranges(comp, loose):
|
|
996
|
+
logger.debug("replaceXRanges %s %s", comp, loose)
|
|
997
|
+
return " ".join([replace_xrange(c, loose) for c in re.split(r"\s+", comp.strip())])
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
def replace_xrange(comp, loose):
|
|
1001
|
+
comp = comp.strip()
|
|
1002
|
+
r = regexp[XRANGELOOSE] if loose else regexp[XRANGE]
|
|
1003
|
+
|
|
1004
|
+
def repl(mob):
|
|
1005
|
+
ret = mob.group(0)
|
|
1006
|
+
gtlt, M, m, p, pr, _ = mob.groups()
|
|
1007
|
+
|
|
1008
|
+
logger.debug("xrange %s %s %s %s %s %s %s", comp, ret, gtlt, M, m, p, pr)
|
|
1009
|
+
|
|
1010
|
+
xM = is_x(M)
|
|
1011
|
+
xm = xM or is_x(m)
|
|
1012
|
+
xp = xm or is_x(p)
|
|
1013
|
+
any_x = xp
|
|
1014
|
+
|
|
1015
|
+
if gtlt == "=" and any_x:
|
|
1016
|
+
gtlt = ""
|
|
1017
|
+
|
|
1018
|
+
logger.debug("xrange gtlt=%s any_x=%s", gtlt, any_x)
|
|
1019
|
+
if xM:
|
|
1020
|
+
if gtlt == ">" or gtlt == "<": # noqa SIM108
|
|
1021
|
+
# nothing is allowed
|
|
1022
|
+
ret = "<0.0.0"
|
|
1023
|
+
else:
|
|
1024
|
+
ret = "*"
|
|
1025
|
+
elif gtlt and any_x:
|
|
1026
|
+
# replace X with 0, and then append the -0 min-prerelease
|
|
1027
|
+
if xm:
|
|
1028
|
+
m = 0
|
|
1029
|
+
if xp:
|
|
1030
|
+
p = 0
|
|
1031
|
+
|
|
1032
|
+
if gtlt == ">":
|
|
1033
|
+
# >1 => >=2.0.0
|
|
1034
|
+
# >1.2 => >=1.3.0
|
|
1035
|
+
# >1.2.3 => >= 1.2.4
|
|
1036
|
+
gtlt = ">="
|
|
1037
|
+
if xm:
|
|
1038
|
+
M = int(M) + 1
|
|
1039
|
+
m = 0
|
|
1040
|
+
p = 0
|
|
1041
|
+
elif xp:
|
|
1042
|
+
m = int(m) + 1
|
|
1043
|
+
p = 0
|
|
1044
|
+
elif gtlt == "<=":
|
|
1045
|
+
# <=0.7.x is actually <0.8.0, since any 0.7.x should
|
|
1046
|
+
# pass. Similarly, <=7.x is actually <8.0.0, etc.
|
|
1047
|
+
gtlt = "<"
|
|
1048
|
+
if xm:
|
|
1049
|
+
M = int(M) + 1
|
|
1050
|
+
else:
|
|
1051
|
+
m = int(m) + 1
|
|
1052
|
+
|
|
1053
|
+
ret = gtlt + str(M) + "." + str(m) + "." + str(p)
|
|
1054
|
+
elif xm:
|
|
1055
|
+
ret = ">=" + M + ".0.0 <" + str(int(M) + 1) + ".0.0"
|
|
1056
|
+
elif xp:
|
|
1057
|
+
ret = ">=" + M + "." + m + ".0 <" + M + "." + str(int(m) + 1) + ".0"
|
|
1058
|
+
logger.debug("xRange return %s", ret)
|
|
1059
|
+
|
|
1060
|
+
return ret
|
|
1061
|
+
|
|
1062
|
+
return r.sub(repl, comp)
|
|
1063
|
+
|
|
1064
|
+
|
|
1065
|
+
# Because * is AND-ed with everything else in the comparator,
|
|
1066
|
+
# and '' means "any version", just remove the *s entirely.
|
|
1067
|
+
def replace_stars(comp, loose):
|
|
1068
|
+
logger.debug("replaceStars %s %s", comp, loose)
|
|
1069
|
+
# Looseness is ignored here. star is always as loose as it gets!
|
|
1070
|
+
return regexp[STAR].sub("", comp.strip())
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
# This function is passed to string.replace(re[HYPHENRANGE])
|
|
1074
|
+
# M, m, patch, prerelease, build
|
|
1075
|
+
# 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
|
|
1076
|
+
# 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do
|
|
1077
|
+
# 1.2 - 3.4 => >=1.2.0 <3.5.0
|
|
1078
|
+
def hyphen_replace(mob):
|
|
1079
|
+
from_, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr, tb = mob.groups()
|
|
1080
|
+
if is_x(fM):
|
|
1081
|
+
from_ = ""
|
|
1082
|
+
elif is_x(fm):
|
|
1083
|
+
from_ = ">=" + fM + ".0.0"
|
|
1084
|
+
elif is_x(fp):
|
|
1085
|
+
from_ = ">=" + fM + "." + fm + ".0"
|
|
1086
|
+
else:
|
|
1087
|
+
from_ = ">=" + from_
|
|
1088
|
+
|
|
1089
|
+
if is_x(tM):
|
|
1090
|
+
to = ""
|
|
1091
|
+
elif is_x(tm):
|
|
1092
|
+
to = "<" + str(int(tM) + 1) + ".0.0"
|
|
1093
|
+
elif is_x(tp):
|
|
1094
|
+
to = "<" + tM + "." + str(int(tm) + 1) + ".0"
|
|
1095
|
+
elif tpr:
|
|
1096
|
+
to = "<=" + tM + "." + tm + "." + tp + "-" + tpr
|
|
1097
|
+
else:
|
|
1098
|
+
to = "<=" + to
|
|
1099
|
+
return (from_ + " " + to).strip()
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
def test_set(set_, version):
|
|
1103
|
+
for e in set_:
|
|
1104
|
+
if not e.test(version):
|
|
1105
|
+
return False
|
|
1106
|
+
if len(version.prerelease) > 0:
|
|
1107
|
+
# Find the set of versions that are allowed to have prereleases
|
|
1108
|
+
# For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0
|
|
1109
|
+
# That should allow `1.2.3-pr.2` to pass.
|
|
1110
|
+
# However, `1.2.4-alpha.notready` should NOT be allowed,
|
|
1111
|
+
# even though it's within the range set by the comparators.
|
|
1112
|
+
for e in set_:
|
|
1113
|
+
if e.semver == ANY:
|
|
1114
|
+
continue
|
|
1115
|
+
if len(e.semver.prerelease) > 0:
|
|
1116
|
+
allowed = e.semver
|
|
1117
|
+
if (
|
|
1118
|
+
allowed.major == version.major
|
|
1119
|
+
and allowed.minor == version.minor
|
|
1120
|
+
and allowed.patch == version.patch
|
|
1121
|
+
):
|
|
1122
|
+
return True
|
|
1123
|
+
# Version has a -pre, but it's not one of the ones we like.
|
|
1124
|
+
return False
|
|
1125
|
+
return True
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
def satisfies(version, range_, loose=False):
|
|
1129
|
+
try:
|
|
1130
|
+
range_ = make_range(range_, loose)
|
|
1131
|
+
except Exception:
|
|
1132
|
+
return False
|
|
1133
|
+
return range_.test(version)
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
def max_satisfying(versions, range_, loose=False):
|
|
1137
|
+
try:
|
|
1138
|
+
range_ob = make_range(range_, loose=loose)
|
|
1139
|
+
except Exception:
|
|
1140
|
+
return None
|
|
1141
|
+
max_ = None
|
|
1142
|
+
max_sv = None
|
|
1143
|
+
for v in versions:
|
|
1144
|
+
if range_ob.test(v): # noqa # satisfies(v, range_, loose=loose)
|
|
1145
|
+
if max_ is None or max_sv.compare(v) == -1: # compare(max, v, true)
|
|
1146
|
+
max_ = v
|
|
1147
|
+
max_sv = make_semver(max_, loose=loose)
|
|
1148
|
+
return max_
|
|
1149
|
+
|
|
1150
|
+
|
|
1151
|
+
def valid_range(range_, loose):
|
|
1152
|
+
try:
|
|
1153
|
+
# Return '*' instead of '' so that truthiness works.
|
|
1154
|
+
# This will throw if it's invalid anyway
|
|
1155
|
+
return make_range(range_, loose).range or "*"
|
|
1156
|
+
except Exception:
|
|
1157
|
+
return None
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
# Determine if version is less than all the versions possible in the range
|
|
1161
|
+
def ltr(version, range_, loose):
|
|
1162
|
+
return outside(version, range_, "<", loose)
|
|
1163
|
+
|
|
1164
|
+
|
|
1165
|
+
# Determine if version is greater than all the versions possible in the range.
|
|
1166
|
+
def rtr(version, range_, loose):
|
|
1167
|
+
return outside(version, range_, ">", loose)
|
|
1168
|
+
|
|
1169
|
+
|
|
1170
|
+
def outside(version, range_, hilo, loose):
|
|
1171
|
+
version = make_semver(version, loose)
|
|
1172
|
+
range_ = make_range(range_, loose)
|
|
1173
|
+
|
|
1174
|
+
if hilo == ">":
|
|
1175
|
+
gtfn = gt
|
|
1176
|
+
ltefn = lte
|
|
1177
|
+
ltfn = lt
|
|
1178
|
+
comp = ">"
|
|
1179
|
+
ecomp = ">="
|
|
1180
|
+
elif hilo == "<":
|
|
1181
|
+
gtfn = lt
|
|
1182
|
+
ltefn = gte
|
|
1183
|
+
ltfn = gt
|
|
1184
|
+
comp = "<"
|
|
1185
|
+
ecomp = "<="
|
|
1186
|
+
else:
|
|
1187
|
+
raise ValueError("Must provide a hilo val of '<' or '>'")
|
|
1188
|
+
|
|
1189
|
+
# If it satisfies the range it is not outside
|
|
1190
|
+
if satisfies(version, range_, loose):
|
|
1191
|
+
return False
|
|
1192
|
+
|
|
1193
|
+
# From now on, variable terms are as if we're in "gtr" mode.
|
|
1194
|
+
# but note that everything is flipped for the "ltr" function.
|
|
1195
|
+
for comparators in range_.set:
|
|
1196
|
+
high = None
|
|
1197
|
+
low = None
|
|
1198
|
+
|
|
1199
|
+
for comparator in comparators:
|
|
1200
|
+
high = high or comparator
|
|
1201
|
+
low = low or comparator
|
|
1202
|
+
|
|
1203
|
+
if gtfn(comparator.semver, high.semver, loose):
|
|
1204
|
+
high = comparator
|
|
1205
|
+
elif ltfn(comparator.semver, low.semver, loose):
|
|
1206
|
+
low = comparator
|
|
1207
|
+
|
|
1208
|
+
# If the edge version comparator has a operator then our version
|
|
1209
|
+
# isn't outside it
|
|
1210
|
+
if high.operator == comp or high.operator == ecomp:
|
|
1211
|
+
return False
|
|
1212
|
+
|
|
1213
|
+
# If the lowest version comparator has an operator and our version
|
|
1214
|
+
# is less than it then it isn't higher than the range
|
|
1215
|
+
if (not low.operator or low.operator == comp) and ltefn(version, low.semver): # noqa SIM114
|
|
1216
|
+
return False
|
|
1217
|
+
elif low.operator == ecomp and ltfn(version, low.semver):
|
|
1218
|
+
return False
|
|
1219
|
+
return True
|