vxSDK/vxsdk/cli/pkg/search.py

162 lines
4.8 KiB
Python

"""
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 <OPTIONS> to change this default behaviour). Each "target" can
be written specificaly like this:
<NAME@version> (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