""" Vhex package searching user interface """ import sys from core.logger import log import core.pkg __all__ = [ 'pkg_search_cli_parse' ] __HELP__ = r""" vxsdk-pkg-search Package manager : search commands SYNOPSIS: vxsdk pkg search [ OPTIONS ] [ targets[, ...] ] DESCRIPTION: This part of the vxSDK will performs search queries in remote and local arena (see to change this default behaviour). Each "target" can be written specificaly like this: (ex: vxKernel@1.2.3) This will allow the searching to try to match package with specific version information. This part is very powerfull because If the 'version' is detected to respect the correct semantic versioning, you can perform version operations in the version target: Caret requirements (^) ^1.2.3 := >=1.2.3, <2.0.0 ^1.2 := >=1.2.0, <2.0.0 ^1 := >=1.0.0, <2.0.0 ^0.2.3 := >=0.2.3, <0.3.0 ^0.2 := >=0.2.0, <0.3.0 ^0.0.3 := >=0.0.3, <0.0.4 ^0.0 := >=0.0.0, <0.1.0 ^0 := >=0.0.0, <1.0.0 Tilde requirements (~) ~1.2.3 := >=1.2.3, <1.3.0 ~1.2 := >=1.2.0, <1.3.0 ~1 := >=1.0.0, <2.0.0 Wildcard requirements (*) * := >=0.0.0 1.* := >=1.0.0, <2.0.0 1.2.* := >=1.2.0, <1.3.0 Note that it's possible that a package can have two same version (one for branch name and another for a tag), by default, the tag is always selected, but here the display information will explicitly describe if the version is a tag and / or a branch. OPTIONS: -a, --all Display all package found -l, --local Performs search in "local" and local -L, --local-only Performs search only in "local" -r, --remote Performs search only in "remote" -i, --info Print extra information for each repositories -s, --short Print short information for each repositories (default) -h, --help Print this help and exit """.strip() #--- # Internals #--- def _pkg_list_display(pkg_list, version, display_extra_info=False): for pkg in pkg_list: indent = ' ' log.user(f"{pkg['full_name']}") # handle special version request version_available = pkg['versions'] if version: version_available = [] for ver in pkg['versions']: if ver.validate(version): version_available.append(ver) if display_extra_info: log.user( f"- Description : {pkg['description']}\n" f"- Created at {pkg['created']}\n" f"- Updated at {pkg['updated']}\n" f"- Authors : {pkg['author']}\n" f"- URL : {pkg['url']}\n" "- Versions:" ) if not version_available: log.user(f"{indent}No version available for '{version}'") return for ver in version_available: ind = ' ' if len(ver.sources) == 1: ind = '(r-) ' if ver.sources[0] == 'remote' else '(-l) ' if len(ver.sources) > 1: ind = '(rl) ' content = f"{indent}{ind}{pkg['name']}@{ver.name}".ljust(32) content += f"({ver.type})" log.user(content) log.user(" ") #--- # Public #--- def pkg_search_cli_parse(argv): """ Search command handling """ if not argv: log.notice(__HELP__) sys.exit(84) if '-h' in argv or '--help' in argv: log.user(__HELP__) sys.exit(0) local = True remote = True display_extra_info = False for arg in argv: # handle search arena if arg in ['-l', '--local', '-r', '--remote']: local = arg in ['-l', '--local'] remote = arg in ['-r', '--remote'] continue # handle display mode if arg in ['-i', '--info', '-s', '--short']: display_extra_info = arg in ['-i', '--info'] continue # performs searching operation # @note # - handle search exception when all package a requested if arg in ['-a', '--all']: pkg_list = core.pkg.find(None, None, local, remote) else: pkg_list = core.pkg.find( arg.split('@')[0], None, local, remote ) if not pkg_list: log.warn(f"{arg}: package not found, skipped") continue # display package information _pkg_list_display( pkg_list, None if len(arg.split('@')) != 2 else arg.split('@')[1], display_extra_info ) return 0