idf-build-apps 2.3.0__tar.gz → 2.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/.github/workflows/check-pre-commit.yml +1 -1
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/.pre-commit-config.yaml +2 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/CHANGELOG.md +13 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/PKG-INFO +5 -2
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/README.md +3 -1
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/manifest.md +31 -2
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/__init__.py +1 -1
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/app.py +12 -0
- idf_build_apps-2.4.0/idf_build_apps/autocompletions.py +54 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/constants.py +35 -1
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/main.py +67 -20
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/manifest/soc_header.py +22 -9
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/utils.py +4 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/pyproject.toml +2 -1
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/setup.py +2 -2
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/tests/test_manifest.py +17 -7
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/.editorconfig +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/.git-blame-ignore-revs +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/.gitattributes +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/.github/dependabot.yml +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/.github/workflows/issue_comment.yml +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/.github/workflows/new_issues.yml +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/.github/workflows/new_prs.yml +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/.github/workflows/publish-pypi.yml +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/.github/workflows/test-build-docs.yml +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/.github/workflows/test-build-idf-apps.yml +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/.gitignore +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/.readthedocs.yml +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/CONTRIBUTING.md +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/LICENSE +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/CHANGELOG.md +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/CONTRIBUTING.md +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/Makefile +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/_apidoc_templates/module.rst_t +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/_apidoc_templates/package.rst_t +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/_apidoc_templates/toc.rst_t +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/_static/espressif-logo.svg +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/_static/theme_overrides.css +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/_templates/layout.html +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/cli.rst +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/conf.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/config_file.md +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/find_build.md +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/index.rst +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/docs/migration/1.x_to_2.x.md +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/__main__.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/build_apps_args.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/config.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/finder.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/junit/__init__.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/junit/report.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/junit/utils.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/log.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/manifest/__init__.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/manifest/if_parser.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/manifest/manifest.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/session_args.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/yaml/__init__.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/idf_build_apps/yaml/parser.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/license_header.txt +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/tests/conftest.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/tests/test_app.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/tests/test_build.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/tests/test_finder.py +0 -0
- {idf_build_apps-2.3.0 → idf_build_apps-2.4.0}/tests/test_utils.py +0 -0
|
@@ -12,7 +12,7 @@ jobs:
|
|
|
12
12
|
fetch-depth: 0
|
|
13
13
|
- uses: actions/setup-python@v5
|
|
14
14
|
- id: changed-files
|
|
15
|
-
uses: tj-actions/changed-files@
|
|
15
|
+
uses: tj-actions/changed-files@v44
|
|
16
16
|
- uses: pre-commit/action@v3.0.1
|
|
17
17
|
with:
|
|
18
18
|
extra_args: --files ${{ steps.changed-files.outputs.all_changed_files }}
|
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## v2.4.0 (2024-06-17)
|
|
6
|
+
|
|
7
|
+
### Feat
|
|
8
|
+
|
|
9
|
+
- support esp32c5 soc header
|
|
10
|
+
- **cli**: add CLI autocompletions
|
|
11
|
+
|
|
12
|
+
## v2.3.1 (2024-04-22)
|
|
13
|
+
|
|
14
|
+
### Fix
|
|
15
|
+
|
|
16
|
+
- copy sdkconfig file while `_post_build` instead of the final phase of `build_apps`
|
|
17
|
+
|
|
5
18
|
## v2.3.0 (2024-03-20)
|
|
6
19
|
|
|
7
20
|
### Feat
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: idf-build-apps
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: Tools for building ESP-IDF related apps.
|
|
5
5
|
Author-email: Fu Hanxi <fuhanxi@espressif.com>
|
|
6
6
|
Requires-Python: >=3.7
|
|
@@ -18,6 +18,7 @@ Requires-Dist: pyyaml
|
|
|
18
18
|
Requires-Dist: packaging
|
|
19
19
|
Requires-Dist: toml; python_version < '3.11'
|
|
20
20
|
Requires-Dist: pydantic~=2.0
|
|
21
|
+
Requires-Dist: argcomplete>=3
|
|
21
22
|
Requires-Dist: typing-extensions ; extra == "dev" and ( python_version < '3.8')
|
|
22
23
|
Requires-Dist: sphinx ; extra == "doc"
|
|
23
24
|
Requires-Dist: sphinx-rtd-theme ; extra == "doc"
|
|
@@ -68,10 +69,11 @@ pipx install idf-build-apps
|
|
|
68
69
|
|
|
69
70
|
`idf-build-apps` is a python package that could be used as a library or a CLI tool.
|
|
70
71
|
|
|
71
|
-
As a CLI tool, it contains
|
|
72
|
+
As a CLI tool, it contains three sub-commands.
|
|
72
73
|
|
|
73
74
|
- `find` to find the buildable applications
|
|
74
75
|
- `build` to build the found applications
|
|
76
|
+
- `completions` to activate autocompletions or print instructions for manual activation
|
|
75
77
|
|
|
76
78
|
For detailed explanation to all CLI options, you may run
|
|
77
79
|
|
|
@@ -79,6 +81,7 @@ For detailed explanation to all CLI options, you may run
|
|
|
79
81
|
idf-build-apps -h
|
|
80
82
|
idf-build-apps find -h
|
|
81
83
|
idf-build-apps build -h
|
|
84
|
+
idf-build-apps completions -h
|
|
82
85
|
```
|
|
83
86
|
|
|
84
87
|
As a library, you may check the [API documentation][api-doc] for more information. Overall it provides
|
|
@@ -31,10 +31,11 @@ pipx install idf-build-apps
|
|
|
31
31
|
|
|
32
32
|
`idf-build-apps` is a python package that could be used as a library or a CLI tool.
|
|
33
33
|
|
|
34
|
-
As a CLI tool, it contains
|
|
34
|
+
As a CLI tool, it contains three sub-commands.
|
|
35
35
|
|
|
36
36
|
- `find` to find the buildable applications
|
|
37
37
|
- `build` to build the found applications
|
|
38
|
+
- `completions` to activate autocompletions or print instructions for manual activation
|
|
38
39
|
|
|
39
40
|
For detailed explanation to all CLI options, you may run
|
|
40
41
|
|
|
@@ -42,6 +43,7 @@ For detailed explanation to all CLI options, you may run
|
|
|
42
43
|
idf-build-apps -h
|
|
43
44
|
idf-build-apps find -h
|
|
44
45
|
idf-build-apps build -h
|
|
46
|
+
idf-build-apps completions -h
|
|
45
47
|
```
|
|
46
48
|
|
|
47
49
|
As a library, you may check the [API documentation][api-doc] for more information. Overall it provides
|
|
@@ -19,6 +19,33 @@ One typical manifest file look like this:
|
|
|
19
19
|
- ...
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
## Terms
|
|
23
|
+
|
|
24
|
+
### Supported Targets
|
|
25
|
+
|
|
26
|
+
This refers to the targets that are fully supported by the ESP-IDF project. You may check the supported targets by running `idf.py --list-targets`.
|
|
27
|
+
|
|
28
|
+
`idf-build-apps` will get this information dynamically from your `$IDF_PATH`. For ESP-IDF release 5.3, the supported targets are:
|
|
29
|
+
|
|
30
|
+
- esp32
|
|
31
|
+
- esp32s2
|
|
32
|
+
- esp32c3
|
|
33
|
+
- esp32s3
|
|
34
|
+
- esp32c2
|
|
35
|
+
- esp32c6
|
|
36
|
+
- esp32h2
|
|
37
|
+
- esp32p4
|
|
38
|
+
|
|
39
|
+
### Preview Targets
|
|
40
|
+
|
|
41
|
+
This refers to the targets that are still in preview status. You may check the preview targets by running `idf.py --list-targets --preview`.
|
|
42
|
+
|
|
43
|
+
`idf-build-apps` will get this information dynamically from your `$IDF_PATH`. For ESP-IDF release 5.3, the preview targets are:
|
|
44
|
+
|
|
45
|
+
- linux
|
|
46
|
+
- esp32c5
|
|
47
|
+
- esp32c61
|
|
48
|
+
|
|
22
49
|
## `if` Clauses
|
|
23
50
|
|
|
24
51
|
### Operands
|
|
@@ -30,7 +57,7 @@ One typical manifest file look like this:
|
|
|
30
57
|
- `IDF_VERSION_MAJOR`
|
|
31
58
|
- `IDF_VERSION_MINOR`
|
|
32
59
|
- `IDF_VERSION_PATCH`
|
|
33
|
-
- `INCLUDE_DEFAULT` (The default value of
|
|
60
|
+
- `INCLUDE_DEFAULT` (The default value of supported targets is 1, and the default value of preview targets is 0)
|
|
34
61
|
- `CONFIG_NAME` (config name defined in [](project:#config-rules))
|
|
35
62
|
- environment variables, default to `0` if not set
|
|
36
63
|
- String, must be double-quoted. e.g., `"esp32"`, `"12345"`
|
|
@@ -53,7 +80,9 @@ All operators are binary operators. For more than two operands, you may use the
|
|
|
53
80
|
|
|
54
81
|
## Enable/Disable Rules
|
|
55
82
|
|
|
56
|
-
By default, we enable build and test for all supported targets. In other words,
|
|
83
|
+
By default, we enable build and test for all supported targets. In other words, all preview targets are disabled.
|
|
84
|
+
|
|
85
|
+
To simplify the manifest file, if an app needs to be build and tested on all supported targets, it does not need to be added in a manifest file. The manifest files are files that set the violation rules for apps.
|
|
57
86
|
|
|
58
87
|
Three rules (disable rules are calculated after the `enable` rule):
|
|
59
88
|
- `enable`: run CI build/test jobs for targets that match any of the specified conditions only
|
|
@@ -124,6 +124,7 @@ class App(BaseModel):
|
|
|
124
124
|
verbose: bool = False
|
|
125
125
|
check_warnings: bool = False
|
|
126
126
|
preserve: bool = True
|
|
127
|
+
copy_sdkconfig: bool = False
|
|
127
128
|
|
|
128
129
|
# build_apps() related
|
|
129
130
|
build_apps_args: t.Optional[BuildAppsArgs] = None
|
|
@@ -561,6 +562,17 @@ class App(BaseModel):
|
|
|
561
562
|
def _post_build(self) -> None:
|
|
562
563
|
self._build_stage = BuildStage.POST_BUILD
|
|
563
564
|
|
|
565
|
+
if self.copy_sdkconfig:
|
|
566
|
+
try:
|
|
567
|
+
shutil.copy(
|
|
568
|
+
os.path.join(self.work_dir, 'sdkconfig'),
|
|
569
|
+
os.path.join(self.build_path, 'sdkconfig'),
|
|
570
|
+
)
|
|
571
|
+
except Exception as e:
|
|
572
|
+
self._logger.warning('Copy sdkconfig file from failed: %s', e)
|
|
573
|
+
else:
|
|
574
|
+
self._logger.debug('Copied sdkconfig file from %s to %s', self.work_dir, self.build_path)
|
|
575
|
+
|
|
564
576
|
if not os.path.isfile(self.build_log_path):
|
|
565
577
|
return
|
|
566
578
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from .utils import AutocompleteActivationError
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def append_to_file(file_path: str, content: str) -> None:
|
|
11
|
+
"""Add commands to shell configuration file
|
|
12
|
+
|
|
13
|
+
:param file_path: path to shell configurations file
|
|
14
|
+
:param content: commands to add
|
|
15
|
+
"""
|
|
16
|
+
if os.path.exists(file_path):
|
|
17
|
+
with open(file_path) as file:
|
|
18
|
+
if content.strip() in file.read():
|
|
19
|
+
print(f'Autocompletion already set up in {file_path}')
|
|
20
|
+
return
|
|
21
|
+
with open(file_path, 'a') as file:
|
|
22
|
+
file.write(f'\n# Begin added by idf-build-apps \n{content} \n# End added by idf-build-apps')
|
|
23
|
+
print(f'Autocompletion added to {file_path}')
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def activate_completions(shell_type: Optional[str]) -> None:
|
|
27
|
+
"""Activates autocompletion for supported shells.
|
|
28
|
+
|
|
29
|
+
:raises AutocompleteActivationError: if the $SHELL env variable is empty, or if the detected shell is unsupported.
|
|
30
|
+
"""
|
|
31
|
+
supported_shells = ['bash', 'zsh', 'fish']
|
|
32
|
+
|
|
33
|
+
if shell_type == 'auto':
|
|
34
|
+
shell_type = os.path.basename(os.environ.get('SHELL', ''))
|
|
35
|
+
|
|
36
|
+
if not shell_type:
|
|
37
|
+
raise AutocompleteActivationError('$SHELL is empty. Please provide your shell type with the `--shell` option')
|
|
38
|
+
|
|
39
|
+
if shell_type not in supported_shells:
|
|
40
|
+
raise AutocompleteActivationError('Unsupported shell. Autocompletion is supported for bash, zsh and fish.')
|
|
41
|
+
|
|
42
|
+
if shell_type == 'bash':
|
|
43
|
+
completion_command = 'eval "$(register-python-argcomplete idf-build-apps)"'
|
|
44
|
+
elif shell_type == 'zsh':
|
|
45
|
+
completion_command = (
|
|
46
|
+
'autoload -U bashcompinit && bashcompinit && eval "$(register-python-argcomplete idf-build-apps)"'
|
|
47
|
+
)
|
|
48
|
+
elif shell_type == 'fish':
|
|
49
|
+
completion_command = 'register-python-argcomplete --shell fish idf-build-apps | source'
|
|
50
|
+
|
|
51
|
+
rc_file = {'bash': '~/.bashrc', 'zsh': '~/.zshrc', 'fish': '~/.config/fish/completions/idf-build-apps.fish'}
|
|
52
|
+
|
|
53
|
+
shell_rc = os.path.expanduser(rc_file[shell_type])
|
|
54
|
+
append_to_file(shell_rc, completion_command)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: 2022-
|
|
1
|
+
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import enum
|
|
@@ -95,3 +95,37 @@ class BuildStage(str, enum.Enum):
|
|
|
95
95
|
@classmethod
|
|
96
96
|
def max_length(cls) -> int:
|
|
97
97
|
return max(len(v.value) for v in cls.__members__.values())
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
completion_instructions = """
|
|
101
|
+
With `--activate` option detect your shell type and add the appropriate commands to your shell's config file
|
|
102
|
+
so that it is run on startup. You will likely have to restart
|
|
103
|
+
or re-login for the autocompletion to start working.
|
|
104
|
+
|
|
105
|
+
You can also specify your shell by the `--shell` option.
|
|
106
|
+
|
|
107
|
+
If you do not want automaticall modifying your shell config file
|
|
108
|
+
you can manually add commands provided below to activate autocompletion
|
|
109
|
+
or run them in your current terminal session for one-time activation.
|
|
110
|
+
|
|
111
|
+
Once again, you will likely have to restart
|
|
112
|
+
or re-login for the autocompletion to start working.
|
|
113
|
+
|
|
114
|
+
bash:
|
|
115
|
+
eval "$(register-python-argcomplete idf-build-apps)"
|
|
116
|
+
|
|
117
|
+
zsh:
|
|
118
|
+
To activate completions in zsh, first make sure compinit is marked for
|
|
119
|
+
autoload and run autoload:
|
|
120
|
+
|
|
121
|
+
autoload -U compinit
|
|
122
|
+
compinit
|
|
123
|
+
|
|
124
|
+
Afterwards you can enable completions for idf-build-apps:
|
|
125
|
+
|
|
126
|
+
eval "$(register-python-argcomplete idf-build-apps)"
|
|
127
|
+
|
|
128
|
+
fish:
|
|
129
|
+
# Not required to be in the config file, only run once
|
|
130
|
+
register-python-argcomplete --shell fish idf-build-apps >~/.config/fish/completions/idf-build-apps.fish
|
|
131
|
+
"""
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# PYTHON_ARGCOMPLETE_OK
|
|
2
|
+
|
|
1
3
|
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
|
2
4
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
5
|
|
|
@@ -6,11 +8,11 @@ import json
|
|
|
6
8
|
import logging
|
|
7
9
|
import os
|
|
8
10
|
import re
|
|
9
|
-
import shutil
|
|
10
11
|
import sys
|
|
11
12
|
import textwrap
|
|
12
13
|
import typing as t
|
|
13
14
|
|
|
15
|
+
import argcomplete
|
|
14
16
|
from pydantic import (
|
|
15
17
|
Field,
|
|
16
18
|
create_model,
|
|
@@ -25,16 +27,14 @@ from .app import (
|
|
|
25
27
|
CMakeApp,
|
|
26
28
|
MakeApp,
|
|
27
29
|
)
|
|
30
|
+
from .autocompletions import activate_completions
|
|
28
31
|
from .build_apps_args import (
|
|
29
32
|
BuildAppsArgs,
|
|
30
33
|
)
|
|
31
34
|
from .config import (
|
|
32
35
|
get_valid_config,
|
|
33
36
|
)
|
|
34
|
-
from .constants import
|
|
35
|
-
ALL_TARGETS,
|
|
36
|
-
BuildStatus,
|
|
37
|
-
)
|
|
37
|
+
from .constants import ALL_TARGETS, BuildStatus, completion_instructions
|
|
38
38
|
from .finder import (
|
|
39
39
|
_find_apps,
|
|
40
40
|
)
|
|
@@ -51,6 +51,7 @@ from .manifest.manifest import (
|
|
|
51
51
|
Manifest,
|
|
52
52
|
)
|
|
53
53
|
from .utils import (
|
|
54
|
+
AutocompleteActivationError,
|
|
54
55
|
InvalidCommand,
|
|
55
56
|
files_matches_patterns,
|
|
56
57
|
get_parallel_start_stop,
|
|
@@ -324,6 +325,7 @@ def build_apps(
|
|
|
324
325
|
app.dry_run = dry_run
|
|
325
326
|
app.index = index
|
|
326
327
|
app.verbose = build_verbose
|
|
328
|
+
app.copy_sdkconfig = copy_sdkconfig
|
|
327
329
|
|
|
328
330
|
LOGGER.info('(%s/%s) Building app: %s', index, len(apps), app)
|
|
329
331
|
|
|
@@ -353,17 +355,6 @@ def build_apps(
|
|
|
353
355
|
fw.write(app.to_json() + '\n')
|
|
354
356
|
LOGGER.debug('Recorded app info in %s', build_apps_args.collect_app_info)
|
|
355
357
|
|
|
356
|
-
if copy_sdkconfig:
|
|
357
|
-
try:
|
|
358
|
-
shutil.copy(
|
|
359
|
-
os.path.join(app.work_dir, 'sdkconfig'),
|
|
360
|
-
os.path.join(app.build_path, 'sdkconfig'),
|
|
361
|
-
)
|
|
362
|
-
except Exception as e:
|
|
363
|
-
LOGGER.warning('Copy sdkconfig file from failed: %s', e)
|
|
364
|
-
else:
|
|
365
|
-
LOGGER.debug('Copied sdkconfig file from %s to %s', app.work_dir, app.build_path)
|
|
366
|
-
|
|
367
358
|
if app.build_status == BuildStatus.FAILED:
|
|
368
359
|
if not keep_going:
|
|
369
360
|
return 1
|
|
@@ -617,10 +608,27 @@ def get_parser() -> argparse.ArgumentParser:
|
|
|
617
608
|
help='enable colored output by default on UNIX-like systems. enable this flag to make the logs uncolored.',
|
|
618
609
|
)
|
|
619
610
|
|
|
620
|
-
find_parser = actions.add_parser(
|
|
611
|
+
find_parser = actions.add_parser(
|
|
612
|
+
'find',
|
|
613
|
+
help='Find the buildable applications. Run `idf-build-apps find --help` for more information on a command',
|
|
614
|
+
description='Find the buildable applications in the given path or paths for specified chips. '
|
|
615
|
+
'`--path` and `--target` options must be provided. '
|
|
616
|
+
'By default, print the found apps in stdout. '
|
|
617
|
+
'To find apps for all chips use the `--target` option with the `all` argument.',
|
|
618
|
+
parents=[common_args],
|
|
619
|
+
formatter_class=IdfBuildAppsCliFormatter,
|
|
620
|
+
)
|
|
621
|
+
|
|
621
622
|
find_parser.add_argument('-o', '--output', help='Print the found apps to the specified file instead of stdout')
|
|
622
623
|
|
|
623
|
-
build_parser = actions.add_parser(
|
|
624
|
+
build_parser = actions.add_parser(
|
|
625
|
+
'build',
|
|
626
|
+
help='Build the found applications. Run `idf-build-apps build --help` for more information on a command',
|
|
627
|
+
description='Build the application in the given path or paths for specified chips. '
|
|
628
|
+
'`--path` and `--target` options must be provided.',
|
|
629
|
+
parents=[common_args],
|
|
630
|
+
formatter_class=IdfBuildAppsCliFormatter,
|
|
631
|
+
)
|
|
624
632
|
build_parser.add_argument(
|
|
625
633
|
'--build-verbose',
|
|
626
634
|
action='store_true',
|
|
@@ -685,14 +693,48 @@ def get_parser() -> argparse.ArgumentParser:
|
|
|
685
693
|
help='Path to the junitxml file. If specified, the junitxml file will be generated. Can expand placeholder @p',
|
|
686
694
|
)
|
|
687
695
|
|
|
696
|
+
completions_parser = actions.add_parser(
|
|
697
|
+
'completions',
|
|
698
|
+
help='Add the autocompletion activation script to the shell rc file. '
|
|
699
|
+
'Run `idf-build-apps complations --help` for more information on a command',
|
|
700
|
+
description='Without `--activate` option print instructions for manual activation. '
|
|
701
|
+
'With `--activate` option add the autocompletion activation script to the shell rc file '
|
|
702
|
+
'for bash, zsh, or fish. Other shells are not supported. '
|
|
703
|
+
'The `--shell` option used only with the `--activate` option, '
|
|
704
|
+
'if provided, add the autocompletion activation script to the given shell; '
|
|
705
|
+
'without this argument, will detect shell type automatically. '
|
|
706
|
+
'May need to restart or re-login for the autocompletion to start working',
|
|
707
|
+
formatter_class=IdfBuildAppsCliFormatter,
|
|
708
|
+
)
|
|
709
|
+
completions_parser.add_argument(
|
|
710
|
+
'-a', '--activate', action='store_true', help='Activate autocompletion automatically and permanently'
|
|
711
|
+
)
|
|
712
|
+
completions_parser.add_argument(
|
|
713
|
+
'-s',
|
|
714
|
+
'--shell',
|
|
715
|
+
choices=['bash', 'zsh', 'fish'],
|
|
716
|
+
help='Specify the shell type for the autocomplite activation script. ',
|
|
717
|
+
)
|
|
718
|
+
|
|
688
719
|
return parser
|
|
689
720
|
|
|
690
721
|
|
|
722
|
+
def handle_completions(args: argparse.Namespace) -> None:
|
|
723
|
+
if args.activate:
|
|
724
|
+
if not args.shell:
|
|
725
|
+
args.shell = 'auto'
|
|
726
|
+
activate_completions(args.shell)
|
|
727
|
+
elif not args.activate and args.shell:
|
|
728
|
+
raise AutocompleteActivationError('The --shell option can only be used with the --activate option.')
|
|
729
|
+
else:
|
|
730
|
+
print(completion_instructions)
|
|
731
|
+
|
|
732
|
+
|
|
691
733
|
def validate_args(parser: argparse.ArgumentParser, args: argparse.Namespace) -> None:
|
|
692
734
|
# validate cli subcommands
|
|
693
|
-
if args.action not in ['find', 'build']:
|
|
735
|
+
if args.action not in ['find', 'build', 'completions']:
|
|
694
736
|
parser.print_help()
|
|
695
|
-
raise InvalidCommand('subcommand is required. {find, build}')
|
|
737
|
+
raise InvalidCommand('subcommand is required. {find, build, completions}')
|
|
696
738
|
|
|
697
739
|
if not args.paths:
|
|
698
740
|
raise InvalidCommand(
|
|
@@ -739,8 +781,13 @@ def apply_config_args(args: argparse.Namespace) -> None:
|
|
|
739
781
|
|
|
740
782
|
def main():
|
|
741
783
|
parser = get_parser()
|
|
784
|
+
argcomplete.autocomplete(parser)
|
|
742
785
|
args = parser.parse_args()
|
|
743
786
|
|
|
787
|
+
if args.action == 'completions':
|
|
788
|
+
handle_completions(args)
|
|
789
|
+
sys.exit(0)
|
|
790
|
+
|
|
744
791
|
apply_config_args(args)
|
|
745
792
|
validate_args(parser, args)
|
|
746
793
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import glob
|
|
3
4
|
import logging
|
|
4
5
|
import os.path
|
|
5
6
|
import typing as t
|
|
@@ -82,35 +83,47 @@ class SocHeader(dict):
|
|
|
82
83
|
super().__init__(**soc_header_dict)
|
|
83
84
|
|
|
84
85
|
@staticmethod
|
|
85
|
-
def
|
|
86
|
+
def _get_dirs_from_candidates(candidates: t.List[str]) -> t.List[str]:
|
|
87
|
+
dirs = []
|
|
86
88
|
for d in candidates:
|
|
87
89
|
if not os.path.isdir(d):
|
|
88
90
|
LOGGER.debug('folder "%s" not found. Skipping...', os.path.abspath(d))
|
|
89
91
|
else:
|
|
90
|
-
|
|
92
|
+
dirs.append(d)
|
|
91
93
|
|
|
92
|
-
return
|
|
94
|
+
return dirs
|
|
95
|
+
|
|
96
|
+
@staticmethod
|
|
97
|
+
def _find_candidates_from_pattern(pattern: str) -> t.List[str]:
|
|
98
|
+
# get dirs from pattern
|
|
99
|
+
return [d for d in glob.glob(pattern) if os.path.isdir(d)]
|
|
93
100
|
|
|
94
101
|
@classmethod
|
|
95
102
|
def _parse_soc_header(cls, target: str) -> t.Dict[str, t.Any]:
|
|
96
|
-
|
|
103
|
+
soc_headers_dirs = cls._get_dirs_from_candidates([
|
|
104
|
+
# master c5
|
|
105
|
+
*cls._find_candidates_from_pattern(
|
|
106
|
+
os.path.join(IDF_PATH, 'components', 'soc', target, '*', 'include', 'soc')
|
|
107
|
+
),
|
|
97
108
|
# other branches
|
|
98
109
|
os.path.abspath(os.path.join(IDF_PATH, 'components', 'soc', target, 'include', 'soc')),
|
|
99
110
|
# release/v4.2
|
|
100
111
|
os.path.abspath(os.path.join(IDF_PATH, 'components', 'soc', 'soc', target, 'include', 'soc')),
|
|
101
112
|
])
|
|
102
|
-
|
|
113
|
+
esp_rom_headers_dirs = cls._get_dirs_from_candidates([
|
|
114
|
+
# master c5
|
|
115
|
+
*cls._find_candidates_from_pattern(os.path.join(IDF_PATH, 'components', 'esp_rom', target, '*', target)),
|
|
103
116
|
os.path.join(IDF_PATH, 'components', 'esp_rom', target),
|
|
104
117
|
])
|
|
105
118
|
|
|
106
119
|
header_files: t.List[str] = []
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
header_files += [str(p.resolve()) for p in Path(esp_rom_headers_dir).glob(cls.CAPS_HEADER_FILEPATTERN)]
|
|
120
|
+
for d in [*soc_headers_dirs, *esp_rom_headers_dirs]:
|
|
121
|
+
LOGGER.debug('Checking dir %s', d)
|
|
122
|
+
header_files += [str(p.resolve()) for p in Path(d).glob(cls.CAPS_HEADER_FILEPATTERN)]
|
|
111
123
|
|
|
112
124
|
output_dict = {}
|
|
113
125
|
for f in header_files:
|
|
126
|
+
LOGGER.debug('Checking header file %s', f)
|
|
114
127
|
for line in get_defines(f):
|
|
115
128
|
try:
|
|
116
129
|
res = parse_define(line)
|
|
@@ -28,6 +28,7 @@ dependencies = [
|
|
|
28
28
|
"packaging",
|
|
29
29
|
"toml; python_version < '3.11'",
|
|
30
30
|
"pydantic~=2.0",
|
|
31
|
+
"argcomplete>=3"
|
|
31
32
|
]
|
|
32
33
|
|
|
33
34
|
[project.optional-dependencies]
|
|
@@ -60,7 +61,7 @@ idf-build-apps = "idf_build_apps:main.main"
|
|
|
60
61
|
|
|
61
62
|
[tool.commitizen]
|
|
62
63
|
name = "cz_conventional_commits"
|
|
63
|
-
version = "2.
|
|
64
|
+
version = "2.4.0"
|
|
64
65
|
tag_format = "v$version"
|
|
65
66
|
version_files = [
|
|
66
67
|
"idf_build_apps/__init__.py",
|
|
@@ -13,7 +13,7 @@ package_data = \
|
|
|
13
13
|
{'': ['*']}
|
|
14
14
|
|
|
15
15
|
install_requires = \
|
|
16
|
-
['pyparsing', 'pyyaml', 'packaging', 'pydantic~=2.0']
|
|
16
|
+
['pyparsing', 'pyyaml', 'packaging', 'pydantic~=2.0', 'argcomplete>=3']
|
|
17
17
|
|
|
18
18
|
extras_require = \
|
|
19
19
|
{":python_version < '3.11'": ['toml'],
|
|
@@ -30,7 +30,7 @@ entry_points = \
|
|
|
30
30
|
{'console_scripts': ['idf-build-apps = idf_build_apps:main.main']}
|
|
31
31
|
|
|
32
32
|
setup(name='idf-build-apps',
|
|
33
|
-
version='2.
|
|
33
|
+
version='2.4.0',
|
|
34
34
|
description='Tools for building ESP-IDF related apps.',
|
|
35
35
|
author=None,
|
|
36
36
|
author_email='Fu Hanxi <fuhanxi@espressif.com>',
|
|
@@ -122,7 +122,8 @@ test5:
|
|
|
122
122
|
|
|
123
123
|
os.chdir(tmpdir)
|
|
124
124
|
Manifest.ROOTPATH = tmpdir
|
|
125
|
-
|
|
125
|
+
with pytest.warns(UserWarning, match='Folder ".+" does not exist. Please check your manifest file'):
|
|
126
|
+
manifest = Manifest.from_file(yaml_file)
|
|
126
127
|
|
|
127
128
|
assert manifest.depends_components('test1', None, None) == ['VVV']
|
|
128
129
|
assert manifest.depends_components('test1', None, 'AAA') == ['VVV']
|
|
@@ -175,7 +176,8 @@ test1:
|
|
|
175
176
|
)
|
|
176
177
|
os.chdir(tmpdir)
|
|
177
178
|
Manifest.ROOTPATH = tmpdir
|
|
178
|
-
|
|
179
|
+
with pytest.warns(UserWarning, match='Folder ".+" does not exist. Please check your manifest file'):
|
|
180
|
+
manifest = Manifest.from_file(yaml_file)
|
|
179
181
|
|
|
180
182
|
assert manifest.depends_components('test1', None, None) == ['DF']
|
|
181
183
|
assert manifest.depends_components('test1', None, 'CCC') == ['DF']
|
|
@@ -202,7 +204,8 @@ def test_manifest_switch_clause_wrong_manifest_format(tmpdir):
|
|
|
202
204
|
encoding='utf8',
|
|
203
205
|
)
|
|
204
206
|
try:
|
|
205
|
-
|
|
207
|
+
with pytest.warns(UserWarning, match='Folder ".+" does not exist. Please check your manifest file'):
|
|
208
|
+
Manifest.from_file(yaml_file)
|
|
206
209
|
except InvalidManifest as e:
|
|
207
210
|
assert str(e) == "Only the 'if' and 'default' keywords are supported in switch clause."
|
|
208
211
|
|
|
@@ -219,7 +222,8 @@ def test_manifest_switch_clause_wrong_manifest_format(tmpdir):
|
|
|
219
222
|
encoding='utf8',
|
|
220
223
|
)
|
|
221
224
|
try:
|
|
222
|
-
|
|
225
|
+
with pytest.warns(UserWarning, match='Folder ".+" does not exist. Please check your manifest file'):
|
|
226
|
+
Manifest.from_file(yaml_file)
|
|
223
227
|
except InvalidManifest as e:
|
|
224
228
|
assert str(e) == 'Current manifest format has to fit either the switch format or the list format.'
|
|
225
229
|
|
|
@@ -260,7 +264,9 @@ foo:
|
|
|
260
264
|
""",
|
|
261
265
|
encoding='utf8',
|
|
262
266
|
)
|
|
263
|
-
|
|
267
|
+
with pytest.warns(UserWarning, match='Folder ".+" does not exist. Please check your manifest file'):
|
|
268
|
+
manifest = Manifest.from_file(yaml_file)
|
|
269
|
+
|
|
264
270
|
assert manifest.enable_build_targets('foo') == sorted(SUPPORTED_TARGETS)
|
|
265
271
|
|
|
266
272
|
yaml_file.write_text(
|
|
@@ -281,7 +287,9 @@ examples/wifi/coexist:
|
|
|
281
287
|
encoding='utf8',
|
|
282
288
|
)
|
|
283
289
|
|
|
284
|
-
|
|
290
|
+
with pytest.warns(UserWarning, match='Folder ".+" does not exist. Please check your manifest file'):
|
|
291
|
+
manifest = Manifest.from_file(yaml_file)
|
|
292
|
+
|
|
285
293
|
assert manifest.depends_components('examples/wifi/coexist') == ['esp_coex', 'esp_hw_support', 'esp_wifi']
|
|
286
294
|
|
|
287
295
|
yaml_file.write_text(
|
|
@@ -428,7 +436,9 @@ examples/wifi/coexist:
|
|
|
428
436
|
encoding='utf8',
|
|
429
437
|
)
|
|
430
438
|
|
|
431
|
-
|
|
439
|
+
with pytest.warns(UserWarning, match='Folder ".+" does not exist. Please check your manifest file'):
|
|
440
|
+
manifest = Manifest.from_file(yaml_file)
|
|
441
|
+
|
|
432
442
|
assert manifest.depends_components('examples/wifi/coexist') == ['esp_hw_support']
|
|
433
443
|
|
|
434
444
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|