mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-29 18:27:20 +02:00
tools: add new outdated option for idf_tools.py list
This adds a new outdated option, which only lists outdated packages installed in IDF_TOOLS_PATH. It searches for the latest installed tool version in the IDF_TOOLS_PATH/tools path and compares it against the latest available version in the tools.json file. If the latest version of a tool installed in IDF_TOOLS_PATH/tools is smaller, it's reported as outdated. Nothing is reported if the tool is up to date. Two new tests are added. First just checks if nothing is reported in case there is no update available. The second artificially generates new tools.json file called tools.outdated.json and sets XTENSA_ESP32_ELF version to 'zzzzzz'. It then checks if the XTENSA_ESP32_ELF tool is reported as outdated by the 'zzzzzz' version. Description of the new outdated option is addedd to docs as well. Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
This commit is contained in:
@ -107,6 +107,10 @@ Any mirror server can be used provided the URL matches the ``github.com`` downlo
|
||||
|
||||
* ``list``: Lists the known versions of the tools, and indicates which ones are installed.
|
||||
|
||||
Following options are available to customize the output.
|
||||
|
||||
- ``--outdated``: List only outdated versions of tools installed in ``IDF_TOOLS_PATH``.
|
||||
|
||||
* ``check``: For each tool, checks whether the tool is available in the system path and in ``IDF_TOOLS_PATH``.
|
||||
|
||||
* ``install-python-env``: Create a Python virtual environment in the ``${IDF_TOOLS_PATH}/python_env`` directory and install there the required Python packages. An optional ``--features`` argument allows one to specify a comma-separated list of features to be added or removed. Feature that begins with ``-`` will be removed and features with ``+`` or without any sign will be added. Example syntax for removing feature ``XY`` is ``--features=-XY`` and for adding ``--features=+XY`` or ``--features=XY``. If both removing and adding options are provided with the same feature, no operation is performed. For each feature a requirements file must exist. For example, feature ``XY`` is a valid feature if ``${IDF_PATH}/tools/requirements/requirements.XY.txt`` is an existing file with a list of Python packages to be installed. There is one mandatory ``core`` feature ensuring core functionality of ESP-IDF (build, flash, monitor, debug in console). There can be an arbitrary number of optional features. The selected list of features is stored in ``idf-env.json``. The requirement files contain a list of the desired Python packages to be installed and ``espidf.constraints.*.txt`` downloaded from https://dl.espressif.com and stored in ``${IDF_TOOLS_PATH}`` the package version requirements for a given ESP-IDF version. Althought it is not recommended, the download and use of constraint files can be disabled with the ``--no-constraints`` argument or setting the ``IDF_PYTHON_CHECK_CONSTRAINTS`` environment variable to ``no``.
|
||||
|
@ -759,6 +759,31 @@ class IDFTool(object):
|
||||
else:
|
||||
self.versions_installed.append(version)
|
||||
|
||||
def latest_installed_version(self): # type: () -> Optional[str]
|
||||
"""
|
||||
Get the latest installed tool version by directly checking the
|
||||
tool's version directories.
|
||||
"""
|
||||
tool_path = self.get_path()
|
||||
if not os.path.exists(tool_path):
|
||||
return None
|
||||
dentries = os.listdir(tool_path)
|
||||
dirs = [d for d in dentries if os.path.isdir(os.path.join(tool_path, d))]
|
||||
for version in sorted(dirs, reverse=True):
|
||||
# get_path_for_version() has assert to check if version is in versions
|
||||
# dict, so get_export_paths() cannot be used. Let's just create the
|
||||
# export paths list directly here.
|
||||
paths = [os.path.join(tool_path, version, *p) for p in self._current_options.export_paths]
|
||||
try:
|
||||
ver_str = self.get_version(paths)
|
||||
except (ToolNotFound, ToolExecError):
|
||||
continue
|
||||
if ver_str != version:
|
||||
continue
|
||||
return version
|
||||
|
||||
return None
|
||||
|
||||
def download(self, version): # type: (str) -> None
|
||||
assert version in self.versions
|
||||
download_obj = self.versions[version].get_download_for_platform(self._platform)
|
||||
@ -1495,7 +1520,7 @@ def active_repo_id() -> str:
|
||||
return global_idf_path + '-v' + get_idf_version()
|
||||
|
||||
|
||||
def action_list(args): # type: ignore
|
||||
def list_default(args): # type: ignore
|
||||
tools_info = load_tools_info()
|
||||
for name, tool in tools_info.items():
|
||||
if tool.get_install_type() == IDFTool.INSTALL_NEVER:
|
||||
@ -1514,6 +1539,29 @@ def action_list(args): # type: ignore
|
||||
', installed' if version in tool.versions_installed else ''))
|
||||
|
||||
|
||||
def list_outdated(args): # type: ignore
|
||||
tools_info = load_tools_info()
|
||||
for name, tool in tools_info.items():
|
||||
if tool.get_install_type() == IDFTool.INSTALL_NEVER:
|
||||
continue
|
||||
versions_for_platform = {k: v for k, v in tool.versions.items() if v.compatible_with_platform()}
|
||||
if not versions_for_platform:
|
||||
continue
|
||||
version_installed = tool.latest_installed_version()
|
||||
if not version_installed:
|
||||
continue
|
||||
version_available = sorted(versions_for_platform.keys(), key=tool.versions.get, reverse=True)[0]
|
||||
if version_installed < version_available:
|
||||
info(f'{name}: version {version_installed} is outdated by {version_available}')
|
||||
|
||||
|
||||
def action_list(args): # type: ignore
|
||||
if args.outdated:
|
||||
list_outdated(args)
|
||||
else:
|
||||
list_default(args)
|
||||
|
||||
|
||||
def action_check(args): # type: ignore
|
||||
tools_info = load_tools_info()
|
||||
tools_info = filter_tools_info(IDFEnv.get_idf_env(), tools_info)
|
||||
@ -2447,7 +2495,8 @@ def main(argv): # type: (list[str]) -> None
|
||||
parser.add_argument('--idf-path', help='ESP-IDF path to use')
|
||||
|
||||
subparsers = parser.add_subparsers(dest='action')
|
||||
subparsers.add_parser('list', help='List tools and versions available')
|
||||
list_parser = subparsers.add_parser('list', help='List tools and versions available')
|
||||
list_parser.add_argument('--outdated', help='Print only outdated installed tools', action='store_true')
|
||||
subparsers.add_parser('check', help='Print summary of tools installed or found in PATH')
|
||||
export = subparsers.add_parser('export', help='Output command for setting tool paths, suitable for shell')
|
||||
export.add_argument('--format', choices=[EXPORT_SHELL, EXPORT_KEY_VALUE], default=EXPORT_SHELL,
|
||||
|
@ -190,6 +190,37 @@ class TestUsage(unittest.TestCase):
|
||||
self.assertIn('%s/tools/esp-rom-elfs/%s/' %
|
||||
(self.temp_tools_dir, ESP_ROM_ELFS_VERSION), output)
|
||||
|
||||
output = self.run_idf_tools_with_action(['list', '--outdated'])
|
||||
self.assertEqual('', output)
|
||||
|
||||
tools_json_outdated = os.path.join(self.temp_tools_dir, 'tools', 'tools.outdated.json')
|
||||
new_version = 'zzzzzz'
|
||||
self.run_idf_tools_with_action(
|
||||
[
|
||||
'add-version',
|
||||
'--tool',
|
||||
XTENSA_ESP32_ELF,
|
||||
'--url-prefix',
|
||||
'http://test.com',
|
||||
'--version',
|
||||
new_version,
|
||||
'--override',
|
||||
'--checksum-file',
|
||||
'add_version/checksum.sha256',
|
||||
'--output',
|
||||
tools_json_outdated
|
||||
])
|
||||
|
||||
output = self.run_idf_tools_with_action(
|
||||
[
|
||||
'--tools-json',
|
||||
tools_json_outdated,
|
||||
'list',
|
||||
'--outdated'
|
||||
])
|
||||
self.assertIn((f'{XTENSA_ESP32_ELF}: version {XTENSA_ESP32_ELF_VERSION} '
|
||||
f'is outdated by {new_version}'), output)
|
||||
|
||||
def test_tools_for_esp32(self):
|
||||
required_tools_installed = 5
|
||||
output = self.run_idf_tools_with_action(['install', '--targets=esp32'])
|
||||
|
Reference in New Issue
Block a user