mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Tools: Make easier the detection of the list of Python features
This commit is contained in:
parent
a470ae224d
commit
fddc73759e
@ -201,8 +201,6 @@
|
|||||||
|
|
||||||
/tools/unit-test-app/ @esp-idf-codeowners/system @esp-idf-codeowners/tools
|
/tools/unit-test-app/ @esp-idf-codeowners/system @esp-idf-codeowners/tools
|
||||||
|
|
||||||
requirements.*.txt @esp-idf-codeowners/tools
|
|
||||||
|
|
||||||
# sort-order-reset
|
# sort-order-reset
|
||||||
|
|
||||||
/components/**/test_apps/**/*.py @esp-idf-codeowners/ci @esp-idf-codeowners/tools
|
/components/**/test_apps/**/*.py @esp-idf-codeowners/ci @esp-idf-codeowners/tools
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
- "tools/cmake/**/*"
|
- "tools/cmake/**/*"
|
||||||
- "tools/kconfig_new/**/*"
|
- "tools/kconfig_new/**/*"
|
||||||
- "tools/tools.json"
|
- "tools/tools.json"
|
||||||
|
- "tools/requirements.json"
|
||||||
- "tools/ci/test_build_system*.sh"
|
- "tools/ci/test_build_system*.sh"
|
||||||
|
|
||||||
.patterns-custom_test: &patterns-custom_test
|
.patterns-custom_test: &patterns-custom_test
|
||||||
@ -127,6 +128,10 @@
|
|||||||
- "tools/test_idf_tools/**/*"
|
- "tools/test_idf_tools/**/*"
|
||||||
- "tools/install_util.py"
|
- "tools/install_util.py"
|
||||||
|
|
||||||
|
- "tools/requirements/*"
|
||||||
|
- "tools/requirements.json"
|
||||||
|
- "tools/requirements_schema.json"
|
||||||
|
|
||||||
- "tools/mkdfu.py"
|
- "tools/mkdfu.py"
|
||||||
- "tools/test_mkdfu/**/*"
|
- "tools/test_mkdfu/**/*"
|
||||||
|
|
||||||
|
@ -111,6 +111,14 @@ repos:
|
|||||||
language: python
|
language: python
|
||||||
files: \.(py|c|h|cpp|hpp|ld)$
|
files: \.(py|c|h|cpp|hpp|ld)$
|
||||||
require_serial: true
|
require_serial: true
|
||||||
|
- id: check-requirement-files
|
||||||
|
name: Check requirement files
|
||||||
|
entry: tools/ci/check_requirement_files.py
|
||||||
|
additional_dependencies:
|
||||||
|
- 'jsonschema'
|
||||||
|
language: python
|
||||||
|
files: 'tools/requirements.+|tools/requirements/.+'
|
||||||
|
pass_filenames: false
|
||||||
- id: check-tools-files-patterns
|
- id: check-tools-files-patterns
|
||||||
name: Check tools dir files patterns
|
name: Check tools dir files patterns
|
||||||
entry: tools/ci/check_tools_files_patterns.py
|
entry: tools/ci/check_tools_files_patterns.py
|
||||||
|
@ -104,9 +104,9 @@ Any mirror server can be used provided the URL matches the ``github.com`` downlo
|
|||||||
|
|
||||||
* ``check``: For each tool, checks whether the tool is available in the system path and 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. For each feature a requirements file must exist. For example, feature ``XY`` is a valid feature if ``${IDF_PATH}/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.
|
* ``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. 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.
|
||||||
|
|
||||||
* ``check-python-dependencies``: Checks if all required Python packages are installed. Packages from ``${IDF_PATH}/requirements.*.txt`` files selected by the feature list of ``idf-env.json`` are checked with the package versions specified in the ``espidf.constraints.*.txt`` file. The constraint file will be downloaded from https://dl.espressif.com if this step hasn't been done already in the last day.
|
* ``check-python-dependencies``: Checks if all required Python packages are installed. Packages from ``${IDF_PATH}/tools/requirements/requirements.*.txt`` files selected by the feature list of ``idf-env.json`` are checked with the package versions specified in the ``espidf.constraints.*.txt`` file. The constraint file will be downloaded from https://dl.espressif.com if this step hasn't been done already in the last day.
|
||||||
|
|
||||||
.. _idf-tools-install:
|
.. _idf-tools-install:
|
||||||
|
|
||||||
|
58
tools/ci/check_requirement_files.py
Executable file
58
tools/ci/check_requirement_files.py
Executable file
@ -0,0 +1,58 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import jsonschema
|
||||||
|
|
||||||
|
IDF_PATH = os.environ['IDF_PATH']
|
||||||
|
JSON_PATH = os.path.join(IDF_PATH, 'tools', 'requirements.json')
|
||||||
|
SCHEMA_PATH = os.path.join(IDF_PATH, 'tools', 'requirements_schema.json')
|
||||||
|
REQ_DIR = os.path.join(IDF_PATH, 'tools', 'requirements')
|
||||||
|
RE_FEATURE = re.compile(r'requirements\.(\w+)\.txt')
|
||||||
|
|
||||||
|
|
||||||
|
def action_validate(req_obj: Any) -> None: # "Any" because we are checking this in this script
|
||||||
|
'''
|
||||||
|
Check that the parsed JSON object is valid according to the JSON schema provided
|
||||||
|
'''
|
||||||
|
with open(SCHEMA_PATH, 'r') as schema_file:
|
||||||
|
schema_json = json.load(schema_file)
|
||||||
|
jsonschema.validate(req_obj, schema_json)
|
||||||
|
|
||||||
|
|
||||||
|
def action_check_directory(req_obj: Any) -> None: # "Any" because we are checking this in this script
|
||||||
|
'''
|
||||||
|
Check that all directory items are listed in the JSON file
|
||||||
|
'''
|
||||||
|
features = set(d['name'] for d in req_obj['features'])
|
||||||
|
features_found = set()
|
||||||
|
|
||||||
|
for file_name in os.listdir(REQ_DIR):
|
||||||
|
m = re.match(RE_FEATURE, file_name)
|
||||||
|
if m:
|
||||||
|
if m.group(1) not in features:
|
||||||
|
raise RuntimeError(f'Cannot find a feature for {file_name} in {JSON_PATH}')
|
||||||
|
features_found.add(m.group(1))
|
||||||
|
else:
|
||||||
|
raise RuntimeError(f'{file_name} in {REQ_DIR} doesn\'t match the expected name')
|
||||||
|
|
||||||
|
features_not_found = features - features_found
|
||||||
|
|
||||||
|
if len(features_not_found) > 0:
|
||||||
|
raise RuntimeError(f'There are no requirements file in {REQ_DIR} for {features_not_found}')
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
with open(JSON_PATH, 'r') as f:
|
||||||
|
req_obj = json.load(f)
|
||||||
|
action_validate(req_obj)
|
||||||
|
action_check_directory(req_obj)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -60,6 +60,7 @@ tools/ci/check_executables.py
|
|||||||
tools/ci/check_idf_version.sh
|
tools/ci/check_idf_version.sh
|
||||||
tools/ci/check_kconfigs.py
|
tools/ci/check_kconfigs.py
|
||||||
tools/ci/check_readme_links.py
|
tools/ci/check_readme_links.py
|
||||||
|
tools/ci/check_requirement_files.py
|
||||||
tools/ci/check_rules_yml.py
|
tools/ci/check_rules_yml.py
|
||||||
tools/ci/check_soc_struct_headers.py
|
tools/ci/check_soc_struct_headers.py
|
||||||
tools/ci/check_tools_files_patterns.py
|
tools/ci/check_tools_files_patterns.py
|
||||||
|
@ -1091,7 +1091,7 @@ def add_and_save_targets(targets_str): # type: (str) -> list[str]
|
|||||||
|
|
||||||
|
|
||||||
def feature_to_requirements_path(feature): # type: (str) -> str
|
def feature_to_requirements_path(feature): # type: (str) -> str
|
||||||
return os.path.join(global_idf_path or '', 'requirements.{}.txt'.format(feature))
|
return os.path.join(global_idf_path or '', 'tools', 'requirements', 'requirements.{}.txt'.format(feature))
|
||||||
|
|
||||||
|
|
||||||
def add_and_save_features(features_str): # type: (str) -> list[str]
|
def add_and_save_features(features_str): # type: (str) -> list[str]
|
||||||
|
17
tools/requirements.json
Normal file
17
tools/requirements.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"features": [
|
||||||
|
{
|
||||||
|
"name": "core",
|
||||||
|
"description": "Core packages necessary for ESP-IDF",
|
||||||
|
"optional": false,
|
||||||
|
"requirement_path": "tools/requirements/requirements.core.txt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "gdbgui",
|
||||||
|
"description": "Packages for supporting debugging from web browser",
|
||||||
|
"optional": true,
|
||||||
|
"requirement_path": "tools/requirements/requirements.gdbgui.txt"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
52
tools/requirements_schema.json
Normal file
52
tools/requirements_schema.json
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"$id": "https://github.com/espressif/esp-idf/blob/master/tools/requirements_schema.json",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"version": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Metadata file version"
|
||||||
|
},
|
||||||
|
"features": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "List of features",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/featInfo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"version",
|
||||||
|
"features"
|
||||||
|
],
|
||||||
|
"definitions": {
|
||||||
|
"featInfo": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Information about one feature",
|
||||||
|
"properties": {
|
||||||
|
"name" : {
|
||||||
|
"description": "Feature name",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description" : {
|
||||||
|
"description": "A short description of the feature",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"optional": {
|
||||||
|
"description": "The feature is optional if the user can choose to not install it",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"requirement_path": {
|
||||||
|
"description": "Path to the requirements file with Python packages",
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^tools/requirements/requirements\\..+\\.txt$"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"optional",
|
||||||
|
"requirement_path"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,8 +18,8 @@ IDF_PATH = os.environ.get('IDF_PATH', '../..')
|
|||||||
TOOLS_DIR = os.environ.get('IDF_TOOLS_PATH') or os.path.expanduser(idf_tools.IDF_TOOLS_PATH_DEFAULT)
|
TOOLS_DIR = os.environ.get('IDF_TOOLS_PATH') or os.path.expanduser(idf_tools.IDF_TOOLS_PATH_DEFAULT)
|
||||||
PYTHON_DIR = os.path.join(TOOLS_DIR, 'python_env')
|
PYTHON_DIR = os.path.join(TOOLS_DIR, 'python_env')
|
||||||
REQ_SATISFIED = 'Python requirements are satisfied'
|
REQ_SATISFIED = 'Python requirements are satisfied'
|
||||||
REQ_CORE = '- {}/requirements.core.txt'.format(IDF_PATH)
|
REQ_CORE = '- {}'.format(os.path.join(IDF_PATH, 'tools', 'requirements', 'requirements.core.txt'))
|
||||||
REQ_GDBGUI = '- {}/requirements.gdbgui.txt'.format(IDF_PATH)
|
REQ_GDBGUI = '- {}'.format(os.path.join(IDF_PATH, 'tools', 'requirements', 'requirements.gdbgui.txt'))
|
||||||
CONSTR = 'Constraint file: {}/espidf.constraints'.format(TOOLS_DIR)
|
CONSTR = 'Constraint file: {}/espidf.constraints'.format(TOOLS_DIR)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user