idf-build-apps 2.6.0__tar.gz → 2.6.2__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.
Files changed (78) hide show
  1. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/.github/workflows/publish-pypi.yml +3 -3
  2. idf_build_apps-2.6.2/.github/workflows/sync-jira.yml +61 -0
  3. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/.github/workflows/test-build-docs.yml +1 -1
  4. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/.github/workflows/test-build-idf-apps.yml +2 -1
  5. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/.pre-commit-config.yaml +1 -0
  6. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/.readthedocs.yml +4 -0
  7. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/CHANGELOG.md +12 -0
  8. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/PKG-INFO +2 -1
  9. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/__init__.py +1 -1
  10. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/args.py +25 -12
  11. idf_build_apps-2.6.2/idf_build_apps/constants.py +77 -0
  12. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/main.py +7 -5
  13. idf_build_apps-2.6.2/idf_build_apps/manifest/__init__.py +17 -0
  14. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/manifest/manifest.py +16 -8
  15. idf_build_apps-2.6.2/idf_build_apps/manifest/soc_header.py +6 -0
  16. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/vendors/pydantic_sources.py +7 -3
  17. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/pyproject.toml +5 -1
  18. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/setup.py +3 -2
  19. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/tests/conftest.py +5 -5
  20. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/tests/test_args.py +38 -1
  21. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/tests/test_manifest.py +32 -23
  22. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/tests/test_utils.py +1 -15
  23. idf_build_apps-2.6.0/.github/workflows/issue_comment.yml +0 -20
  24. idf_build_apps-2.6.0/.github/workflows/new_issues.yml +0 -20
  25. idf_build_apps-2.6.0/.github/workflows/new_prs.yml +0 -25
  26. idf_build_apps-2.6.0/idf_build_apps/constants.py +0 -122
  27. idf_build_apps-2.6.0/idf_build_apps/manifest/__init__.py +0 -6
  28. idf_build_apps-2.6.0/idf_build_apps/manifest/if_parser.py +0 -240
  29. idf_build_apps-2.6.0/idf_build_apps/manifest/soc_header.py +0 -141
  30. idf_build_apps-2.6.0/tests/test_soc_caps.py +0 -21
  31. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/.editorconfig +0 -0
  32. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/.git-blame-ignore-revs +0 -0
  33. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/.gitattributes +0 -0
  34. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/.github/dependabot.yml +0 -0
  35. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/.github/workflows/check-pre-commit.yml +0 -0
  36. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/.gitignore +0 -0
  37. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/CONTRIBUTING.md +0 -0
  38. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/LICENSE +0 -0
  39. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/README.md +0 -0
  40. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/_apidoc_templates/module.rst_t +0 -0
  41. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/_apidoc_templates/package.rst_t +0 -0
  42. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/_apidoc_templates/toc.rst_t +0 -0
  43. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/_static/espressif-logo.svg +0 -0
  44. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/_static/theme_overrides.css +0 -0
  45. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/_templates/layout.html +0 -0
  46. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/conf_common.py +0 -0
  47. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/en/Makefile +0 -0
  48. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/en/conf.py +0 -0
  49. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/en/explanations/build.rst +0 -0
  50. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/en/explanations/config_rules.rst +0 -0
  51. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/en/explanations/dependency_driven_build.rst +0 -0
  52. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/en/explanations/find.rst +0 -0
  53. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/en/guides/1.x_to_2.x.md +0 -0
  54. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/en/index.rst +0 -0
  55. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/en/others/CHANGELOG.md +0 -0
  56. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/en/others/CONTRIBUTING.md +0 -0
  57. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/en/references/cli.rst +0 -0
  58. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/en/references/config_file.rst +0 -0
  59. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/docs/en/references/manifest.rst +0 -0
  60. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/__main__.py +0 -0
  61. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/app.py +0 -0
  62. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/autocompletions.py +0 -0
  63. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/finder.py +0 -0
  64. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/junit/__init__.py +0 -0
  65. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/junit/report.py +0 -0
  66. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/junit/utils.py +0 -0
  67. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/log.py +0 -0
  68. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/py.typed +0 -0
  69. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/session_args.py +0 -0
  70. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/utils.py +0 -0
  71. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/vendors/__init__.py +0 -0
  72. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/yaml/__init__.py +0 -0
  73. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/idf_build_apps/yaml/parser.py +0 -0
  74. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/license_header.txt +0 -0
  75. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/tests/test_app.py +0 -0
  76. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/tests/test_build.py +0 -0
  77. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/tests/test_cmd.py +0 -0
  78. {idf_build_apps-2.6.0 → idf_build_apps-2.6.2}/tests/test_finder.py +0 -0
@@ -3,16 +3,16 @@ name: Publish PyPI
3
3
  on:
4
4
  push:
5
5
  tags:
6
- - 'v*'
6
+ - "v*"
7
7
 
8
8
  jobs:
9
9
  deploy:
10
- runs-on: ubuntu-latest
10
+ runs-on: ubuntu-22.04
11
11
  steps:
12
12
  - uses: actions/checkout@v4
13
13
  - uses: actions/setup-python@v5
14
14
  with:
15
- python-version: '3.7'
15
+ python-version: "3.7"
16
16
  - name: Publish packages
17
17
  env:
18
18
  FLIT_USERNAME: __token__
@@ -0,0 +1,61 @@
1
+ # FILE: .github/workflows/sync-jira.yml
2
+ ---
3
+ # This GitHub Actions workflow synchronizes GitHub issues, comments, and pull requests with Jira.
4
+ # It triggers on new issues, issue comments, and on a scheduled basis.
5
+ # The workflow uses a custom action to perform the synchronization with Jira (espressif/sync-jira-actions).
6
+
7
+ name: 🔷 Sync to Jira
8
+
9
+ run-name: >
10
+ Sync to Jira -
11
+ ${{ github.event_name == 'issue_comment' && 'Issue Comment' ||
12
+ github.event_name == 'schedule' && 'New Pull Requests' ||
13
+ github.event_name == 'issues' && 'New Issue' ||
14
+ github.event_name == 'workflow_dispatch' && 'Manual Sync' }}
15
+
16
+ on:
17
+ issues: { types: [opened] }
18
+ issue_comment: { types: [created, edited, deleted] }
19
+ schedule: [cron: "0 * * * *"]
20
+ workflow_dispatch:
21
+ inputs:
22
+ action:
23
+ {
24
+ description: "Action to be performed",
25
+ required: true,
26
+ default: "mirror-issues",
27
+ }
28
+ issue-numbers:
29
+ {
30
+ description: "Issue numbers to sync (comma-separated)",
31
+ required: true,
32
+ }
33
+
34
+ jobs:
35
+ sync-to-jira:
36
+ name: >
37
+ Sync to Jira -
38
+ ${{ github.event_name == 'issue_comment' && 'Issue Comment' ||
39
+ github.event_name == 'schedule' && 'New Pull Requests' ||
40
+ github.event_name == 'issues' && 'New Issue' ||
41
+ github.event_name == 'workflow_dispatch' && 'Manual Sync' }}
42
+ runs-on: ubuntu-latest
43
+ permissions:
44
+ contents: read
45
+ issues: write
46
+ pull-requests: write
47
+ steps:
48
+ - name: Check out
49
+ uses: actions/checkout@v4
50
+
51
+ - name: Run synchronization to Jira
52
+ uses: espressif/sync-jira-actions@v1
53
+ with:
54
+ cron_job: ${{ github.event_name == 'schedule' && 'true' || '' }}
55
+ env:
56
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
57
+ JIRA_PASS: ${{ secrets.JIRA_PASS }}
58
+ JIRA_PROJECT: RDT
59
+ JIRA_COMPONENT: idf-build-apps
60
+ JIRA_URL: ${{ secrets.JIRA_URL }}
61
+ JIRA_USER: ${{ secrets.JIRA_USER }}
@@ -5,7 +5,7 @@ on:
5
5
 
6
6
  jobs:
7
7
  build-docs:
8
- runs-on: ubuntu-latest
8
+ runs-on: ubuntu-22.04
9
9
  steps:
10
10
  - uses: actions/checkout@v4
11
11
  - name: Set up Python
@@ -17,7 +17,7 @@ defaults:
17
17
 
18
18
  jobs:
19
19
  build-python-packages:
20
- runs-on: ubuntu-latest
20
+ runs-on: ubuntu-22.04
21
21
  steps:
22
22
  - uses: actions/checkout@v4
23
23
  - uses: actions/setup-python@v5
@@ -78,6 +78,7 @@ jobs:
78
78
  --size-file size_info.json
79
79
  pytest --cov idf_build_apps --cov-report term-missing:skip-covered --junit-xml pytest.xml | tee pytest-coverage.txt
80
80
  - name: Pytest coverage comment
81
+ if: github.event_name == 'pull_request'
81
82
  uses: MishaKav/pytest-coverage-comment@main
82
83
  with:
83
84
  pytest-coverage-path: pytest-coverage.txt
@@ -37,6 +37,7 @@ repos:
37
37
  - types-toml
38
38
  - pytest
39
39
  - argcomplete>=3
40
+ - esp-bool-parser>=0.1.2,<1
40
41
  - repo: https://github.com/hfudev/rstfmt
41
42
  rev: v0.1.4
42
43
  hooks:
@@ -4,6 +4,10 @@
4
4
 
5
5
  version: 2
6
6
 
7
+ sphinx:
8
+ # Path to your Sphinx configuration file.
9
+ configuration: docs/en/conf.py
10
+
7
11
  build:
8
12
  os: ubuntu-22.04
9
13
  tools:
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## v2.6.2 (2025-01-21)
6
+
7
+ ### Fix
8
+
9
+ - windows root dir returns '\\' instead of the drive
10
+
11
+ ## v2.6.1 (2025-01-13)
12
+
13
+ ### Fix
14
+
15
+ - --config-file not refreshed
16
+
5
17
  ## v2.6.0 (2025-01-02)
6
18
 
7
19
  ### Feat
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: idf-build-apps
3
- Version: 2.6.0
3
+ Version: 2.6.2
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
@@ -21,6 +21,7 @@ Requires-Dist: pydantic~=2.0
21
21
  Requires-Dist: pydantic_settings
22
22
  Requires-Dist: argcomplete>=3
23
23
  Requires-Dist: typing-extensions; python_version < '3.11'
24
+ Requires-Dist: esp-bool-parser>=0.1.2,<1
24
25
  Requires-Dist: sphinx ; extra == "doc"
25
26
  Requires-Dist: sphinx-rtd-theme ; extra == "doc"
26
27
  Requires-Dist: sphinx_copybutton ; extra == "doc"
@@ -8,7 +8,7 @@ Tools for building ESP-IDF related apps.
8
8
  # ruff: noqa: E402
9
9
  # avoid circular imports
10
10
 
11
- __version__ = '2.6.0'
11
+ __version__ = '2.6.2'
12
12
 
13
13
  from .session_args import (
14
14
  SessionArgs,
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import argparse
@@ -115,8 +115,9 @@ def get_meta(f: FieldInfo) -> t.Optional[FieldMetadata]:
115
115
  class BaseArguments(BaseSettings):
116
116
  """Base settings class for all settings classes"""
117
117
 
118
+ CONFIG_FILE_PATH: t.ClassVar[t.Optional[Path]] = None
119
+
118
120
  model_config = SettingsConfigDict(
119
- toml_file=IDF_BUILD_APPS_TOML_FN,
120
121
  # these below two are supported in pydantic 2.6
121
122
  pyproject_toml_table_header=('tool', 'idf-build-apps'),
122
123
  pyproject_toml_depth=sys.maxsize,
@@ -132,11 +133,15 @@ class BaseArguments(BaseSettings):
132
133
  dotenv_settings: PydanticBaseSettingsSource, # noqa: ARG003
133
134
  file_secret_settings: PydanticBaseSettingsSource, # noqa: ARG003
134
135
  ) -> t.Tuple[PydanticBaseSettingsSource, ...]:
135
- return (
136
- init_settings,
137
- TomlConfigSettingsSource(settings_cls),
138
- PyprojectTomlConfigSettingsSource(settings_cls),
139
- )
136
+ sources: t.Tuple[PydanticBaseSettingsSource, ...] = (init_settings,)
137
+ if cls.CONFIG_FILE_PATH is None:
138
+ sources += (TomlConfigSettingsSource(settings_cls, toml_file=Path(IDF_BUILD_APPS_TOML_FN)),)
139
+ sources += (PyprojectTomlConfigSettingsSource(settings_cls, toml_file=Path('pyproject.toml')),)
140
+ else:
141
+ sources += (TomlConfigSettingsSource(settings_cls, toml_file=Path(cls.CONFIG_FILE_PATH)),)
142
+ sources += (PyprojectTomlConfigSettingsSource(settings_cls, toml_file=Path(cls.CONFIG_FILE_PATH)),)
143
+
144
+ return sources
140
145
 
141
146
  @field_validator('*', mode='before')
142
147
  @classmethod
@@ -874,12 +879,20 @@ def add_args_to_obj_doc_as_params(argument_cls: t.Type[GlobalArguments], obj: t.
874
879
  _obj.__doc__ = _doc_str
875
880
 
876
881
 
877
- def apply_config_file(config_file: t.Optional[str]) -> None:
882
+ def apply_config_file(config_file: t.Optional[str] = None, reset: bool = False) -> None:
878
883
  def _subclasses(klass: t.Type[T]) -> t.Set[t.Type[T]]:
879
884
  return set(klass.__subclasses__()).union([s for c in klass.__subclasses__() for s in _subclasses(c)])
880
885
 
881
- if config_file:
882
- BaseArguments.model_config['toml_file'] = str(config_file)
883
- # modify all subclasses
886
+ if reset:
887
+ BaseArguments.CONFIG_FILE_PATH = None
884
888
  for cls in _subclasses(BaseArguments):
885
- cls.model_config['toml_file'] = str(config_file)
889
+ cls.CONFIG_FILE_PATH = None
890
+
891
+ if config_file:
892
+ if os.path.isfile(config_file):
893
+ p = Path(config_file)
894
+ BaseArguments.CONFIG_FILE_PATH = p
895
+ for cls in _subclasses(BaseArguments):
896
+ cls.CONFIG_FILE_PATH = p
897
+ else:
898
+ LOGGER.warning(f'Config file {config_file} does not exist. Ignoring...')
@@ -0,0 +1,77 @@
1
+ # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ import enum
5
+ import os
6
+
7
+ import esp_bool_parser
8
+
9
+ IDF_PATH = esp_bool_parser.IDF_PATH
10
+ IDF_PY = os.path.join(IDF_PATH, 'tools', 'idf.py')
11
+ IDF_SIZE_PY = os.path.join(IDF_PATH, 'tools', 'idf_size.py')
12
+
13
+ PROJECT_DESCRIPTION_JSON = 'project_description.json'
14
+ DEFAULT_SDKCONFIG = 'sdkconfig.defaults'
15
+
16
+ SUPPORTED_TARGETS = esp_bool_parser.SUPPORTED_TARGETS
17
+ PREVIEW_TARGETS = esp_bool_parser.PREVIEW_TARGETS
18
+ ALL_TARGETS = esp_bool_parser.ALL_TARGETS
19
+ IDF_VERSION_MAJOR = esp_bool_parser.IDF_VERSION_MAJOR
20
+ IDF_VERSION_MINOR = esp_bool_parser.IDF_VERSION_MINOR
21
+ IDF_VERSION_PATCH = esp_bool_parser.IDF_VERSION_PATCH
22
+ IDF_VERSION = esp_bool_parser.IDF_VERSION
23
+
24
+
25
+ class BuildStatus(str, enum.Enum):
26
+ UNKNOWN = 'unknown'
27
+ DISABLED = 'disabled'
28
+ SKIPPED = 'skipped'
29
+ SHOULD_BE_BUILT = 'should be built'
30
+ FAILED = 'build failed'
31
+ SUCCESS = 'build success'
32
+
33
+
34
+ class BuildStage(str, enum.Enum):
35
+ DRY_RUN = 'Dry Run'
36
+ PRE_BUILD = 'Pre Build'
37
+ BUILD = 'Build'
38
+ POST_BUILD = 'Post Build'
39
+
40
+ @classmethod
41
+ def max_length(cls) -> int:
42
+ return max(len(v.value) for v in cls.__members__.values())
43
+
44
+
45
+ completion_instructions = """
46
+ With the `--activate` option, detect your shell type and add the appropriate commands to your shell's config file
47
+ so that it runs on startup. You will likely have to restart.
48
+ or re-login for the autocompletion to start working.
49
+
50
+ You can also specify your shell using the `--shell` option.
51
+
52
+ If you do not want automatic modification of your shell configuration file
53
+ You can manually add the commands provided below to activate autocompletion.
54
+ or run them in your current terminal session for one-time activation.
55
+
56
+ Once again, you will likely have to restart
57
+ or re-login for the autocompletion to start working.
58
+
59
+ bash:
60
+ eval "$(register-python-argcomplete idf-build-apps)"
61
+
62
+ zsh:
63
+ To activate completions in zsh, first make sure compinit is marked for
64
+ autoload and run autoload:
65
+
66
+ autoload -U compinit
67
+ compinit
68
+
69
+ Afterwards you can enable completions for idf-build-apps:
70
+
71
+ eval "$(register-python-argcomplete idf-build-apps)"
72
+
73
+ fish:
74
+ # Not required to be in the config file, only run once
75
+ register-python-argcomplete --shell fish idf-build-apps >~/.config/fish/completions/idf-build-apps.fish
76
+ """
77
+ IDF_BUILD_APPS_TOML_FN = '.idf_build_apps.toml'
@@ -1,6 +1,6 @@
1
1
  # PYTHON_ARGCOMPLETE_OK
2
2
 
3
- # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
3
+ # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
4
4
  # SPDX-License-Identifier: Apache-2.0
5
5
 
6
6
  import argparse
@@ -68,7 +68,8 @@ def find_apps(
68
68
 
69
69
  :return: list of found apps
70
70
  """
71
- apply_config_file(config_file)
71
+ if config_file:
72
+ apply_config_file(config_file)
72
73
 
73
74
  # compatible with old usage
74
75
  ## `preserve`
@@ -132,7 +133,8 @@ def build_apps(
132
133
 
133
134
  :return: exit code
134
135
  """
135
- apply_config_file(config_file)
136
+ if config_file:
137
+ apply_config_file(config_file)
136
138
 
137
139
  # compatible with old usage
138
140
  ## `check_app_dependencies`
@@ -385,8 +387,8 @@ def main():
385
387
  kwargs = vars(args)
386
388
  action = kwargs.pop('action')
387
389
  config_file = kwargs.pop('config_file')
388
-
389
- apply_config_file(config_file)
390
+ if config_file:
391
+ apply_config_file(config_file)
390
392
 
391
393
  if action == 'dump-manifest-sha':
392
394
  arguments = DumpManifestShaArguments(**drop_none_kwargs(kwargs))
@@ -0,0 +1,17 @@
1
+ # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ """
5
+ Manifest file
6
+ """
7
+
8
+ from esp_bool_parser import register_addition_attribute
9
+
10
+ from .manifest import FolderRule
11
+
12
+
13
+ def folder_rule_attr(target, **kwargs):
14
+ return 1 if target in FolderRule.DEFAULT_BUILD_TARGETS else 0
15
+
16
+
17
+ register_addition_attribute('INCLUDE_DEFAULT', folder_rule_attr)
@@ -1,11 +1,11 @@
1
- # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  import logging
4
4
  import os
5
- import pickle
6
5
  import typing as t
7
6
  from hashlib import sha512
8
7
 
8
+ from esp_bool_parser import BoolStmt, parse_bool_expr
9
9
  from pyparsing import (
10
10
  ParseException,
11
11
  )
@@ -23,10 +23,6 @@ from ..utils import (
23
23
  from ..yaml import (
24
24
  parse,
25
25
  )
26
- from .if_parser import (
27
- BOOL_EXPR,
28
- BoolStmt,
29
- )
30
26
 
31
27
  LOGGER = logging.getLogger(__name__)
32
28
 
@@ -34,7 +30,8 @@ LOGGER = logging.getLogger(__name__)
34
30
  class IfClause:
35
31
  def __init__(self, stmt: str, temporary: bool = False, reason: t.Optional[str] = None) -> None:
36
32
  try:
37
- self.stmt: BoolStmt = BOOL_EXPR.parseString(stmt)[0]
33
+ self.stmt: BoolStmt = parse_bool_expr(stmt)
34
+ self._stmt: str = stmt
38
35
  except (ParseException, InvalidIfClause) as ex:
39
36
  raise InvalidIfClause(f'Invalid if clause: {stmt}. {ex}')
40
37
 
@@ -51,6 +48,9 @@ class IfClause:
51
48
  f' reason: lack of ci runners'
52
49
  )
53
50
 
51
+ def __repr__(self):
52
+ return f'IfClause(stmt={self._stmt!r}, temporary={self.temporary!r}, reason={self.reason!r})'
53
+
54
54
  def get_value(self, target: str, config_name: str) -> t.Any:
55
55
  return self.stmt.get_value(target, config_name)
56
56
 
@@ -69,6 +69,14 @@ class SwitchClause:
69
69
  return content
70
70
  return self.default_clause
71
71
 
72
+ def __repr__(self) -> str:
73
+ return (
74
+ f'SwitchClause('
75
+ f'if_clauses={self.if_clauses!r}, '
76
+ f'contents={self.contents!r}, '
77
+ f'default_clause={self.default_clause!r})'
78
+ )
79
+
72
80
 
73
81
  class FolderRule:
74
82
  DEFAULT_BUILD_TARGETS = SUPPORTED_TARGETS
@@ -153,7 +161,7 @@ class FolderRule:
153
161
  self.depends_components,
154
162
  self.depends_filepatterns,
155
163
  ]:
156
- sha.update(pickle.dumps(obj, protocol=4)) # protocol 4 by default is set in Python 3.8
164
+ sha.update(repr(obj).encode())
157
165
 
158
166
  return sha.hexdigest()
159
167
 
@@ -0,0 +1,6 @@
1
+ # SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ import esp_bool_parser
5
+
6
+ SOC_HEADERS = esp_bool_parser.SOC_HEADERS
@@ -17,6 +17,7 @@ Modifications:
17
17
  - recursively find TOML file.
18
18
  """
19
19
 
20
+ import logging
20
21
  import os
21
22
  import sys
22
23
  from abc import ABC, abstractmethod
@@ -30,6 +31,7 @@ from idf_build_apps.constants import IDF_BUILD_APPS_TOML_FN
30
31
 
31
32
  PathType = Union[Path, str, List[Union[Path, str]], Tuple[Union[Path, str], ...]]
32
33
  DEFAULT_PATH = Path('')
34
+ LOGGER = logging.getLogger(__name__)
33
35
 
34
36
 
35
37
  class ConfigFileSourceMixin(ABC):
@@ -93,17 +95,19 @@ class TomlConfigSettingsSource(InitSettingsSource, ConfigFileSourceMixin):
93
95
  :param depth: Number of directories up the tree to check of a pyproject.toml.
94
96
  """
95
97
  if provided and Path(provided).is_file():
96
- return provided.resolve()
98
+ fp = provided.resolve()
99
+ LOGGER.debug(f'Loading config file: {fp}')
100
+ return fp
97
101
 
98
102
  rv = Path.cwd()
99
103
  count = -1
100
104
  while count < depth:
101
- if str(rv) == rv.root:
105
+ if len(rv.parts) == 1:
102
106
  break
103
107
 
104
108
  fp = rv / filename
105
109
  if fp.is_file():
106
- print(f'Loading config file: {fp}')
110
+ LOGGER.debug(f'Loading config file: {fp}')
107
111
  return fp
108
112
 
109
113
  rv = rv.parent
@@ -31,6 +31,7 @@ dependencies = [
31
31
  "pydantic_settings",
32
32
  "argcomplete>=3",
33
33
  "typing-extensions; python_version < '3.11'",
34
+ "esp-bool-parser>=0.1.2,<1"
34
35
  ]
35
36
 
36
37
  [project.optional-dependencies]
@@ -61,7 +62,7 @@ idf-build-apps = "idf_build_apps:main.main"
61
62
 
62
63
  [tool.commitizen]
63
64
  name = "cz_conventional_commits"
64
- version = "2.6.0"
65
+ version = "2.6.2"
65
66
  tag_format = "v$version"
66
67
  version_files = [
67
68
  "idf_build_apps/__init__.py",
@@ -156,5 +157,8 @@ typing-modules = [
156
157
  quote-style = "single"
157
158
  docstring-code-format = true
158
159
 
160
+ [tool.ruff.lint.flake8-unused-arguments]
161
+ ignore-variadic-names = true
162
+
159
163
  [tool.mypy]
160
164
  python_version = "3.8"
@@ -19,7 +19,8 @@ install_requires = \
19
19
  'packaging',
20
20
  'pydantic~=2.0',
21
21
  'pydantic_settings',
22
- 'argcomplete>=3']
22
+ 'argcomplete>=3',
23
+ 'esp-bool-parser>=0.1.2,<1']
23
24
 
24
25
  extras_require = \
25
26
  {":python_version < '3.11'": ['toml', 'typing-extensions'],
@@ -36,7 +37,7 @@ entry_points = \
36
37
  {'console_scripts': ['idf-build-apps = idf_build_apps:main.main']}
37
38
 
38
39
  setup(name='idf-build-apps',
39
- version='2.6.0',
40
+ version='2.6.2',
40
41
  description='Tools for building ESP-IDF related apps.',
41
42
  author=None,
42
43
  author_email='Fu Hanxi <fuhanxi@espressif.com>',
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  import os
4
4
 
@@ -10,7 +10,7 @@ from idf_build_apps import (
10
10
  setup_logging,
11
11
  )
12
12
  from idf_build_apps.args import apply_config_file
13
- from idf_build_apps.constants import IDF_BUILD_APPS_TOML_FN, SUPPORTED_TARGETS
13
+ from idf_build_apps.constants import SUPPORTED_TARGETS
14
14
  from idf_build_apps.manifest.manifest import FolderRule
15
15
 
16
16
 
@@ -19,7 +19,7 @@ def clean_cls_attr(tmp_path):
19
19
  App.MANIFEST = None
20
20
  FolderRule.DEFAULT_BUILD_TARGETS = SUPPORTED_TARGETS
21
21
  idf_build_apps.SESSION_ARGS.clean()
22
- apply_config_file(IDF_BUILD_APPS_TOML_FN)
22
+ apply_config_file(reset=True)
23
23
  os.chdir(tmp_path)
24
24
 
25
25
 
@@ -63,7 +63,7 @@ def sha_of_enable_only_esp32():
63
63
  # !!! ONLY CHANGE IT WHEN NECESSARY !!!
64
64
  assert (
65
65
  sha
66
- == '6fd3175a5068c46bccc411efadf3b98314210e775c25c62833998bff8b0cf1bc1daf738326f138f0d6629caa07338428f2aa122e2b830e6ad43662057c7ea0b1' # noqa: E501
66
+ == 'bfc1c61176cfb76169eab6c4f00dbcc4d7886fee4b93ede5fac2c005dd85db640464e9b03986d3da3bfaa4d109b053862c07dc4d5a407e58f773a8f710ec60cb' # noqa: E501
67
67
  )
68
68
 
69
69
  return sha
@@ -76,7 +76,7 @@ def sha_of_enable_esp32_or_esp32s2():
76
76
  # !!! ONLY CHANGE IT WHEN NECESSARY !!!
77
77
  assert (
78
78
  sha
79
- == 'f3408e9bf1d6b9a9e14559e6567917986678a3414229b29f96493aec4dc1bc3e6d0ecc4f79adced0d5c26bc1cd80a4d15fe6aaefa5d1e7033a58290374f4fc7f' # noqa: E501
79
+ == '9ab121a0d39bcb590465837091e82dfd798cd1ff9579e92c23e8bebaee127b46751108f0de3953993cb7993903e45d78851fc465d774a606b0ab1251fbe4b9f5' # noqa: E501
80
80
  )
81
81
 
82
82
  return sha
@@ -1,6 +1,7 @@
1
- # SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  import os
4
+ from tempfile import NamedTemporaryFile
4
5
  from xml.etree import ElementTree
5
6
 
6
7
  import pytest
@@ -323,3 +324,39 @@ dry_run = false
323
324
  assert test_suite.attrib['skipped'] == '2'
324
325
  assert test_suite.findall('testcase')[0].attrib['name'] == 'foo/build_esp32'
325
326
  assert test_suite.findall('testcase')[1].attrib['name'] == 'foo/build_esp32s2'
327
+
328
+ def test_config_file_by_cli(self, tmp_path, monkeypatch):
329
+ create_project('foo', tmp_path)
330
+ create_project('bar', tmp_path)
331
+
332
+ with open(IDF_BUILD_APPS_TOML_FN, 'w') as fw:
333
+ fw.write('paths = ["foo"]')
334
+
335
+ with NamedTemporaryFile(mode='w', suffix='.toml') as ft:
336
+ ft.write('paths = ["bar"]')
337
+ ft.flush()
338
+
339
+ with monkeypatch.context() as m:
340
+ m.setattr(
341
+ 'sys.argv',
342
+ [
343
+ 'idf-build-apps',
344
+ 'build',
345
+ '-t',
346
+ 'esp32',
347
+ '--config-file',
348
+ ft.name,
349
+ '--junitxml',
350
+ 'test.xml',
351
+ '--dry-run',
352
+ ],
353
+ )
354
+ main()
355
+
356
+ with open('test.xml') as f:
357
+ xml = ElementTree.fromstring(f.read())
358
+ test_suite = xml.findall('testsuite')[0]
359
+ assert test_suite.attrib['failures'] == '0'
360
+ assert test_suite.attrib['errors'] == '0'
361
+ assert test_suite.attrib['skipped'] == '1'
362
+ assert test_suite.findall('testcase')[0].attrib['name'] == 'bar/build'