Skip to content

Commit 43f1473

Browse files
authored
Added support for the from_native function in both Composer and Golang version ranges. which fixes issue #47
Signed-off-by: Aayush Kumar <aayush214.kumar@gmail.com>
1 parent a57771b commit 43f1473

1 file changed

Lines changed: 109 additions & 3 deletions

File tree

src/univers/version_range.py

Lines changed: 109 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -842,8 +842,11 @@ class NugetVersionRange(MavenVersionRange):
842842

843843

844844
class ComposerVersionRange(VersionRange):
845-
# TODO composer may need its own scheme see https//github.com/aboutcode-org/univers/issues/5
846-
# and https//getcomposer.org/doc/articles/versions.md
845+
"""
846+
Composer version range as documented at
847+
https://getcomposer.org/doc/articles/versions.md
848+
"""
849+
847850
scheme = "composer"
848851
version_class = versions.ComposerVersion
849852

@@ -856,6 +859,75 @@ class ComposerVersionRange(VersionRange):
856859
"=": "=", # This is not a native composer-semver comparator, but is used in the gitlab version range for composer packages.
857860
}
858861

862+
@classmethod
863+
def from_native(cls, string):
864+
"""
865+
Parse a Composer version range string into a version range object.
866+
"""
867+
string = string.strip()
868+
869+
if string.startswith("^"):
870+
base_version = string[1:]
871+
base_version_obj = cls.version_class(base_version)
872+
base_parts = base_version.split(".")
873+
if base_parts[0] == "0":
874+
upper_constraint = VersionConstraint(
875+
comparator="<", version=cls.version_class(f"0.{int(base_parts[1]) + 1}.0")
876+
)
877+
else:
878+
upper_constraint = VersionConstraint(
879+
comparator="<", version=cls.version_class(f"{int(base_parts[0]) + 1}.0.0")
880+
)
881+
lower_constraint = VersionConstraint(comparator=">=", version=base_version_obj)
882+
return cls(constraints=[lower_constraint, upper_constraint])
883+
884+
if string.startswith("~"):
885+
base_version = string[1:]
886+
base_version_obj = cls.version_class(base_version)
887+
base_parts = base_version.split(".")
888+
889+
if len(base_parts) == 3:
890+
upper_constraint = VersionConstraint(
891+
comparator="<",
892+
version=cls.version_class(f"{base_parts[0]}.{int(base_parts[1]) + 1}.0"),
893+
)
894+
else:
895+
upper_constraint = VersionConstraint(
896+
comparator="<", version=cls.version_class(f"{int(base_parts[0]) + 1}.0.0")
897+
)
898+
899+
lower_constraint = VersionConstraint(comparator=">=", version=base_version_obj)
900+
return cls(constraints=[lower_constraint, upper_constraint])
901+
902+
if ".*" in string:
903+
base_version = string.replace(".*", ".0")
904+
base_version_obj = cls.version_class(base_version)
905+
base_parts = base_version.split(".")
906+
upper_constraint = VersionConstraint(
907+
comparator="<",
908+
version=cls.version_class(f"{base_parts[0]}.{int(base_parts[1]) + 1}.0"),
909+
)
910+
lower_constraint = VersionConstraint(comparator=">=", version=base_version_obj)
911+
return cls(constraints=[lower_constraint, upper_constraint])
912+
913+
constraints = []
914+
915+
segments = string.split("||")
916+
917+
for segment in segments:
918+
if not any(op in string for op in cls.vers_by_native_comparators):
919+
segment = "==" + segment
920+
specifiers = SpecifierSet(segment)
921+
for spec in specifiers:
922+
operator = spec.operator
923+
version = spec.version
924+
version = cls.version_class(version)
925+
comparator = cls.vers_by_native_comparators.get(operator, "=")
926+
constraint = VersionConstraint(comparator=comparator, version=version)
927+
constraints.append(constraint)
928+
929+
return cls(constraints=constraints)
930+
859931

860932
class RpmVersionRange(VersionRange):
861933
# http://ftp.rpm.org/api/4.4.2.2/dependencies.html
@@ -942,7 +1014,7 @@ def from_natives(cls, strings):
9421014

9431015
class GolangVersionRange(VersionRange):
9441016
"""
945-
Go modules use strict semver with pseudo numbering for Git repos
1017+
Go modules use strict semver with pseudo numbering for Git commits.
9461018
https://go.dev/doc/modules/version-numbers
9471019
"""
9481020

@@ -958,6 +1030,39 @@ class GolangVersionRange(VersionRange):
9581030
"=": "=", # This is not a native golang-semver comparator, but is used in the gitlab version range for go packages.
9591031
}
9601032

1033+
@classmethod
1034+
def from_native(cls, string):
1035+
"""
1036+
Parse a native GoLang version range into a set of constraints.
1037+
"""
1038+
constraints = []
1039+
1040+
segments = string.split("||")
1041+
for segment in segments:
1042+
1043+
if not any(op in string for op in cls.vers_by_native_comparators):
1044+
segment = "==" + segment
1045+
1046+
specifiers = SpecifierSet(segment)
1047+
for spec in specifiers:
1048+
operator = spec.operator
1049+
version = spec.version
1050+
version = cls.version_class(version)
1051+
comparator = cls.vers_by_native_comparators.get(operator, "=")
1052+
constraint = VersionConstraint(comparator=comparator, version=version)
1053+
constraints.append(constraint)
1054+
1055+
return cls(constraints=constraints)
1056+
1057+
@classmethod
1058+
def from_natives(cls, strings):
1059+
if isinstance(strings, str):
1060+
return cls.from_native(strings)
1061+
constraints = []
1062+
for rel in strings:
1063+
constraints.extend(cls.from_native(rel).constraints)
1064+
return cls(constraints=constraints)
1065+
9611066

9621067
class GenericVersionRange(VersionRange):
9631068
scheme = "generic"
@@ -1431,3 +1536,4 @@ def build_range_from_snyk_advisory_string(scheme: str, string: Union[str, List])
14311536
"packagist": "composer",
14321537
"conan": "conan",
14331538
}
1539+

0 commit comments

Comments
 (0)