|
|
|
@ -34,16 +34,11 @@ from rich.table import Table |
|
|
|
|
COMPONENT_PREFIX = "homeassistant.components" |
|
|
|
|
PKG_SET = "home-assistant.python.pkgs" |
|
|
|
|
|
|
|
|
|
# If some requirements are matched by multiple Python packages, |
|
|
|
|
# the following can be used to choose one of them |
|
|
|
|
# If some requirements are matched by multiple or no Python packages, the |
|
|
|
|
# following can be used to choose the correct one |
|
|
|
|
PKG_PREFERENCES = { |
|
|
|
|
# Use python3Packages.youtube-dl-light instead of python3Packages.youtube-dl |
|
|
|
|
"youtube-dl": "youtube-dl-light", |
|
|
|
|
"tensorflow-bin": "tensorflow", |
|
|
|
|
"tensorflow-bin_2": "tensorflow", |
|
|
|
|
"tensorflowWithoutCuda": "tensorflow", |
|
|
|
|
"tensorflow-build_2": "tensorflow", |
|
|
|
|
"whois": "python-whois", |
|
|
|
|
"youtube_dl": "youtube-dl-light", |
|
|
|
|
"tensorflow": "tensorflow", |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -120,39 +115,28 @@ def dump_packages() -> Dict[str, Dict[str, str]]: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def name_to_attr_path(req: str, packages: Dict[str, Dict[str, str]]) -> Optional[str]: |
|
|
|
|
attr_paths = set() |
|
|
|
|
if req in PKG_PREFERENCES: |
|
|
|
|
return f"{PKG_SET}.{PKG_PREFERENCES[req]}" |
|
|
|
|
attr_paths = [] |
|
|
|
|
names = [req] |
|
|
|
|
# E.g. python-mpd2 is actually called python3.6-mpd2 |
|
|
|
|
# instead of python-3.6-python-mpd2 inside Nixpkgs |
|
|
|
|
if req.startswith("python-") or req.startswith("python_"): |
|
|
|
|
names.append(req[len("python-") :]) |
|
|
|
|
# Add name variant without extra_require, e.g. samsungctl |
|
|
|
|
# instead of samsungctl[websocket] |
|
|
|
|
if req.endswith("]"): |
|
|
|
|
names.append(req[:req.find("[")]) |
|
|
|
|
for name in names: |
|
|
|
|
# treat "-" and "_" equally |
|
|
|
|
name = re.sub("[-_]", "[-_]", name) |
|
|
|
|
# python(minor).(major)-(pname)-(version or unstable-date) |
|
|
|
|
# we need the version qualifier, or we'll have multiple matches |
|
|
|
|
# (e.g. pyserial and pyserial-asyncio when looking for pyserial) |
|
|
|
|
pattern = re.compile("^python\\d\\.\\d-{}-(?:\\d|unstable-.*)".format(name), re.I) |
|
|
|
|
pattern = re.compile(f"^python\\d\\.\\d-{name}-(?:\\d|unstable-.*)", re.I) |
|
|
|
|
for attr_path, package in packages.items(): |
|
|
|
|
if pattern.match(package["name"]): |
|
|
|
|
attr_paths.add(attr_path) |
|
|
|
|
if len(attr_paths) > 1: |
|
|
|
|
for to_replace, replacement in PKG_PREFERENCES.items(): |
|
|
|
|
try: |
|
|
|
|
attr_paths.remove(PKG_SET + "." + to_replace) |
|
|
|
|
attr_paths.add(PKG_SET + "." + replacement) |
|
|
|
|
except KeyError: |
|
|
|
|
pass |
|
|
|
|
attr_paths.append(attr_path) |
|
|
|
|
# Let's hope there's only one derivation with a matching name |
|
|
|
|
assert len(attr_paths) <= 1, "{} matches more than one derivation: {}".format( |
|
|
|
|
req, attr_paths |
|
|
|
|
) |
|
|
|
|
if len(attr_paths) == 1: |
|
|
|
|
return attr_paths.pop() |
|
|
|
|
assert len(attr_paths) <= 1, f"{req} matches more than one derivation: {attr_paths}" |
|
|
|
|
if attr_paths: |
|
|
|
|
return attr_paths[0] |
|
|
|
|
else: |
|
|
|
|
return None |
|
|
|
|
|
|
|
|
@ -180,6 +164,10 @@ def main() -> None: |
|
|
|
|
# Therefore, if there's a "#" in the line, only take the part after it |
|
|
|
|
req = req[req.find("#") + 1 :] |
|
|
|
|
name, required_version = req.split("==", maxsplit=1) |
|
|
|
|
# Remove extra_require from name, e.g. samsungctl instead of |
|
|
|
|
# samsungctl[websocket] |
|
|
|
|
if name.endswith("]"): |
|
|
|
|
name = name[:name.find("[")] |
|
|
|
|
attr_path = name_to_attr_path(name, packages) |
|
|
|
|
if our_version := get_pkg_version(name, packages): |
|
|
|
|
if Version.parse(our_version) < Version.parse(required_version): |
|
|
|
|