Add npm, maven, conan configs (excluding cache)
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
import re
|
||||
import os
|
||||
|
||||
min_version_format_rx = re.compile(r"^>=\s*(?P<min_version>[A-Za-z0-9\.\-]+)(\+[A-Za-z0-9\.\-\+]*)?\s*$")
|
||||
semver_rx = re.compile(r"^(?P<version>[A-Za-z0-9\.\-]+)(\+[A-Za-z0-9\.\-\+]*)?$")
|
||||
|
||||
def use_nuget_versioning(enable_debug_log: bool = False):
|
||||
if NugetStyleRangeResolver.using_nuget_versioning:
|
||||
return
|
||||
NugetStyleRangeResolver.using_nuget_versioning = True
|
||||
NugetStyleRangeResolver.enable_debug_log = enable_debug_log
|
||||
NugetStyleRangeResolver.override_conan1()
|
||||
|
||||
class NugetStyleRangeResolver:
|
||||
replaced = False
|
||||
using_nuget_versioning = False
|
||||
enable_debug_log = False
|
||||
|
||||
@staticmethod
|
||||
def debug_log(msg):
|
||||
if NugetStyleRangeResolver.enable_debug_log:
|
||||
print(f"[nuget versioning] {msg}")
|
||||
|
||||
@staticmethod
|
||||
def info_log(msg):
|
||||
print(f"[nuget versioning] {msg}")
|
||||
|
||||
@staticmethod
|
||||
def override_conan1():
|
||||
# https://github.com/conan-io/conan/blob/1.66.0/conans/model/requires.py
|
||||
# https://github.com/conan-io/conan/tree/1.66.0/conans/client/graph
|
||||
# https://github.com/conan-io/conan/blob/1.66.0/conans/client/graph/graph_builder.py
|
||||
# https://github.com/conan-io/conan/blob/1.66.0/conans/client/graph/range_resolver.py
|
||||
if NugetStyleRangeResolver.replaced:
|
||||
return
|
||||
NugetStyleRangeResolver.replaced = True
|
||||
|
||||
from conans.errors import ConanException
|
||||
from conans.client.graph.range_resolver import satisfying, RangeResolver, _parse_versionexpr
|
||||
from conans.search.search import search_recipes
|
||||
from semver import make_range, semver as make_semver, InvalidTypeIncluded, Range
|
||||
|
||||
def min_satisfying(versions, range_, loose=False, include_prerelease=False):
|
||||
try:
|
||||
range_ob = make_range(range_, loose=loose)
|
||||
except InvalidTypeIncluded:
|
||||
raise
|
||||
except ValueError as e:
|
||||
return None
|
||||
|
||||
min_ = None
|
||||
min_sv = None
|
||||
for v in versions:
|
||||
if range_ob.test(v, include_prerelease=include_prerelease): # satisfies(v, range_, loose=loose)
|
||||
sv = make_semver(v, loose=loose)
|
||||
if min_ is None or sv.compare(min_sv) == -1: # compare(max, v, true)
|
||||
min_ = v
|
||||
min_sv = sv
|
||||
return min_
|
||||
|
||||
def satisfying(list_versions, versionexpr:str, result):
|
||||
from semver import SemVer, Range, max_satisfying
|
||||
import re
|
||||
|
||||
original_versionexpr = versionexpr
|
||||
|
||||
select_max = False
|
||||
if versionexpr.startswith("+"):
|
||||
versionexpr = versionexpr[1:]
|
||||
select_max = True
|
||||
else:
|
||||
# minimum version selection doesn't care about upper bounds, so force it to true
|
||||
include_prerelease = True
|
||||
# fix upper bounds including prereleases
|
||||
versionexpr = re.sub(r"(\<)(\d(\.\d)*)(\s|,|$)", r"\1\2-\4", versionexpr)
|
||||
version_range, loose, include_prerelease = _parse_versionexpr(versionexpr, result)
|
||||
|
||||
NugetStyleRangeResolver.debug_log(f"{original_versionexpr} => {versionexpr}")
|
||||
|
||||
# Check version range expression
|
||||
try:
|
||||
act_range = Range(version_range, loose)
|
||||
except ValueError:
|
||||
raise ConanException("version range expression '%s' is not valid" % version_range)
|
||||
|
||||
# Validate all versions
|
||||
candidates = {}
|
||||
for v in list_versions:
|
||||
try:
|
||||
NugetStyleRangeResolver.debug_log(f"\t{v}")
|
||||
ver = SemVer(v, loose=loose)
|
||||
candidates[ver] = v
|
||||
except (ValueError, AttributeError):
|
||||
result.append("WARN: Version '%s' is not semver, cannot be compared with a range"
|
||||
% str(v))
|
||||
|
||||
# Search best matching version in range
|
||||
result = None
|
||||
if select_max:
|
||||
result = max_satisfying(candidates, act_range, loose=loose, include_prerelease=include_prerelease)
|
||||
else:
|
||||
result = min_satisfying(candidates, act_range, loose=loose, include_prerelease=True)
|
||||
|
||||
NugetStyleRangeResolver.debug_log(f"={result}")
|
||||
return candidates.get(result)
|
||||
|
||||
def _resolve_local(self, search_ref, version_range):
|
||||
local_found = search_recipes(self._cache, search_ref)
|
||||
local_found = \
|
||||
[ref for ref in local_found
|
||||
if ref.user == search_ref.user and
|
||||
ref.channel == search_ref.channel]
|
||||
|
||||
if local_found:
|
||||
ret = self._resolve_version(version_range, local_found)
|
||||
range_match = min_version_format_rx.search(version_range)
|
||||
if ret is not None and range_match is not None:
|
||||
min_version = range_match.group("min_version")
|
||||
version_match = semver_rx.search(ret.version)
|
||||
ret_version = version_match.group("version")
|
||||
|
||||
is_online = os.getenv("INSEINC_OFFLINE") != "1"
|
||||
if is_online and min_version != ret_version:
|
||||
NugetStyleRangeResolver.info_log(f"{ret}: Expected to find version {min_version} via {version_range}, forcing update")
|
||||
return None
|
||||
return ret
|
||||
|
||||
og_conflicting_references = None
|
||||
@staticmethod
|
||||
def _conflicting_references(previous, new_ref, consumer_ref=None):
|
||||
try:
|
||||
if previous.ref.copy_clear_rev() != new_ref.copy_clear_rev():
|
||||
if consumer_ref:
|
||||
new_ref_semver = make_semver(new_ref.version, loose=True)
|
||||
previous_semver = make_semver(previous.ref.version, loose=True)
|
||||
latest_version = None
|
||||
if new_ref_semver.compare(previous_semver) == -1:
|
||||
latest_version = previous.ref
|
||||
else:
|
||||
latest_version = new_ref
|
||||
|
||||
return ("Conflict in %s:\n"
|
||||
" %s\n required from %s\n"
|
||||
" %s\n required from %s\n"
|
||||
"To resolve the conflict, upgrade the dependency with:\n"
|
||||
" self.requires(\"%s\", override=True)"
|
||||
% (consumer_ref,
|
||||
new_ref, consumer_ref,
|
||||
previous.ref, next(iter(previous.dependants)).src,
|
||||
latest_version))
|
||||
return "Unresolvable conflict between {} and {}".format(previous.ref, new_ref)
|
||||
except:
|
||||
return og_conflicting_references(previous, new_ref, consumer_ref)
|
||||
|
||||
# now replace the functions
|
||||
import importlib
|
||||
graph_builder = importlib.import_module("conans.client.graph.graph_builder")
|
||||
og_conflicting_references = graph_builder.DepsGraphBuilder._conflicting_references
|
||||
graph_builder.DepsGraphBuilder._conflicting_references = _conflicting_references
|
||||
|
||||
range_resolver = importlib.import_module("conans.client.graph.range_resolver")
|
||||
range_resolver.satisfying = satisfying
|
||||
range_resolver.RangeResolver._resolve_local = _resolve_local
|
||||
importlib.reload(importlib.import_module("conans.model.graph_lock")) # TODO: this?
|
||||
importlib.reload(importlib.import_module("conans.client.graph.graph_builder")) # TODO: this?
|
||||
|
||||
@staticmethod
|
||||
def override_conan2():
|
||||
from conans.client.graph.range_resolver import RangeResolver
|
||||
|
||||
@staticmethod
|
||||
def _resolve_version(version_range, refs_found, resolve_prereleases):
|
||||
print(f"replaced function: {version_range}")
|
||||
for ref in sorted(refs_found):
|
||||
if version_range.contains(ref.version, resolve_prereleases):
|
||||
return ref
|
||||
RangeResolver._resolve_version = _resolve_version
|
||||
Reference in New Issue
Block a user